From 82b289a71ab42d29c64160341d4a4cbcb954864d Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Sat, 24 Jun 2023 14:23:31 -0700 Subject: [PATCH 001/356] rebase conflicts --- latch_cli/centromere/ctx.py | 93 ++++++++++++++++++++--------------- latch_cli/centromere/utils.py | 10 ++++ 2 files changed, 63 insertions(+), 40 deletions(-) diff --git a/latch_cli/centromere/ctx.py b/latch_cli/centromere/ctx.py index 18766147..e59eea25 100644 --- a/latch_cli/centromere/ctx.py +++ b/latch_cli/centromere/ctx.py @@ -2,10 +2,12 @@ import subprocess import time from dataclasses import dataclass +from enum import Enum from pathlib import Path from textwrap import dedent from typing import Dict, Optional, Tuple +import click import docker import paramiko import paramiko.util @@ -19,9 +21,9 @@ _construct_dkr_client, _construct_ssh_client, _import_flyte_objects, + get_default_dockerfile, ) from latch_cli.constants import latch_constants -from latch_cli.docker_utils import generate_dockerfile from latch_cli.utils import ( account_id_from_token, current_workspace, @@ -31,6 +33,11 @@ ) +class WorkflowType(Enum): + latchbiosdk = "latchbiosdk" + snakemake = "snakemake" + + @dataclass class _Container: dockerfile: Path @@ -62,6 +69,7 @@ class _CentromereCtx: # Used to associate alternate containers with tasks container_map: Dict[str, _Container] workflow_name: Optional[str] + workflow_type: WorkflowType latch_register_api_url = config.api.workflow.register latch_image_api_url = config.api.workflow.upload_image @@ -95,51 +103,58 @@ def __init__( else: self.account_id = ws - self.pkg_root = Path(pkg_root).resolve() self.dkr_repo = config.dkr_repo self.remote = remote - self.container_map = {} + self.disable_auto_version = disable_auto_version + self.pkg_root = Path(pkg_root).resolve() - default_dockerfile = self.pkg_root.joinpath("Dockerfile") - if not default_dockerfile.exists(): - generate_dockerfile( - self.pkg_root, self.pkg_root.joinpath(".latch/Dockerfile") + # TODO (kenny) better rules to auto detect workflow type + if ( + self.pkg_root.joinpath("Snakefile").exists() + and not self.pkg_root.joinpath("wf").exists() + ): + self.workflow_type = WorkflowType.snakemake + else: + self.workflow_type = WorkflowType.latchbiosdk + + version_file = self.pkg_root.joinpath("version") + if not version_file.exists(): + self.version = "0.0.0" + with open(version_file, "w") as vf: + vf.write(self.version) + click.echo( + "Created a version file with initial version 0.0.0 for this" + " workflow." ) - default_dockerfile = self.pkg_root.joinpath(".latch/Dockerfile") - - _import_flyte_objects([self.pkg_root]) - - self.disable_auto_version = disable_auto_version - try: - version_file = self.pkg_root.joinpath("version") + else: with open(version_file, "r") as vf: self.version = vf.read().strip() - if not self.disable_auto_version: - hash = hash_directory(self.pkg_root) - self.version = self.version + "-" + hash[:6] - except Exception as e: - raise ValueError( - f"Unable to extract pkg version from {str(self.pkg_root)}" - ) from e - - # Global FlyteEntities object holds all serializable objects after they are imported. - for entity in FlyteEntities.entities: - if isinstance(entity, PythonFunctionWorkflow): - self.workflow_name = entity.name - if isinstance(entity, PythonTask): - if ( - hasattr(entity, "dockerfile_path") - and entity.dockerfile_path is not None - ): - self.container_map[entity.name] = _Container( - dockerfile=entity.dockerfile_path, - image_name=self.task_image_name(entity.name), - pkg_dir=entity.dockerfile_path.parent, - ) + + if not self.disable_auto_version: + hash = hash_directory(self.pkg_root) + self.version = self.version + "-" + hash[:6] if self.nucleus_check_version(self.version, self.workflow_name) is True: raise ValueError(f"Version {self.version} has already been registered.") + # We do not support per task containers for snakemake rn + self.container_map = {} + if self.workflow_type == WorkflowType.latchbiosdk: + for entity in FlyteEntities.entities: + if isinstance(entity, PythonFunctionWorkflow): + self.workflow_name = entity.name + if isinstance(entity, PythonTask): + if ( + hasattr(entity, "dockerfile_path") + and entity.dockerfile_path is not None + ): + self.container_map[entity.name] = _Container( + dockerfile=entity.dockerfile_path, + image_name=self.task_image_name(entity.name), + pkg_dir=entity.dockerfile_path.parent, + ) + + default_dockerfile = get_default_dockerfile(self.pkg_root) self.default_container = _Container( dockerfile=default_dockerfile, image_name=self.image_tagged, @@ -205,10 +220,8 @@ def image_tagged(self): match = re.match("^[a-zA-Z0-9_][a-zA-Z0-9._-]{,127}$", self.version) if match is None: raise ValueError( - ( - f"{self.version} is an invalid version for AWS " - "ECR. Please provide a version that accomodates the " - ), + f"{self.version} is an invalid version for AWS " + "ECR. Please provide a version that accomodates the ", "tag restrictions listed here - ", "https://docs.aws.amazon.com/AmazonECR/latest/userguide/ecr-using-tags.html", ) diff --git a/latch_cli/centromere/utils.py b/latch_cli/centromere/utils.py index 2e771319..31605b96 100644 --- a/latch_cli/centromere/utils.py +++ b/latch_cli/centromere/utils.py @@ -16,6 +16,7 @@ from flytekit.tools import module_loader from latch_cli.constants import latch_constants +from latch_cli.docker_utils import generate_dockerfile @contextlib.contextmanager @@ -189,6 +190,15 @@ def _construct_ssh_client(internal_ip: str, username: str) -> paramiko.SSHClient return ssh +def get_default_dockerfile(pkg_root: Path): + + default_dockerfile = pkg_root.joinpath("Dockerfile") + if not default_dockerfile.exists(): + generate_dockerfile(pkg_root, pkg_root.joinpath(".latch/Dockerfile")) + default_dockerfile = pkg_root.joinpath(".latch/Dockerfile") + return default_dockerfile + + class _TmpDir: """Represents a temporary directory that can be local or on a remote machine.""" From 0cc4135f01162f75823b86a5ced6d7b711a4e57c Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Thu, 18 May 2023 15:24:46 -0700 Subject: [PATCH 002/356] add back flyte object import --- latch_cli/centromere/ctx.py | 1 + 1 file changed, 1 insertion(+) diff --git a/latch_cli/centromere/ctx.py b/latch_cli/centromere/ctx.py index e59eea25..de815cff 100644 --- a/latch_cli/centromere/ctx.py +++ b/latch_cli/centromere/ctx.py @@ -140,6 +140,7 @@ def __init__( # We do not support per task containers for snakemake rn self.container_map = {} if self.workflow_type == WorkflowType.latchbiosdk: + _import_flyte_objects([self.pkg_root]) for entity in FlyteEntities.entities: if isinstance(entity, PythonFunctionWorkflow): self.workflow_name = entity.name From 2d81d08cca847c0be695c452cf21726ea6839a46 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Sat, 24 Jun 2023 14:27:19 -0700 Subject: [PATCH 003/356] rebase fixes --- latch_cli/centromere/ctx.py | 50 +++---- latch_cli/centromere/utils.py | 3 +- latch_cli/docker_utils/__init__.py | 15 +- latch_cli/services/register/__init__.py | 4 +- latch_cli/services/register/register.py | 43 +++--- latch_cli/services/register/utils.py | 17 ++- latch_cli/services/serialize.py | 190 ++++++++++++++++++++++++ latch_cli/utils.py | 6 + 8 files changed, 266 insertions(+), 62 deletions(-) create mode 100644 latch_cli/services/serialize.py diff --git a/latch_cli/centromere/ctx.py b/latch_cli/centromere/ctx.py index de815cff..6823c2d9 100644 --- a/latch_cli/centromere/ctx.py +++ b/latch_cli/centromere/ctx.py @@ -2,7 +2,6 @@ import subprocess import time from dataclasses import dataclass -from enum import Enum from pathlib import Path from textwrap import dedent from typing import Dict, Optional, Tuple @@ -18,6 +17,7 @@ import latch_cli.tinyrequests as tinyrequests from latch_cli.centromere.utils import ( + WorkflowType, _construct_dkr_client, _construct_ssh_client, _import_flyte_objects, @@ -33,11 +33,6 @@ ) -class WorkflowType(Enum): - latchbiosdk = "latchbiosdk" - snakemake = "snakemake" - - @dataclass class _Container: dockerfile: Path @@ -117,6 +112,27 @@ def __init__( else: self.workflow_type = WorkflowType.latchbiosdk + # We do not support per task containers for snakemake rn + self.container_map = {} + if self.workflow_type == WorkflowType.latchbiosdk: + _import_flyte_objects([self.pkg_root]) + for entity in FlyteEntities.entities: + if isinstance(entity, PythonFunctionWorkflow): + self.workflow_name = entity.name + if isinstance(entity, PythonTask): + if ( + hasattr(entity, "dockerfile_path") + and entity.dockerfile_path is not None + ): + self.container_map[entity.name] = _Container( + dockerfile=entity.dockerfile_path, + image_name=self.task_image_name(entity.name), + pkg_dir=entity.dockerfile_path.parent, + ) + else: + # TODO + self.workflow_name = "snakemake workflow" + version_file = self.pkg_root.joinpath("version") if not version_file.exists(): self.version = "0.0.0" @@ -137,25 +153,9 @@ def __init__( if self.nucleus_check_version(self.version, self.workflow_name) is True: raise ValueError(f"Version {self.version} has already been registered.") - # We do not support per task containers for snakemake rn - self.container_map = {} - if self.workflow_type == WorkflowType.latchbiosdk: - _import_flyte_objects([self.pkg_root]) - for entity in FlyteEntities.entities: - if isinstance(entity, PythonFunctionWorkflow): - self.workflow_name = entity.name - if isinstance(entity, PythonTask): - if ( - hasattr(entity, "dockerfile_path") - and entity.dockerfile_path is not None - ): - self.container_map[entity.name] = _Container( - dockerfile=entity.dockerfile_path, - image_name=self.task_image_name(entity.name), - pkg_dir=entity.dockerfile_path.parent, - ) - - default_dockerfile = get_default_dockerfile(self.pkg_root) + default_dockerfile = get_default_dockerfile( + self.pkg_root, self.workflow_type + ) self.default_container = _Container( dockerfile=default_dockerfile, image_name=self.image_tagged, diff --git a/latch_cli/centromere/utils.py b/latch_cli/centromere/utils.py index 31605b96..c8f29b69 100644 --- a/latch_cli/centromere/utils.py +++ b/latch_cli/centromere/utils.py @@ -17,6 +17,7 @@ from latch_cli.constants import latch_constants from latch_cli.docker_utils import generate_dockerfile +from latch_cli.utils import WorkflowType @contextlib.contextmanager @@ -190,7 +191,7 @@ def _construct_ssh_client(internal_ip: str, username: str) -> paramiko.SSHClient return ssh -def get_default_dockerfile(pkg_root: Path): +def get_default_dockerfile(pkg_root: Path, wf_type: WorkflowType): default_dockerfile = pkg_root.joinpath("Dockerfile") if not default_dockerfile.exists(): diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 76385573..b30d6ebb 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -9,6 +9,7 @@ import yaml from latch_cli.constants import latch_constants +from latch_cli.utils import WorkflowType from latch_cli.workflow_config import LatchWorkflowConfig, create_and_write_config @@ -38,12 +39,12 @@ def get_prologue(config: LatchWorkflowConfig) -> List[str]: ), f"from {config.base_image}", f"run pip install latch=={config.latch_version}", - f"run mkdir /opt/latch", + "run mkdir /opt/latch", ] -def get_epilogue() -> List[str]: - return [ +def get_epilogue(wf_type: WorkflowType = WorkflowType.latchbiosdk) -> List[str]: + cmds = [ ( "# latch internal tagging system + expected root directory --- changing" " these lines will break the workflow" @@ -52,6 +53,9 @@ def get_epilogue() -> List[str]: "env FLYTE_INTERNAL_IMAGE $tag", "workdir /root", ] + if wf_type == WorkflowType.snakemake: + cmds.insert("copy .latch/latch_entrypoint.py /root/latch_entrypoint.py") + return cmds def infer_commands(pkg_root: Path) -> List[DockerCmdBlock]: @@ -187,16 +191,17 @@ def infer_commands(pkg_root: Path) -> List[DockerCmdBlock]: return commands -def generate_dockerfile(pkg_root: Path, outfile: Path) -> None: +def generate_dockerfile(pkg_root: Path, outfile: Path, wf_type: WorkflowType) -> None: """Generate a best effort Dockerfile from files in the workflow directory. Args: pkg_root: A path to a workflow directory. outfile: The path to write the generated Dockerfile. + wf_type: The type of workflow (eg. snakemake) the Dockerfile is for Example: - >>> generate_dockerfile(Path("test-workflow"), Path("test-workflow/Dockerfile")) + >>> generate_dockerfile(Path("test-workflow"), Path("test-workflow/Dockerfile"), WorkflowType.snakemake) # The resulting file structure will look like # test-workflow # ├── Dockerfile diff --git a/latch_cli/services/register/__init__.py b/latch_cli/services/register/__init__.py index 56cd227e..95957c5c 100644 --- a/latch_cli/services/register/__init__.py +++ b/latch_cli/services/register/__init__.py @@ -1,5 +1,5 @@ from latch_cli.services.register.register import ( - _build_image, - _print_and_save_build_logs, + build_image, + print_and_write_build_logs, register, ) diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index fc5bb4c7..b18e4851 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -15,10 +15,10 @@ from latch_cli.centromere.utils import _construct_ssh_client, _TmpDir from latch_cli.services.register.constants import ANSI_REGEX, MAX_LINES from latch_cli.services.register.utils import ( - _build_image, - _register_serialized_pkg, - _serialize_pkg_in_container, - _upload_image, + build_image, + register_serialized_pkg, + serialize_pkg_in_container, + upload_image, ) from latch_cli.utils import current_workspace @@ -52,7 +52,7 @@ def _print_window(curr_lines: List[str], line: str): return curr_lines -def _print_and_save_build_logs(build_logs, image: str, pkg_root: Path): +def print_and_write_build_logs(build_logs, image: str, pkg_root: Path): print(f"Building Docker image for {image}") logs_path = Path(pkg_root).joinpath(".logs").joinpath(image).resolve() @@ -87,7 +87,7 @@ def _print_and_save_build_logs(build_logs, image: str, pkg_root: Path): _delete_lines(curr_lines) -def _print_upload_logs(upload_image_logs, image): +def print_upload_logs(upload_image_logs, image): print(f"Uploading Docker image for {image}") prog_map = {} @@ -141,40 +141,34 @@ def _print_reg_resp(resp, image): print(resp.get("stdout")) -def _print_serialize_logs(serialize_logs, image): +def print_serialize_logs(serialize_logs, image): print(f"Serializing workflow in {image}:") for x in serialize_logs: print(x, end="") -def _build_and_serialize( +def build_and_serialize( ctx: _CentromereCtx, image_name: str, context_path: Path, tmp_dir: Path, dockerfile: Optional[Path] = None, ): - """Encapsulates build, serialize, push flow needed for each dockerfile + """Builds an image, serializes the workflow within the image, and pushes the image.""" - - Build image - - Serialize workflow in image - - Save proto files to passed temporary directory - - Push image - """ - - build_logs = _build_image(ctx, image_name, context_path, dockerfile) - _print_and_save_build_logs(build_logs, image_name, ctx.pkg_root) + image_build_logs = build_image(ctx, image_name, context_path, dockerfile) + print_and_write_build_logs(image_build_logs, image_name, ctx.pkg_root) - serialize_logs, container_id = _serialize_pkg_in_container(ctx, image_name, tmp_dir) - _print_serialize_logs(serialize_logs, image_name) + serialize_logs, container_id = serialize_pkg_in_container(ctx, image_name, tmp_dir) + print_serialize_logs(serialize_logs, image_name) exit_status = ctx.dkr_client.wait(container_id) if exit_status["StatusCode"] != 0: raise ValueError( f"Serialization exited with nonzero exit code: {exit_status['Error']}" ) - upload_image_logs = _upload_image(ctx, image_name) - _print_upload_logs(upload_image_logs, image_name) + upload_image_logs = upload_image(ctx, image_name) + print_upload_logs(upload_image_logs, image_name) def _recursive_list(directory: Path) -> List[Path]: @@ -292,13 +286,14 @@ def register( username=ctx.username, ) ) - _build_and_serialize( + build_and_serialize( ctx, ctx.default_container.image_name, ctx.default_container.pkg_dir, td, dockerfile=ctx.default_container.dockerfile, ) + quit() protos = _recursive_list(td) if remote: local_td = stack.enter_context(tempfile.TemporaryDirectory()) @@ -318,7 +313,7 @@ def register( ) ) try: - _build_and_serialize( + build_and_serialize( ctx, container.image_name, # always use root as build context @@ -360,7 +355,7 @@ def register( f"{container.dockerfile} given to {task_name} is invalid.", ) from e - reg_resp = _register_serialized_pkg(ctx, protos) + reg_resp = register_serialized_pkg(ctx, protos) _print_reg_resp(reg_resp, ctx.default_container.image_name) click.secho( diff --git a/latch_cli/services/register/utils.py b/latch_cli/services/register/utils.py index 6e47dbdf..a67aede8 100644 --- a/latch_cli/services/register/utils.py +++ b/latch_cli/services/register/utils.py @@ -1,3 +1,5 @@ +from latch_cli.utils import WorkflowType + "Utilites for registration." import base64 @@ -48,7 +50,7 @@ def _docker_login(ctx: _CentromereCtx): ) -def _build_image( +def build_image( ctx: _CentromereCtx, image_name: str, context_path: Path, @@ -69,7 +71,7 @@ def _build_image( return build_logs -def _upload_image(ctx: _CentromereCtx, image_name: str) -> List[str]: +def upload_image(ctx: _CentromereCtx, image_name: str) -> List[str]: return ctx.dkr_client.push( repository=f"{ctx.dkr_repo}/{image_name}", stream=True, @@ -77,10 +79,15 @@ def _upload_image(ctx: _CentromereCtx, image_name: str) -> List[str]: ) -def _serialize_pkg_in_container( +def serialize_pkg_in_container( ctx: _CentromereCtx, image_name: str, serialize_dir: Path ) -> List[str]: - _serialize_cmd = ["make", "serialize"] + _serialize_cmd = ["make"] + if ctx.workflow_type == WorkflowType.latchbiosdk: + _serialize_cmd.append("serialize") + else: + _serialize_cmd.append("snakemake-serialize") + container = ctx.dkr_client.create_container( f"{ctx.dkr_repo}/{image_name}", command=_serialize_cmd, @@ -101,7 +108,7 @@ def _serialize_pkg_in_container( return [x.decode("utf-8") for x in logs], container_id -def _register_serialized_pkg(ctx: _CentromereCtx, files: List[Path]) -> dict: +def register_serialized_pkg(ctx: _CentromereCtx, files: List[Path]) -> dict: headers = {"Authorization": f"Bearer {ctx.token}"} serialize_files = { diff --git a/latch_cli/services/serialize.py b/latch_cli/services/serialize.py new file mode 100644 index 00000000..5e2d6e1c --- /dev/null +++ b/latch_cli/services/serialize.py @@ -0,0 +1,190 @@ +import os +import textwrap +from itertools import chain, filterfalse +from pathlib import Path + +from snakemake.common import ON_WINDOWS +from snakemake.dag import DAG +from snakemake.persistence import Persistence +from snakemake.rules import Rule +from snakemake.workflow import Workflow + + +class SnakemakeWorkflowExtractor(Workflow): + def __init__(self, snakefile): + super().__init__(snakefile=snakefile) + + def extract(self): + def rules(items): + return map(self._rules.__getitem__, filter(self.is_rule, items)) + + def files(items): + relpath = ( + lambda f: f + if os.path.isabs(f) or f.startswith("root://") + else os.path.relpath(f) + ) + return map(relpath, filterfalse(self.is_rule, items)) + + # if not targets and not target_jobs: + targets = [self.default_target] if self.default_target is not None else list() + + prioritytargets = list() + forcerun = list() + until = list() + omit_from = list() + + priorityrules = set(rules(prioritytargets)) + priorityfiles = set(files(prioritytargets)) + forcerules = set(rules(forcerun)) + forcefiles = set(files(forcerun)) + untilrules = set(rules(until)) + untilfiles = set(files(until)) + omitrules = set(rules(omit_from)) + omitfiles = set(files(omit_from)) + targetrules = set( + chain( + rules(targets), + filterfalse(Rule.has_wildcards, priorityrules), + filterfalse(Rule.has_wildcards, forcerules), + filterfalse(Rule.has_wildcards, untilrules), + ) + ) + targetfiles = set(chain(files(targets), priorityfiles, forcefiles, untilfiles)) + + if ON_WINDOWS: + targetfiles = set(tf.replace(os.sep, os.altsep) for tf in targetfiles) + + rules = self.rules + + dag = DAG( + self, + rules, + targetfiles=targetfiles, + targetrules=targetrules, + forcefiles=forcefiles, + forcerules=forcerules, + priorityfiles=priorityfiles, + priorityrules=priorityrules, + untilfiles=untilfiles, + untilrules=untilrules, + omitfiles=omitfiles, + omitrules=omitrules, + ) + + self.persistence = Persistence( + dag=dag, + ) + + dag.init() + dag.update_checkpoint_dependencies() + dag.check_dynamic() + + return self, dag + + +def serialize(pkg_root: Path): + """Serializes workflow code into lyteidl protobuf. + + Args: + pkg_root: The directory of project with workflow code to be serialized + """ + + ... + + +def generate_snakemake_entrypoint(snakefile: Path): + + workflow = SnakemakeWorkflowExtractor( + snakefile=snakefile, + ) + workflow.include( + snakefile, + overwrite_default_target=True, + ) + wf, dag = workflow.extract() + + entrypoint_code_block = textwrap.dedent( + """\ + import subprocess + from pathlib import Path + from typing import NamedTuple + + from latch import small_task + from latch.types import LatchFile + + def ensure_parents_exist(path: Path): + path.parent.mkdir(parents=True, exist_ok=True) + return path + """ + ) + + with open("latch_entrypoint.py", "w") as f: + f.write(entrypoint_code_block) + + +def generate_python_function_for_job(): + + code_block = "" + + fn_interface = f"\n\n@small_task\ndef {self.name}(" + for idx, (param, t) in enumerate(self._python_inputs.items()): + fn_interface += f"{param}: {t.__name__}" + if idx == len(self._python_inputs) - 1: + fn_interface += ")" + else: + fn_interface += ", " + + # NamedTuple("OP", B_bam=LatchFile) + if len(self._python_outputs.items()) > 0: + for idx, (param, t) in enumerate(self._python_outputs.items()): + if idx == 0: + fn_interface += f" -> NamedTuple('{self.name}_output', " + fn_interface += f"{param}={t.__name__}" + if idx == len(self._python_outputs) - 1: + fn_interface += "):" + else: + fn_interface += ", " + else: + fn_interface += ":" + + code_block += fn_interface + + # rename statement + + for param, t in self._python_inputs.items(): + if t == LatchFile: + code_block += f'\n\tPath({param}).resolve().rename(ensure_parents_exist(Path("{self._target_file_for_param[param]}")))' + + # Snakemake subprocess + + executor = RealExecutor(workflow, dag) + executor.cores = 8 + snakemake_cmd = ["snakemake", *executor.get_job_args(self.job).split(" ")] + snakemake_cmd.remove("") + formatted_snakemake_cmd = "\n\n\tsubprocess.run([" + + for i, arg in enumerate(snakemake_cmd): + arg_wo_quotes = arg.strip('"').strip("'") + formatted_snakemake_cmd += f'"{arg_wo_quotes}"' + if i == len(snakemake_cmd) - 1: + formatted_snakemake_cmd += "], check=True)" + else: + formatted_snakemake_cmd += ", " + code_block += formatted_snakemake_cmd + + return_stmt = "\n\treturn (" + for i, x in enumerate(self._python_outputs): + if self._is_target: + return_stmt += ( + f"LatchFile('{self._target_file_for_param[x]}'," + f" 'latch:///{self._target_file_for_param[x]}')" + ) + else: + return_stmt += f"LatchFile('{self._target_file_for_param[x]}')" + if i == len(self._python_outputs) - 1: + return_stmt += ")" + else: + return_stmt += ", " + code_block += return_stmt + return code_block diff --git a/latch_cli/utils.py b/latch_cli/utils.py index bc9e05e4..99fe94be 100644 --- a/latch_cli/utils.py +++ b/latch_cli/utils.py @@ -4,6 +4,7 @@ import os import subprocess from datetime import datetime, timedelta +from enum import Enum from pathlib import Path from typing import List @@ -289,3 +290,8 @@ def __enter__(self): def __exit__(self, type, value, traceback): self.cleanup() + + +class WorkflowType(Enum): + latchbiosdk = "latchbiosdk" + snakemake = "snakemake" From c131fb41f1dc06d6874d79ee8252ee1b98ce0594 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Sat, 24 Jun 2023 14:28:02 -0700 Subject: [PATCH 004/356] rebase conflicts --- latch_cli/services/register/utils.py | 1 + latch_cli/services/serialize.py | 157 +++++---- latch_cli/snakemake/serialize_utils.py | 199 +++++++++++ latch_cli/snakemake/workflow.py | 469 +++++++++++++++++++++++++ 4 files changed, 754 insertions(+), 72 deletions(-) create mode 100644 latch_cli/snakemake/serialize_utils.py create mode 100644 latch_cli/snakemake/workflow.py diff --git a/latch_cli/services/register/utils.py b/latch_cli/services/register/utils.py index a67aede8..896d962e 100644 --- a/latch_cli/services/register/utils.py +++ b/latch_cli/services/register/utils.py @@ -83,6 +83,7 @@ def serialize_pkg_in_container( ctx: _CentromereCtx, image_name: str, serialize_dir: Path ) -> List[str]: _serialize_cmd = ["make"] + if ctx.workflow_type == WorkflowType.latchbiosdk: _serialize_cmd.append("serialize") else: diff --git a/latch_cli/services/serialize.py b/latch_cli/services/serialize.py index 5e2d6e1c..89d93ea0 100644 --- a/latch_cli/services/serialize.py +++ b/latch_cli/services/serialize.py @@ -3,12 +3,30 @@ from itertools import chain, filterfalse from pathlib import Path +from flytekit import LaunchPlan +from flytekit.configuration import Image, ImageConfig, SerializationSettings +from flytekit.core.workflow import ( + WorkflowFailurePolicy, + WorkflowMetadata, + WorkflowMetadataDefaults, +) +from flytekit.models import launch_plan as launch_plan_models +from flytekit.models import literals as literals_models +from flytekit.models import task as task_models +from flytekit.models.admin import workflow as admin_workflow_models +from flytekit.tools.serialize_helpers import persist_registrable_entities from snakemake.common import ON_WINDOWS from snakemake.dag import DAG from snakemake.persistence import Persistence from snakemake.rules import Rule from snakemake.workflow import Workflow +from latch_cli.snakemake.serialize_utils import ( + get_serializable_launch_plan, + get_serializable_workflow, +) +from latch_cli.workflow import SnakemakeWorkflow, transform_inputs_to_parameters + class SnakemakeWorkflowExtractor(Workflow): def __init__(self, snakefile): @@ -90,11 +108,7 @@ def serialize(pkg_root: Path): pkg_root: The directory of project with workflow code to be serialized """ - ... - - -def generate_snakemake_entrypoint(snakefile: Path): - + snakefile = Path("Snakemake") workflow = SnakemakeWorkflowExtractor( snakefile=snakefile, ) @@ -102,7 +116,62 @@ def generate_snakemake_entrypoint(snakefile: Path): snakefile, overwrite_default_target=True, ) - wf, dag = workflow.extract() + _, dag = workflow.extract() + + wf_name = "snakemake_wf" + metadata = WorkflowMetadata(on_failure=WorkflowFailurePolicy.FAIL_IMMEDIATELY) + + interruptible = False + workflow_metadata_defaults = WorkflowMetadataDefaults(interruptible) + + wf = SnakemakeWorkflow( + wf_name, + dag, + metadata=metadata, + default_metadata=workflow_metadata_defaults, + ) + wf.compile() + + default_img = Image( + name=wf_name, + fqn=f"812206152185.dkr.ecr.us-west-2.amazonaws.com/{wf_name}", + tag="", + ) + settings = SerializationSettings( + project="", + domain="", + version="", + env={}, + image_config=ImageConfig(default_image=default_img, images=[default_img]), + ) + + registrable_entity_cache = {} + + get_serializable_workflow(wf, settings, registrable_entity_cache) + + parameter_map = transform_inputs_to_parameters(wf.python_interface) + lp = LaunchPlan( + name=wf.name, + workflow=wf, + parameters=parameter_map, + fixed_inputs=literals_models.LiteralMap(literals={}), + ) + admin_lp = get_serializable_launch_plan(settings, lp, registrable_entity_cache) + + new_api_model_values = list(registrable_entity_cache.values()) + entities_to_be_serialized = [ + x.to_flyte_idl() + for x in list(filter(should_register_with_admin, new_api_model_values)) + + [admin_lp] + ] + + persist_registrable_entities(entities_to_be_serialized, "/tmp") + + entrypoint = Path("latch_entrypoint.py") + generate_snakemake_entrypoint(snakefile, entrypoint) + + +def generate_snakemake_entrypoint(snakefile: Path, entrypoint: Path): entrypoint_code_block = textwrap.dedent( """\ @@ -119,72 +188,16 @@ def ensure_parents_exist(path: Path): """ ) - with open("latch_entrypoint.py", "w") as f: + with open(entrypoint, "w") as f: f.write(entrypoint_code_block) -def generate_python_function_for_job(): - - code_block = "" - - fn_interface = f"\n\n@small_task\ndef {self.name}(" - for idx, (param, t) in enumerate(self._python_inputs.items()): - fn_interface += f"{param}: {t.__name__}" - if idx == len(self._python_inputs) - 1: - fn_interface += ")" - else: - fn_interface += ", " - - # NamedTuple("OP", B_bam=LatchFile) - if len(self._python_outputs.items()) > 0: - for idx, (param, t) in enumerate(self._python_outputs.items()): - if idx == 0: - fn_interface += f" -> NamedTuple('{self.name}_output', " - fn_interface += f"{param}={t.__name__}" - if idx == len(self._python_outputs) - 1: - fn_interface += "):" - else: - fn_interface += ", " - else: - fn_interface += ":" - - code_block += fn_interface - - # rename statement - - for param, t in self._python_inputs.items(): - if t == LatchFile: - code_block += f'\n\tPath({param}).resolve().rename(ensure_parents_exist(Path("{self._target_file_for_param[param]}")))' - - # Snakemake subprocess - - executor = RealExecutor(workflow, dag) - executor.cores = 8 - snakemake_cmd = ["snakemake", *executor.get_job_args(self.job).split(" ")] - snakemake_cmd.remove("") - formatted_snakemake_cmd = "\n\n\tsubprocess.run([" - - for i, arg in enumerate(snakemake_cmd): - arg_wo_quotes = arg.strip('"').strip("'") - formatted_snakemake_cmd += f'"{arg_wo_quotes}"' - if i == len(snakemake_cmd) - 1: - formatted_snakemake_cmd += "], check=True)" - else: - formatted_snakemake_cmd += ", " - code_block += formatted_snakemake_cmd - - return_stmt = "\n\treturn (" - for i, x in enumerate(self._python_outputs): - if self._is_target: - return_stmt += ( - f"LatchFile('{self._target_file_for_param[x]}'," - f" 'latch:///{self._target_file_for_param[x]}')" - ) - else: - return_stmt += f"LatchFile('{self._target_file_for_param[x]}')" - if i == len(self._python_outputs) - 1: - return_stmt += ")" - else: - return_stmt += ", " - code_block += return_stmt - return code_block +def should_register_with_admin(entity) -> bool: + return isinstance( + entity, + ( + task_models.TaskSpec, + launch_plan_models.LaunchPlan, + admin_workflow_models.WorkflowSpec, + ), + ) diff --git a/latch_cli/snakemake/serialize_utils.py b/latch_cli/snakemake/serialize_utils.py new file mode 100644 index 00000000..6fec4b85 --- /dev/null +++ b/latch_cli/snakemake/serialize_utils.py @@ -0,0 +1,199 @@ +from typing import Union + +from flytekit import LaunchPlan +from flytekit.configuration import SerializationSettings +from flytekit.core import constants as common_constants +from flytekit.core.base_task import PythonTask +from flytekit.core.node import Node +from flytekit.core.utils import _dnsify +from flytekit.core.workflow import WorkflowBase +from flytekit.models import common as common_models +from flytekit.models import interface as interface_models +from flytekit.models import launch_plan as launch_plan_models +from flytekit.models import task as task_models +from flytekit.models.admin import workflow as admin_workflow_models +from flytekit.models.core import identifier as identifier_model +from flytekit.models.core import workflow as workflow_model +from flytekit.models.core.workflow import TaskNodeOverrides + +FlyteLocalEntity = Union[ + PythonTask, + Node, + LaunchPlan, + WorkflowBase, +] + +FlyteSerializableModel = Union[ + task_models.TaskSpec, + workflow_model.Node, + launch_plan_models.LaunchPlan, + admin_workflow_models.WorkflowSpec, +] + +EntityCache = dict[FlyteLocalEntity, FlyteSerializableModel] + + +def get_serializable_launch_plan( + settings: SerializationSettings, + entity: LaunchPlan, + cache: EntityCache, +) -> launch_plan_models.LaunchPlan: + + wf_id = identifier_model.Identifier( + resource_type=identifier_model.ResourceType.WORKFLOW, + project=settings.project, + domain=settings.domain, + name=entity.workflow.name, + version=settings.version, + ) + raw = None + + lps = launch_plan_models.LaunchPlanSpec( + workflow_id=wf_id, + entity_metadata=launch_plan_models.LaunchPlanMetadata( + schedule=entity.schedule, + notifications=entity.notifications, + ), + default_inputs=entity.parameters, + fixed_inputs=entity.fixed_inputs, + labels=common_models.Labels({}), + annotations=entity.annotations or common_models.Annotations({}), + auth_role=None, + raw_output_data_config=raw + or entity.raw_output_data_config + or common_models.RawOutputDataConfig(""), + max_parallelism=entity.max_parallelism, + security_context=entity.security_context, + ) + + lp_id = identifier_model.Identifier( + resource_type=identifier_model.ResourceType.LAUNCH_PLAN, + project=settings.project, + domain=settings.domain, + name=entity.name, + version=settings.version, + ) + lp_model = launch_plan_models.LaunchPlan( + id=lp_id, + spec=lps, + closure=launch_plan_models.LaunchPlanClosure( + state=None, + expected_inputs=interface_models.ParameterMap({}), + expected_outputs=interface_models.VariableMap({}), + ), + ) + + return lp_model + + +def get_serializable_task( + entity: FlyteLocalEntity, + settings: SerializationSettings, + cache: EntityCache, +) -> task_models.TaskSpec: + + if entity in cache: + return cache[entity] + + task_id = identifier_model.Identifier( + identifier_model.ResourceType.TASK, + settings.project, + settings.domain, + entity.name, + settings.version, + ) + + container = entity.get_container(settings) + pod = entity.get_k8s_pod(settings) + + tt = task_models.TaskTemplate( + id=task_id, + type=entity.task_type, + metadata=entity.metadata.to_taskmetadata_model(), + interface=entity.interface, + custom=entity.get_custom(settings), + container=container, + task_type_version=entity.task_type_version, + security_context=entity.security_context, + config=entity.get_config(settings), + k8s_pod=pod, + sql=entity.get_sql(settings), + ) + task_model = task_models.TaskSpec(template=tt) + cache[entity] = task_model + return task_model + + +def get_serializable_node( + entity: Node, + settings: SerializationSettings, + cache: EntityCache, +) -> workflow_model.Node: + + if entity in cache: + return cache[entity] + + if entity.flyte_entity is None: + raise Exception(f"Node {entity.id} has no flyte entity") + + upstream_sdk_nodes = [ + get_serializable_node(n, settings) + for n in entity.upstream_nodes + if n.id != common_constants.GLOBAL_INPUT_NODE_ID + ] + + if isinstance(entity.flyte_entity, PythonTask): + task_spec = get_serializable_task(entity.flyte_entity, settings) + node_model = workflow_model.Node( + id=_dnsify(entity.id), + metadata=entity.metadata, + inputs=entity.bindings, + upstream_node_ids=[n.id for n in upstream_sdk_nodes], + output_aliases=[], + task_node=workflow_model.TaskNode( + reference_id=task_spec.template.id, + overrides=TaskNodeOverrides(resources=entity._resources), + ), + ) + cache[entity] = node_model + return node_model + else: + raise Exception( + f"Node contained non-serializable entity {entity._flyte_entity}" + ) + + +def get_serializable_workflow( + entity: WorkflowBase, + settings: SerializationSettings, + cache: EntityCache, +) -> admin_workflow_models.WorkflowSpec: + + if entity in cache: + return cache[entity] + + upstream_node_models = [ + get_serializable_node(n, settings) + for n in entity.nodes + if n.id != common_constants.GLOBAL_INPUT_NODE_ID + ] + + wf_id = identifier_model.Identifier( + resource_type=identifier_model.ResourceType.WORKFLOW, + project=settings.project, + domain=settings.domain, + name=entity.name, + version=settings.version, + ) + wf_t = workflow_model.WorkflowTemplate( + id=wf_id, + metadata=entity.workflow_metadata.to_flyte_model(), + metadata_defaults=entity.workflow_metadata_defaults.to_flyte_model(), + interface=entity.interface, + nodes=upstream_node_models, + outputs=entity.output_bindings, + ) + + admin_wf = admin_workflow_models.WorkflowSpec(template=wf_t, sub_workflows=[]) + cache[entity] = admin_wf + return admin_wf diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py new file mode 100644 index 00000000..3c62fcd2 --- /dev/null +++ b/latch_cli/snakemake/workflow.py @@ -0,0 +1,469 @@ +import importlib +import textwrap +import typing +from collections import OrderedDict +from pathlib import Path +from typing import Any, Callable, Dict, List, Optional, Type, TypeVar + +import snakemake +from flytekit import LaunchPlan +from flytekit.configuration import Image, ImageConfig, SerializationSettings +from flytekit.core import constants as _common_constants +from flytekit.core.class_based_resolver import ClassStorageTaskResolver +from flytekit.core.docstring import Docstring +from flytekit.core.interface import Interface, transform_interface_to_typed_interface +from flytekit.core.node import Node +from flytekit.core.promise import NodeOutput, Promise +from flytekit.core.python_auto_container import ( + DefaultTaskResolver, + PythonAutoContainerTask, +) +from flytekit.core.python_function_task import PythonFunctionTask +from flytekit.core.type_engine import TypeEngine +from flytekit.core.utils import _dnsify +from flytekit.core.workflow import ( + WorkflowBase, + WorkflowMetadata, + WorkflowMetadataDefaults, +) +from flytekit.exceptions import scopes as exception_scopes +from flytekit.models import interface as interface_models +from flytekit.models import literals as literals_models +from flytekit.models import types as type_models +from snakemake.dag import DAG +from snakemake.executors import RealExecutor +from snakemake.persistence import Persistence +from snakemake.resources import DefaultResources, ResourceScopes, parse_resources +from snakemake.rules import Rule +from snakemake.target_jobs import encode_target_jobs_cli_args +from snakemake.workflow import Workflow + +from latch.types import LatchAuthor, LatchFile, LatchMetadata, LatchParameter + +T = TypeVar("T") + + +def variable_name_for_target_file(name: str): + + return name.replace("/", "_").replace(".", "_") + + +def snakemake_dag_to_interface( + dag: DAG, docstring: Optional[Docstring] = None +) -> Interface: + + outputs: Dict[str, Type] = {} + + for target in dag.targetjobs: + if type(target.input) == snakemake.io.InputFiles: + for x in target.input: + outputs[variable_name_for_target_file(x.file)] = LatchFile + else: + raise ValueError(f"Unsupported snakemake input type {type(target.input)}") + + inputs: Dict[str, Type] = {} + for job in dag.jobs: + dep_outputs = [] + for dep, dep_files in dag.dependencies[job].items(): + for o in dep.output: + if o in dep_files: + dep_outputs.append(o) + + for x in job.input: + if x not in dep_outputs: + inputs[variable_name_for_target_file(x.file)] = (LatchFile, None) + + return Interface(inputs, outputs, docstring=docstring) + + +def binding_data_from_python( + expected_literal_type: type_models.LiteralType, + t_value: typing.Any, + t_value_type: Optional[type] = None, +) -> literals_models.BindingData: + + if isinstance(t_value, Promise): + if not t_value.is_ready: + return literals_models.BindingData(promise=t_value.ref) + + +def binding_from_python( + var_name: str, + expected_literal_type: type_models.LiteralType, + t_value: typing.Any, + t_value_type: type, +) -> literals_models.Binding: + binding_data = binding_data_from_python( + expected_literal_type, t_value, t_value_type + ) + return literals_models.Binding(var=var_name, binding=binding_data) + + +def transform_type(x: type, description: str = None) -> interface_models.Variable: + return interface_models.Variable( + type=TypeEngine.to_literal_type(x), description=description + ) + + +def transform_types_in_variable_map( + variable_map: Dict[str, type], + descriptions: Dict[str, str] = {}, +) -> Dict[str, interface_models.Variable]: + res = OrderedDict() + if variable_map: + for k, v in variable_map.items(): + res[k] = transform_type(v, descriptions.get(k, k)) + return res + + +def interface_to_parameters( + interface: Interface, +) -> interface_models.ParameterMap: + if interface is None or interface.inputs_with_defaults is None: + return interface_models.ParameterMap({}) + if interface.docstring is None: + inputs_vars = transform_types_in_variable_map(interface.inputs) + else: + inputs_vars = transform_types_in_variable_map( + interface.inputs, interface.docstring.input_descriptions + ) + params = {} + inputs_with_def = interface.inputs_with_defaults + for k, v in inputs_vars.items(): + val, _default = inputs_with_def[k] + required = _default is None + default_lv = None + if _default is not None: + default_lv = TypeEngine.to_literal( + None, _default, python_type=interface.inputs[k], expected=v.type + ) + params[k] = interface_models.Parameter( + var=v, default=default_lv, required=required + ) + return interface_models.ParameterMap(params) + + +class SnakemakeWorkflow(WorkflowBase, ClassStorageTaskResolver): + def __init__( + self, + name: str, + dag: DAG, + metadata: Optional[WorkflowMetadata], + default_metadata: Optional[WorkflowMetadataDefaults], + ): + + parameter_metadata = {} + for job in dag.jobs: + for x in job.input: + var = variable_name_for_target_file(x.file) + parameter_metadata[var] = LatchParameter(display_name=var) + + latch_metadata = LatchMetadata( + display_name=name, + documentation="", + author=LatchAuthor( + name="", + email="", + github="", + ), + repository="", + license="", + parameters=parameter_metadata, + tags=[], + ) + docstring = Docstring(f"{name}\n\nSample Description\n\n" + str(latch_metadata)) + + native_interface = snakemake_dag_to_interface(dag, docstring) + + self._input_parameters = None + self._dag = dag + + super().__init__( + name=name, + workflow_metadata=metadata, + workflow_metadata_defaults=default_metadata, + python_interface=native_interface, + ) + + def compile(self, **kwargs): + + self._input_parameters = interface_to_parameters(self.python_interface) + + GLOBAL_START_NODE = Node( + id=_common_constants.GLOBAL_INPUT_NODE_ID, + metadata=None, + bindings=[], + upstream_nodes=[], + flyte_entity=None, + ) + + entrypoint_code_block = textwrap.dedent( + """\ + import subprocess + from pathlib import Path + from typing import NamedTuple + + from latch import small_task + from latch.types import LatchFile + + def ensure_parents_exist(path: Path): + path.parent.mkdir(parents=True, exist_ok=True) + return path + """ + ) + + node_map = {} + + target_files = [x for job in self._dag.targetjobs for x in job.input] + + for layer in self._dag.toposorted(): + for job in layer: + + is_target = False + + if job in self._dag.targetjobs: + continue + + target_file_for_param: Dict[str, str] = {} + + python_outputs: Dict[str, Type] = {} + for x in job.output: + if x.file in target_files: + is_target = True + param = variable_name_for_target_file(x.file) + target_file_for_param[param] = x.file + python_outputs[param] = LatchFile + + dep_outputs = {} + for dep, dep_files in self._dag.dependencies[job].items(): + for o in dep.output: + if o in dep_files: + dep_outputs[o] = dep.jobid + + python_inputs: Dict[str, Type] = {} + promise_map: Dict[str, str] = {} + for x in job.input: + param = variable_name_for_target_file(x.file) + target_file_for_param[param] = x.file + python_inputs[param] = LatchFile + if x in dep_outputs: + promise_map[param] = dep_outputs[x] + + interface = Interface(python_inputs, python_outputs, docstring=None) + task = SnakemakeJobTask( + job=job, + inputs=python_inputs, + outputs=python_outputs, + target_file_for_param=target_file_for_param, + is_target=is_target, + interface=interface, + ) + entrypoint_code_block += task.get_fn_code() + + typed_interface = transform_interface_to_typed_interface(interface) + + self.interface.inputs.keys() + bindings = [] + for k in sorted(interface.inputs): + + var = typed_interface.inputs[k] + if var.description in promise_map: + promise_to_bind = Promise( + var=k, + val=NodeOutput( + node=node_map[promise_map[var.description]], + var=var.description, + ), + ) + else: + promise_to_bind = Promise( + var=k, + val=NodeOutput(node=GLOBAL_START_NODE, var=k), + ) + bindings.append( + binding_from_python( + var_name=k, + expected_literal_type=var.type, + t_value=promise_to_bind, + t_value_type=interface.inputs[k], + ) + ) + + upstream_nodes = [] + for x in self._dag.dependencies[job].keys(): + if x.jobid in node_map: + upstream_nodes.append(node_map[x.jobid]) + + node = Node( + id=str(job.jobid), + metadata=task.construct_node_metadata(), + bindings=sorted(bindings, key=lambda b: b.var), + upstream_nodes=upstream_nodes, + flyte_entity=task, + ) + node_map[job.jobid] = node + + bindings = [] + output_names = list(self.interface.outputs.keys()) + for i, out in enumerate(output_names): + + def find_upstream_node(): + for j in self._dag.targetjobs: + for depen, files in self._dag.dependencies[j].items(): + for f in files: + if variable_name_for_target_file(f) == out: + return depen.jobid, variable_name_for_target_file(f) + + upstream_id, upstream_var = find_upstream_node() + promise_to_bind = Promise( + var=out, + val=NodeOutput(node=node_map[upstream_id], var=upstream_var), + ) + t = self.python_interface.outputs[out] + b = binding_from_python( + out, + self.interface.outputs[out].type, + promise_to_bind, + t, + ) + bindings.append(b) + + self._nodes = list(node_map.values()) + self._output_bindings = bindings + + with open("latch_entrypoint.py", "w") as f: + f.write(entrypoint_code_block) + + def execute(self, **kwargs): + return exception_scopes.user_entry_point(self._workflow_function)(**kwargs) + + +class SnakemakeJobTask(PythonAutoContainerTask[T]): + def __init__( + self, + job: snakemake.jobs.Job, + inputs: Dict[str, Type], + outputs: Dict[str, Type], + target_file_for_param: Dict[str, str], + is_target: bool, + interface: Interface, + task_type="python-task", + ): + + name = f"{job.name}_{job.jobid}" + + self.job = job + self._is_target = is_target + self._python_inputs = inputs + self._python_outputs = outputs + self._target_file_for_param = target_file_for_param + + def placeholder(): + ... + + self._task_function = placeholder + + super().__init__( + task_type=task_type, + name=name, + interface=interface, + task_config=None, + task_resolver=SnakemakeJobTaskResolver(), + ) + + def get_fn_code(self, wf): + + code_block = "" + + fn_interface = f"\n\n@small_task\ndef {self.name}(" + for idx, (param, t) in enumerate(self._python_inputs.items()): + fn_interface += f"{param}: {t.__name__}" + if idx == len(self._python_inputs) - 1: + fn_interface += ")" + else: + fn_interface += ", " + + if len(self._python_outputs.items()) > 0: + for idx, (param, t) in enumerate(self._python_outputs.items()): + if idx == 0: + fn_interface += f" -> NamedTuple('{self.name}_output', " + fn_interface += f"{param}={t.__name__}" + if idx == len(self._python_outputs) - 1: + fn_interface += "):" + else: + fn_interface += ", " + else: + fn_interface += ":" + + code_block += fn_interface + + for param, t in self._python_inputs.items(): + if t == LatchFile: + code_block += f'\n\tPath({param}).resolve().rename(ensure_parents_exist(Path("{self._target_file_for_param[param]}")))' + + executor = RealExecutor(wf, self._dag) + executor.cores = 8 + snakemake_cmd = ["snakemake", *executor.get_job_args(self.job).split(" ")] + snakemake_cmd.remove("") + formatted_snakemake_cmd = "\n\n\tsubprocess.run([" + + for i, arg in enumerate(snakemake_cmd): + arg_wo_quotes = arg.strip('"').strip("'") + formatted_snakemake_cmd += f'"{arg_wo_quotes}"' + if i == len(snakemake_cmd) - 1: + formatted_snakemake_cmd += "], check=True)" + else: + formatted_snakemake_cmd += ", " + code_block += formatted_snakemake_cmd + + return_stmt = "\n\treturn (" + for i, x in enumerate(self._python_outputs): + if self._is_target: + return_stmt += ( + f"LatchFile('{self._target_file_for_param[x]}'," + f" 'latch:///{self._target_file_for_param[x]}')" + ) + else: + return_stmt += f"LatchFile('{self._target_file_for_param[x]}')" + if i == len(self._python_outputs) - 1: + return_stmt += ")" + else: + return_stmt += ", " + code_block += return_stmt + return code_block + + @property + def dockerfile_path(self) -> Path: + return self._dockerfile_path + + @property + def task_function(self): + return self._task_function + + def execute(self, **kwargs) -> Any: + """ + This method will be invoked to execute the task. If you do decide to override this method you must also + handle dynamic tasks or you will no longer be able to use the task as a dynamic task generator. + """ + return exception_scopes.user_entry_point(self._task_function)(**kwargs) + + +class SnakemakeJobTaskResolver(DefaultTaskResolver): + @property + def location(self) -> str: + + return "flytekit.core.python_auto_container.default_task_resolver" + + def loader_args( + self, settings: SerializationSettings, task: SnakemakeJobTask + ) -> List[str]: + return ["task-module", "latch_entrypoint", "task-name", task.name] + + def load_task(self, loader_args: List[str]) -> PythonAutoContainerTask: + + _, task_module, _, task_name, *_ = loader_args + + task_module = importlib.import_module(task_module) + + task_def = getattr(task_module, task_name) + return task_def From e4e8013773e8de9d849cbb8b206697df9f351979 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Sat, 20 May 2023 20:47:42 -0700 Subject: [PATCH 005/356] rename enum members, snakemake version --- latch_cli/centromere/ctx.py | 6 +++--- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/services/register/utils.py | 2 +- latch_cli/services/serialize.py | 16 ++-------------- latch_cli/snakemake/workflow.py | 11 +++++++---- latch_cli/utils.py | 4 ++-- 6 files changed, 16 insertions(+), 25 deletions(-) diff --git a/latch_cli/centromere/ctx.py b/latch_cli/centromere/ctx.py index 6823c2d9..7b364650 100644 --- a/latch_cli/centromere/ctx.py +++ b/latch_cli/centromere/ctx.py @@ -108,13 +108,13 @@ def __init__( self.pkg_root.joinpath("Snakefile").exists() and not self.pkg_root.joinpath("wf").exists() ): - self.workflow_type = WorkflowType.snakemake + self.workflow_type = WorkflowType.SNAKEMAKE else: - self.workflow_type = WorkflowType.latchbiosdk + self.workflow_type = WorkflowType.LATCHBIOSDK # We do not support per task containers for snakemake rn self.container_map = {} - if self.workflow_type == WorkflowType.latchbiosdk: + if self.workflow_type == WorkflowType.LATCHBIOSDK: _import_flyte_objects([self.pkg_root]) for entity in FlyteEntities.entities: if isinstance(entity, PythonFunctionWorkflow): diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index b30d6ebb..5bf992ca 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -43,7 +43,7 @@ def get_prologue(config: LatchWorkflowConfig) -> List[str]: ] -def get_epilogue(wf_type: WorkflowType = WorkflowType.latchbiosdk) -> List[str]: +def get_epilogue(wf_type: WorkflowType = WorkflowType.LATCHBIOSDK) -> List[str]: cmds = [ ( "# latch internal tagging system + expected root directory --- changing" diff --git a/latch_cli/services/register/utils.py b/latch_cli/services/register/utils.py index 896d962e..b6004ceb 100644 --- a/latch_cli/services/register/utils.py +++ b/latch_cli/services/register/utils.py @@ -84,7 +84,7 @@ def serialize_pkg_in_container( ) -> List[str]: _serialize_cmd = ["make"] - if ctx.workflow_type == WorkflowType.latchbiosdk: + if ctx.workflow_type == WorkflowType.LATCHBIOSDK: _serialize_cmd.append("serialize") else: _serialize_cmd.append("snakemake-serialize") diff --git a/latch_cli/services/serialize.py b/latch_cli/services/serialize.py index 89d93ea0..c1be4b86 100644 --- a/latch_cli/services/serialize.py +++ b/latch_cli/services/serialize.py @@ -5,11 +5,6 @@ from flytekit import LaunchPlan from flytekit.configuration import Image, ImageConfig, SerializationSettings -from flytekit.core.workflow import ( - WorkflowFailurePolicy, - WorkflowMetadata, - WorkflowMetadataDefaults, -) from flytekit.models import launch_plan as launch_plan_models from flytekit.models import literals as literals_models from flytekit.models import task as task_models @@ -98,7 +93,7 @@ def files(items): dag.update_checkpoint_dependencies() dag.check_dynamic() - return self, dag + return dag def serialize(pkg_root: Path): @@ -116,19 +111,12 @@ def serialize(pkg_root: Path): snakefile, overwrite_default_target=True, ) - _, dag = workflow.extract() + dag = workflow.extract() wf_name = "snakemake_wf" - metadata = WorkflowMetadata(on_failure=WorkflowFailurePolicy.FAIL_IMMEDIATELY) - - interruptible = False - workflow_metadata_defaults = WorkflowMetadataDefaults(interruptible) - wf = SnakemakeWorkflow( wf_name, dag, - metadata=metadata, - default_metadata=workflow_metadata_defaults, ) wf.compile() diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 3c62fcd2..dba5e821 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -23,6 +23,7 @@ from flytekit.core.utils import _dnsify from flytekit.core.workflow import ( WorkflowBase, + WorkflowFailurePolicy, WorkflowMetadata, WorkflowMetadataDefaults, ) @@ -148,8 +149,6 @@ def __init__( self, name: str, dag: DAG, - metadata: Optional[WorkflowMetadata], - default_metadata: Optional[WorkflowMetadataDefaults], ): parameter_metadata = {} @@ -178,10 +177,14 @@ def __init__( self._input_parameters = None self._dag = dag + workflow_metadata = WorkflowMetadata( + on_failure=WorkflowFailurePolicy.FAIL_IMMEDIATELY + ) + workflow_metadata_defaults = WorkflowMetadataDefaults(False) super().__init__( name=name, - workflow_metadata=metadata, - workflow_metadata_defaults=default_metadata, + workflow_metadata=workflow_metadata, + workflow_metadata_defaults=workflow_metadata_defaults, python_interface=native_interface, ) diff --git a/latch_cli/utils.py b/latch_cli/utils.py index 99fe94be..83a98eb3 100644 --- a/latch_cli/utils.py +++ b/latch_cli/utils.py @@ -293,5 +293,5 @@ def __exit__(self, type, value, traceback): class WorkflowType(Enum): - latchbiosdk = "latchbiosdk" - snakemake = "snakemake" + LATCHBIOSDK = "latchbiosdk" + SNAKEMAKE = "snakemake" From 6d1f3bbd0c3248cc93892614cbf3108ba2804e25 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Sat, 24 Jun 2023 14:28:27 -0700 Subject: [PATCH 006/356] rebase conflicts --- setup.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup.py b/setup.py index b86d1eff..a972e6ac 100644 --- a/setup.py +++ b/setup.py @@ -25,6 +25,8 @@ ] }, install_requires=[ + "asyncssh==2.12.0", + "aioconsole==0.5.1", "kubernetes>=24.2.0", "pyjwt>=0.2.0", "requests>=2.28.1", From 22f375f7e0477264ac3a6928483ad932f1605450 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Sat, 24 Jun 2023 14:29:08 -0700 Subject: [PATCH 007/356] rebase conflicts --- latch_cli/centromere/ctx.py | 17 ++- latch_cli/main.py | 32 ++++-- latch_cli/services/register/register.py | 12 ++- latch_cli/services/serialize.py | 137 +++++++++++++++--------- latch_cli/snakemake/serialize_utils.py | 6 +- latch_cli/snakemake/workflow.py | 26 +---- 6 files changed, 143 insertions(+), 87 deletions(-) diff --git a/latch_cli/centromere/ctx.py b/latch_cli/centromere/ctx.py index 7b364650..0b18cc37 100644 --- a/latch_cli/centromere/ctx.py +++ b/latch_cli/centromere/ctx.py @@ -85,7 +85,14 @@ def __init__( token: Optional[str] = None, disable_auto_version: bool = False, remote: bool = False, + no_register: bool = False, ): + """ + Params: + no_register: If True, do not perform a version check or create + docker/ssh clients. Used when serializing file. Used when + serializing files. + """ try: if token is None: self.token = retrieve_or_login() @@ -150,8 +157,11 @@ def __init__( hash = hash_directory(self.pkg_root) self.version = self.version + "-" + hash[:6] - if self.nucleus_check_version(self.version, self.workflow_name) is True: - raise ValueError(f"Version {self.version} has already been registered.") + if not no_register: + if self.nucleus_check_version(self.version, self.workflow_name) is True: + raise ValueError( + f"Version {self.version} has already been registered." + ) default_dockerfile = get_default_dockerfile( self.pkg_root, self.workflow_type @@ -162,7 +172,8 @@ def __init__( pkg_dir=self.pkg_root, ) - if remote is True: + if no_register is False and remote is True: + # todo(maximsmol): connect only AFTER confirming registration self.ssh_key_path = Path(self.pkg_root) / latch_constants.pkg_ssh_key self.jump_key_path = Path(self.pkg_root) / latch_constants.pkg_jump_key self.public_key = generate_temporary_ssh_credentials(self.ssh_key_path) diff --git a/latch_cli/main.py b/latch_cli/main.py index 62d86aec..fa4c0aea 100644 --- a/latch_cli/main.py +++ b/latch_cli/main.py @@ -43,10 +43,12 @@ def main(): latest_ver = parse_version(get_latest_package_version()) if local_ver < latest_ver: click.secho( - textwrap.dedent(f""" + textwrap.dedent( + f""" WARN: Your local version of latch ({local_ver}) is out of date. This may result in unexpected behavior. Please upgrade to the latest version ({latest_ver}) using `python3 -m pip install --upgrade latch`. - """).strip("\n"), + """ + ).strip("\n"), fg="yellow", ) @@ -124,6 +126,26 @@ def register(pkg_root: str, disable_auto_version: bool, remote: bool, yes: bool) ) +@main.command("serialize") +@click.argument("pkg_root", type=click.Path(exists=True, file_okay=False)) +@click.argument("output_dir", type=click.Path(exists=True, file_okay=False)) +def serialize(pkg_root: str, output_dir: Path): + """Serializes workflow code into lyteidl protobuf. + + Designed to be used internally by `latch register`. May behave strangely + if used directly. + + Visit docs.latch.bio to learn more. + """ + + crash_handler.message = f"Unable to serialize workflow in {pkg_root}." + crash_handler.pkg_root = pkg_root + + from latch_cli.services.serialize import serialize + + serialize(pkg_root, output_dir) + + @main.command("develop") @click.argument("pkg_root", nargs=1, type=click.Path(exists=True, path_type=Path)) @click.option( @@ -445,10 +467,8 @@ def get_params(wf_name: Union[str, None], version: Union[str, None] = None): if version is None: version = "latest" click.secho( - ( - f"Successfully generated python param map named {wf_name}.params.py with" - f" version {version}\n Run `latch launch {wf_name}.params.py` to launch it." - ), + f"Successfully generated python param map named {wf_name}.params.py with" + f" version {version}\n Run `latch launch {wf_name}.params.py` to launch it.", fg="green", ) diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index b18e4851..300a5f92 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -20,7 +20,12 @@ serialize_pkg_in_container, upload_image, ) -from latch_cli.utils import current_workspace +from latch_cli.services.serialize import ( + extract_snakemake_workflow, + generate_snakemake_entrypoint, + get_snakefile, +) +from latch_cli.utils import WorkflowType, current_workspace from ..workspace import _get_workspaces @@ -156,6 +161,11 @@ def build_and_serialize( ): """Builds an image, serializes the workflow within the image, and pushes the image.""" + if ctx.workflow_type == WorkflowType.SNAKEMAKE: + snakefile = get_snakefile(ctx.pkg_root) + _, wf = extract_snakemake_workflow(snakefile) + generate_snakemake_entrypoint(wf, ctx) + image_build_logs = build_image(ctx, image_name, context_path, dockerfile) print_and_write_build_logs(image_build_logs, image_name, ctx.pkg_root) diff --git a/latch_cli/services/serialize.py b/latch_cli/services/serialize.py index c1be4b86..d8cccd33 100644 --- a/latch_cli/services/serialize.py +++ b/latch_cli/services/serialize.py @@ -2,6 +2,7 @@ import textwrap from itertools import chain, filterfalse from pathlib import Path +from typing import List, Union from flytekit import LaunchPlan from flytekit.configuration import Image, ImageConfig, SerializationSettings @@ -12,15 +13,34 @@ from flytekit.tools.serialize_helpers import persist_registrable_entities from snakemake.common import ON_WINDOWS from snakemake.dag import DAG +from snakemake.executors import RealExecutor from snakemake.persistence import Persistence from snakemake.rules import Rule from snakemake.workflow import Workflow +from latch_cli.centromere.ctx import _CentromereCtx from latch_cli.snakemake.serialize_utils import ( get_serializable_launch_plan, get_serializable_workflow, ) -from latch_cli.workflow import SnakemakeWorkflow, transform_inputs_to_parameters +from latch_cli.snakemake.workflow import SnakemakeWorkflow, interface_to_parameters + +RegistrableEntity = Union[ + task_models.TaskSpec, + launch_plan_models.LaunchPlan, + admin_workflow_models.WorkflowSpec, +] + + +def should_register_with_admin(entity) -> bool: + return isinstance( + entity, + ( + task_models.TaskSpec, + launch_plan_models.LaunchPlan, + admin_workflow_models.WorkflowSpec, + ), + ) class SnakemakeWorkflowExtractor(Workflow): @@ -96,14 +116,8 @@ def files(items): return dag -def serialize(pkg_root: Path): - """Serializes workflow code into lyteidl protobuf. +def extract_snakemake_workflow(snakefile: Path) -> (str, SnakemakeWorkflow): - Args: - pkg_root: The directory of project with workflow code to be serialized - """ - - snakefile = Path("Snakemake") workflow = SnakemakeWorkflowExtractor( snakefile=snakefile, ) @@ -119,47 +133,62 @@ def serialize(pkg_root: Path): dag, ) wf.compile() + return wf_name, wf - default_img = Image( - name=wf_name, - fqn=f"812206152185.dkr.ecr.us-west-2.amazonaws.com/{wf_name}", - tag="", - ) - settings = SerializationSettings( - project="", - domain="", - version="", - env={}, - image_config=ImageConfig(default_image=default_img, images=[default_img]), - ) - registrable_entity_cache = {} +def get_snakefile(pkg_root: Path) -> Path: + return Path("Snakefile") - get_serializable_workflow(wf, settings, registrable_entity_cache) - parameter_map = transform_inputs_to_parameters(wf.python_interface) - lp = LaunchPlan( - name=wf.name, - workflow=wf, - parameters=parameter_map, - fixed_inputs=literals_models.LiteralMap(literals={}), - ) - admin_lp = get_serializable_launch_plan(settings, lp, registrable_entity_cache) +def serialize(pkg_root: Path, output_dir: Path): + """Serializes workflow code into lyteidl protobuf. - new_api_model_values = list(registrable_entity_cache.values()) - entities_to_be_serialized = [ - x.to_flyte_idl() - for x in list(filter(should_register_with_admin, new_api_model_values)) - + [admin_lp] - ] + Args: + pkg_root: The directory of project with workflow code to be serialized + output_dir: The directory where generated protobuf will go + """ - persist_registrable_entities(entities_to_be_serialized, "/tmp") + pkg_root = Path(pkg_root).resolve() + snakefile = get_snakefile(pkg_root) + with _CentromereCtx(pkg_root, no_register=True) as ctx: - entrypoint = Path("latch_entrypoint.py") - generate_snakemake_entrypoint(snakefile, entrypoint) + wf_name, wf = extract_snakemake_workflow(snakefile) + + default_img = Image( + name=wf_name, + fqn=f"{ctx.dkr_repo}/{wf_name}", + tag=ctx.version, + ) + settings = SerializationSettings( + image_config=ImageConfig(default_image=default_img, images=[default_img]), + ) + registrable_entity_cache = {} -def generate_snakemake_entrypoint(snakefile: Path, entrypoint: Path): + get_serializable_workflow(wf, settings, registrable_entity_cache) + + parameter_map = interface_to_parameters(wf.python_interface) + lp = LaunchPlan( + name=wf.name, + workflow=wf, + parameters=parameter_map, + fixed_inputs=literals_models.LiteralMap(literals={}), + ) + admin_lp = get_serializable_launch_plan(settings, lp, registrable_entity_cache) + + registrable_entities = [ + x.to_flyte_idl() + for x in list( + filter( + should_register_with_admin, list(registrable_entity_cache.values()) + ) + ) + + [admin_lp] + ] + persist_registrable_entities(registrable_entities, output_dir) + + +def generate_snakemake_entrypoint(wf: SnakemakeWorkflow, ctx: _CentromereCtx): entrypoint_code_block = textwrap.dedent( """\ @@ -175,17 +204,23 @@ def ensure_parents_exist(path: Path): return path """ ) + entrypoint = ctx.pkg_root.joinpath(".latch/latch_entrypoint.py") + snakefile = get_snakefile(ctx.pkg_root) - with open(entrypoint, "w") as f: - f.write(entrypoint_code_block) + # TODO - pull out what we need from RealExecutor + workflow = SnakemakeWorkflowExtractor( + snakefile=snakefile, + ) + workflow.include( + snakefile, + overwrite_default_target=True, + ) + dag = workflow.extract() + executor = RealExecutor(workflow, dag) + executor.cores = 8 + for task in wf.snakemake_tasks: + entrypoint_code_block += task.get_fn_code(executor) -def should_register_with_admin(entity) -> bool: - return isinstance( - entity, - ( - task_models.TaskSpec, - launch_plan_models.LaunchPlan, - admin_workflow_models.WorkflowSpec, - ), - ) + with open(entrypoint, "w") as f: + f.write(entrypoint_code_block) diff --git a/latch_cli/snakemake/serialize_utils.py b/latch_cli/snakemake/serialize_utils.py index 6fec4b85..3f7588b9 100644 --- a/latch_cli/snakemake/serialize_utils.py +++ b/latch_cli/snakemake/serialize_utils.py @@ -137,13 +137,13 @@ def get_serializable_node( raise Exception(f"Node {entity.id} has no flyte entity") upstream_sdk_nodes = [ - get_serializable_node(n, settings) + get_serializable_node(n, settings, cache) for n in entity.upstream_nodes if n.id != common_constants.GLOBAL_INPUT_NODE_ID ] if isinstance(entity.flyte_entity, PythonTask): - task_spec = get_serializable_task(entity.flyte_entity, settings) + task_spec = get_serializable_task(entity.flyte_entity, settings, cache) node_model = workflow_model.Node( id=_dnsify(entity.id), metadata=entity.metadata, @@ -173,7 +173,7 @@ def get_serializable_workflow( return cache[entity] upstream_node_models = [ - get_serializable_node(n, settings) + get_serializable_node(n, settings, cache) for n in entity.nodes if n.id != common_constants.GLOBAL_INPUT_NODE_ID ] diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index dba5e821..59319d75 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -32,7 +32,6 @@ from flytekit.models import literals as literals_models from flytekit.models import types as type_models from snakemake.dag import DAG -from snakemake.executors import RealExecutor from snakemake.persistence import Persistence from snakemake.resources import DefaultResources, ResourceScopes, parse_resources from snakemake.rules import Rule @@ -176,6 +175,7 @@ def __init__( self._input_parameters = None self._dag = dag + self.snakemake_tasks = [] workflow_metadata = WorkflowMetadata( on_failure=WorkflowFailurePolicy.FAIL_IMMEDIATELY @@ -200,21 +200,6 @@ def compile(self, **kwargs): flyte_entity=None, ) - entrypoint_code_block = textwrap.dedent( - """\ - import subprocess - from pathlib import Path - from typing import NamedTuple - - from latch import small_task - from latch.types import LatchFile - - def ensure_parents_exist(path: Path): - path.parent.mkdir(parents=True, exist_ok=True) - return path - """ - ) - node_map = {} target_files = [x for job in self._dag.targetjobs for x in job.input] @@ -261,7 +246,7 @@ def ensure_parents_exist(path: Path): is_target=is_target, interface=interface, ) - entrypoint_code_block += task.get_fn_code() + self.snakemake_tasks.append(task) typed_interface = transform_interface_to_typed_interface(interface) @@ -334,9 +319,6 @@ def find_upstream_node(): self._nodes = list(node_map.values()) self._output_bindings = bindings - with open("latch_entrypoint.py", "w") as f: - f.write(entrypoint_code_block) - def execute(self, **kwargs): return exception_scopes.user_entry_point(self._workflow_function)(**kwargs) @@ -374,7 +356,7 @@ def placeholder(): task_resolver=SnakemakeJobTaskResolver(), ) - def get_fn_code(self, wf): + def get_fn_code(self, executor): code_block = "" @@ -404,8 +386,6 @@ def get_fn_code(self, wf): if t == LatchFile: code_block += f'\n\tPath({param}).resolve().rename(ensure_parents_exist(Path("{self._target_file_for_param[param]}")))' - executor = RealExecutor(wf, self._dag) - executor.cores = 8 snakemake_cmd = ["snakemake", *executor.get_job_args(self.job).split(" ")] snakemake_cmd.remove("") formatted_snakemake_cmd = "\n\n\tsubprocess.run([" From f7c9394b90b2551ad1c4e748d0f10592421c6066 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Sat, 24 Jun 2023 14:30:16 -0700 Subject: [PATCH 008/356] rebase fixes --- latch_cli/centromere/ctx.py | 16 ++----- latch_cli/docker_utils/__init__.py | 4 +- latch_cli/services/register/register.py | 27 ++++++----- latch_cli/services/register/utils.py | 10 ++--- latch_cli/services/serialize.py | 59 ++++++++++++------------- 5 files changed, 52 insertions(+), 64 deletions(-) diff --git a/latch_cli/centromere/ctx.py b/latch_cli/centromere/ctx.py index 0b18cc37..a8967c0f 100644 --- a/latch_cli/centromere/ctx.py +++ b/latch_cli/centromere/ctx.py @@ -85,14 +85,7 @@ def __init__( token: Optional[str] = None, disable_auto_version: bool = False, remote: bool = False, - no_register: bool = False, ): - """ - Params: - no_register: If True, do not perform a version check or create - docker/ssh clients. Used when serializing file. Used when - serializing files. - """ try: if token is None: self.token = retrieve_or_login() @@ -157,11 +150,8 @@ def __init__( hash = hash_directory(self.pkg_root) self.version = self.version + "-" + hash[:6] - if not no_register: - if self.nucleus_check_version(self.version, self.workflow_name) is True: - raise ValueError( - f"Version {self.version} has already been registered." - ) + if self.nucleus_check_version(self.version, self.workflow_name) is True: + raise ValueError(f"Version {self.version} has already been registered.") default_dockerfile = get_default_dockerfile( self.pkg_root, self.workflow_type @@ -172,7 +162,7 @@ def __init__( pkg_dir=self.pkg_root, ) - if no_register is False and remote is True: + if remote is True: # todo(maximsmol): connect only AFTER confirming registration self.ssh_key_path = Path(self.pkg_root) / latch_constants.pkg_ssh_key self.jump_key_path = Path(self.pkg_root) / latch_constants.pkg_jump_key diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 5bf992ca..25ce1739 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -54,7 +54,7 @@ def get_epilogue(wf_type: WorkflowType = WorkflowType.LATCHBIOSDK) -> List[str]: "workdir /root", ] if wf_type == WorkflowType.snakemake: - cmds.insert("copy .latch/latch_entrypoint.py /root/latch_entrypoint.py") + cmds.insert(-1, "copy .latch/latch_entrypoint.py /root/latch_entrypoint.py") return cmds @@ -221,7 +221,7 @@ def generate_dockerfile(pkg_root: Path, outfile: Path, wf_type: WorkflowType) -> ) create_and_write_config(pkg_root) with (pkg_root / latch_constants.pkg_config).open("r") as f: - config: LatchWorkflowConfig = LatchWorkflowConfig(**json.load(f)) + config = LatchWorkflowConfig(**json.load(f)) with outfile.open("w") as f: f.write("\n".join(get_prologue(config)) + "\n\n") diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index 300a5f92..54ef5a2a 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -24,6 +24,7 @@ extract_snakemake_workflow, generate_snakemake_entrypoint, get_snakefile, + serialize, ) from latch_cli.utils import WorkflowType, current_workspace @@ -166,16 +167,21 @@ def build_and_serialize( _, wf = extract_snakemake_workflow(snakefile) generate_snakemake_entrypoint(wf, ctx) - image_build_logs = build_image(ctx, image_name, context_path, dockerfile) - print_and_write_build_logs(image_build_logs, image_name, ctx.pkg_root) + # image_build_logs = build_image(ctx, image_name, context_path, dockerfile) + # print_and_write_build_logs(image_build_logs, image_name, ctx.pkg_root) - serialize_logs, container_id = serialize_pkg_in_container(ctx, image_name, tmp_dir) - print_serialize_logs(serialize_logs, image_name) - exit_status = ctx.dkr_client.wait(container_id) - if exit_status["StatusCode"] != 0: - raise ValueError( - f"Serialization exited with nonzero exit code: {exit_status['Error']}" + if ctx.workflow_type == WorkflowType.LATCHBIOSDK: + serialize_logs, container_id = serialize_pkg_in_container( + ctx, image_name, tmp_dir ) + print_serialize_logs(serialize_logs, image_name) + exit_status = ctx.dkr_client.wait(container_id) + if exit_status["StatusCode"] != 0: + raise ValueError( + f"Serialization exited with nonzero exit code: {exit_status['Error']}" + ) + else: + serialize(ctx.pkg_root, tmp_dir, ctx.dkr_repo, ctx.version) upload_image_logs = upload_image(ctx, image_name) print_upload_logs(upload_image_logs, image_name) @@ -291,7 +297,7 @@ def register( with contextlib.ExitStack() as stack: td = stack.enter_context( _TmpDir( - remote=remote, + remote=ctx.workflow_type == WorkflowType.LATCHBIOSDK and remote, internal_ip=ctx.internal_ip, username=ctx.username, ) @@ -303,9 +309,8 @@ def register( td, dockerfile=ctx.default_container.dockerfile, ) - quit() protos = _recursive_list(td) - if remote: + if ctx.workflow_type == WorkflowType.LATCHBIOSDK and remote: local_td = stack.enter_context(tempfile.TemporaryDirectory()) ssh = _construct_ssh_client(ctx.internal_ip, ctx.username) scp = SCPClient(transport=ssh.get_transport(), sanitize=lambda x: x) diff --git a/latch_cli/services/register/utils.py b/latch_cli/services/register/utils.py index b6004ceb..627d939e 100644 --- a/latch_cli/services/register/utils.py +++ b/latch_cli/services/register/utils.py @@ -1,4 +1,4 @@ -from latch_cli.utils import WorkflowType +from latch_cli.services.serialize import serialize "Utilites for registration." @@ -82,17 +82,13 @@ def upload_image(ctx: _CentromereCtx, image_name: str) -> List[str]: def serialize_pkg_in_container( ctx: _CentromereCtx, image_name: str, serialize_dir: Path ) -> List[str]: - _serialize_cmd = ["make"] - - if ctx.workflow_type == WorkflowType.LATCHBIOSDK: - _serialize_cmd.append("serialize") - else: - _serialize_cmd.append("snakemake-serialize") + _serialize_cmd = ["make", "serialize"] container = ctx.dkr_client.create_container( f"{ctx.dkr_repo}/{image_name}", command=_serialize_cmd, volumes=[str(serialize_dir)], + environment={"LATCH_DKR_REPO": ctx.dkr_repo, "LATCH_VERSION": ctx.version}, host_config=ctx.dkr_client.create_host_config( binds={ str(serialize_dir): { diff --git a/latch_cli/services/serialize.py b/latch_cli/services/serialize.py index d8cccd33..d0296d4f 100644 --- a/latch_cli/services/serialize.py +++ b/latch_cli/services/serialize.py @@ -140,7 +140,7 @@ def get_snakefile(pkg_root: Path) -> Path: return Path("Snakefile") -def serialize(pkg_root: Path, output_dir: Path): +def serialize(pkg_root: Path, output_dir: Path, dkr_repo: str, version: str): """Serializes workflow code into lyteidl protobuf. Args: @@ -150,42 +150,39 @@ def serialize(pkg_root: Path, output_dir: Path): pkg_root = Path(pkg_root).resolve() snakefile = get_snakefile(pkg_root) - with _CentromereCtx(pkg_root, no_register=True) as ctx: - wf_name, wf = extract_snakemake_workflow(snakefile) + wf_name, wf = extract_snakemake_workflow(snakefile) - default_img = Image( - name=wf_name, - fqn=f"{ctx.dkr_repo}/{wf_name}", - tag=ctx.version, - ) - settings = SerializationSettings( - image_config=ImageConfig(default_image=default_img, images=[default_img]), - ) + default_img = Image( + name=wf_name, + fqn=f"{dkr_repo}/{wf_name}", + tag=version, + ) + settings = SerializationSettings( + image_config=ImageConfig(default_image=default_img, images=[default_img]), + ) - registrable_entity_cache = {} + registrable_entity_cache = {} - get_serializable_workflow(wf, settings, registrable_entity_cache) + get_serializable_workflow(wf, settings, registrable_entity_cache) - parameter_map = interface_to_parameters(wf.python_interface) - lp = LaunchPlan( - name=wf.name, - workflow=wf, - parameters=parameter_map, - fixed_inputs=literals_models.LiteralMap(literals={}), + parameter_map = interface_to_parameters(wf.python_interface) + lp = LaunchPlan( + name=wf.name, + workflow=wf, + parameters=parameter_map, + fixed_inputs=literals_models.LiteralMap(literals={}), + ) + admin_lp = get_serializable_launch_plan(settings, lp, registrable_entity_cache) + + registrable_entities = [ + x.to_flyte_idl() + for x in list( + filter(should_register_with_admin, list(registrable_entity_cache.values())) ) - admin_lp = get_serializable_launch_plan(settings, lp, registrable_entity_cache) - - registrable_entities = [ - x.to_flyte_idl() - for x in list( - filter( - should_register_with_admin, list(registrable_entity_cache.values()) - ) - ) - + [admin_lp] - ] - persist_registrable_entities(registrable_entities, output_dir) + + [admin_lp] + ] + persist_registrable_entities(registrable_entities, output_dir) def generate_snakemake_entrypoint(wf: SnakemakeWorkflow, ctx: _CentromereCtx): From f87f22b901e713d4e37fc4fd85e7b7521cb70a61 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Sat, 24 Jun 2023 14:31:17 -0700 Subject: [PATCH 009/356] rebase fixes --- latch_cli/centromere/utils.py | 2 +- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/services/serialize.py | 21 ++------ latch_cli/snakemake/workflow.py | 79 ++++++++++++++++++++---------- 4 files changed, 58 insertions(+), 46 deletions(-) diff --git a/latch_cli/centromere/utils.py b/latch_cli/centromere/utils.py index c8f29b69..e37cda98 100644 --- a/latch_cli/centromere/utils.py +++ b/latch_cli/centromere/utils.py @@ -195,7 +195,7 @@ def get_default_dockerfile(pkg_root: Path, wf_type: WorkflowType): default_dockerfile = pkg_root.joinpath("Dockerfile") if not default_dockerfile.exists(): - generate_dockerfile(pkg_root, pkg_root.joinpath(".latch/Dockerfile")) + generate_dockerfile(pkg_root, pkg_root.joinpath(".latch/Dockerfile"), wf_type) default_dockerfile = pkg_root.joinpath(".latch/Dockerfile") return default_dockerfile diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 25ce1739..92eb6b7f 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -53,7 +53,7 @@ def get_epilogue(wf_type: WorkflowType = WorkflowType.LATCHBIOSDK) -> List[str]: "env FLYTE_INTERNAL_IMAGE $tag", "workdir /root", ] - if wf_type == WorkflowType.snakemake: + if wf_type == WorkflowType.SNAKEMAKE: cmds.insert(-1, "copy .latch/latch_entrypoint.py /root/latch_entrypoint.py") return cmds diff --git a/latch_cli/services/serialize.py b/latch_cli/services/serialize.py index d0296d4f..66efb84b 100644 --- a/latch_cli/services/serialize.py +++ b/latch_cli/services/serialize.py @@ -2,7 +2,7 @@ import textwrap from itertools import chain, filterfalse from pathlib import Path -from typing import List, Union +from typing import Union from flytekit import LaunchPlan from flytekit.configuration import Image, ImageConfig, SerializationSettings @@ -13,7 +13,6 @@ from flytekit.tools.serialize_helpers import persist_registrable_entities from snakemake.common import ON_WINDOWS from snakemake.dag import DAG -from snakemake.executors import RealExecutor from snakemake.persistence import Persistence from snakemake.rules import Rule from snakemake.workflow import Workflow @@ -201,23 +200,9 @@ def ensure_parents_exist(path: Path): return path """ ) - entrypoint = ctx.pkg_root.joinpath(".latch/latch_entrypoint.py") - snakefile = get_snakefile(ctx.pkg_root) - - # TODO - pull out what we need from RealExecutor - workflow = SnakemakeWorkflowExtractor( - snakefile=snakefile, - ) - workflow.include( - snakefile, - overwrite_default_target=True, - ) - dag = workflow.extract() - executor = RealExecutor(workflow, dag) - executor.cores = 8 - for task in wf.snakemake_tasks: - entrypoint_code_block += task.get_fn_code(executor) + entrypoint_code_block += task.get_fn_code() + entrypoint = ctx.pkg_root.joinpath(".latch/latch_entrypoint.py") with open(entrypoint, "w") as f: f.write(entrypoint_code_block) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 59319d75..b0da8166 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1,13 +1,11 @@ import importlib -import textwrap import typing from collections import OrderedDict from pathlib import Path -from typing import Any, Callable, Dict, List, Optional, Type, TypeVar +from typing import Any, Dict, List, Optional, Type, TypeVar, Union import snakemake -from flytekit import LaunchPlan -from flytekit.configuration import Image, ImageConfig, SerializationSettings +from flytekit.configuration import SerializationSettings from flytekit.core import constants as _common_constants from flytekit.core.class_based_resolver import ClassStorageTaskResolver from flytekit.core.docstring import Docstring @@ -18,9 +16,7 @@ DefaultTaskResolver, PythonAutoContainerTask, ) -from flytekit.core.python_function_task import PythonFunctionTask from flytekit.core.type_engine import TypeEngine -from flytekit.core.utils import _dnsify from flytekit.core.workflow import ( WorkflowBase, WorkflowFailurePolicy, @@ -32,20 +28,29 @@ from flytekit.models import literals as literals_models from flytekit.models import types as type_models from snakemake.dag import DAG -from snakemake.persistence import Persistence -from snakemake.resources import DefaultResources, ResourceScopes, parse_resources -from snakemake.rules import Rule from snakemake.target_jobs import encode_target_jobs_cli_args -from snakemake.workflow import Workflow from latch.types import LatchAuthor, LatchFile, LatchMetadata, LatchParameter T = TypeVar("T") -def variable_name_for_target_file(name: str): +SnakemakeInputVal = Union[snakemake.io._IOFile] - return name.replace("/", "_").replace(".", "_") + +def variable_name_for_value( + val: SnakemakeInputVal, + params: Union[snakemake.io.InputFiles, snakemake.io.OutputFiles] = None, +) -> str: + + # TODO cache + + if params: + for name, v in params.items(): + if val == v: + return name + + return val.file.replace("/", "_").replace(".", "_").replace("-", "_") def snakemake_dag_to_interface( @@ -57,7 +62,7 @@ def snakemake_dag_to_interface( for target in dag.targetjobs: if type(target.input) == snakemake.io.InputFiles: for x in target.input: - outputs[variable_name_for_target_file(x.file)] = LatchFile + outputs[variable_name_for_value(x, target.input)] = LatchFile else: raise ValueError(f"Unsupported snakemake input type {type(target.input)}") @@ -71,7 +76,10 @@ def snakemake_dag_to_interface( for x in job.input: if x not in dep_outputs: - inputs[variable_name_for_target_file(x.file)] = (LatchFile, None) + inputs[variable_name_for_value(x, job.input)] = ( + LatchFile, + None, + ) return Interface(inputs, outputs, docstring=docstring) @@ -153,7 +161,7 @@ def __init__( parameter_metadata = {} for job in dag.jobs: for x in job.input: - var = variable_name_for_target_file(x.file) + var = variable_name_for_value(x, job.input) parameter_metadata[var] = LatchParameter(display_name=var) latch_metadata = LatchMetadata( @@ -216,10 +224,10 @@ def compile(self, **kwargs): python_outputs: Dict[str, Type] = {} for x in job.output: - if x.file in target_files: + if x in target_files: is_target = True - param = variable_name_for_target_file(x.file) - target_file_for_param[param] = x.file + param = variable_name_for_value(x, job.output) + target_file_for_param[param] = x python_outputs[param] = LatchFile dep_outputs = {} @@ -231,8 +239,8 @@ def compile(self, **kwargs): python_inputs: Dict[str, Type] = {} promise_map: Dict[str, str] = {} for x in job.input: - param = variable_name_for_target_file(x.file) - target_file_for_param[param] = x.file + param = variable_name_for_value(x, job.input) + target_file_for_param[param] = x python_inputs[param] = LatchFile if x in dep_outputs: promise_map[param] = dep_outputs[x] @@ -249,7 +257,6 @@ def compile(self, **kwargs): self.snakemake_tasks.append(task) typed_interface = transform_interface_to_typed_interface(interface) - self.interface.inputs.keys() bindings = [] for k in sorted(interface.inputs): @@ -299,8 +306,10 @@ def find_upstream_node(): for j in self._dag.targetjobs: for depen, files in self._dag.dependencies[j].items(): for f in files: - if variable_name_for_target_file(f) == out: - return depen.jobid, variable_name_for_target_file(f) + if variable_name_for_value(f) == out: + return depen.jobid, variable_name_for_value( + f, depen.output + ) upstream_id, upstream_var = find_upstream_node() promise_to_bind = Promise( @@ -356,7 +365,7 @@ def placeholder(): task_resolver=SnakemakeJobTaskResolver(), ) - def get_fn_code(self, executor): + def get_fn_code(self): code_block = "" @@ -386,8 +395,26 @@ def get_fn_code(self, executor): if t == LatchFile: code_block += f'\n\tPath({param}).resolve().rename(ensure_parents_exist(Path("{self._target_file_for_param[param]}")))' - snakemake_cmd = ["snakemake", *executor.get_job_args(self.job).split(" ")] - snakemake_cmd.remove("") + snakemake_cmd = ["snakemake"] + snakemake_cmd.extend( + ["--target-jobs", *encode_target_jobs_cli_args(self.job.get_target_spec())] + ) + snakemake_cmd.extend(["--allowed-rules", *self.job.rules]) + snakemake_cmd.extend(["--local-groupid", str(self.job.jobid)]) + snakemake_cmd.extend(["--cores", "8"]) + + if not self.job.is_group(): + snakemake_cmd.append("--force-use-threads") + + excluded = {"_nodes", "_cores", "tmpdir"} + allowed_resources = list( + filter(lambda x: x[0] not in excluded, self.job.resources.items()) + ) + if len(allowed_resources) > 0: + snakemake_cmd.append("--resources") + for resource, value in allowed_resources: + snakemake_cmd.append(f"{resource}={value}") + formatted_snakemake_cmd = "\n\n\tsubprocess.run([" for i, arg in enumerate(snakemake_cmd): From 519f6ba8f070801a0cd0d9d755dd5545e6da9f9e Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Tue, 23 May 2023 16:23:47 -0700 Subject: [PATCH 010/356] woop --- latch_cli/services/register/register.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index 54ef5a2a..42c811cf 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -167,8 +167,8 @@ def build_and_serialize( _, wf = extract_snakemake_workflow(snakefile) generate_snakemake_entrypoint(wf, ctx) - # image_build_logs = build_image(ctx, image_name, context_path, dockerfile) - # print_and_write_build_logs(image_build_logs, image_name, ctx.pkg_root) + image_build_logs = build_image(ctx, image_name, context_path, dockerfile) + print_and_write_build_logs(image_build_logs, image_name, ctx.pkg_root) if ctx.workflow_type == WorkflowType.LATCHBIOSDK: serialize_logs, container_id = serialize_pkg_in_container( From 214db2aa4920462d295c94d48a155a8cf6ae2787 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Tue, 23 May 2023 18:07:29 -0700 Subject: [PATCH 011/356] fix image name --- latch_cli/services/register/register.py | 2 +- latch_cli/services/serialize.py | 10 ++++++---- latch_cli/snakemake/workflow.py | 3 +++ 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index 42c811cf..4aadc6f9 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -181,7 +181,7 @@ def build_and_serialize( f"Serialization exited with nonzero exit code: {exit_status['Error']}" ) else: - serialize(ctx.pkg_root, tmp_dir, ctx.dkr_repo, ctx.version) + serialize(ctx.pkg_root, tmp_dir, image_name, ctx.dkr_repo) upload_image_logs = upload_image(ctx, image_name) print_upload_logs(upload_image_logs, image_name) diff --git a/latch_cli/services/serialize.py b/latch_cli/services/serialize.py index 66efb84b..27fb2524 100644 --- a/latch_cli/services/serialize.py +++ b/latch_cli/services/serialize.py @@ -124,6 +124,7 @@ def extract_snakemake_workflow(snakefile: Path) -> (str, SnakemakeWorkflow): snakefile, overwrite_default_target=True, ) + # TODO - get default parameter and file values from workflow.globals dag = workflow.extract() wf_name = "snakemake_wf" @@ -139,7 +140,7 @@ def get_snakefile(pkg_root: Path) -> Path: return Path("Snakefile") -def serialize(pkg_root: Path, output_dir: Path, dkr_repo: str, version: str): +def serialize(pkg_root: Path, output_dir: Path, image_name: str, dkr_repo: str): """Serializes workflow code into lyteidl protobuf. Args: @@ -150,11 +151,12 @@ def serialize(pkg_root: Path, output_dir: Path, dkr_repo: str, version: str): pkg_root = Path(pkg_root).resolve() snakefile = get_snakefile(pkg_root) - wf_name, wf = extract_snakemake_workflow(snakefile) + _, wf = extract_snakemake_workflow(snakefile) + image_name_no_version, version = image_name.split(":") default_img = Image( - name=wf_name, - fqn=f"{dkr_repo}/{wf_name}", + name=image_name, + fqn=f"{dkr_repo}/{image_name_no_version}", tag=version, ) settings = SerializationSettings( diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index b0da8166..5282a660 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -68,6 +68,7 @@ def snakemake_dag_to_interface( inputs: Dict[str, Type] = {} for job in dag.jobs: + dep_outputs = [] for dep, dep_files in dag.dependencies[job].items(): for o in dep.output: @@ -306,6 +307,8 @@ def find_upstream_node(): for j in self._dag.targetjobs: for depen, files in self._dag.dependencies[j].items(): for f in files: + # TODO - better link than str representation of + # target file if variable_name_for_value(f) == out: return depen.jobid, variable_name_for_value( f, depen.output From 0f63e936d8e4fa4be6abe5a264371538f77097a7 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Sat, 24 Jun 2023 14:32:15 -0700 Subject: [PATCH 012/356] rebase conflicts --- latch_cli/centromere/ctx.py | 10 ++++------ latch_cli/centromere/utils.py | 15 ++++++--------- latch_cli/docker_utils/__init__.py | 17 +++++++++++++++-- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/latch_cli/centromere/ctx.py b/latch_cli/centromere/ctx.py index a8967c0f..d68b7834 100644 --- a/latch_cli/centromere/ctx.py +++ b/latch_cli/centromere/ctx.py @@ -17,14 +17,15 @@ import latch_cli.tinyrequests as tinyrequests from latch_cli.centromere.utils import ( - WorkflowType, _construct_dkr_client, _construct_ssh_client, _import_flyte_objects, - get_default_dockerfile, + is_snakemake_project, ) from latch_cli.constants import latch_constants +from latch_cli.docker_utils import get_default_dockerfile from latch_cli.utils import ( + WorkflowType, account_id_from_token, current_workspace, generate_temporary_ssh_credentials, @@ -104,10 +105,7 @@ def __init__( self.pkg_root = Path(pkg_root).resolve() # TODO (kenny) better rules to auto detect workflow type - if ( - self.pkg_root.joinpath("Snakefile").exists() - and not self.pkg_root.joinpath("wf").exists() - ): + if is_snakemake_project(self.pkg_root): self.workflow_type = WorkflowType.SNAKEMAKE else: self.workflow_type = WorkflowType.LATCHBIOSDK diff --git a/latch_cli/centromere/utils.py b/latch_cli/centromere/utils.py index e37cda98..779b3f98 100644 --- a/latch_cli/centromere/utils.py +++ b/latch_cli/centromere/utils.py @@ -191,15 +191,6 @@ def _construct_ssh_client(internal_ip: str, username: str) -> paramiko.SSHClient return ssh -def get_default_dockerfile(pkg_root: Path, wf_type: WorkflowType): - - default_dockerfile = pkg_root.joinpath("Dockerfile") - if not default_dockerfile.exists(): - generate_dockerfile(pkg_root, pkg_root.joinpath(".latch/Dockerfile"), wf_type) - default_dockerfile = pkg_root.joinpath(".latch/Dockerfile") - return default_dockerfile - - class _TmpDir: """Represents a temporary directory that can be local or on a remote machine.""" @@ -254,3 +245,9 @@ def cleanup(self, *args): elif not (self.internal_ip is None or self.username is None): client = _construct_ssh_client(self.internal_ip, self.username) client.exec_command(f"rm -rf {self._tempdir}") + + +def is_snakemake_project(pkg_root: Path) -> bool: + if pkg_root.joinpath("Snakefile").exists() and not pkg_root.joinpath("wf").exists(): + return True + return False diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 92eb6b7f..ba5dd1f2 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -8,6 +8,7 @@ import yaml +from latch_cli.centromere.utils import is_snakemake_project from latch_cli.constants import latch_constants from latch_cli.utils import WorkflowType from latch_cli.workflow_config import LatchWorkflowConfig, create_and_write_config @@ -191,7 +192,7 @@ def infer_commands(pkg_root: Path) -> List[DockerCmdBlock]: return commands -def generate_dockerfile(pkg_root: Path, outfile: Path, wf_type: WorkflowType) -> None: +def generate_dockerfile(pkg_root: Path, outfile: Path) -> None: """Generate a best effort Dockerfile from files in the workflow directory. Args: @@ -239,6 +240,18 @@ def generate_dockerfile(pkg_root: Path, outfile: Path, wf_type: WorkflowType) -> if block.order == DockerCmdBlockOrder.postcopy: block.write_block(f) - f.write("\n".join(get_epilogue()) + "\n") + wf_type = WorkflowType.LATCHBIOSDK + if is_snakemake_project(pkg_root): + wf_type = WorkflowType.SNAKEMAKE + f.write("\n".join(get_epilogue(wf_type)) + "\n") print("Generated.") + + +def get_default_dockerfile(pkg_root: Path, wf_type: WorkflowType): + + default_dockerfile = pkg_root.joinpath("Dockerfile") + if not default_dockerfile.exists(): + generate_dockerfile(pkg_root, pkg_root.joinpath(".latch/Dockerfile"), wf_type) + default_dockerfile = pkg_root.joinpath(".latch/Dockerfile") + return default_dockerfile From bf4ecfad47620010da29ec02b0f546239d952bf1 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Tue, 23 May 2023 23:22:56 -0700 Subject: [PATCH 013/356] threads --- latch_cli/snakemake/workflow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 5282a660..e459e569 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -404,7 +404,7 @@ def get_fn_code(self): ) snakemake_cmd.extend(["--allowed-rules", *self.job.rules]) snakemake_cmd.extend(["--local-groupid", str(self.job.jobid)]) - snakemake_cmd.extend(["--cores", "8"]) + snakemake_cmd.extend(["--cores", str(self.job.threads)]) if not self.job.is_group(): snakemake_cmd.append("--force-use-threads") From ad15828805723779fc993c58d059f9444b9d2bc6 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Wed, 24 May 2023 23:54:06 -0700 Subject: [PATCH 014/356] different maps for inputs and outputs --- latch_cli/snakemake/workflow.py | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index e459e569..9b68ba63 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -221,14 +221,15 @@ def compile(self, **kwargs): if job in self._dag.targetjobs: continue - target_file_for_param: Dict[str, str] = {} + target_file_for_output_param: Dict[str, str] = {} + target_file_for_input_param: Dict[str, str] = {} python_outputs: Dict[str, Type] = {} for x in job.output: if x in target_files: is_target = True param = variable_name_for_value(x, job.output) - target_file_for_param[param] = x + target_file_for_output_param[param] = x python_outputs[param] = LatchFile dep_outputs = {} @@ -241,7 +242,7 @@ def compile(self, **kwargs): promise_map: Dict[str, str] = {} for x in job.input: param = variable_name_for_value(x, job.input) - target_file_for_param[param] = x + target_file_for_input_param[param] = x python_inputs[param] = LatchFile if x in dep_outputs: promise_map[param] = dep_outputs[x] @@ -251,7 +252,8 @@ def compile(self, **kwargs): job=job, inputs=python_inputs, outputs=python_outputs, - target_file_for_param=target_file_for_param, + target_file_for_input_param=target_file_for_input_param, + target_file_for_output_param=target_file_for_output_param, is_target=is_target, interface=interface, ) @@ -341,7 +343,8 @@ def __init__( job: snakemake.jobs.Job, inputs: Dict[str, Type], outputs: Dict[str, Type], - target_file_for_param: Dict[str, str], + target_file_for_input_param: Dict[str, str], + target_file_for_output_param: Dict[str, str], is_target: bool, interface: Interface, task_type="python-task", @@ -353,7 +356,8 @@ def __init__( self._is_target = is_target self._python_inputs = inputs self._python_outputs = outputs - self._target_file_for_param = target_file_for_param + self._target_file_for_input_param = target_file_for_input_param + self._target_file_for_output_param = target_file_for_output_param def placeholder(): ... @@ -396,7 +400,7 @@ def get_fn_code(self): for param, t in self._python_inputs.items(): if t == LatchFile: - code_block += f'\n\tPath({param}).resolve().rename(ensure_parents_exist(Path("{self._target_file_for_param[param]}")))' + code_block += f'\n\tPath({param}).resolve().rename(ensure_parents_exist(Path("{self._target_file_for_input_param[param]}")))' snakemake_cmd = ["snakemake"] snakemake_cmd.extend( @@ -433,11 +437,11 @@ def get_fn_code(self): for i, x in enumerate(self._python_outputs): if self._is_target: return_stmt += ( - f"LatchFile('{self._target_file_for_param[x]}'," - f" 'latch:///{self._target_file_for_param[x]}')" + f"LatchFile('{self._target_file_for_output_param[x]}'," + f" 'latch:///{self._target_file_for_output_param[x]}')" ) else: - return_stmt += f"LatchFile('{self._target_file_for_param[x]}')" + return_stmt += f"LatchFile('{self._target_file_for_output_param[x]}')" if i == len(self._python_outputs) - 1: return_stmt += ")" else: From 46523e46cc9c6e7a4ed55ab162eaa80f8f0f4b7d Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Sat, 24 Jun 2023 14:33:02 -0700 Subject: [PATCH 015/356] rebase conflict --- latch_cli/centromere/ctx.py | 11 ++++---- latch_cli/docker_utils/__init__.py | 8 +++--- latch_cli/main.py | 36 +++++++++++-------------- latch_cli/services/register/register.py | 15 +++++++---- latch_cli/services/register/utils.py | 3 +-- latch_cli/services/serialize.py | 24 +++++++---------- latch_cli/snakemake/workflow.py | 30 ++++++++------------- 7 files changed, 55 insertions(+), 72 deletions(-) diff --git a/latch_cli/centromere/ctx.py b/latch_cli/centromere/ctx.py index d68b7834..61f3cbc2 100644 --- a/latch_cli/centromere/ctx.py +++ b/latch_cli/centromere/ctx.py @@ -20,7 +20,6 @@ _construct_dkr_client, _construct_ssh_client, _import_flyte_objects, - is_snakemake_project, ) from latch_cli.constants import latch_constants from latch_cli.docker_utils import get_default_dockerfile @@ -66,6 +65,7 @@ class _CentromereCtx: container_map: Dict[str, _Container] workflow_name: Optional[str] workflow_type: WorkflowType + snakefile: Optional[Path] latch_register_api_url = config.api.workflow.register latch_image_api_url = config.api.workflow.upload_image @@ -86,6 +86,7 @@ def __init__( token: Optional[str] = None, disable_auto_version: bool = False, remote: bool = False, + snakefile: Path = None, ): try: if token is None: @@ -104,11 +105,11 @@ def __init__( self.disable_auto_version = disable_auto_version self.pkg_root = Path(pkg_root).resolve() - # TODO (kenny) better rules to auto detect workflow type - if is_snakemake_project(self.pkg_root): - self.workflow_type = WorkflowType.SNAKEMAKE - else: + if snakefile is None: self.workflow_type = WorkflowType.LATCHBIOSDK + else: + self.workflow_type = WorkflowType.SNAKEMAKE + self.snakefile = snakefile # We do not support per task containers for snakemake rn self.container_map = {} diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index ba5dd1f2..51eec600 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -8,7 +8,6 @@ import yaml -from latch_cli.centromere.utils import is_snakemake_project from latch_cli.constants import latch_constants from latch_cli.utils import WorkflowType from latch_cli.workflow_config import LatchWorkflowConfig, create_and_write_config @@ -192,7 +191,9 @@ def infer_commands(pkg_root: Path) -> List[DockerCmdBlock]: return commands -def generate_dockerfile(pkg_root: Path, outfile: Path) -> None: +def generate_dockerfile( + pkg_root: Path, outfile: Path, wf_type: WorkflowType = WorkflowType.LATCHBIOSDK +) -> None: """Generate a best effort Dockerfile from files in the workflow directory. Args: @@ -240,9 +241,6 @@ def generate_dockerfile(pkg_root: Path, outfile: Path) -> None: if block.order == DockerCmdBlockOrder.postcopy: block.write_block(f) - wf_type = WorkflowType.LATCHBIOSDK - if is_snakemake_project(pkg_root): - wf_type = WorkflowType.SNAKEMAKE f.write("\n".join(get_epilogue(wf_type)) + "\n") print("Generated.") diff --git a/latch_cli/main.py b/latch_cli/main.py index fa4c0aea..a7f587a0 100644 --- a/latch_cli/main.py +++ b/latch_cli/main.py @@ -107,7 +107,20 @@ def dockerfile(pkg_root: str): type=bool, help="Skip the confirmation dialog.", ) -def register(pkg_root: str, disable_auto_version: bool, remote: bool, yes: bool): +@click.option( + "-s", + "--snakefile", + type=click.Path(exists=True), + default=None, + help="Full path to Snakefile to register.", +) +def register( + pkg_root: str, + disable_auto_version: bool, + remote: bool, + yes: bool, + snakefile: Optional[str], +): """Register local workflow code to Latch. Visit docs.latch.bio to learn more. @@ -123,29 +136,10 @@ def register(pkg_root: str, disable_auto_version: bool, remote: bool, yes: bool) disable_auto_version=disable_auto_version, remote=remote, skip_confirmation=yes, + snakefile=snakefile, ) -@main.command("serialize") -@click.argument("pkg_root", type=click.Path(exists=True, file_okay=False)) -@click.argument("output_dir", type=click.Path(exists=True, file_okay=False)) -def serialize(pkg_root: str, output_dir: Path): - """Serializes workflow code into lyteidl protobuf. - - Designed to be used internally by `latch register`. May behave strangely - if used directly. - - Visit docs.latch.bio to learn more. - """ - - crash_handler.message = f"Unable to serialize workflow in {pkg_root}." - crash_handler.pkg_root = pkg_root - - from latch_cli.services.serialize import serialize - - serialize(pkg_root, output_dir) - - @main.command("develop") @click.argument("pkg_root", nargs=1, type=click.Path(exists=True, path_type=Path)) @click.option( diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index 4aadc6f9..23103229 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -23,8 +23,7 @@ from latch_cli.services.serialize import ( extract_snakemake_workflow, generate_snakemake_entrypoint, - get_snakefile, - serialize, + serialize_snakemake, ) from latch_cli.utils import WorkflowType, current_workspace @@ -163,8 +162,7 @@ def build_and_serialize( """Builds an image, serializes the workflow within the image, and pushes the image.""" if ctx.workflow_type == WorkflowType.SNAKEMAKE: - snakefile = get_snakefile(ctx.pkg_root) - _, wf = extract_snakemake_workflow(snakefile) + _, wf = extract_snakemake_workflow(ctx.snakefile) generate_snakemake_entrypoint(wf, ctx) image_build_logs = build_image(ctx, image_name, context_path, dockerfile) @@ -181,7 +179,9 @@ def build_and_serialize( f"Serialization exited with nonzero exit code: {exit_status['Error']}" ) else: - serialize(ctx.pkg_root, tmp_dir, image_name, ctx.dkr_repo) + serialize_snakemake( + ctx.pkg_root, ctx.snakefile, tmp_dir, image_name, ctx.dkr_repo + ) upload_image_logs = upload_image(ctx, image_name) print_upload_logs(upload_image_logs, image_name) @@ -200,6 +200,7 @@ def register( disable_auto_version: bool = False, remote: bool = False, skip_confirmation: bool = False, + snakefile: Optional[str] = None, ): """Registers a workflow, defined as python code, with Latch. @@ -247,10 +248,14 @@ def register( """ pkg_root = Path(pkg_root).resolve() + if snakefile: + snakefile = Path(snakefile).resolve() + with _CentromereCtx( pkg_root, disable_auto_version=disable_auto_version, remote=remote, + snakefile=snakefile, ) as ctx: assert ctx.workflow_name is not None, "Unable to determine workflow name" assert ctx.version is not None, "Unable to determine workflow version" diff --git a/latch_cli/services/register/utils.py b/latch_cli/services/register/utils.py index 627d939e..f37657c2 100644 --- a/latch_cli/services/register/utils.py +++ b/latch_cli/services/register/utils.py @@ -1,5 +1,3 @@ -from latch_cli.services.serialize import serialize - "Utilites for registration." import base64 @@ -11,6 +9,7 @@ import requests from latch_cli.centromere.ctx import _CentromereCtx +from latch_cli.services.serialize import serialize_snakemake from latch_cli.utils import current_workspace diff --git a/latch_cli/services/serialize.py b/latch_cli/services/serialize.py index 27fb2524..dd58e04b 100644 --- a/latch_cli/services/serialize.py +++ b/latch_cli/services/serialize.py @@ -2,8 +2,9 @@ import textwrap from itertools import chain, filterfalse from pathlib import Path -from typing import Union +from typing import Optional, Union +import click from flytekit import LaunchPlan from flytekit.configuration import Image, ImageConfig, SerializationSettings from flytekit.models import launch_plan as launch_plan_models @@ -124,7 +125,6 @@ def extract_snakemake_workflow(snakefile: Path) -> (str, SnakemakeWorkflow): snakefile, overwrite_default_target=True, ) - # TODO - get default parameter and file values from workflow.globals dag = workflow.extract() wf_name = "snakemake_wf" @@ -136,21 +136,15 @@ def extract_snakemake_workflow(snakefile: Path) -> (str, SnakemakeWorkflow): return wf_name, wf -def get_snakefile(pkg_root: Path) -> Path: - return Path("Snakefile") - - -def serialize(pkg_root: Path, output_dir: Path, image_name: str, dkr_repo: str): - """Serializes workflow code into lyteidl protobuf. - - Args: - pkg_root: The directory of project with workflow code to be serialized - output_dir: The directory where generated protobuf will go - """ +def serialize_snakemake( + pkg_root: Path, + snakefile: Path, + output_dir: Path, + image_name: str, + dkr_repo: str, +): pkg_root = Path(pkg_root).resolve() - snakefile = get_snakefile(pkg_root) - _, wf = extract_snakemake_workflow(snakefile) image_name_no_version, version = image_name.split(":") diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 9b68ba63..2d97846a 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -32,10 +32,11 @@ from latch.types import LatchAuthor, LatchFile, LatchMetadata, LatchParameter -T = TypeVar("T") +SnakemakeInputVal = Union[snakemake.io._IOFile] -SnakemakeInputVal = Union[snakemake.io._IOFile] +def variable_name_for_file(file: snakemake.io.AnnotatedString): + return file.replace("/", "_").replace(".", "_").replace("-", "_") def variable_name_for_value( @@ -43,14 +44,12 @@ def variable_name_for_value( params: Union[snakemake.io.InputFiles, snakemake.io.OutputFiles] = None, ) -> str: - # TODO cache - if params: for name, v in params.items(): if val == v: return name - return val.file.replace("/", "_").replace(".", "_").replace("-", "_") + return variable_name_for_file(val.file) def snakemake_dag_to_interface( @@ -60,11 +59,8 @@ def snakemake_dag_to_interface( outputs: Dict[str, Type] = {} for target in dag.targetjobs: - if type(target.input) == snakemake.io.InputFiles: - for x in target.input: - outputs[variable_name_for_value(x, target.input)] = LatchFile - else: - raise ValueError(f"Unsupported snakemake input type {type(target.input)}") + for x in target.input: + outputs[variable_name_for_value(x, target.input)] = LatchFile inputs: Dict[str, Type] = {} for job in dag.jobs: @@ -165,6 +161,7 @@ def __init__( var = variable_name_for_value(x, job.input) parameter_metadata[var] = LatchParameter(display_name=var) + # TODO - support for metadata + parameters in future releases latch_metadata = LatchMetadata( display_name=name, documentation="", @@ -173,8 +170,6 @@ def __init__( email="", github="", ), - repository="", - license="", parameters=parameter_metadata, tags=[], ) @@ -309,9 +304,7 @@ def find_upstream_node(): for j in self._dag.targetjobs: for depen, files in self._dag.dependencies[j].items(): for f in files: - # TODO - better link than str representation of - # target file - if variable_name_for_value(f) == out: + if variable_name_for_file(f) == out: return depen.jobid, variable_name_for_value( f, depen.output ) @@ -337,6 +330,9 @@ def execute(self, **kwargs): return exception_scopes.user_entry_point(self._workflow_function)(**kwargs) +T = TypeVar("T") + + class SnakemakeJobTask(PythonAutoContainerTask[T]): def __init__( self, @@ -458,10 +454,6 @@ def task_function(self): return self._task_function def execute(self, **kwargs) -> Any: - """ - This method will be invoked to execute the task. If you do decide to override this method you must also - handle dynamic tasks or you will no longer be able to use the task as a dynamic task generator. - """ return exception_scopes.user_entry_point(self._task_function)(**kwargs) From 793024436b66445f05e59eb5bd4ec6226fe6f7f7 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Thu, 25 May 2023 17:03:36 -0700 Subject: [PATCH 016/356] create proper bindings for named outputs --- latch_cli/snakemake/workflow.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 2d97846a..7c910cb3 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1,6 +1,7 @@ import importlib import typing from collections import OrderedDict +from dataclasses import dataclass from pathlib import Path from typing import Any, Dict, List, Optional, Type, TypeVar, Union @@ -227,11 +228,21 @@ def compile(self, **kwargs): target_file_for_output_param[param] = x python_outputs[param] = LatchFile + @dataclass + class JobOutputInfo: + jobid: str + output_param_name: str + dep_outputs = {} for dep, dep_files in self._dag.dependencies[job].items(): for o in dep.output: if o in dep_files: - dep_outputs[o] = dep.jobid + dep_outputs[o] = JobOutputInfo( + jobid=dep.jobid, + output_param_name=variable_name_for_value( + o, dep.output + ), + ) python_inputs: Dict[str, Type] = {} promise_map: Dict[str, str] = {} @@ -261,11 +272,12 @@ def compile(self, **kwargs): var = typed_interface.inputs[k] if var.description in promise_map: + job_output_info = promise_map[var.description] promise_to_bind = Promise( var=k, val=NodeOutput( - node=node_map[promise_map[var.description]], - var=var.description, + node=node_map[job_output_info.jobid], + var=job_output_info.output_param_name, ), ) else: From ffa6049b715e874305eaeff675dc1c3ee0168d10 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Thu, 25 May 2023 19:06:50 -0700 Subject: [PATCH 017/356] snakemake path in container --- latch_cli/services/register/register.py | 2 +- latch_cli/services/serialize.py | 9 +++++++-- latch_cli/snakemake/workflow.py | 3 ++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index 23103229..2ef36ba4 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -163,7 +163,7 @@ def build_and_serialize( if ctx.workflow_type == WorkflowType.SNAKEMAKE: _, wf = extract_snakemake_workflow(ctx.snakefile) - generate_snakemake_entrypoint(wf, ctx) + generate_snakemake_entrypoint(wf, ctx, ctx.snakefile) image_build_logs = build_image(ctx, image_name, context_path, dockerfile) print_and_write_build_logs(image_build_logs, image_name, ctx.pkg_root) diff --git a/latch_cli/services/serialize.py b/latch_cli/services/serialize.py index dd58e04b..df55dc3e 100644 --- a/latch_cli/services/serialize.py +++ b/latch_cli/services/serialize.py @@ -180,7 +180,9 @@ def serialize_snakemake( persist_registrable_entities(registrable_entities, output_dir) -def generate_snakemake_entrypoint(wf: SnakemakeWorkflow, ctx: _CentromereCtx): +def generate_snakemake_entrypoint( + wf: SnakemakeWorkflow, ctx: _CentromereCtx, snakefile: Path +): entrypoint_code_block = textwrap.dedent( """\ @@ -197,7 +199,10 @@ def ensure_parents_exist(path: Path): """ ) for task in wf.snakemake_tasks: - entrypoint_code_block += task.get_fn_code() + snakefile_path_in_container = str(snakefile.resolve())[ + len(str(ctx.pkg_root.resolve())) + 1 : + ] + entrypoint_code_block += task.get_fn_code(snakefile_path_in_container) entrypoint = ctx.pkg_root.joinpath(".latch/latch_entrypoint.py") with open(entrypoint, "w") as f: diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 7c910cb3..27a638f5 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -380,7 +380,7 @@ def placeholder(): task_resolver=SnakemakeJobTaskResolver(), ) - def get_fn_code(self): + def get_fn_code(self, snakefile_path_in_container: str): code_block = "" @@ -411,6 +411,7 @@ def get_fn_code(self): code_block += f'\n\tPath({param}).resolve().rename(ensure_parents_exist(Path("{self._target_file_for_input_param[param]}")))' snakemake_cmd = ["snakemake"] + snakemake_cmd.extend(["-s", snakefile_path_in_container]) snakemake_cmd.extend( ["--target-jobs", *encode_target_jobs_cli_args(self.job.get_target_spec())] ) From eee21535d9431b25cc5f9fc3716b8cdad7caa7b3 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Sat, 24 Jun 2023 14:33:45 -0700 Subject: [PATCH 018/356] rebase fixes --- latch_cli/centromere/ctx.py | 18 +++++++--------- latch_cli/docker_utils/__init__.py | 11 +++++----- latch_cli/main.py | 6 +++--- latch_cli/services/register/register.py | 2 -- latch_cli/services/register/utils.py | 1 - latch_cli/snakemake/workflow.py | 28 ++++++++++++------------- 6 files changed, 30 insertions(+), 36 deletions(-) diff --git a/latch_cli/centromere/ctx.py b/latch_cli/centromere/ctx.py index 61f3cbc2..41692711 100644 --- a/latch_cli/centromere/ctx.py +++ b/latch_cli/centromere/ctx.py @@ -86,7 +86,7 @@ def __init__( token: Optional[str] = None, disable_auto_version: bool = False, remote: bool = False, - snakefile: Path = None, + snakefile: Optional[Path] = None, ): try: if token is None: @@ -111,7 +111,6 @@ def __init__( self.workflow_type = WorkflowType.SNAKEMAKE self.snakefile = snakefile - # We do not support per task containers for snakemake rn self.container_map = {} if self.workflow_type == WorkflowType.LATCHBIOSDK: _import_flyte_objects([self.pkg_root]) @@ -129,21 +128,20 @@ def __init__( pkg_dir=entity.dockerfile_path.parent, ) else: - # TODO + # TODO (kenny) - support per container task and custom workflow + # name for snakemake self.workflow_name = "snakemake workflow" - version_file = self.pkg_root.joinpath("version") + version_file = self.pkg_root / "version" if not version_file.exists(): - self.version = "0.0.0" - with open(version_file, "w") as vf: - vf.write(self.version) + self.version = "0.1.0" + version_file.write_text(self.version + "\n") click.echo( - "Created a version file with initial version 0.0.0 for this" + "Created a version file with initial version 0.1.0 for this" " workflow." ) else: - with open(version_file, "r") as vf: - self.version = vf.read().strip() + self.version = version_file.read_text().strip() if not self.disable_auto_version: hash = hash_directory(self.pkg_root) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 51eec600..3b0a394e 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -54,7 +54,7 @@ def get_epilogue(wf_type: WorkflowType = WorkflowType.LATCHBIOSDK) -> List[str]: "workdir /root", ] if wf_type == WorkflowType.SNAKEMAKE: - cmds.insert(-1, "copy .latch/latch_entrypoint.py /root/latch_entrypoint.py") + cmds.append("copy .latch/latch_entrypoint.py /root/latch_entrypoint.py") return cmds @@ -203,7 +203,7 @@ def generate_dockerfile( Example: - >>> generate_dockerfile(Path("test-workflow"), Path("test-workflow/Dockerfile"), WorkflowType.snakemake) + >>> generate_dockerfile(Path("test-workflow"), Path("test-workflow/Dockerfile"), WorkflowType.LATCHBIOSDK) # The resulting file structure will look like # test-workflow # ├── Dockerfile @@ -247,9 +247,8 @@ def generate_dockerfile( def get_default_dockerfile(pkg_root: Path, wf_type: WorkflowType): - - default_dockerfile = pkg_root.joinpath("Dockerfile") + default_dockerfile = pkg_root / "Dockerfile" if not default_dockerfile.exists(): - generate_dockerfile(pkg_root, pkg_root.joinpath(".latch/Dockerfile"), wf_type) - default_dockerfile = pkg_root.joinpath(".latch/Dockerfile") + generate_dockerfile(pkg_root, pkg_root / ".latch" / "Dockerfile"), wf_type) + default_dockerfile=pkg_root / ".latch" / "Dockerfile" return default_dockerfile diff --git a/latch_cli/main.py b/latch_cli/main.py index a7f587a0..4323b6de 100644 --- a/latch_cli/main.py +++ b/latch_cli/main.py @@ -110,16 +110,16 @@ def dockerfile(pkg_root: str): @click.option( "-s", "--snakefile", - type=click.Path(exists=True), + type=click.Path(exists=True, path_type=Path), default=None, - help="Full path to Snakefile to register.", + help="Path to a Snakefile to register.", ) def register( pkg_root: str, disable_auto_version: bool, remote: bool, yes: bool, - snakefile: Optional[str], + snakefile: Optional[Path], ): """Register local workflow code to Latch. diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index 2ef36ba4..e5b7483b 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -248,8 +248,6 @@ def register( """ pkg_root = Path(pkg_root).resolve() - if snakefile: - snakefile = Path(snakefile).resolve() with _CentromereCtx( pkg_root, diff --git a/latch_cli/services/register/utils.py b/latch_cli/services/register/utils.py index f37657c2..ce7df41f 100644 --- a/latch_cli/services/register/utils.py +++ b/latch_cli/services/register/utils.py @@ -9,7 +9,6 @@ import requests from latch_cli.centromere.ctx import _CentromereCtx -from latch_cli.services.serialize import serialize_snakemake from latch_cli.utils import current_workspace diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 27a638f5..327d6541 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1,9 +1,8 @@ import importlib import typing -from collections import OrderedDict from dataclasses import dataclass from pathlib import Path -from typing import Any, Dict, List, Optional, Type, TypeVar, Union +from typing import Any, Dict, List, Optional, TypeAlias, TypeVar, Union import snakemake from flytekit.configuration import SerializationSettings @@ -33,11 +32,12 @@ from latch.types import LatchAuthor, LatchFile, LatchMetadata, LatchParameter -SnakemakeInputVal = Union[snakemake.io._IOFile] +SnakemakeInputVal: TypeAlias = snakemake.io._IOFile def variable_name_for_file(file: snakemake.io.AnnotatedString): - return file.replace("/", "_").replace(".", "_").replace("-", "_") + + return file.replace("/", "_").replace(".", "__").replace("-", "____") def variable_name_for_value( @@ -57,13 +57,13 @@ def snakemake_dag_to_interface( dag: DAG, docstring: Optional[Docstring] = None ) -> Interface: - outputs: Dict[str, Type] = {} + outputs: Dict[str, LatchFile] = {} for target in dag.targetjobs: for x in target.input: outputs[variable_name_for_value(x, target.input)] = LatchFile - inputs: Dict[str, Type] = {} + inputs: Dict[str, LatchFile] = {} for job in dag.jobs: dep_outputs = [] @@ -115,7 +115,7 @@ def transform_types_in_variable_map( variable_map: Dict[str, type], descriptions: Dict[str, str] = {}, ) -> Dict[str, interface_models.Variable]: - res = OrderedDict() + res = {} if variable_map: for k, v in variable_map.items(): res[k] = transform_type(v, descriptions.get(k, k)) @@ -133,7 +133,7 @@ def interface_to_parameters( inputs_vars = transform_types_in_variable_map( interface.inputs, interface.docstring.input_descriptions ) - params = {} + params: Dict[str, interface_models.ParameterMap] = {} inputs_with_def = interface.inputs_with_defaults for k, v in inputs_vars.items(): val, _default = inputs_with_def[k] @@ -156,7 +156,7 @@ def __init__( dag: DAG, ): - parameter_metadata = {} + parameter_metadata: Dict[str, LatchParameter] = {} for job in dag.jobs: for x in job.input: var = variable_name_for_value(x, job.input) @@ -205,7 +205,7 @@ def compile(self, **kwargs): flyte_entity=None, ) - node_map = {} + node_map: Dict[int, Node] = {} target_files = [x for job in self._dag.targetjobs for x in job.input] @@ -220,7 +220,7 @@ def compile(self, **kwargs): target_file_for_output_param: Dict[str, str] = {} target_file_for_input_param: Dict[str, str] = {} - python_outputs: Dict[str, Type] = {} + python_outputs: Dict[str, LatchFile] = {} for x in job.output: if x in target_files: is_target = True @@ -244,7 +244,7 @@ class JobOutputInfo: ), ) - python_inputs: Dict[str, Type] = {} + python_inputs: Dict[str, LatchFile] = {} promise_map: Dict[str, str] = {} for x in job.input: param = variable_name_for_value(x, job.input) @@ -349,8 +349,8 @@ class SnakemakeJobTask(PythonAutoContainerTask[T]): def __init__( self, job: snakemake.jobs.Job, - inputs: Dict[str, Type], - outputs: Dict[str, Type], + inputs: Dict[str, LatchFile], + outputs: Dict[str, LatchFile], target_file_for_input_param: Dict[str, str], target_file_for_output_param: Dict[str, str], is_target: bool, From 2e1749e2e61209a19ee60515198ebe8d43f936be Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Sat, 24 Jun 2023 14:35:44 -0700 Subject: [PATCH 019/356] rebase fixes --- latch/resources/launch_plan.py | 1 - latch/types/directory.py | 1 - latch_cli/auth/oauth2.py | 5 +---- latch_cli/centromere/ctx.py | 6 ++++-- latch_cli/docker_utils/__init__.py | 4 ++-- latch_cli/main.py | 12 ++++++------ latch_cli/services/init/init.py | 9 +++++++++ latch_cli/services/register/utils.py | 1 - latch_cli/services/serialize.py | 15 ++++----------- latch_cli/snakemake/serialize_utils.py | 4 ---- latch_cli/snakemake/workflow.py | 13 ------------- tests/fixtures.py | 1 - 12 files changed, 26 insertions(+), 46 deletions(-) diff --git a/latch/resources/launch_plan.py b/latch/resources/launch_plan.py index ac185b7e..60256a11 100644 --- a/latch/resources/launch_plan.py +++ b/latch/resources/launch_plan.py @@ -27,7 +27,6 @@ class LaunchPlan: """ def __init__(self, workflow: Callable, name: str, default_params: Dict[str, Any]): - # This constructor is invoked twice when task code is executed. # 1. When the pyflyte-execute entrypoint is invoked to start task. # `mod.__name__` of caller is `wf` diff --git a/latch/types/directory.py b/latch/types/directory.py index 30449701..3326892c 100644 --- a/latch/types/directory.py +++ b/latch/types/directory.py @@ -141,7 +141,6 @@ def to_python_value( lv: Literal, expected_python_type: Union[Type[LatchDir], PathLike], ) -> FlyteDirectory: - uri = lv.scalar.blob.uri if expected_python_type is PathLike: raise TypeError( diff --git a/latch_cli/auth/oauth2.py b/latch_cli/auth/oauth2.py index 967dbd85..89caaf7d 100644 --- a/latch_cli/auth/oauth2.py +++ b/latch_cli/auth/oauth2.py @@ -87,7 +87,6 @@ def authorization_request(self, connection: Optional[str]) -> str: class _CallbackHandler(http.server.BaseHTTPRequestHandler): def do_GET(self): - parsed_url = urllib.parse.urlsplit(self.path) if parsed_url.path != "/callback": return @@ -122,9 +121,7 @@ def do_GET(self):

Your Latch SDK has been authenticated.

- """.encode( - "utf-8" - ) + """.encode("utf-8") self.wfile.write(auth_response_html) def log_request(self, format, *args): diff --git a/latch_cli/centromere/ctx.py b/latch_cli/centromere/ctx.py index 41692711..9f3ff365 100644 --- a/latch_cli/centromere/ctx.py +++ b/latch_cli/centromere/ctx.py @@ -219,8 +219,10 @@ def image_tagged(self): match = re.match("^[a-zA-Z0-9_][a-zA-Z0-9._-]{,127}$", self.version) if match is None: raise ValueError( - f"{self.version} is an invalid version for AWS " - "ECR. Please provide a version that accomodates the ", + ( + f"{self.version} is an invalid version for AWS " + "ECR. Please provide a version that accomodates the " + ), "tag restrictions listed here - ", "https://docs.aws.amazon.com/AmazonECR/latest/userguide/ecr-using-tags.html", ) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 3b0a394e..86a06b3a 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -249,6 +249,6 @@ def generate_dockerfile( def get_default_dockerfile(pkg_root: Path, wf_type: WorkflowType): default_dockerfile = pkg_root / "Dockerfile" if not default_dockerfile.exists(): - generate_dockerfile(pkg_root, pkg_root / ".latch" / "Dockerfile"), wf_type) - default_dockerfile=pkg_root / ".latch" / "Dockerfile" + default_dockerfile = pkg_root / ".latch" / "Dockerfile" + generate_dockerfile(default_dockerfile, wf_type) return default_dockerfile diff --git a/latch_cli/main.py b/latch_cli/main.py index 4323b6de..7aab485c 100644 --- a/latch_cli/main.py +++ b/latch_cli/main.py @@ -43,12 +43,10 @@ def main(): latest_ver = parse_version(get_latest_package_version()) if local_ver < latest_ver: click.secho( - textwrap.dedent( - f""" + textwrap.dedent(f""" WARN: Your local version of latch ({local_ver}) is out of date. This may result in unexpected behavior. Please upgrade to the latest version ({latest_ver}) using `python3 -m pip install --upgrade latch`. - """ - ).strip("\n"), + """).strip("\n"), fg="yellow", ) @@ -461,8 +459,10 @@ def get_params(wf_name: Union[str, None], version: Union[str, None] = None): if version is None: version = "latest" click.secho( - f"Successfully generated python param map named {wf_name}.params.py with" - f" version {version}\n Run `latch launch {wf_name}.params.py` to launch it.", + ( + f"Successfully generated python param map named {wf_name}.params.py with" + f" version {version}\n Run `latch launch {wf_name}.params.py` to launch it." + ), fg="green", ) diff --git a/latch_cli/services/init/init.py b/latch_cli/services/init/init.py index c90c6066..0efc85dc 100644 --- a/latch_cli/services/init/init.py +++ b/latch_cli/services/init/init.py @@ -298,6 +298,15 @@ def init( else template_flag_to_option[template] ) +<<<<<<< HEAD +======= + if base_image_type_str not in BaseImageOptions.__members__: + raise ValueError( + f"Invalid base image type: {base_image_type_str}. Must be one of" + f" {list(BaseImageOptions.__members__.keys())}" + ) + +>>>>>>> 9ddde0b (black 23.3.0) if selected_option is None: return False diff --git a/latch_cli/services/register/utils.py b/latch_cli/services/register/utils.py index ce7df41f..dde52fd0 100644 --- a/latch_cli/services/register/utils.py +++ b/latch_cli/services/register/utils.py @@ -80,7 +80,6 @@ def upload_image(ctx: _CentromereCtx, image_name: str) -> List[str]: def serialize_pkg_in_container( ctx: _CentromereCtx, image_name: str, serialize_dir: Path ) -> List[str]: - _serialize_cmd = ["make", "serialize"] container = ctx.dkr_client.create_container( f"{ctx.dkr_repo}/{image_name}", diff --git a/latch_cli/services/serialize.py b/latch_cli/services/serialize.py index df55dc3e..c0d7d214 100644 --- a/latch_cli/services/serialize.py +++ b/latch_cli/services/serialize.py @@ -52,10 +52,8 @@ def rules(items): return map(self._rules.__getitem__, filter(self.is_rule, items)) def files(items): - relpath = ( - lambda f: f - if os.path.isabs(f) or f.startswith("root://") - else os.path.relpath(f) + relpath = lambda f: ( + f if os.path.isabs(f) or f.startswith("root://") else os.path.relpath(f) ) return map(relpath, filterfalse(self.is_rule, items)) @@ -117,7 +115,6 @@ def files(items): def extract_snakemake_workflow(snakefile: Path) -> (str, SnakemakeWorkflow): - workflow = SnakemakeWorkflowExtractor( snakefile=snakefile, ) @@ -143,7 +140,6 @@ def serialize_snakemake( image_name: str, dkr_repo: str, ): - pkg_root = Path(pkg_root).resolve() _, wf = extract_snakemake_workflow(snakefile) @@ -183,9 +179,7 @@ def serialize_snakemake( def generate_snakemake_entrypoint( wf: SnakemakeWorkflow, ctx: _CentromereCtx, snakefile: Path ): - - entrypoint_code_block = textwrap.dedent( - """\ + entrypoint_code_block = textwrap.dedent("""\ import subprocess from pathlib import Path from typing import NamedTuple @@ -196,8 +190,7 @@ def generate_snakemake_entrypoint( def ensure_parents_exist(path: Path): path.parent.mkdir(parents=True, exist_ok=True) return path - """ - ) + """) for task in wf.snakemake_tasks: snakefile_path_in_container = str(snakefile.resolve())[ len(str(ctx.pkg_root.resolve())) + 1 : diff --git a/latch_cli/snakemake/serialize_utils.py b/latch_cli/snakemake/serialize_utils.py index 3f7588b9..e1f084f3 100644 --- a/latch_cli/snakemake/serialize_utils.py +++ b/latch_cli/snakemake/serialize_utils.py @@ -38,7 +38,6 @@ def get_serializable_launch_plan( entity: LaunchPlan, cache: EntityCache, ) -> launch_plan_models.LaunchPlan: - wf_id = identifier_model.Identifier( resource_type=identifier_model.ResourceType.WORKFLOW, project=settings.project, @@ -91,7 +90,6 @@ def get_serializable_task( settings: SerializationSettings, cache: EntityCache, ) -> task_models.TaskSpec: - if entity in cache: return cache[entity] @@ -129,7 +127,6 @@ def get_serializable_node( settings: SerializationSettings, cache: EntityCache, ) -> workflow_model.Node: - if entity in cache: return cache[entity] @@ -168,7 +165,6 @@ def get_serializable_workflow( settings: SerializationSettings, cache: EntityCache, ) -> admin_workflow_models.WorkflowSpec: - if entity in cache: return cache[entity] diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 327d6541..f673451e 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -36,7 +36,6 @@ def variable_name_for_file(file: snakemake.io.AnnotatedString): - return file.replace("/", "_").replace(".", "__").replace("-", "____") @@ -44,7 +43,6 @@ def variable_name_for_value( val: SnakemakeInputVal, params: Union[snakemake.io.InputFiles, snakemake.io.OutputFiles] = None, ) -> str: - if params: for name, v in params.items(): if val == v: @@ -56,7 +54,6 @@ def variable_name_for_value( def snakemake_dag_to_interface( dag: DAG, docstring: Optional[Docstring] = None ) -> Interface: - outputs: Dict[str, LatchFile] = {} for target in dag.targetjobs: @@ -65,7 +62,6 @@ def snakemake_dag_to_interface( inputs: Dict[str, LatchFile] = {} for job in dag.jobs: - dep_outputs = [] for dep, dep_files in dag.dependencies[job].items(): for o in dep.output: @@ -87,7 +83,6 @@ def binding_data_from_python( t_value: typing.Any, t_value_type: Optional[type] = None, ) -> literals_models.BindingData: - if isinstance(t_value, Promise): if not t_value.is_ready: return literals_models.BindingData(promise=t_value.ref) @@ -155,7 +150,6 @@ def __init__( name: str, dag: DAG, ): - parameter_metadata: Dict[str, LatchParameter] = {} for job in dag.jobs: for x in job.input: @@ -194,7 +188,6 @@ def __init__( ) def compile(self, **kwargs): - self._input_parameters = interface_to_parameters(self.python_interface) GLOBAL_START_NODE = Node( @@ -211,7 +204,6 @@ def compile(self, **kwargs): for layer in self._dag.toposorted(): for job in layer: - is_target = False if job in self._dag.targetjobs: @@ -269,7 +261,6 @@ class JobOutputInfo: self.interface.inputs.keys() bindings = [] for k in sorted(interface.inputs): - var = typed_interface.inputs[k] if var.description in promise_map: job_output_info = promise_map[var.description] @@ -357,7 +348,6 @@ def __init__( interface: Interface, task_type="python-task", ): - name = f"{job.name}_{job.jobid}" self.job = job @@ -381,7 +371,6 @@ def placeholder(): ) def get_fn_code(self, snakefile_path_in_container: str): - code_block = "" fn_interface = f"\n\n@small_task\ndef {self.name}(" @@ -473,7 +462,6 @@ def execute(self, **kwargs) -> Any: class SnakemakeJobTaskResolver(DefaultTaskResolver): @property def location(self) -> str: - return "flytekit.core.python_auto_container.default_task_resolver" def loader_args( @@ -482,7 +470,6 @@ def loader_args( return ["task-module", "latch_entrypoint", "task-name", task.name] def load_task(self, loader_args: List[str]) -> PythonAutoContainerTask: - _, task_module, _, task_name, *_ = loader_args task_module = importlib.import_module(task_module) diff --git a/tests/fixtures.py b/tests/fixtures.py index 2e534a4c..8fe1dc7d 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -8,7 +8,6 @@ @pytest.fixture(scope="session") def test_account_jwt(): - tmp_token = os.environ["TEST_TOKEN"] token_dir = Path.home().joinpath(".latch") token_dir.mkdir(exist_ok=True) From 30aa032760618e15ab87ed5e6a14f51c80c0107e Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Tue, 30 May 2023 14:34:14 -0700 Subject: [PATCH 020/356] add black to dev requirements --- dev-requirements.in | 1 + dev-requirements.txt | 36 ++++++++++++++++++++++-------------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/dev-requirements.in b/dev-requirements.in index e079f8a6..547a6eb8 100644 --- a/dev-requirements.in +++ b/dev-requirements.in @@ -1 +1,2 @@ pytest +black==23.3.0 diff --git a/dev-requirements.txt b/dev-requirements.txt index 625033db..94546c91 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,24 +1,32 @@ # -# This file is autogenerated by pip-compile with python 3.10 -# To update, run: +# This file is autogenerated by pip-compile with Python 3.10 +# by the following command: # # pip-compile dev-requirements.in # -attrs==21.4.0 - # via pytest -iniconfig==1.1.1 +black==23.3.0 + # via -r dev-requirements.in +click==8.1.3 + # via black +exceptiongroup==1.1.1 # via pytest -packaging==21.3 +iniconfig==2.0.0 # via pytest +mypy-extensions==1.0.0 + # via black +packaging==23.1 + # via + # black + # pytest +pathspec==0.11.1 + # via black +platformdirs==3.5.1 + # via black pluggy==1.0.0 # via pytest -py==1.11.0 - # via pytest -pyparsing==3.0.7 - # via packaging -pytest==7.0.0 +pytest==7.3.1 # via -r dev-requirements.in tomli==2.0.1 - # via pytest -tqdm==4.63.0 - # via -r dev-requirements.in + # via + # black + # pytest From 94c3ea9109ff7201022b6e1008ddcddb475ef6df Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Sat, 24 Jun 2023 14:36:28 -0700 Subject: [PATCH 021/356] rebase fixes --- latch_cli/centromere/ctx.py | 6 +++--- latch_cli/docker_utils/__init__.py | 8 ++++---- latch_cli/services/register/register.py | 6 +++--- latch_cli/services/serialize.py | 10 +++++++--- latch_cli/utils.py | 4 ++-- 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/latch_cli/centromere/ctx.py b/latch_cli/centromere/ctx.py index 9f3ff365..d4aaf202 100644 --- a/latch_cli/centromere/ctx.py +++ b/latch_cli/centromere/ctx.py @@ -106,13 +106,13 @@ def __init__( self.pkg_root = Path(pkg_root).resolve() if snakefile is None: - self.workflow_type = WorkflowType.LATCHBIOSDK + self.workflow_type = WorkflowType.latchbiosdk else: - self.workflow_type = WorkflowType.SNAKEMAKE + self.workflow_type = WorkflowType.snakemake self.snakefile = snakefile self.container_map = {} - if self.workflow_type == WorkflowType.LATCHBIOSDK: + if self.workflow_type == WorkflowType.latchbiosdk: _import_flyte_objects([self.pkg_root]) for entity in FlyteEntities.entities: if isinstance(entity, PythonFunctionWorkflow): diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 86a06b3a..f49f94c1 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -43,7 +43,7 @@ def get_prologue(config: LatchWorkflowConfig) -> List[str]: ] -def get_epilogue(wf_type: WorkflowType = WorkflowType.LATCHBIOSDK) -> List[str]: +def get_epilogue(wf_type: WorkflowType = WorkflowType.latchbiosdk) -> List[str]: cmds = [ ( "# latch internal tagging system + expected root directory --- changing" @@ -53,7 +53,7 @@ def get_epilogue(wf_type: WorkflowType = WorkflowType.LATCHBIOSDK) -> List[str]: "env FLYTE_INTERNAL_IMAGE $tag", "workdir /root", ] - if wf_type == WorkflowType.SNAKEMAKE: + if wf_type == WorkflowType.snakemake: cmds.append("copy .latch/latch_entrypoint.py /root/latch_entrypoint.py") return cmds @@ -192,7 +192,7 @@ def infer_commands(pkg_root: Path) -> List[DockerCmdBlock]: def generate_dockerfile( - pkg_root: Path, outfile: Path, wf_type: WorkflowType = WorkflowType.LATCHBIOSDK + pkg_root: Path, outfile: Path, wf_type: WorkflowType = WorkflowType.latchbiosdk ) -> None: """Generate a best effort Dockerfile from files in the workflow directory. @@ -203,7 +203,7 @@ def generate_dockerfile( Example: - >>> generate_dockerfile(Path("test-workflow"), Path("test-workflow/Dockerfile"), WorkflowType.LATCHBIOSDK) + >>> generate_dockerfile(Path("test-workflow"), Path("test-workflow/Dockerfile"), WorkflowType.latchbiosdk) # The resulting file structure will look like # test-workflow # ├── Dockerfile diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index e5b7483b..24819587 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -161,14 +161,14 @@ def build_and_serialize( ): """Builds an image, serializes the workflow within the image, and pushes the image.""" - if ctx.workflow_type == WorkflowType.SNAKEMAKE: + if ctx.workflow_type == WorkflowType.snakemake: _, wf = extract_snakemake_workflow(ctx.snakefile) generate_snakemake_entrypoint(wf, ctx, ctx.snakefile) image_build_logs = build_image(ctx, image_name, context_path, dockerfile) print_and_write_build_logs(image_build_logs, image_name, ctx.pkg_root) - if ctx.workflow_type == WorkflowType.LATCHBIOSDK: + if ctx.workflow_type == WorkflowType.latchbiosdk: serialize_logs, container_id = serialize_pkg_in_container( ctx, image_name, tmp_dir ) @@ -313,7 +313,7 @@ def register( dockerfile=ctx.default_container.dockerfile, ) protos = _recursive_list(td) - if ctx.workflow_type == WorkflowType.LATCHBIOSDK and remote: + if ctx.workflow_type == WorkflowType.latchbiosdk and remote: local_td = stack.enter_context(tempfile.TemporaryDirectory()) ssh = _construct_ssh_client(ctx.internal_ip, ctx.username) scp = SCPClient(transport=ssh.get_transport(), sanitize=lambda x: x) diff --git a/latch_cli/services/serialize.py b/latch_cli/services/serialize.py index c0d7d214..f2b01da2 100644 --- a/latch_cli/services/serialize.py +++ b/latch_cli/services/serialize.py @@ -52,9 +52,13 @@ def rules(items): return map(self._rules.__getitem__, filter(self.is_rule, items)) def files(items): - relpath = lambda f: ( - f if os.path.isabs(f) or f.startswith("root://") else os.path.relpath(f) - ) + def relpath(f): + return ( + f + if os.path.isabs(f) or f.startswith("root://") + else os.path.relpath(f) + ) + return map(relpath, filterfalse(self.is_rule, items)) # if not targets and not target_jobs: diff --git a/latch_cli/utils.py b/latch_cli/utils.py index 83a98eb3..99fe94be 100644 --- a/latch_cli/utils.py +++ b/latch_cli/utils.py @@ -293,5 +293,5 @@ def __exit__(self, type, value, traceback): class WorkflowType(Enum): - LATCHBIOSDK = "latchbiosdk" - SNAKEMAKE = "snakemake" + latchbiosdk = "latchbiosdk" + snakemake = "snakemake" From 6b5c9cc4878e994b2cc7ed981b0d220bcae1e7a2 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Sat, 24 Jun 2023 14:37:05 -0700 Subject: [PATCH 022/356] rebase fixes --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index a972e6ac..7187f23c 100644 --- a/setup.py +++ b/setup.py @@ -46,6 +46,7 @@ "latch-sdk-gql==0.0.2", "latch-sdk-config==0.0.1", ], + extras_require={"snakemake": ["snakemake>=7.25.4"]}, classifiers=[ "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", From 8beb8a08aa413361e38eec052a1cf42149c7cd44 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Tue, 30 May 2023 16:17:10 -0700 Subject: [PATCH 023/356] remove fluff --- latch_cli/services/serialize.py | 82 ++++++++------------------------- 1 file changed, 18 insertions(+), 64 deletions(-) diff --git a/latch_cli/services/serialize.py b/latch_cli/services/serialize.py index f2b01da2..9df95c81 100644 --- a/latch_cli/services/serialize.py +++ b/latch_cli/services/serialize.py @@ -2,9 +2,8 @@ import textwrap from itertools import chain, filterfalse from pathlib import Path -from typing import Optional, Union +from typing import List, Set, Union, get_args -import click from flytekit import LaunchPlan from flytekit.configuration import Image, ImageConfig, SerializationSettings from flytekit.models import launch_plan as launch_plan_models @@ -32,79 +31,34 @@ ] -def should_register_with_admin(entity) -> bool: - return isinstance( - entity, - ( - task_models.TaskSpec, - launch_plan_models.LaunchPlan, - admin_workflow_models.WorkflowSpec, - ), - ) +def should_register_with_admin(entity: RegistrableEntity) -> bool: + return isinstance(entity, get_args(RegistrableEntity)) class SnakemakeWorkflowExtractor(Workflow): - def __init__(self, snakefile): + def __init__(self, snakefile: Path): super().__init__(snakefile=snakefile) - def extract(self): - def rules(items): - return map(self._rules.__getitem__, filter(self.is_rule, items)) - - def files(items): - def relpath(f): - return ( - f - if os.path.isabs(f) or f.startswith("root://") - else os.path.relpath(f) - ) - - return map(relpath, filterfalse(self.is_rule, items)) - - # if not targets and not target_jobs: - targets = [self.default_target] if self.default_target is not None else list() - - prioritytargets = list() - forcerun = list() - until = list() - omit_from = list() - - priorityrules = set(rules(prioritytargets)) - priorityfiles = set(files(prioritytargets)) - forcerules = set(rules(forcerun)) - forcefiles = set(files(forcerun)) - untilrules = set(rules(until)) - untilfiles = set(files(until)) - omitrules = set(rules(omit_from)) - omitfiles = set(files(omit_from)) - targetrules = set( - chain( - rules(targets), - filterfalse(Rule.has_wildcards, priorityrules), - filterfalse(Rule.has_wildcards, forcerules), - filterfalse(Rule.has_wildcards, untilrules), - ) + def extract_dag(self): + targets: List[str] = ( + [self.default_target] if self.default_target is not None else [] + ) + targetrules: Set[Rule] = set( + map(self._rules.__getitem__, filter(self.is_rule, targets)) ) - targetfiles = set(chain(files(targets), priorityfiles, forcefiles, untilfiles)) - - if ON_WINDOWS: - targetfiles = set(tf.replace(os.sep, os.altsep) for tf in targetfiles) - rules = self.rules + targetfiles = set() + for f in filterfalse(self.is_rule, targets): + if os.path.isabs(f) or f.startswith("root://"): + targetfiles.add(f) + else: + targetfiles.add(os.path.relpath(f)) dag = DAG( self, - rules, + self.rules, targetfiles=targetfiles, targetrules=targetrules, - forcefiles=forcefiles, - forcerules=forcerules, - priorityfiles=priorityfiles, - priorityrules=priorityrules, - untilfiles=untilfiles, - untilrules=untilrules, - omitfiles=omitfiles, - omitrules=omitrules, ) self.persistence = Persistence( @@ -126,7 +80,7 @@ def extract_snakemake_workflow(snakefile: Path) -> (str, SnakemakeWorkflow): snakefile, overwrite_default_target=True, ) - dag = workflow.extract() + dag = workflow.extract_dag() wf_name = "snakemake_wf" wf = SnakemakeWorkflow( From 1370aa4a3e22abddb992e8ad4f339b9f1264ba0a Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Tue, 30 May 2023 16:42:36 -0700 Subject: [PATCH 024/356] comments --- latch_cli/services/serialize.py | 16 ++++++++-------- latch_cli/snakemake/serialize_utils.py | 19 ++++++++++--------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/latch_cli/services/serialize.py b/latch_cli/services/serialize.py index 9df95c81..fc25d236 100644 --- a/latch_cli/services/serialize.py +++ b/latch_cli/services/serialize.py @@ -11,7 +11,6 @@ from flytekit.models import task as task_models from flytekit.models.admin import workflow as admin_workflow_models from flytekit.tools.serialize_helpers import persist_registrable_entities -from snakemake.common import ON_WINDOWS from snakemake.dag import DAG from snakemake.persistence import Persistence from snakemake.rules import Rule @@ -19,6 +18,7 @@ from latch_cli.centromere.ctx import _CentromereCtx from latch_cli.snakemake.serialize_utils import ( + EntityCache, get_serializable_launch_plan, get_serializable_workflow, ) @@ -43,22 +43,22 @@ def extract_dag(self): targets: List[str] = ( [self.default_target] if self.default_target is not None else [] ) - targetrules: Set[Rule] = set( + target_rules: Set[Rule] = set( map(self._rules.__getitem__, filter(self.is_rule, targets)) ) - targetfiles = set() + target_files = set() for f in filterfalse(self.is_rule, targets): if os.path.isabs(f) or f.startswith("root://"): - targetfiles.add(f) + target_files.add(f) else: - targetfiles.add(os.path.relpath(f)) + target_files.add(os.path.relpath(f)) dag = DAG( self, self.rules, - targetfiles=targetfiles, - targetrules=targetrules, + targetfiles=target_files, + targetrules=target_rules, ) self.persistence = Persistence( @@ -111,7 +111,7 @@ def serialize_snakemake( image_config=ImageConfig(default_image=default_img, images=[default_img]), ) - registrable_entity_cache = {} + registrable_entity_cache: EntityCache = {} get_serializable_workflow(wf, settings, registrable_entity_cache) diff --git a/latch_cli/snakemake/serialize_utils.py b/latch_cli/snakemake/serialize_utils.py index e1f084f3..77383c95 100644 --- a/latch_cli/snakemake/serialize_utils.py +++ b/latch_cli/snakemake/serialize_utils.py @@ -1,4 +1,4 @@ -from typing import Union +from typing import Dict, TypeAlias, Union from flytekit import LaunchPlan from flytekit.configuration import SerializationSettings @@ -16,28 +16,31 @@ from flytekit.models.core import workflow as workflow_model from flytekit.models.core.workflow import TaskNodeOverrides -FlyteLocalEntity = Union[ +FlyteLocalEntity: TypeAlias = Union[ PythonTask, Node, LaunchPlan, WorkflowBase, ] -FlyteSerializableModel = Union[ +FlyteSerializableModel: TypeAlias = Union[ task_models.TaskSpec, workflow_model.Node, launch_plan_models.LaunchPlan, admin_workflow_models.WorkflowSpec, ] -EntityCache = dict[FlyteLocalEntity, FlyteSerializableModel] +EntityCache: TypeAlias = Dict[FlyteLocalEntity, FlyteSerializableModel] def get_serializable_launch_plan( - settings: SerializationSettings, entity: LaunchPlan, + settings: SerializationSettings, cache: EntityCache, ) -> launch_plan_models.LaunchPlan: + if entity in cache: + return cache[entity] + wf_id = identifier_model.Identifier( resource_type=identifier_model.ResourceType.WORKFLOW, project=settings.project, @@ -45,7 +48,6 @@ def get_serializable_launch_plan( name=entity.workflow.name, version=settings.version, ) - raw = None lps = launch_plan_models.LaunchPlanSpec( workflow_id=wf_id, @@ -58,9 +60,7 @@ def get_serializable_launch_plan( labels=common_models.Labels({}), annotations=entity.annotations or common_models.Annotations({}), auth_role=None, - raw_output_data_config=raw - or entity.raw_output_data_config - or common_models.RawOutputDataConfig(""), + raw_output_data_config=None, max_parallelism=entity.max_parallelism, security_context=entity.security_context, ) @@ -81,6 +81,7 @@ def get_serializable_launch_plan( expected_outputs=interface_models.VariableMap({}), ), ) + cache[entity] = lp_model return lp_model From 72ee0738963603ef49866a14afc776f707b5b577 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Tue, 30 May 2023 20:15:50 -0700 Subject: [PATCH 025/356] more pr comments --- latch_cli/services/serialize.py | 6 +- latch_cli/snakemake/serialize_utils.py | 25 +++- latch_cli/snakemake/workflow.py | 155 ++++++++++++------------- 3 files changed, 100 insertions(+), 86 deletions(-) diff --git a/latch_cli/services/serialize.py b/latch_cli/services/serialize.py index fc25d236..9fd4fb2f 100644 --- a/latch_cli/services/serialize.py +++ b/latch_cli/services/serialize.py @@ -122,7 +122,7 @@ def serialize_snakemake( parameters=parameter_map, fixed_inputs=literals_models.LiteralMap(literals={}), ) - admin_lp = get_serializable_launch_plan(settings, lp, registrable_entity_cache) + admin_lp = get_serializable_launch_plan(lp, settings, registrable_entity_cache) registrable_entities = [ x.to_flyte_idl() @@ -145,7 +145,9 @@ def generate_snakemake_entrypoint( from latch import small_task from latch.types import LatchFile - def ensure_parents_exist(path: Path): + def check_exists_and_ensure_parents(path: Path): + if path.exists(): + print(f"A file already exists at {path} and will be overwritten.") path.parent.mkdir(parents=True, exist_ok=True) return path """) diff --git a/latch_cli/snakemake/serialize_utils.py b/latch_cli/snakemake/serialize_utils.py index 77383c95..d674adee 100644 --- a/latch_cli/snakemake/serialize_utils.py +++ b/latch_cli/snakemake/serialize_utils.py @@ -58,9 +58,17 @@ def get_serializable_launch_plan( default_inputs=entity.parameters, fixed_inputs=entity.fixed_inputs, labels=common_models.Labels({}), - annotations=entity.annotations or common_models.Annotations({}), + annotations=( + entity.annotations + if entity.annotations is not None + else common_models.Annotations({}) + ), auth_role=None, - raw_output_data_config=None, + raw_output_data_config=( + entity.raw_output_data_config + if entity.raw_output_data_config is not None + else common_models.RawOutputDataConfig("") + ), max_parallelism=entity.max_parallelism, security_context=entity.security_context, ) @@ -123,6 +131,10 @@ def get_serializable_task( return task_model +class SerializationError(Exception): + pass + + def get_serializable_node( entity: Node, settings: SerializationSettings, @@ -132,7 +144,9 @@ def get_serializable_node( return cache[entity] if entity.flyte_entity is None: - raise Exception(f"Node {entity.id} has no flyte entity") + raise SerializationError( + f"SnakemakeWorkflow Node {entity.id} has no task and cannot be serialized." + ) upstream_sdk_nodes = [ get_serializable_node(n, settings, cache) @@ -156,8 +170,9 @@ def get_serializable_node( cache[entity] = node_model return node_model else: - raise Exception( - f"Node contained non-serializable entity {entity._flyte_entity}" + raise SerializationError( + "Cannot serialize a SnakemakeWorkflow node {entity.id} containing a task" + f" of type {entity._flyte_entity}.The task must be a PythonTask." ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index f673451e..1e228c73 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -2,7 +2,7 @@ import typing from dataclasses import dataclass from pathlib import Path -from typing import Any, Dict, List, Optional, TypeAlias, TypeVar, Union +from typing import Any, Dict, List, Optional, Tuple, Type, TypeAlias, TypeVar, Union import snakemake from flytekit.configuration import SerializationSettings @@ -35,15 +35,28 @@ SnakemakeInputVal: TypeAlias = snakemake.io._IOFile +T = TypeVar("T") + + +@dataclass +class JobOutputInfo: + jobid: str + output_param_name: str + + +def task_fn_placeholder(): + ... + + def variable_name_for_file(file: snakemake.io.AnnotatedString): return file.replace("/", "_").replace(".", "__").replace("-", "____") def variable_name_for_value( val: SnakemakeInputVal, - params: Union[snakemake.io.InputFiles, snakemake.io.OutputFiles] = None, + params: Union[snakemake.io.InputFiles, snakemake.io.OutputFiles, None] = None, ) -> str: - if params: + if params is not None: for name, v in params.items(): if val == v: return name @@ -60,7 +73,7 @@ def snakemake_dag_to_interface( for x in target.input: outputs[variable_name_for_value(x, target.input)] = LatchFile - inputs: Dict[str, LatchFile] = {} + inputs: Dict[str, Tuple[LatchFile, None]] = {} for job in dag.jobs: dep_outputs = [] for dep, dep_files in dag.dependencies[job].items(): @@ -81,8 +94,8 @@ def snakemake_dag_to_interface( def binding_data_from_python( expected_literal_type: type_models.LiteralType, t_value: typing.Any, - t_value_type: Optional[type] = None, -) -> literals_models.BindingData: + t_value_type: Optional[Type] = None, +) -> Optional[literals_models.BindingData]: if isinstance(t_value, Promise): if not t_value.is_ready: return literals_models.BindingData(promise=t_value.ref) @@ -92,7 +105,7 @@ def binding_from_python( var_name: str, expected_literal_type: type_models.LiteralType, t_value: typing.Any, - t_value_type: type, + t_value_type: Type, ) -> literals_models.Binding: binding_data = binding_data_from_python( expected_literal_type, t_value, t_value_type @@ -100,14 +113,16 @@ def binding_from_python( return literals_models.Binding(var=var_name, binding=binding_data) -def transform_type(x: type, description: str = None) -> interface_models.Variable: +def transform_type( + x: Type, description: Optional[str] = None +) -> interface_models.Variable: return interface_models.Variable( type=TypeEngine.to_literal_type(x), description=description ) def transform_types_in_variable_map( - variable_map: Dict[str, type], + variable_map: Dict[str, Type], descriptions: Dict[str, str] = {}, ) -> Dict[str, interface_models.Variable]: res = {} @@ -118,7 +133,7 @@ def transform_types_in_variable_map( def interface_to_parameters( - interface: Interface, + interface: Optional[Interface], ) -> interface_models.ParameterMap: if interface is None or interface.inputs_with_defaults is None: return interface_models.ParameterMap({}) @@ -129,14 +144,13 @@ def interface_to_parameters( interface.inputs, interface.docstring.input_descriptions ) params: Dict[str, interface_models.ParameterMap] = {} - inputs_with_def = interface.inputs_with_defaults for k, v in inputs_vars.items(): - val, _default = inputs_with_def[k] - required = _default is None + val, default = interface.inputs_with_defaults[k] + required = default is None default_lv = None - if _default is not None: + if default is not None: default_lv = TypeEngine.to_literal( - None, _default, python_type=interface.inputs[k], expected=v.type + None, default, python_type=interface.inputs[k], expected=v.type ) params[k] = interface_models.Parameter( var=v, default=default_lv, required=required @@ -220,11 +234,6 @@ def compile(self, **kwargs): target_file_for_output_param[param] = x python_outputs[param] = LatchFile - @dataclass - class JobOutputInfo: - jobid: str - output_param_name: str - dep_outputs = {} for dep, dep_files in self._dag.dependencies[job].items(): for o in dep.output: @@ -258,9 +267,8 @@ class JobOutputInfo: self.snakemake_tasks.append(task) typed_interface = transform_interface_to_typed_interface(interface) - self.interface.inputs.keys() - bindings = [] - for k in sorted(interface.inputs): + bindings: List[literals_models.Binding] = [] + for k in interface.inputs: var = typed_interface.inputs[k] if var.description in promise_map: job_output_info = promise_map[var.description] @@ -299,20 +307,9 @@ class JobOutputInfo: ) node_map[job.jobid] = node - bindings = [] - output_names = list(self.interface.outputs.keys()) - for i, out in enumerate(output_names): - - def find_upstream_node(): - for j in self._dag.targetjobs: - for depen, files in self._dag.dependencies[j].items(): - for f in files: - if variable_name_for_file(f) == out: - return depen.jobid, variable_name_for_value( - f, depen.output - ) - - upstream_id, upstream_var = find_upstream_node() + bindings: List[literals_models.Binding] = [] + for i, out in enumerate(self.interface.outputs.keys()): + upstream_id, upstream_var = self.find_upstream_node_matching_output_var(out) promise_to_bind = Promise( var=out, val=NodeOutput(node=node_map[upstream_id], var=upstream_var), @@ -329,13 +326,17 @@ def find_upstream_node(): self._nodes = list(node_map.values()) self._output_bindings = bindings + def find_upstream_node_matching_output_var(self, out_var: str): + for j in self._dag.targetjobs: + for depen, files in self._dag.dependencies[j].items(): + for f in files: + if variable_name_for_file(f) == out_var: + return depen.jobid, variable_name_for_value(f, depen.output) + def execute(self, **kwargs): return exception_scopes.user_entry_point(self._workflow_function)(**kwargs) -T = TypeVar("T") - - class SnakemakeJobTask(PythonAutoContainerTask[T]): def __init__( self, @@ -357,10 +358,7 @@ def __init__( self._target_file_for_input_param = target_file_for_input_param self._target_file_for_output_param = target_file_for_output_param - def placeholder(): - ... - - self._task_function = placeholder + self._task_function = task_fn_placeholder super().__init__( task_type=task_type, @@ -374,22 +372,22 @@ def get_fn_code(self, snakefile_path_in_container: str): code_block = "" fn_interface = f"\n\n@small_task\ndef {self.name}(" - for idx, (param, t) in enumerate(self._python_inputs.items()): - fn_interface += f"{param}: {t.__name__}" - if idx == len(self._python_inputs) - 1: - fn_interface += ")" - else: - fn_interface += ", " + fn_interface += ( + "(" + + ", ".join( + f"{param}: {t.__name__}" for param, t in self._python_inputs.items() + ) + + ")" + ) if len(self._python_outputs.items()) > 0: - for idx, (param, t) in enumerate(self._python_outputs.items()): - if idx == 0: - fn_interface += f" -> NamedTuple('{self.name}_output', " - fn_interface += f"{param}={t.__name__}" - if idx == len(self._python_outputs) - 1: - fn_interface += "):" - else: - fn_interface += ", " + fn_interface += ( + f" -> NamedTuple('{self.name}_output', " + + ", ".join( + f"{param}={t.__name__}" for param, t in self._python_outputs.items() + ) + + "):" + ) else: fn_interface += ":" @@ -397,17 +395,23 @@ def get_fn_code(self, snakefile_path_in_container: str): for param, t in self._python_inputs.items(): if t == LatchFile: - code_block += f'\n\tPath({param}).resolve().rename(ensure_parents_exist(Path("{self._target_file_for_input_param[param]}")))' - - snakemake_cmd = ["snakemake"] - snakemake_cmd.extend(["-s", snakefile_path_in_container]) - snakemake_cmd.extend( - ["--target-jobs", *encode_target_jobs_cli_args(self.job.get_target_spec())] - ) - snakemake_cmd.extend(["--allowed-rules", *self.job.rules]) - snakemake_cmd.extend(["--local-groupid", str(self.job.jobid)]) - snakemake_cmd.extend(["--cores", str(self.job.threads)]) - + code_block += f'\n\tPath({param}).resolve().rename(check_exists_and_ensure_parents(Path("{self._target_file_for_input_param[param]}")))' + + snakemake_cmd = [ + "snakemake", + "-s", + snakefile_path_in_container, + "--target-jobs", + *encode_target_jobs_cli_args(self.job.get_target_spec()), + "--allowed-rules", + *self.job.rules, + "--allowed-rules", + *self.job.rules, + "--local-groupid", + str(self.job.jobid), + "--cores", + str(self.job.threads), + ] if not self.job.is_group(): snakemake_cmd.append("--force-use-threads") @@ -420,16 +424,9 @@ def get_fn_code(self, snakefile_path_in_container: str): for resource, value in allowed_resources: snakemake_cmd.append(f"{resource}={value}") - formatted_snakemake_cmd = "\n\n\tsubprocess.run([" - - for i, arg in enumerate(snakemake_cmd): - arg_wo_quotes = arg.strip('"').strip("'") - formatted_snakemake_cmd += f'"{arg_wo_quotes}"' - if i == len(snakemake_cmd) - 1: - formatted_snakemake_cmd += "], check=True)" - else: - formatted_snakemake_cmd += ", " - code_block += formatted_snakemake_cmd + code_block += ( + "\n\n\tsubprocess.run({repr(formatted_snakemake_cmd)}, check=True)" + ) return_stmt = "\n\treturn (" for i, x in enumerate(self._python_outputs): From 55343dd6cb8c5ac5e48131359e9f0d7163b79350 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Thu, 1 Jun 2023 08:42:16 -0700 Subject: [PATCH 026/356] rebase conflicts --- latch_cli/services/init/init.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/latch_cli/services/init/init.py b/latch_cli/services/init/init.py index 0efc85dc..c90c6066 100644 --- a/latch_cli/services/init/init.py +++ b/latch_cli/services/init/init.py @@ -298,15 +298,6 @@ def init( else template_flag_to_option[template] ) -<<<<<<< HEAD -======= - if base_image_type_str not in BaseImageOptions.__members__: - raise ValueError( - f"Invalid base image type: {base_image_type_str}. Must be one of" - f" {list(BaseImageOptions.__members__.keys())}" - ) - ->>>>>>> 9ddde0b (black 23.3.0) if selected_option is None: return False From 80835cd3afb54e97e8ba3e02effbd6ae5174eb6b Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Thu, 1 Jun 2023 13:10:02 -0700 Subject: [PATCH 027/356] fixes --- latch_cli/snakemake/workflow.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 1e228c73..4c7ee3d5 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -373,8 +373,7 @@ def get_fn_code(self, snakefile_path_in_container: str): fn_interface = f"\n\n@small_task\ndef {self.name}(" fn_interface += ( - "(" - + ", ".join( + ", ".join( f"{param}: {t.__name__}" for param, t in self._python_inputs.items() ) + ")" @@ -424,9 +423,7 @@ def get_fn_code(self, snakefile_path_in_container: str): for resource, value in allowed_resources: snakemake_cmd.append(f"{resource}={value}") - code_block += ( - "\n\n\tsubprocess.run({repr(formatted_snakemake_cmd)}, check=True)" - ) + code_block += f"\n\n\tsubprocess.run({repr(snakemake_cmd)}, check=True)" return_stmt = "\n\treturn (" for i, x in enumerate(self._python_outputs): From cc45dc68bf8c8d185fa24847036d916b33551864 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Sat, 24 Jun 2023 14:37:31 -0700 Subject: [PATCH 028/356] rebase fixes --- latch/types/metadata.py | 16 +- latch_cli/centromere/ctx.py | 1 + latch_cli/services/register/register.py | 30 ++- latch_cli/services/register/utils.py | 24 +- latch_cli/services/serialize.py | 130 +++++++++- latch_cli/snakemake/workflow.py | 331 +++++++++++++++++++++--- 6 files changed, 463 insertions(+), 69 deletions(-) diff --git a/latch/types/metadata.py b/latch/types/metadata.py index af7866a1..095601fd 100644 --- a/latch/types/metadata.py +++ b/latch/types/metadata.py @@ -6,6 +6,8 @@ import yaml +from latch.types.directory import LatchDir + @dataclass class LatchRule: @@ -376,7 +378,7 @@ def wf(read1: LatchFile): """ display_name: str - """The name of the workflow""" + """The display name of the workflow""" author: LatchAuthor """ A `LatchAuthor` object that describes the author of the workflow""" documentation: Optional[str] = None @@ -428,3 +430,15 @@ def _parameter_str(t: Tuple[str, LatchParameter]): return ( metadata_yaml + "Args:\n" + indent(parameter_yaml, " ", lambda _: True) ).strip("\n ") + + +@dataclass +class SnakemakeMetadata(LatchMetadata): + output_dir: Optional[LatchDir] = None + + def __post_init__(self): + global _snakemake_metadata + _snakemake_metadata = self + + +_snakemake_metadata: Optional[SnakemakeMetadata] = None diff --git a/latch_cli/centromere/ctx.py b/latch_cli/centromere/ctx.py index d4aaf202..377867b7 100644 --- a/latch_cli/centromere/ctx.py +++ b/latch_cli/centromere/ctx.py @@ -403,6 +403,7 @@ def nucleus_check_version(self, version: str, workflow_name: str) -> bool: ) resp = response.json() + print(resp) try: return resp["exists"] except KeyError as e: diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index 24819587..341cef17 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -12,7 +12,8 @@ from scp import SCPClient from latch_cli.centromere.ctx import _CentromereCtx -from latch_cli.centromere.utils import _construct_ssh_client, _TmpDir +from latch_cli.centromere.utils import _TmpDir +from latch_cli.config.user import user_config from latch_cli.services.register.constants import ANSI_REGEX, MAX_LINES from latch_cli.services.register.utils import ( build_image, @@ -22,8 +23,8 @@ ) from latch_cli.services.serialize import ( extract_snakemake_workflow, - generate_snakemake_entrypoint, - serialize_snakemake, + generate_jit_register_code, + serialize_jit_register_workflow, ) from latch_cli.utils import WorkflowType, current_workspace @@ -162,13 +163,24 @@ def build_and_serialize( """Builds an image, serializes the workflow within the image, and pushes the image.""" if ctx.workflow_type == WorkflowType.snakemake: - _, wf = extract_snakemake_workflow(ctx.snakefile) - generate_snakemake_entrypoint(wf, ctx, ctx.snakefile) + wf = extract_snakemake_workflow(ctx.snakefile) + generate_jit_register_code( + wf, + ctx.pkg_root, + ctx.snakefile, + ctx.version, + image_name, + user_config.workspace_id, + ) image_build_logs = build_image(ctx, image_name, context_path, dockerfile) print_and_write_build_logs(image_build_logs, image_name, ctx.pkg_root) - if ctx.workflow_type == WorkflowType.latchbiosdk: + if ctx.workflow_type == WorkflowType.snakemake: + serialize_jit_register_workflow( + ctx.pkg_root, ctx.snakefile, tmp_dir, image_name, ctx.dkr_repo + ) + else: serialize_logs, container_id = serialize_pkg_in_container( ctx, image_name, tmp_dir ) @@ -178,10 +190,6 @@ def build_and_serialize( raise ValueError( f"Serialization exited with nonzero exit code: {exit_status['Error']}" ) - else: - serialize_snakemake( - ctx.pkg_root, ctx.snakefile, tmp_dir, image_name, ctx.dkr_repo - ) upload_image_logs = upload_image(ctx, image_name) print_upload_logs(upload_image_logs, image_name) @@ -373,7 +381,7 @@ def register( f"{container.dockerfile} given to {task_name} is invalid.", ) from e - reg_resp = register_serialized_pkg(ctx, protos) + reg_resp = register_serialized_pkg(protos, ctx.token, ctx.version) _print_reg_resp(reg_resp, ctx.default_container.image_name) click.secho( diff --git a/latch_cli/services/register/utils.py b/latch_cli/services/register/utils.py index dde52fd0..8ab2b7b9 100644 --- a/latch_cli/services/register/utils.py +++ b/latch_cli/services/register/utils.py @@ -2,6 +2,7 @@ import base64 import contextlib +import os from pathlib import Path from typing import List, Optional @@ -9,6 +10,7 @@ import requests from latch_cli.centromere.ctx import _CentromereCtx +from latch_cli.config.latch import config from latch_cli.utils import current_workspace @@ -102,11 +104,25 @@ def serialize_pkg_in_container( return [x.decode("utf-8") for x in logs], container_id -def register_serialized_pkg(ctx: _CentromereCtx, files: List[Path]) -> dict: - headers = {"Authorization": f"Bearer {ctx.token}"} +def register_serialized_pkg( + files: List[Path], + token: Optional[str], + version: str, + latch_register_url: str = config.api.workflow.register, +) -> dict: + if token is None: + token = os.environ.get("FLYTE_INTERNAL_EXECUTION_ID", "") + if token != "": + headers = {"Authorization": f"Latch-Execution-Token {token}"} + else: + raise OSError( + "The environment variable FLYTE_INTERNAL_EXECUTION_ID does not exist" + ) + else: + headers = {"Authorization": f"Bearer {token}"} serialize_files = { - "version": ctx.version.encode("utf-8"), + "version": version.encode("utf-8"), ".latch_ws": current_workspace().encode("utf-8"), } with contextlib.ExitStack() as stack: @@ -115,7 +131,7 @@ def register_serialized_pkg(ctx: _CentromereCtx, files: List[Path]) -> dict: serialize_files[fh.name] = fh response = requests.post( - ctx.latch_register_api_url, + latch_register_url, headers=headers, files=serialize_files, ) diff --git a/latch_cli/services/serialize.py b/latch_cli/services/serialize.py index 9fd4fb2f..14e5f645 100644 --- a/latch_cli/services/serialize.py +++ b/latch_cli/services/serialize.py @@ -72,7 +72,7 @@ def extract_dag(self): return dag -def extract_snakemake_workflow(snakefile: Path) -> (str, SnakemakeWorkflow): +def extract_snakemake_workflow(snakefile: Path) -> SnakemakeWorkflow: workflow = SnakemakeWorkflowExtractor( snakefile=snakefile, ) @@ -82,13 +82,10 @@ def extract_snakemake_workflow(snakefile: Path) -> (str, SnakemakeWorkflow): ) dag = workflow.extract_dag() - wf_name = "snakemake_wf" wf = SnakemakeWorkflow( - wf_name, dag, ) - wf.compile() - return wf_name, wf + return wf def serialize_snakemake( @@ -99,7 +96,8 @@ def serialize_snakemake( dkr_repo: str, ): pkg_root = Path(pkg_root).resolve() - _, wf = extract_snakemake_workflow(snakefile) + wf = extract_snakemake_workflow(snakefile) + wf.compile() image_name_no_version, version = image_name.split(":") default_img = Image( @@ -134,8 +132,56 @@ def serialize_snakemake( persist_registrable_entities(registrable_entities, output_dir) +def serialize_jit_register_workflow( + pkg_root: Path, + snakefile: Path, + output_dir: Path, + image_name: str, + dkr_repo: str, +): + pkg_root = Path(pkg_root).resolve() + wf = extract_snakemake_workflow(snakefile) + jit_wf = wf.build_jit_register_wrapper() + + image_name_no_version, version = image_name.split(":") + default_img = Image( + name=image_name, + fqn=f"{dkr_repo}/{image_name_no_version}", + tag=version, + ) + settings = SerializationSettings( + image_config=ImageConfig(default_image=default_img, images=[default_img]), + ) + + registrable_entity_cache: EntityCache = {} + + get_serializable_workflow(jit_wf, settings, registrable_entity_cache) + + parameter_map = interface_to_parameters(jit_wf.python_interface) + lp = LaunchPlan( + name=jit_wf.name, + workflow=jit_wf, + parameters=parameter_map, + fixed_inputs=literals_models.LiteralMap(literals={}), + ) + admin_lp = get_serializable_launch_plan(lp, settings, registrable_entity_cache) + + registrable_entities = [ + x.to_flyte_idl() + for x in list( + filter(should_register_with_admin, list(registrable_entity_cache.values())) + ) + + [admin_lp] + ] + persist_registrable_entities(registrable_entities, output_dir) + + +def snakefile_path_in_container(snakefile: Path, pkg_root: Path) -> str: + return str(snakefile.resolve())[len(str(pkg_root.resolve())) + 1 :] + + def generate_snakemake_entrypoint( - wf: SnakemakeWorkflow, ctx: _CentromereCtx, snakefile: Path + wf: SnakemakeWorkflow, pkg_root: Path, snakefile: Path ): entrypoint_code_block = textwrap.dedent("""\ import subprocess @@ -152,11 +198,71 @@ def check_exists_and_ensure_parents(path: Path): return path """) for task in wf.snakemake_tasks: - snakefile_path_in_container = str(snakefile.resolve())[ - len(str(ctx.pkg_root.resolve())) + 1 : - ] - entrypoint_code_block += task.get_fn_code(snakefile_path_in_container) + entrypoint_code_block += task.get_fn_code( + snakefile_path_in_container(snakefile, pkg_root) + ) - entrypoint = ctx.pkg_root.joinpath(".latch/latch_entrypoint.py") + entrypoint = pkg_root.joinpath("latch_entrypoint.py") with open(entrypoint, "w") as f: f.write(entrypoint_code_block) + + +def generate_jit_register_code( + wf: SnakemakeWorkflow, + pkg_root: Path, + snakefile: Path, + version: str, + image_name: str, + account_id: str, +) -> Path: + code_block = textwrap.dedent("""\ + import json + import os + import tempfile + import time + from functools import partial + from pathlib import Path + from typing import List, NamedTuple, Optional, TypedDict + + import google.protobuf.json_format as gpjson + import gql + import requests + from flyteidl.core import literals_pb2 as _literals_pb2 + from flytekit.core import utils + from flytekit.core.context_manager import FlyteContext + + from latch import small_task, workflow + from latch.gql._execute import execute + from latch.types import LatchFile + from latch_cli.config.latch import config + from latch_cli.services.register.register import ( + _print_reg_resp, + _recursive_list, + register_serialized_pkg, + ) + from latch_cli.services.serialize import ( + extract_snakemake_workflow, + generate_snakemake_entrypoint, + serialize_snakemake, + ) + + + print = partial(print, flush=True) + + def check_exists_and_ensure_parents(path: Path): + if path.exists(): + print(f"A file already exists at {path} and will be overwritten.") + path.parent.mkdir(parents=True, exist_ok=True) + return path + """) + code_block += wf.get_fn_code( + snakefile_path_in_container(snakefile, pkg_root), + version, + image_name, + account_id, + ) + + entrypoint = pkg_root.joinpath(".latch/jit_entrypoint.py") + with open(entrypoint, "w") as f: + f.write(code_block) + return entrypoint diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 4c7ee3d5..3018dc17 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1,4 +1,5 @@ import importlib +import textwrap import typing from dataclasses import dataclass from pathlib import Path @@ -30,7 +31,8 @@ from snakemake.dag import DAG from snakemake.target_jobs import encode_target_jobs_cli_args -from latch.types import LatchAuthor, LatchFile, LatchMetadata, LatchParameter +import latch.types.metadata as metadata +from latch.types import LatchAuthor, LatchFile, LatchParameter SnakemakeInputVal: TypeAlias = snakemake.io._IOFile @@ -38,6 +40,10 @@ T = TypeVar("T") +class JITRegisterWorkflow(WorkflowBase, ClassStorageTaskResolver): + ... + + @dataclass class JobOutputInfo: jobid: str @@ -66,14 +72,17 @@ def variable_name_for_value( def snakemake_dag_to_interface( dag: DAG, docstring: Optional[Docstring] = None -) -> Interface: +) -> (Interface, Dict[str, LatchFile], Dict[str, LatchFile]): outputs: Dict[str, LatchFile] = {} - + target_file_for_output_param: Dict[str, str] = {} for target in dag.targetjobs: for x in target.input: - outputs[variable_name_for_value(x, target.input)] = LatchFile + param = variable_name_for_value(x, target.input) + outputs[param] = LatchFile + target_file_for_output_param[param] = x inputs: Dict[str, Tuple[LatchFile, None]] = {} + target_file_for_input_param: Dict[str, str] = {} for job in dag.jobs: dep_outputs = [] for dep, dep_files in dag.dependencies[job].items(): @@ -83,12 +92,18 @@ def snakemake_dag_to_interface( for x in job.input: if x not in dep_outputs: - inputs[variable_name_for_value(x, job.input)] = ( + param = variable_name_for_value(x, job.input) + inputs[param] = ( LatchFile, None, ) + target_file_for_input_param[param] = x - return Interface(inputs, outputs, docstring=docstring) + return ( + Interface(inputs, outputs, docstring=docstring), + target_file_for_input_param, + target_file_for_output_param, + ) def binding_data_from_python( @@ -161,30 +176,27 @@ def interface_to_parameters( class SnakemakeWorkflow(WorkflowBase, ClassStorageTaskResolver): def __init__( self, - name: str, dag: DAG, ): - parameter_metadata: Dict[str, LatchParameter] = {} + parameter_metadata = metadata._snakemake_metadata.parameters for job in dag.jobs: for x in job.input: var = variable_name_for_value(x, job.input) - parameter_metadata[var] = LatchParameter(display_name=var) - - # TODO - support for metadata + parameters in future releases - latch_metadata = LatchMetadata( - display_name=name, - documentation="", - author=LatchAuthor( - name="", - email="", - github="", - ), - parameters=parameter_metadata, - tags=[], + if var not in parameter_metadata: + parameter_metadata[var] = LatchParameter(display_name=var) + + metadata._snakemake_metadata.parameters = parameter_metadata + name = metadata._snakemake_metadata.display_name + docstring = Docstring( + f"{name}\n\nSample Description\n\n" + str(metadata._snakemake_metadata) + ) + + native_interface, target_file_for_input_param, target_file_for_output_param = ( + snakemake_dag_to_interface(dag, docstring) ) - docstring = Docstring(f"{name}\n\nSample Description\n\n" + str(latch_metadata)) - native_interface = snakemake_dag_to_interface(dag, docstring) + self._target_file_for_input_param = target_file_for_input_param + self._target_file_for_output_param = target_file_for_output_param self._input_parameters = None self._dag = dag @@ -326,6 +338,82 @@ def compile(self, **kwargs): self._nodes = list(node_map.values()) self._output_bindings = bindings + def build_jit_register_wrapper(self) -> JITRegisterWorkflow: + workflow_metadata = WorkflowMetadata( + on_failure=WorkflowFailurePolicy.FAIL_IMMEDIATELY + ) + workflow_metadata_defaults = WorkflowMetadataDefaults(False) + python_interface = self.python_interface + wrapper_wf = JITRegisterWorkflow( + name=f"{self.name}_jit_register", + workflow_metadata=workflow_metadata, + workflow_metadata_defaults=workflow_metadata_defaults, + python_interface=python_interface, + ) + wrapper_wf._input_parameters = interface_to_parameters(python_interface) + + GLOBAL_START_NODE = Node( + id=_common_constants.GLOBAL_INPUT_NODE_ID, + metadata=None, + bindings=[], + upstream_nodes=[], + flyte_entity=None, + ) + + task_interface = Interface( + python_interface.inputs, python_interface.outputs, docstring=None + ) + task = PythonAutoContainerTask[T]( + name=f"{self.name}_jit_register_task", + task_type="python-task", + interface=task_interface, + task_config=None, + task_resolver=JITRegisterWorkflowResolver(), + ) + + task_bindings: List[literals_models.Binding] = [] + typed_interface = transform_interface_to_typed_interface(python_interface) + for k in python_interface.inputs: + var = typed_interface.inputs[k] + promise_to_bind = Promise( + var=k, + val=NodeOutput(node=GLOBAL_START_NODE, var=k), + ) + task_bindings.append( + binding_from_python( + var_name=k, + expected_literal_type=var.type, + t_value=promise_to_bind, + t_value_type=python_interface.inputs[k], + ) + ) + task_node = Node( + id=f"{self.name}_jit_register_node", + metadata=task.construct_node_metadata(), + bindings=sorted(task_bindings, key=lambda b: b.var), + upstream_nodes=[], + flyte_entity=task, + ) + + wf_bindings: List[literals_models.Binding] = [] + for i, out in enumerate(python_interface.outputs.keys()): + promise_to_bind = Promise( + var=out, + val=NodeOutput(node=task_node, var=out), + ) + t = python_interface.outputs[out] + b = binding_from_python( + out, + self.interface.outputs[out].type, + promise_to_bind, + t, + ) + wf_bindings.append(b) + + wrapper_wf._nodes = [task_node] + wrapper_wf._output_bindings = wf_bindings + return wrapper_wf + def find_upstream_node_matching_output_var(self, out_var: str): for j in self._dag.targetjobs: for depen, files in self._dag.dependencies[j].items(): @@ -336,6 +424,142 @@ def find_upstream_node_matching_output_var(self, out_var: str): def execute(self, **kwargs): return exception_scopes.user_entry_point(self._workflow_function)(**kwargs) + def get_fn_interface( + self, decorator_name="small_task", fn_name: Optional[str] = None + ): + if fn_name is None: + fn_name = self.name + fn_interface = f"\n\n@{decorator_name}\ndef {fn_name}(" + fn_interface += ( + ", ".join( + f"{param}: {t.__name__}" + for param, t in self.python_interface.inputs.items() + ) + + ")" + ) + + if len(self.python_interface.outputs) > 0: + fn_interface += ( + f" -> NamedTuple('{self.name}_output', " + + ", ".join( + f"{param}={t.__name__}" + for param, t in self.python_interface.outputs.items() + ) + + "):" + ) + else: + fn_interface += ":" + + return fn_interface + + def get_fn_return_stmt(self): + return_stmt = ( + "\n\treturn (" + + ", ".join( + f"LatchFile('{self._target_file_for_output_param[x]}')" + for x in self.python_interface.outputs + ) + + ")" + ) + + return return_stmt + + def get_fn_code( + self, snakefile_path: str, version: str, image_name: str, account_id: str + ): + task_name = f"{self.name}_jit_register_task" + code_block = "" + code_block += self.get_fn_interface(fn_name=task_name) + + for param, t in self.python_interface.inputs.items(): + if t == LatchFile: + code_block += f'\n\tPath({param}).resolve().rename(check_exists_and_ensure_parents(Path("{self._target_file_for_input_param[param]}")))' + + code_block += textwrap.indent( + textwrap.dedent(f""" + + image_name = "{image_name}" + version = "{version}" + account_id = "{account_id}" + snakefile = Path("{snakefile_path}") + + """), + "\t", + ) + + code_block += textwrap.indent( + textwrap.dedent(""" + pkg_root = Path(".") + + wf = extract_snakemake_workflow(snakefile) + wf_name = wf.name + generate_snakemake_entrypoint(wf, pkg_root, snakefile) + + temp_dir = tempfile.TemporaryDirectory() + with Path(temp_dir.name).resolve() as td: + serialize_snakemake(pkg_root, snakefile, td, image_name, config.dkr_repo) + + protos = _recursive_list(td) + reg_resp = register_serialized_pkg(protos, None, version) + _print_reg_resp(reg_resp, image_name) + + + class _WorkflowInfoNode(TypedDict): + id: str + + + nodes: Optional[List[_WorkflowInfoNode]] = None + while not nodes: + time.sleep(1) + nodes = execute( + gql.gql(''' + query workflowQuery($name: String, $ownerId: BigInt, $version: String) { + workflowInfos(condition: { name: $name, ownerId: $ownerId, version: $version}) { + nodes { + id + } + } + } + '''), + {"name": wf_name, "version": version, "ownerId": account_id}, + )["workflowInfos"]["nodes"] + + if len(nodes) > 1: + raise ValueError( + "Invariant violated - more than one workflow identified for unique combination" + " of {wf_name}, {version}, {account_id}" + ) + + print(nodes) + wf_id = nodes[0]["id"] + + + local_inputs_file = os.path.join(FlyteContext.execution_state.working_dir, "inputs.pb") + input_proto = utils.load_proto_from_file(_literals_pb2.LiteralMap, local_inputs_file) + + params = json.loads(gpjson.MessageToJson(input_proto))["literals"] + gpjson.MessageToJson() + + token = os.environ.get("FLYTE_INTERNAL_EXECUTION_ID", "") + headers = { + "Authorization": f"Latch-Execution-Token {token}", + } + + _interface_request = { + "workflow_id": wf_id, + "params": params, + "execution_token": token, + } + url = "https://console.ligma.ai/api/create-execution" + + response = requests.post(url, headers=headers, json=_interface_request) + print(response.json()) + """), + "\t", + ) + code_block += self.get_fn_return_stmt() + return code_block + class SnakemakeJobTask(PythonAutoContainerTask[T]): def __init__( @@ -368,9 +592,7 @@ def __init__( task_resolver=SnakemakeJobTaskResolver(), ) - def get_fn_code(self, snakefile_path_in_container: str): - code_block = "" - + def get_fn_interface(self): fn_interface = f"\n\n@small_task\ndef {self.name}(" fn_interface += ( ", ".join( @@ -390,7 +612,28 @@ def get_fn_code(self, snakefile_path_in_container: str): else: fn_interface += ":" - code_block += fn_interface + return fn_interface + + def get_fn_return_stmt(self): + return_stmt = "\n\treturn (" + for i, x in enumerate(self._python_outputs): + if self._is_target: + return_stmt += ( + f"LatchFile('{self._target_file_for_output_param[x]}'," + f" 'latch:///{self._target_file_for_output_param[x]}')" + ) + else: + return_stmt += f"LatchFile('{self._target_file_for_output_param[x]}')" + if i == len(self._python_outputs) - 1: + return_stmt += ")" + else: + return_stmt += ", " + + return return_stmt + + def get_fn_code(self, snakefile_path_in_container: str): + code_block = "" + code_block += self.get_fn_interface() for param, t in self._python_inputs.items(): if t == LatchFile: @@ -425,20 +668,7 @@ def get_fn_code(self, snakefile_path_in_container: str): code_block += f"\n\n\tsubprocess.run({repr(snakemake_cmd)}, check=True)" - return_stmt = "\n\treturn (" - for i, x in enumerate(self._python_outputs): - if self._is_target: - return_stmt += ( - f"LatchFile('{self._target_file_for_output_param[x]}'," - f" 'latch:///{self._target_file_for_output_param[x]}')" - ) - else: - return_stmt += f"LatchFile('{self._target_file_for_output_param[x]}')" - if i == len(self._python_outputs) - 1: - return_stmt += ")" - else: - return_stmt += ", " - code_block += return_stmt + code_block += self.get_fn_return_stmt() return code_block @property @@ -470,3 +700,22 @@ def load_task(self, loader_args: List[str]) -> PythonAutoContainerTask: task_def = getattr(task_module, task_name) return task_def + + +class JITRegisterWorkflowResolver(DefaultTaskResolver): + @property + def location(self) -> str: + return "flytekit.core.python_auto_container.default_task_resolver" + + def loader_args( + self, settings: SerializationSettings, task: PythonAutoContainerTask[T] + ) -> List[str]: + return ["task-module", "jit_entrypoint", "task-name", task.name] + + def load_task(self, loader_args: List[str]) -> PythonAutoContainerTask: + _, task_module, _, task_name, *_ = loader_args + + task_module = importlib.import_module(task_module) + + task_def = getattr(task_module, task_name) + return task_def From 7259282b4f657bab6ee67a86166ade06c63be48e Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Sat, 10 Jun 2023 12:26:49 -0700 Subject: [PATCH 029/356] changes to jit script --- latch_cli/services/register/register.py | 4 +++- latch_cli/services/register/utils.py | 3 ++- latch_cli/services/serialize.py | 1 + latch_cli/snakemake/workflow.py | 7 +++---- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index 341cef17..b87305c3 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -381,7 +381,9 @@ def register( f"{container.dockerfile} given to {task_name} is invalid.", ) from e - reg_resp = register_serialized_pkg(protos, ctx.token, ctx.version) + reg_resp = register_serialized_pkg( + protos, ctx.token, ctx.version, current_workspace().encode("utf-8") + ) _print_reg_resp(reg_resp, ctx.default_container.image_name) click.secho( diff --git a/latch_cli/services/register/utils.py b/latch_cli/services/register/utils.py index 8ab2b7b9..fb121978 100644 --- a/latch_cli/services/register/utils.py +++ b/latch_cli/services/register/utils.py @@ -108,6 +108,7 @@ def register_serialized_pkg( files: List[Path], token: Optional[str], version: str, + workspace_id: str, latch_register_url: str = config.api.workflow.register, ) -> dict: if token is None: @@ -123,7 +124,7 @@ def register_serialized_pkg( serialize_files = { "version": version.encode("utf-8"), - ".latch_ws": current_workspace().encode("utf-8"), + ".latch_ws": workspace_id, } with contextlib.ExitStack() as stack: file_handlers = [stack.enter_context(open(file, "rb")) for file in files] diff --git a/latch_cli/services/serialize.py b/latch_cli/services/serialize.py index 14e5f645..8ede29de 100644 --- a/latch_cli/services/serialize.py +++ b/latch_cli/services/serialize.py @@ -223,6 +223,7 @@ def generate_jit_register_code( from functools import partial from pathlib import Path from typing import List, NamedTuple, Optional, TypedDict + import inspect import google.protobuf.json_format as gpjson import gql diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 3018dc17..4da39d7a 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -500,7 +500,7 @@ def get_fn_code( serialize_snakemake(pkg_root, snakefile, td, image_name, config.dkr_repo) protos = _recursive_list(td) - reg_resp = register_serialized_pkg(protos, None, version) + reg_resp = register_serialized_pkg(protos, None, version, account_id) _print_reg_resp(reg_resp, image_name) @@ -533,12 +533,11 @@ class _WorkflowInfoNode(TypedDict): print(nodes) wf_id = nodes[0]["id"] - - local_inputs_file = os.path.join(FlyteContext.execution_state.working_dir, "inputs.pb") + exec_ctx = inspect.stack()[6][0].f_locals["ctx"] + local_inputs_file = os.path.join(exec_ctx.execution_state.working_dir, "inputs.pb") input_proto = utils.load_proto_from_file(_literals_pb2.LiteralMap, local_inputs_file) params = json.loads(gpjson.MessageToJson(input_proto))["literals"] - gpjson.MessageToJson() token = os.environ.get("FLYTE_INTERNAL_EXECUTION_ID", "") headers = { From 1f19f16c2aa276ab400b2a737c0afef3f6354d11 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Sat, 10 Jun 2023 13:23:42 -0700 Subject: [PATCH 030/356] single output parameter --- latch_cli/snakemake/workflow.py | 45 ++++++++++++++------------------- 1 file changed, 19 insertions(+), 26 deletions(-) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 4da39d7a..d1e3df84 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -343,7 +343,12 @@ def build_jit_register_wrapper(self) -> JITRegisterWorkflow: on_failure=WorkflowFailurePolicy.FAIL_IMMEDIATELY ) workflow_metadata_defaults = WorkflowMetadataDefaults(False) - python_interface = self.python_interface + out_parameter_name = "latch_entrypoint" + python_interface = Interface( + self.python_interface.inputs, + {out_parameter_name: LatchFile}, + docstring=self.python_interface.docstring, + ) wrapper_wf = JITRegisterWorkflow( name=f"{self.name}_jit_register", workflow_metadata=workflow_metadata, @@ -395,23 +400,20 @@ def build_jit_register_wrapper(self) -> JITRegisterWorkflow: flyte_entity=task, ) - wf_bindings: List[literals_models.Binding] = [] - for i, out in enumerate(python_interface.outputs.keys()): - promise_to_bind = Promise( - var=out, - val=NodeOutput(node=task_node, var=out), - ) - t = python_interface.outputs[out] - b = binding_from_python( - out, - self.interface.outputs[out].type, - promise_to_bind, - t, - ) - wf_bindings.append(b) + promise_to_bind = Promise( + var=out_parameter_name, + val=NodeOutput(node=task_node, var=out_parameter_name), + ) + t = python_interface.outputs[out_parameter_name] + output_binding = binding_from_python( + out_parameter_name, + LatchFile, + promise_to_bind, + t, + ) wrapper_wf._nodes = [task_node] - wrapper_wf._output_bindings = wf_bindings + wrapper_wf._output_bindings = [output_binding] return wrapper_wf def find_upstream_node_matching_output_var(self, out_var: str): @@ -453,16 +455,7 @@ def get_fn_interface( return fn_interface def get_fn_return_stmt(self): - return_stmt = ( - "\n\treturn (" - + ", ".join( - f"LatchFile('{self._target_file_for_output_param[x]}')" - for x in self.python_interface.outputs - ) - + ")" - ) - - return return_stmt + return "\n\treturn LatchFile('latch_entrypoint.py')" def get_fn_code( self, snakefile_path: str, version: str, image_name: str, account_id: str From 8055fba5456eab380c8e1f4c1fb1aeeb905708f3 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Sat, 10 Jun 2023 14:07:15 -0700 Subject: [PATCH 031/356] use execution name as version --- latch_cli/snakemake/workflow.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index d1e3df84..2c5ff9ff 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -472,7 +472,6 @@ def get_fn_code( textwrap.dedent(f""" image_name = "{image_name}" - version = "{version}" account_id = "{account_id}" snakefile = Path("{snakefile_path}") @@ -483,6 +482,7 @@ def get_fn_code( code_block += textwrap.indent( textwrap.dedent(""" pkg_root = Path(".") + version = os.environ.get("FLYTE_INTERNAL_EXECUTION_ID") wf = extract_snakemake_workflow(snakefile) wf_name = wf.name @@ -540,7 +540,6 @@ class _WorkflowInfoNode(TypedDict): _interface_request = { "workflow_id": wf_id, "params": params, - "execution_token": token, } url = "https://console.ligma.ai/api/create-execution" From b4d0de96d8226dd2b50acdeb666b4db8c168c6a9 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Sat, 24 Jun 2023 14:38:33 -0700 Subject: [PATCH 032/356] rebase fixes --- latch_cli/config/latch.py | 112 ++++++++++++++++++++ latch_cli/services/register/register.py | 1 - latch_cli/services/serialize.py | 38 +++---- latch_cli/snakemake/workflow.py | 129 +++++++++++++++++++----- latch_cli/utils.py | 5 +- 5 files changed, 238 insertions(+), 47 deletions(-) create mode 100644 latch_cli/config/latch.py diff --git a/latch_cli/config/latch.py b/latch_cli/config/latch.py new file mode 100644 index 00000000..06aec099 --- /dev/null +++ b/latch_cli/config/latch.py @@ -0,0 +1,112 @@ +""" +config.latch +~~~~~~~~~~~~ +Platform wide configuration, eg. api endpoints, callback server ports... +""" + +# todo(ayush): put all configs into a `latch-config` package + +import os +from dataclasses import dataclass, fields, is_dataclass +from typing import Type, TypeVar +from urllib.parse import urljoin + +DOMAIN = os.environ.get("LATCH_SDK_DOMAIN", "latch.bio") +CONSOLE_URL = f"https://console.{DOMAIN}" +NUCLEUS_URL = f"https://nucleus.{DOMAIN}" +VACUOLE_URL = f"https://vacuole.{DOMAIN}" + +T = TypeVar("T") + + +@dataclass +class _DataAPI: + id: str = "/sdk/node-id" + list: str = "/sdk/list" + remove: str = "/sdk/rm" + touch: str = "/sdk/touch" + mkdir: str = "/sdk/mkdir" + verify: str = "/sdk/verify" + test_data: str = "/sdk/get-test-data-creds" + + get_signed_url: str = "/ldata/get-signed-url" + get_signed_urls_recursive: str = "/ldata/get-signed-urls-recursive" + start_upload: str = "/ldata/start-upload" + end_upload: str = "/ldata/end-upload" + + +@dataclass +class _WorkflowAPI: + upload_image: str = "/sdk/initiate-image-upload" + get_image: str = "/sdk/get-image-from-task" + register: str = "/sdk/register-workflow" + list: str = "/sdk/get-wf" + interface: str = "/sdk/wf-interface" + graph: str = "/sdk/get-workflow-graph" + check_version: str = "/sdk/check-workflow-version" + get_latest: str = "/sdk/get-latest-version-new" + preview: str = "/sdk/workflow-ui-preview" + create_execution: str = "/api/create-execution" + + +@dataclass +class _ExecutionAPI: + create: str = "/sdk/wf" + list: str = "/sdk/get-executions" + abort: str = "/sdk/abort-execution" + logs: str = "/sdk/get-logs-for-node" + exec: str = "/sdk/get-pod-exec-info" + + +@dataclass +class _UserAPI: + jwt: str = "/sdk/access-jwt" + list_workspaces: str = "/sdk/get-ws" + get_secret: str = "/secrets/get" + get_secret_local: str = "/secrets/get-local" + + +@dataclass +class _CentromereAPI: + provision: str = "/sdk/provision-centromere" + start_local_dev: str = "/sdk/initiate-local-development-session" + stop_local_dev: str = "/sdk/close-local-development-session" + + +@dataclass +class _API: + data: _DataAPI + workflow: _WorkflowAPI + execution: _ExecutionAPI + user: _UserAPI + centromere: _CentromereAPI + + +@dataclass +class _ConsoleRoutes: + developer: str = urljoin(CONSOLE_URL, "/settings/developer") + + +@dataclass +class _LatchConfig: + api: _API + gql: str = f"{VACUOLE_URL}/graphql" + console_routes: _ConsoleRoutes = _ConsoleRoutes() + dkr_repo: str = "812206152185.dkr.ecr.us-west-2.amazonaws.com" + console_url: str = CONSOLE_URL + nucleus_url: str = NUCLEUS_URL + vacuole_url: str = VACUOLE_URL + + +def build_endpoints(x: Type[T]) -> T: + res = {} + for field in fields(x): + if is_dataclass(field.type): + res[field.name] = build_endpoints(field.type) + elif field.type is str: + res[field.name] = urljoin(NUCLEUS_URL, str(field.default)) + return x(**res) + + +# singleton config instance +config = _LatchConfig(api=build_endpoints(_API)) diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index b87305c3..9316ceda 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -342,7 +342,6 @@ def register( build_and_serialize( ctx, container.image_name, - # always use root as build context ctx.default_container.pkg_dir, task_td, dockerfile=container.dockerfile, diff --git a/latch_cli/services/serialize.py b/latch_cli/services/serialize.py index 8ede29de..e01c9bf5 100644 --- a/latch_cli/services/serialize.py +++ b/latch_cli/services/serialize.py @@ -81,24 +81,19 @@ def extract_snakemake_workflow(snakefile: Path) -> SnakemakeWorkflow: overwrite_default_target=True, ) dag = workflow.extract_dag() - wf = SnakemakeWorkflow( dag, ) + wf.compile() return wf def serialize_snakemake( - pkg_root: Path, - snakefile: Path, + wf: SnakemakeWorkflow, output_dir: Path, image_name: str, dkr_repo: str, ): - pkg_root = Path(pkg_root).resolve() - wf = extract_snakemake_workflow(snakefile) - wf.compile() - image_name_no_version, version = image_name.split(":") default_img = Image( name=image_name, @@ -216,36 +211,41 @@ def generate_jit_register_code( account_id: str, ) -> Path: code_block = textwrap.dedent("""\ + import inspect import json import os + import subprocess import tempfile + import textwrap import time from functools import partial from pathlib import Path from typing import List, NamedTuple, Optional, TypedDict - import inspect + import base64 + import boto3 import google.protobuf.json_format as gpjson import gql import requests from flyteidl.core import literals_pb2 as _literals_pb2 from flytekit.core import utils from flytekit.core.context_manager import FlyteContext + from latch_cli import tinyrequests + from latch_cli.centromere.utils import _construct_dkr_client + from latch_cli.config.latch import config + from latch_cli.services.register.register import (_print_reg_resp, + _recursive_list, + register_serialized_pkg, + print_and_write_build_logs, + print_upload_logs) + from latch_cli.services.serialize import (extract_snakemake_workflow, + generate_snakemake_entrypoint, + serialize_snakemake) + from latch_cli.utils import generate_temporary_ssh_credentials from latch import small_task, workflow from latch.gql._execute import execute from latch.types import LatchFile - from latch_cli.config.latch import config - from latch_cli.services.register.register import ( - _print_reg_resp, - _recursive_list, - register_serialized_pkg, - ) - from latch_cli.services.serialize import ( - extract_snakemake_workflow, - generate_snakemake_entrypoint, - serialize_snakemake, - ) print = partial(print, flush=True) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 2c5ff9ff..30dfd64f 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -437,25 +437,12 @@ def get_fn_interface( f"{param}: {t.__name__}" for param, t in self.python_interface.inputs.items() ) - + ")" + + ") -> bool:" ) - - if len(self.python_interface.outputs) > 0: - fn_interface += ( - f" -> NamedTuple('{self.name}_output', " - + ", ".join( - f"{param}={t.__name__}" - for param, t in self.python_interface.outputs.items() - ) - + "):" - ) - else: - fn_interface += ":" - return fn_interface def get_fn_return_stmt(self): - return "\n\treturn LatchFile('latch_entrypoint.py')" + return "\n\treturn True" def get_fn_code( self, snakefile_path: str, version: str, image_name: str, account_id: str @@ -488,13 +475,113 @@ def get_fn_code( wf_name = wf.name generate_snakemake_entrypoint(wf, pkg_root, snakefile) + dockerfile = Path("Dockerfile-dynamic").resolve() + dockerfile.write_text( + textwrap.dedent( + f''' + from 812206152185.dkr.ecr.us-west-2.amazonaws.com/{image_name} + + copy latch_entrypoint.py /root/latch_entrypoint.py + ''' + ) + ) + new_image_name = f"{image_name}-{version}" + + os.mkdir("/root/.ssh") + ssh_key_path = Path("/root/.ssh/id_rsa") + cmd = ["ssh-keygen", "-f", ssh_key_path, "-N", "", "-q"] + try: + subprocess.run(cmd, check=True) + except subprocess.CalledProcessError as e: + raise ValueError( + "There was a problem creating temporary SSH credentials. Please ensure" + " that `ssh-keygen` is installed and available in your PATH." + ) from e + os.chmod(ssh_key_path, 0o700) + + token = os.environ.get("FLYTE_INTERNAL_EXECUTION_ID", "") + headers = { + "Authorization": f"Latch-Execution-Token {token}", + } + + ssh_public_key_path = Path("/root/.ssh/id_rsa.pub") + response = tinyrequests.post( + config.api.centromere.provision, + headers=headers, + json={ + "public_key": ssh_public_key_path.read_text().strip(), + }, + ) + + resp = response.json() + try: + public_ip = resp["ip"] + username = resp["username"] + except KeyError as e: + raise ValueError( + f"Malformed response from request for centromere login: {resp}" + ) from e + + + subprocess.run(["ssh", "-o", "StrictHostKeyChecking=no", f"{username}@{public_ip}", "uptime"]) + dkr_client = _construct_dkr_client(ssh_host=f"ssh://{username}@{public_ip}") + + data = {"pkg_name": new_image_name.split(":")[0], "ws_account_id": account_id} + response = requests.post(config.api.workflow.upload_image, headers=headers, json=data) + + try: + response = response.json() + access_key = response["tmp_access_key"] + secret_key = response["tmp_secret_key"] + session_token = response["tmp_session_token"] + except KeyError as err: + raise ValueError(f"malformed response on image upload: {response}") from err + + try: + client = boto3.session.Session( + aws_access_key_id=access_key, + aws_secret_access_key=secret_key, + aws_session_token=session_token, + region_name="us-west-2", + ).client("ecr") + token = client.get_authorization_token()["authorizationData"][0][ + "authorizationToken" + ] + except Exception as err: + raise ValueError( + f"unable to retreive an ecr login token for user {account_id}" + ) from err + + user, password = base64.b64decode(token).decode("utf-8").split(":") + dkr_client.login( + username=user, + password=password, + registry=config.dkr_repo, + ) + + image_build_logs = dkr_client.build( + path=str(pkg_root), + dockerfile=str(dockerfile), + buildargs={"tag": f"{config.dkr_repo}/{new_image_name}"}, + tag=f"{config.dkr_repo}/{new_image_name}", + decode=True, + ) + print_and_write_build_logs(image_build_logs, new_image_name, pkg_root) + + upload_image_logs = dkr_client.push( + repository=f"{config.dkr_repo}/{new_image_name}", + stream=True, + decode=True, + ) + print_upload_logs(upload_image_logs, new_image_name) + temp_dir = tempfile.TemporaryDirectory() with Path(temp_dir.name).resolve() as td: - serialize_snakemake(pkg_root, snakefile, td, image_name, config.dkr_repo) + serialize_snakemake(wf, td, new_image_name, config.dkr_repo) protos = _recursive_list(td) reg_resp = register_serialized_pkg(protos, None, version, account_id) - _print_reg_resp(reg_resp, image_name) + _print_reg_resp(reg_resp, new_image_name) class _WorkflowInfoNode(TypedDict): @@ -532,18 +619,12 @@ class _WorkflowInfoNode(TypedDict): params = json.loads(gpjson.MessageToJson(input_proto))["literals"] - token = os.environ.get("FLYTE_INTERNAL_EXECUTION_ID", "") - headers = { - "Authorization": f"Latch-Execution-Token {token}", - } - _interface_request = { "workflow_id": wf_id, "params": params, } - url = "https://console.ligma.ai/api/create-execution" - response = requests.post(url, headers=headers, json=_interface_request) + response = requests.post(config.api.workflow.create_execution, headers=headers, json=_interface_request) print(response.json()) """), "\t", diff --git a/latch_cli/utils.py b/latch_cli/utils.py index 99fe94be..b6da44a8 100644 --- a/latch_cli/utils.py +++ b/latch_cli/utils.py @@ -201,8 +201,7 @@ def generate_temporary_ssh_credentials(ssh_key_path: Path) -> str: except subprocess.CalledProcessError as e: raise ValueError( "There was an issue adding temporary SSH credentials to your SSH Agent." - " Please ensure that your SSH Agent is running, or (re)start it manually by" - " running\n\n $ eval `ssh-agent -s`\n\n" + " Please ensure that your SSH Agent is running" ) from e # decode private key into public key @@ -266,7 +265,7 @@ def cleanup(self): and self._ssh_key_path.with_suffix(".pub").exists() ): subprocess.run( - ["ssh-add", "-d", self._ssh_key_path], + ["ssh-agent", "ssh-add", "-d", self._ssh_key_path], check=True, capture_output=True, ) From d7f591fc1c3346053a0ae4dd227fe9979a827713 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Thu, 15 Jun 2023 19:53:47 -0700 Subject: [PATCH 033/356] more stuff for dynamic registration --- latch/types/metadata.py | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/latch/types/metadata.py b/latch/types/metadata.py index 095601fd..ab16efd0 100644 --- a/latch/types/metadata.py +++ b/latch/types/metadata.py @@ -1,12 +1,14 @@ import re from dataclasses import asdict, dataclass, field from enum import Enum +from pathlib import Path from textwrap import indent -from typing import Dict, List, Optional, Tuple +from typing import Dict, List, Optional, Tuple, Union import yaml from latch.types.directory import LatchDir +from latch.types.file import LatchFile @dataclass @@ -125,6 +127,8 @@ class Section(FlowBase): display_name="Paired-end reads", description="FASTQ files", batch_table_column=True, + ), + batch_table_column=True, ), "single_end": LatchParameter( display_name="Single-end reads", @@ -330,6 +334,18 @@ def dict(self): return {"__metadata__": parameter_dict} +@dataclass +class SnakemakeFileParameter(LatchParameter): + type: Optional[Union[LatchFile, LatchDir]] = None + """ + The python type of the parameter. + """ + path: Optional[Path] = None + """ + The path where the file passed to this parameter will be copied. + """ + + @dataclass class LatchMetadata: """Class for organizing workflow metadata @@ -339,20 +355,6 @@ class LatchMetadata: ```python from latch.types import LatchMetadata, LatchAuthor, LatchRule, LatchAppearanceType - metadata = LatchMetadata( - parameters={ - "read1": LatchParameter( - display_name="Read 1", - description="Paired-end read 1 file to be assembled.", - hidden=True, - section_title="Sample Reads", - placeholder="Select a file", - comment="This is a comment", - output=False, - appearance_type=LatchAppearanceType.paragraph, - rules=[ - LatchRule( - regex="(.fasta|.fa|.faa|.fas)$", message="Only .fasta, .fa, .fas, or .faa extensions are valid" ) ], From 645ec0877959785369c2e92c575a725489302a87 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Thu, 15 Jun 2023 20:46:42 -0700 Subject: [PATCH 034/356] custom remote output url + input values for dynamic --- latch_cli/services/register/register.py | 5 +- latch_cli/services/serialize.py | 58 ++- latch_cli/snakemake/workflow.py | 581 +++++++++++++----------- 3 files changed, 361 insertions(+), 283 deletions(-) diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index 9316ceda..d86b9ff9 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -164,8 +164,9 @@ def build_and_serialize( if ctx.workflow_type == WorkflowType.snakemake: wf = extract_snakemake_workflow(ctx.snakefile) + jit_wf = wf.build_jit_register_wrapper() generate_jit_register_code( - wf, + jit_wf, ctx.pkg_root, ctx.snakefile, ctx.version, @@ -178,7 +179,7 @@ def build_and_serialize( if ctx.workflow_type == WorkflowType.snakemake: serialize_jit_register_workflow( - ctx.pkg_root, ctx.snakefile, tmp_dir, image_name, ctx.dkr_repo + jit_wf, ctx.pkg_root, ctx.snakefile, tmp_dir, image_name, ctx.dkr_repo ) else: serialize_logs, container_id = serialize_pkg_in_container( diff --git a/latch_cli/services/serialize.py b/latch_cli/services/serialize.py index e01c9bf5..77387177 100644 --- a/latch_cli/services/serialize.py +++ b/latch_cli/services/serialize.py @@ -2,7 +2,7 @@ import textwrap from itertools import chain, filterfalse from pathlib import Path -from typing import List, Set, Union, get_args +from typing import List, Optional, Set, Union, get_args from flytekit import LaunchPlan from flytekit.configuration import Image, ImageConfig, SerializationSettings @@ -16,13 +16,18 @@ from snakemake.rules import Rule from snakemake.workflow import Workflow +from latch.types.directory import LatchDir from latch_cli.centromere.ctx import _CentromereCtx from latch_cli.snakemake.serialize_utils import ( EntityCache, get_serializable_launch_plan, get_serializable_workflow, ) -from latch_cli.snakemake.workflow import SnakemakeWorkflow, interface_to_parameters +from latch_cli.snakemake.workflow import ( + JITRegisterWorkflow, + SnakemakeWorkflow, + interface_to_parameters, +) RegistrableEntity = Union[ task_models.TaskSpec, @@ -128,6 +133,7 @@ def serialize_snakemake( def serialize_jit_register_workflow( + jit_wf: JITRegisterWorkflow, pkg_root: Path, snakefile: Path, output_dir: Path, @@ -135,9 +141,6 @@ def serialize_jit_register_workflow( dkr_repo: str, ): pkg_root = Path(pkg_root).resolve() - wf = extract_snakemake_workflow(snakefile) - jit_wf = wf.build_jit_register_wrapper() - image_name_no_version, version = image_name.split(":") default_img = Image( name=image_name, @@ -176,25 +179,31 @@ def snakefile_path_in_container(snakefile: Path, pkg_root: Path) -> str: def generate_snakemake_entrypoint( - wf: SnakemakeWorkflow, pkg_root: Path, snakefile: Path + wf: SnakemakeWorkflow, + pkg_root: Path, + snakefile: Path, + remote_output_url: Optional[str] = None, ): entrypoint_code_block = textwrap.dedent("""\ - import subprocess + import os from pathlib import Path + import shutil + import subprocess from typing import NamedTuple from latch import small_task - from latch.types import LatchFile - - def check_exists_and_ensure_parents(path: Path): - if path.exists(): - print(f"A file already exists at {path} and will be overwritten.") - path.parent.mkdir(parents=True, exist_ok=True) - return path + from latch.types.file import LatchFile + + def check_exists_and_rename(old: Path, new: Path): + if new.exists(): + print(f"A file already exists at {new} and will be overwritten.") + if new.is_dir(): + shutil.rmtree(new) + os.renames(old, new) """) for task in wf.snakemake_tasks: entrypoint_code_block += task.get_fn_code( - snakefile_path_in_container(snakefile, pkg_root) + snakefile_path_in_container(snakefile, pkg_root), remote_output_url ) entrypoint = pkg_root.joinpath("latch_entrypoint.py") @@ -203,7 +212,7 @@ def check_exists_and_ensure_parents(path: Path): def generate_jit_register_code( - wf: SnakemakeWorkflow, + wf: JITRegisterWorkflow, pkg_root: Path, snakefile: Path, version: str, @@ -220,6 +229,7 @@ def generate_jit_register_code( import time from functools import partial from pathlib import Path + import shutil from typing import List, NamedTuple, Optional, TypedDict import base64 @@ -230,6 +240,7 @@ def generate_jit_register_code( from flyteidl.core import literals_pb2 as _literals_pb2 from flytekit.core import utils from flytekit.core.context_manager import FlyteContext + from flytekit.extras.persistence import LatchPersistence from latch_cli import tinyrequests from latch_cli.centromere.utils import _construct_dkr_client from latch_cli.config.latch import config @@ -245,22 +256,25 @@ def generate_jit_register_code( from latch import small_task, workflow from latch.gql._execute import execute - from latch.types import LatchFile + from latch.types.directory import LatchDir + from latch.types.file import LatchFile print = partial(print, flush=True) - def check_exists_and_ensure_parents(path: Path): - if path.exists(): - print(f"A file already exists at {path} and will be overwritten.") - path.parent.mkdir(parents=True, exist_ok=True) - return path + def check_exists_and_rename(old: Path, new: Path): + if new.exists(): + print(f"A file already exists at {new} and will be overwritten.") + if new.is_dir(): + shutil.rmtree(new) + os.renames(old, new) """) code_block += wf.get_fn_code( snakefile_path_in_container(snakefile, pkg_root), version, image_name, account_id, + wf.remote_output_url, ) entrypoint = pkg_root.joinpath(".latch/jit_entrypoint.py") diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 30dfd64f..392cdb43 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -4,6 +4,7 @@ from dataclasses import dataclass from pathlib import Path from typing import Any, Dict, List, Optional, Tuple, Type, TypeAlias, TypeVar, Union +from urllib.parse import urlparse import snakemake from flytekit.configuration import SerializationSettings @@ -28,11 +29,15 @@ from flytekit.models import interface as interface_models from flytekit.models import literals as literals_models from flytekit.models import types as type_models +from flytekit.models.core.types import BlobType +from flytekit.models.literals import Blob, BlobMetadata, Literal, LiteralMap, Scalar from snakemake.dag import DAG from snakemake.target_jobs import encode_target_jobs_cli_args import latch.types.metadata as metadata -from latch.types import LatchAuthor, LatchFile, LatchParameter +from latch.types.directory import LatchDir +from latch.types.file import LatchFile +from latch.types.metadata import LatchAuthor, LatchParameter SnakemakeInputVal: TypeAlias = snakemake.io._IOFile @@ -40,10 +45,6 @@ T = TypeVar("T") -class JITRegisterWorkflow(WorkflowBase, ClassStorageTaskResolver): - ... - - @dataclass class JobOutputInfo: jobid: str @@ -70,19 +71,24 @@ def variable_name_for_value( return variable_name_for_file(val.file) +@dataclass +class RemoteFile: + local_path: str + remote_path: str + + def snakemake_dag_to_interface( - dag: DAG, docstring: Optional[Docstring] = None -) -> (Interface, Dict[str, LatchFile], Dict[str, LatchFile]): + dag: DAG, wf_name: str, docstring: Optional[Docstring] = None +) -> (Interface, LiteralMap, List[RemoteFile]): outputs: Dict[str, LatchFile] = {} - target_file_for_output_param: Dict[str, str] = {} for target in dag.targetjobs: for x in target.input: param = variable_name_for_value(x, target.input) outputs[param] = LatchFile - target_file_for_output_param[param] = x + literals: Dict[str, Literal] = {} inputs: Dict[str, Tuple[LatchFile, None]] = {} - target_file_for_input_param: Dict[str, str] = {} + return_files: List[RemoteFile] = [] for job in dag.jobs: dep_outputs = [] for dep, dep_files in dag.dependencies[job].items(): @@ -97,12 +103,27 @@ def snakemake_dag_to_interface( LatchFile, None, ) - target_file_for_input_param[param] = x + remote_path = Path("/.snakemake_latch") / wf_name / x + remote_url = f"latch://{remote_path}" + return_files.append(RemoteFile(local_path=x, remote_path=remote_url)) + literals[param] = Literal( + scalar=Scalar( + blob=Blob( + metadata=BlobMetadata( + type=BlobType( + format="", + dimensionality=BlobType.BlobDimensionality.SINGLE, + ) + ), + uri=remote_url, + ) + ) + ) return ( Interface(inputs, outputs, docstring=docstring), - target_file_for_input_param, - target_file_for_output_param, + LiteralMap(literals=literals), + return_files, ) @@ -173,31 +194,283 @@ def interface_to_parameters( return interface_models.ParameterMap(params) -class SnakemakeWorkflow(WorkflowBase, ClassStorageTaskResolver): +class JITRegisterWorkflow(WorkflowBase, ClassStorageTaskResolver): + out_parameter_name = "success" + def __init__( self, - dag: DAG, ): parameter_metadata = metadata._snakemake_metadata.parameters - for job in dag.jobs: - for x in job.input: - var = variable_name_for_value(x, job.input) - if var not in parameter_metadata: - parameter_metadata[var] = LatchParameter(display_name=var) - metadata._snakemake_metadata.parameters = parameter_metadata - name = metadata._snakemake_metadata.display_name + display_name = metadata._snakemake_metadata.display_name + docstring = Docstring( - f"{name}\n\nSample Description\n\n" + str(metadata._snakemake_metadata) + f"{display_name}\n\nSample Description\n\n" + + str(metadata._snakemake_metadata) + ) + native_interface = Interface( + {k: v.type for k, v in parameter_metadata.items()}, + {self.out_parameter_name: bool}, + docstring=docstring, + ) + self.parameter_metadata = parameter_metadata + if metadata._snakemake_metadata.output_dir is not None: + self.remote_output_url = metadata._snakemake_metadata.output_dir.remote_path + else: + self.remote_output_url = None + + workflow_metadata = WorkflowMetadata( + on_failure=WorkflowFailurePolicy.FAIL_IMMEDIATELY + ) + name = f"{display_name}_jit_register" + workflow_metadata_defaults = WorkflowMetadataDefaults(False) + super().__init__( + name=name, + workflow_metadata=workflow_metadata, + workflow_metadata_defaults=workflow_metadata_defaults, + python_interface=native_interface, ) - native_interface, target_file_for_input_param, target_file_for_output_param = ( - snakemake_dag_to_interface(dag, docstring) + def get_fn_interface( + self, decorator_name="small_task", fn_name: Optional[str] = None + ): + if fn_name is None: + fn_name = self.name + fn_interface = f"\n\n@{decorator_name}\ndef {fn_name}(" + fn_interface += ( + ", ".join( + f"{param}: {t.__name__}" + for param, t in self.python_interface.inputs.items() + ) + + ") -> bool:" ) + return fn_interface + + def get_fn_return_stmt(self): + return "\n\treturn True" + + def get_fn_code( + self, + snakefile_path: str, + version: str, + image_name: str, + account_id: str, + remote_output_url: Optional[str], + ): + task_name = f"{self.name}_task" + code_block = "" + code_block += self.get_fn_interface(fn_name=task_name) + + for param, t in self.python_interface.inputs.items(): + if t in (LatchFile, LatchDir): + code_block += ( + f"\n\tcheck_exists_and_rename(Path({param}).resolve()," + f' Path("{self.parameter_metadata[param].path}"))' + ) + else: + raise ValueError(f"Unsupported parameter type {t} for {param}") + + code_block += textwrap.indent( + textwrap.dedent(f""" + + image_name = "{image_name}" + account_id = "{account_id}" + snakefile = Path("{snakefile_path}") + + """), + "\t", + ) + + if remote_output_url is not None: + remote_output_url = "'{remote_output_url}'" + code_block += textwrap.indent( + textwrap.dedent(f""" + pkg_root = Path(".") + version = os.environ.get("FLYTE_INTERNAL_EXECUTION_ID") + + wf = extract_snakemake_workflow(snakefile) + wf_name = wf.name + generate_snakemake_entrypoint(wf, pkg_root, snakefile, {remote_output_url}) + """), + "\t", + ) + + code_block += textwrap.indent( + textwrap.dedent(""" + dockerfile = Path("Dockerfile-dynamic").resolve() + dockerfile.write_text( + textwrap.dedent( + f''' + from 812206152185.dkr.ecr.us-west-2.amazonaws.com/{image_name} + + copy latch_entrypoint.py /root/latch_entrypoint.py + ''' + ) + ) + new_image_name = f"{image_name}-{version}" + + os.mkdir("/root/.ssh") + ssh_key_path = Path("/root/.ssh/id_rsa") + cmd = ["ssh-keygen", "-f", ssh_key_path, "-N", "", "-q"] + try: + subprocess.run(cmd, check=True) + except subprocess.CalledProcessError as e: + raise ValueError( + "There was a problem creating temporary SSH credentials. Please ensure" + " that `ssh-keygen` is installed and available in your PATH." + ) from e + os.chmod(ssh_key_path, 0o700) + + token = os.environ.get("FLYTE_INTERNAL_EXECUTION_ID", "") + headers = { + "Authorization": f"Latch-Execution-Token {token}", + } + + ssh_public_key_path = Path("/root/.ssh/id_rsa.pub") + response = tinyrequests.post( + config.api.centromere.provision, + headers=headers, + json={ + "public_key": ssh_public_key_path.read_text().strip(), + }, + ) + + resp = response.json() + try: + public_ip = resp["ip"] + username = resp["username"] + except KeyError as e: + raise ValueError( + f"Malformed response from request for centromere login: {resp}" + ) from e + + + subprocess.run(["ssh", "-o", "StrictHostKeyChecking=no", f"{username}@{public_ip}", "uptime"]) + dkr_client = _construct_dkr_client(ssh_host=f"ssh://{username}@{public_ip}") + + data = {"pkg_name": new_image_name.split(":")[0], "ws_account_id": account_id} + response = requests.post(config.api.workflow.upload_image, headers=headers, json=data) + + try: + response = response.json() + access_key = response["tmp_access_key"] + secret_key = response["tmp_secret_key"] + session_token = response["tmp_session_token"] + except KeyError as err: + raise ValueError(f"malformed response on image upload: {response}") from err + + try: + client = boto3.session.Session( + aws_access_key_id=access_key, + aws_secret_access_key=secret_key, + aws_session_token=session_token, + region_name="us-west-2", + ).client("ecr") + token = client.get_authorization_token()["authorizationData"][0][ + "authorizationToken" + ] + except Exception as err: + raise ValueError( + f"unable to retreive an ecr login token for user {account_id}" + ) from err + + user, password = base64.b64decode(token).decode("utf-8").split(":") + dkr_client.login( + username=user, + password=password, + registry=config.dkr_repo, + ) + + image_build_logs = dkr_client.build( + path=str(pkg_root), + dockerfile=str(dockerfile), + buildargs={"tag": f"{config.dkr_repo}/{new_image_name}"}, + tag=f"{config.dkr_repo}/{new_image_name}", + decode=True, + ) + print_and_write_build_logs(image_build_logs, new_image_name, pkg_root) + + upload_image_logs = dkr_client.push( + repository=f"{config.dkr_repo}/{new_image_name}", + stream=True, + decode=True, + ) + print_upload_logs(upload_image_logs, new_image_name) + + temp_dir = tempfile.TemporaryDirectory() + with Path(temp_dir.name).resolve() as td: + serialize_snakemake(wf, td, new_image_name, config.dkr_repo) + + protos = _recursive_list(td) + reg_resp = register_serialized_pkg(protos, None, version, account_id) + _print_reg_resp(reg_resp, new_image_name) + + + class _WorkflowInfoNode(TypedDict): + id: str + + + nodes: Optional[List[_WorkflowInfoNode]] = None + while not nodes: + time.sleep(1) + nodes = execute( + gql.gql(''' + query workflowQuery($name: String, $ownerId: BigInt, $version: String) { + workflowInfos(condition: { name: $name, ownerId: $ownerId, version: $version}) { + nodes { + id + } + } + } + '''), + {"name": wf_name, "version": version, "ownerId": account_id}, + )["workflowInfos"]["nodes"] + + if len(nodes) > 1: + raise ValueError( + "Invariant violated - more than one workflow identified for unique combination" + " of {wf_name}, {version}, {account_id}" + ) + + print(nodes) + + lp = LatchPersistence() + for file in wf.return_files: + print(f"Uploading {file.local_path} -> {file.remote_path}") + lp.upload(file.local_path, file.remote_path) + + wf_id = nodes[0]["id"] + params = json.loads(gpjson.MessageToJson(wf.literal_map.to_flyte_idl()))["literals"] + + _interface_request = { + "workflow_id": wf_id, + "params": params, + } + + response = requests.post(config.api.workflow.create_execution, headers=headers, json=_interface_request) + print(response.json()) + """), + "\t", + ) + code_block += self.get_fn_return_stmt() + return code_block - self._target_file_for_input_param = target_file_for_input_param - self._target_file_for_output_param = target_file_for_output_param +class SnakemakeWorkflow(WorkflowBase, ClassStorageTaskResolver): + def __init__( + self, + dag: DAG, + ): + name = metadata._snakemake_metadata.display_name + docstring = Docstring( + f"{name}\n\nSample Description\n\n" + str(metadata._snakemake_metadata) + ) + + native_interface, literal_map, return_files = snakemake_dag_to_interface( + dag, name, docstring + ) + self.literal_map = literal_map + self.return_files = return_files self._input_parameters = None self._dag = dag self.snakemake_tasks = [] @@ -339,22 +612,10 @@ def compile(self, **kwargs): self._output_bindings = bindings def build_jit_register_wrapper(self) -> JITRegisterWorkflow: - workflow_metadata = WorkflowMetadata( - on_failure=WorkflowFailurePolicy.FAIL_IMMEDIATELY - ) - workflow_metadata_defaults = WorkflowMetadataDefaults(False) - out_parameter_name = "latch_entrypoint" - python_interface = Interface( - self.python_interface.inputs, - {out_parameter_name: LatchFile}, - docstring=self.python_interface.docstring, - ) - wrapper_wf = JITRegisterWorkflow( - name=f"{self.name}_jit_register", - workflow_metadata=workflow_metadata, - workflow_metadata_defaults=workflow_metadata_defaults, - python_interface=python_interface, - ) + out_parameter_name = "success" + wrapper_wf = JITRegisterWorkflow() + + python_interface = wrapper_wf.python_interface wrapper_wf._input_parameters = interface_to_parameters(python_interface) GLOBAL_START_NODE = Node( @@ -369,7 +630,7 @@ def build_jit_register_wrapper(self) -> JITRegisterWorkflow: python_interface.inputs, python_interface.outputs, docstring=None ) task = PythonAutoContainerTask[T]( - name=f"{self.name}_jit_register_task", + name=f"{wrapper_wf.name}_task", task_type="python-task", interface=task_interface, task_config=None, @@ -393,7 +654,7 @@ def build_jit_register_wrapper(self) -> JITRegisterWorkflow: ) ) task_node = Node( - id=f"{self.name}_jit_register_node", + id=f"{wrapper_wf.name}_jit_register_node", metadata=task.construct_node_metadata(), bindings=sorted(task_bindings, key=lambda b: b.var), upstream_nodes=[], @@ -426,212 +687,6 @@ def find_upstream_node_matching_output_var(self, out_var: str): def execute(self, **kwargs): return exception_scopes.user_entry_point(self._workflow_function)(**kwargs) - def get_fn_interface( - self, decorator_name="small_task", fn_name: Optional[str] = None - ): - if fn_name is None: - fn_name = self.name - fn_interface = f"\n\n@{decorator_name}\ndef {fn_name}(" - fn_interface += ( - ", ".join( - f"{param}: {t.__name__}" - for param, t in self.python_interface.inputs.items() - ) - + ") -> bool:" - ) - return fn_interface - - def get_fn_return_stmt(self): - return "\n\treturn True" - - def get_fn_code( - self, snakefile_path: str, version: str, image_name: str, account_id: str - ): - task_name = f"{self.name}_jit_register_task" - code_block = "" - code_block += self.get_fn_interface(fn_name=task_name) - - for param, t in self.python_interface.inputs.items(): - if t == LatchFile: - code_block += f'\n\tPath({param}).resolve().rename(check_exists_and_ensure_parents(Path("{self._target_file_for_input_param[param]}")))' - - code_block += textwrap.indent( - textwrap.dedent(f""" - - image_name = "{image_name}" - account_id = "{account_id}" - snakefile = Path("{snakefile_path}") - - """), - "\t", - ) - - code_block += textwrap.indent( - textwrap.dedent(""" - pkg_root = Path(".") - version = os.environ.get("FLYTE_INTERNAL_EXECUTION_ID") - - wf = extract_snakemake_workflow(snakefile) - wf_name = wf.name - generate_snakemake_entrypoint(wf, pkg_root, snakefile) - - dockerfile = Path("Dockerfile-dynamic").resolve() - dockerfile.write_text( - textwrap.dedent( - f''' - from 812206152185.dkr.ecr.us-west-2.amazonaws.com/{image_name} - - copy latch_entrypoint.py /root/latch_entrypoint.py - ''' - ) - ) - new_image_name = f"{image_name}-{version}" - - os.mkdir("/root/.ssh") - ssh_key_path = Path("/root/.ssh/id_rsa") - cmd = ["ssh-keygen", "-f", ssh_key_path, "-N", "", "-q"] - try: - subprocess.run(cmd, check=True) - except subprocess.CalledProcessError as e: - raise ValueError( - "There was a problem creating temporary SSH credentials. Please ensure" - " that `ssh-keygen` is installed and available in your PATH." - ) from e - os.chmod(ssh_key_path, 0o700) - - token = os.environ.get("FLYTE_INTERNAL_EXECUTION_ID", "") - headers = { - "Authorization": f"Latch-Execution-Token {token}", - } - - ssh_public_key_path = Path("/root/.ssh/id_rsa.pub") - response = tinyrequests.post( - config.api.centromere.provision, - headers=headers, - json={ - "public_key": ssh_public_key_path.read_text().strip(), - }, - ) - - resp = response.json() - try: - public_ip = resp["ip"] - username = resp["username"] - except KeyError as e: - raise ValueError( - f"Malformed response from request for centromere login: {resp}" - ) from e - - - subprocess.run(["ssh", "-o", "StrictHostKeyChecking=no", f"{username}@{public_ip}", "uptime"]) - dkr_client = _construct_dkr_client(ssh_host=f"ssh://{username}@{public_ip}") - - data = {"pkg_name": new_image_name.split(":")[0], "ws_account_id": account_id} - response = requests.post(config.api.workflow.upload_image, headers=headers, json=data) - - try: - response = response.json() - access_key = response["tmp_access_key"] - secret_key = response["tmp_secret_key"] - session_token = response["tmp_session_token"] - except KeyError as err: - raise ValueError(f"malformed response on image upload: {response}") from err - - try: - client = boto3.session.Session( - aws_access_key_id=access_key, - aws_secret_access_key=secret_key, - aws_session_token=session_token, - region_name="us-west-2", - ).client("ecr") - token = client.get_authorization_token()["authorizationData"][0][ - "authorizationToken" - ] - except Exception as err: - raise ValueError( - f"unable to retreive an ecr login token for user {account_id}" - ) from err - - user, password = base64.b64decode(token).decode("utf-8").split(":") - dkr_client.login( - username=user, - password=password, - registry=config.dkr_repo, - ) - - image_build_logs = dkr_client.build( - path=str(pkg_root), - dockerfile=str(dockerfile), - buildargs={"tag": f"{config.dkr_repo}/{new_image_name}"}, - tag=f"{config.dkr_repo}/{new_image_name}", - decode=True, - ) - print_and_write_build_logs(image_build_logs, new_image_name, pkg_root) - - upload_image_logs = dkr_client.push( - repository=f"{config.dkr_repo}/{new_image_name}", - stream=True, - decode=True, - ) - print_upload_logs(upload_image_logs, new_image_name) - - temp_dir = tempfile.TemporaryDirectory() - with Path(temp_dir.name).resolve() as td: - serialize_snakemake(wf, td, new_image_name, config.dkr_repo) - - protos = _recursive_list(td) - reg_resp = register_serialized_pkg(protos, None, version, account_id) - _print_reg_resp(reg_resp, new_image_name) - - - class _WorkflowInfoNode(TypedDict): - id: str - - - nodes: Optional[List[_WorkflowInfoNode]] = None - while not nodes: - time.sleep(1) - nodes = execute( - gql.gql(''' - query workflowQuery($name: String, $ownerId: BigInt, $version: String) { - workflowInfos(condition: { name: $name, ownerId: $ownerId, version: $version}) { - nodes { - id - } - } - } - '''), - {"name": wf_name, "version": version, "ownerId": account_id}, - )["workflowInfos"]["nodes"] - - if len(nodes) > 1: - raise ValueError( - "Invariant violated - more than one workflow identified for unique combination" - " of {wf_name}, {version}, {account_id}" - ) - - print(nodes) - wf_id = nodes[0]["id"] - - exec_ctx = inspect.stack()[6][0].f_locals["ctx"] - local_inputs_file = os.path.join(exec_ctx.execution_state.working_dir, "inputs.pb") - input_proto = utils.load_proto_from_file(_literals_pb2.LiteralMap, local_inputs_file) - - params = json.loads(gpjson.MessageToJson(input_proto))["literals"] - - _interface_request = { - "workflow_id": wf_id, - "params": params, - } - - response = requests.post(config.api.workflow.create_execution, headers=headers, json=_interface_request) - print(response.json()) - """), - "\t", - ) - code_block += self.get_fn_return_stmt() - return code_block - class SnakemakeJobTask(PythonAutoContainerTask[T]): def __init__( @@ -686,14 +741,17 @@ def get_fn_interface(self): return fn_interface - def get_fn_return_stmt(self): + def get_fn_return_stmt(self, remote_output_url: Optional[str] = None): return_stmt = "\n\treturn (" for i, x in enumerate(self._python_outputs): if self._is_target: - return_stmt += ( - f"LatchFile('{self._target_file_for_output_param[x]}'," - f" 'latch:///{self._target_file_for_output_param[x]}')" - ) + target_path = self._target_file_for_output_param[x] + if remote_output_url is None: + remote_path = Path("/Snakemake Outputs") / target_path + else: + remote_path = Path(urlparse(remote_output_url).path) / target_path + + return_stmt += f"LatchFile('{target_path}', 'latch://{remote_path}')" else: return_stmt += f"LatchFile('{self._target_file_for_output_param[x]}')" if i == len(self._python_outputs) - 1: @@ -703,13 +761,18 @@ def get_fn_return_stmt(self): return return_stmt - def get_fn_code(self, snakefile_path_in_container: str): + def get_fn_code( + self, snakefile_path_in_container: str, remote_output_url: Optional[str] = None + ): code_block = "" code_block += self.get_fn_interface() for param, t in self._python_inputs.items(): if t == LatchFile: - code_block += f'\n\tPath({param}).resolve().rename(check_exists_and_ensure_parents(Path("{self._target_file_for_input_param[param]}")))' + code_block += ( + f"\n\tcheck_exists_and_rename(Path({param}).resolve()," + f' Path("{self._target_file_for_input_param[param]}"))' + ) snakemake_cmd = [ "snakemake", @@ -740,7 +803,7 @@ def get_fn_code(self, snakefile_path_in_container: str): code_block += f"\n\n\tsubprocess.run({repr(snakemake_cmd)}, check=True)" - code_block += self.get_fn_return_stmt() + code_block += self.get_fn_return_stmt(remote_output_url=remote_output_url) return code_block @property From 9e4e0031d66f073c112e278e939d29369bd226fe Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Fri, 16 Jun 2023 10:45:20 -0700 Subject: [PATCH 035/356] dynamic workflow named by execution id --- latch_cli/services/serialize.py | 6 ++---- latch_cli/snakemake/workflow.py | 10 ++++------ 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/latch_cli/services/serialize.py b/latch_cli/services/serialize.py index 77387177..703d254f 100644 --- a/latch_cli/services/serialize.py +++ b/latch_cli/services/serialize.py @@ -77,7 +77,7 @@ def extract_dag(self): return dag -def extract_snakemake_workflow(snakefile: Path) -> SnakemakeWorkflow: +def extract_snakemake_workflow(snakefile: Path, version: str) -> SnakemakeWorkflow: workflow = SnakemakeWorkflowExtractor( snakefile=snakefile, ) @@ -86,9 +86,7 @@ def extract_snakemake_workflow(snakefile: Path) -> SnakemakeWorkflow: overwrite_default_target=True, ) dag = workflow.extract_dag() - wf = SnakemakeWorkflow( - dag, - ) + wf = SnakemakeWorkflow(dag, version) wf.compile() return wf diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 392cdb43..b3b0cd2a 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -288,7 +288,7 @@ def get_fn_code( pkg_root = Path(".") version = os.environ.get("FLYTE_INTERNAL_EXECUTION_ID") - wf = extract_snakemake_workflow(snakefile) + wf = extract_snakemake_workflow(snakefile, version) wf_name = wf.name generate_snakemake_entrypoint(wf, pkg_root, snakefile, {remote_output_url}) """), @@ -460,14 +460,12 @@ class SnakemakeWorkflow(WorkflowBase, ClassStorageTaskResolver): def __init__( self, dag: DAG, + version: str, ): - name = metadata._snakemake_metadata.display_name - docstring = Docstring( - f"{name}\n\nSample Description\n\n" + str(metadata._snakemake_metadata) - ) + name = f"{metadata._snakemake_metadata.display_name}-{version}" native_interface, literal_map, return_files = snakemake_dag_to_interface( - dag, name, docstring + dag, name, None ) self.literal_map = literal_map self.return_files = return_files From 984e0445e182d4c1ebdfcdf4a77e5fe3fbf11d73 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Fri, 16 Jun 2023 14:42:22 -0700 Subject: [PATCH 036/356] support for custom output dir --- latch_cli/services/serialize.py | 4 +++- latch_cli/snakemake/workflow.py | 11 +++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/latch_cli/services/serialize.py b/latch_cli/services/serialize.py index 703d254f..87203a75 100644 --- a/latch_cli/services/serialize.py +++ b/latch_cli/services/serialize.py @@ -77,7 +77,9 @@ def extract_dag(self): return dag -def extract_snakemake_workflow(snakefile: Path, version: str) -> SnakemakeWorkflow: +def extract_snakemake_workflow( + snakefile: Path, version: Optional[str] = None +) -> SnakemakeWorkflow: workflow = SnakemakeWorkflowExtractor( snakefile=snakefile, ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index b3b0cd2a..2f86b0eb 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -282,7 +282,7 @@ def get_fn_code( ) if remote_output_url is not None: - remote_output_url = "'{remote_output_url}'" + remote_output_url = f"'{remote_output_url}'" code_block += textwrap.indent( textwrap.dedent(f""" pkg_root = Path(".") @@ -460,9 +460,12 @@ class SnakemakeWorkflow(WorkflowBase, ClassStorageTaskResolver): def __init__( self, dag: DAG, - version: str, + version: Optional[str] = None, ): - name = f"{metadata._snakemake_metadata.display_name}-{version}" + if version is not None: + name = f"{metadata._snakemake_metadata.display_name}-{version}" + else: + name = metadata._snakemake_metadata.display_name native_interface, literal_map, return_files = snakemake_dag_to_interface( dag, name, None @@ -666,7 +669,7 @@ def build_jit_register_wrapper(self) -> JITRegisterWorkflow: t = python_interface.outputs[out_parameter_name] output_binding = binding_from_python( out_parameter_name, - LatchFile, + bool, promise_to_bind, t, ) From 3b1741b0855864d412ed3ff5951b5e700b0059cf Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Sun, 18 Jun 2023 18:27:34 -0700 Subject: [PATCH 037/356] node name in jit workflow --- latch_cli/snakemake/workflow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 2f86b0eb..a6d8a045 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -655,7 +655,7 @@ def build_jit_register_wrapper(self) -> JITRegisterWorkflow: ) ) task_node = Node( - id=f"{wrapper_wf.name}_jit_register_node", + id="n0", metadata=task.construct_node_metadata(), bindings=sorted(task_bindings, key=lambda b: b.var), upstream_nodes=[], From 667d03da1fe83aff1bb1cbd0ac6a89f5d7efb90f Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Thu, 22 Jun 2023 10:30:17 -0700 Subject: [PATCH 038/356] check for metadata in snakefile --- latch_cli/services/register/register.py | 2 ++ latch_cli/services/serialize.py | 38 +++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index d86b9ff9..f8a81ff4 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -22,6 +22,7 @@ upload_image, ) from latch_cli.services.serialize import ( + ensure_snakemake_metadata_exists, extract_snakemake_workflow, generate_jit_register_code, serialize_jit_register_workflow, @@ -163,6 +164,7 @@ def build_and_serialize( """Builds an image, serializes the workflow within the image, and pushes the image.""" if ctx.workflow_type == WorkflowType.snakemake: + ensure_snakemake_metadata_exists() wf = extract_snakemake_workflow(ctx.snakefile) jit_wf = wf.build_jit_register_wrapper() generate_jit_register_code( diff --git a/latch_cli/services/serialize.py b/latch_cli/services/serialize.py index 87203a75..6939c2b9 100644 --- a/latch_cli/services/serialize.py +++ b/latch_cli/services/serialize.py @@ -1,7 +1,8 @@ import os import textwrap -from itertools import chain, filterfalse +from itertools import filterfalse from pathlib import Path +from textwrap import dedent from typing import List, Optional, Set, Union, get_args from flytekit import LaunchPlan @@ -16,8 +17,7 @@ from snakemake.rules import Rule from snakemake.workflow import Workflow -from latch.types.directory import LatchDir -from latch_cli.centromere.ctx import _CentromereCtx +import latch.types.metadata as metadata from latch_cli.snakemake.serialize_utils import ( EntityCache, get_serializable_launch_plan, @@ -77,6 +77,38 @@ def extract_dag(self): return dag +def ensure_snakemake_metadata_exists(): + if metadata._snakemake_metadata is None: + raise ValueError(dedent(""" + + No `SnakemakeMetadata` object was detected in your Snakefile. This + object needs to be defined to register this workflow with Latch. + + You can paste the following in the top of your Snakefile to get + started: + + ``` + from latch.types.metadata import SnakemakeMetadata, SnakemakeFileParameter + from latch.types.file import LatchFile + from latch.types.metadata import LatchAuthor, LatchMetadata + + SnakemakeMetadata( + display_name="My Snakemake Workflow", + author=LatchAuthor( + name="John Doe", + ), + parameters={ + "foo" : SnakemakeFileParameter( + display_name="Some Param", + type=LatchFile, + path=Path("foo.txt"), + ), + ``` + + Find more information at docs.latch.bio. + """)) + + def extract_snakemake_workflow( snakefile: Path, version: Optional[str] = None ) -> SnakemakeWorkflow: From a2acbd5f16715453339c21f6fd3f0df5f4657b0f Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Thu, 22 Jun 2023 11:27:37 -0700 Subject: [PATCH 039/356] fix --- latch_cli/services/register/register.py | 2 -- latch_cli/services/serialize.py | 5 ++++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index f8a81ff4..d86b9ff9 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -22,7 +22,6 @@ upload_image, ) from latch_cli.services.serialize import ( - ensure_snakemake_metadata_exists, extract_snakemake_workflow, generate_jit_register_code, serialize_jit_register_workflow, @@ -164,7 +163,6 @@ def build_and_serialize( """Builds an image, serializes the workflow within the image, and pushes the image.""" if ctx.workflow_type == WorkflowType.snakemake: - ensure_snakemake_metadata_exists() wf = extract_snakemake_workflow(ctx.snakefile) jit_wf = wf.build_jit_register_wrapper() generate_jit_register_code( diff --git a/latch_cli/services/serialize.py b/latch_cli/services/serialize.py index 6939c2b9..3e9ed373 100644 --- a/latch_cli/services/serialize.py +++ b/latch_cli/services/serialize.py @@ -102,7 +102,9 @@ def ensure_snakemake_metadata_exists(): display_name="Some Param", type=LatchFile, path=Path("foo.txt"), - ), + ) + } + ) ``` Find more information at docs.latch.bio. @@ -119,6 +121,7 @@ def extract_snakemake_workflow( snakefile, overwrite_default_target=True, ) + ensure_snakemake_metadata_exists() dag = workflow.extract_dag() wf = SnakemakeWorkflow(dag, version) wf.compile() From 45f9e6f1b6e7b36c432ef1c659bf516f82022002 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Thu, 22 Jun 2023 17:54:59 -0700 Subject: [PATCH 040/356] name in metadata --- latch/types/metadata.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/latch/types/metadata.py b/latch/types/metadata.py index ab16efd0..699f979c 100644 --- a/latch/types/metadata.py +++ b/latch/types/metadata.py @@ -437,9 +437,11 @@ def _parameter_str(t: Tuple[str, LatchParameter]): @dataclass class SnakemakeMetadata(LatchMetadata): output_dir: Optional[LatchDir] = None + name: Optional[str] = None def __post_init__(self): global _snakemake_metadata + self.name = self.display_name.lower().replace(" ", "_") _snakemake_metadata = self From 23fef3e55e8abe81345e558ff6eab2be7bc26a8f Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Fri, 23 Jun 2023 16:03:26 -0700 Subject: [PATCH 041/356] fix --- latch_cli/snakemake/workflow.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index a6d8a045..b89398b2 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -203,6 +203,7 @@ def __init__( parameter_metadata = metadata._snakemake_metadata.parameters metadata._snakemake_metadata.parameters = parameter_metadata display_name = metadata._snakemake_metadata.display_name + name = metadata._snakemake_metadata.name docstring = Docstring( f"{display_name}\n\nSample Description\n\n" @@ -222,7 +223,7 @@ def __init__( workflow_metadata = WorkflowMetadata( on_failure=WorkflowFailurePolicy.FAIL_IMMEDIATELY ) - name = f"{display_name}_jit_register" + name = f"{name}_jit_register" workflow_metadata_defaults = WorkflowMetadataDefaults(False) super().__init__( name=name, @@ -463,9 +464,9 @@ def __init__( version: Optional[str] = None, ): if version is not None: - name = f"{metadata._snakemake_metadata.display_name}-{version}" + name = f"{metadata._snakemake_metadata.name}-{version}" else: - name = metadata._snakemake_metadata.display_name + name = metadata._snakemake_metadata.name native_interface, literal_map, return_files = snakemake_dag_to_interface( dag, name, None From 580d43792b64a8bb23b95ce88b9fa705981d0bd1 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Wed, 5 Jul 2023 16:43:57 -0700 Subject: [PATCH 042/356] big cleanup/fixes Signed-off-by: maximsmol --- latch_cli/centromere/ctx.py | 66 ++++----- latch_cli/centromere/utils.py | 17 ++- latch_cli/constants.py | 4 - latch_cli/docker_utils/__init__.py | 2 +- latch_cli/exceptions/handler.py | 9 +- latch_cli/main.py | 6 +- latch_cli/services/local_dev.py | 4 +- latch_cli/services/register/register.py | 125 +++++++++++------- latch_cli/services/register/utils.py | 50 ++++--- .../{services => snakemake}/serialize.py | 80 ++++++----- latch_cli/snakemake/serialize_utils.py | 3 +- latch_cli/snakemake/workflow.py | 4 +- latch_cli/utils.py | 3 +- 13 files changed, 190 insertions(+), 183 deletions(-) rename latch_cli/{services => snakemake}/serialize.py (89%) diff --git a/latch_cli/centromere/ctx.py b/latch_cli/centromere/ctx.py index fbbff2eb..9168c293 100644 --- a/latch_cli/centromere/ctx.py +++ b/latch_cli/centromere/ctx.py @@ -55,13 +55,9 @@ class _CentromereCtx: pkg_root: Optional[Path] = None # root disable_auto_version: bool = False image_full = None - token = None version = None serialize_dir = None default_container: _Container - # Used to associate alternate containers with tasks - container_map: Dict[str, _Container] - workflow_name: Optional[str] workflow_type: WorkflowType snakefile: Optional[Path] @@ -81,31 +77,22 @@ class _CentromereCtx: def __init__( self, pkg_root: Path, - token: Optional[str] = None, + *, disable_auto_version: bool = False, remote: bool = False, snakefile: Optional[Path] = None, - *, use_new_centromere: bool = False, ): - self.use_new_centromere = use_new_centromere - - try: - if token is None: - self.token = retrieve_or_login() - else: - self.token = token + with self: + self.use_new_centromere = use_new_centromere + self.remote = remote + self.disable_auto_version = disable_auto_version - ws = current_workspace() - if ws == "" or ws is None: - self.account_id = account_id_from_token(self.token) - else: - self.account_id = ws + self.token = retrieve_or_login() + self.account_id = current_workspace() self.dkr_repo = config.dkr_repo - self.remote = remote - self.disable_auto_version = disable_auto_version - self.pkg_root = Path(pkg_root).resolve() + self.pkg_root = pkg_root.resolve() if snakefile is None: self.workflow_type = WorkflowType.latchbiosdk @@ -113,12 +100,13 @@ def __init__( self.workflow_type = WorkflowType.snakemake self.snakefile = snakefile - self.container_map = {} + self.container_map: Dict[str, _Container] = {} if self.workflow_type == WorkflowType.latchbiosdk: _import_flyte_objects([self.pkg_root]) for entity in FlyteEntities.entities: if isinstance(entity, PythonFunctionWorkflow): self.workflow_name = entity.name + if isinstance(entity, PythonTask): if ( hasattr(entity, "dockerfile_path") @@ -130,41 +118,38 @@ def __init__( pkg_dir=entity.dockerfile_path.parent, ) else: - # TODO (kenny) - support per container task and custom workflow + # todo(kenny): support per container task and custom workflow # name for snakemake self.workflow_name = "snakemake workflow" version_file = self.pkg_root / "version" - if not version_file.exists(): + try: + self.version = version_file.read_text() + except FileNotFoundError: self.version = "0.1.0" - version_file.write_text(self.version + "\n") + version_file.write_text(f"{self.version}\n") click.echo( - "Created a version file with initial version 0.1.0 for this" - " workflow." + f"Created a version file with initial version {self.version}." ) - else: - self.version = version_file.read_text().strip() + self.version = self.version.strip() if not self.disable_auto_version: hash = hash_directory(self.pkg_root) - self.version = self.version + "-" + hash[:6] + self.version = f"{self.version}-{hash[:6]}" - if self.nucleus_check_version(self.version, self.workflow_name) is True: + if self.nucleus_check_version(self.version, self.workflow_name): raise ValueError(f"Version {self.version} has already been registered.") - default_dockerfile = get_default_dockerfile( - self.pkg_root, self.workflow_type - ) self.default_container = _Container( - dockerfile=default_dockerfile, + dockerfile=get_default_dockerfile(self.pkg_root, self.workflow_type), image_name=self.image_tagged, pkg_dir=self.pkg_root, ) - if remote is True: + if remote: # todo(maximsmol): connect only AFTER confirming registration - self.ssh_key_path = Path(self.pkg_root) / latch_constants.pkg_ssh_key - self.jump_key_path = Path(self.pkg_root) / latch_constants.pkg_jump_key + self.ssh_key_path = self.pkg_root / ".latch/ssh_key" + self.jump_key_path = self.pkg_root / ".latch/jump_key" self.public_key = generate_temporary_ssh_credentials(self.ssh_key_path) if use_new_centromere: @@ -199,9 +184,6 @@ def _patched_create_paramiko_client(self, base_url): else: self.dkr_client = _construct_dkr_client() - except (Exception, KeyboardInterrupt) as e: - self.cleanup() - raise e @property def image(self): @@ -386,7 +368,6 @@ def nucleus_check_version(self, version: str, workflow_name: str) -> bool: ) resp = response.json() - print(resp) try: return resp["exists"] except KeyError as e: @@ -401,6 +382,7 @@ def cleanup(self): if self.ssh_key_path is not None: self.ssh_key_path.unlink(missing_ok=True) self.ssh_key_path.with_suffix(".pub").unlink(missing_ok=True) + if self.jump_key_path is not None: self.jump_key_path.unlink(missing_ok=True) diff --git a/latch_cli/centromere/utils.py b/latch_cli/centromere/utils.py index 94d31c92..7cb1986f 100644 --- a/latch_cli/centromere/utils.py +++ b/latch_cli/centromere/utils.py @@ -17,8 +17,6 @@ from flytekit.tools import module_loader from latch_cli.constants import latch_constants -from latch_cli.docker_utils import generate_dockerfile -from latch_cli.utils import WorkflowType @dataclass @@ -240,16 +238,16 @@ class MaybeRemoteDir: def __init__(self, ssh_client: Optional[paramiko.SSHClient] = None): self.ssh_client = ssh_client - def __enter__(self, *args): - return self.create(*args) + def __enter__(self): + return self.create() - def __exit__(self, *args): - self.cleanup(*args) + def __exit__(self, exc_type, exc_value, tb): + self.cleanup() - def create(self, *args): + def create(self): if self.ssh_client is None: self._tempdir = tempfile.TemporaryDirectory() - return Path(self._tempdir.name).resolve() + return str(Path(self._tempdir.name).resolve()) td = build_random_string() @@ -258,10 +256,11 @@ def create(self, *args): self.ssh_client.exec_command(f"mkdir {self._tempdir}") return self._tempdir - def cleanup(self, *args): + def cleanup(self): if self.ssh_client is not None: self.ssh_client.exec_command(f"rm -rf {self._tempdir}") return + if self._tempdir is not None and not isinstance(self._tempdir, str): self._tempdir.cleanup() diff --git a/latch_cli/constants.py b/latch_cli/constants.py index 27ca85ae..ca43e3c5 100644 --- a/latch_cli/constants.py +++ b/latch_cli/constants.py @@ -1,5 +1,3 @@ -"""Package-wide constants.""" - import re from dataclasses import dataclass from enum import Enum @@ -36,8 +34,6 @@ class LatchConstants: maximum_upload_size = 5 * units.TiB pkg_name: str = "latch" - pkg_ssh_key: str = ".latch/ssh_key" - pkg_jump_key: str = ".latch/jump_key" pkg_config: str = ".latch/config" # todo(aidan): make this aware of the current working directory so that we do not remove useful context diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index f49f94c1..4d98000b 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -250,5 +250,5 @@ def get_default_dockerfile(pkg_root: Path, wf_type: WorkflowType): default_dockerfile = pkg_root / "Dockerfile" if not default_dockerfile.exists(): default_dockerfile = pkg_root / ".latch" / "Dockerfile" - generate_dockerfile(default_dockerfile, wf_type) + generate_dockerfile(pkg_root, default_dockerfile) return default_dockerfile diff --git a/latch_cli/exceptions/handler.py b/latch_cli/exceptions/handler.py index 892eb994..29366b73 100644 --- a/latch_cli/exceptions/handler.py +++ b/latch_cli/exceptions/handler.py @@ -71,13 +71,12 @@ def _write_state_to_tarball(self): tf.add(ntf.name, arcname="traceback.txt") if self.pkg_root is not None: - pkg_path = Path(self.pkg_root).resolve() - - if (pkg_path / ".logs").exists(): - tf.add(pkg_path / ".logs", arcname="logs") + logs_path = Path(self.pkg_root) / ".latch" / ".logs" + if logs_path.exists(): + tf.add(logs_path, arcname="logs") pkg_files: List[Path] = [] - for dp, _, fnames in os.walk(pkg_path): + for dp, _, fnames in os.walk(logs_path): for f in fnames: p = (Path(dp) / f).resolve() if ( diff --git a/latch_cli/main.py b/latch_cli/main.py index b3e6b24f..e9f9c745 100644 --- a/latch_cli/main.py +++ b/latch_cli/main.py @@ -3,7 +3,6 @@ import os import textwrap from collections import OrderedDict -from enum import Flag from pathlib import Path from typing import List, Optional, Union @@ -23,8 +22,6 @@ latch_cli.click_utils.patch() -from latch_cli.constants import latch_constants, units - crash_handler = CrashHandler() @@ -107,9 +104,8 @@ def dockerfile(pkg_root: str): help="Skip the confirmation dialog.", ) @click.option( - "-s", "--snakefile", - type=click.Path(exists=True, path_type=Path), + type=click.Path(exists=True, dir_okay=False, path_type=Path), default=None, help="Path to a Snakefile to register.", ) diff --git a/latch_cli/services/local_dev.py b/latch_cli/services/local_dev.py index 45f53be2..0bfe350b 100644 --- a/latch_cli/services/local_dev.py +++ b/latch_cli/services/local_dev.py @@ -158,8 +158,8 @@ def local_development( click.echo("Session cancelled.") return - key_path = pkg_root / latch_constants.pkg_ssh_key - jump_key_path = pkg_root / latch_constants.pkg_jump_key + key_path = pkg_root / ".latch/ssh_key" + jump_key_path = pkg_root / ".latch/jump_key" with TemporarySSHCredentials(key_path) as ssh: click.echo( "Starting local development session. This may take a few minutes for larger" diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index 79ae453a..108d3cf7 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -1,7 +1,4 @@ -"""Service to register workflows.""" - import contextlib -import os import re import shutil import tempfile @@ -11,22 +8,16 @@ import click from scp import SCPClient -from latch_cli.centromere.ctx import _CentromereCtx -from latch_cli.centromere.utils import MaybeRemoteDir, _construct_ssh_client -from latch_cli.services.register.constants import ANSI_REGEX, MAX_LINES -from latch_cli.services.register.utils import ( +from ...centromere.ctx import _CentromereCtx +from ...centromere.utils import MaybeRemoteDir +from ...utils import WorkflowType, current_workspace +from ..register.constants import ANSI_REGEX, MAX_LINES +from ..register.utils import ( build_image, register_serialized_pkg, serialize_pkg_in_container, upload_image, ) -from latch_cli.services.serialize import ( - extract_snakemake_workflow, - generate_jit_register_code, - serialize_jit_register_workflow, -) -from latch_cli.utils import WorkflowType, current_workspace - from ..workspace import _get_workspaces @@ -60,7 +51,7 @@ def _print_window(curr_lines: List[str], line: str): def print_and_write_build_logs(build_logs, image: str, pkg_root: Path): print(f"Building Docker image for {image}") - logs_path = Path(pkg_root).joinpath(".logs").joinpath(image).resolve() + logs_path = (pkg_root / ".latch" / ".logs" / image).resolve() logs_path.mkdir(parents=True, exist_ok=True) with open(logs_path.joinpath("docker-build-logs.txt"), "w") as save_file: r = re.compile("^Step [0-9]+/[0-9]+ :") @@ -156,12 +147,21 @@ def _build_and_serialize( ctx: _CentromereCtx, image_name: str, context_path: Path, - tmp_dir: Path, + tmp_dir: str, dockerfile: Optional[Path] = None, ): - """Builds an image, serializes the workflow within the image, and pushes the image.""" + assert ctx.pkg_root is not None + jit_wf = None if ctx.workflow_type == WorkflowType.snakemake: + assert ctx.snakefile is not None + assert ctx.version is not None + + from ...snakemake.serialize import ( + extract_snakemake_workflow, + generate_jit_register_code, + ) + wf = extract_snakemake_workflow(ctx.snakefile) jit_wf = wf.build_jit_register_wrapper() generate_jit_register_code( @@ -170,21 +170,26 @@ def _build_and_serialize( ctx.snakefile, ctx.version, image_name, - user_config.workspace_id, + current_workspace(), ) image_build_logs = build_image(ctx, image_name, context_path, dockerfile) print_and_write_build_logs(image_build_logs, image_name, ctx.pkg_root) if ctx.workflow_type == WorkflowType.snakemake: - serialize_jit_register_workflow( - jit_wf, ctx.pkg_root, ctx.snakefile, tmp_dir, image_name, ctx.dkr_repo - ) + assert jit_wf is not None + assert ctx.dkr_repo is not None + + from ...snakemake.serialize import serialize_jit_register_workflow + + serialize_jit_register_workflow(jit_wf, tmp_dir, image_name, ctx.dkr_repo) else: serialize_logs, container_id = serialize_pkg_in_container( ctx, image_name, tmp_dir ) print_serialize_logs(serialize_logs, image_name) + + assert ctx.dkr_client is not None exit_status = ctx.dkr_client.wait(container_id) if exit_status["StatusCode"] != 0: raise ValueError( @@ -196,11 +201,18 @@ def _build_and_serialize( def _recursive_list(directory: Path) -> List[Path]: - files = [] - for dirname, dirnames, fnames in os.walk(directory): - for filename in fnames + dirnames: - files.append(Path(dirname).resolve().joinpath(filename)) - return files + res: List[Path] = [] + + stack: List[Path] = [directory] + while len(stack) > 0: + cur = stack.pop() + for x in cur.iterdir(): + res.append(x) + + if x.is_dir(): + stack.append(x) + + return res def register( @@ -208,7 +220,7 @@ def register( disable_auto_version: bool = False, remote: bool = False, skip_confirmation: bool = False, - snakefile: Optional[str] = None, + snakefile: Optional[Path] = None, *, use_new_centromere: bool = False, ): @@ -257,10 +269,14 @@ def register( https://docs.flyte.org/en/latest/concepts/registration.html """ - pkg_root = Path(pkg_root).resolve() + if snakefile is not None: + try: + import snakemake + except ImportError as e: + raise RuntimeError("could not load snakemake: package not installed") from e with _CentromereCtx( - pkg_root, + Path(pkg_root), disable_auto_version=disable_auto_version, remote=remote, snakefile=snakefile, @@ -308,11 +324,20 @@ def register( click.secho("Skipping confirmation because of --yes", bold=True) click.secho("Initializing registration", bold=True) + transport = None + scp = None + if remote: print("Connecting to remote server for docker build...") + assert ctx.ssh_client is not None + transport = ctx.ssh_client.get_transport() + + assert transport is not None + scp = SCPClient(transport=transport, sanitize=lambda x: x) + with contextlib.ExitStack() as stack: - td = stack.enter_context(MaybeRemoteDir(ctx.ssh_client)) + td: str = stack.enter_context(MaybeRemoteDir(ctx.ssh_client)) _build_and_serialize( ctx, ctx.default_container.image_name, @@ -320,21 +345,21 @@ def register( td, dockerfile=ctx.default_container.dockerfile, ) - protos = _recursive_list(td) - if ctx.workflow_type == WorkflowType.latchbiosdk and remote: - local_td = stack.enter_context(tempfile.TemporaryDirectory()) - scp = SCPClient( - transport=ctx.ssh_client.get_transport(), sanitize=lambda x: x - ) - scp.get(f"{td}/*", local_path=local_td, recursive=True) - protos = _recursive_list(local_td) + + if remote: + local_td = Path(stack.enter_context(tempfile.TemporaryDirectory())) + + assert scp is not None + scp.get(f"{td}/*", local_path=str(local_td), recursive=True) else: - protos = _recursive_list(td) + local_td = Path(td) + + protos = _recursive_list(local_td) for task_name, container in ctx.container_map.items(): task_td = stack.enter_context(MaybeRemoteDir(ctx.ssh_client)) try: - build_and_serialize( + _build_and_serialize( ctx, container.image_name, ctx.default_container.pkg_dir, @@ -343,15 +368,21 @@ def register( ) if remote: - local_td = stack.enter_context(tempfile.TemporaryDirectory()) - scp = SCPClient( - transport=ctx.ssh_client.get_transport(), - sanitize=lambda x: x, + local_task_td = Path( + stack.enter_context(tempfile.TemporaryDirectory()) + ) + + assert scp is not None + scp.get( + f"{task_td}/*", local_path=str(local_td), recursive=True ) - scp.get(f"{task_td}/*", local_path=local_td, recursive=True) + new_protos = _recursive_list(local_td) else: - new_protos = _recursive_list(task_td) + local_task_td = Path(task_td) + + new_protos = _recursive_list(local_task_td) + try: split_task_name = task_name.split(".") task_name = ".".join( @@ -375,7 +406,7 @@ def register( ) from e reg_resp = register_serialized_pkg( - protos, ctx.token, ctx.version, current_workspace().encode("utf-8") + protos, ctx.token, ctx.version, current_workspace() ) _print_reg_resp(reg_resp, ctx.default_container.image_name) diff --git a/latch_cli/services/register/utils.py b/latch_cli/services/register/utils.py index fb121978..70bedbc2 100644 --- a/latch_cli/services/register/utils.py +++ b/latch_cli/services/register/utils.py @@ -1,20 +1,22 @@ -"Utilites for registration." - import base64 import contextlib +import io import os +import typing from pathlib import Path -from typing import List, Optional +from typing import Dict, Iterable, List, Optional, Tuple, Union import boto3 import requests -from latch_cli.centromere.ctx import _CentromereCtx -from latch_cli.config.latch import config -from latch_cli.utils import current_workspace +from ...centromere.ctx import _CentromereCtx +from ...config.latch import config +from ...utils import current_workspace def _docker_login(ctx: _CentromereCtx): + assert ctx.dkr_client is not None + headers = {"Authorization": f"Bearer {ctx.token}"} data = {"pkg_name": ctx.image, "ws_account_id": current_workspace()} response = requests.post(ctx.latch_image_api_url, headers=headers, json=data) @@ -56,13 +58,12 @@ def build_image( context_path: Path, dockerfile: Optional[Path] = None, ) -> List[str]: - _docker_login(ctx) - if dockerfile is not None: - dockerfile = str(dockerfile) + assert ctx.dkr_client is not None + _docker_login(ctx) build_logs = ctx.dkr_client.build( path=str(context_path), - dockerfile=dockerfile, + dockerfile=str(dockerfile) if dockerfile is not None else None, buildargs={"tag": f"{ctx.dkr_repo}/{image_name}"}, tag=f"{ctx.dkr_repo}/{image_name}", decode=True, @@ -72,6 +73,7 @@ def build_image( def upload_image(ctx: _CentromereCtx, image_name: str) -> List[str]: + assert ctx.dkr_client is not None return ctx.dkr_client.push( repository=f"{ctx.dkr_repo}/{image_name}", stream=True, @@ -80,26 +82,28 @@ def upload_image(ctx: _CentromereCtx, image_name: str) -> List[str]: def serialize_pkg_in_container( - ctx: _CentromereCtx, image_name: str, serialize_dir: Path -) -> List[str]: + ctx: _CentromereCtx, image_name: str, serialize_dir: str +) -> Tuple[List[str], str]: + assert ctx.dkr_client is not None + _serialize_cmd = ["make", "serialize"] container = ctx.dkr_client.create_container( f"{ctx.dkr_repo}/{image_name}", command=_serialize_cmd, - volumes=[str(serialize_dir)], + volumes=[serialize_dir], environment={"LATCH_DKR_REPO": ctx.dkr_repo, "LATCH_VERSION": ctx.version}, host_config=ctx.dkr_client.create_host_config( binds={ - str(serialize_dir): { + serialize_dir: { "bind": "/tmp/output", "mode": "rw", }, } ), ) - container_id = container.get("Id") + container_id = typing.cast(str, container.get("Id")) ctx.dkr_client.start(container_id) - logs = ctx.dkr_client.logs(container_id, stream=True) + logs = typing.cast(Iterable[bytes], ctx.dkr_client.logs(container_id, stream=True)) return [x.decode("utf-8") for x in logs], container_id @@ -110,7 +114,7 @@ def register_serialized_pkg( version: str, workspace_id: str, latch_register_url: str = config.api.workflow.register, -) -> dict: +) -> object: if token is None: token = os.environ.get("FLYTE_INTERNAL_EXECUTION_ID", "") if token != "": @@ -122,13 +126,15 @@ def register_serialized_pkg( else: headers = {"Authorization": f"Bearer {token}"} - serialize_files = { + serialize_files: Dict[str, Union[bytes, io.BufferedReader]] = { "version": version.encode("utf-8"), - ".latch_ws": workspace_id, + ".latch_ws": workspace_id.encode("utf-8"), } with contextlib.ExitStack() as stack: - file_handlers = [stack.enter_context(open(file, "rb")) for file in files] - for fh in file_handlers: + for file in files: + fh = open(file, "rb") + stack.enter_context(fh) + serialize_files[fh.name] = fh response = requests.post( @@ -137,4 +143,4 @@ def register_serialized_pkg( files=serialize_files, ) - return response.json() + return response.json() diff --git a/latch_cli/services/serialize.py b/latch_cli/snakemake/serialize.py similarity index 89% rename from latch_cli/services/serialize.py rename to latch_cli/snakemake/serialize.py index 3e9ed373..a6b36546 100644 --- a/latch_cli/services/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -40,47 +40,10 @@ def should_register_with_admin(entity: RegistrableEntity) -> bool: return isinstance(entity, get_args(RegistrableEntity)) -class SnakemakeWorkflowExtractor(Workflow): - def __init__(self, snakefile: Path): - super().__init__(snakefile=snakefile) - - def extract_dag(self): - targets: List[str] = ( - [self.default_target] if self.default_target is not None else [] - ) - target_rules: Set[Rule] = set( - map(self._rules.__getitem__, filter(self.is_rule, targets)) - ) - - target_files = set() - for f in filterfalse(self.is_rule, targets): - if os.path.isabs(f) or f.startswith("root://"): - target_files.add(f) - else: - target_files.add(os.path.relpath(f)) - - dag = DAG( - self, - self.rules, - targetfiles=target_files, - targetrules=target_rules, - ) - - self.persistence = Persistence( - dag=dag, - ) - - dag.init() - dag.update_checkpoint_dependencies() - dag.check_dynamic() - - return dag - - def ensure_snakemake_metadata_exists(): if metadata._snakemake_metadata is None: raise ValueError(dedent(""" - + No `SnakemakeMetadata` object was detected in your Snakefile. This object needs to be defined to register this workflow with Latch. @@ -114,6 +77,42 @@ def ensure_snakemake_metadata_exists(): def extract_snakemake_workflow( snakefile: Path, version: Optional[str] = None ) -> SnakemakeWorkflow: + class SnakemakeWorkflowExtractor(Workflow): + def __init__(self, snakefile: Path): + super().__init__(snakefile=snakefile) + + def extract_dag(self): + targets: List[str] = ( + [self.default_target] if self.default_target is not None else [] + ) + target_rules: Set[Rule] = set( + map(self._rules.__getitem__, filter(self.is_rule, targets)) + ) + + target_files = set() + for f in filterfalse(self.is_rule, targets): + if os.path.isabs(f) or f.startswith("root://"): + target_files.add(f) + else: + target_files.add(os.path.relpath(f)) + + dag = DAG( + self, + self.rules, + targetfiles=target_files, + targetrules=target_rules, + ) + + self.persistence = Persistence( + dag=dag, + ) + + dag.init() + dag.update_checkpoint_dependencies() + dag.check_dynamic() + + return dag + workflow = SnakemakeWorkflowExtractor( snakefile=snakefile, ) @@ -169,13 +168,10 @@ def serialize_snakemake( def serialize_jit_register_workflow( jit_wf: JITRegisterWorkflow, - pkg_root: Path, - snakefile: Path, - output_dir: Path, + output_dir: str, image_name: str, dkr_repo: str, ): - pkg_root = Path(pkg_root).resolve() image_name_no_version, version = image_name.split(":") default_img = Image( name=image_name, diff --git a/latch_cli/snakemake/serialize_utils.py b/latch_cli/snakemake/serialize_utils.py index d674adee..4064c1a1 100644 --- a/latch_cli/snakemake/serialize_utils.py +++ b/latch_cli/snakemake/serialize_utils.py @@ -1,4 +1,4 @@ -from typing import Dict, TypeAlias, Union +from typing import Dict, Union from flytekit import LaunchPlan from flytekit.configuration import SerializationSettings @@ -15,6 +15,7 @@ from flytekit.models.core import identifier as identifier_model from flytekit.models.core import workflow as workflow_model from flytekit.models.core.workflow import TaskNodeOverrides +from typing_extensions import TypeAlias FlyteLocalEntity: TypeAlias = Union[ PythonTask, diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index b89398b2..6f7bffe4 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -3,7 +3,7 @@ import typing from dataclasses import dataclass from pathlib import Path -from typing import Any, Dict, List, Optional, Tuple, Type, TypeAlias, TypeVar, Union +from typing import Any, Dict, List, Optional, Tuple, Type, TypeVar, Union from urllib.parse import urlparse import snakemake @@ -33,11 +33,11 @@ from flytekit.models.literals import Blob, BlobMetadata, Literal, LiteralMap, Scalar from snakemake.dag import DAG from snakemake.target_jobs import encode_target_jobs_cli_args +from typing_extensions import TypeAlias import latch.types.metadata as metadata from latch.types.directory import LatchDir from latch.types.file import LatchFile -from latch.types.metadata import LatchAuthor, LatchParameter SnakemakeInputVal: TypeAlias = snakemake.io._IOFile diff --git a/latch_cli/utils.py b/latch_cli/utils.py index b6da44a8..b7580179 100644 --- a/latch_cli/utils.py +++ b/latch_cli/utils.py @@ -35,6 +35,7 @@ def current_workspace() -> str: if ws == "": ws = account_id_from_token(retrieve_or_login()) user_config.update_workspace(ws, "Personal Workspace") + return ws @@ -119,7 +120,7 @@ def hash_directory(dir_path: Path) -> str: m.update(current_workspace().encode("utf-8")) ignore_file = dir_path / ".dockerignore" - exclude: List[str] = [] + exclude: List[str] = ["/.latch"] try: for l in ignore_file.open("r"): l = l.strip() From 7b9d6ac9a3863265a68193036736aa2a8a864f69 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Wed, 5 Jul 2023 17:03:18 -0700 Subject: [PATCH 043/356] fix relative paths Signed-off-by: maximsmol --- latch_cli/services/register/register.py | 2 +- latch_cli/snakemake/serialize.py | 40 ++++++++++++++++--------- latch_cli/snakemake/workflow.py | 2 +- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index 108d3cf7..55c343b7 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -162,7 +162,7 @@ def _build_and_serialize( generate_jit_register_code, ) - wf = extract_snakemake_workflow(ctx.snakefile) + wf = extract_snakemake_workflow(ctx.pkg_root, ctx.snakefile) jit_wf = wf.build_jit_register_wrapper() generate_jit_register_code( jit_wf, diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index a6b36546..4ef0c68b 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -15,7 +15,7 @@ from snakemake.dag import DAG from snakemake.persistence import Persistence from snakemake.rules import Rule -from snakemake.workflow import Workflow +from snakemake.workflow import Workflow, WorkflowError import latch.types.metadata as metadata from latch_cli.snakemake.serialize_utils import ( @@ -75,7 +75,7 @@ def ensure_snakemake_metadata_exists(): def extract_snakemake_workflow( - snakefile: Path, version: Optional[str] = None + pkg_root: Path, snakefile: Path, version: Optional[str] = None ) -> SnakemakeWorkflow: class SnakemakeWorkflowExtractor(Workflow): def __init__(self, snakefile: Path): @@ -113,18 +113,30 @@ def extract_dag(self): return dag - workflow = SnakemakeWorkflowExtractor( - snakefile=snakefile, - ) - workflow.include( - snakefile, - overwrite_default_target=True, - ) - ensure_snakemake_metadata_exists() - dag = workflow.extract_dag() - wf = SnakemakeWorkflow(dag, version) - wf.compile() - return wf + old_cwd = os.getcwd() + snakefile = snakefile.resolve() + try: + os.chdir(pkg_root) + + workflow = SnakemakeWorkflowExtractor( + snakefile=snakefile, + ) + workflow.include( + snakefile, + overwrite_default_target=True, + ) + ensure_snakemake_metadata_exists() + dag = workflow.extract_dag() + wf = SnakemakeWorkflow(dag, version) + wf.compile() + return wf + except WorkflowError as e: + # todo(maximsmol): handle specific errors + # WorkflowError: Failed to open source file /Users/maximsmol/projects/latchbio/latch/test/CGI_WGS_GATK_Pipeline/Snakefiles/CGI_WGS_GATK_Pipeline/Snakefiles/calc_frag_len.smk + # FileNotFoundError: [Errno 2] No such file or directory: '/Users/maximsmol/projects/latchbio/latch/test/CGI_WGS_GATK_Pipeline/Snakefiles/CGI_WGS_GATK_Pipeline/Snakefiles/calc_frag_len.smk' + raise RuntimeError("invalid Snakefile") from e + finally: + os.chdir(old_cwd) def serialize_snakemake( diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 6f7bffe4..7ce6acdc 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -289,7 +289,7 @@ def get_fn_code( pkg_root = Path(".") version = os.environ.get("FLYTE_INTERNAL_EXECUTION_ID") - wf = extract_snakemake_workflow(snakefile, version) + wf = extract_snakemake_workflow(pkg_root, snakefile, version) wf_name = wf.name generate_snakemake_entrypoint(wf, pkg_root, snakefile, {remote_output_url}) """), From fd9420d335f36d81ff96de48aee4a2ea0b78893f Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Wed, 5 Jul 2023 17:56:46 -0700 Subject: [PATCH 044/356] save state Signed-off-by: Ayush Kamat --- latch_cli/services/cp/throttle.py | 21 +++++ latch_cli/services/cp/upload.py | 136 +++++++++++++++++++----------- 2 files changed, 108 insertions(+), 49 deletions(-) create mode 100644 latch_cli/services/cp/throttle.py diff --git a/latch_cli/services/cp/throttle.py b/latch_cli/services/cp/throttle.py new file mode 100644 index 00000000..03663927 --- /dev/null +++ b/latch_cli/services/cp/throttle.py @@ -0,0 +1,21 @@ +from multiprocessing.managers import BaseManager + +from attr import dataclass + + +@dataclass +class Throttle: + delay: float = 0 + + def get_delay(self): + return self.delay + + def set_delay(self, d: float): + self.delay = d + + +class ThrottleManager(BaseManager): + ... + + +ThrottleManager.register("Throttle", Throttle) diff --git a/latch_cli/services/cp/upload.py b/latch_cli/services/cp/upload.py index d301b516..8f805d36 100644 --- a/latch_cli/services/cp/upload.py +++ b/latch_cli/services/cp/upload.py @@ -20,6 +20,7 @@ from latch_cli.services.cp.ldata_utils import LDataNodeType, get_node_data from latch_cli.services.cp.path_utils import normalize_path, urljoins from latch_cli.services.cp.progress import ProgressBarManager, ProgressBars +from latch_cli.services.cp.throttle import Throttle, ThrottleManager from latch_cli.services.cp.utils import ( get_auth_header, get_max_workers, @@ -28,7 +29,8 @@ from latch_cli.utils import with_si_suffix if TYPE_CHECKING: - QueueType: TypeAlias = Queue[Optional[Path]] + PathQueueType: TypeAlias = Queue[Optional[Path]] + LatencyQueueType: TypeAlias = Queue[Optional[float]] PartsBySrcType: TypeAlias = DictProxy[Path, ListProxy["CompletedPart"]] UploadInfoBySrcType: TypeAlias = DictProxy[Path, "StartUploadReturnType"] @@ -56,13 +58,12 @@ def upload( dest: str, config: CPConfig, ): - click.clear() - src_path = Path(src) if not src_path.exists(): raise ValueError(f"Could not find {src_path}.") - click.secho(f"Uploading {src_path.name}", fg="blue") + if config.progress != Progress.none: + click.secho(f"Uploading {src_path.name}", fg="blue") node_data = get_node_data(dest, allow_resolve_to_parent=True) dest_data = node_data.data[dest] @@ -130,51 +131,55 @@ def upload( num_files = len(jobs) - url_generation_bar: ProgressBars - with closing( - pbar_manager.ProgressBars( - 0, - show_total_progress=(config.progress != Progress.none), - ) - ) as url_generation_bar: - url_generation_bar.set_total(num_files, "Generating URLs") + with ThrottleManager() as throt_man: + throttle: Throttle = throt_man.Throttle() + latency_q: "LatencyQueueType" = state_manager.Queue() + + url_generation_bar: ProgressBars + with closing( + pbar_manager.ProgressBars( + 0, + show_total_progress=( + config.progress != Progress.none + ), + ) + ) as url_generation_bar: + url_generation_bar.set_total( + num_files, "Generating URLs" + ) - start_upload_futs: List[ - Future[Optional[StartUploadReturnType]] - ] = [] - batch_futs: List[ - Future[Optional[StartUploadReturnType]] - ] = [] + start_upload_futs: List[ + Future[Optional[StartUploadReturnType]] + ] = [] - start = time.monotonic() - for job in jobs: - fut = executor.submit( - start_upload, - job.src, - job.dest, - url_generation_bar, + throttle_listener = executor.submit( + throttler, throttle, latency_q ) - start_upload_futs.append(fut) - batch_futs.append(fut) - if len(batch_futs) == start_upload_batch_size: - wait(batch_futs) - - for fut in batch_futs: - res = fut.result() - if res is not None: - upload_info_by_src[res.src] = res + start = time.monotonic() + for job in jobs: + start_upload_futs.append( + executor.submit( + start_upload, + job.src, + job.dest, + url_generation_bar, + throttle, + latency_q, + ) + ) - batch_futs = [] + wait(start_upload_futs) - wait(batch_futs) + latency_q.put(None) + wait([throttle_listener]) - for fut in batch_futs: - res = fut.result() - if res is not None: - upload_info_by_src[res.src] = res + for fut in start_upload_futs: + res = fut.result() + if res is not None: + upload_info_by_src[res.src] = res - queue: "QueueType" = state_manager.Queue() + queue: "PathQueueType" = state_manager.Queue() listeners = [ end_upload_executor.submit( end_upload_listener, @@ -232,7 +237,8 @@ def upload( wait(chunk_futs) queue.put(None) - print("Finalizing uploads...") + if config.progress != Progress.none: + print("Finalizing uploads...") wait(listeners) else: if dest_exists and dest_is_dir: @@ -283,14 +289,14 @@ def upload( end = time.monotonic() total_time = end - start - - click.clear() - click.echo( - f"""{click.style("Upload Complete", fg="green")} + if config.progress != Progress.none: + click.clear() + click.echo( + f"""{click.style("Upload Complete", fg="green")} {click.style("Time Elapsed: ", fg="blue")}{human_readable_time(total_time)} {click.style("Files Uploaded: ", fg="blue")}{num_files} ({with_si_suffix(total_bytes)})""" - ) + ) @dataclass(frozen=True) @@ -307,6 +313,8 @@ def start_upload( src: Path, dest: str, progress_bars: Optional[ProgressBars] = None, + throttle: Optional[Throttle] = None, + latency_q: Optional["LatencyQueueType"] = None, ) -> Optional[StartUploadReturnType]: if not src.exists(): raise ValueError(f"Could not find {src}: no such file or link") @@ -341,6 +349,10 @@ def start_upload( math.ceil(file_size / latch_constants.maximum_upload_parts), ) + if throttle is not None: + time.sleep(throttle.get_delay()) + + start = time.monotonic() res = tinyrequests.post( latch_config.api.data.start_upload, headers={"Authorization": get_auth_header()}, @@ -350,12 +362,16 @@ def start_upload( "part_count": part_count, }, ) + end = time.monotonic() json_data = res.json() if res.status_code != 200: raise ValueError(json_data["error"]) + if latency_q is not None: + latency_q.put(end - start) + if progress_bars is not None: progress_bars.update_total_progress(1) @@ -383,7 +399,7 @@ def upload_file_chunk( part_size: int, progress_bars: ProgressBars, pbar_index: Optional[int], - queue: Optional["QueueType"] = None, + queue: Optional["PathQueueType"] = None, parts_by_source: Optional["PartsBySrcType"] = None, ) -> CompletedPart: with open(src, "rb") as f: @@ -447,7 +463,7 @@ def end_upload( def end_upload_listener( - queue: "QueueType", + queue: "PathQueueType", parts_by_src: "PartsBySrcType", upload_info_by_src: "UploadInfoBySrcType", ): @@ -464,3 +480,25 @@ def end_upload_listener( upload_info.upload_id, list(parts_by_src[src]), ) + + +def throttler(t: Throttle, q: "LatencyQueueType"): + ema = 0 + + # todo(ayush): these params were tuned via naive grid search uploading a + # test directory w/ ~19k files, ideally we should do something more rigorous + alpha = 0.6 + beta = 1 / 60 + threshold = 15 # seconds + + while True: + latency = q.get() + if latency is None: + return + + ema = (1 - alpha) * ema + alpha * latency + + if ema > threshold: + t.set_delay(beta * ema) + else: + t.set_delay(0) From b5c4e3696a574af0f0c0583b19c697355e845f1f Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 14 Jul 2023 11:51:24 -0700 Subject: [PATCH 045/356] fixes 1 Signed-off-by: maximsmol --- latch_cli/services/register/register.py | 7 +- latch_cli/snakemake/serialize.py | 136 ++++++++++++++---------- latch_cli/snakemake/workflow.py | 131 ++++++++++++----------- 3 files changed, 152 insertions(+), 122 deletions(-) diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index 55c343b7..f5d15ad5 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -158,12 +158,13 @@ def _build_and_serialize( assert ctx.version is not None from ...snakemake.serialize import ( - extract_snakemake_workflow, generate_jit_register_code, + snakemake_workflow_extractor, ) + from ...snakemake.workflow import build_jit_register_wrapper - wf = extract_snakemake_workflow(ctx.pkg_root, ctx.snakefile) - jit_wf = wf.build_jit_register_wrapper() + wf = snakemake_workflow_extractor(ctx.pkg_root, ctx.snakefile) + jit_wf = build_jit_register_wrapper() generate_jit_register_code( jit_wf, ctx.pkg_root, diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index 4ef0c68b..c993d2a5 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -16,6 +16,7 @@ from snakemake.persistence import Persistence from snakemake.rules import Rule from snakemake.workflow import Workflow, WorkflowError +from typing_extensions import Self import latch.types.metadata as metadata from latch_cli.snakemake.serialize_utils import ( @@ -51,6 +52,7 @@ def ensure_snakemake_metadata_exists(): started: ``` + from pathlib import Path from latch.types.metadata import SnakemakeMetadata, SnakemakeFileParameter from latch.types.file import LatchFile from latch.types.metadata import LatchAuthor, LatchMetadata @@ -74,69 +76,95 @@ def ensure_snakemake_metadata_exists(): """)) -def extract_snakemake_workflow( +class SnakemakeWorkflowExtractor(Workflow): + def __init__(self, pkg_root: Path, snakefile: Path): + super().__init__(snakefile=snakefile) + + self.pkg_root = pkg_root + self._old_cwd = "" + + def extract_dag(self): + targets: List[str] = ( + [self.default_target] if self.default_target is not None else [] + ) + target_rules: Set[Rule] = set( + map(self._rules.__getitem__, filter(self.is_rule, targets)) + ) + + target_files = set() + for f in filterfalse(self.is_rule, targets): + if os.path.isabs(f) or f.startswith("root://"): + target_files.add(f) + else: + target_files.add(os.path.relpath(f)) + + dag = DAG( + self, + self.rules, + targetfiles=target_files, + targetrules=target_rules, + ) + + self.persistence = Persistence( + dag=dag, + ) + + dag.init() + dag.update_checkpoint_dependencies() + dag.check_dynamic() + + return dag + + def __enter__(self) -> Self: + self._old_cwd = os.getcwd() + os.chdir(self.pkg_root) + + return self + + def __exit__(self, typ, value, traceback): + os.chdir(self._old_cwd) + + if typ is None: + return False + + if not isinstance(value, WorkflowError): + return False + + # todo(maximsmol): handle specific errors + # WorkflowError: Failed to open source file /Users/maximsmol/projects/latchbio/latch/test/CGI_WGS_GATK_Pipeline/Snakefiles/CGI_WGS_GATK_Pipeline/Snakefiles/calc_frag_len.smk + # FileNotFoundError: [Errno 2] No such file or directory: '/Users/maximsmol/projects/latchbio/latch/test/CGI_WGS_GATK_Pipeline/Snakefiles/CGI_WGS_GATK_Pipeline/Snakefiles/calc_frag_len.smk' + raise RuntimeError("invalid Snakefile") from value + + +def snakemake_workflow_extractor( pkg_root: Path, snakefile: Path, version: Optional[str] = None -) -> SnakemakeWorkflow: - class SnakemakeWorkflowExtractor(Workflow): - def __init__(self, snakefile: Path): - super().__init__(snakefile=snakefile) - - def extract_dag(self): - targets: List[str] = ( - [self.default_target] if self.default_target is not None else [] - ) - target_rules: Set[Rule] = set( - map(self._rules.__getitem__, filter(self.is_rule, targets)) - ) - - target_files = set() - for f in filterfalse(self.is_rule, targets): - if os.path.isabs(f) or f.startswith("root://"): - target_files.add(f) - else: - target_files.add(os.path.relpath(f)) - - dag = DAG( - self, - self.rules, - targetfiles=target_files, - targetrules=target_rules, - ) - - self.persistence = Persistence( - dag=dag, - ) - - dag.init() - dag.update_checkpoint_dependencies() - dag.check_dynamic() - - return dag - - old_cwd = os.getcwd() +) -> SnakemakeWorkflowExtractor: snakefile = snakefile.resolve() - try: - os.chdir(pkg_root) - workflow = SnakemakeWorkflowExtractor( - snakefile=snakefile, - ) - workflow.include( + extractor = SnakemakeWorkflowExtractor( + pkg_root=pkg_root, + snakefile=snakefile, + ) + with extractor: + extractor.include( snakefile, overwrite_default_target=True, ) ensure_snakemake_metadata_exists() - dag = workflow.extract_dag() + + return extractor + + +def extract_snakemake_workflow( + pkg_root: Path, snakefile: Path, version: Optional[str] = None +) -> SnakemakeWorkflow: + extractor = snakemake_workflow_extractor(pkg_root, snakefile, version) + with extractor: + dag = extractor.extract_dag() wf = SnakemakeWorkflow(dag, version) wf.compile() - return wf - except WorkflowError as e: - # todo(maximsmol): handle specific errors - # WorkflowError: Failed to open source file /Users/maximsmol/projects/latchbio/latch/test/CGI_WGS_GATK_Pipeline/Snakefiles/CGI_WGS_GATK_Pipeline/Snakefiles/calc_frag_len.smk - # FileNotFoundError: [Errno 2] No such file or directory: '/Users/maximsmol/projects/latchbio/latch/test/CGI_WGS_GATK_Pipeline/Snakefiles/CGI_WGS_GATK_Pipeline/Snakefiles/calc_frag_len.smk' - raise RuntimeError("invalid Snakefile") from e - finally: - os.chdir(old_cwd) + + return wf def serialize_snakemake( diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 7ce6acdc..36bcd936 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -613,81 +613,82 @@ def compile(self, **kwargs): self._nodes = list(node_map.values()) self._output_bindings = bindings - def build_jit_register_wrapper(self) -> JITRegisterWorkflow: - out_parameter_name = "success" - wrapper_wf = JITRegisterWorkflow() + def find_upstream_node_matching_output_var(self, out_var: str): + for j in self._dag.targetjobs: + for depen, files in self._dag.dependencies[j].items(): + for f in files: + if variable_name_for_file(f) == out_var: + return depen.jobid, variable_name_for_value(f, depen.output) - python_interface = wrapper_wf.python_interface - wrapper_wf._input_parameters = interface_to_parameters(python_interface) + def execute(self, **kwargs): + return exception_scopes.user_entry_point(self._workflow_function)(**kwargs) - GLOBAL_START_NODE = Node( - id=_common_constants.GLOBAL_INPUT_NODE_ID, - metadata=None, - bindings=[], - upstream_nodes=[], - flyte_entity=None, - ) - task_interface = Interface( - python_interface.inputs, python_interface.outputs, docstring=None - ) - task = PythonAutoContainerTask[T]( - name=f"{wrapper_wf.name}_task", - task_type="python-task", - interface=task_interface, - task_config=None, - task_resolver=JITRegisterWorkflowResolver(), - ) +def build_jit_register_wrapper() -> JITRegisterWorkflow: + out_parameter_name = "success" + wrapper_wf = JITRegisterWorkflow() - task_bindings: List[literals_models.Binding] = [] - typed_interface = transform_interface_to_typed_interface(python_interface) - for k in python_interface.inputs: - var = typed_interface.inputs[k] - promise_to_bind = Promise( - var=k, - val=NodeOutput(node=GLOBAL_START_NODE, var=k), - ) - task_bindings.append( - binding_from_python( - var_name=k, - expected_literal_type=var.type, - t_value=promise_to_bind, - t_value_type=python_interface.inputs[k], - ) - ) - task_node = Node( - id="n0", - metadata=task.construct_node_metadata(), - bindings=sorted(task_bindings, key=lambda b: b.var), - upstream_nodes=[], - flyte_entity=task, - ) + python_interface = wrapper_wf.python_interface + wrapper_wf._input_parameters = interface_to_parameters(python_interface) + GLOBAL_START_NODE = Node( + id=_common_constants.GLOBAL_INPUT_NODE_ID, + metadata=None, + bindings=[], + upstream_nodes=[], + flyte_entity=None, + ) + + task_interface = Interface( + python_interface.inputs, python_interface.outputs, docstring=None + ) + task = PythonAutoContainerTask[T]( + name=f"{wrapper_wf.name}_task", + task_type="python-task", + interface=task_interface, + task_config=None, + task_resolver=JITRegisterWorkflowResolver(), + ) + + task_bindings: List[literals_models.Binding] = [] + typed_interface = transform_interface_to_typed_interface(python_interface) + for k in python_interface.inputs: + var = typed_interface.inputs[k] promise_to_bind = Promise( - var=out_parameter_name, - val=NodeOutput(node=task_node, var=out_parameter_name), + var=k, + val=NodeOutput(node=GLOBAL_START_NODE, var=k), ) - t = python_interface.outputs[out_parameter_name] - output_binding = binding_from_python( - out_parameter_name, - bool, - promise_to_bind, - t, + task_bindings.append( + binding_from_python( + var_name=k, + expected_literal_type=var.type, + t_value=promise_to_bind, + t_value_type=python_interface.inputs[k], + ) ) + task_node = Node( + id="n0", + metadata=task.construct_node_metadata(), + bindings=sorted(task_bindings, key=lambda b: b.var), + upstream_nodes=[], + flyte_entity=task, + ) - wrapper_wf._nodes = [task_node] - wrapper_wf._output_bindings = [output_binding] - return wrapper_wf - - def find_upstream_node_matching_output_var(self, out_var: str): - for j in self._dag.targetjobs: - for depen, files in self._dag.dependencies[j].items(): - for f in files: - if variable_name_for_file(f) == out_var: - return depen.jobid, variable_name_for_value(f, depen.output) + promise_to_bind = Promise( + var=out_parameter_name, + val=NodeOutput(node=task_node, var=out_parameter_name), + ) + t = python_interface.outputs[out_parameter_name] + output_binding = binding_from_python( + out_parameter_name, + bool, + promise_to_bind, + t, + ) - def execute(self, **kwargs): - return exception_scopes.user_entry_point(self._workflow_function)(**kwargs) + wrapper_wf._nodes = [task_node] + wrapper_wf._output_bindings = [output_binding] + return wrapper_wf class SnakemakeJobTask(PythonAutoContainerTask[T]): From 0129da229b9d2fa9cbc8a44e49ed5435bcd69049 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 14 Jul 2023 13:37:37 -0700 Subject: [PATCH 046/356] im stuff Signed-off-by: maximsmol --- latch_cli/centromere/ctx.py | 2 +- latch_cli/exceptions/handler.py | 16 ++- latch_cli/main.py | 12 ++ latch_cli/services/register/register.py | 175 +++++++++++++++++------- latch_cli/services/register/utils.py | 24 +++- 5 files changed, 176 insertions(+), 53 deletions(-) diff --git a/latch_cli/centromere/ctx.py b/latch_cli/centromere/ctx.py index 9168c293..b8955782 100644 --- a/latch_cli/centromere/ctx.py +++ b/latch_cli/centromere/ctx.py @@ -199,7 +199,7 @@ def image(self): else: account_id = self.account_id - return f"{account_id}_{self.pkg_root.name}" + return f"{account_id}_{self.pkg_root.name.lower()}" @property def image_tagged(self): diff --git a/latch_cli/exceptions/handler.py b/latch_cli/exceptions/handler.py index 29366b73..d50c59b5 100644 --- a/latch_cli/exceptions/handler.py +++ b/latch_cli/exceptions/handler.py @@ -116,8 +116,18 @@ def _excepthook( print(f"{self.message} - printing traceback:\n") _Traceback(type_, value, traceback).pretty_print() print(self.metadata) - if click.confirm("Generate a crash report?"): - print("Generating...") - self._write_state_to_tarball() + + if os.environ.get("LATCH_NO_CRASH_REPORT") == "1": + click.echo( + "Not generating crash report due to $LATCH_NO_CRASH_REPORT", + bold=True, + ) + return + + if not click.confirm("Generate a crash report?"): + return + + print("Generating...") + self._write_state_to_tarball() sys.excepthook = _excepthook diff --git a/latch_cli/main.py b/latch_cli/main.py index e9f9c745..1080acda 100644 --- a/latch_cli/main.py +++ b/latch_cli/main.py @@ -95,6 +95,16 @@ def dockerfile(pkg_root: str): type=bool, help="Use a remote server to build workflow.", ) +@click.option( + "--progress-plain", + is_flag=True, + default=False, + type=bool, + help=( + "No special Docker build log handling. Equivalent to `docker build" + " --progress=plain`." + ), +) @click.option( "-y", "--yes", @@ -113,6 +123,7 @@ def register( pkg_root: str, disable_auto_version: bool, remote: bool, + progress_plain: bool, yes: bool, snakefile: Optional[Path], ): @@ -134,6 +145,7 @@ def register( remote=remote, skip_confirmation=yes, snakefile=snakefile, + progress_plain=progress_plain, use_new_centromere=use_new_centromere, ) diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index f5d15ad5..a023e579 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -1,19 +1,25 @@ import contextlib import re import shutil +import sys import tempfile +from collections.abc import Iterable from pathlib import Path from typing import List, Optional import click from scp import SCPClient +import latch.types.metadata as metadata + from ...centromere.ctx import _CentromereCtx from ...centromere.utils import MaybeRemoteDir from ...utils import WorkflowType, current_workspace from ..register.constants import ANSI_REGEX, MAX_LINES from ..register.utils import ( + DockerBuildLogItem, build_image, + import_module_by_path, register_serialized_pkg, serialize_pkg_in_container, upload_image, @@ -21,70 +27,90 @@ from ..workspace import _get_workspaces -def _delete_lines(lines: List[str]): +def _delete_lines(num: int): """Deletes the previous len(lines) lines, assuming cursor is on a new line just below the first line to be deleted""" - for _ in lines: + for i in range(num): print("\x1b[1F\x1b[0G\x1b[2K", end="") return [] -def _print_window(curr_lines: List[str], line: str): +def _print_window(cur_lines: List[str], line: str): """Prints the lines curr_lines[1:] and line, overwriting curr_lines in the process""" if line == "": - return curr_lines - elif len(curr_lines) >= MAX_LINES: + return cur_lines + elif len(cur_lines) >= MAX_LINES: line = ANSI_REGEX.sub("", line) - new_lines = curr_lines[len(curr_lines) - MAX_LINES + 1 :] + new_lines = cur_lines[len(cur_lines) - MAX_LINES + 1 :] new_lines.append(line) - _delete_lines(curr_lines) + _delete_lines(len(cur_lines)) for s in new_lines: print("\x1b[38;5;245m" + s + "\x1b[0m") return new_lines else: print("\x1b[38;5;245m" + line + "\x1b[0m") - curr_lines.append(line) - return curr_lines + cur_lines.append(line) + return cur_lines + + +docker_build_step_pat = re.compile("^Step [0-9]+/[0-9]+ :") -def print_and_write_build_logs(build_logs, image: str, pkg_root: Path): - print(f"Building Docker image for {image}") +def print_and_write_build_logs( + build_logs: Iterable[DockerBuildLogItem], + image: str, + pkg_root: Path, + *, + progress_plain: bool = False, +): + click.secho(f"Building Docker image", bold=True) - logs_path = (pkg_root / ".latch" / ".logs" / image).resolve() + logs_path = pkg_root / ".latch" / ".logs" / image logs_path.mkdir(parents=True, exist_ok=True) - with open(logs_path.joinpath("docker-build-logs.txt"), "w") as save_file: - r = re.compile("^Step [0-9]+/[0-9]+ :") - curr_lines = [] + + click.echo(f" Writing log to {click.style(logs_path, italic=True)}\n") + + with (logs_path / "docker-build-logs.txt").open("w") as save_file: + cur_lines: list[str] = [] + for x in build_logs: # for dockerfile parse errors - message: str = x.get("message") + message = x.get("message") if message is not None: save_file.write(f"{message}\n") raise ValueError(message) - lines: str = x.get("stream") - error: str = x.get("error") + lines = x.get("stream") + error = x.get("error") if error is not None: save_file.write(f"{error}\n") raise OSError(f"Error when building image ~ {error}") - if lines: + + if lines is not None: save_file.write(f"{lines}\n") - for line in lines.split("\n"): - curr_terminal_width = shutil.get_terminal_size()[0] - if len(line) > curr_terminal_width: - line = line[: curr_terminal_width - 3] + "..." - - if r.match(line): - curr_lines = _delete_lines(curr_lines) - print("\x1b[38;5;33m" + line + "\x1b[0m") - else: - curr_lines = _print_window(curr_lines, line) - _delete_lines(curr_lines) + + if not progress_plain: + for line in lines.split("\n"): + curr_terminal_width = shutil.get_terminal_size()[0] + + if len(line) > curr_terminal_width: + line = line[: curr_terminal_width - 3] + "..." + + if docker_build_step_pat.match(line): + cur_lines = _delete_lines(len(cur_lines)) + click.secho(line, fg="blue") + else: + cur_lines = _print_window(cur_lines, line) + else: + click.echo(lines, nl=False) + + if not progress_plain: + _delete_lines(len(cur_lines)) def print_upload_logs(upload_image_logs, image): - print(f"Uploading Docker image for {image}") + click.secho(f"Uploading Docker image", bold=True) prog_map = {} def _pp_prog_map(prog_map, prev_lines): @@ -109,32 +135,53 @@ def _pp_prog_map(prog_map, prev_lines): x.get("error") is not None and "denied: Your authorization token has expired." in x["error"] ): - raise OSError(f"Docker authorization for {image} is expired.") + click.secho( + f"\nDocker authorization token for {image} is expired.", + fg="red", + bold=True, + ) + sys.exit(1) + prog_map[x.get("id")] = x.get("progress") prev_lines = _pp_prog_map(prog_map, prev_lines) def _print_reg_resp(resp, image): - print(f"Registering {image} with LatchBio.") + click.secho("Registering workflow", bold=True) version = image.split(":")[1] if not resp.get("success"): - error_str = f"Error registering {image}\n\n" + error_str = f"Failed:\n\n" if resp.get("stderr") is not None: for line in resp.get("stderr").split("\n"): - if line and not line.startswith('{"json"'): - error_str += line + "\n" + if not line: + continue + + if line.startswith('{"json"'): + continue + + error_str += line + "\n" + if "task with different structure already exists" in error_str: - error_str = f"This version ({version}) already exists." - " Make sure that you've saved any changes you made." - raise ValueError(error_str) + error_str = ( + f"Version {version} already exists. Make sure that you've saved any" + " changes you made." + ) + + click.secho(f"\n{error_str}", fg="red", bold=True) + sys.exit(1) elif not "Successfully registered file" in resp["stdout"]: - raise ValueError( - f"This version ({version}) already exists." - " Make sure that you've saved any changes you made." + click.secho( + ( + f"\nVersion ({version}) already exists." + " Make sure that you've saved any changes you made." + ), + fg="red", + bold=True, ) - else: - print(resp.get("stdout")) + sys.exit(1) + + click.echo(resp.get("stdout")) def print_serialize_logs(serialize_logs, image): @@ -149,6 +196,8 @@ def _build_and_serialize( context_path: Path, tmp_dir: str, dockerfile: Optional[Path] = None, + *, + progress_plain: bool = False, ): assert ctx.pkg_root is not None @@ -163,7 +212,13 @@ def _build_and_serialize( ) from ...snakemake.workflow import build_jit_register_wrapper - wf = snakemake_workflow_extractor(ctx.pkg_root, ctx.snakefile) + meta = ctx.pkg_root / "latch_metadata.py" + if meta.exists(): + click.echo(f"Using metadata file {click.style(meta, italic=True)}") + import_module_by_path(meta) + else: + wf = snakemake_workflow_extractor(ctx.pkg_root, ctx.snakefile) + jit_wf = build_jit_register_wrapper() generate_jit_register_code( jit_wf, @@ -174,8 +229,11 @@ def _build_and_serialize( current_workspace(), ) + click.echo() image_build_logs = build_image(ctx, image_name, context_path, dockerfile) - print_and_write_build_logs(image_build_logs, image_name, ctx.pkg_root) + print_and_write_build_logs( + image_build_logs, image_name, ctx.pkg_root, progress_plain=progress_plain + ) if ctx.workflow_type == WorkflowType.snakemake: assert jit_wf is not None @@ -197,6 +255,7 @@ def _build_and_serialize( f"Serialization exited with nonzero exit code: {exit_status['Error']}" ) + click.echo() upload_image_logs = upload_image(ctx, image_name) print_upload_logs(upload_image_logs, image_name) @@ -223,6 +282,7 @@ def register( skip_confirmation: bool = False, snakefile: Optional[Path] = None, *, + progress_plain=False, use_new_centromere: bool = False, ): """Registers a workflow, defined as python code, with Latch. @@ -313,6 +373,14 @@ def register( ] ) ) + click.echo( + " ".join( + [ + click.style("Workflow root:", fg="bright_blue"), + str(ctx.default_container.pkg_dir), + ] + ) + ) if use_new_centromere: click.secho("Using experimental registration server.", fg="yellow") @@ -322,12 +390,23 @@ def register( click.secho("Cancelled", bold=True) return else: - click.secho("Skipping confirmation because of --yes", bold=True) + click.secho("Skipping confirmation because of --yes\n", bold=True) click.secho("Initializing registration", bold=True) transport = None scp = None + click.echo( + " ".join( + [ + click.style("Docker Image:", fg="bright_blue"), + ctx.default_container.image_name, + ] + ) + ) + + print() + if remote: print("Connecting to remote server for docker build...") @@ -345,6 +424,7 @@ def register( ctx.default_container.pkg_dir, td, dockerfile=ctx.default_container.dockerfile, + progress_plain=progress_plain, ) if remote: @@ -366,6 +446,7 @@ def register( ctx.default_container.pkg_dir, task_td, dockerfile=container.dockerfile, + progress_plain=progress_plain, ) if remote: diff --git a/latch_cli/services/register/utils.py b/latch_cli/services/register/utils.py index 70bedbc2..72e3187f 100644 --- a/latch_cli/services/register/utils.py +++ b/latch_cli/services/register/utils.py @@ -1,10 +1,13 @@ import base64 +import collections import contextlib +import importlib.util as iu import io import os import typing +from collections.abc import Iterable from pathlib import Path -from typing import Dict, Iterable, List, Optional, Tuple, Union +from typing import Dict, List, Optional, Tuple, TypedDict, Union import boto3 import requests @@ -52,12 +55,18 @@ def _docker_login(ctx: _CentromereCtx): ) +class DockerBuildLogItem(TypedDict): + message: Optional[str] + error: Optional[str] + stream: Optional[str] + + def build_image( ctx: _CentromereCtx, image_name: str, context_path: Path, dockerfile: Optional[Path] = None, -) -> List[str]: +) -> Iterable[DockerBuildLogItem]: assert ctx.dkr_client is not None _docker_login(ctx) @@ -144,3 +153,14 @@ def register_serialized_pkg( ) return response.json() + + +def import_module_by_path(x: Path): + spec = iu.spec_from_file_location("metadata", x) + assert spec is not None + assert spec.loader is not None + + module = iu.module_from_spec(spec) + spec.loader.exec_module(module) + + return module From d6cf3f8b7fe1c639f3b7904bbad59dc8db558e24 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 14 Jul 2023 13:46:03 -0700 Subject: [PATCH 047/356] fix snakemake name metadata Signed-off-by: maximsmol --- latch/types/metadata.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/latch/types/metadata.py b/latch/types/metadata.py index 699f979c..6ab8ee80 100644 --- a/latch/types/metadata.py +++ b/latch/types/metadata.py @@ -440,8 +440,17 @@ class SnakemakeMetadata(LatchMetadata): name: Optional[str] = None def __post_init__(self): + if self.name is None: + name = self.display_name.lower() + start = name[0] + + res: List[str] = [start if start.isidentifier() else "_"] + for x in name[1:]: + res.append(x if f"_{x}".isidentifier() else "_") + + self.name = "".join(res) + global _snakemake_metadata - self.name = self.display_name.lower().replace(" ", "_") _snakemake_metadata = self From 53d22ca1683d908730073386e24c58a9cbe5df89 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 14 Jul 2023 14:42:51 -0700 Subject: [PATCH 048/356] the big nasty Signed-off-by: maximsmol --- latch_cli/centromere/ctx.py | 2 +- latch_cli/docker_utils/__init__.py | 278 +++++++++++++++++------- latch_cli/exceptions/handler.py | 42 +++- latch_cli/services/register/register.py | 5 +- latch_cli/snakemake/serialize.py | 12 +- latch_cli/utils.py | 48 ++-- 6 files changed, 269 insertions(+), 118 deletions(-) diff --git a/latch_cli/centromere/ctx.py b/latch_cli/centromere/ctx.py index b8955782..d11901ac 100644 --- a/latch_cli/centromere/ctx.py +++ b/latch_cli/centromere/ctx.py @@ -2,7 +2,6 @@ import time from dataclasses import dataclass from pathlib import Path -from textwrap import dedent from typing import Dict, Optional, Tuple import click @@ -136,6 +135,7 @@ def __init__( if not self.disable_auto_version: hash = hash_directory(self.pkg_root) self.version = f"{self.version}-{hash[:6]}" + click.echo(f" {self.version}\n") if self.nucleus_check_version(self.version, self.workflow_name): raise ValueError(f"Version {self.version} has already been registered.") diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 4d98000b..678f0a1f 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -6,6 +6,7 @@ from textwrap import dedent from typing import List +import click import yaml from latch_cli.constants import latch_constants @@ -33,28 +34,58 @@ def write_block(self, f: TextIOWrapper): def get_prologue(config: LatchWorkflowConfig) -> List[str]: return [ - ( - "# latch base image + dependencies for latch SDK --- removing these will" - " break the workflow" - ), + "# DO NOT CHANGE", f"from {config.base_image}", - f"run pip install latch=={config.latch_version}", + "", + "workdir /tmp/docker-build/work/", + "", + dedent(r""" + shell [ \ + "/usr/bin/env", "bash", \ + "-o", "errexit", \ + "-o", "pipefail", \ + "-o", "nounset", \ + "-o", "verbose", \ + "-o", "errtrace", \ + "-O", "inherit_errexit", \ + "-O", "shift_verbose", \ + "-c" \ + ] + """).strip(), + "env TZ='Etc/UTC'", + "env LANG='en_US.UTF-8'", + "", + "arg DEBIAN_FRONTEND=noninteractive", + "", + "# Latch SDK", + f"# DO NOT REMOVE", + "run pip install latch=={config.latch_version}", "run mkdir /opt/latch", ] def get_epilogue(wf_type: WorkflowType = WorkflowType.latchbiosdk) -> List[str]: - cmds = [ - ( - "# latch internal tagging system + expected root directory --- changing" - " these lines will break the workflow" - ), + cmds: list[str] = [] + + if wf_type == WorkflowType.snakemake: + cmds += [ + "", + "# Latch snakemake workflow entrypoint", + "# DO NOT CHANGE", + "copy .latch/snakemake_jit_entrypoint.py /root/snakemake_jit_entrypoint.py", + ] + + cmds += [ + "", + "# Latch workflow registration metadata", + "# DO NOT CHANGE", "arg tag", + "# DO NOT CHANGE", "env FLYTE_INTERNAL_IMAGE $tag", + "", "workdir /root", ] - if wf_type == WorkflowType.snakemake: - cmds.append("copy .latch/latch_entrypoint.py /root/latch_entrypoint.py") + return cmds @@ -62,42 +93,89 @@ def infer_commands(pkg_root: Path) -> List[DockerCmdBlock]: commands: List[DockerCmdBlock] = [] if (pkg_root / "system-requirements.txt").exists(): - print("Adding system requirements installation phase") + click.echo( + " ".join( + [ + click.style(f"system-requirements.txt:", bold=True), + "System dependencies installation phase", + ] + ) + ) + commands.append( DockerCmdBlock( - comment="install system requirements", + comment="Install system dependencies", commands=[ "copy system-requirements.txt /opt/latch/system-requirements.txt", - ( - "run apt-get update --yes && xargs apt-get install --yes" - " List[DockerCmdBlock]: else: env_name = "workflow" + # todo(maximsmol): install `curl` and other build deps ahead of time once (or in base image) commands += [ DockerCmdBlock( - comment="set conda environment variables", + comment="Install Mambaforge", commands=[ - "env CONDA_DIR /opt/conda", - "env PATH=$CONDA_DIR/bin:$PATH", + dedent(r""" + run apt-get update --yes && \ + apt-get install --yes curl && \ + curl \ + --location \ + --fail \ + --remote-name \ + https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh && \ + `# Docs for -b and -p flags: https://docs.anaconda.com/anaconda/install/silent-mode/#linux-macos` \ + bash Mambaforge-Linux-x86_64.sh -b -p /opt/conda -u && \ + rm Mambaforge-Linux-x86_64.sh + """).strip(), ], order=DockerCmdBlockOrder.precopy, ), DockerCmdBlock( - comment="install miniconda", + comment="Set conda PATH", commands=[ - dedent(""" - run apt-get update --yes && \ - apt-get install --yes curl && \ - curl -O https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh && \ - mkdir /root/.conda && \ - # docs for -b and -p flags: https://docs.anaconda.com/anaconda/install/silent-mode/#linux-macos - bash Miniconda3-latest-Linux-x86_64.sh -b -p /opt/conda && \ - rm -f Miniconda3-latest-Linux-x86_64.sh - """).strip(), + "env PATH=/opt/conda/bin:$PATH", ], order=DockerCmdBlockOrder.precopy, ), DockerCmdBlock( - comment="build and configure conda environment", + comment="Build conda environment", commands=[ "copy environment.yaml /opt/latch/environment.yaml", - ( - "run conda env create --file /opt/latch/environment.yaml" - f" --name {env_name}" - ), - f"env PATH=$CONDA_DIR/envs/{env_name}/bin:$PATH", + dedent(rf""" + run mamba env create \ + --file /opt/latch/environment.yaml \ + --name {env_name} + """).strip(), + f"env PATH=/opt/conda/envs/{env_name}/bin:$PATH", ], order=DockerCmdBlockOrder.precopy, ), ] # from https://peps.python.org/pep-0518/ and https://peps.python.org/pep-0621/ - if (pkg_root / "setup.py").exists() or (pkg_root / "pyproject.toml").exists(): - print("Adding local package installation phase") + for f in [(pkg_root / "setup.py"), (pkg_root / "pyproject.toml")]: + if not f.exists(): + continue + + click.echo( + " ".join( + [ + click.style(f"{f.name}:", bold=True), + "Python package installation phase", + ] + ) + ) + + print() commands.append( DockerCmdBlock( - comment="add local package to python environment", - commands=["run pip install --editable /root/"], + comment="Install python package", + commands=["run pip install /root/"], order=DockerCmdBlockOrder.postcopy, ) ) if (pkg_root / "requirements.txt").exists(): - print("Adding python dependency installation phase") + click.echo( + " ".join( + [ + click.style("requirements.txt:", bold=True), + "Python pip dependencies installation phase", + ] + ) + ) commands.append( DockerCmdBlock( - comment=( - "add requirements from `requirements.txt` to python environment" - ), + comment="Install pip dependencies from `requirements.txt`", commands=[ "copy requirements.txt /opt/latch/requirements.txt", "run pip install --requirement /opt/latch/requirements.txt", @@ -171,20 +270,25 @@ def infer_commands(pkg_root: Path) -> List[DockerCmdBlock]: ) if (pkg_root / ".env").exists(): - print("Adding environment variable phase") - envs = [] + click.echo( + " ".join([click.style(".env:", bold=True), "Environment variable setup"]) + ) + envs: list[str] = [] for line in (pkg_root / ".env").read_text().splitlines(): - if line.startswith("#"): + line = line.strip() + + if line == "": continue - if line.strip() == "": + if line.startswith("#"): continue + envs.append(f"env {line}") commands.append( DockerCmdBlock( - comment="set environment variables", + comment="Set environment variables", commands=envs, - order=DockerCmdBlockOrder.postcopy, + order=DockerCmdBlockOrder.precopy, ) ) @@ -210,45 +314,63 @@ def generate_dockerfile( # └── ... """ - print("Generating Dockerfile") + click.secho("Generating Dockerfile", bold=True) try: with (pkg_root / latch_constants.pkg_config).open("r") as f: config: LatchWorkflowConfig = LatchWorkflowConfig(**json.load(f)) - print(" - base image:", config.base_image) - print(" - latch version:", config.latch_version) - except FileNotFoundError as e: - print( - "Could not find a .latch/config file in the supplied directory. Creating" - " configuration" - ) + except FileNotFoundError: + click.secho("Creating a default configuration file") + create_and_write_config(pkg_root) with (pkg_root / latch_constants.pkg_config).open("r") as f: config = LatchWorkflowConfig(**json.load(f)) + click.echo( + " ".join( + [ + click.style("Base image:", fg="bright_blue"), + config.base_image, + ] + ) + ) + click.echo( + " ".join( + [ + click.style("Latch SDK version:", fg="bright_blue"), + config.latch_version, + ] + ) + ) + click.echo() + with outfile.open("w") as f: f.write("\n".join(get_prologue(config)) + "\n\n") commands = infer_commands(pkg_root) for block in commands: - if block.order == DockerCmdBlockOrder.precopy: - block.write_block(f) + if block.order != DockerCmdBlockOrder.precopy: + continue - f.write("# copy all code from package (use .dockerignore to skip files)\n") + block.write_block(f) + + f.write("# Copy workflow data (use .dockerignore to skip files)\n") f.write("copy . /root/\n\n") for block in commands: - if block.order == DockerCmdBlockOrder.postcopy: - block.write_block(f) + if block.order != DockerCmdBlockOrder.postcopy: + continue - f.write("\n".join(get_epilogue(wf_type)) + "\n") + block.write_block(f) - print("Generated.") + f.write("\n".join(get_epilogue(wf_type)) + "\n") def get_default_dockerfile(pkg_root: Path, wf_type: WorkflowType): default_dockerfile = pkg_root / "Dockerfile" + if not default_dockerfile.exists(): default_dockerfile = pkg_root / ".latch" / "Dockerfile" - generate_dockerfile(pkg_root, default_dockerfile) + generate_dockerfile(pkg_root, default_dockerfile, wf_type) + return default_dockerfile diff --git a/latch_cli/exceptions/handler.py b/latch_cli/exceptions/handler.py index d50c59b5..f51c16f2 100644 --- a/latch_cli/exceptions/handler.py +++ b/latch_cli/exceptions/handler.py @@ -6,7 +6,6 @@ import tempfile from dataclasses import asdict, dataclass from pathlib import Path -from textwrap import dedent from traceback import print_exc from types import TracebackType from typing import List, Optional, Type @@ -26,13 +25,33 @@ class _Metadata: py_version: str = sys.version platform: str = platform.platform() - def __str__(self): - return dedent(f""" - Latch Version: {self.latch_version} - Python Version: {self.py_version} - Platform: {self.platform} - OS: {self.os_name}, {self.os_version} - """) + def print(self): + click.secho("Crash info:", bold=True) + click.echo( + " ".join( + [ + click.style("Latch SDK version:", fg="red"), + self.latch_version, + ] + ) + ) + click.echo( + " ".join( + [ + click.style("Python version:", fg="red"), + self.py_version.replace("\n", ";"), + ] + ) + ) + click.echo(" ".join([click.style("Platform:", fg="red"), self.platform])) + click.echo( + " ".join( + [ + click.style("OS:", fg="red"), + f"{self.os_name}; {self.os_version}", + ] + ) + ) class CrashHandler: @@ -113,12 +132,13 @@ def _excepthook( value: BaseException, traceback: Optional[TracebackType], ) -> None: - print(f"{self.message} - printing traceback:\n") + click.secho(f"\n{self.message}:\n", fg="red", bold=True) _Traceback(type_, value, traceback).pretty_print() - print(self.metadata) + + self.metadata.print() if os.environ.get("LATCH_NO_CRASH_REPORT") == "1": - click.echo( + click.secho( "Not generating crash report due to $LATCH_NO_CRASH_REPORT", bold=True, ) diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index a023e579..c3c7ef89 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -85,7 +85,8 @@ def print_and_write_build_logs( error = x.get("error") if error is not None: save_file.write(f"{error}\n") - raise OSError(f"Error when building image ~ {error}") + click.secho(f"Error when building image:\n{error}", fg="red", bold=True) + sys.exit(1) if lines is not None: save_file.write(f"{lines}\n") @@ -343,6 +344,8 @@ def register( snakefile=snakefile, use_new_centromere=use_new_centromere, ) as ctx: + click.echo("") + assert ctx.workflow_name is not None, "Unable to determine workflow name" assert ctx.version is not None, "Unable to determine workflow version" diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index c993d2a5..af41d257 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -291,7 +291,6 @@ def generate_jit_register_code( account_id: str, ) -> Path: code_block = textwrap.dedent("""\ - import inspect import json import os import subprocess @@ -308,9 +307,7 @@ def generate_jit_register_code( import google.protobuf.json_format as gpjson import gql import requests - from flyteidl.core import literals_pb2 as _literals_pb2 from flytekit.core import utils - from flytekit.core.context_manager import FlyteContext from flytekit.extras.persistence import LatchPersistence from latch_cli import tinyrequests from latch_cli.centromere.utils import _construct_dkr_client @@ -323,9 +320,8 @@ def generate_jit_register_code( from latch_cli.services.serialize import (extract_snakemake_workflow, generate_snakemake_entrypoint, serialize_snakemake) - from latch_cli.utils import generate_temporary_ssh_credentials - from latch import small_task, workflow + from latch import small_task from latch.gql._execute import execute from latch.types.directory import LatchDir from latch.types.file import LatchFile @@ -348,7 +344,7 @@ def check_exists_and_rename(old: Path, new: Path): wf.remote_output_url, ) - entrypoint = pkg_root.joinpath(".latch/jit_entrypoint.py") - with open(entrypoint, "w") as f: - f.write(code_block) + entrypoint = pkg_root / ".latch" / "snakemake_jit_entrypoint.py" + entrypoint.write_text(code_block) + return entrypoint diff --git a/latch_cli/utils.py b/latch_cli/utils.py index b7580179..a3037cb5 100644 --- a/latch_cli/utils.py +++ b/latch_cli/utils.py @@ -8,6 +8,7 @@ from pathlib import Path from typing import List +import click import jwt from latch_sdk_config.user import user_config @@ -116,23 +117,29 @@ def with_si_suffix(num, suffix="B", styled=False): def hash_directory(dir_path: Path) -> str: + # todo(maximsmol): store per-file hashes to show which files triggered a version change + click.secho("Calculating workflow version based on file content hash", bold=True) + m = hashlib.new("sha256") m.update(current_workspace().encode("utf-8")) ignore_file = dir_path / ".dockerignore" exclude: List[str] = ["/.latch"] try: - for l in ignore_file.open("r"): - l = l.strip() + with ignore_file.open("r") as f: + click.echo("Using .dockerignore") + + for l in f: + l = l.strip() - if l == "": - continue - if l[0] == "#": - continue + if l == "": + continue + if l[0] == "#": + continue - exclude.append(l) + exclude.append(l) except FileNotFoundError: - print("No .dockerignore file found --- including all files") + ... from docker.utils import exclude_paths @@ -140,23 +147,26 @@ def hash_directory(dir_path: Path) -> str: paths.sort() for item in paths: - # for repeatability guarantees p = Path(dir_path / item) if p.is_dir(): - m.update(str(p).encode("utf-8")) + m.update(p.name.encode("utf-8")) continue - m.update(str(p).encode("utf-8")) + m.update(p.name.encode("utf-8")) + file_size = p.stat().st_size - if file_size < latch_constants.file_max_size: - m.update(p.read_bytes()) - else: - print( - "\x1b[38;5;226m" - f"WARNING: {p.relative_to(dir_path.resolve())} is too large " - f"({with_si_suffix(file_size)}) to checksum, skipping." - "\x1b[0m" + if file_size > latch_constants.file_max_size: + click.secho( + ( + f"{p.relative_to(dir_path.resolve())} is too large" + f" ({with_si_suffix(file_size)}) to checksum. Ignoring contents" + ), + fg="yellow", + bold=True, ) + continue + + m.update(p.read_bytes()) return m.hexdigest() From e30f119c790967a7f3c781ba9ebf8f9e690aa65f Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 14 Jul 2023 14:44:10 -0700 Subject: [PATCH 049/356] oopsie Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 678f0a1f..8b6038ae 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -58,8 +58,8 @@ def get_prologue(config: LatchWorkflowConfig) -> List[str]: "arg DEBIAN_FRONTEND=noninteractive", "", "# Latch SDK", - f"# DO NOT REMOVE", - "run pip install latch=={config.latch_version}", + "# DO NOT REMOVE", + f"run pip install latch=={config.latch_version}", "run mkdir /opt/latch", ] From 340df5762a53c0cbe21ed843bb6de372ed92ff6b Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 14 Jul 2023 15:06:20 -0700 Subject: [PATCH 050/356] fix entrypoint name Signed-off-by: maximsmol --- latch_cli/services/register/register.py | 12 ++++++++++-- latch_cli/snakemake/workflow.py | 2 +- latch_cli/utils.py | 1 + 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index c3c7ef89..b25f5083 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -32,7 +32,6 @@ def _delete_lines(num: int): new line just below the first line to be deleted""" for i in range(num): print("\x1b[1F\x1b[0G\x1b[2K", end="") - return [] def _print_window(cur_lines: List[str], line: str): @@ -99,7 +98,8 @@ def print_and_write_build_logs( line = line[: curr_terminal_width - 3] + "..." if docker_build_step_pat.match(line): - cur_lines = _delete_lines(len(cur_lines)) + _delete_lines(len(cur_lines)) + cur_lines = [] click.secho(line, fg="blue") else: cur_lines = _print_window(cur_lines, line) @@ -332,6 +332,14 @@ def register( """ if snakefile is not None: + if remote: + click.secho( + "Cannot use remote builds with Snakemake, switching to a local build\n", + fg="yellow", + bold=True, + ) + remote = False + try: import snakemake except ImportError as e: diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 36bcd936..6848817d 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -848,7 +848,7 @@ def location(self) -> str: def loader_args( self, settings: SerializationSettings, task: PythonAutoContainerTask[T] ) -> List[str]: - return ["task-module", "jit_entrypoint", "task-name", task.name] + return ["task-module", "snakemake_jit_entrypoint", "task-name", task.name] def load_task(self, loader_args: List[str]) -> PythonAutoContainerTask: _, task_module, _, task_name, *_ = loader_args diff --git a/latch_cli/utils.py b/latch_cli/utils.py index a3037cb5..ddbfbd10 100644 --- a/latch_cli/utils.py +++ b/latch_cli/utils.py @@ -119,6 +119,7 @@ def with_si_suffix(num, suffix="B", styled=False): def hash_directory(dir_path: Path) -> str: # todo(maximsmol): store per-file hashes to show which files triggered a version change click.secho("Calculating workflow version based on file content hash", bold=True) + click.secho(" Disable with --disable-auto-version/-d", italic=True, dim=True) m = hashlib.new("sha256") m.update(current_workspace().encode("utf-8")) From ab9d8fea4257a369ffb11cc6e4e245ae1ded2d0c Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 14 Jul 2023 15:59:09 -0700 Subject: [PATCH 051/356] fixies Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 7 +- latch_cli/services/register/register.py | 8 +- latch_cli/snakemake/serialize.py | 97 +++++++++++++------------ 3 files changed, 60 insertions(+), 52 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 8b6038ae..17997e6c 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -59,7 +59,12 @@ def get_prologue(config: LatchWorkflowConfig) -> List[str]: "", "# Latch SDK", "# DO NOT REMOVE", - f"run pip install latch=={config.latch_version}", + # f"run pip install latch=={config.latch_version}", + "run apt-get update --yes && apt-get install --yes git", + ( + "run pip install" + " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'" + ), "run mkdir /opt/latch", ] diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index b25f5083..83ba8720 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -15,8 +15,9 @@ from ...centromere.ctx import _CentromereCtx from ...centromere.utils import MaybeRemoteDir from ...utils import WorkflowType, current_workspace -from ..register.constants import ANSI_REGEX, MAX_LINES -from ..register.utils import ( +from ..workspace import _get_workspaces +from .constants import ANSI_REGEX, MAX_LINES +from .utils import ( DockerBuildLogItem, build_image, import_module_by_path, @@ -24,7 +25,6 @@ serialize_pkg_in_container, upload_image, ) -from ..workspace import _get_workspaces def _delete_lines(num: int): @@ -148,7 +148,7 @@ def _pp_prog_map(prog_map, prev_lines): def _print_reg_resp(resp, image): - click.secho("Registering workflow", bold=True) + click.secho(f"Registering workflow {image}", bold=True) version = image.split(":")[1] if not resp.get("success"): diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index af41d257..12918119 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -5,6 +5,7 @@ from textwrap import dedent from typing import List, Optional, Set, Union, get_args +import click from flytekit import LaunchPlan from flytekit.configuration import Image, ImageConfig, SerializationSettings from flytekit.models import launch_plan as launch_plan_models @@ -242,6 +243,8 @@ def serialize_jit_register_workflow( ) + [admin_lp] ] + + click.secho("\nSerializing workflow entities", bold=True) persist_registrable_entities(registrable_entities, output_dir) @@ -290,52 +293,52 @@ def generate_jit_register_code( image_name: str, account_id: str, ) -> Path: - code_block = textwrap.dedent("""\ - import json - import os - import subprocess - import tempfile - import textwrap - import time - from functools import partial - from pathlib import Path - import shutil - from typing import List, NamedTuple, Optional, TypedDict - - import base64 - import boto3 - import google.protobuf.json_format as gpjson - import gql - import requests - from flytekit.core import utils - from flytekit.extras.persistence import LatchPersistence - from latch_cli import tinyrequests - from latch_cli.centromere.utils import _construct_dkr_client - from latch_cli.config.latch import config - from latch_cli.services.register.register import (_print_reg_resp, - _recursive_list, - register_serialized_pkg, - print_and_write_build_logs, - print_upload_logs) - from latch_cli.services.serialize import (extract_snakemake_workflow, - generate_snakemake_entrypoint, - serialize_snakemake) - - from latch import small_task - from latch.gql._execute import execute - from latch.types.directory import LatchDir - from latch.types.file import LatchFile - - - print = partial(print, flush=True) - - def check_exists_and_rename(old: Path, new: Path): - if new.exists(): - print(f"A file already exists at {new} and will be overwritten.") - if new.is_dir(): - shutil.rmtree(new) - os.renames(old, new) - """) + code_block = textwrap.dedent(r""" + import json + import os + import subprocess + import tempfile + import textwrap + import time + from functools import partial + from pathlib import Path + import shutil + from typing import List, NamedTuple, Optional, TypedDict + + import base64 + import boto3 + import google.protobuf.json_format as gpjson + import gql + import requests + from flytekit.core import utils + from flytekit.extras.persistence import LatchPersistence + from latch_cli import tinyrequests + from latch_cli.centromere.utils import _construct_dkr_client + from latch_sdk_config.latch import config + from latch_cli.services.register.register import (_print_reg_resp, + _recursive_list, + register_serialized_pkg, + print_and_write_build_logs, + print_upload_logs) + from latch_cli.services.serialize import (extract_snakemake_workflow, + generate_snakemake_entrypoint, + serialize_snakemake) + + from latch import small_task + from latch_sdk_gql.execute import execute + from latch.types.directory import LatchDir + from latch.types.file import LatchFile + + + print = partial(print, flush=True) + + def check_exists_and_rename(old: Path, new: Path): + if new.exists(): + print(f"A file already exists at {new} and will be overwritten.") + if new.is_dir(): + shutil.rmtree(new) + os.renames(old, new) + """).strip() code_block += wf.get_fn_code( snakefile_path_in_container(snakefile, pkg_root), version, @@ -345,6 +348,6 @@ def check_exists_and_rename(old: Path, new: Path): ) entrypoint = pkg_root / ".latch" / "snakemake_jit_entrypoint.py" - entrypoint.write_text(code_block) + entrypoint.write_text(code_block + "\n") return entrypoint From 93cd41ce7758b416d30241b8bed029ef4ed1f15b Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 14 Jul 2023 16:03:21 -0700 Subject: [PATCH 052/356] del old config file Signed-off-by: maximsmol --- latch_cli/config/latch.py | 112 --------------------------- latch_cli/services/register/utils.py | 2 +- 2 files changed, 1 insertion(+), 113 deletions(-) delete mode 100644 latch_cli/config/latch.py diff --git a/latch_cli/config/latch.py b/latch_cli/config/latch.py deleted file mode 100644 index 06aec099..00000000 --- a/latch_cli/config/latch.py +++ /dev/null @@ -1,112 +0,0 @@ -""" -config.latch -~~~~~~~~~~~~ -Platform wide configuration, eg. api endpoints, callback server ports... -""" - -# todo(ayush): put all configs into a `latch-config` package - -import os -from dataclasses import dataclass, fields, is_dataclass -from typing import Type, TypeVar -from urllib.parse import urljoin - -DOMAIN = os.environ.get("LATCH_SDK_DOMAIN", "latch.bio") -CONSOLE_URL = f"https://console.{DOMAIN}" -NUCLEUS_URL = f"https://nucleus.{DOMAIN}" -VACUOLE_URL = f"https://vacuole.{DOMAIN}" - -T = TypeVar("T") - - -@dataclass -class _DataAPI: - id: str = "/sdk/node-id" - list: str = "/sdk/list" - remove: str = "/sdk/rm" - touch: str = "/sdk/touch" - mkdir: str = "/sdk/mkdir" - verify: str = "/sdk/verify" - test_data: str = "/sdk/get-test-data-creds" - - get_signed_url: str = "/ldata/get-signed-url" - get_signed_urls_recursive: str = "/ldata/get-signed-urls-recursive" - start_upload: str = "/ldata/start-upload" - end_upload: str = "/ldata/end-upload" - - -@dataclass -class _WorkflowAPI: - upload_image: str = "/sdk/initiate-image-upload" - get_image: str = "/sdk/get-image-from-task" - register: str = "/sdk/register-workflow" - list: str = "/sdk/get-wf" - interface: str = "/sdk/wf-interface" - graph: str = "/sdk/get-workflow-graph" - check_version: str = "/sdk/check-workflow-version" - get_latest: str = "/sdk/get-latest-version-new" - preview: str = "/sdk/workflow-ui-preview" - create_execution: str = "/api/create-execution" - - -@dataclass -class _ExecutionAPI: - create: str = "/sdk/wf" - list: str = "/sdk/get-executions" - abort: str = "/sdk/abort-execution" - logs: str = "/sdk/get-logs-for-node" - exec: str = "/sdk/get-pod-exec-info" - - -@dataclass -class _UserAPI: - jwt: str = "/sdk/access-jwt" - list_workspaces: str = "/sdk/get-ws" - get_secret: str = "/secrets/get" - get_secret_local: str = "/secrets/get-local" - - -@dataclass -class _CentromereAPI: - provision: str = "/sdk/provision-centromere" - start_local_dev: str = "/sdk/initiate-local-development-session" - stop_local_dev: str = "/sdk/close-local-development-session" - - -@dataclass -class _API: - data: _DataAPI - workflow: _WorkflowAPI - execution: _ExecutionAPI - user: _UserAPI - centromere: _CentromereAPI - - -@dataclass -class _ConsoleRoutes: - developer: str = urljoin(CONSOLE_URL, "/settings/developer") - - -@dataclass -class _LatchConfig: - api: _API - gql: str = f"{VACUOLE_URL}/graphql" - console_routes: _ConsoleRoutes = _ConsoleRoutes() - dkr_repo: str = "812206152185.dkr.ecr.us-west-2.amazonaws.com" - console_url: str = CONSOLE_URL - nucleus_url: str = NUCLEUS_URL - vacuole_url: str = VACUOLE_URL - - -def build_endpoints(x: Type[T]) -> T: - res = {} - for field in fields(x): - if is_dataclass(field.type): - res[field.name] = build_endpoints(field.type) - elif field.type is str: - res[field.name] = urljoin(NUCLEUS_URL, str(field.default)) - return x(**res) - - -# singleton config instance -config = _LatchConfig(api=build_endpoints(_API)) diff --git a/latch_cli/services/register/utils.py b/latch_cli/services/register/utils.py index 72e3187f..3caebc9b 100644 --- a/latch_cli/services/register/utils.py +++ b/latch_cli/services/register/utils.py @@ -11,9 +11,9 @@ import boto3 import requests +from latch_sdk_config.latch import config from ...centromere.ctx import _CentromereCtx -from ...config.latch import config from ...utils import current_workspace From d87f15a6208d05221b225b70dce61d8cd0f63cdd Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 14 Jul 2023 16:17:31 -0700 Subject: [PATCH 053/356] upload Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 17 +++++++++++------ latch_cli/exceptions/handler.py | 2 +- latch_cli/snakemake/serialize.py | 25 +++++++++++++++---------- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 17997e6c..8b481eb7 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -59,12 +59,7 @@ def get_prologue(config: LatchWorkflowConfig) -> List[str]: "", "# Latch SDK", "# DO NOT REMOVE", - # f"run pip install latch=={config.latch_version}", - "run apt-get update --yes && apt-get install --yes git", - ( - "run pip install" - " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'" - ), + f"run pip install latch=={config.latch_version}", "run mkdir /opt/latch", ] @@ -359,6 +354,16 @@ def generate_dockerfile( block.write_block(f) + f.write("run apt-get update --yes && apt-get install --yes git\n") + f.write( + "run pip install" + " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" + ) + f.write( + "run echo 1 && pip install" + " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" + ) + f.write("# Copy workflow data (use .dockerignore to skip files)\n") f.write("copy . /root/\n\n") diff --git a/latch_cli/exceptions/handler.py b/latch_cli/exceptions/handler.py index f51c16f2..b7fb6646 100644 --- a/latch_cli/exceptions/handler.py +++ b/latch_cli/exceptions/handler.py @@ -26,7 +26,7 @@ class _Metadata: platform: str = platform.platform() def print(self): - click.secho("Crash info:", bold=True) + click.secho("Crash info:", fg="red", bold=True) click.echo( " ".join( [ diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index 12918119..733acff9 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -300,6 +300,7 @@ def generate_jit_register_code( import tempfile import textwrap import time + import sys from functools import partial from pathlib import Path import shutil @@ -315,22 +316,26 @@ def generate_jit_register_code( from latch_cli import tinyrequests from latch_cli.centromere.utils import _construct_dkr_client from latch_sdk_config.latch import config - from latch_cli.services.register.register import (_print_reg_resp, - _recursive_list, - register_serialized_pkg, - print_and_write_build_logs, - print_upload_logs) - from latch_cli.services.serialize import (extract_snakemake_workflow, - generate_snakemake_entrypoint, - serialize_snakemake) + from latch_cli.services.register.register import ( + _print_reg_resp, + _recursive_list, + register_serialized_pkg, + print_and_write_build_logs, + print_upload_logs, + ) + from latch_cli.snakemake.serialize import ( + extract_snakemake_workflow, + generate_snakemake_entrypoint, + serialize_snakemake, + ) from latch import small_task from latch_sdk_gql.execute import execute from latch.types.directory import LatchDir from latch.types.file import LatchFile - - print = partial(print, flush=True) + sys.stdout.reconfigure(line_buffering=True) + sys.stderr.reconfigure(line_buffering=True) def check_exists_and_rename(old: Path, new: Path): if new.exists(): From 899089c3d8e31164eff96e146a559103000d6827 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 14 Jul 2023 16:23:11 -0700 Subject: [PATCH 054/356] upload Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/__init__.py | 0 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 latch_cli/snakemake/__init__.py diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 8b481eb7..526eef70 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -360,7 +360,7 @@ def generate_dockerfile( " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) f.write( - "run echo 1 && pip install" + "run echo 3 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/__init__.py b/latch_cli/snakemake/__init__.py new file mode 100644 index 00000000..e69de29b From a58f564db30a0311600f9d8148b76c7f9ea1eac1 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 14 Jul 2023 16:39:49 -0700 Subject: [PATCH 055/356] fix jit workflow new metadata loading Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/serialize.py | 69 +++++++++++++++++------------- latch_cli/snakemake/workflow.py | 6 +-- 3 files changed, 43 insertions(+), 34 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 526eef70..b5a6d2ed 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -360,7 +360,7 @@ def generate_dockerfile( " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) f.write( - "run echo 3 && pip install" + "run echo 4 && pip uninstall --yes latch && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index 733acff9..e73b0129 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -31,6 +31,8 @@ interface_to_parameters, ) +from ..services.register.utils import import_module_by_path + RegistrableEntity = Union[ task_models.TaskSpec, launch_plan_models.LaunchPlan, @@ -44,37 +46,40 @@ def should_register_with_admin(entity: RegistrableEntity) -> bool: def ensure_snakemake_metadata_exists(): if metadata._snakemake_metadata is None: - raise ValueError(dedent(""" - - No `SnakemakeMetadata` object was detected in your Snakefile. This - object needs to be defined to register this workflow with Latch. - - You can paste the following in the top of your Snakefile to get - started: - - ``` - from pathlib import Path - from latch.types.metadata import SnakemakeMetadata, SnakemakeFileParameter - from latch.types.file import LatchFile - from latch.types.metadata import LatchAuthor, LatchMetadata - - SnakemakeMetadata( - display_name="My Snakemake Workflow", - author=LatchAuthor( - name="John Doe", - ), - parameters={ - "foo" : SnakemakeFileParameter( - display_name="Some Param", - type=LatchFile, - path=Path("foo.txt"), - ) - } + click.secho( + dedent(""" + No `SnakemakeMetadata` object was detected in your Snakefile. This + object needs to be defined to register this workflow with Latch. + + You can paste the following in the top of your Snakefile to get + started: + + ``` + from pathlib import Path + from latch.types.metadata import SnakemakeMetadata, SnakemakeFileParameter + from latch.types.file import LatchFile + from latch.types.metadata import LatchAuthor, LatchMetadata + + SnakemakeMetadata( + display_name="My Snakemake Workflow", + author=LatchAuthor( + name="John Doe", + ), + parameters={ + "foo" : SnakemakeFileParameter( + display_name="Some Param", + type=LatchFile, + path=Path("foo.txt"), + ) + } + ) + ``` + + Find more information at docs.latch.bio. + """), + bold=True, + fg="red", ) - ``` - - Find more information at docs.latch.bio. - """)) class SnakemakeWorkflowExtractor(Workflow): @@ -142,6 +147,10 @@ def snakemake_workflow_extractor( ) -> SnakemakeWorkflowExtractor: snakefile = snakefile.resolve() + meta = pkg_root / "latch_metadata.py" + if meta.exists(): + import_module_by_path(meta) + extractor = SnakemakeWorkflowExtractor( pkg_root=pkg_root, snakefile=snakefile, diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 6848817d..a3e86f68 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -279,7 +279,7 @@ def get_fn_code( snakefile = Path("{snakefile_path}") """), - "\t", + " ", ) if remote_output_url is not None: @@ -293,7 +293,7 @@ def get_fn_code( wf_name = wf.name generate_snakemake_entrypoint(wf, pkg_root, snakefile, {remote_output_url}) """), - "\t", + " ", ) code_block += textwrap.indent( @@ -451,7 +451,7 @@ class _WorkflowInfoNode(TypedDict): response = requests.post(config.api.workflow.create_execution, headers=headers, json=_interface_request) print(response.json()) """), - "\t", + " ", ) code_block += self.get_fn_return_stmt() return code_block From e9407d9c5a9b471c53727bd0f3047347bd2d2b42 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 14 Jul 2023 16:46:08 -0700 Subject: [PATCH 056/356] fixup indents Signed-off-by: maximsmol --- latch_cli/snakemake/serialize.py | 139 +++++++------ latch_cli/snakemake/workflow.py | 330 +++++++++++++++---------------- 2 files changed, 233 insertions(+), 236 deletions(-) diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index e73b0129..713d8f53 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -267,31 +267,30 @@ def generate_snakemake_entrypoint( snakefile: Path, remote_output_url: Optional[str] = None, ): - entrypoint_code_block = textwrap.dedent("""\ - import os - from pathlib import Path - import shutil - import subprocess - from typing import NamedTuple - - from latch import small_task - from latch.types.file import LatchFile - - def check_exists_and_rename(old: Path, new: Path): - if new.exists(): - print(f"A file already exists at {new} and will be overwritten.") - if new.is_dir(): - shutil.rmtree(new) - os.renames(old, new) - """) + entrypoint_code_block = textwrap.dedent(r""" + import os + from pathlib import Path + import shutil + import subprocess + from typing import NamedTuple + + from latch import small_task + from latch.types.file import LatchFile + + def check_exists_and_rename(old: Path, new: Path): + if new.exists(): + print(f"A file already exists at {new} and will be overwritten.") + if new.is_dir(): + shutil.rmtree(new) + os.renames(old, new) + """).strip() for task in wf.snakemake_tasks: entrypoint_code_block += task.get_fn_code( snakefile_path_in_container(snakefile, pkg_root), remote_output_url ) - entrypoint = pkg_root.joinpath("latch_entrypoint.py") - with open(entrypoint, "w") as f: - f.write(entrypoint_code_block) + entrypoint = pkg_root / "latch_entrypoint.py" + entrypoint.write_text(entrypoint_code_block + "\n") def generate_jit_register_code( @@ -303,56 +302,56 @@ def generate_jit_register_code( account_id: str, ) -> Path: code_block = textwrap.dedent(r""" - import json - import os - import subprocess - import tempfile - import textwrap - import time - import sys - from functools import partial - from pathlib import Path - import shutil - from typing import List, NamedTuple, Optional, TypedDict - - import base64 - import boto3 - import google.protobuf.json_format as gpjson - import gql - import requests - from flytekit.core import utils - from flytekit.extras.persistence import LatchPersistence - from latch_cli import tinyrequests - from latch_cli.centromere.utils import _construct_dkr_client - from latch_sdk_config.latch import config - from latch_cli.services.register.register import ( - _print_reg_resp, - _recursive_list, - register_serialized_pkg, - print_and_write_build_logs, - print_upload_logs, - ) - from latch_cli.snakemake.serialize import ( - extract_snakemake_workflow, - generate_snakemake_entrypoint, - serialize_snakemake, - ) - - from latch import small_task - from latch_sdk_gql.execute import execute - from latch.types.directory import LatchDir - from latch.types.file import LatchFile - - sys.stdout.reconfigure(line_buffering=True) - sys.stderr.reconfigure(line_buffering=True) - - def check_exists_and_rename(old: Path, new: Path): - if new.exists(): - print(f"A file already exists at {new} and will be overwritten.") - if new.is_dir(): - shutil.rmtree(new) - os.renames(old, new) - """).strip() + import json + import os + import subprocess + import tempfile + import textwrap + import time + import sys + from functools import partial + from pathlib import Path + import shutil + from typing import List, NamedTuple, Optional, TypedDict + + import base64 + import boto3 + import google.protobuf.json_format as gpjson + import gql + import requests + from flytekit.core import utils + from flytekit.extras.persistence import LatchPersistence + from latch_cli import tinyrequests + from latch_cli.centromere.utils import _construct_dkr_client + from latch_sdk_config.latch import config + from latch_cli.services.register.register import ( + _print_reg_resp, + _recursive_list, + register_serialized_pkg, + print_and_write_build_logs, + print_upload_logs, + ) + from latch_cli.snakemake.serialize import ( + extract_snakemake_workflow, + generate_snakemake_entrypoint, + serialize_snakemake, + ) + + from latch import small_task + from latch_sdk_gql.execute import execute + from latch.types.directory import LatchDir + from latch.types.file import LatchFile + + sys.stdout.reconfigure(line_buffering=True) + sys.stderr.reconfigure(line_buffering=True) + + def check_exists_and_rename(old: Path, new: Path): + if new.exists(): + print(f"A file already exists at {new} and will be overwritten.") + if new.is_dir(): + shutil.rmtree(new) + os.renames(old, new) + """).strip() code_block += wf.get_fn_code( snakefile_path_in_container(snakefile, pkg_root), version, diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index a3e86f68..14218fb9 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -248,7 +248,7 @@ def get_fn_interface( return fn_interface def get_fn_return_stmt(self): - return "\n\treturn True" + return "\n return True" def get_fn_code( self, @@ -265,192 +265,190 @@ def get_fn_code( for param, t in self.python_interface.inputs.items(): if t in (LatchFile, LatchDir): code_block += ( - f"\n\tcheck_exists_and_rename(Path({param}).resolve()," + f"\n check_exists_and_rename(Path({param}).resolve()," f' Path("{self.parameter_metadata[param].path}"))' ) else: raise ValueError(f"Unsupported parameter type {t} for {param}") code_block += textwrap.indent( - textwrap.dedent(f""" - - image_name = "{image_name}" - account_id = "{account_id}" - snakefile = Path("{snakefile_path}") - - """), + textwrap.dedent(rf""" + image_name = "{image_name}" + account_id = "{account_id}" + snakefile = Path("{snakefile_path}") + """), " ", ) if remote_output_url is not None: remote_output_url = f"'{remote_output_url}'" code_block += textwrap.indent( - textwrap.dedent(f""" - pkg_root = Path(".") - version = os.environ.get("FLYTE_INTERNAL_EXECUTION_ID") - - wf = extract_snakemake_workflow(pkg_root, snakefile, version) - wf_name = wf.name - generate_snakemake_entrypoint(wf, pkg_root, snakefile, {remote_output_url}) - """), + textwrap.dedent(rf""" + pkg_root = Path(".") + version = os.environ.get("FLYTE_INTERNAL_EXECUTION_ID") + + wf = extract_snakemake_workflow(pkg_root, snakefile, version) + wf_name = wf.name + generate_snakemake_entrypoint(wf, pkg_root, snakefile, {remote_output_url}) + """), " ", ) code_block += textwrap.indent( - textwrap.dedent(""" - dockerfile = Path("Dockerfile-dynamic").resolve() - dockerfile.write_text( - textwrap.dedent( - f''' - from 812206152185.dkr.ecr.us-west-2.amazonaws.com/{image_name} - - copy latch_entrypoint.py /root/latch_entrypoint.py - ''' - ) - ) - new_image_name = f"{image_name}-{version}" - - os.mkdir("/root/.ssh") - ssh_key_path = Path("/root/.ssh/id_rsa") - cmd = ["ssh-keygen", "-f", ssh_key_path, "-N", "", "-q"] - try: - subprocess.run(cmd, check=True) - except subprocess.CalledProcessError as e: - raise ValueError( - "There was a problem creating temporary SSH credentials. Please ensure" - " that `ssh-keygen` is installed and available in your PATH." - ) from e - os.chmod(ssh_key_path, 0o700) - - token = os.environ.get("FLYTE_INTERNAL_EXECUTION_ID", "") - headers = { - "Authorization": f"Latch-Execution-Token {token}", - } - - ssh_public_key_path = Path("/root/.ssh/id_rsa.pub") - response = tinyrequests.post( - config.api.centromere.provision, - headers=headers, - json={ - "public_key": ssh_public_key_path.read_text().strip(), - }, - ) + textwrap.dedent(r""" + dockerfile = Path("Dockerfile-dynamic").resolve() + dockerfile.write_text( + textwrap.dedent( + f''' + from 812206152185.dkr.ecr.us-west-2.amazonaws.com/{image_name} + + copy latch_entrypoint.py /root/latch_entrypoint.py + ''' + ) + ) + new_image_name = f"{image_name}-{version}" + + os.mkdir("/root/.ssh") + ssh_key_path = Path("/root/.ssh/id_rsa") + cmd = ["ssh-keygen", "-f", ssh_key_path, "-N", "", "-q"] + try: + subprocess.run(cmd, check=True) + except subprocess.CalledProcessError as e: + raise ValueError( + "There was a problem creating temporary SSH credentials. Please ensure" + " that `ssh-keygen` is installed and available in your PATH." + ) from e + os.chmod(ssh_key_path, 0o700) + + token = os.environ.get("FLYTE_INTERNAL_EXECUTION_ID", "") + headers = { + "Authorization": f"Latch-Execution-Token {token}", + } + + ssh_public_key_path = Path("/root/.ssh/id_rsa.pub") + response = tinyrequests.post( + config.api.centromere.provision, + headers=headers, + json={ + "public_key": ssh_public_key_path.read_text().strip(), + }, + ) - resp = response.json() - try: - public_ip = resp["ip"] - username = resp["username"] - except KeyError as e: - raise ValueError( - f"Malformed response from request for centromere login: {resp}" - ) from e - - - subprocess.run(["ssh", "-o", "StrictHostKeyChecking=no", f"{username}@{public_ip}", "uptime"]) - dkr_client = _construct_dkr_client(ssh_host=f"ssh://{username}@{public_ip}") - - data = {"pkg_name": new_image_name.split(":")[0], "ws_account_id": account_id} - response = requests.post(config.api.workflow.upload_image, headers=headers, json=data) - - try: - response = response.json() - access_key = response["tmp_access_key"] - secret_key = response["tmp_secret_key"] - session_token = response["tmp_session_token"] - except KeyError as err: - raise ValueError(f"malformed response on image upload: {response}") from err - - try: - client = boto3.session.Session( - aws_access_key_id=access_key, - aws_secret_access_key=secret_key, - aws_session_token=session_token, - region_name="us-west-2", - ).client("ecr") - token = client.get_authorization_token()["authorizationData"][0][ - "authorizationToken" - ] - except Exception as err: - raise ValueError( - f"unable to retreive an ecr login token for user {account_id}" - ) from err - - user, password = base64.b64decode(token).decode("utf-8").split(":") - dkr_client.login( - username=user, - password=password, - registry=config.dkr_repo, - ) + resp = response.json() + try: + public_ip = resp["ip"] + username = resp["username"] + except KeyError as e: + raise ValueError( + f"Malformed response from request for centromere login: {resp}" + ) from e + + + subprocess.run(["ssh", "-o", "StrictHostKeyChecking=no", f"{username}@{public_ip}", "uptime"]) + dkr_client = _construct_dkr_client(ssh_host=f"ssh://{username}@{public_ip}") + + data = {"pkg_name": new_image_name.split(":")[0], "ws_account_id": account_id} + response = requests.post(config.api.workflow.upload_image, headers=headers, json=data) + + try: + response = response.json() + access_key = response["tmp_access_key"] + secret_key = response["tmp_secret_key"] + session_token = response["tmp_session_token"] + except KeyError as err: + raise ValueError(f"malformed response on image upload: {response}") from err + + try: + client = boto3.session.Session( + aws_access_key_id=access_key, + aws_secret_access_key=secret_key, + aws_session_token=session_token, + region_name="us-west-2", + ).client("ecr") + token = client.get_authorization_token()["authorizationData"][0][ + "authorizationToken" + ] + except Exception as err: + raise ValueError( + f"unable to retreive an ecr login token for user {account_id}" + ) from err + + user, password = base64.b64decode(token).decode("utf-8").split(":") + dkr_client.login( + username=user, + password=password, + registry=config.dkr_repo, + ) - image_build_logs = dkr_client.build( - path=str(pkg_root), - dockerfile=str(dockerfile), - buildargs={"tag": f"{config.dkr_repo}/{new_image_name}"}, - tag=f"{config.dkr_repo}/{new_image_name}", - decode=True, - ) - print_and_write_build_logs(image_build_logs, new_image_name, pkg_root) + image_build_logs = dkr_client.build( + path=str(pkg_root), + dockerfile=str(dockerfile), + buildargs={"tag": f"{config.dkr_repo}/{new_image_name}"}, + tag=f"{config.dkr_repo}/{new_image_name}", + decode=True, + ) + print_and_write_build_logs(image_build_logs, new_image_name, pkg_root) - upload_image_logs = dkr_client.push( - repository=f"{config.dkr_repo}/{new_image_name}", - stream=True, - decode=True, - ) - print_upload_logs(upload_image_logs, new_image_name) - - temp_dir = tempfile.TemporaryDirectory() - with Path(temp_dir.name).resolve() as td: - serialize_snakemake(wf, td, new_image_name, config.dkr_repo) - - protos = _recursive_list(td) - reg_resp = register_serialized_pkg(protos, None, version, account_id) - _print_reg_resp(reg_resp, new_image_name) - - - class _WorkflowInfoNode(TypedDict): - id: str - - - nodes: Optional[List[_WorkflowInfoNode]] = None - while not nodes: - time.sleep(1) - nodes = execute( - gql.gql(''' - query workflowQuery($name: String, $ownerId: BigInt, $version: String) { - workflowInfos(condition: { name: $name, ownerId: $ownerId, version: $version}) { - nodes { - id - } - } - } - '''), - {"name": wf_name, "version": version, "ownerId": account_id}, - )["workflowInfos"]["nodes"] - - if len(nodes) > 1: - raise ValueError( - "Invariant violated - more than one workflow identified for unique combination" - " of {wf_name}, {version}, {account_id}" - ) + upload_image_logs = dkr_client.push( + repository=f"{config.dkr_repo}/{new_image_name}", + stream=True, + decode=True, + ) + print_upload_logs(upload_image_logs, new_image_name) + + temp_dir = tempfile.TemporaryDirectory() + with Path(temp_dir.name).resolve() as td: + serialize_snakemake(wf, td, new_image_name, config.dkr_repo) + + protos = _recursive_list(td) + reg_resp = register_serialized_pkg(protos, None, version, account_id) + _print_reg_resp(reg_resp, new_image_name) + + + class _WorkflowInfoNode(TypedDict): + id: str + + + nodes: Optional[List[_WorkflowInfoNode]] = None + while not nodes: + time.sleep(1) + nodes = execute( + gql.gql(''' + query workflowQuery($name: String, $ownerId: BigInt, $version: String) { + workflowInfos(condition: { name: $name, ownerId: $ownerId, version: $version}) { + nodes { + id + } + } + } + '''), + {"name": wf_name, "version": version, "ownerId": account_id}, + )["workflowInfos"]["nodes"] + + if len(nodes) > 1: + raise ValueError( + "Invariant violated - more than one workflow identified for unique combination" + " of {wf_name}, {version}, {account_id}" + ) - print(nodes) + print(nodes) - lp = LatchPersistence() - for file in wf.return_files: - print(f"Uploading {file.local_path} -> {file.remote_path}") - lp.upload(file.local_path, file.remote_path) + lp = LatchPersistence() + for file in wf.return_files: + print(f"Uploading {file.local_path} -> {file.remote_path}") + lp.upload(file.local_path, file.remote_path) - wf_id = nodes[0]["id"] - params = json.loads(gpjson.MessageToJson(wf.literal_map.to_flyte_idl()))["literals"] + wf_id = nodes[0]["id"] + params = json.loads(gpjson.MessageToJson(wf.literal_map.to_flyte_idl()))["literals"] - _interface_request = { - "workflow_id": wf_id, - "params": params, - } + _interface_request = { + "workflow_id": wf_id, + "params": params, + } - response = requests.post(config.api.workflow.create_execution, headers=headers, json=_interface_request) - print(response.json()) - """), + response = requests.post(config.api.workflow.create_execution, headers=headers, json=_interface_request) + print(response.json()) + """), " ", ) code_block += self.get_fn_return_stmt() @@ -745,7 +743,7 @@ def get_fn_interface(self): return fn_interface def get_fn_return_stmt(self, remote_output_url: Optional[str] = None): - return_stmt = "\n\treturn (" + return_stmt = "\n return (" for i, x in enumerate(self._python_outputs): if self._is_target: target_path = self._target_file_for_output_param[x] @@ -773,7 +771,7 @@ def get_fn_code( for param, t in self._python_inputs.items(): if t == LatchFile: code_block += ( - f"\n\tcheck_exists_and_rename(Path({param}).resolve()," + f"\n check_exists_and_rename(Path({param}).resolve()," f' Path("{self._target_file_for_input_param[param]}"))' ) @@ -804,7 +802,7 @@ def get_fn_code( for resource, value in allowed_resources: snakemake_cmd.append(f"{resource}={value}") - code_block += f"\n\n\tsubprocess.run({repr(snakemake_cmd)}, check=True)" + code_block += f"\n\n subprocess.run({repr(snakemake_cmd)}, check=True)" code_block += self.get_fn_return_stmt(remote_output_url=remote_output_url) return code_block From ca3065e571ef4060722a2de65196482c654ce347 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 14 Jul 2023 17:59:11 -0700 Subject: [PATCH 057/356] upload Signed-off-by: maximsmol --- latch/types/metadata.py | 12 +++------ latch_cli/centromere/ctx.py | 12 +++++++-- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/services/register/register.py | 35 +++++++++++++++---------- latch_cli/snakemake/serialize.py | 14 ++++------ latch_cli/snakemake/workflow.py | 8 +++++- latch_cli/utils.py | 11 ++++++++ 7 files changed, 59 insertions(+), 35 deletions(-) diff --git a/latch/types/metadata.py b/latch/types/metadata.py index 6ab8ee80..ab88da2e 100644 --- a/latch/types/metadata.py +++ b/latch/types/metadata.py @@ -9,6 +9,7 @@ from latch.types.directory import LatchDir from latch.types.file import LatchFile +from latch_cli.utils import identifier_from_str, identifier_suffix_from_str @dataclass @@ -441,14 +442,9 @@ class SnakemakeMetadata(LatchMetadata): def __post_init__(self): if self.name is None: - name = self.display_name.lower() - start = name[0] - - res: List[str] = [start if start.isidentifier() else "_"] - for x in name[1:]: - res.append(x if f"_{x}".isidentifier() else "_") - - self.name = "".join(res) + self.name = ( + f"snakemake_{identifier_suffix_from_str(self.display_name.lower())}" + ) global _snakemake_metadata _snakemake_metadata = self diff --git a/latch_cli/centromere/ctx.py b/latch_cli/centromere/ctx.py index d11901ac..aae985a7 100644 --- a/latch_cli/centromere/ctx.py +++ b/latch_cli/centromere/ctx.py @@ -32,6 +32,8 @@ retrieve_or_login, ) +from ..utils import identifier_suffix_from_str + @dataclass class _Container: @@ -81,6 +83,7 @@ def __init__( remote: bool = False, snakefile: Optional[Path] = None, use_new_centromere: bool = False, + custom_workflow_name: Optional[str] = None, ): with self: self.use_new_centromere = use_new_centromere @@ -101,6 +104,8 @@ def __init__( self.container_map: Dict[str, _Container] = {} if self.workflow_type == WorkflowType.latchbiosdk: + assert custom_workflow_name is None + _import_flyte_objects([self.pkg_root]) for entity in FlyteEntities.entities: if isinstance(entity, PythonFunctionWorkflow): @@ -119,7 +124,8 @@ def __init__( else: # todo(kenny): support per container task and custom workflow # name for snakemake - self.workflow_name = "snakemake workflow" + assert custom_workflow_name is not None + self.workflow_name = custom_workflow_name version_file = self.pkg_root / "version" try: @@ -199,7 +205,9 @@ def image(self): else: account_id = self.account_id - return f"{account_id}_{self.pkg_root.name.lower()}" + wf_name = identifier_suffix_from_str(self.workflow_name) + + return f"{account_id}_{wf_name}" @property def image_tagged(self): diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index b5a6d2ed..decb7e13 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -360,7 +360,7 @@ def generate_dockerfile( " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) f.write( - "run echo 4 && pip uninstall --yes latch && pip install" + "run echo 5 && pip uninstall --yes latch && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index 83ba8720..93b46324 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -10,8 +10,6 @@ import click from scp import SCPClient -import latch.types.metadata as metadata - from ...centromere.ctx import _CentromereCtx from ...centromere.utils import MaybeRemoteDir from ...utils import WorkflowType, current_workspace @@ -207,19 +205,9 @@ def _build_and_serialize( assert ctx.snakefile is not None assert ctx.version is not None - from ...snakemake.serialize import ( - generate_jit_register_code, - snakemake_workflow_extractor, - ) + from ...snakemake.serialize import generate_jit_register_code from ...snakemake.workflow import build_jit_register_wrapper - meta = ctx.pkg_root / "latch_metadata.py" - if meta.exists(): - click.echo(f"Using metadata file {click.style(meta, italic=True)}") - import_module_by_path(meta) - else: - wf = snakemake_workflow_extractor(ctx.pkg_root, ctx.snakefile) - jit_wf = build_jit_register_wrapper() generate_jit_register_code( jit_wf, @@ -331,6 +319,9 @@ def register( https://docs.flyte.org/en/latest/concepts/registration.html """ + pkg_root_p = Path(pkg_root) + custom_workflow_name = None + if snakefile is not None: if remote: click.secho( @@ -345,12 +336,28 @@ def register( except ImportError as e: raise RuntimeError("could not load snakemake: package not installed") from e + import latch.types.metadata as metadata + + from ...snakemake.serialize import snakemake_workflow_extractor + + meta = pkg_root_p / "latch_metadata.py" + if meta.exists(): + click.echo(f"Using metadata file {click.style(meta, italic=True)}") + import_module_by_path(meta) + else: + snakemake_workflow_extractor(pkg_root_p, snakefile) + + assert metadata._snakemake_metadata is not None + assert metadata._snakemake_metadata.name is not None + custom_workflow_name = metadata._snakemake_metadata.name + with _CentromereCtx( - Path(pkg_root), + pkg_root_p, disable_auto_version=disable_auto_version, remote=remote, snakefile=snakefile, use_new_centromere=use_new_centromere, + custom_workflow_name=custom_workflow_name, ) as ctx: click.echo("") diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index 713d8f53..df05cff1 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -19,19 +19,13 @@ from snakemake.workflow import Workflow, WorkflowError from typing_extensions import Self -import latch.types.metadata as metadata -from latch_cli.snakemake.serialize_utils import ( +from ..services.register.utils import import_module_by_path +from .serialize_utils import ( EntityCache, get_serializable_launch_plan, get_serializable_workflow, ) -from latch_cli.snakemake.workflow import ( - JITRegisterWorkflow, - SnakemakeWorkflow, - interface_to_parameters, -) - -from ..services.register.utils import import_module_by_path +from .workflow import JITRegisterWorkflow, SnakemakeWorkflow, interface_to_parameters RegistrableEntity = Union[ task_models.TaskSpec, @@ -45,6 +39,8 @@ def should_register_with_admin(entity: RegistrableEntity) -> bool: def ensure_snakemake_metadata_exists(): + import latch.types.metadata as metadata + if metadata._snakemake_metadata is None: click.secho( dedent(""" diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 14218fb9..e29251bb 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -7,6 +7,7 @@ from urllib.parse import urlparse import snakemake +import snakemake.io from flytekit.configuration import SerializationSettings from flytekit.core import constants as _common_constants from flytekit.core.class_based_resolver import ClassStorageTaskResolver @@ -39,6 +40,8 @@ from latch.types.directory import LatchDir from latch.types.file import LatchFile +from ..utils import identifier_suffix_from_str + SnakemakeInputVal: TypeAlias = snakemake.io._IOFile @@ -56,7 +59,10 @@ def task_fn_placeholder(): def variable_name_for_file(file: snakemake.io.AnnotatedString): - return file.replace("/", "_").replace(".", "__").replace("-", "____") + if file[0] == "/": + return f"a_{identifier_suffix_from_str(file)}" + + return f"r_{identifier_suffix_from_str(file)}" def variable_name_for_value( diff --git a/latch_cli/utils.py b/latch_cli/utils.py index ddbfbd10..d82f55c6 100644 --- a/latch_cli/utils.py +++ b/latch_cli/utils.py @@ -306,3 +306,14 @@ def __exit__(self, type, value, traceback): class WorkflowType(Enum): latchbiosdk = "latchbiosdk" snakemake = "snakemake" + + +def identifier_suffix_from_str(x: str) -> str: + res = "" + for c in x: + res += c if f"_{c}".isidentifier() else "_" + return res + + +def identifier_from_str(x: str) -> str: + return (x[0] if x[0].isidentifier() else "_") + identifier_suffix_from_str(x[1:]) From 73024d1c9696ba1d9bf6eff4b1dc0438ff1c6124 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 14 Jul 2023 17:59:39 -0700 Subject: [PATCH 058/356] upgrade pre-commit black Signed-off-by: maximsmol --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 58b5b1b2..81dd97e6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,7 +36,7 @@ repos: # - id: sort-simple-yaml # - id: trailing-whitespace - repo: https://github.com/psf/black - rev: 23.3.0 + rev: 23.7.0 hooks: - id: black - repo: https://github.com/PyCQA/isort From 4fb19f79f6b8875ae58a1bb31b65eca2098ed369 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 14 Jul 2023 18:16:12 -0700 Subject: [PATCH 059/356] upload entrypoint to debug Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index decb7e13..7280661e 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -360,7 +360,7 @@ def generate_dockerfile( " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) f.write( - "run echo 5 && pip uninstall --yes latch && pip install" + "run echo 6 && pip uninstall --yes latch && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index e29251bb..49ab745f 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -206,6 +206,8 @@ class JITRegisterWorkflow(WorkflowBase, ClassStorageTaskResolver): def __init__( self, ): + assert metadata._snakemake_metadata is not None + parameter_metadata = metadata._snakemake_metadata.parameters metadata._snakemake_metadata.parameters = parameter_metadata display_name = metadata._snakemake_metadata.display_name @@ -282,12 +284,15 @@ def get_fn_code( image_name = "{image_name}" account_id = "{account_id}" snakefile = Path("{snakefile_path}") + + lp = LatchPersistence() """), " ", ) if remote_output_url is not None: remote_output_url = f"'{remote_output_url}'" + code_block += textwrap.indent( textwrap.dedent(rf""" pkg_root = Path(".") @@ -296,6 +301,8 @@ def get_fn_code( wf = extract_snakemake_workflow(pkg_root, snakefile, version) wf_name = wf.name generate_snakemake_entrypoint(wf, pkg_root, snakefile, {remote_output_url}) + + lp.upload("latch_entrypoint.py", f"latch:///.snakemake_latch/workflow_entrypoints/{{image_name}}-{{version}}.py") """), " ", ) @@ -439,7 +446,6 @@ class _WorkflowInfoNode(TypedDict): print(nodes) - lp = LatchPersistence() for file in wf.return_files: print(f"Uploading {file.local_path} -> {file.remote_path}") lp.upload(file.local_path, file.remote_path) @@ -452,7 +458,7 @@ class _WorkflowInfoNode(TypedDict): "params": params, } - response = requests.post(config.api.workflow.create_execution, headers=headers, json=_interface_request) + response = requests.post("/api/create-execution", headers=headers, json=_interface_request) print(response.json()) """), " ", From 9f4e0759ed68bd2448f79304d77390efb997da11 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 14 Jul 2023 18:24:07 -0700 Subject: [PATCH 060/356] upload Signed-off-by: maximsmol --- latch_cli/centromere/ctx.py | 29 +++++++++++++++++-------- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/services/register/register.py | 28 +++--------------------- latch_cli/services/register/utils.py | 8 +++++-- latch_cli/snakemake/serialize.py | 1 + latch_cli/snakemake/workflow.py | 5 ++++- 6 files changed, 35 insertions(+), 38 deletions(-) diff --git a/latch_cli/centromere/ctx.py b/latch_cli/centromere/ctx.py index aae985a7..26e51311 100644 --- a/latch_cli/centromere/ctx.py +++ b/latch_cli/centromere/ctx.py @@ -32,6 +32,7 @@ retrieve_or_login, ) +from ..services.register.utils import import_module_by_path from ..utils import identifier_suffix_from_str @@ -83,7 +84,6 @@ def __init__( remote: bool = False, snakefile: Optional[Path] = None, use_new_centromere: bool = False, - custom_workflow_name: Optional[str] = None, ): with self: self.use_new_centromere = use_new_centromere @@ -104,8 +104,6 @@ def __init__( self.container_map: Dict[str, _Container] = {} if self.workflow_type == WorkflowType.latchbiosdk: - assert custom_workflow_name is None - _import_flyte_objects([self.pkg_root]) for entity in FlyteEntities.entities: if isinstance(entity, PythonFunctionWorkflow): @@ -122,10 +120,25 @@ def __init__( pkg_dir=entity.dockerfile_path.parent, ) else: + assert snakefile is not None + + import latch.types.metadata as metadata + + from ..snakemake.serialize import snakemake_workflow_extractor + + meta = pkg_root / "latch_metadata.py" + if meta.exists(): + click.echo(f"Using metadata file {click.style(meta, italic=True)}") + import_module_by_path(meta) + else: + snakemake_workflow_extractor(pkg_root, snakefile) + + assert metadata._snakemake_metadata is not None + assert metadata._snakemake_metadata.name is not None + # todo(kenny): support per container task and custom workflow # name for snakemake - assert custom_workflow_name is not None - self.workflow_name = custom_workflow_name + self.workflow_name = metadata._snakemake_metadata.name version_file = self.pkg_root / "version" try: @@ -229,10 +242,8 @@ def image_tagged(self): match = re.match("^[a-zA-Z0-9_][a-zA-Z0-9._-]{,127}$", self.version) if match is None: raise ValueError( - ( - f"{self.version} is an invalid version for AWS " - "ECR. Please provide a version that accomodates the " - ), + f"{self.version} is an invalid version for AWS " + "ECR. Please provide a version that accomodates the ", "tag restrictions listed here - ", "https://docs.aws.amazon.com/AmazonECR/latest/userguide/ecr-using-tags.html", ) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 7280661e..e287a2ee 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -360,7 +360,7 @@ def generate_dockerfile( " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) f.write( - "run echo 6 && pip uninstall --yes latch && pip install" + "run echo 7 && pip uninstall --yes latch && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index 93b46324..fd37b914 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -171,10 +171,8 @@ def _print_reg_resp(resp, image): sys.exit(1) elif not "Successfully registered file" in resp["stdout"]: click.secho( - ( - f"\nVersion ({version}) already exists." - " Make sure that you've saved any changes you made." - ), + f"\nVersion ({version}) already exists." + " Make sure that you've saved any changes you made.", fg="red", bold=True, ) @@ -218,7 +216,6 @@ def _build_and_serialize( current_workspace(), ) - click.echo() image_build_logs = build_image(ctx, image_name, context_path, dockerfile) print_and_write_build_logs( image_build_logs, image_name, ctx.pkg_root, progress_plain=progress_plain @@ -319,9 +316,6 @@ def register( https://docs.flyte.org/en/latest/concepts/registration.html """ - pkg_root_p = Path(pkg_root) - custom_workflow_name = None - if snakefile is not None: if remote: click.secho( @@ -336,28 +330,12 @@ def register( except ImportError as e: raise RuntimeError("could not load snakemake: package not installed") from e - import latch.types.metadata as metadata - - from ...snakemake.serialize import snakemake_workflow_extractor - - meta = pkg_root_p / "latch_metadata.py" - if meta.exists(): - click.echo(f"Using metadata file {click.style(meta, italic=True)}") - import_module_by_path(meta) - else: - snakemake_workflow_extractor(pkg_root_p, snakefile) - - assert metadata._snakemake_metadata is not None - assert metadata._snakemake_metadata.name is not None - custom_workflow_name = metadata._snakemake_metadata.name - with _CentromereCtx( - pkg_root_p, + Path(pkg_root), disable_auto_version=disable_auto_version, remote=remote, snakefile=snakefile, use_new_centromere=use_new_centromere, - custom_workflow_name=custom_workflow_name, ) as ctx: click.echo("") diff --git a/latch_cli/services/register/utils.py b/latch_cli/services/register/utils.py index 3caebc9b..dc5c133f 100644 --- a/latch_cli/services/register/utils.py +++ b/latch_cli/services/register/utils.py @@ -7,15 +7,19 @@ import typing from collections.abc import Iterable from pathlib import Path -from typing import Dict, List, Optional, Tuple, TypedDict, Union +from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, TypedDict, Union import boto3 import requests from latch_sdk_config.latch import config -from ...centromere.ctx import _CentromereCtx from ...utils import current_workspace +if TYPE_CHECKING: + from ...centromere.ctx import _CentromereCtx +else: + _CentromereCtx = "" + def _docker_login(ctx: _CentromereCtx): assert ctx.dkr_client is not None diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index df05cff1..c5ebbcbe 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -268,6 +268,7 @@ def generate_snakemake_entrypoint( from pathlib import Path import shutil import subprocess + import hashlib from typing import NamedTuple from latch import small_task diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 49ab745f..46a7135b 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -296,7 +296,10 @@ def get_fn_code( code_block += textwrap.indent( textwrap.dedent(rf""" pkg_root = Path(".") - version = os.environ.get("FLYTE_INTERNAL_EXECUTION_ID") + + exec_id_hash = hashlib.sha1() + exec_id_hash.update(os.environ["FLYTE_INTERNAL_EXECUTION_ID"].encode("utf-8")) + version = exec_id_hash.hexdigest()[:16] wf = extract_snakemake_workflow(pkg_root, snakefile, version) wf_name = wf.name From 60d4ff02c444b932a20f766e766ee6009aaf9bb3 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 14 Jul 2023 18:49:41 -0700 Subject: [PATCH 061/356] fix endpoint Signed-off-by: maximsmol --- latch_cli/snakemake/serialize.py | 1 + latch_cli/snakemake/workflow.py | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index c5ebbcbe..ecc05492 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -270,6 +270,7 @@ def generate_snakemake_entrypoint( import subprocess import hashlib from typing import NamedTuple + from urllib.parse import urljoin from latch import small_task from latch.types.file import LatchFile diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 46a7135b..fddde25b 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -305,7 +305,9 @@ def get_fn_code( wf_name = wf.name generate_snakemake_entrypoint(wf, pkg_root, snakefile, {remote_output_url}) - lp.upload("latch_entrypoint.py", f"latch:///.snakemake_latch/workflow_entrypoints/{{image_name}}-{{version}}.py") + entrypoint_remote = f"latch:///.snakemake_latch/workflow_entrypoints/{{image_name}}-{{version}}.py" + lp.upload("latch_entrypoint.py", entrypoint_remote) + print(f"latch_entrypoint.py -> {{entrypoint_remote}}") """), " ", ) @@ -461,7 +463,7 @@ class _WorkflowInfoNode(TypedDict): "params": params, } - response = requests.post("/api/create-execution", headers=headers, json=_interface_request) + response = requests.post(urljoin(config.nucleus_url, "/api/create-execution"), headers=headers, json=_interface_request) print(response.json()) """), " ", From 9eb7764d4246d48daa0c8fc72308f9753b22ef05 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 14 Jul 2023 19:03:57 -0700 Subject: [PATCH 062/356] fix hashlib import Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/serialize.py | 8 +++++--- latch_cli/snakemake/workflow.py | 6 +++++- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index e287a2ee..6e7eb090 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -360,7 +360,7 @@ def generate_dockerfile( " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) f.write( - "run echo 7 && pip uninstall --yes latch && pip install" + "run echo 8 && pip uninstall --yes latch && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index ecc05492..f309760c 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -13,6 +13,7 @@ from flytekit.models import task as task_models from flytekit.models.admin import workflow as admin_workflow_models from flytekit.tools.serialize_helpers import persist_registrable_entities +from google.protobuf.json_format import MessageToJson from snakemake.dag import DAG from snakemake.persistence import Persistence from snakemake.rules import Rule @@ -191,7 +192,8 @@ def serialize_snakemake( registrable_entity_cache: EntityCache = {} - get_serializable_workflow(wf, settings, registrable_entity_cache) + wf_spec = get_serializable_workflow(wf, settings, registrable_entity_cache) + Path("wf_spec.json").write_text(MessageToJson(wf_spec.to_flyte_idl())) parameter_map = interface_to_parameters(wf.python_interface) lp = LaunchPlan( @@ -268,9 +270,7 @@ def generate_snakemake_entrypoint( from pathlib import Path import shutil import subprocess - import hashlib from typing import NamedTuple - from urllib.parse import urljoin from latch import small_task from latch.types.file import LatchFile @@ -311,6 +311,8 @@ def generate_jit_register_code( from pathlib import Path import shutil from typing import List, NamedTuple, Optional, TypedDict + import hashlib + from urllib.parse import urljoin import base64 import boto3 diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index fddde25b..fcb19b74 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -305,7 +305,7 @@ def get_fn_code( wf_name = wf.name generate_snakemake_entrypoint(wf, pkg_root, snakefile, {remote_output_url}) - entrypoint_remote = f"latch:///.snakemake_latch/workflow_entrypoints/{{image_name}}-{{version}}.py" + entrypoint_remote = f"latch:///.snakemake_latch/workflows/{{image_name}}-{{version}}/entrypoint.py" lp.upload("latch_entrypoint.py", entrypoint_remote) print(f"latch_entrypoint.py -> {{entrypoint_remote}}") """), @@ -422,6 +422,10 @@ def get_fn_code( reg_resp = register_serialized_pkg(protos, None, version, account_id) _print_reg_resp(reg_resp, new_image_name) + wf_spec_remote = f"latch:///.snakemake_latch/workflows/{{image_name}}-{{version}}/spec.json" + lp.upload("wf_spec.json", wf_spec_remote) + print(f"wf_spec.json -> {{wf_spec_remote}}") + class _WorkflowInfoNode(TypedDict): id: str From c97f644629517e369b32010289da20ff3797a02e Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 14 Jul 2023 19:22:30 -0700 Subject: [PATCH 063/356] add metadata for params Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/services/register/register.py | 1 - latch_cli/snakemake/workflow.py | 12 +++++++++--- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 6e7eb090..97e9564e 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -360,7 +360,7 @@ def generate_dockerfile( " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) f.write( - "run echo 8 && pip uninstall --yes latch && pip install" + "run echo 9 && pip uninstall --yes latch && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index fd37b914..915f9d31 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -18,7 +18,6 @@ from .utils import ( DockerBuildLogItem, build_image, - import_module_by_path, register_serialized_pkg, serialize_pkg_in_container, upload_image, diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index fcb19b74..ac440671 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -126,8 +126,14 @@ def snakemake_dag_to_interface( ) ) + meta = metadata.LatchMetadata( + display_name=wf_name, + author=metadata.LatchAuthor(name="Latch Snakemake JIT"), + parameters={k: metadata.LatchParameter(display_name=k) for k in inputs.keys()}, + ) + return ( - Interface(inputs, outputs, docstring=docstring), + Interface(inputs, outputs, docstring=Docstring(str(meta))), LiteralMap(literals=literals), return_files, ) @@ -422,9 +428,9 @@ def get_fn_code( reg_resp = register_serialized_pkg(protos, None, version, account_id) _print_reg_resp(reg_resp, new_image_name) - wf_spec_remote = f"latch:///.snakemake_latch/workflows/{{image_name}}-{{version}}/spec.json" + wf_spec_remote = f"latch:///.snakemake_latch/workflows/{image_name}-{version}/spec.json" lp.upload("wf_spec.json", wf_spec_remote) - print(f"wf_spec.json -> {{wf_spec_remote}}") + print(f"wf_spec.json -> {wf_spec_remote}") class _WorkflowInfoNode(TypedDict): From 6ad08310529d58dee482e586e0fe521208e854fe Mon Sep 17 00:00:00 2001 From: maximsmol Date: Sat, 15 Jul 2023 10:44:47 -0700 Subject: [PATCH 064/356] upload Signed-off-by: maximsmol --- latch_cli/snakemake/serialize.py | 18 ++ latch_cli/snakemake/workflow.py | 374 ++++++++++++++++--------------- 2 files changed, 217 insertions(+), 175 deletions(-) diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index f309760c..3dc7f74e 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -281,6 +281,24 @@ def check_exists_and_rename(old: Path, new: Path): if new.is_dir(): shutil.rmtree(new) os.renames(old, new) + + + def si_unit(num, base: float = 1000.0): + for unit in (" ", "k", "M", "G", "T", "P", "E", "Z"): + if abs(num) < base: + return f"{num:3.1f}{unit}" + num /= base + return f"{num:.1f}Y" + + + def file_name_and_size(x: Path): + s = x.stat() + + if stat.S_ISDIR(s.st_mode): + return f"{'D':>8} {x.name}/" + + return f"{si_unit(s.st_size):>7}B {x.name}" + """).strip() for task in wf.snakemake_tasks: entrypoint_code_block += task.get_fn_code( diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index ac440671..5c660110 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -48,6 +48,13 @@ T = TypeVar("T") +# todo(maximsmol): use a stateful writer that keeps track of indent level +def reindent(x: str, level: int) -> str: + if x[0] == "\n": + x = x[1:] + return textwrap.indent(textwrap.dedent(x), " " * level) + + @dataclass class JobOutputInfo: jobid: str @@ -285,198 +292,198 @@ def get_fn_code( else: raise ValueError(f"Unsupported parameter type {t} for {param}") - code_block += textwrap.indent( - textwrap.dedent(rf""" - image_name = "{image_name}" - account_id = "{account_id}" - snakefile = Path("{snakefile_path}") + code_block += reindent( + rf""" + image_name = "{image_name}" + account_id = "{account_id}" + snakefile = Path("{snakefile_path}") - lp = LatchPersistence() - """), - " ", + lp = LatchPersistence() + """, + 1, ) if remote_output_url is not None: remote_output_url = f"'{remote_output_url}'" - code_block += textwrap.indent( - textwrap.dedent(rf""" - pkg_root = Path(".") + code_block += reindent( + rf""" + pkg_root = Path(".") - exec_id_hash = hashlib.sha1() - exec_id_hash.update(os.environ["FLYTE_INTERNAL_EXECUTION_ID"].encode("utf-8")) - version = exec_id_hash.hexdigest()[:16] + exec_id_hash = hashlib.sha1() + exec_id_hash.update(os.environ["FLYTE_INTERNAL_EXECUTION_ID"].encode("utf-8")) + version = exec_id_hash.hexdigest()[:16] - wf = extract_snakemake_workflow(pkg_root, snakefile, version) - wf_name = wf.name - generate_snakemake_entrypoint(wf, pkg_root, snakefile, {remote_output_url}) + wf = extract_snakemake_workflow(pkg_root, snakefile, version) + wf_name = wf.name + generate_snakemake_entrypoint(wf, pkg_root, snakefile, {remote_output_url}) - entrypoint_remote = f"latch:///.snakemake_latch/workflows/{{image_name}}-{{version}}/entrypoint.py" - lp.upload("latch_entrypoint.py", entrypoint_remote) - print(f"latch_entrypoint.py -> {{entrypoint_remote}}") - """), - " ", + entrypoint_remote = f"latch:///.snakemake_latch/workflows/{{image_name}}-{{version}}/entrypoint.py" + lp.upload("latch_entrypoint.py", entrypoint_remote) + print(f"latch_entrypoint.py -> {{entrypoint_remote}}") + """, + 1, ) - code_block += textwrap.indent( - textwrap.dedent(r""" - dockerfile = Path("Dockerfile-dynamic").resolve() - dockerfile.write_text( - textwrap.dedent( - f''' - from 812206152185.dkr.ecr.us-west-2.amazonaws.com/{image_name} + code_block += reindent( + r""" + dockerfile = Path("Dockerfile-dynamic").resolve() + dockerfile.write_text( + textwrap.dedent( + f''' + from 812206152185.dkr.ecr.us-west-2.amazonaws.com/{image_name} - copy latch_entrypoint.py /root/latch_entrypoint.py - ''' - ) - ) - new_image_name = f"{image_name}-{version}" - - os.mkdir("/root/.ssh") - ssh_key_path = Path("/root/.ssh/id_rsa") - cmd = ["ssh-keygen", "-f", ssh_key_path, "-N", "", "-q"] - try: - subprocess.run(cmd, check=True) - except subprocess.CalledProcessError as e: - raise ValueError( - "There was a problem creating temporary SSH credentials. Please ensure" - " that `ssh-keygen` is installed and available in your PATH." - ) from e - os.chmod(ssh_key_path, 0o700) - - token = os.environ.get("FLYTE_INTERNAL_EXECUTION_ID", "") - headers = { - "Authorization": f"Latch-Execution-Token {token}", - } - - ssh_public_key_path = Path("/root/.ssh/id_rsa.pub") - response = tinyrequests.post( - config.api.centromere.provision, - headers=headers, - json={ - "public_key": ssh_public_key_path.read_text().strip(), - }, - ) + copy latch_entrypoint.py /root/latch_entrypoint.py + ''' + ) + ) + new_image_name = f"{image_name}-{version}" + + os.mkdir("/root/.ssh") + ssh_key_path = Path("/root/.ssh/id_rsa") + cmd = ["ssh-keygen", "-f", ssh_key_path, "-N", "", "-q"] + try: + subprocess.run(cmd, check=True) + except subprocess.CalledProcessError as e: + raise ValueError( + "There was a problem creating temporary SSH credentials. Please ensure" + " that `ssh-keygen` is installed and available in your PATH." + ) from e + os.chmod(ssh_key_path, 0o700) + + token = os.environ.get("FLYTE_INTERNAL_EXECUTION_ID", "") + headers = { + "Authorization": f"Latch-Execution-Token {token}", + } + + ssh_public_key_path = Path("/root/.ssh/id_rsa.pub") + response = tinyrequests.post( + config.api.centromere.provision, + headers=headers, + json={ + "public_key": ssh_public_key_path.read_text().strip(), + }, + ) - resp = response.json() - try: - public_ip = resp["ip"] - username = resp["username"] - except KeyError as e: - raise ValueError( - f"Malformed response from request for centromere login: {resp}" - ) from e - - - subprocess.run(["ssh", "-o", "StrictHostKeyChecking=no", f"{username}@{public_ip}", "uptime"]) - dkr_client = _construct_dkr_client(ssh_host=f"ssh://{username}@{public_ip}") - - data = {"pkg_name": new_image_name.split(":")[0], "ws_account_id": account_id} - response = requests.post(config.api.workflow.upload_image, headers=headers, json=data) - - try: - response = response.json() - access_key = response["tmp_access_key"] - secret_key = response["tmp_secret_key"] - session_token = response["tmp_session_token"] - except KeyError as err: - raise ValueError(f"malformed response on image upload: {response}") from err - - try: - client = boto3.session.Session( - aws_access_key_id=access_key, - aws_secret_access_key=secret_key, - aws_session_token=session_token, - region_name="us-west-2", - ).client("ecr") - token = client.get_authorization_token()["authorizationData"][0][ - "authorizationToken" - ] - except Exception as err: - raise ValueError( - f"unable to retreive an ecr login token for user {account_id}" - ) from err - - user, password = base64.b64decode(token).decode("utf-8").split(":") - dkr_client.login( - username=user, - password=password, - registry=config.dkr_repo, - ) + resp = response.json() + try: + public_ip = resp["ip"] + username = resp["username"] + except KeyError as e: + raise ValueError( + f"Malformed response from request for centromere login: {resp}" + ) from e + + + subprocess.run(["ssh", "-o", "StrictHostKeyChecking=no", f"{username}@{public_ip}", "uptime"]) + dkr_client = _construct_dkr_client(ssh_host=f"ssh://{username}@{public_ip}") + + data = {"pkg_name": new_image_name.split(":")[0], "ws_account_id": account_id} + response = requests.post(config.api.workflow.upload_image, headers=headers, json=data) + + try: + response = response.json() + access_key = response["tmp_access_key"] + secret_key = response["tmp_secret_key"] + session_token = response["tmp_session_token"] + except KeyError as err: + raise ValueError(f"malformed response on image upload: {response}") from err + + try: + client = boto3.session.Session( + aws_access_key_id=access_key, + aws_secret_access_key=secret_key, + aws_session_token=session_token, + region_name="us-west-2", + ).client("ecr") + token = client.get_authorization_token()["authorizationData"][0][ + "authorizationToken" + ] + except Exception as err: + raise ValueError( + f"unable to retreive an ecr login token for user {account_id}" + ) from err + + user, password = base64.b64decode(token).decode("utf-8").split(":") + dkr_client.login( + username=user, + password=password, + registry=config.dkr_repo, + ) - image_build_logs = dkr_client.build( - path=str(pkg_root), - dockerfile=str(dockerfile), - buildargs={"tag": f"{config.dkr_repo}/{new_image_name}"}, - tag=f"{config.dkr_repo}/{new_image_name}", - decode=True, - ) - print_and_write_build_logs(image_build_logs, new_image_name, pkg_root) + image_build_logs = dkr_client.build( + path=str(pkg_root), + dockerfile=str(dockerfile), + buildargs={"tag": f"{config.dkr_repo}/{new_image_name}"}, + tag=f"{config.dkr_repo}/{new_image_name}", + decode=True, + ) + print_and_write_build_logs(image_build_logs, new_image_name, pkg_root) - upload_image_logs = dkr_client.push( - repository=f"{config.dkr_repo}/{new_image_name}", - stream=True, - decode=True, - ) - print_upload_logs(upload_image_logs, new_image_name) - - temp_dir = tempfile.TemporaryDirectory() - with Path(temp_dir.name).resolve() as td: - serialize_snakemake(wf, td, new_image_name, config.dkr_repo) - - protos = _recursive_list(td) - reg_resp = register_serialized_pkg(protos, None, version, account_id) - _print_reg_resp(reg_resp, new_image_name) - - wf_spec_remote = f"latch:///.snakemake_latch/workflows/{image_name}-{version}/spec.json" - lp.upload("wf_spec.json", wf_spec_remote) - print(f"wf_spec.json -> {wf_spec_remote}") - - - class _WorkflowInfoNode(TypedDict): - id: str - - - nodes: Optional[List[_WorkflowInfoNode]] = None - while not nodes: - time.sleep(1) - nodes = execute( - gql.gql(''' - query workflowQuery($name: String, $ownerId: BigInt, $version: String) { - workflowInfos(condition: { name: $name, ownerId: $ownerId, version: $version}) { - nodes { - id - } - } - } - '''), - {"name": wf_name, "version": version, "ownerId": account_id}, - )["workflowInfos"]["nodes"] - - if len(nodes) > 1: - raise ValueError( - "Invariant violated - more than one workflow identified for unique combination" - " of {wf_name}, {version}, {account_id}" - ) + upload_image_logs = dkr_client.push( + repository=f"{config.dkr_repo}/{new_image_name}", + stream=True, + decode=True, + ) + print_upload_logs(upload_image_logs, new_image_name) + + temp_dir = tempfile.TemporaryDirectory() + with Path(temp_dir.name).resolve() as td: + serialize_snakemake(wf, td, new_image_name, config.dkr_repo) + + protos = _recursive_list(td) + reg_resp = register_serialized_pkg(protos, None, version, account_id) + _print_reg_resp(reg_resp, new_image_name) + + wf_spec_remote = f"latch:///.snakemake_latch/workflows/{image_name}-{version}/spec.json" + lp.upload("wf_spec.json", wf_spec_remote) + print(f"wf_spec.json -> {wf_spec_remote}") + + + class _WorkflowInfoNode(TypedDict): + id: str + + + nodes: Optional[List[_WorkflowInfoNode]] = None + while not nodes: + time.sleep(1) + nodes = execute( + gql.gql(''' + query workflowQuery($name: String, $ownerId: BigInt, $version: String) { + workflowInfos(condition: { name: $name, ownerId: $ownerId, version: $version}) { + nodes { + id + } + } + } + '''), + {"name": wf_name, "version": version, "ownerId": account_id}, + )["workflowInfos"]["nodes"] + + if len(nodes) > 1: + raise ValueError( + "Invariant violated - more than one workflow identified for unique combination" + " of {wf_name}, {version}, {account_id}" + ) - print(nodes) + print(nodes) - for file in wf.return_files: - print(f"Uploading {file.local_path} -> {file.remote_path}") - lp.upload(file.local_path, file.remote_path) + for file in wf.return_files: + print(f"Uploading {file.local_path} -> {file.remote_path}") + lp.upload(file.local_path, file.remote_path) - wf_id = nodes[0]["id"] - params = json.loads(gpjson.MessageToJson(wf.literal_map.to_flyte_idl()))["literals"] + wf_id = nodes[0]["id"] + params = json.loads(gpjson.MessageToJson(wf.literal_map.to_flyte_idl()))["literals"] - _interface_request = { - "workflow_id": wf_id, - "params": params, - } + _interface_request = { + "workflow_id": wf_id, + "params": params, + } - response = requests.post(urljoin(config.nucleus_url, "/api/create-execution"), headers=headers, json=_interface_request) - print(response.json()) - """), - " ", + response = requests.post(urljoin(config.nucleus_url, "/api/create-execution"), headers=headers, json=_interface_request) + print(response.json()) + """, + 1, ) code_block += self.get_fn_return_stmt() return code_block @@ -797,9 +804,26 @@ def get_fn_code( for param, t in self._python_inputs.items(): if t == LatchFile: - code_block += ( - f"\n check_exists_and_rename(Path({param}).resolve()," - f' Path("{self._target_file_for_input_param[param]}"))' + code_block += reindent( + rf""" + {param}_dst_p = Path({self._target_file_for_input_param[param]}) + + print(f"Downloading {{{param}.remote_path}}") + {param}_p = Path({param}).resolve() + print(f" {{file_name_and_size({param}_p)}}") + """, + 1, + ) + + code_block += reindent( + rf""" + print(f"Moving {param} to {{{param}_dst_p}}") + check_exists_and_rename( + {param}_p, + {param}_dst_p + ) + """, + 1, ) snakemake_cmd = [ From 7c0b37433b5d0c3217b4b9abe840cfe18d0ac5c7 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Sat, 15 Jul 2023 11:16:22 -0700 Subject: [PATCH 065/356] upload Signed-off-by: maximsmol --- latch_cli/snakemake/serialize.py | 23 +++++- latch_cli/snakemake/workflow.py | 117 ++++++++++++++++++++++++------- 2 files changed, 112 insertions(+), 28 deletions(-) diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index 3dc7f74e..2e8f3d7c 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -271,6 +271,7 @@ def generate_snakemake_entrypoint( import shutil import subprocess from typing import NamedTuple + import stat from latch import small_task from latch.types.file import LatchFile @@ -299,7 +300,7 @@ def file_name_and_size(x: Path): return f"{si_unit(s.st_size):>7}B {x.name}" - """).strip() + """).lstrip() for task in wf.snakemake_tasks: entrypoint_code_block += task.get_fn_code( snakefile_path_in_container(snakefile, pkg_root), remote_output_url @@ -332,8 +333,10 @@ def generate_jit_register_code( import hashlib from urllib.parse import urljoin + import stat import base64 import boto3 + import boto3.session import google.protobuf.json_format as gpjson import gql import requests @@ -369,7 +372,23 @@ def check_exists_and_rename(old: Path, new: Path): if new.is_dir(): shutil.rmtree(new) os.renames(old, new) - """).strip() + + def si_unit(num, base: float = 1000.0): + for unit in (" ", "k", "M", "G", "T", "P", "E", "Z"): + if abs(num) < base: + return f"{num:3.1f}{unit}" + num /= base + return f"{num:.1f}Y" + + def file_name_and_size(x: Path): + s = x.stat() + + if stat.S_ISDIR(s.st_mode): + return f"{'D':>8} {x.name}/" + + return f"{si_unit(s.st_size):>7}B {x.name}" + + """).lstrip() code_block += wf.get_fn_code( snakefile_path_in_container(snakefile, pkg_root), version, diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 5c660110..e21bba9d 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -258,15 +258,26 @@ def get_fn_interface( ): if fn_name is None: fn_name = self.name - fn_interface = f"\n\n@{decorator_name}\ndef {fn_name}(" - fn_interface += ( - ", ".join( - f"{param}: {t.__name__}" - for param, t in self.python_interface.inputs.items() - ) - + ") -> bool:" + + params_str = ",\n".join( + reindent( + rf""" + {param}: {t.__name__} + """, + 1, + ).rstrip() + for param, t in self.python_interface.inputs.items() ) - return fn_interface + + return reindent( + rf""" + @{decorator_name} + def {fn_name}( + __params__ + ) -> bool: + """, + 0, + ).replace("__params__", params_str) def get_fn_return_stmt(self): return "\n return True" @@ -280,14 +291,44 @@ def get_fn_code( remote_output_url: Optional[str], ): task_name = f"{self.name}_task" + code_block = "" code_block += self.get_fn_interface(fn_name=task_name) for param, t in self.python_interface.inputs.items(): if t in (LatchFile, LatchDir): - code_block += ( - f"\n check_exists_and_rename(Path({param}).resolve()," - f' Path("{self.parameter_metadata[param].path}"))' + code_block += reindent( + rf""" + {param}_dst_p = Path("{self.parameter_metadata[param].path}") + + print(f"Downloading {{{param}.remote_path}}") + {param}_p = Path({param}).resolve() + print(f" {{file_name_and_size({param}_p)}}") + + """, + 1, + ) + + if t is LatchDir: + code_block += reindent( + rf""" + for x in {param}_p.iterdir(): + print(f" {{file_name_and_size(x)}}") + + """, + 1, + ) + + code_block += reindent( + rf""" + print(f"Moving {param} to {{{param}_dst_p}}") + check_exists_and_rename( + {param}_p, + {param}_dst_p + ) + + """, + 1, ) else: raise ValueError(f"Unsupported parameter type {t} for {param}") @@ -755,26 +796,50 @@ def __init__( ) def get_fn_interface(self): - fn_interface = f"\n\n@small_task\ndef {self.name}(" - fn_interface += ( - ", ".join( - f"{param}: {t.__name__}" for param, t in self._python_inputs.items() + params_str = ",\n".join( + reindent( + rf""" + {param}: {t.__name__} + """, + 1, ) - + ")" + for param, t in self._python_inputs.items() ) + outputs_str = "None:" if len(self._python_outputs.items()) > 0: - fn_interface += ( - f" -> NamedTuple('{self.name}_output', " - + ", ".join( - f"{param}={t.__name__}" for param, t in self._python_outputs.items() - ) - + "):" + outputs_str = ",\n".join( + reindent( + rf""" + {param}={t.__name__} + """, + 1, + ).rstrip() + for param, t in self._python_outputs.items() + ) + outputs_str = reindent( + rf""" + NamedTuple( + "{self.name}_output", + {outputs_str} + ): + """, + 0, ) - else: - fn_interface += ":" - return fn_interface + return ( + reindent( + rf""" + @small_task + def {self.name}( + __params__ + ) -> __outputs__ + """, + 0, + ) + .replace("__params__", params_str) + .replace("__outputs__", outputs_str) + ) def get_fn_return_stmt(self, remote_output_url: Optional[str] = None): return_stmt = "\n return (" @@ -806,7 +871,7 @@ def get_fn_code( if t == LatchFile: code_block += reindent( rf""" - {param}_dst_p = Path({self._target_file_for_input_param[param]}) + {param}_dst_p = Path("{self._target_file_for_input_param[param]}") print(f"Downloading {{{param}.remote_path}}") {param}_p = Path({param}).resolve() From b89e41ccee64d65f8c9e7c7e71818c3e790d56b3 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Sat, 15 Jul 2023 11:49:38 -0700 Subject: [PATCH 066/356] upload Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/serialize.py | 6 ++- latch_cli/snakemake/workflow.py | 83 ++++++++++++++++++++---------- 3 files changed, 62 insertions(+), 29 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 97e9564e..905727af 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -360,7 +360,7 @@ def generate_dockerfile( " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) f.write( - "run echo 9 && pip uninstall --yes latch && pip install" + "run echo 10 && pip uninstall --yes latch && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index 2e8f3d7c..aba2af6e 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -301,10 +301,12 @@ def file_name_and_size(x: Path): return f"{si_unit(s.st_size):>7}B {x.name}" """).lstrip() - for task in wf.snakemake_tasks: - entrypoint_code_block += task.get_fn_code( + entrypoint_code_block += "\n\n".join( + task.get_fn_code( snakefile_path_in_container(snakefile, pkg_root), remote_output_url ) + for task in wf.snakemake_tasks + ) entrypoint = pkg_root / "latch_entrypoint.py" entrypoint.write_text(entrypoint_code_block + "\n") diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index e21bba9d..a56072f0 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -280,7 +280,12 @@ def {fn_name}( ).replace("__params__", params_str) def get_fn_return_stmt(self): - return "\n return True" + return reindent( + rf""" + return True + """, + 1, + ) def get_fn_code( self, @@ -808,7 +813,7 @@ def get_fn_interface(self): outputs_str = "None:" if len(self._python_outputs.items()) > 0: - outputs_str = ",\n".join( + outputs_list_str = ",\n".join( reindent( rf""" {param}={t.__name__} @@ -821,20 +826,20 @@ def get_fn_interface(self): rf""" NamedTuple( "{self.name}_output", - {outputs_str} + __outputs__ ): """, 0, - ) + ).replace("__outputs__", outputs_list_str) return ( reindent( rf""" - @small_task - def {self.name}( - __params__ - ) -> __outputs__ - """, + @small_task + def {self.name}( + __params__ + ) -> __outputs__ + """, 0, ) .replace("__params__", params_str) @@ -842,24 +847,44 @@ def {self.name}( ) def get_fn_return_stmt(self, remote_output_url: Optional[str] = None): - return_stmt = "\n return (" - for i, x in enumerate(self._python_outputs): - if self._is_target: - target_path = self._target_file_for_output_param[x] - if remote_output_url is None: - remote_path = Path("/Snakemake Outputs") / target_path - else: - remote_path = Path(urlparse(remote_output_url).path) / target_path - - return_stmt += f"LatchFile('{target_path}', 'latch://{remote_path}')" - else: - return_stmt += f"LatchFile('{self._target_file_for_output_param[x]}')" - if i == len(self._python_outputs) - 1: - return_stmt += ")" + results: list[str] = [] + for out in self._python_outputs: + if not self._is_target: + results.append( + reindent( + rf""" + LatchFile("{self._target_file_for_output_param[out]}") + """, + 1, + ).rstrip() + ) + continue + + target_path = self._target_file_for_output_param[out] + if remote_output_url is None: + remote_path = Path("/Snakemake Outputs") / target_path else: - return_stmt += ", " + remote_path = Path(urlparse(remote_output_url).path) / target_path + + results.append( + reindent( + rf""" + LatchFile("{target_path}", "latch://{remote_path}") + """, + 1, + ).rstrip() + ) - return return_stmt + return_str = ",\n".join(results) + + return reindent( + rf""" + return ( + __return_str__ + ) + """, + 1, + ).replace("__return_str__", return_str) def get_fn_code( self, snakefile_path_in_container: str, remote_output_url: Optional[str] = None @@ -876,6 +901,7 @@ def get_fn_code( print(f"Downloading {{{param}.remote_path}}") {param}_p = Path({param}).resolve() print(f" {{file_name_and_size({param}_p)}}") + """, 1, ) @@ -918,7 +944,12 @@ def get_fn_code( for resource, value in allowed_resources: snakemake_cmd.append(f"{resource}={value}") - code_block += f"\n\n subprocess.run({repr(snakemake_cmd)}, check=True)" + code_block += reindent( + rf""" + subprocess.run({repr(snakemake_cmd)}, check=True) + """, + 1, + ) code_block += self.get_fn_return_stmt(remote_output_url=remote_output_url) return code_block From 00899008abfa184d428a9fcdcd9420f45be2555d Mon Sep 17 00:00:00 2001 From: maximsmol Date: Sat, 15 Jul 2023 12:35:05 -0700 Subject: [PATCH 067/356] use dataclasses, misc Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/serialize.py | 4 ++++ latch_cli/snakemake/workflow.py | 37 ++++++++++++++++++------------ 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 905727af..33d4b1cf 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -360,7 +360,7 @@ def generate_dockerfile( " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) f.write( - "run echo 10 && pip uninstall --yes latch && pip install" + "run echo 11 && pip uninstall --yes latch && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index aba2af6e..f8bedc93 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -272,10 +272,14 @@ def generate_snakemake_entrypoint( import subprocess from typing import NamedTuple import stat + from dataclasses import dataclass from latch import small_task from latch.types.file import LatchFile + sys.stdout.reconfigure(line_buffering=True) + sys.stderr.reconfigure(line_buffering=True) + def check_exists_and_rename(old: Path, new: Path): if new.exists(): print(f"A file already exists at {new} and will be overwritten.") diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index a56072f0..c818e010 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -801,38 +801,42 @@ def __init__( ) def get_fn_interface(self): + res = "" + params_str = ",\n".join( reindent( rf""" {param}: {t.__name__} """, 1, - ) + ).rstrip() for param, t in self._python_inputs.items() ) outputs_str = "None:" if len(self._python_outputs.items()) > 0: - outputs_list_str = ",\n".join( + output_fields = "\n".join( reindent( rf""" - {param}={t.__name__} + {param}: {t.__name__} """, 1, ).rstrip() for param, t in self._python_outputs.items() ) - outputs_str = reindent( + + res += reindent( rf""" - NamedTuple( - "{self.name}_output", - __outputs__ - ): + @dataclass + class Res{self.name}: + __output_fields__ + """, 0, - ).replace("__outputs__", outputs_list_str) + ).replace("__output_fields__", output_fields) + outputs_str = f"Res{self.name}:" - return ( + res += ( reindent( rf""" @small_task @@ -845,22 +849,23 @@ def {self.name}( .replace("__params__", params_str) .replace("__outputs__", outputs_str) ) + return res def get_fn_return_stmt(self, remote_output_url: Optional[str] = None): results: list[str] = [] - for out in self._python_outputs: + for out_name in self._python_outputs: if not self._is_target: results.append( reindent( rf""" - LatchFile("{self._target_file_for_output_param[out]}") + {out_name}=LatchFile("{self._target_file_for_output_param[out_name]}") """, 1, ).rstrip() ) continue - target_path = self._target_file_for_output_param[out] + target_path = self._target_file_for_output_param[out_name] if remote_output_url is None: remote_path = Path("/Snakemake Outputs") / target_path else: @@ -869,7 +874,7 @@ def get_fn_return_stmt(self, remote_output_url: Optional[str] = None): results.append( reindent( rf""" - LatchFile("{target_path}", "latch://{remote_path}") + {out_name}=LatchFile("{target_path}", "latch://{remote_path}") """, 1, ).rstrip() @@ -879,7 +884,7 @@ def get_fn_return_stmt(self, remote_output_url: Optional[str] = None): return reindent( rf""" - return ( + return Res{self.name}( __return_str__ ) """, @@ -946,7 +951,9 @@ def get_fn_code( code_block += reindent( rf""" + subprocess.run({repr(snakemake_cmd)}, check=True) + """, 1, ) From 989ffaa65ade108a12f7662fc1e4f15c30f9c57c Mon Sep 17 00:00:00 2001 From: maximsmol Date: Sat, 15 Jul 2023 12:38:23 -0700 Subject: [PATCH 068/356] oops Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/serialize.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 33d4b1cf..bc40e711 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -360,7 +360,7 @@ def generate_dockerfile( " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) f.write( - "run echo 11 && pip uninstall --yes latch && pip install" + "run echo 12 && pip uninstall --yes latch && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index f8bedc93..44ac90d3 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -273,6 +273,7 @@ def generate_snakemake_entrypoint( from typing import NamedTuple import stat from dataclasses import dataclass + import sys from latch import small_task from latch.types.file import LatchFile From e64e9817a86d74114e31c76dd9f7eac9210e5efe Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 17 Jul 2023 12:23:07 -0700 Subject: [PATCH 069/356] upload Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/serialize.py | 2 + latch_cli/snakemake/single_task_snakemake.py | 73 ++++++++++++++++++++ latch_cli/snakemake/workflow.py | 16 +++-- 4 files changed, 88 insertions(+), 5 deletions(-) create mode 100644 latch_cli/snakemake/single_task_snakemake.py diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index bc40e711..f77720f1 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -360,7 +360,7 @@ def generate_dockerfile( " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) f.write( - "run echo 12 && pip uninstall --yes latch && pip install" + "run echo 13 && pip uninstall --yes latch && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index 44ac90d3..4e14cefa 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -79,6 +79,7 @@ def ensure_snakemake_metadata_exists(): ) +# todo(maximsmol): this needs to run in a subprocess because it pollutes globals class SnakemakeWorkflowExtractor(Workflow): def __init__(self, pkg_root: Path, snakefile: Path): super().__init__(snakefile=snakefile) @@ -364,6 +365,7 @@ def generate_jit_register_code( generate_snakemake_entrypoint, serialize_snakemake, ) + import latch_cli.snakemake from latch import small_task from latch_sdk_gql.execute import execute diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py new file mode 100644 index 00000000..88a8ec77 --- /dev/null +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -0,0 +1,73 @@ +import json +import os +from textwrap import dedent + +import snakemake +from snakemake.parser import ( + Input, + Output, + Rule, + StopAutomaton, + is_comment, + is_dedent, + is_indent, + is_newline, +) + +target_rules = set(json.loads(os.environ["LATCH_SNAKEMAKE_RULES"])) +target_rule_output = os.environ["LATCH_SNAKEMAKE_TARGET_OUTPUT"] + +# Add a custom entrypoint rule +_real_rule_start = Rule.start + + +def rule_start(self, aux=""): + prefix = "" + if self.rulename in target_rules: + prefix = dedent(f""" + @workflow.rule(name='latch_entrypoint', lineno=1, snakefile='workflow/Snakefile') + @workflow.input( + {target_rule_output} + ) + @workflow.norun() + @workflow.run + def __rule_latch_entrypoint(input, output, params, wildcards, threads, resources, log, version, rule, conda_env, container_img, singularity_args, use_singularity, env_modules, bench_record, jobid, is_shell, bench_iteration, cleanup_scripts, shadow_dir, edit_notebook, conda_base_path, basedir, runtime_sourcecache_path, __is_snakemake_rule_func=True): + pass + + """) + + yield prefix + next(_real_rule_start(self, aux)) + + +Rule.start = rule_start + + +# Skip @workflow.input and @workflow.output for non-target tasks +def skip_block(self, token, force_block_end=False): + if self.lasttoken == "\n" and is_comment(token): + # ignore lines containing only comments + self.line -= 1 + if force_block_end or self.is_block_end(token): + yield from self.decorate_end(token) + yield "\n", token + raise StopAutomaton(token) + + if is_newline(token): + self.line += 1 + yield token.string, token + + elif not (is_indent(token) or is_dedent(token)): + if is_comment(token): + yield token.string, token + else: + if self.lasttoken == "\n" and self.rulename not in target_rules: + yield "#", token + + yield from self.block_content(token) + + +Input.block = skip_block +Output.block = skip_block + +# Run snakemake +snakemake.main() diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index c818e010..e23997ad 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1,4 +1,5 @@ import importlib +import json import textwrap import typing from dataclasses import dataclass @@ -923,15 +924,15 @@ def get_fn_code( ) snakemake_cmd = [ - "snakemake", + "python", + "-m", + "latch_cli.snakemake.single_task_snakemake", "-s", snakefile_path_in_container, "--target-jobs", *encode_target_jobs_cli_args(self.job.get_target_spec()), "--allowed-rules", *self.job.rules, - "--allowed-rules", - *self.job.rules, "--local-groupid", str(self.job.jobid), "--cores", @@ -952,7 +953,14 @@ def get_fn_code( code_block += reindent( rf""" - subprocess.run({repr(snakemake_cmd)}, check=True) + subprocess.run( + {repr(snakemake_cmd)}, + check=True, + env={{ + "LATCH_SNAKEMAKE_RULES": "{json.dumps([job.rulename for job in self.job.get_target_spec()])}", + "LATCH_SNAKEMAKE_TARGET_OUTPUT": {repr(next(iter(self._target_file_for_output_param.values())))} + }} + ) """, 1, From 89d99d8462bf2f2d9b814a01cec5210c920c12c7 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 17 Jul 2023 13:44:20 -0700 Subject: [PATCH 070/356] fix docker tokens Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/services/register/utils.py | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index f77720f1..88ca2fe8 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -360,7 +360,7 @@ def generate_dockerfile( " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) f.write( - "run echo 13 && pip uninstall --yes latch && pip install" + "run echo 14 && pip uninstall --yes latch && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/services/register/utils.py b/latch_cli/services/register/utils.py index dc5c133f..ed1b21e9 100644 --- a/latch_cli/services/register/utils.py +++ b/latch_cli/services/register/utils.py @@ -4,6 +4,7 @@ import importlib.util as iu import io import os +import sys import typing from collections.abc import Iterable from pathlib import Path @@ -21,6 +22,7 @@ _CentromereCtx = "" +# todo(maximsmol): only login if the credentials are expired def _docker_login(ctx: _CentromereCtx): assert ctx.dkr_client is not None @@ -51,12 +53,16 @@ def _docker_login(ctx: _CentromereCtx): f"unable to retreive an ecr login token for user {ctx.account_id}" ) from err + auth = ctx.dkr_client._auth_configs + store_name = auth.get_credential_store(ctx.dkr_repo) + store = auth._get_store_instance(store_name) + store.erase(ctx.dkr_repo) + user, password = base64.b64decode(token).decode("utf-8").split(":") - ctx.dkr_client.login( - username=user, - password=password, - registry=ctx.dkr_repo, + res = ctx.dkr_client.login( + username=user, password=password, registry=ctx.dkr_repo, reauth=True ) + assert res["Status"] == "Login Succeeded" class DockerBuildLogItem(TypedDict): From aded071bb8ad1b23c129309f6f875fb1718531ac Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 17 Jul 2023 13:58:49 -0700 Subject: [PATCH 071/356] fixie Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 88ca2fe8..00315d60 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -360,7 +360,7 @@ def generate_dockerfile( " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) f.write( - "run echo 14 && pip uninstall --yes latch && pip install" + "run echo 18 && pip uninstall --yes latch && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index e23997ad..24e1ed92 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -957,7 +957,7 @@ def get_fn_code( {repr(snakemake_cmd)}, check=True, env={{ - "LATCH_SNAKEMAKE_RULES": "{json.dumps([job.rulename for job in self.job.get_target_spec()])}", + "LATCH_SNAKEMAKE_RULES": {repr(json.dumps([job.rulename for job in self.job.get_target_spec()]))}, "LATCH_SNAKEMAKE_TARGET_OUTPUT": {repr(next(iter(self._target_file_for_output_param.values())))} }} ) From 9a3a25eed01e9abe3c97c17e6be7c179beee9639 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 17 Jul 2023 14:05:48 -0700 Subject: [PATCH 072/356] use sys.executable Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/services/register/register.py | 14 +++++++------- latch_cli/snakemake/workflow.py | 11 +++++------ 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 00315d60..4ae44bb2 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -360,7 +360,7 @@ def generate_dockerfile( " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) f.write( - "run echo 18 && pip uninstall --yes latch && pip install" + "run echo 19 && pip uninstall --yes latch && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index 915f9d31..d8bad6cf 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -28,7 +28,7 @@ def _delete_lines(num: int): """Deletes the previous len(lines) lines, assuming cursor is on a new line just below the first line to be deleted""" for i in range(num): - print("\x1b[1F\x1b[0G\x1b[2K", end="") + click.echo("\x1b[1F\x1b[0G\x1b[2K", nl=False) def _print_window(cur_lines: List[str], line: str): @@ -42,10 +42,10 @@ def _print_window(cur_lines: List[str], line: str): new_lines.append(line) _delete_lines(len(cur_lines)) for s in new_lines: - print("\x1b[38;5;245m" + s + "\x1b[0m") + click.echo("\x1b[38;5;245m" + s + "\x1b[0m") return new_lines else: - print("\x1b[38;5;245m" + line + "\x1b[0m") + click.echo("\x1b[38;5;245m" + line + "\x1b[0m") cur_lines.append(line) return cur_lines @@ -113,7 +113,7 @@ def print_upload_logs(upload_image_logs, image): def _pp_prog_map(prog_map, prev_lines): if prev_lines > 0: - print("\x1b[2K\x1b[1E" * prev_lines + f"\x1b[{prev_lines}F", end="") + click.echo("\x1b[2K\x1b[1E" * prev_lines + f"\x1b[{prev_lines}F", nl=False) prog_chunk = "" i = 0 for id, prog in prog_map.items(): @@ -123,7 +123,7 @@ def _pp_prog_map(prog_map, prev_lines): i += 1 if prog_chunk == "": return 0 - print(prog_chunk, end=f"\x1b[{i}A") + click.echo(prog_chunk + f"\x1b[{i}A", nl=False) return i prev_lines = 0 @@ -181,9 +181,9 @@ def _print_reg_resp(resp, image): def print_serialize_logs(serialize_logs, image): - print(f"Serializing workflow in {image}:") + click.echo(f"Serializing workflow in {image}:") for x in serialize_logs: - print(x, end="") + click.echo(x, nl=False) def _build_and_serialize( diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 24e1ed92..5c0134af 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -923,8 +923,7 @@ def get_fn_code( 1, ) - snakemake_cmd = [ - "python", + snakemake_args = [ "-m", "latch_cli.snakemake.single_task_snakemake", "-s", @@ -939,22 +938,22 @@ def get_fn_code( str(self.job.threads), ] if not self.job.is_group(): - snakemake_cmd.append("--force-use-threads") + snakemake_args.append("--force-use-threads") excluded = {"_nodes", "_cores", "tmpdir"} allowed_resources = list( filter(lambda x: x[0] not in excluded, self.job.resources.items()) ) if len(allowed_resources) > 0: - snakemake_cmd.append("--resources") + snakemake_args.append("--resources") for resource, value in allowed_resources: - snakemake_cmd.append(f"{resource}={value}") + snakemake_args.append(f"{resource}={value}") code_block += reindent( rf""" subprocess.run( - {repr(snakemake_cmd)}, + [sys.executable,{','.join(repr(x) for x in snakemake_args)}], check=True, env={{ "LATCH_SNAKEMAKE_RULES": {repr(json.dumps([job.rulename for job in self.job.get_target_spec()]))}, From ed05f803c95c0a1caed7d69be57bcd527107e5e6 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 17 Jul 2023 14:13:11 -0700 Subject: [PATCH 073/356] do not remove standard env Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 4ae44bb2..3fd1f81d 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -360,7 +360,7 @@ def generate_dockerfile( " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) f.write( - "run echo 19 && pip uninstall --yes latch && pip install" + "run echo 21 && pip uninstall --yes latch && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 5c0134af..f163070f 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -956,6 +956,7 @@ def get_fn_code( [sys.executable,{','.join(repr(x) for x in snakemake_args)}], check=True, env={{ + **os.environ, "LATCH_SNAKEMAKE_RULES": {repr(json.dumps([job.rulename for job in self.job.get_target_spec()]))}, "LATCH_SNAKEMAKE_TARGET_OUTPUT": {repr(next(iter(self._target_file_for_output_param.values())))} }} From 39089f6ad4506204505790ce54c816f13c81b1ba Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 17 Jul 2023 14:17:51 -0700 Subject: [PATCH 074/356] fix compiled snakemake parser patch thing Signed-off-by: maximsmol --- latch_cli/snakemake/single_task_snakemake.py | 2 +- latch_cli/snakemake/workflow.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 88a8ec77..e588d379 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -27,7 +27,7 @@ def rule_start(self, aux=""): prefix = dedent(f""" @workflow.rule(name='latch_entrypoint', lineno=1, snakefile='workflow/Snakefile') @workflow.input( - {target_rule_output} + {repr(target_rule_output)} ) @workflow.norun() @workflow.run diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index f163070f..2b25c670 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -936,6 +936,7 @@ def get_fn_code( str(self.job.jobid), "--cores", str(self.job.threads), + "--print-compilation", ] if not self.job.is_group(): snakemake_args.append("--force-use-threads") From 7e1105d7ac851d87a828c49968e258fdf3c36ea4 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 17 Jul 2023 14:52:56 -0700 Subject: [PATCH 075/356] actually rn wf Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/single_task_snakemake.py | 2 ++ latch_cli/snakemake/workflow.py | 35 ++++++++++++++++---- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 3fd1f81d..1b393d5c 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -360,7 +360,7 @@ def generate_dockerfile( " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) f.write( - "run echo 21 && pip uninstall --yes latch && pip install" + "run echo 24 && pip uninstall --yes latch && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index e588d379..85edfc14 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -6,6 +6,7 @@ from snakemake.parser import ( Input, Output, + Params, Rule, StopAutomaton, is_comment, @@ -68,6 +69,7 @@ def skip_block(self, token, force_block_end=False): Input.block = skip_block Output.block = skip_block +Params.block = skip_block # Run snakemake snakemake.main() diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 2b25c670..bb939ca3 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -853,20 +853,31 @@ def {self.name}( return res def get_fn_return_stmt(self, remote_output_url: Optional[str] = None): + print_outs: list[str] = [] results: list[str] = [] for out_name in self._python_outputs: + target_path = self._target_file_for_output_param[out_name] + + print_outs.append( + reindent( + rf""" + print(f" {out_name}={{file_name_and_size(Path("{target_path}"))}}") + """, + 1, + ) + ) + if not self._is_target: results.append( reindent( rf""" - {out_name}=LatchFile("{self._target_file_for_output_param[out_name]}") + {out_name}=LatchFile("{target_path}") """, 1, ).rstrip() ) continue - target_path = self._target_file_for_output_param[out_name] if remote_output_url is None: remote_path = Path("/Snakemake Outputs") / target_path else: @@ -881,16 +892,24 @@ def get_fn_return_stmt(self, remote_output_url: Optional[str] = None): ).rstrip() ) + print_out_str = "\n".join(print_outs) return_str = ",\n".join(results) - return reindent( - rf""" + return ( + reindent( + rf""" + print("Uploading results:") + __print_out__ + return Res{self.name}( __return_str__ ) """, - 1, - ).replace("__return_str__", return_str) + 1, + ) + .replace("__print_out__", print_out_str) + .replace("__return_str__", return_str) + ) def get_fn_code( self, snakefile_path_in_container: str, remote_output_url: Optional[str] = None @@ -936,7 +955,7 @@ def get_fn_code( str(self.job.jobid), "--cores", str(self.job.threads), - "--print-compilation", + # "--print-compilation", ] if not self.job.is_group(): snakemake_args.append("--force-use-threads") @@ -953,6 +972,7 @@ def get_fn_code( code_block += reindent( rf""" + print("\n\n\nRunning snakemake task\n\n\n") subprocess.run( [sys.executable,{','.join(repr(x) for x in snakemake_args)}], check=True, @@ -962,6 +982,7 @@ def get_fn_code( "LATCH_SNAKEMAKE_TARGET_OUTPUT": {repr(next(iter(self._target_file_for_output_param.values())))} }} ) + print("\n\n\nDone\n\n\n") """, 1, From 77f4a62e96c677df0baefde3a843cca576cf9b02 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 17 Jul 2023 14:57:40 -0700 Subject: [PATCH 076/356] fix indent Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 1b393d5c..967c4fe3 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -360,7 +360,7 @@ def generate_dockerfile( " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) f.write( - "run echo 24 && pip uninstall --yes latch && pip install" + "run echo 25 && pip uninstall --yes latch && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index bb939ca3..d45e9990 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -863,7 +863,7 @@ def get_fn_return_stmt(self, remote_output_url: Optional[str] = None): rf""" print(f" {out_name}={{file_name_and_size(Path("{target_path}"))}}") """, - 1, + 0, ) ) From 61988ee0195501a14fd581def1205f1ed307d072 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 17 Jul 2023 15:03:17 -0700 Subject: [PATCH 077/356] fix quotes Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 967c4fe3..2c41ba7d 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -360,7 +360,7 @@ def generate_dockerfile( " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) f.write( - "run echo 25 && pip uninstall --yes latch && pip install" + "run echo 27 && pip uninstall --yes latch && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index d45e9990..16fdb032 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -861,7 +861,7 @@ def get_fn_return_stmt(self, remote_output_url: Optional[str] = None): print_outs.append( reindent( rf""" - print(f" {out_name}={{file_name_and_size(Path("{target_path}"))}}") + print(f' {out_name}={{file_name_and_size(Path("{target_path}"))}}') """, 0, ) From 89cf2325da5bf9548f423ffc1ddc7e6e9f2a5ff4 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 17 Jul 2023 15:56:11 -0700 Subject: [PATCH 078/356] fix output names Signed-off-by: maximsmol --- latch_cli/snakemake/serialize.py | 2 +- latch_cli/snakemake/workflow.py | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index 4e14cefa..b0491970 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -1,4 +1,5 @@ import os +import sys import textwrap from itertools import filterfalse from pathlib import Path @@ -273,7 +274,6 @@ def generate_snakemake_entrypoint( import subprocess from typing import NamedTuple import stat - from dataclasses import dataclass import sys from latch import small_task diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 16fdb032..b4ca4d72 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -665,7 +665,7 @@ def compile(self, **kwargs): upstream_nodes.append(node_map[x.jobid]) node = Node( - id=str(job.jobid), + id=f"n{job.jobid}", metadata=task.construct_node_metadata(), bindings=sorted(bindings, key=lambda b: b.var), upstream_nodes=upstream_nodes, @@ -704,8 +704,8 @@ def execute(self, **kwargs): def build_jit_register_wrapper() -> JITRegisterWorkflow: - out_parameter_name = "success" wrapper_wf = JITRegisterWorkflow() + out_parameter_name = wrapper_wf.out_parameter_name python_interface = wrapper_wf.python_interface wrapper_wf._input_parameters = interface_to_parameters(python_interface) @@ -717,7 +717,6 @@ def build_jit_register_wrapper() -> JITRegisterWorkflow: upstream_nodes=[], flyte_entity=None, ) - task_interface = Interface( python_interface.inputs, python_interface.outputs, docstring=None ) @@ -828,8 +827,7 @@ def get_fn_interface(self): res += reindent( rf""" - @dataclass - class Res{self.name}: + class Res{self.name}(NamedTuple): __output_fields__ """, From 46ae1b7011c312906f2cf002da217248a7498de2 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 17 Jul 2023 16:20:01 -0700 Subject: [PATCH 079/356] fix output value in JIT Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 2c41ba7d..f5f36e65 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -360,7 +360,7 @@ def generate_dockerfile( " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) f.write( - "run echo 27 && pip uninstall --yes latch && pip install" + "run echo 28 && pip uninstall --yes latch && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index b4ca4d72..c3fc817b 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -215,7 +215,7 @@ def interface_to_parameters( class JITRegisterWorkflow(WorkflowBase, ClassStorageTaskResolver): - out_parameter_name = "success" + out_parameter_name = "o0" # must be "o0" def __init__( self, From 8da5b8fa393b3a2097cd30e2596a655e52eb8fb2 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 17 Jul 2023 17:18:57 -0700 Subject: [PATCH 080/356] add debug compiled py upload Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 3 ++- latch_cli/snakemake/serialize.py | 1 + latch_cli/snakemake/workflow.py | 14 ++++++++++++++ setup.py | 2 +- 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index f5f36e65..797f6ac8 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -359,8 +359,9 @@ def generate_dockerfile( "run pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) + f.write("run pip uninstall --yes latch\n") f.write( - "run echo 28 && pip uninstall --yes latch && pip install" + "run echo 28 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index b0491970..f5960510 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -275,6 +275,7 @@ def generate_snakemake_entrypoint( from typing import NamedTuple import stat import sys + from flytekit.extras.persistence import LatchPersistence from latch import small_task from latch.types.file import LatchFile diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index c3fc817b..69b09e7b 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -969,6 +969,20 @@ def get_fn_code( code_block += reindent( rf""" + lp = LatchPersistence() + compiled = Path("compiled.py") + with compiled.open("w") as f: + subprocess.run( + [sys.executable,{','.join(repr(x) for x in [snakemake_args, "--print-compilation"])}], + check=True, + env={{ + **os.environ, + "LATCH_SNAKEMAKE_RULES": {repr(json.dumps([job.rulename for job in self.job.get_target_spec()]))}, + "LATCH_SNAKEMAKE_TARGET_OUTPUT": {repr(next(iter(self._target_file_for_output_param.values())))} + }}, + stdout=f + ) + lp.upload(compiled, "latch:///.snakemake_latch/{self.name}_compiled.py") print("\n\n\nRunning snakemake task\n\n\n") subprocess.run( diff --git a/setup.py b/setup.py index a0b6ea84..6e7c8620 100644 --- a/setup.py +++ b/setup.py @@ -36,7 +36,7 @@ "scp>=0.14.0", "boto3>=1.26.0", "tqdm>=4.63.0", - "lytekit==0.14.13", + "lytekit==0.14.15", "lytekitplugins-pods==0.4.0", "typing-extensions==4.5.0", "apscheduler==3.9.1", From abf0a23ed917c421479792a687b3feb1d1946db3 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 17 Jul 2023 17:26:13 -0700 Subject: [PATCH 081/356] fix oopsie Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 797f6ac8..35a5a1ef 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 28 && pip install" + "run echo 30 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 69b09e7b..97177585 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -973,7 +973,7 @@ def get_fn_code( compiled = Path("compiled.py") with compiled.open("w") as f: subprocess.run( - [sys.executable,{','.join(repr(x) for x in [snakemake_args, "--print-compilation"])}], + [sys.executable,{','.join(repr(x) for x in [*snakemake_args, "--print-compilation"])}], check=True, env={{ **os.environ, From 19d1a1e58a03637a47d00c419e5a198127de9b23 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 17 Jul 2023 17:30:19 -0700 Subject: [PATCH 082/356] debug more Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/serialize.py | 2 ++ latch_cli/snakemake/workflow.py | 23 +++++++++++++---------- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 35a5a1ef..8896c04a 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 30 && pip install" + "run echo 31 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index f5960510..336ec4e0 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -275,7 +275,9 @@ def generate_snakemake_entrypoint( from typing import NamedTuple import stat import sys + from flytekit.extras.persistence import LatchPersistence + import traceback from latch import small_task from latch.types.file import LatchFile diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 97177585..df8a7ab3 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -972,16 +972,19 @@ def get_fn_code( lp = LatchPersistence() compiled = Path("compiled.py") with compiled.open("w") as f: - subprocess.run( - [sys.executable,{','.join(repr(x) for x in [*snakemake_args, "--print-compilation"])}], - check=True, - env={{ - **os.environ, - "LATCH_SNAKEMAKE_RULES": {repr(json.dumps([job.rulename for job in self.job.get_target_spec()]))}, - "LATCH_SNAKEMAKE_TARGET_OUTPUT": {repr(next(iter(self._target_file_for_output_param.values())))} - }}, - stdout=f - ) + try: + subprocess.run( + [sys.executable,{','.join(repr(x) for x in [*snakemake_args, "--print-compilation"])}], + check=True, + env={{ + **os.environ, + "LATCH_SNAKEMAKE_RULES": {repr(json.dumps([job.rulename for job in self.job.get_target_spec()]))}, + "LATCH_SNAKEMAKE_TARGET_OUTPUT": {repr(next(iter(self._target_file_for_output_param.values())))} + }}, + stdout=f + ) + except Exception: + traceback.print_exc() lp.upload(compiled, "latch:///.snakemake_latch/{self.name}_compiled.py") print("\n\n\nRunning snakemake task\n\n\n") From 75b62b0874ece08f402aa451f0866cd54f0eaf46 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 17 Jul 2023 22:14:53 -0700 Subject: [PATCH 083/356] fix old snakemake compat Signed-off-by: maximsmol --- latch_cli/snakemake/single_task_snakemake.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 85edfc14..77a4700a 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -61,7 +61,12 @@ def skip_block(self, token, force_block_end=False): if is_comment(token): yield token.string, token else: - if self.lasttoken == "\n" and self.rulename not in target_rules: + if ( + self.lasttoken == "\n" + or + # old snakemake sometime does not put a newline after the decorate parenthesis + (self.line == 0 and self.lasttoken[-1] == "(") + ) and self.rulename not in target_rules: yield "#", token yield from self.block_content(token) From 9b12204d9b29e52ff8728d67c5dfabf78026972b Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 17 Jul 2023 23:16:01 -0700 Subject: [PATCH 084/356] replace i/o/params for all tasks Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/single_task_snakemake.py | 30 ++++++++++++++++---- latch_cli/snakemake/workflow.py | 24 +++++++++++++--- 3 files changed, 46 insertions(+), 10 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 8896c04a..698c862b 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 31 && pip install" + "run echo 32 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 77a4700a..0b15602e 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -15,8 +15,9 @@ is_newline, ) -target_rules = set(json.loads(os.environ["LATCH_SNAKEMAKE_RULES"])) -target_rule_output = os.environ["LATCH_SNAKEMAKE_TARGET_OUTPUT"] +data = json.loads(os.environ["LATCH_SNAKEMAKE_DATA"]) +rules = data["rules"] +outputs = data["outputs"] # Add a custom entrypoint rule _real_rule_start = Rule.start @@ -24,11 +25,12 @@ def rule_start(self, aux=""): prefix = "" - if self.rulename in target_rules: + if self.rulename in rules: + outputs_str = ",\n".join(f" {repr(x)}" for x in outputs) prefix = dedent(f""" @workflow.rule(name='latch_entrypoint', lineno=1, snakefile='workflow/Snakefile') @workflow.input( - {repr(target_rule_output)} + {outputs_str} ) @workflow.norun() @workflow.run @@ -66,7 +68,25 @@ def skip_block(self, token, force_block_end=False): or # old snakemake sometime does not put a newline after the decorate parenthesis (self.line == 0 and self.lasttoken[-1] == "(") - ) and self.rulename not in target_rules: + ): + if self.rulename in rules: + cur_data = rules[self.rulename] + if isinstance(self, Params): + xs = cur_data["params"] + + for k, v in xs.items(): + yield f"{k}={repr(v)}", token + + else: + xs = [] + if isinstance(self, Input): + xs = cur_data["inputs"] + if isinstance(self, Output): + xs = cur_data["outputs"] + + for x in xs: + yield repr(x), token + yield "#", token yield from self.block_content(token) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index df8a7ab3..654abc11 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -9,6 +9,7 @@ import snakemake import snakemake.io +import snakemake.jobs from flytekit.configuration import SerializationSettings from flytekit.core import constants as _common_constants from flytekit.core.class_based_resolver import ClassStorageTaskResolver @@ -34,6 +35,7 @@ from flytekit.models.core.types import BlobType from flytekit.models.literals import Blob, BlobMetadata, Literal, LiteralMap, Scalar from snakemake.dag import DAG +from snakemake.jobs import GroupJob from snakemake.target_jobs import encode_target_jobs_cli_args from typing_extensions import TypeAlias @@ -967,6 +969,22 @@ def get_fn_code( for resource, value in allowed_resources: snakemake_args.append(f"{resource}={value}") + jobs = [self.job] + if isinstance(self.job, GroupJob): + jobs = self.job.jobs + + snakemake_data = { + "rules": { + job.rule.name: { + "inputs": job.rule.inputs, + "outputs": job.rule.outputs, + "params": {k: v for k, v in job.rule.params.items()}, + } + for job in jobs + }, + "outputs": self.job.output, + } + code_block += reindent( rf""" lp = LatchPersistence() @@ -978,8 +996,7 @@ def get_fn_code( check=True, env={{ **os.environ, - "LATCH_SNAKEMAKE_RULES": {repr(json.dumps([job.rulename for job in self.job.get_target_spec()]))}, - "LATCH_SNAKEMAKE_TARGET_OUTPUT": {repr(next(iter(self._target_file_for_output_param.values())))} + "LATCH_SNAKEMAKE_DATA": {repr(json.dumps(snakemake_data))} }}, stdout=f ) @@ -993,8 +1010,7 @@ def get_fn_code( check=True, env={{ **os.environ, - "LATCH_SNAKEMAKE_RULES": {repr(json.dumps([job.rulename for job in self.job.get_target_spec()]))}, - "LATCH_SNAKEMAKE_TARGET_OUTPUT": {repr(next(iter(self._target_file_for_output_param.values())))} + "LATCH_SNAKEMAKE_DATA": {repr(json.dumps(snakemake_data))} }} ) print("\n\n\nDone\n\n\n") From b3e7ed140e102adef430a0b793da66cd7dd0881b Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 18 Jul 2023 10:21:02 -0700 Subject: [PATCH 085/356] fixup Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/single_task_snakemake.py | 72 +++++++++++++------- 2 files changed, 49 insertions(+), 25 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 698c862b..ce36f28a 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 32 && pip install" + "run echo 33 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 0b15602e..3c5c296c 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -1,9 +1,12 @@ import json import os +import sys +import traceback from textwrap import dedent import snakemake from snakemake.parser import ( + INDENT, Input, Output, Params, @@ -45,6 +48,31 @@ def __rule_latch_entrypoint(input, output, params, wildcards, threads, resources Rule.start = rule_start +def emit_overrides(self, token): + cur_data = rules[self.rulename] + + if isinstance(self, Input): + xs = (repr(x) for x in cur_data["inputs"]) + elif isinstance(self, Output): + xs = (repr(x) for x in cur_data["outputs"]) + elif isinstance(self, Params): + params = cur_data["params"] + xs = (f"{k}={repr(v)}" for k, v in params.items()) + else: + raise ValueError(f"tried to emit overrides for unknown state: {type(self)}") + + for x in xs: + yield x, token + yield ",", token + yield "\n", token + + # we'll need to re-indent the commented-out originals too + yield INDENT * self.base_indent, token + + +emitted_overrides_per_type: dict[str, set[str]] = {} + + # Skip @workflow.input and @workflow.output for non-target tasks def skip_block(self, token, force_block_end=False): if self.lasttoken == "\n" and is_comment(token): @@ -63,31 +91,27 @@ def skip_block(self, token, force_block_end=False): if is_comment(token): yield token.string, token else: - if ( - self.lasttoken == "\n" - or + try: + at_newline = self.lasttoken == "\n" + # old snakemake sometime does not put a newline after the decorate parenthesis - (self.line == 0 and self.lasttoken[-1] == "(") - ): - if self.rulename in rules: - cur_data = rules[self.rulename] - if isinstance(self, Params): - xs = cur_data["params"] - - for k, v in xs.items(): - yield f"{k}={repr(v)}", token - - else: - xs = [] - if isinstance(self, Input): - xs = cur_data["inputs"] - if isinstance(self, Output): - xs = cur_data["outputs"] - - for x in xs: - yield repr(x), token - - yield "#", token + at_start = self.line == 0 and self.lasttoken[-1] == "(" + + if at_newline or at_start: + emitted_overrides = emitted_overrides_per_type.setdefault( + type(self).__name__, set() + ) + + if ( + self.rulename in rules + and self.rulename not in emitted_overrides + ): + yield from emit_overrides(self, token) + emitted_overrides.add(self.rulename) + + yield "#", token + except: + traceback.print_exc() yield from self.block_content(token) From 624a1dea4c0d05b91ae8f07ed7260125c187bcd7 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 18 Jul 2023 10:30:45 -0700 Subject: [PATCH 086/356] fix oopsie Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index ce36f28a..72f8d795 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 33 && pip install" + "run echo 34 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 654abc11..0648ae5d 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -976,8 +976,8 @@ def get_fn_code( snakemake_data = { "rules": { job.rule.name: { - "inputs": job.rule.inputs, - "outputs": job.rule.outputs, + "inputs": job.rule.input, + "outputs": job.rule.output, "params": {k: v for k, v in job.rule.params.items()}, } for job in jobs From ec5c982b2fde6ad155dd9d95bd01d2c765b378c4 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 18 Jul 2023 10:53:00 -0700 Subject: [PATCH 087/356] upload logs, benchmarks Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 48 ++++++++++++++++++++---------- 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 72f8d795..f0279017 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 34 && pip install" + "run echo 35 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 0648ae5d..70d59aab 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -352,9 +352,6 @@ def get_fn_code( 1, ) - if remote_output_url is not None: - remote_output_url = f"'{remote_output_url}'" - code_block += reindent( rf""" pkg_root = Path(".") @@ -365,9 +362,9 @@ def get_fn_code( wf = extract_snakemake_workflow(pkg_root, snakefile, version) wf_name = wf.name - generate_snakemake_entrypoint(wf, pkg_root, snakefile, {remote_output_url}) + generate_snakemake_entrypoint(wf, pkg_root, snakefile, {repr(remote_output_url)}) - entrypoint_remote = f"latch:///.snakemake_latch/workflows/{{image_name}}-{{version}}/entrypoint.py" + entrypoint_remote = f"latch:///.snakemake_latch/workflows/{{image_name}}/entrypoint.py" lp.upload("latch_entrypoint.py", entrypoint_remote) print(f"latch_entrypoint.py -> {{entrypoint_remote}}") """, @@ -484,7 +481,7 @@ def get_fn_code( reg_resp = register_serialized_pkg(protos, None, version, account_id) _print_reg_resp(reg_resp, new_image_name) - wf_spec_remote = f"latch:///.snakemake_latch/workflows/{image_name}-{version}/spec.json" + wf_spec_remote = f"latch:///.snakemake_latch/workflows/{image_name}/spec.json" lp.upload("wf_spec.json", wf_spec_remote) print(f"wf_spec.json -> {wf_spec_remote}") @@ -985,6 +982,11 @@ def get_fn_code( "outputs": self.job.output, } + if remote_output_url is None: + remote_path = Path("/Snakemake Outputs") + else: + remote_path = Path(urlparse(remote_output_url).path) + code_block += reindent( rf""" lp = LatchPersistence() @@ -1005,15 +1007,31 @@ def get_fn_code( lp.upload(compiled, "latch:///.snakemake_latch/{self.name}_compiled.py") print("\n\n\nRunning snakemake task\n\n\n") - subprocess.run( - [sys.executable,{','.join(repr(x) for x in snakemake_args)}], - check=True, - env={{ - **os.environ, - "LATCH_SNAKEMAKE_DATA": {repr(json.dumps(snakemake_data))} - }} - ) - print("\n\n\nDone\n\n\n") + try: + subprocess.run( + [sys.executable,{','.join(repr(x) for x in snakemake_args)}], + check=True, + env={{ + **os.environ, + "LATCH_SNAKEMAKE_DATA": {repr(json.dumps(snakemake_data))} + }} + ) + print("\n\n\nDone\n\n\n") + except Exception as e: + print("\n\n\nFailed\n\n\n") + raise e + finally: + print("Uploading logs") + for x in {repr([x.file for x in self.job.log])}: + local = Path(x) + print(f" {{file_name_and_size(local)}}") + lp.upload(local, f"latch://{remote_path}/{{local}}") + + print("\nUploading benchmarks") + for x in {repr([x.file for x in self.job.benchmark])}: + local = Path(x) + print(f" {{file_name_and_size(local)}}") + lp.upload(local, f"latch://{remote_path}/{{local}}") """, 1, From c9b45dfb22998a975c12374a46a8927a0e75d4cc Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 18 Jul 2023 10:58:14 -0700 Subject: [PATCH 088/356] work with tasks with no benchmarks Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index f0279017..41226cf0 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 35 && pip install" + "run echo 36 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 70d59aab..035197e8 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -987,6 +987,13 @@ def get_fn_code( else: remote_path = Path(urlparse(remote_output_url).path) + log_files = [x.file for x in self.job.log] if self.job.log is not None else [] + benchmark_files = ( + [x.file for x in self.job.benchmark] + if self.job.benchmark is not None + else [] + ) + code_block += reindent( rf""" lp = LatchPersistence() @@ -1022,13 +1029,13 @@ def get_fn_code( raise e finally: print("Uploading logs") - for x in {repr([x.file for x in self.job.log])}: + for x in {repr(log_files)}: local = Path(x) print(f" {{file_name_and_size(local)}}") lp.upload(local, f"latch://{remote_path}/{{local}}") print("\nUploading benchmarks") - for x in {repr([x.file for x in self.job.benchmark])}: + for x in {repr(benchmark_files)}: local = Path(x) print(f" {{file_name_and_size(local)}}") lp.upload(local, f"latch://{remote_path}/{{local}}") From 890835deb02f2f3027431e08d6a457ffe0b77364 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 18 Jul 2023 11:00:19 -0700 Subject: [PATCH 089/356] fix Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 41226cf0..b8beba00 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 36 && pip install" + "run echo 37 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 035197e8..666d637f 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -989,9 +989,7 @@ def get_fn_code( log_files = [x.file for x in self.job.log] if self.job.log is not None else [] benchmark_files = ( - [x.file for x in self.job.benchmark] - if self.job.benchmark is not None - else [] + [x for x in self.job.benchmark] if self.job.benchmark is not None else [] ) code_block += reindent( From 3c8450f40f10c636c4ca4feabdd0fd966672df4a Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 18 Jul 2023 11:25:35 -0700 Subject: [PATCH 090/356] fix debug? Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/serialize.py | 9 ++++++--- latch_cli/snakemake/single_task_snakemake.py | 1 - latch_cli/snakemake/workflow.py | 20 +++++++++++--------- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index b8beba00..ea99a83b 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 37 && pip install" + "run echo 38 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index 336ec4e0..895dca4f 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -93,11 +93,14 @@ def extract_dag(self): [self.default_target] if self.default_target is not None else [] ) target_rules: Set[Rule] = set( - map(self._rules.__getitem__, filter(self.is_rule, targets)) + self._rules[x] for x in targets if self.is_rule(x) ) - target_files = set() - for f in filterfalse(self.is_rule, targets): + target_files: set[str] = set() + for f in targets: + if self.is_rule(f): + continue + if os.path.isabs(f) or f.startswith("root://"): target_files.add(f) else: diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 3c5c296c..20c48cd3 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -1,6 +1,5 @@ import json import os -import sys import traceback from textwrap import dedent diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 666d637f..270f750b 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -837,7 +837,7 @@ class Res{self.name}(NamedTuple): res += ( reindent( rf""" - @small_task + @small_task(cache=True) def {self.name}( __params__ ) -> __outputs__ @@ -987,10 +987,8 @@ def get_fn_code( else: remote_path = Path(urlparse(remote_output_url).path) - log_files = [x.file for x in self.job.log] if self.job.log is not None else [] - benchmark_files = ( - [x for x in self.job.benchmark] if self.job.benchmark is not None else [] - ) + log_files = [self.job.log] if self.job.log is not None else [] + benchmark_files = [self.job.benchmark] if self.job.benchmark is not None else [] code_block += reindent( rf""" @@ -1029,14 +1027,18 @@ def get_fn_code( print("Uploading logs") for x in {repr(log_files)}: local = Path(x) - print(f" {{file_name_and_size(local)}}") - lp.upload(local, f"latch://{remote_path}/{{local}}") + remote = f"latch://{remote_path}/{{local}}" + print(f" {{file_name_and_size(local)}} -> {{remote}}") + lp.upload(local, remote) + print(" Done") print("\nUploading benchmarks") for x in {repr(benchmark_files)}: local = Path(x) - print(f" {{file_name_and_size(local)}}") - lp.upload(local, f"latch://{remote_path}/{{local}}") + remote = f"latch://{remote_path}/{{local}}" + print(f" {{file_name_and_size(local)}} -> {{remote}}") + lp.upload(local, remote) + print(" Done") """, 1, From 6c60419358010bfafa644d4ab0e5072209e061db Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 18 Jul 2023 11:32:35 -0700 Subject: [PATCH 091/356] fix Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index ea99a83b..7c30a59a 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 38 && pip install" + "run echo 39 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 270f750b..b5b7c2ee 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -344,6 +344,7 @@ def get_fn_code( code_block += reindent( rf""" image_name = "{image_name}" + image_base_name = image_name.split(":")[0] account_id = "{account_id}" snakefile = Path("{snakefile_path}") @@ -364,7 +365,7 @@ def get_fn_code( wf_name = wf.name generate_snakemake_entrypoint(wf, pkg_root, snakefile, {repr(remote_output_url)}) - entrypoint_remote = f"latch:///.snakemake_latch/workflows/{{image_name}}/entrypoint.py" + entrypoint_remote = f"latch:///.snakemake_latch/workflows/{{image_base_name}}/entrypoint.py" lp.upload("latch_entrypoint.py", entrypoint_remote) print(f"latch_entrypoint.py -> {{entrypoint_remote}}") """, @@ -481,7 +482,7 @@ def get_fn_code( reg_resp = register_serialized_pkg(protos, None, version, account_id) _print_reg_resp(reg_resp, new_image_name) - wf_spec_remote = f"latch:///.snakemake_latch/workflows/{image_name}/spec.json" + wf_spec_remote = f"latch:///.snakemake_latch/workflows/{image_base_name}/spec.json" lp.upload("wf_spec.json", wf_spec_remote) print(f"wf_spec.json -> {wf_spec_remote}") @@ -987,8 +988,7 @@ def get_fn_code( else: remote_path = Path(urlparse(remote_output_url).path) - log_files = [self.job.log] if self.job.log is not None else [] - benchmark_files = [self.job.benchmark] if self.job.benchmark is not None else [] + log_files = self.job.log if self.job.log is not None else [] code_block += reindent( rf""" @@ -1032,9 +1032,11 @@ def get_fn_code( lp.upload(local, remote) print(" Done") - print("\nUploading benchmarks") - for x in {repr(benchmark_files)}: - local = Path(x) + benchmark_file = {repr(self.job.benchmark)} + if benchmark_file is not None: + print("\nUploading benchmark") + + local = Path(benchmark_file) remote = f"latch://{remote_path}/{{local}}" print(f" {{file_name_and_size(local)}} -> {{remote}}") lp.upload(local, remote) From b3793eca0472e22980ae07a2c17d21ebb2ccd26b Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 18 Jul 2023 11:40:04 -0700 Subject: [PATCH 092/356] fixie Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 7c30a59a..8fb77bae 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 39 && pip install" + "run echo 40 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index b5b7c2ee..7b46ab40 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1024,20 +1024,20 @@ def get_fn_code( print("\n\n\nFailed\n\n\n") raise e finally: - print("Uploading logs") + print("Uploading logs:") for x in {repr(log_files)}: local = Path(x) - remote = f"latch://{remote_path}/{{local}}" + remote = f"latch://{remote_path}/{{local.remove_prefix('/')}}" print(f" {{file_name_and_size(local)}} -> {{remote}}") lp.upload(local, remote) print(" Done") benchmark_file = {repr(self.job.benchmark)} if benchmark_file is not None: - print("\nUploading benchmark") + print("\nUploading benchmark:") local = Path(benchmark_file) - remote = f"latch://{remote_path}/{{local}}" + remote = f"latch://{remote_path}/{{local.remove_prefix('/')}}" print(f" {{file_name_and_size(local)}} -> {{remote}}") lp.upload(local, remote) print(" Done") From 33e45f64ef1b1ac8ba08ef767ca76b594b4df3a1 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 18 Jul 2023 11:44:50 -0700 Subject: [PATCH 093/356] fix oopsie Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 8fb77bae..0f0ef950 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 40 && pip install" + "run echo 41 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 7b46ab40..0ebe7b79 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1027,7 +1027,7 @@ def get_fn_code( print("Uploading logs:") for x in {repr(log_files)}: local = Path(x) - remote = f"latch://{remote_path}/{{local.remove_prefix('/')}}" + remote = f"latch://{remote_path}/{{str(local).remove_prefix('/')}}" print(f" {{file_name_and_size(local)}} -> {{remote}}") lp.upload(local, remote) print(" Done") @@ -1037,7 +1037,7 @@ def get_fn_code( print("\nUploading benchmark:") local = Path(benchmark_file) - remote = f"latch://{remote_path}/{{local.remove_prefix('/')}}" + remote = f"latch://{remote_path}/{{str(local).remove_prefix('/')}}" print(f" {{file_name_and_size(local)}} -> {{remote}}") lp.upload(local, remote) print(" Done") From e594db727a2909e2904ea19633f4949aae6fd193 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 18 Jul 2023 11:48:12 -0700 Subject: [PATCH 094/356] cmon Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 0f0ef950..5009197e 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 41 && pip install" + "run echo 42 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 0ebe7b79..224a1838 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1027,7 +1027,7 @@ def get_fn_code( print("Uploading logs:") for x in {repr(log_files)}: local = Path(x) - remote = f"latch://{remote_path}/{{str(local).remove_prefix('/')}}" + remote = f"latch://{remote_path}/{{str(local).removeprefix('/')}}" print(f" {{file_name_and_size(local)}} -> {{remote}}") lp.upload(local, remote) print(" Done") @@ -1037,7 +1037,7 @@ def get_fn_code( print("\nUploading benchmark:") local = Path(benchmark_file) - remote = f"latch://{remote_path}/{{str(local).remove_prefix('/')}}" + remote = f"latch://{remote_path}/{{str(local).removeprefix('/')}}" print(f" {{file_name_and_size(local)}} -> {{remote}}") lp.upload(local, remote) print(" Done") From 7d70abecc8e1f35dd7462d628a09929e086bf797 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 18 Jul 2023 13:29:27 -0700 Subject: [PATCH 095/356] support nameless params Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/single_task_snakemake.py | 44 +++++++++++++++++++- latch_cli/snakemake/workflow.py | 36 ++++++++++------ 3 files changed, 68 insertions(+), 14 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 5009197e..589aa871 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 42 && pip install" + "run echo 43 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 20c48cd3..b1b0ee82 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -1,6 +1,8 @@ import json import os +import sys import traceback +from itertools import chain from textwrap import dedent import snakemake @@ -17,10 +19,45 @@ is_newline, ) +sys.stdout.reconfigure(line_buffering=True) +sys.stderr.reconfigure(line_buffering=True) + + +def eprint(x: str) -> None: + print(x, file=sys.stderr) + + data = json.loads(os.environ["LATCH_SNAKEMAKE_DATA"]) rules = data["rules"] outputs = data["outputs"] +eprint("\n>>><<<\n") +eprint("Using LATCH_SNAKEMAKE_DATA:") +for rule in rules: + rule_data = rules[rule] + eprint(f" {rule}:") + + eprint(" Inputs:") + for x in rule_data["inputs"]: + eprint(f" {repr(x)}") + + eprint(" Outputs:") + for x in rule_data["outputs"]: + eprint(f" {repr(x)}") + + eprint(" Nameless Params:") + for k, v in rule_data["nameless_params"].items(): + eprint(f" {k}={repr(v)}") + + eprint(" Params:") + for k, v in rule_data["params"].items(): + eprint(f" {k}={repr(v)}") + +eprint("\nExpected outputs:") +for x in outputs: + eprint(repr(x)) +eprint("\n>>><<<\n") + # Add a custom entrypoint rule _real_rule_start = Rule.start @@ -55,8 +92,13 @@ def emit_overrides(self, token): elif isinstance(self, Output): xs = (repr(x) for x in cur_data["outputs"]) elif isinstance(self, Params): + nameless_params = cur_data["nameless_params"] + n_params_gen = (f"{repr(x)}" for x in nameless_params) + params = cur_data["params"] - xs = (f"{k}={repr(v)}" for k, v in params.items()) + params_gen = (f"{k}={repr(v)}" for k, v in params.items()) + + xs = chain(n_params_gen, params_gen) else: raise ValueError(f"tried to emit overrides for unknown state: {type(self)}") diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 224a1838..5538762b 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -972,17 +972,26 @@ def get_fn_code( jobs = self.job.jobs snakemake_data = { - "rules": { - job.rule.name: { - "inputs": job.rule.input, - "outputs": job.rule.output, - "params": {k: v for k, v in job.rule.params.items()}, - } - for job in jobs - }, + "rules": {}, "outputs": self.job.output, } + for job in jobs: + params: dict[str, str] = dict(job.rule.params.items()) + named_params: set[str] = set(params.values()) + + # not all params in snakemake have associated keys + nameless_params: list[str] = [ + x for x in job.rule.params if x not in named_params + ] + + snakemake_data[job.rule.name] = { + "inputs": job.rule.input, + "outputs": job.rule.output, + "nameless_params": nameless_params, + "params": params, + } + if remote_output_url is None: remote_path = Path("/Snakemake Outputs") else: @@ -1037,10 +1046,13 @@ def get_fn_code( print("\nUploading benchmark:") local = Path(benchmark_file) - remote = f"latch://{remote_path}/{{str(local).removeprefix('/')}}" - print(f" {{file_name_and_size(local)}} -> {{remote}}") - lp.upload(local, remote) - print(" Done") + if local.exists(): + remote = f"latch://{remote_path}/{{str(local).removeprefix('/')}}" + print(f" {{file_name_and_size(local)}} -> {{remote}}") + lp.upload(local, remote) + print(" Done") + else: + print(" Does not exist") """, 1, From 4b966451581b6286de6ca00d43a83cafc7068d9f Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 18 Jul 2023 13:49:36 -0700 Subject: [PATCH 096/356] fix Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 589aa871..2bad2153 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 43 && pip install" + "run echo 44 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 5538762b..45d23e0a 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -985,7 +985,7 @@ def get_fn_code( x for x in job.rule.params if x not in named_params ] - snakemake_data[job.rule.name] = { + snakemake_data["rules"][job.rule.name] = { "inputs": job.rule.input, "outputs": job.rule.output, "nameless_params": nameless_params, From 81f4abbe0981d5b32146fa6a24f6a3167547c916 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 18 Jul 2023 13:58:48 -0700 Subject: [PATCH 097/356] fix typo Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/single_task_snakemake.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 2bad2153..2afd1990 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 44 && pip install" + "run echo 45 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index b1b0ee82..79b79a3c 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -46,8 +46,8 @@ def eprint(x: str) -> None: eprint(f" {repr(x)}") eprint(" Nameless Params:") - for k, v in rule_data["nameless_params"].items(): - eprint(f" {k}={repr(v)}") + for x in rule_data["nameless_params"]: + eprint(f" {repr(x)}") eprint(" Params:") for k, v in rule_data["params"].items(): From 0be0a80399f81f061e6c6d8b02569b0c399c4cac Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 18 Jul 2023 14:25:48 -0700 Subject: [PATCH 098/356] support keyword inputs Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/single_task_snakemake.py | 41 ++++++++++---------- latch_cli/snakemake/workflow.py | 22 +++++------ 3 files changed, 33 insertions(+), 32 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 2afd1990..f82142c4 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 45 && pip install" + "run echo 46 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 79b79a3c..9ef0502b 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -31,6 +31,16 @@ def eprint(x: str) -> None: rules = data["rules"] outputs = data["outputs"] + +def eprint_named_list(xs): + eprint(" Positional:") + for x in xs["positional"]: + eprint(f" {repr(x)}") + eprint(" Keyword:") + for k, v in xs["keyword"].items(): + eprint(f" {k}={repr(v)}") + + eprint("\n>>><<<\n") eprint("Using LATCH_SNAKEMAKE_DATA:") for rule in rules: @@ -38,20 +48,13 @@ def eprint(x: str) -> None: eprint(f" {rule}:") eprint(" Inputs:") - for x in rule_data["inputs"]: - eprint(f" {repr(x)}") + eprint_named_list(rule_data["inputs"]) eprint(" Outputs:") - for x in rule_data["outputs"]: - eprint(f" {repr(x)}") - - eprint(" Nameless Params:") - for x in rule_data["nameless_params"]: - eprint(f" {repr(x)}") + eprint_named_list(rule_data["outputs"]) eprint(" Params:") - for k, v in rule_data["params"].items(): - eprint(f" {k}={repr(v)}") + eprint_named_list(rule_data["params"]) eprint("\nExpected outputs:") for x in outputs: @@ -88,21 +91,19 @@ def emit_overrides(self, token): cur_data = rules[self.rulename] if isinstance(self, Input): - xs = (repr(x) for x in cur_data["inputs"]) + xs = cur_data["inputs"] elif isinstance(self, Output): - xs = (repr(x) for x in cur_data["outputs"]) + xs = cur_data["outputs"] elif isinstance(self, Params): - nameless_params = cur_data["nameless_params"] - n_params_gen = (f"{repr(x)}" for x in nameless_params) - - params = cur_data["params"] - params_gen = (f"{k}={repr(v)}" for k, v in params.items()) - - xs = chain(n_params_gen, params_gen) + xs = cur_data["params"] else: raise ValueError(f"tried to emit overrides for unknown state: {type(self)}") - for x in xs: + positional_data = (repr(x) for x in xs["positional"]) + keyword_data = (f"{k}={repr(v)}" for k, v in xs["keyword"].items()) + data = chain(positional_data, keyword_data) + + for x in data: yield x, token yield ",", token yield "\n", token diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 45d23e0a..49a8b31d 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -769,6 +769,13 @@ def build_jit_register_wrapper() -> JITRegisterWorkflow: return wrapper_wf +def handle_named_list(xs: snakemake.io.Namedlist): + named: dict[str, str] = dict(xs.items()) + named_values = set(named.values()) + unnamed = [x for x in xs if x not in named_values] + return {"positional": named, "keyword": unnamed} + + class SnakemakeJobTask(PythonAutoContainerTask[T]): def __init__( self, @@ -977,19 +984,12 @@ def get_fn_code( } for job in jobs: - params: dict[str, str] = dict(job.rule.params.items()) - named_params: set[str] = set(params.values()) - - # not all params in snakemake have associated keys - nameless_params: list[str] = [ - x for x in job.rule.params if x not in named_params - ] + rule = job.rule snakemake_data["rules"][job.rule.name] = { - "inputs": job.rule.input, - "outputs": job.rule.output, - "nameless_params": nameless_params, - "params": params, + "inputs": handle_named_list(job.rule.input), + "outputs": handle_named_list(job.rule.output), + "params": handle_named_list(job.rule.params), } if remote_output_url is None: From 952600d2500d8669b7bd059933891240450ebb21 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 18 Jul 2023 14:34:43 -0700 Subject: [PATCH 099/356] fix Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index f82142c4..3091eb7e 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 46 && pip install" + "run echo 47 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 49a8b31d..68b8ba77 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -773,7 +773,7 @@ def handle_named_list(xs: snakemake.io.Namedlist): named: dict[str, str] = dict(xs.items()) named_values = set(named.values()) unnamed = [x for x in xs if x not in named_values] - return {"positional": named, "keyword": unnamed} + return {"positional": unnamed, "keyword": named} class SnakemakeJobTask(PythonAutoContainerTask[T]): From aa77d1de347ff57cd9ade3dc2946ebe6937bde39 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 18 Jul 2023 15:38:30 -0700 Subject: [PATCH 100/356] fix multioutput tasks Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 3091eb7e..d4c7f12b 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 47 && pip install" + "run echo 48 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 68b8ba77..c7cf6c89 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -868,7 +868,7 @@ def get_fn_return_stmt(self, remote_output_url: Optional[str] = None): rf""" print(f' {out_name}={{file_name_and_size(Path("{target_path}"))}}') """, - 0, + 1, ) ) @@ -878,7 +878,7 @@ def get_fn_return_stmt(self, remote_output_url: Optional[str] = None): rf""" {out_name}=LatchFile("{target_path}") """, - 1, + 2, ).rstrip() ) continue @@ -893,7 +893,7 @@ def get_fn_return_stmt(self, remote_output_url: Optional[str] = None): rf""" {out_name}=LatchFile("{target_path}", "latch://{remote_path}") """, - 1, + 2, ).rstrip() ) @@ -903,14 +903,14 @@ def get_fn_return_stmt(self, remote_output_url: Optional[str] = None): return ( reindent( rf""" - print("Uploading results:") - __print_out__ + print("Uploading results:") + __print_out__ - return Res{self.name}( - __return_str__ - ) + return Res{self.name}( + __return_str__ + ) """, - 1, + 0, ) .replace("__print_out__", print_out_str) .replace("__return_str__", return_str) From 3b5e49073bc043fe5d7b1d0b4f68199177d44ccc Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 18 Jul 2023 15:42:54 -0700 Subject: [PATCH 101/356] fix multiple target files Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/single_task_snakemake.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index d4c7f12b..eab9b39e 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 48 && pip install" + "run echo 49 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 9ef0502b..bad7a4cf 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -72,14 +72,14 @@ def rule_start(self, aux=""): prefix = dedent(f""" @workflow.rule(name='latch_entrypoint', lineno=1, snakefile='workflow/Snakefile') @workflow.input( - {outputs_str} + __outputs__ ) @workflow.norun() @workflow.run def __rule_latch_entrypoint(input, output, params, wildcards, threads, resources, log, version, rule, conda_env, container_img, singularity_args, use_singularity, env_modules, bench_record, jobid, is_shell, bench_iteration, cleanup_scripts, shadow_dir, edit_notebook, conda_base_path, basedir, runtime_sourcecache_path, __is_snakemake_rule_func=True): pass - """) + """).replace("__outputs__", outputs_str) yield prefix + next(_real_rule_start(self, aux)) From cb98d0d134d5743305d8e1c3fb08757167e651bc Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 18 Jul 2023 16:09:08 -0700 Subject: [PATCH 102/356] add support for directory() Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/single_task_snakemake.py | 24 +++++++++++++-- latch_cli/snakemake/workflow.py | 31 ++++++++++++++------ 3 files changed, 45 insertions(+), 12 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index eab9b39e..851a8614 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 49 && pip install" + "run echo 50 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index bad7a4cf..3c7409ab 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -4,8 +4,10 @@ import traceback from itertools import chain from textwrap import dedent +from typing import Union import snakemake +from snakemake.io import AnnotatedString from snakemake.parser import ( INDENT, Input, @@ -87,6 +89,24 @@ def __rule_latch_entrypoint(input, output, params, wildcards, threads, resources Rule.start = rule_start +def render_annotated_str(x) -> str: + if not isinstance(x, dict): + return x + + value = x["value"] + flags = dict(x["flags"]) + + res = repr(value) + if flags.get("directory", False): + res = f"directory({res})" + del flags["directory"] + + if len(flags) != 0: + raise RuntimeError(f"found unsupported flags: {repr(flags)}") + + return res + + def emit_overrides(self, token): cur_data = rules[self.rulename] @@ -99,8 +119,8 @@ def emit_overrides(self, token): else: raise ValueError(f"tried to emit overrides for unknown state: {type(self)}") - positional_data = (repr(x) for x in xs["positional"]) - keyword_data = (f"{k}={repr(v)}" for k, v in xs["keyword"].items()) + positional_data = (render_annotated_str(x) for x in xs["positional"]) + keyword_data = (f"{k}={render_annotated_str(v)}" for k, v in xs["keyword"].items()) data = chain(positional_data, keyword_data) for x in data: diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index c7cf6c89..b50a2502 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -592,13 +592,19 @@ def compile(self, **kwargs): target_file_for_output_param: Dict[str, str] = {} target_file_for_input_param: Dict[str, str] = {} - python_outputs: Dict[str, LatchFile] = {} + python_outputs: Dict[str, Union[LatchFile, LatchDir]] = {} for x in job.output: + assert isinstance(x, SnakemakeInputVal) + if x in target_files: is_target = True param = variable_name_for_value(x, job.output) target_file_for_output_param[param] = x - python_outputs[param] = LatchFile + + if x.is_directory: + python_outputs[param] = LatchDir + else: + python_outputs[param] = LatchFile dep_outputs = {} for dep, dep_files in self._dag.dependencies[job].items(): @@ -769,10 +775,17 @@ def build_jit_register_wrapper() -> JITRegisterWorkflow: return wrapper_wf -def handle_named_list(xs: snakemake.io.Namedlist): - named: dict[str, str] = dict(xs.items()) +def annotated_str_to_json(x: Union[str, snakemake.io.AnnotatedString]): + if not isinstance(x, snakemake.io.AnnotatedString): + return x + + return {"value": str(x), "flags": dict(x.flags.items())} + + +def named_list_to_json(xs: snakemake.io.Namedlist): + named: dict[str, object] = {k: annotated_str_to_json(v) for k, v in xs.items()} named_values = set(named.values()) - unnamed = [x for x in xs if x not in named_values] + unnamed = [annotated_str_to_json(x) for x in xs if x not in named_values] return {"positional": unnamed, "keyword": named} @@ -781,7 +794,7 @@ def __init__( self, job: snakemake.jobs.Job, inputs: Dict[str, LatchFile], - outputs: Dict[str, LatchFile], + outputs: Dict[str, Union[LatchFile, LatchDir]], target_file_for_input_param: Dict[str, str], target_file_for_output_param: Dict[str, str], is_target: bool, @@ -987,9 +1000,9 @@ def get_fn_code( rule = job.rule snakemake_data["rules"][job.rule.name] = { - "inputs": handle_named_list(job.rule.input), - "outputs": handle_named_list(job.rule.output), - "params": handle_named_list(job.rule.params), + "inputs": named_list_to_json(job.rule.input), + "outputs": named_list_to_json(job.rule.output), + "params": named_list_to_json(job.rule.params), } if remote_output_url is None: From 80e6e23f3a02a51be7e52a5c725a318779bd24bf Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 18 Jul 2023 16:22:33 -0700 Subject: [PATCH 103/356] allow using directories between tasks Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 26 +++++++++++++++++++------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 851a8614..24573c87 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 50 && pip install" + "run echo 51 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index b50a2502..d3f0724d 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -62,6 +62,7 @@ def reindent(x: str, level: int) -> str: class JobOutputInfo: jobid: str output_param_name: str + type_: Union[LatchFile, LatchDir] def task_fn_placeholder(): @@ -578,12 +579,13 @@ def compile(self, **kwargs): flyte_entity=None, ) - node_map: Dict[int, Node] = {} + node_map: Dict[str, Node] = {} target_files = [x for job in self._dag.targetjobs for x in job.input] for layer in self._dag.toposorted(): for job in layer: + assert isinstance(job, snakemake.jobs.Job) is_target = False if job in self._dag.targetjobs: @@ -606,25 +608,33 @@ def compile(self, **kwargs): else: python_outputs[param] = LatchFile - dep_outputs = {} + dep_outputs: dict[SnakemakeInputVal, JobOutputInfo] = {} for dep, dep_files in self._dag.dependencies[job].items(): for o in dep.output: if o in dep_files: + assert isinstance(o, SnakemakeInputVal) + dep_outputs[o] = JobOutputInfo( jobid=dep.jobid, output_param_name=variable_name_for_value( o, dep.output ), + type_=LatchDir if o.is_directory else LatchFile, ) - python_inputs: Dict[str, LatchFile] = {} - promise_map: Dict[str, str] = {} + python_inputs: Dict[str, Union[LatchFile, LatchDir]] = {} + promise_map: Dict[str, JobOutputInfo] = {} for x in job.input: param = variable_name_for_value(x, job.input) target_file_for_input_param[param] = x + + dep_out = dep_outputs.get(x) + python_inputs[param] = LatchFile - if x in dep_outputs: - promise_map[param] = dep_outputs[x] + + if dep_out is not None: + python_inputs[param] = dep_out.type_ + promise_map[param] = dep_out interface = Interface(python_inputs, python_outputs, docstring=None) task = SnakemakeJobTask( @@ -639,6 +649,8 @@ def compile(self, **kwargs): self.snakemake_tasks.append(task) typed_interface = transform_interface_to_typed_interface(interface) + assert typed_interface is not None + bindings: List[literals_models.Binding] = [] for k in interface.inputs: var = typed_interface.inputs[k] @@ -793,7 +805,7 @@ class SnakemakeJobTask(PythonAutoContainerTask[T]): def __init__( self, job: snakemake.jobs.Job, - inputs: Dict[str, LatchFile], + inputs: Dict[str, Union[LatchFile, LatchDir]], outputs: Dict[str, Union[LatchFile, LatchDir]], target_file_for_input_param: Dict[str, str], target_file_for_output_param: Dict[str, str], From e18abc6ddaae8ba6c6a20adb7d5ba7f9bb2bb2a0 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 18 Jul 2023 16:42:58 -0700 Subject: [PATCH 104/356] support dirs in workflow output Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 26 +++++++++++++++++--------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 24573c87..b900af9c 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 51 && pip install" + "run echo 52 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index d3f0724d..62779bf7 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -99,9 +99,17 @@ def snakemake_dag_to_interface( ) -> (Interface, LiteralMap, List[RemoteFile]): outputs: Dict[str, LatchFile] = {} for target in dag.targetjobs: - for x in target.input: - param = variable_name_for_value(x, target.input) - outputs[param] = LatchFile + for desired in target.input: + param = variable_name_for_value(desired, target.input) + + jobs: list[snakemake.jobs.Job] = dag.file2jobs(desired) + producer_out: snakemake.io._IOFile = next( + x for x in jobs[0].output if x == x + ) + if producer_out.is_directory: + outputs[param] = LatchDir + else: + outputs[param] = LatchFile literals: Dict[str, Literal] = {} inputs: Dict[str, Tuple[LatchFile, None]] = {} @@ -133,7 +141,7 @@ def snakemake_dag_to_interface( ) ), uri=remote_url, - ) + ), ) ) @@ -805,8 +813,8 @@ class SnakemakeJobTask(PythonAutoContainerTask[T]): def __init__( self, job: snakemake.jobs.Job, - inputs: Dict[str, Union[LatchFile, LatchDir]], - outputs: Dict[str, Union[LatchFile, LatchDir]], + inputs: Dict[str, Union[Type[LatchFile], Type[LatchDir]]], + outputs: Dict[str, Union[Type[LatchFile], Type[LatchDir]]], target_file_for_input_param: Dict[str, str], target_file_for_output_param: Dict[str, str], is_target: bool, @@ -885,7 +893,7 @@ def {self.name}( def get_fn_return_stmt(self, remote_output_url: Optional[str] = None): print_outs: list[str] = [] results: list[str] = [] - for out_name in self._python_outputs: + for out_name, out_type in self._python_outputs.items(): target_path = self._target_file_for_output_param[out_name] print_outs.append( @@ -901,7 +909,7 @@ def get_fn_return_stmt(self, remote_output_url: Optional[str] = None): results.append( reindent( rf""" - {out_name}=LatchFile("{target_path}") + {out_name}={out_type.__name__}("{target_path}") """, 2, ).rstrip() @@ -916,7 +924,7 @@ def get_fn_return_stmt(self, remote_output_url: Optional[str] = None): results.append( reindent( rf""" - {out_name}=LatchFile("{target_path}", "latch://{remote_path}") + {out_name}={out_type.__name__}("{target_path}", "latch://{remote_path}") """, 2, ).rstrip() From 74a356c217aa7264942b3fdad3ec518a51d89769 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 18 Jul 2023 16:53:19 -0700 Subject: [PATCH 105/356] fix missing import Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/serialize.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index b900af9c..d9d4705d 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 52 && pip install" + "run echo 53 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index 895dca4f..f8d3fe47 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -283,6 +283,7 @@ def generate_snakemake_entrypoint( import traceback from latch import small_task + from latch.types.directory import LatchDir from latch.types.file import LatchFile sys.stdout.reconfigure(line_buffering=True) From 10d313144e149bde663a858906732cb4f7f37d51 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 18 Jul 2023 16:59:00 -0700 Subject: [PATCH 106/356] fix Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/single_task_snakemake.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index d9d4705d..aa92c33f 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 53 && pip install" + "run echo 54 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 3c7409ab..5109abda 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -91,7 +91,7 @@ def __rule_latch_entrypoint(input, output, params, wildcards, threads, resources def render_annotated_str(x) -> str: if not isinstance(x, dict): - return x + return repr(x) value = x["value"] flags = dict(x["flags"]) From e7113c35296996f2c022ea0ebaa994b15d340e2f Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 18 Jul 2023 17:03:24 -0700 Subject: [PATCH 107/356] deal with iofile Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index aa92c33f..b4c1d37b 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 54 && pip install" + "run echo 55 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 62779bf7..c03c8be5 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -795,8 +795,10 @@ def build_jit_register_wrapper() -> JITRegisterWorkflow: return wrapper_wf -def annotated_str_to_json(x: Union[str, snakemake.io.AnnotatedString]): - if not isinstance(x, snakemake.io.AnnotatedString): +def annotated_str_to_json( + x: Union[str, snakemake.io._IOFile, snakemake.io.AnnotatedString] +): + if not isinstance(x, (snakemake.io.AnnotatedString, snakemake.io._IOFile)): return x return {"value": str(x), "flags": dict(x.flags.items())} From 28cc1efd0349b73fa2462ba928d58bfc4148b3a0 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 18 Jul 2023 17:08:35 -0700 Subject: [PATCH 108/356] unhashable type Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 23 ++++++++++++++++++----- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index b4c1d37b..22341613 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 55 && pip install" + "run echo 56 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index c03c8be5..3b7fc34e 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -37,7 +37,7 @@ from snakemake.dag import DAG from snakemake.jobs import GroupJob from snakemake.target_jobs import encode_target_jobs_cli_args -from typing_extensions import TypeAlias +from typing_extensions import TypeAlias, TypedDict import latch.types.metadata as metadata from latch.types.directory import LatchDir @@ -795,18 +795,31 @@ def build_jit_register_wrapper() -> JITRegisterWorkflow: return wrapper_wf +class AnnotatedStrJson(TypedDict): + value: str + flags: dict[str, bool] + + def annotated_str_to_json( x: Union[str, snakemake.io._IOFile, snakemake.io.AnnotatedString] -): +) -> Union[str, AnnotatedStrJson]: if not isinstance(x, (snakemake.io.AnnotatedString, snakemake.io._IOFile)): return x return {"value": str(x), "flags": dict(x.flags.items())} -def named_list_to_json(xs: snakemake.io.Namedlist): - named: dict[str, object] = {k: annotated_str_to_json(v) for k, v in xs.items()} - named_values = set(named.values()) +class NamedListJson(TypedDict): + positional: list[Union[str, AnnotatedStrJson]] + keyword: dict[str, Union[str, AnnotatedStrJson]] + + +def named_list_to_json(xs: snakemake.io.Namedlist) -> NamedListJson: + named: dict[str, Union[str, AnnotatedStrJson]] = { + k: annotated_str_to_json(v) for k, v in xs.items() + } + named_values = set(x if isinstance(x, str) else x["value"] for x in named.values()) + unnamed = [annotated_str_to_json(x) for x in xs if x not in named_values] return {"positional": unnamed, "keyword": named} From 5e69260144a006e31fb76fd5ec3e6698d310a51a Mon Sep 17 00:00:00 2001 From: maximsmol Date: Thu, 20 Jul 2023 11:33:33 -0700 Subject: [PATCH 109/356] add latch_metadata.py suggestion Signed-off-by: maximsmol --- latch_cli/centromere/ctx.py | 35 +++++++++++++++++++-- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/serialize.py | 49 ++++++++++++++++-------------- 3 files changed, 60 insertions(+), 26 deletions(-) diff --git a/latch_cli/centromere/ctx.py b/latch_cli/centromere/ctx.py index 26e51311..9c5ebd2b 100644 --- a/latch_cli/centromere/ctx.py +++ b/latch_cli/centromere/ctx.py @@ -1,5 +1,7 @@ import re +import sys import time +import traceback from dataclasses import dataclass from pathlib import Path from typing import Dict, Optional, Tuple @@ -124,14 +126,43 @@ def __init__( import latch.types.metadata as metadata - from ..snakemake.serialize import snakemake_workflow_extractor + from ..snakemake.serialize import ( + snakemake_metadata_example, + snakemake_workflow_extractor, + ) meta = pkg_root / "latch_metadata.py" if meta.exists(): click.echo(f"Using metadata file {click.style(meta, italic=True)}") import_module_by_path(meta) else: - snakemake_workflow_extractor(pkg_root, snakefile) + click.echo("Trying to extract metadata from the Snakefile") + try: + snakemake_workflow_extractor(pkg_root, snakefile) + except (ImportError, FileNotFoundError): + traceback.print_exc() + click.secho( + "\n\n\n" + + "The above error occured when reading " + + "the Snakefile to extract workflow metadata.", + bold=True, + fg="red", + ) + click.secho( + "\nIt is possible to avoid including the Snakefile prior to" + " registration by providing a `latch_metadata.py` file in" + " the workflow root.\nThis way it is not necessary to" + " install dependencies or ensure that Snakemake inputs" + " locally.", + fg="red", + ) + click.secho("\nExample ", fg="red", nl=False) + click.secho(f"`{meta}`", bold=True, fg="red", nl=False) + click.secho( + f" file:{snakemake_metadata_example}", + fg="red", + ) + sys.exit(1) assert metadata._snakemake_metadata is not None assert metadata._snakemake_metadata.name is not None diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 22341613..4f4ff8ee 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 56 && pip install" + "run echo 57 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index f8d3fe47..edd27e59 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -1,7 +1,5 @@ import os -import sys import textwrap -from itertools import filterfalse from pathlib import Path from textwrap import dedent from typing import List, Optional, Set, Union, get_args @@ -40,6 +38,30 @@ def should_register_with_admin(entity: RegistrableEntity) -> bool: return isinstance(entity, get_args(RegistrableEntity)) +snakemake_metadata_example = """ +``` +from pathlib import Path +from latch.types.metadata import SnakemakeMetadata, SnakemakeFileParameter +from latch.types.file import LatchFile +from latch.types.metadata import LatchAuthor, LatchMetadata + +SnakemakeMetadata( + display_name="My Snakemake Workflow", + author=LatchAuthor( + name="John Doe", + ), + parameters={ + "foo" : SnakemakeFileParameter( + display_name="Some Param", + type=LatchFile, + path=Path("foo.txt"), + ) + } +) +``` +""" + + def ensure_snakemake_metadata_exists(): import latch.types.metadata as metadata @@ -52,29 +74,10 @@ def ensure_snakemake_metadata_exists(): You can paste the following in the top of your Snakefile to get started: - ``` - from pathlib import Path - from latch.types.metadata import SnakemakeMetadata, SnakemakeFileParameter - from latch.types.file import LatchFile - from latch.types.metadata import LatchAuthor, LatchMetadata - - SnakemakeMetadata( - display_name="My Snakemake Workflow", - author=LatchAuthor( - name="John Doe", - ), - parameters={ - "foo" : SnakemakeFileParameter( - display_name="Some Param", - type=LatchFile, - path=Path("foo.txt"), - ) - } - ) - ``` + __example__ Find more information at docs.latch.bio. - """), + """).replace("__example__", snakemake_metadata_example), bold=True, fg="red", ) From a1e201579b88a3d3f761674ba04a6bb41f7fafe5 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Thu, 20 Jul 2023 12:59:31 -0700 Subject: [PATCH 110/356] support named i/o with expand Signed-off-by: maximsmol --- latch_cli/snakemake/single_task_snakemake.py | 1 + latch_cli/snakemake/workflow.py | 40 ++++++++++++++++---- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 5109abda..9ca5a66b 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -38,6 +38,7 @@ def eprint_named_list(xs): eprint(" Positional:") for x in xs["positional"]: eprint(f" {repr(x)}") + eprint(" Keyword:") for k, v in xs["keyword"].items(): eprint(f" {k}={repr(v)}") diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 3b7fc34e..8a098f26 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -800,27 +800,51 @@ class AnnotatedStrJson(TypedDict): flags: dict[str, bool] +MaybeAnnotatedStrJson: TypeAlias = Union[str, AnnotatedStrJson] + + def annotated_str_to_json( x: Union[str, snakemake.io._IOFile, snakemake.io.AnnotatedString] -) -> Union[str, AnnotatedStrJson]: +) -> MaybeAnnotatedStrJson: if not isinstance(x, (snakemake.io.AnnotatedString, snakemake.io._IOFile)): return x return {"value": str(x), "flags": dict(x.flags.items())} +IONamedListItem = Union[MaybeAnnotatedStrJson, list[MaybeAnnotatedStrJson]] + + class NamedListJson(TypedDict): - positional: list[Union[str, AnnotatedStrJson]] - keyword: dict[str, Union[str, AnnotatedStrJson]] + positional: list[IONamedListItem] + keyword: dict[str, IONamedListItem] def named_list_to_json(xs: snakemake.io.Namedlist) -> NamedListJson: - named: dict[str, Union[str, AnnotatedStrJson]] = { - k: annotated_str_to_json(v) for k, v in xs.items() - } - named_values = set(x if isinstance(x, str) else x["value"] for x in named.values()) + named: dict[str, IONamedListItem] = {} + for k, vs in xs.items(): + if not isinstance(vs, list): + named[k] = annotated_str_to_json(vs) + continue + + named[k] = [annotated_str_to_json(v) for v in vs] + + named_values = set() + for vs in named.values(): + if not isinstance(vs, list): + vs = [vs] + + for v in vs: + named_values.add(v) + + unnamed: list[IONamedListItem] = [] + for vs in xs: + if not isinstance(vs, list): + vs = [vs] + + for v in vs: + unnamed.append(v) - unnamed = [annotated_str_to_json(x) for x in xs if x not in named_values] return {"positional": unnamed, "keyword": named} From e573ddc0183b5e51bcdac4bd2a49f913044a349e Mon Sep 17 00:00:00 2001 From: maximsmol Date: Thu, 20 Jul 2023 13:09:56 -0700 Subject: [PATCH 111/356] fix Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 4f4ff8ee..889381d3 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 57 && pip install" + "run echo 58 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 8a098f26..0f0edf7b 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -835,6 +835,8 @@ def named_list_to_json(xs: snakemake.io.Namedlist) -> NamedListJson: vs = [vs] for v in vs: + if not isinstance(v, str): + v = v["value"] named_values.add(v) unnamed: list[IONamedListItem] = [] @@ -843,7 +845,7 @@ def named_list_to_json(xs: snakemake.io.Namedlist) -> NamedListJson: vs = [vs] for v in vs: - unnamed.append(v) + unnamed.append(annotated_str_to_json(v)) return {"positional": unnamed, "keyword": named} From 16f4747f7a7724237861b2c33f5fae144d74d48c Mon Sep 17 00:00:00 2001 From: maximsmol Date: Thu, 20 Jul 2023 13:21:25 -0700 Subject: [PATCH 112/356] fix wrong check for named namedlist value Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 21 ++++++++++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 889381d3..2947fa5b 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 58 && pip install" + "run echo 59 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 0f0edf7b..30149c4d 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -152,7 +152,11 @@ def snakemake_dag_to_interface( ) return ( - Interface(inputs, outputs, docstring=Docstring(str(meta))), + Interface( + inputs, + outputs, + docstring=Docstring(f"{wf_name}\n\nSample Description\n\n" + str(meta)), + ), LiteralMap(literals=literals), return_files, ) @@ -646,6 +650,7 @@ def compile(self, **kwargs): interface = Interface(python_inputs, python_outputs, docstring=None) task = SnakemakeJobTask( + wf=self, job=job, inputs=python_inputs, outputs=python_outputs, @@ -845,7 +850,15 @@ def named_list_to_json(xs: snakemake.io.Namedlist) -> NamedListJson: vs = [vs] for v in vs: - unnamed.append(annotated_str_to_json(v)) + obj = annotated_str_to_json(v) + + rendered = obj + if not isinstance(rendered, str): + rendered = rendered["value"] + if rendered in named_values: + continue + + unnamed.append(obj) return {"positional": unnamed, "keyword": named} @@ -853,6 +866,7 @@ def named_list_to_json(xs: snakemake.io.Namedlist) -> NamedListJson: class SnakemakeJobTask(PythonAutoContainerTask[T]): def __init__( self, + wf: SnakemakeWorkflow, job: snakemake.jobs.Job, inputs: Dict[str, Union[Type[LatchFile], Type[LatchDir]]], outputs: Dict[str, Union[Type[LatchFile], Type[LatchDir]]], @@ -864,6 +878,7 @@ def __init__( ): name = f"{job.name}_{job.jobid}" + self.wf = wf self.job = job self._is_target = is_target self._python_inputs = inputs @@ -1090,7 +1105,7 @@ def get_fn_code( ) except Exception: traceback.print_exc() - lp.upload(compiled, "latch:///.snakemake_latch/{self.name}_compiled.py") + lp.upload(compiled, "latch:///.snakemake_latch/{self.wf.name}/{self.name}_compiled.py") print("\n\n\nRunning snakemake task\n\n\n") try: From 4e2a25c530d9ca3f9a71bcb82a9cfa6d8c0e116a Mon Sep 17 00:00:00 2001 From: maximsmol Date: Thu, 20 Jul 2023 13:39:44 -0700 Subject: [PATCH 113/356] support lists in single task entrypoint Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/single_task_snakemake.py | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 2947fa5b..4e9f5986 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 59 && pip install" + "run echo 60 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 9ca5a66b..eabdc112 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -108,6 +108,14 @@ def render_annotated_str(x) -> str: return res +def render_annotated_str_list(xs) -> str: + if not isinstance(xs, list): + return render_annotated_str(xs) + + els = ", ".join(render_annotated_str(x) for x in xs) + return f"[{els}]" + + def emit_overrides(self, token): cur_data = rules[self.rulename] @@ -120,8 +128,10 @@ def emit_overrides(self, token): else: raise ValueError(f"tried to emit overrides for unknown state: {type(self)}") - positional_data = (render_annotated_str(x) for x in xs["positional"]) - keyword_data = (f"{k}={render_annotated_str(v)}" for k, v in xs["keyword"].items()) + positional_data = (render_annotated_str_list(x) for x in xs["positional"]) + keyword_data = ( + f"{k}={render_annotated_str_list(v)}" for k, v in xs["keyword"].items() + ) data = chain(positional_data, keyword_data) for x in data: From 893ae7bba368ff3f61c7c19633c0494678776a6c Mon Sep 17 00:00:00 2001 From: maximsmol Date: Thu, 20 Jul 2023 13:49:48 -0700 Subject: [PATCH 114/356] fix logs error, use same internal output dir Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 4e9f5986..05c4478a 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 60 && pip install" + "run echo 61 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 30149c4d..716f8d86 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -378,7 +378,7 @@ def get_fn_code( wf_name = wf.name generate_snakemake_entrypoint(wf, pkg_root, snakefile, {repr(remote_output_url)}) - entrypoint_remote = f"latch:///.snakemake_latch/workflows/{{image_base_name}}/entrypoint.py" + entrypoint_remote = f"latch:///.snakemake_latch/workflows/{{wf_name}}/entrypoint.py" lp.upload("latch_entrypoint.py", entrypoint_remote) print(f"latch_entrypoint.py -> {{entrypoint_remote}}") """, @@ -555,10 +555,7 @@ def __init__( dag: DAG, version: Optional[str] = None, ): - if version is not None: - name = f"{metadata._snakemake_metadata.name}-{version}" - else: - name = metadata._snakemake_metadata.name + name = metadata._snakemake_metadata.name native_interface, literal_map, return_files = snakemake_dag_to_interface( dag, name, None @@ -1105,7 +1102,7 @@ def get_fn_code( ) except Exception: traceback.print_exc() - lp.upload(compiled, "latch:///.snakemake_latch/{self.wf.name}/{self.name}_compiled.py") + lp.upload(compiled, "latch:///.snakemake_latch/workflows/{self.wf.name}/{self.name}_compiled.py") print("\n\n\nRunning snakemake task\n\n\n") try: @@ -1127,6 +1124,10 @@ def get_fn_code( local = Path(x) remote = f"latch://{remote_path}/{{str(local).removeprefix('/')}}" print(f" {{file_name_and_size(local)}} -> {{remote}}") + if not local.exists(): + print(" Does not exist") + continue + lp.upload(local, remote) print(" Done") From a12b042297d782a4c854964e22a01d7b4d99654a Mon Sep 17 00:00:00 2001 From: maximsmol Date: Thu, 20 Jul 2023 14:01:06 -0700 Subject: [PATCH 115/356] better error reporting for when snakemake fails Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/serialize.py | 1 + latch_cli/snakemake/workflow.py | 72 ++++++++++++++++-------------- 3 files changed, 41 insertions(+), 34 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 05c4478a..4743dddd 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 61 && pip install" + "run echo 62 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index edd27e59..37ecb297 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -278,6 +278,7 @@ def generate_snakemake_entrypoint( from pathlib import Path import shutil import subprocess + from subprocess import CalledProcessError from typing import NamedTuple import stat import sys diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 716f8d86..e88ea599 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1089,6 +1089,7 @@ def get_fn_code( rf""" lp = LatchPersistence() compiled = Path("compiled.py") + print("Saving compiled Snakemake script") with compiled.open("w") as f: try: subprocess.run( @@ -1100,49 +1101,54 @@ def get_fn_code( }}, stdout=f ) + except CalledProcessError: + print(" Failed") except Exception: traceback.print_exc() lp.upload(compiled, "latch:///.snakemake_latch/workflows/{self.wf.name}/{self.name}_compiled.py") print("\n\n\nRunning snakemake task\n\n\n") try: - subprocess.run( - [sys.executable,{','.join(repr(x) for x in snakemake_args)}], - check=True, - env={{ - **os.environ, - "LATCH_SNAKEMAKE_DATA": {repr(json.dumps(snakemake_data))} - }} - ) - print("\n\n\nDone\n\n\n") - except Exception as e: - print("\n\n\nFailed\n\n\n") - raise e - finally: - print("Uploading logs:") - for x in {repr(log_files)}: - local = Path(x) - remote = f"latch://{remote_path}/{{str(local).removeprefix('/')}}" - print(f" {{file_name_and_size(local)}} -> {{remote}}") - if not local.exists(): - print(" Does not exist") - continue - - lp.upload(local, remote) - print(" Done") - - benchmark_file = {repr(self.job.benchmark)} - if benchmark_file is not None: - print("\nUploading benchmark:") - - local = Path(benchmark_file) - if local.exists(): + try: + subprocess.run( + [sys.executable,{','.join(repr(x) for x in snakemake_args)}], + check=True, + env={{ + **os.environ, + "LATCH_SNAKEMAKE_DATA": {repr(json.dumps(snakemake_data))} + }} + ) + print("\n\n\nDone\n\n\n") + except Exception as e: + print("\n\n\nFailed\n\n\n") + raise e + finally: + print("Uploading logs:") + for x in {repr(log_files)}: + local = Path(x) remote = f"latch://{remote_path}/{{str(local).removeprefix('/')}}" print(f" {{file_name_and_size(local)}} -> {{remote}}") + if not local.exists(): + print(" Does not exist") + continue + lp.upload(local, remote) print(" Done") - else: - print(" Does not exist") + + benchmark_file = {repr(self.job.benchmark)} + if benchmark_file is not None: + print("\nUploading benchmark:") + + local = Path(benchmark_file) + if local.exists(): + remote = f"latch://{remote_path}/{{str(local).removeprefix('/')}}" + print(f" {{file_name_and_size(local)}} -> {{remote}}") + lp.upload(local, remote) + print(" Done") + else: + print(" Does not exist") + except CalledProcessError: + sys.exit(1) """, 1, From 6d0abd34af44de01d526abec12b24b91fc7fa80b Mon Sep 17 00:00:00 2001 From: maximsmol Date: Thu, 20 Jul 2023 15:48:36 -0700 Subject: [PATCH 116/356] list out current directory on failure Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 4743dddd..41aad316 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 62 && pip install" + "run echo 63 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index e88ea599..e19d1c73 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -322,7 +322,7 @@ def get_fn_code( rf""" {param}_dst_p = Path("{self.parameter_metadata[param].path}") - print(f"Downloading {{{param}.remote_path}}") + print(f"Downloading {param}: {{{param}.remote_path}}") {param}_p = Path({param}).resolve() print(f" {{file_name_and_size({param}_p)}}") @@ -1141,12 +1141,25 @@ def get_fn_code( local = Path(benchmark_file) if local.exists(): + print(local.read_text()) + remote = f"latch://{remote_path}/{{str(local).removeprefix('/')}}" print(f" {{file_name_and_size(local)}} -> {{remote}}") lp.upload(local, remote) print(" Done") else: print(" Does not exist") + + print("Recursive directory listing:") + stack = [(Path("."), 0)] + while len(stack) > 0: + cur, indent = stack.pop() + print(" " * indent + file_name_and_size(cur)) + + if cur.is_dir(): + for x in cur.iterdir(): + stack.append((x, indent + 1)) + except CalledProcessError: sys.exit(1) From da56091d255ab9340c81f4bf37b8d8de387474f2 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Thu, 20 Jul 2023 16:15:09 -0700 Subject: [PATCH 117/356] improve outputs Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 31 ++++++++++++++++++------------ 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 41aad316..cc001c3d 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 63 && pip install" + "run echo 64 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index e19d1c73..6effffa2 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -970,7 +970,7 @@ def get_fn_return_stmt(self, remote_output_url: Optional[str] = None): continue if remote_output_url is None: - remote_path = Path("/Snakemake Outputs") / target_path + remote_path = Path("/Snakemake Outputs") / self.wf.name / target_path else: remote_path = Path(urlparse(remote_output_url).path) / target_path @@ -1014,7 +1014,7 @@ def get_fn_code( rf""" {param}_dst_p = Path("{self._target_file_for_input_param[param]}") - print(f"Downloading {{{param}.remote_path}}") + print(f"Downloading {param}: {{{param}.remote_path}}") {param}_p = Path({param}).resolve() print(f" {{file_name_and_size({param}_p)}}") @@ -1079,7 +1079,7 @@ def get_fn_code( } if remote_output_url is None: - remote_path = Path("/Snakemake Outputs") + remote_path = Path("/Snakemake Outputs") / self.wf.name else: remote_path = Path(urlparse(remote_output_url).path) @@ -1150,17 +1150,24 @@ def get_fn_code( else: print(" Does not exist") - print("Recursive directory listing:") - stack = [(Path("."), 0)] - while len(stack) > 0: - cur, indent = stack.pop() - print(" " * indent + file_name_and_size(cur)) + except CalledProcessError: + ignored_paths = {{".cache"}} + ignored_names = {{".git", ".latch", "__pycache__"}} + + print("Recursive directory listing:") + stack = [(Path("."), 0)] + while len(stack) > 0: + cur, indent = stack.pop() + print(" " * indent + str(cur)) + + if cur.is_dir(): + if cur.name in ignored_names or str(cur) in ignored_paths: + print(" " * indent + " ...") + continue - if cur.is_dir(): - for x in cur.iterdir(): - stack.append((x, indent + 1)) + for x in cur.iterdir(): + stack.append((x, indent + 1)) - except CalledProcessError: sys.exit(1) """, From f84ca91005aab5c8a55e77e139bf74f6a998d46d Mon Sep 17 00:00:00 2001 From: maximsmol Date: Thu, 20 Jul 2023 16:30:48 -0700 Subject: [PATCH 118/356] fixup outputs more Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index cc001c3d..29c40c6a 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 64 && pip install" + "run echo 65 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 6effffa2..51aebaf0 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -128,7 +128,9 @@ def snakemake_dag_to_interface( LatchFile, None, ) - remote_path = Path("/.snakemake_latch") / wf_name / x + remote_path = ( + Path("/.snakemake_latch") / "workflows" / wf_name / "inputs" / x + ) remote_url = f"latch://{remote_path}" return_files.append(RemoteFile(local_path=x, remote_path=remote_url)) literals[param] = Literal( @@ -495,7 +497,7 @@ def get_fn_code( reg_resp = register_serialized_pkg(protos, None, version, account_id) _print_reg_resp(reg_resp, new_image_name) - wf_spec_remote = f"latch:///.snakemake_latch/workflows/{image_base_name}/spec.json" + wf_spec_remote = f"latch:///.snakemake_latch/workflows/{wf_name}/spec.json" lp.upload("wf_spec.json", wf_spec_remote) print(f"wf_spec.json -> {wf_spec_remote}") @@ -1105,7 +1107,7 @@ def get_fn_code( print(" Failed") except Exception: traceback.print_exc() - lp.upload(compiled, "latch:///.snakemake_latch/workflows/{self.wf.name}/{self.name}_compiled.py") + lp.upload(compiled, "latch:///.snakemake_latch/workflows/{self.wf.name}/compiled_tasks/{self.name}.py") print("\n\n\nRunning snakemake task\n\n\n") try: From 9a79b457000976ab5b27ea24489eff50206a8d4a Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 21 Jul 2023 09:41:25 -0700 Subject: [PATCH 119/356] tail the log if there is only one Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 45 ++++++++++++++++++++++-------- 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 29c40c6a..db87909a 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 65 && pip install" + "run echo 66 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 51aebaf0..7950898e 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1109,24 +1109,45 @@ def get_fn_code( traceback.print_exc() lp.upload(compiled, "latch:///.snakemake_latch/workflows/{self.wf.name}/compiled_tasks/{self.name}.py") - print("\n\n\nRunning snakemake task\n\n\n") + print("\n\n\nRunning snakemake task\n") try: + log_files = {repr(log_files)} try: - subprocess.run( - [sys.executable,{','.join(repr(x) for x in snakemake_args)}], - check=True, - env={{ - **os.environ, - "LATCH_SNAKEMAKE_DATA": {repr(json.dumps(snakemake_data))} - }} - ) + tail = None + if len(log_files) == 1: + log = Path(log_files[0]) + print(f"Tailing the only log file: {{log}}") + tail = subprocess.Popen(["tail", "--follow", log]) + + print("\n\n\n") + try: + subprocess.run( + [sys.executable,{','.join(repr(x) for x in snakemake_args)}], + check=True, + env={{ + **os.environ, + "LATCH_SNAKEMAKE_DATA": {repr(json.dumps(snakemake_data))} + }} + ) + finally: + if tail is not None: + tail.send_signal(SIGINT) + try: + tail.wait(1) + except subprocess.TimeoutExpired: + tail.kill() + + tail.wait() + if tail.returncode != 0: + print(f"\n\n\n[!] Log file tail died with code {{tail.returncode}}") + print("\n\n\nDone\n\n\n") except Exception as e: - print("\n\n\nFailed\n\n\n") + print("\n\n\n[!] Failed\n\n\n") raise e finally: print("Uploading logs:") - for x in {repr(log_files)}: + for x in log_files: local = Path(x) remote = f"latch://{remote_path}/{{str(local).removeprefix('/')}}" print(f" {{file_name_and_size(local)}} -> {{remote}}") @@ -1160,7 +1181,7 @@ def get_fn_code( stack = [(Path("."), 0)] while len(stack) > 0: cur, indent = stack.pop() - print(" " * indent + str(cur)) + print(" " * indent + cur.name) if cur.is_dir(): if cur.name in ignored_names or str(cur) in ignored_paths: From e9a4cd4828e1ce8a0bacdd3b1584a255eb5b27ea Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 21 Jul 2023 09:55:11 -0700 Subject: [PATCH 120/356] fix missing import Signed-off-by: maximsmol --- latch_cli/snakemake/workflow.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 7950898e..d20a4384 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1131,7 +1131,8 @@ def get_fn_code( ) finally: if tail is not None: - tail.send_signal(SIGINT) + import signal + tail.send_signal(signal.SIGINT) try: tail.wait(1) except subprocess.TimeoutExpired: From f9a2082b6700e43158fd305f8d569eaa2554dcf9 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 21 Jul 2023 10:03:25 -0700 Subject: [PATCH 121/356] fixup log tailing Signed-off-by: maximsmol --- latch_cli/snakemake/workflow.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index d20a4384..87246161 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1116,6 +1116,8 @@ def get_fn_code( tail = None if len(log_files) == 1: log = Path(log_files[0]) + log.touch() + print(f"Tailing the only log file: {{log}}") tail = subprocess.Popen(["tail", "--follow", log]) @@ -1139,7 +1141,8 @@ def get_fn_code( tail.kill() tail.wait() - if tail.returncode != 0: + # 130 is SIGINT + if tail.returncode != 130 && tail.returncode != 0: print(f"\n\n\n[!] Log file tail died with code {{tail.returncode}}") print("\n\n\nDone\n\n\n") From d85e8950b528f435c883a5b7d20ac93980d43da6 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 21 Jul 2023 10:20:47 -0700 Subject: [PATCH 122/356] print workflow link after register Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/services/register/register.py | 63 +++++++++++++++++++++++-- 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index db87909a..d708e702 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 66 && pip install" + "run echo 69 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index d8bad6cf..d8fd02b7 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -3,11 +3,14 @@ import shutil import sys import tempfile +import time from collections.abc import Iterable from pathlib import Path from typing import List, Optional import click +import gql +import latch_sdk_gql.execute as l_gql from scp import SCPClient from ...centromere.ctx import _CentromereCtx @@ -487,7 +490,59 @@ def register( ) _print_reg_resp(reg_resp, ctx.default_container.image_name) - click.secho( - "Successfully registered workflow. View @ console.latch.bio.", - fg="green", - ) + click.secho("Successfully registered workflow.", fg="green", bold=True) + + wf_infos = [] + retries = 0 + + wf_name = ctx.workflow_name + if snakefile is not None: + # todo(maximsmol): this is quite awful + wf_name = f"{wf_name}_jit_register" + + while len(wf_infos) == 0: + wf_infos = l_gql.execute( + gql.gql(""" + query workflowQuery($name: String, $ownerId: BigInt, $version: String) { + workflowInfos(condition: { name: $name, ownerId: $ownerId, version: $version}) { + nodes { + id + } + } + } + """), + { + "name": wf_name, + "version": ctx.version, + "ownerId": current_workspace(), + }, + )["workflowInfos"]["nodes"] + time.sleep(1) + + if retries >= 5: + click.secho( + "Failed to query workflow ID in 5 seconds.", fg="red", bold=True + ) + click.secho( + "This could be due to high demand or a bug in the platform.", + fg="red", + ) + click.secho( + "If the workflow is not visible in latch console, contact" + " support.", + fg="red", + ) + break + + retries += 1 + + if len(wf_infos) > 0: + if len(wf_infos) > 1: + click.secho( + f"Worfklow {ctx.workflow_name}:{ctx.version} is not unique. The" + " link below might be wrong.", + fg="yellow", + ) + + wf_id = wf_infos[0]["id"] + click.secho(f"https://console.latch.bio/workflows/{wf_id}", fg="green") From f56cff7473585207da5ccd34ef539063eedf7b7c Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 21 Jul 2023 10:42:27 -0700 Subject: [PATCH 123/356] move stuff around Signed-off-by: maximsmol --- latch_cli/main.py | 6 +- latch_cli/{tui.py => menus.py} | 0 latch_cli/services/get_executions.py | 146 +++++++++++----------- latch_cli/services/init/init.py | 2 +- latch_cli/services/local_dev.py | 2 +- latch_cli/services/preview.py | 38 +++--- latch_cli/services/workspace.py | 2 +- latch_cli/tui/__init__.py | 0 latch_cli/{utils.py => utils/__init__.py} | 6 +- latch_cli/utils/doc.py | 38 ++++++ 10 files changed, 137 insertions(+), 103 deletions(-) rename latch_cli/{tui.py => menus.py} (100%) create mode 100644 latch_cli/tui/__init__.py rename latch_cli/{utils.py => utils/__init__.py} (97%) create mode 100644 latch_cli/utils/doc.py diff --git a/latch_cli/main.py b/latch_cli/main.py index 1080acda..86a152d2 100644 --- a/latch_cli/main.py +++ b/latch_cli/main.py @@ -471,10 +471,8 @@ def get_params(wf_name: Union[str, None], version: Union[str, None] = None): if version is None: version = "latest" click.secho( - ( - f"Successfully generated python param map named {wf_name}.params.py with" - f" version {version}\n Run `latch launch {wf_name}.params.py` to launch it." - ), + f"Successfully generated python param map named {wf_name}.params.py with" + f" version {version}\n Run `latch launch {wf_name}.params.py` to launch it.", fg="green", ) diff --git a/latch_cli/tui.py b/latch_cli/menus.py similarity index 100% rename from latch_cli/tui.py rename to latch_cli/menus.py diff --git a/latch_cli/services/get_executions.py b/latch_cli/services/get_executions.py index 10a49d5d..8d3fa401 100644 --- a/latch_cli/services/get_executions.py +++ b/latch_cli/services/get_executions.py @@ -9,7 +9,7 @@ from apscheduler.schedulers.background import BackgroundScheduler from latch_sdk_config.latch import config -import latch_cli.tui as tui +import latch_cli.menus as menus from latch_cli.tinyrequests import post from latch_cli.utils import account_id_from_token, current_workspace, retrieve_or_login @@ -84,7 +84,7 @@ def render( ) -> int: # DISCLAIMER : MOST OF THE MAGIC NUMBERS HERE WERE THROUGH TRIAL AND ERROR - tui.move_cursor((2, 2)) + menus.move_cursor((2, 2)) max_per_page = term_height - 5 vert_index = max(0, curr_selected - max_per_page // 2) @@ -107,8 +107,8 @@ def render( max_row_len = sum(lengths.values()) + column_spacing * (len(column_names) - 1) - tui._print(title) - tui.line_down(2) + menus._print(title) + menus.line_down(2) for i in range(vert_index, vert_index + max_per_page): if i >= len(options): @@ -130,16 +130,16 @@ def render( reset = "\x1b[0m" row_str = f"{green}{bold}{row_str}{reset}" - tui.move_cursor_right(3) - tui._print(row_str) - tui.line_down(1) + menus.move_cursor_right(3) + menus._print(row_str) + menus.line_down(1) - tui.move_cursor((2, term_height - 1)) + menus.move_cursor((2, term_height - 1)) control_str = "[ARROW-KEYS] Navigate\t[ENTER] Select\t[Q] Quit" - tui._print(control_str) - tui.draw_box((2, 3), term_height - 5, term_width - 4) + menus._print(control_str) + menus.draw_box((2, 3), term_height - 5, term_width - 4) - tui._show() + menus._show() return max_row_len old_settings = termios.tcgetattr(sys.stdin.fileno()) @@ -147,16 +147,16 @@ def render( curr_selected = hor_index = 0 - tui.remove_cursor() - tui.clear_screen() - tui.move_cursor((0, 0)) + menus.remove_cursor() + menus.clear_screen() + menus.move_cursor((0, 0)) prev = (curr_selected, hor_index, term_width, term_height) max_row_len = render(curr_selected, hor_index, term_width, term_height) try: while True: - b = tui.read_bytes(1) + b = menus.read_bytes(1) term_width, term_height = os.get_terminal_size() rerender = False if b == b"\r": @@ -172,7 +172,7 @@ def render( _execution_dashboard(selected_execution_data, resp.json()) rerender = True elif b == b"\x1b": - b = tui.read_bytes(2) + b = menus.read_bytes(2) if b == b"[A": # Up Arrow curr_selected = max(0, curr_selected - 1) elif b == b"[B": # Down Arrow @@ -184,7 +184,7 @@ def render( if max_row_len > term_width + 7: hor_index = min(max_row_len - term_width + 7, hor_index + 5) elif b == b"[1": # Start of SHIFT + arrow keys - b = tui.read_bytes(3) + b = menus.read_bytes(3) if b == b";2A": # Up Arrow curr_selected = max(0, curr_selected - 20) elif b == b";2B": # Down Arrow @@ -221,15 +221,15 @@ def render( (curr_selected, hor_index, term_width, term_height) != prev ): prev = (curr_selected, hor_index, term_width, term_height) - tui.clear_screen() + menus.clear_screen() max_row_len = render(curr_selected, hor_index, term_width, term_height) except KeyboardInterrupt: ... finally: - tui.clear_screen() - tui.reveal_cursor() - tui.move_cursor((0, 0)) - tui._show() + menus.clear_screen() + menus.reveal_cursor() + menus.move_cursor((0, 0)) + menus._show() termios.tcsetattr(sys.stdin.fileno(), termios.TCSANOW, old_settings) @@ -238,13 +238,13 @@ def _execution_dashboard(execution_data: Dict[str, str], workflow_graph: Dict): def render(curr_selected: int, term_width: int, term_height: int): # DISCLAIMER : MOST OF THE MAGIC NUMBERS HERE WERE THROUGH TRIAL AND ERROR - tui.move_cursor((2, 2)) - tui._print( + menus.move_cursor((2, 2)) + menus._print( f'{execution_data["display_name"]} - {execution_data["workflow_tagged"]}' ) - tui.draw_box((2, 3), term_height - 5, term_width - 4) + menus.draw_box((2, 3), term_height - 5, term_width - 4) - tui.move_cursor((2, term_height - 1)) + menus.move_cursor((2, term_height - 1)) instructions = [ "[ARROW-KEYS] Navigate", "[ENTER] View Task Logs", @@ -253,9 +253,9 @@ def render(curr_selected: int, term_width: int, term_height: int): if execution_data["status"] == "RUNNING": instructions.append("[A] Abort") instructions.append("[Q] Back to All Executions") - tui._print("\t".join(instructions)) + menus._print("\t".join(instructions)) - tui.move_cursor((4, 4)) + menus.move_cursor((4, 4)) for i, (_, task) in enumerate(fixed_workflow_graph): name, status = task["name"] or task["sub_wf_name"], task["status"] row_str = " ".join([name, status]) @@ -263,14 +263,14 @@ def render(curr_selected: int, term_width: int, term_height: int): green = "\x1b[38;5;40m" bold = "\x1b[1m" reset = "\x1b[0m" - tui._print(f"{green}{bold}{row_str}{reset}") + menus._print(f"{green}{bold}{row_str}{reset}") else: - tui._print(row_str) - tui.line_down(1) - tui.move_cursor_right(3) - tui._show() + menus._print(row_str) + menus.line_down(1) + menus.move_cursor_right(3) + menus._show() - tui.clear_screen() + menus.clear_screen() try: term_width, term_height = os.get_terminal_size() @@ -279,7 +279,7 @@ def render(curr_selected: int, term_width: int, term_height: int): render(curr_selected, term_width, term_height) prev = (curr_selected, term_width, term_height) while True: - b = tui.read_bytes(1) + b = menus.read_bytes(1) rerender = False if b == b"\r": _log_window(execution_data, fixed_workflow_graph, curr_selected) @@ -291,13 +291,13 @@ def render(curr_selected: int, term_width: int, term_height: int): _abort_modal(execution_data) rerender = True elif b == b"\x1b": - b = tui.read_bytes(2) + b = menus.read_bytes(2) if b == b"[A": # Up Arrow curr_selected = max(curr_selected - 1, 0) elif b == b"[B": # Down Arrow curr_selected = min(curr_selected + 1, len(workflow_graph) - 1) elif b == b"[1": # Start of SHIFT + arrow keys - b = tui.read_bytes(3) + b = menus.read_bytes(3) if b == b";2A": # Up Arrow curr_selected = max(0, curr_selected - 20) elif b == b";2B": # Down Arrow @@ -314,30 +314,30 @@ def render(curr_selected: int, term_width: int, term_height: int): curr_selected = max(curr_selected - 20, 0) term_width, term_height = os.get_terminal_size() if rerender or (prev != (curr_selected, term_width, term_height)): - tui.clear_screen() + menus.clear_screen() prev = (curr_selected, term_width, term_height) render(curr_selected, term_width, term_height) except KeyboardInterrupt: ... finally: - tui.clear_screen() - tui.move_cursor((0, 0)) - tui._show() + menus.clear_screen() + menus.move_cursor((0, 0)) + menus._show() def _loading_screen(text: str): # DISCLAIMER : MOST OF THE MAGIC NUMBERS HERE WERE THROUGH TRIAL AND ERROR term_width, term_height = os.get_terminal_size() - tui.clear_screen() - tui.draw_box((2, 3), term_height - 5, term_width - 4) + menus.clear_screen() + menus.draw_box((2, 3), term_height - 5, term_width - 4) x = (term_width - len(text)) // 2 y = term_height // 2 - tui.move_cursor((x, y)) - tui._print(text) - tui._show() + menus.move_cursor((x, y)) + menus._print(text) + menus._show() def _log_window(execution_data, fixed_workflow_graph: list, selected: int): @@ -368,13 +368,13 @@ def get_logs(): f.write(resp.json()["message"].replace("\t", " ")) def render(vert_index, hor_index, term_width, term_height): - tui.move_cursor((2, 2)) - tui._print( + menus.move_cursor((2, 2)) + menus._print( f'{execution_data["display_name"]} - {execution_data["workflow_tagged"]} -' f' {selected_task["name"]}' ) - tui.draw_box((2, 3), term_height - 5, term_width - 4) - tui.move_cursor((4, 4)) + menus.draw_box((2, 3), term_height - 5, term_width - 4) + menus.move_cursor((4, 4)) with open(log_file, "r") as f: for i, line in enumerate(f): if i < vert_index: @@ -382,17 +382,17 @@ def render(vert_index, hor_index, term_width, term_height): elif i > vert_index + term_height - 7: continue line = line.strip("\n\r") - tui._print(line[hor_index : hor_index + term_width - 7]) - tui.line_down(1) - tui.move_cursor_right(3) - tui.move_cursor((2, term_height - 1)) + menus._print(line[hor_index : hor_index + term_width - 7]) + menus.line_down(1) + menus.move_cursor_right(3) + menus.move_cursor((2, term_height - 1)) control_str = "[ARROW-KEYS] Navigate\t[Q] Back" - tui._print(control_str) - tui._show() + menus._print(control_str) + menus._show() try: term_width, term_height = os.get_terminal_size() - tui.clear_screen() + menus.clear_screen() get_logs() log_sched = BackgroundScheduler() @@ -407,12 +407,12 @@ def render(vert_index, hor_index, term_width, term_height): render(vert_index, hor_index, term_width, term_height) prev_term_dims = (vert_index, hor_index, term_width, term_height) while True: - b = tui.read_bytes(1) + b = menus.read_bytes(1) rerender = False if b in (b"r", b"R"): rerender = True elif b == b"\x1b": - b = tui.read_bytes(2) + b = menus.read_bytes(2) if b == b"[A": # Up Arrow vert_index = max(0, vert_index - 1) elif b == b"[B": # Down Arrow @@ -422,7 +422,7 @@ def render(vert_index, hor_index, term_width, term_height): elif b == b"[C": # Right Arrow hor_index += 5 elif b == b"[1": # Start of SHIFT + arrow keys - b = tui.read_bytes(3) + b = menus.read_bytes(3) if b == b";2A": # Up Arrow vert_index = max(0, vert_index - 20) elif b == b";2B": # Down Arrow @@ -451,7 +451,7 @@ def render(vert_index, hor_index, term_width, term_height): if rerender or ( prev_term_dims != (vert_index, hor_index, term_width, term_height) ): - tui.clear_screen() + menus.clear_screen() prev_term_dims = (vert_index, hor_index, term_width, term_height) render(vert_index, hor_index, term_width, term_height) except KeyboardInterrupt: @@ -459,9 +459,9 @@ def render(vert_index, hor_index, term_width, term_height): finally: log_sched.shutdown() log_file.unlink(missing_ok=True) - tui.clear_screen() - tui.move_cursor((0, 0)) - tui._show() + menus.clear_screen() + menus.move_cursor((0, 0)) + menus._show() # TODO(ayush): implement this @@ -472,7 +472,7 @@ def _relaunch_modal(execution_data): def _abort_modal(execution_data): def render(term_width: int, term_height: int): # DISCLAIMER : MOST OF THE MAGIC NUMBERS HERE WERE THROUGH TRIAL AND ERROR - tui.clear_screen() + menus.clear_screen() question = ( f"Are you sure you want to abort {execution_data['display_name']} " @@ -485,23 +485,23 @@ def render(term_width: int, term_height: int): x = (term_width - max_line_length) // 2 y = (term_height - len(lines)) // 2 - tui.draw_box((x - 3, y - 2), len(lines) + 4, max_line_length + 4) + menus.draw_box((x - 3, y - 2), len(lines) + 4, max_line_length + 4) for i, line in enumerate(lines): x = (term_width - len(line)) // 2 - tui.move_cursor((x, y + i)) - tui._print(f"{line}") + menus.move_cursor((x, y + i)) + menus._print(f"{line}") ctrl_str = "[Y] Yes\t[N] No" - tui.move_cursor(((term_width - len(ctrl_str)) // 2, y + len(lines) + 1)) - tui._print(ctrl_str) + menus.move_cursor(((term_width - len(ctrl_str)) // 2, y + len(lines) + 1)) + menus._print(ctrl_str) try: term_width, term_height = os.get_terminal_size() render(term_width, term_height) prev_term_dims = (term_width, term_height) while True: - b = tui.read_bytes(1) + b = menus.read_bytes(1) if b in (b"y", b"Y"): headers = {"Authorization": f"Bearer {retrieve_or_login()}"} resp = post( @@ -519,5 +519,5 @@ def render(term_width: int, term_height: int): except KeyboardInterrupt: ... finally: - tui.clear_screen() - tui.move_cursor((0, 0)) + menus.clear_screen() + menus.move_cursor((0, 0)) diff --git a/latch_cli/services/init/init.py b/latch_cli/services/init/init.py index c90c6066..f08f9381 100644 --- a/latch_cli/services/init/init.py +++ b/latch_cli/services/init/init.py @@ -9,7 +9,7 @@ import click from latch_cli.docker_utils import generate_dockerfile -from latch_cli.tui import select_tui +from latch_cli.menus import select_tui from latch_cli.workflow_config import BaseImageOptions, create_and_write_config diff --git a/latch_cli/services/local_dev.py b/latch_cli/services/local_dev.py index 0bfe350b..646c4afa 100644 --- a/latch_cli/services/local_dev.py +++ b/latch_cli/services/local_dev.py @@ -12,8 +12,8 @@ from latch_sdk_config.latch import config from latch_cli.constants import latch_constants +from latch_cli.menus import select_tui from latch_cli.tinyrequests import post -from latch_cli.tui import select_tui from latch_cli.utils import ( TemporarySSHCredentials, current_workspace, diff --git a/latch_cli/services/preview.py b/latch_cli/services/preview.py index a46dc103..8fc42f29 100644 --- a/latch_cli/services/preview.py +++ b/latch_cli/services/preview.py @@ -10,7 +10,7 @@ from google.protobuf.json_format import MessageToJson from latch_sdk_config.latch import config -import latch_cli.tui as tui +import latch_cli.menus as menus from latch_cli.centromere.utils import _import_flyte_objects from latch_cli.tinyrequests import post from latch_cli.utils import current_workspace, retrieve_or_login @@ -97,8 +97,8 @@ def render( if curr_selected < 0 or curr_selected >= len(options): curr_selected = 0 - tui._print(title) - tui.line_down(2) + menus._print(title) + menus.line_down(2) num_lines_rendered = 4 # 4 "extra" lines for header + footer @@ -110,18 +110,18 @@ def render( color = "\x1b[38;5;40m" bold = "\x1b[1m" reset = "\x1b[0m" - tui._print(f"{indent}{color}{bold}{name}{reset}\x1b[1E") + menus._print(f"{indent}{color}{bold}{name}{reset}\x1b[1E") else: - tui._print(f"{indent}{name}\x1b[1E") + menus._print(f"{indent}{name}\x1b[1E") num_lines_rendered += 1 - tui.line_down(1) + menus.line_down(1) control_str = "[ARROW-KEYS] Navigate\t[ENTER] Select\t[Q] Quit" - tui._print(control_str) - tui.line_up(num_lines_rendered - 1) + menus._print(control_str) + menus.line_up(num_lines_rendered - 1) - tui._show() + menus._show() return num_lines_rendered @@ -131,14 +131,14 @@ def render( curr_selected = 0 start_index = 0 _, term_height = os.get_terminal_size() - tui.remove_cursor() + menus.remove_cursor() if not clear_terminal: - _, curs_height = tui.current_cursor_position() + _, curs_height = menus.current_cursor_position() max_per_page = term_height - curs_height - 4 else: - tui.clear_screen() - tui.move_cursor((0, 0)) + menus.clear_screen() + menus.move_cursor((0, 0)) max_per_page = term_height - 4 num_lines_rendered = render( @@ -149,11 +149,11 @@ def render( try: while True: - b = tui.read_bytes(1) + b = menus.read_bytes(1) if b == b"\r": return options[curr_selected] elif b == b"\x1b": - b = tui.read_bytes(2) + b = menus.read_bytes(2) if b == b"[A": # Up Arrow curr_selected = max(curr_selected - 1, 0) if ( @@ -170,7 +170,7 @@ def render( start_index += 1 else: continue - tui.clear(num_lines_rendered) + menus.clear(num_lines_rendered) num_lines_rendered = render( curr_selected, start_index=start_index, @@ -179,7 +179,7 @@ def render( except KeyboardInterrupt: ... finally: - tui.clear(num_lines_rendered) - tui.reveal_cursor() - tui._show() + menus.clear(num_lines_rendered) + menus.reveal_cursor() + menus._show() termios.tcsetattr(sys.stdin.fileno(), termios.TCSANOW, old_settings) diff --git a/latch_cli/services/workspace.py b/latch_cli/services/workspace.py index 5e918ecb..0bb9e11c 100644 --- a/latch_cli/services/workspace.py +++ b/latch_cli/services/workspace.py @@ -2,8 +2,8 @@ from latch_sdk_config.latch import config from latch_sdk_config.user import user_config +from latch_cli.menus import select_tui from latch_cli.tinyrequests import post -from latch_cli.tui import select_tui from latch_cli.utils import current_workspace, retrieve_or_login diff --git a/latch_cli/tui/__init__.py b/latch_cli/tui/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/latch_cli/utils.py b/latch_cli/utils/__init__.py similarity index 97% rename from latch_cli/utils.py rename to latch_cli/utils/__init__.py index d82f55c6..f3d4e7ac 100644 --- a/latch_cli/utils.py +++ b/latch_cli/utils/__init__.py @@ -158,10 +158,8 @@ def hash_directory(dir_path: Path) -> str: file_size = p.stat().st_size if file_size > latch_constants.file_max_size: click.secho( - ( - f"{p.relative_to(dir_path.resolve())} is too large" - f" ({with_si_suffix(file_size)}) to checksum. Ignoring contents" - ), + f"{p.relative_to(dir_path.resolve())} is too large" + f" ({with_si_suffix(file_size)}) to checksum. Ignoring contents", fg="yellow", bold=True, ) diff --git a/latch_cli/utils/doc.py b/latch_cli/utils/doc.py new file mode 100644 index 00000000..9ea4158e --- /dev/null +++ b/latch_cli/utils/doc.py @@ -0,0 +1,38 @@ +import textwrap +from collections.abc import Generator +from contextlib import contextmanager +from dataclasses import dataclass, field + + +def dedent_chunk(x: str) -> str: + return textwrap.dedent(x).removeprefix("\n").removesuffix("\n") + + +@dataclass +class Doc: + indent_level: int = field(default=0) + + lines: list[str] = field(default_factory=list, init=False) + + def print(self, *args, sep=" ", dedent=True) -> None: + indent = self.indent_level * " " + + strs = (str(x) for x in args) + if dedent: + strs = (dedent_chunk(x) for x in strs) + + lines = sep.join(strs).split("\n") + + for l in lines: + self.lines.append(indent + l) + + @contextmanager + def indent(self) -> Generator[None, None, None]: + self.indent_level += 1 + try: + yield + finally: + self.indent_level -= 1 + + def render(self) -> str: + return "\n".join(self.lines) From 1be28f3e19052e4e7e6c11388ba392b5a2f41bdf Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 21 Jul 2023 10:53:50 -0700 Subject: [PATCH 124/356] fix tailer Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index d708e702..6b1b94a8 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 69 && pip install" + "run echo 70 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 87246161..f0e1bef4 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1142,7 +1142,7 @@ def get_fn_code( tail.wait() # 130 is SIGINT - if tail.returncode != 130 && tail.returncode != 0: + if tail.returncode != 130 and tail.returncode != 0: print(f"\n\n\n[!] Log file tail died with code {{tail.returncode}}") print("\n\n\nDone\n\n\n") From 32bd3bd76811b14fdc19542159b30f5135945842 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 21 Jul 2023 11:06:18 -0700 Subject: [PATCH 125/356] fix bad merge deps Signed-off-by: maximsmol --- setup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/setup.py b/setup.py index a1616c4e..b4402358 100644 --- a/setup.py +++ b/setup.py @@ -26,7 +26,6 @@ }, install_requires=[ "asyncssh==2.12.0", - "aioconsole==0.5.1", "kubernetes>=24.2.0", "pyjwt>=0.2.0", "requests>=2.28.1", From 770e44a207ffbc3c8c44465c1afa034b1bb53a28 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 21 Jul 2023 11:06:52 -0700 Subject: [PATCH 126/356] fix more bad merge Signed-off-by: maximsmol --- setup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/setup.py b/setup.py index b4402358..5ef48530 100644 --- a/setup.py +++ b/setup.py @@ -25,7 +25,6 @@ ] }, install_requires=[ - "asyncssh==2.12.0", "kubernetes>=24.2.0", "pyjwt>=0.2.0", "requests>=2.28.1", From e7acf070eb2222894c3c5b319b4200ff68e5321d Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 21 Jul 2023 11:44:16 -0700 Subject: [PATCH 127/356] del doc for now Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 4 ++-- latch_cli/utils/doc.py | 38 ------------------------------ 3 files changed, 3 insertions(+), 41 deletions(-) delete mode 100644 latch_cli/utils/doc.py diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 6b1b94a8..549f9e95 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 70 && pip install" + "run echo 71 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index f0e1bef4..3a851c15 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1141,8 +1141,8 @@ def get_fn_code( tail.kill() tail.wait() - # 130 is SIGINT - if tail.returncode != 130 and tail.returncode != 0: + # -2 is SIGINT + if tail.returncode != -2 and tail.returncode != 0: print(f"\n\n\n[!] Log file tail died with code {{tail.returncode}}") print("\n\n\nDone\n\n\n") diff --git a/latch_cli/utils/doc.py b/latch_cli/utils/doc.py deleted file mode 100644 index 9ea4158e..00000000 --- a/latch_cli/utils/doc.py +++ /dev/null @@ -1,38 +0,0 @@ -import textwrap -from collections.abc import Generator -from contextlib import contextmanager -from dataclasses import dataclass, field - - -def dedent_chunk(x: str) -> str: - return textwrap.dedent(x).removeprefix("\n").removesuffix("\n") - - -@dataclass -class Doc: - indent_level: int = field(default=0) - - lines: list[str] = field(default_factory=list, init=False) - - def print(self, *args, sep=" ", dedent=True) -> None: - indent = self.indent_level * " " - - strs = (str(x) for x in args) - if dedent: - strs = (dedent_chunk(x) for x in strs) - - lines = sep.join(strs).split("\n") - - for l in lines: - self.lines.append(indent + l) - - @contextmanager - def indent(self) -> Generator[None, None, None]: - self.indent_level += 1 - try: - yield - finally: - self.indent_level -= 1 - - def render(self) -> str: - return "\n".join(self.lines) From 9f4b16bc5c8326052fb5d80ba85c02ab1b98ea35 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 21 Jul 2023 15:52:30 -0700 Subject: [PATCH 128/356] ux fixes Signed-off-by: maximsmol --- latch_cli/services/register/register.py | 3 ++- latch_cli/utils/__init__.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index d8fd02b7..730f5d95 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -330,7 +330,8 @@ def register( try: import snakemake except ImportError as e: - raise RuntimeError("could not load snakemake: package not installed") from e + click.secho("\n`snakemake` package is not installed.", fg="red", bold=True) + sys.exit(1) with _CentromereCtx( Path(pkg_root), diff --git a/latch_cli/utils/__init__.py b/latch_cli/utils/__init__.py index 77229898..831bef35 100644 --- a/latch_cli/utils/__init__.py +++ b/latch_cli/utils/__init__.py @@ -166,7 +166,7 @@ def hash_directory(dir_path: Path) -> str: m.update(current_workspace().encode("utf-8")) ignore_file = dir_path / ".dockerignore" - exclude: List[str] = ["/.latch"] + exclude: List[str] = ["/.latch", ".git"] try: with ignore_file.open("r") as f: click.echo("Using .dockerignore") From 09d056125e5e06e7b6e7095bb12eeced56a9aacc Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 21 Jul 2023 16:16:22 -0700 Subject: [PATCH 129/356] fix Hannah's issues Signed-off-by: maximsmol --- latch_cli/services/register/utils.py | 5 +++-- latch_cli/snakemake/serialize.py | 1 + latch_cli/utils/__init__.py | 16 ++++++++++++++-- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/latch_cli/services/register/utils.py b/latch_cli/services/register/utils.py index ed1b21e9..b739649f 100644 --- a/latch_cli/services/register/utils.py +++ b/latch_cli/services/register/utils.py @@ -55,8 +55,9 @@ def _docker_login(ctx: _CentromereCtx): auth = ctx.dkr_client._auth_configs store_name = auth.get_credential_store(ctx.dkr_repo) - store = auth._get_store_instance(store_name) - store.erase(ctx.dkr_repo) + if store_name is not None: + store = auth._get_store_instance(store_name) + store.erase(ctx.dkr_repo) user, password = base64.b64decode(token).decode("utf-8").split(":") res = ctx.dkr_client.login( diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index 37ecb297..834f7e53 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -418,6 +418,7 @@ def file_name_and_size(x: Path): ) entrypoint = pkg_root / ".latch" / "snakemake_jit_entrypoint.py" + entrypoint.parent.mkdir(parents=True, exist_ok=True) entrypoint.write_text(code_block + "\n") return entrypoint diff --git a/latch_cli/utils/__init__.py b/latch_cli/utils/__init__.py index 831bef35..5423aa58 100644 --- a/latch_cli/utils/__init__.py +++ b/latch_cli/utils/__init__.py @@ -2,6 +2,7 @@ import hashlib import os +import stat import subprocess import urllib.parse from datetime import datetime, timedelta @@ -190,13 +191,24 @@ def hash_directory(dir_path: Path) -> str: for item in paths: p = Path(dir_path / item) - if p.is_dir(): + + p_stat = p.stat() + if stat.S_ISDIR(p_stat.st_mode): m.update(p.name.encode("utf-8")) continue m.update(p.name.encode("utf-8")) - file_size = p.stat().st_size + file_size = p_stat.st_size + if not stat.S_ISREG(p_stat.st_mode): + click.secho( + f"{p.relative_to(dir_path.resolve())} is not a regular file. Ignoring" + " contents", + fg="yellow", + bold=True, + ) + continue + if file_size > latch_constants.file_max_size: click.secho( f"{p.relative_to(dir_path.resolve())} is too large" From 8be9cf60776b23ed5601a409bb94863d42fb7ddd Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 21 Jul 2023 17:13:28 -0700 Subject: [PATCH 130/356] do not depend on encode_target_jobs_cli_args Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 25 ++++++++++++++++++------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 549f9e95..7ae90d1a 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,7 +361,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 71 && pip install" + "run echo 72 && pip install" " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 3a851c15..cf923f60 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -2,6 +2,7 @@ import json import textwrap import typing +from collections.abc import Generator, Iterable from dataclasses import dataclass from pathlib import Path from typing import Any, Dict, List, Optional, Tuple, Type, TypeVar, Union @@ -35,8 +36,7 @@ from flytekit.models.core.types import BlobType from flytekit.models.literals import Blob, BlobMetadata, Literal, LiteralMap, Scalar from snakemake.dag import DAG -from snakemake.jobs import GroupJob -from snakemake.target_jobs import encode_target_jobs_cli_args +from snakemake.jobs import GroupJob, Job from typing_extensions import TypeAlias, TypedDict import latch.types.metadata as metadata @@ -48,6 +48,17 @@ SnakemakeInputVal: TypeAlias = snakemake.io._IOFile +# old snakemake did not have encode_target_jobs_cli_args +def jobs_cli_args( + jobs: Iterable[Job], +) -> Generator[str, None, None]: + for x in jobs: + wildcards = ",".join( + f"{key}={value}" for key, value in x.wildcards_dict.items() + ) + yield f"{x.rule.name}:{wildcards}" + + T = TypeVar("T") @@ -1035,13 +1046,17 @@ def get_fn_code( 1, ) + jobs = [self.job] + if isinstance(self.job, GroupJob): + jobs = self.job.jobs + snakemake_args = [ "-m", "latch_cli.snakemake.single_task_snakemake", "-s", snakefile_path_in_container, "--target-jobs", - *encode_target_jobs_cli_args(self.job.get_target_spec()), + *jobs_cli_args(jobs), "--allowed-rules", *self.job.rules, "--local-groupid", @@ -1062,10 +1077,6 @@ def get_fn_code( for resource, value in allowed_resources: snakemake_args.append(f"{resource}={value}") - jobs = [self.job] - if isinstance(self.job, GroupJob): - jobs = self.job.jobs - snakemake_data = { "rules": {}, "outputs": self.job.output, From 1355a62abfdf462c959c85fc2a1dfd9af1b14d20 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 25 Jul 2023 14:06:51 -0700 Subject: [PATCH 131/356] fix docker image name for workflows with special chars Signed-off-by: maximsmol --- latch_cli/centromere/ctx.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/latch_cli/centromere/ctx.py b/latch_cli/centromere/ctx.py index 9c5ebd2b..32b02f17 100644 --- a/latch_cli/centromere/ctx.py +++ b/latch_cli/centromere/ctx.py @@ -45,6 +45,9 @@ class _Container: image_name: str +docker_image_name_illegal_pat = re.compile(r"[^a-z0-9]+") + + class _CentromereCtx: """Manages state for interaction with centromere. @@ -249,7 +252,8 @@ def image(self): else: account_id = self.account_id - wf_name = identifier_suffix_from_str(self.workflow_name) + wf_name = identifier_suffix_from_str(self.workflow_name).lower() + wf_name = docker_image_name_illegal_pat.sub("_", wf_name) return f"{account_id}_{wf_name}" From 9920746cea883f8b3ac38dbbc4e26443d4ef5e83 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 25 Jul 2023 14:09:40 -0700 Subject: [PATCH 132/356] support environment.yml Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 7ae90d1a..c7c7e827 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -166,17 +166,21 @@ def infer_commands(pkg_root: Path) -> List[DockerCmdBlock]: ), ] - if (pkg_root / "environment.yaml").exists(): + conda_env = pkg_root / "environment.yml" + if not conda_env.exists(): + conda_env = conda_env.with_suffix(".yaml") + + if conda_env.exists(): click.echo( " ".join( [ - click.style(f"environment.yaml:", bold=True), + click.style(f"{conda_env.name}:", bold=True), "Conda dependencies installation phase", ] ) ) - with (pkg_root / "environment.yaml").open("rb") as f: + with conda_env.open("rb") as f: conda_env = yaml.safe_load(f) if "name" in conda_env: @@ -214,7 +218,7 @@ def infer_commands(pkg_root: Path) -> List[DockerCmdBlock]: DockerCmdBlock( comment="Build conda environment", commands=[ - "copy environment.yaml /opt/latch/environment.yaml", + f"copy {conda_env.name} /opt/latch/environment.yaml", dedent(rf""" run mamba env create \ --file /opt/latch/environment.yaml \ From daea05ce0c1484d836a97986ed6c8fb1e0fd02cf Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 25 Jul 2023 14:24:37 -0700 Subject: [PATCH 133/356] oopsie Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index c7c7e827..bb12b859 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -166,21 +166,21 @@ def infer_commands(pkg_root: Path) -> List[DockerCmdBlock]: ), ] - conda_env = pkg_root / "environment.yml" - if not conda_env.exists(): - conda_env = conda_env.with_suffix(".yaml") + conda_env_p = pkg_root / "environment.yml" + if not conda_env_p.exists(): + conda_env_p = conda_env_p.with_suffix(".yaml") - if conda_env.exists(): + if conda_env_p.exists(): click.echo( " ".join( [ - click.style(f"{conda_env.name}:", bold=True), + click.style(f"{conda_env_p.name}:", bold=True), "Conda dependencies installation phase", ] ) ) - with conda_env.open("rb") as f: + with conda_env_p.open("rb") as f: conda_env = yaml.safe_load(f) if "name" in conda_env: @@ -218,7 +218,7 @@ def infer_commands(pkg_root: Path) -> List[DockerCmdBlock]: DockerCmdBlock( comment="Build conda environment", commands=[ - f"copy {conda_env.name} /opt/latch/environment.yaml", + f"copy {conda_env_p.name} /opt/latch/environment.yaml", dedent(rf""" run mamba env create \ --file /opt/latch/environment.yaml \ From 939cfe4612068f096b0685ce1a71dfa6e1d54d1e Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 25 Jul 2023 14:38:34 -0700 Subject: [PATCH 134/356] pull kenny/snakekit Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 4 ++-- latch_cli/services/register/utils.py | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index bb12b859..62e81808 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -361,12 +361,12 @@ def generate_dockerfile( f.write("run apt-get update --yes && apt-get install --yes git\n") f.write( "run pip install" - " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" + " 'git+https://github.com/latchbio/latch.git@kenny/snakekit'\n" ) f.write("run pip uninstall --yes latch\n") f.write( "run echo 72 && pip install" - " 'git+https://github.com/latchbio/latch.git@maximsmol/snakekit-1'\n" + " 'git+https://github.com/latchbio/latch.git@kenny/snakekit'\n" ) f.write("# Copy workflow data (use .dockerignore to skip files)\n") diff --git a/latch_cli/services/register/utils.py b/latch_cli/services/register/utils.py index b739649f..876027af 100644 --- a/latch_cli/services/register/utils.py +++ b/latch_cli/services/register/utils.py @@ -1,10 +1,8 @@ import base64 -import collections import contextlib import importlib.util as iu import io import os -import sys import typing from collections.abc import Iterable from pathlib import Path From d1289969d670fe55aa5bf606fe693d29df640321 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 25 Jul 2023 14:51:31 -0700 Subject: [PATCH 135/356] ignore pyproject.toml that does not have build-system info Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 62e81808..c5273557 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -230,15 +230,27 @@ def infer_commands(pkg_root: Path) -> List[DockerCmdBlock]: ), ] - # from https://peps.python.org/pep-0518/ and https://peps.python.org/pep-0621/ - for f in [(pkg_root / "setup.py"), (pkg_root / "pyproject.toml")]: - if not f.exists(): - continue + has_setup_py = (pkg_root / "setup.py").exists() + + has_buildable_pyproject = False + try: + with (pkg_root / "pyproject.toml").open("r") as f: + for line in f: + if not line.startswith("[build-syste]"): + continue + has_buildable_pyproject = True + break + except FileNotFoundError: + ... + + # from https://peps.python.org/pep-0518/ and https://peps.python.org/pep-0621/ + if has_setup_py or has_buildable_pyproject: + cause = "setup.py" if has_setup_py else "pyproject.toml" click.echo( " ".join( [ - click.style(f"{f.name}:", bold=True), + click.style(f"{cause}:", bold=True), "Python package installation phase", ] ) From b94626574647903cc8ff653c8176a41ca7d5c891 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Wed, 26 Jul 2023 15:47:15 -0700 Subject: [PATCH 136/356] safe remove docker store --- latch_cli/services/register/utils.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/latch_cli/services/register/utils.py b/latch_cli/services/register/utils.py index 876027af..fe868b6a 100644 --- a/latch_cli/services/register/utils.py +++ b/latch_cli/services/register/utils.py @@ -3,12 +3,14 @@ import importlib.util as iu import io import os +import sys import typing from collections.abc import Iterable from pathlib import Path from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, TypedDict, Union import boto3 +import docker import requests from latch_sdk_config.latch import config @@ -55,7 +57,12 @@ def _docker_login(ctx: _CentromereCtx): store_name = auth.get_credential_store(ctx.dkr_repo) if store_name is not None: store = auth._get_store_instance(store_name) - store.erase(ctx.dkr_repo) + try: + store.erase(ctx.dkr_repo) + # To handle: "Credentials store docker-credential-osxkeychain exited + # with "The specified item could not be found in the keychain."" + except docker.credentials.errors.StoreError: + pass user, password = base64.b64decode(token).decode("utf-8").split(":") res = ctx.dkr_client.login( From f065cf2aec88a8ae55b4e5bd574c637a353e6f41 Mon Sep 17 00:00:00 2001 From: AidanAbd Date: Wed, 26 Jul 2023 17:04:19 -0700 Subject: [PATCH 137/356] fix: autogenerate docs again + add storage along side other resources --- docs/source/api/latch.rst | 1 - docs/source/api/latch_cli.rst | 1 - docs/source/api/latch_cli.services.cp.rst | 16 ++++++++++++++++ docs/source/api/latch_cli.services.rst | 16 ++++++++++++++++ docs/source/basics/defining_cloud_resources.md | 16 ++++++++-------- .../getting_started/authoring_your_workflow.md | 6 +++--- docs/source/index.md | 4 ++-- 7 files changed, 45 insertions(+), 15 deletions(-) diff --git a/docs/source/api/latch.rst b/docs/source/api/latch.rst index dd9d00d9..539fb368 100644 --- a/docs/source/api/latch.rst +++ b/docs/source/api/latch.rst @@ -8,7 +8,6 @@ Subpackages :maxdepth: 4 latch.functions - latch.gql latch.registry latch.resources latch.types diff --git a/docs/source/api/latch_cli.rst b/docs/source/api/latch_cli.rst index 89e56dee..28ba4a5d 100644 --- a/docs/source/api/latch_cli.rst +++ b/docs/source/api/latch_cli.rst @@ -9,7 +9,6 @@ Subpackages latch_cli.auth latch_cli.centromere - latch_cli.config latch_cli.docker_utils latch_cli.exceptions latch_cli.services diff --git a/docs/source/api/latch_cli.services.cp.rst b/docs/source/api/latch_cli.services.cp.rst index b33a1e70..3bebf686 100644 --- a/docs/source/api/latch_cli.services.cp.rst +++ b/docs/source/api/latch_cli.services.cp.rst @@ -4,6 +4,14 @@ latch\_cli.services.cp package Submodules ---------- +latch\_cli.services.cp.autocomplete module +------------------------------------------ + +.. automodule:: latch_cli.services.cp.autocomplete + :members: + :undoc-members: + :show-inheritance: + latch\_cli.services.cp.config module ------------------------------------ @@ -28,6 +36,14 @@ latch\_cli.services.cp.exceptions module :undoc-members: :show-inheritance: +latch\_cli.services.cp.glob module +---------------------------------- + +.. automodule:: latch_cli.services.cp.glob + :members: + :undoc-members: + :show-inheritance: + latch\_cli.services.cp.ldata\_utils module ------------------------------------------ diff --git a/docs/source/api/latch_cli.services.rst b/docs/source/api/latch_cli.services.rst index 1f6f7175..67bf264a 100644 --- a/docs/source/api/latch_cli.services.rst +++ b/docs/source/api/latch_cli.services.rst @@ -64,6 +64,14 @@ latch\_cli.services.local\_dev module :undoc-members: :show-inheritance: +latch\_cli.services.local\_dev\_old module +------------------------------------------ + +.. automodule:: latch_cli.services.local_dev_old + :members: + :undoc-members: + :show-inheritance: + latch\_cli.services.login module -------------------------------- @@ -104,6 +112,14 @@ latch\_cli.services.preview module :undoc-members: :show-inheritance: +latch\_cli.services.stop\_pod module +------------------------------------ + +.. automodule:: latch_cli.services.stop_pod + :members: + :undoc-members: + :show-inheritance: + latch\_cli.services.workspace module ------------------------------------ diff --git a/docs/source/basics/defining_cloud_resources.md b/docs/source/basics/defining_cloud_resources.md index bb7478c5..09409ee2 100644 --- a/docs/source/basics/defining_cloud_resources.md +++ b/docs/source/basics/defining_cloud_resources.md @@ -5,7 +5,7 @@ the task are provisioned automatically and managed for the user until task completion. Tasks can be annotated with the resources they are expected to consume (eg. CPU, -RAM, GPU) at runtime and these requests will be fullfilled during the scheduling +RAM, Storage, GPU) at runtime and these requests will be fullfilled during the scheduling process. --- @@ -15,11 +15,11 @@ process. The Latch SDK currently supports a set of prespecified task resource requests represented as decorators: -* `small_task`: 2 cpus, 4 gigs of memory, 0 gpus -* `medium_task`: 32 cpus, 128 gigs of memory, 0 gpus -* `large_task`: 96 cpus, 192 gig sof memory, 0 gpus -* `small_gpu_task`: 8 cpus, 32 gigs of memory, 1 gpu (24 gigs of VRAM, 9,216 cuda cores) -* `large_gpu_task`: 31 cpus, 120 gigs of memory, 1 gpu (24 gigs of VRAM, 9,216 cuda cores) +* `small_task`: 2 cpus, 4 gigs of memory, 500 GiB of storage, 0 gpus +* `medium_task`: 32 cpus, 128 gigs of memory, 2000 GiB of storage, 0 gpus +* `large_task`: 96 cpus, 192 gig sof memory, 5000 GiB of storage, 0 gpus +* `small_gpu_task`: 8 cpus, 32 gigs of memory, 2000 GiB of storage, 1 gpu (24 gigs of VRAM, 9,216 cuda cores) +* `large_gpu_task`: 31 cpus, 120 gigs of memory, 2000 GiB of storage, 1 gpu (24 gigs of VRAM, 9,216 cuda cores) We use the tasks as follows: @@ -41,11 +41,11 @@ def inference( ## Custom Task Resource -You can also arbitrarily specify task resources using `@custom_task`: +You can also specify task resources using `@custom_task`: ```python from latch import custom_task -@custom_task(cpu, memory) # cpu: int, memory: int +@custom_task(cpu, memory, storage_gib = storage_gib) # cpu: int, memory: int, storage_gib: int def my_task( ... ): diff --git a/docs/source/getting_started/authoring_your_workflow.md b/docs/source/getting_started/authoring_your_workflow.md index a34bc374..e6f81a99 100644 --- a/docs/source/getting_started/authoring_your_workflow.md +++ b/docs/source/getting_started/authoring_your_workflow.md @@ -107,13 +107,13 @@ Specifying compute and storage requirements is as easy as using a Python decorat ```python from latch import small_task -@small_task # 2 cpus, 4 gigs of memory, 0 gpus +@small_task # 2 cpus, 4 gigs of memory, 500 GiB of storage, 0 gpus def my_task( ... ): ... -@large_gpu_task #31 cpus, 120 gigs of memory, 1 gpu +@large_gpu_task #31 cpus, 120 gigs of memory, 2000 GiB of storage, 1 gpu def inference( ... ): @@ -126,7 +126,7 @@ To arbitrarily specify resource requirements, use: ```python from latch import custom_task -@custom_task(cpu, memory) +@custom_task(cpu, memory, storage_gib = storage_gib) def my_task( ... ): diff --git a/docs/source/index.md b/docs/source/index.md index be1ee2d9..1f3a0005 100644 --- a/docs/source/index.md +++ b/docs/source/index.md @@ -10,7 +10,7 @@ Bioinformatics workflows developed with the SDK automatically receive: * First class static typing * Containerization and versioning of every registered change * Reliable and scalable managed cloud infrastructure -* Single line definition of arbitrary resource requirements (eg. CPU, GPU) for serverless execution +* Single line definition of arbitrary resource requirements (eg. CPU, GPU, Storage) for serverless execution ![SDK Overview](./assets/sdk-intro.png) @@ -24,7 +24,7 @@ Lacth SDK allows developers to upload workflows to the full-featured [Latch Plat With Latch SDK, developers can write the description to their workflow and customize input parameters using plain Markdown. Latch automatically parses the written text and Python function headers to compile a type-safe UI. -**Specifying arbitrary cloud compute and storage resources for bioinformatics pipelines is difficult.** With Latch SDK, there are several Python task decorators that easily allow you to define the resources available at runtime. The framework starts at 2 CPUs and 4 GBs of memory and goes all the way to 31 CPUs, 120 GBs of memory and 1 GPU (24 GBs of VRAM, 9,216 CUDA cores) to easily handle all processing needs. +**Specifying arbitrary cloud compute and storage resources for bioinformatics pipelines is difficult.** With Latch SDK, there are several Python task decorators that easily allow you to define the resources available at runtime. The framework starts at 2 CPUs and 4 GBs of memory and goes all the way to 95 CPUs, 490 GBs of memory, 5TB of storage, and 1 GPU (24 GBs of VRAM, 9,216 CUDA cores) to easily handle all processing needs. **Bioinformatics tools face the challenges of irreproducibility.** The lack of proper versioning and dependencies management results in a long tail of poorly documented and unusable bioinformatics software tools. From 660cf88258e663f9068e7f9c0af2a727ba9db6de Mon Sep 17 00:00:00 2001 From: AidanAbd Date: Wed, 26 Jul 2023 17:21:40 -0700 Subject: [PATCH 138/356] fix: typo and add explanation --- docs/source/basics/defining_cloud_resources.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/docs/source/basics/defining_cloud_resources.md b/docs/source/basics/defining_cloud_resources.md index 09409ee2..8de53bc8 100644 --- a/docs/source/basics/defining_cloud_resources.md +++ b/docs/source/basics/defining_cloud_resources.md @@ -8,6 +8,21 @@ Tasks can be annotated with the resources they are expected to consume (eg. CPU, RAM, Storage, GPU) at runtime and these requests will be fullfilled during the scheduling process. +## CPU +The number of cpu cores available to the task. If your task uses more than the alotted +number of cores, the task can continue running but will be throttled. + +## Memory +The amount of memory available to the task. If your task uses more than the alotted +amount of memory, the task will crash. + +## Storage +The amount of disc space available to the task. If your task uses more than the alotted +amount of storage, the task will crash. + +## GPU +The number of GPUs available to the task. + --- ## Prespecified Task Resource @@ -17,7 +32,7 @@ represented as decorators: * `small_task`: 2 cpus, 4 gigs of memory, 500 GiB of storage, 0 gpus * `medium_task`: 32 cpus, 128 gigs of memory, 2000 GiB of storage, 0 gpus -* `large_task`: 96 cpus, 192 gig sof memory, 5000 GiB of storage, 0 gpus +* `large_task`: 96 cpus, 192 gigs of memory, 5000 GiB of storage, 0 gpus * `small_gpu_task`: 8 cpus, 32 gigs of memory, 2000 GiB of storage, 1 gpu (24 gigs of VRAM, 9,216 cuda cores) * `large_gpu_task`: 31 cpus, 120 gigs of memory, 2000 GiB of storage, 1 gpu (24 gigs of VRAM, 9,216 cuda cores) From ba20d04fd7151191d83070dc2d0d39caa89b3c60 Mon Sep 17 00:00:00 2001 From: AidanAbd Date: Wed, 26 Jul 2023 17:25:08 -0700 Subject: [PATCH 139/356] fix: typos --- docs/source/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/index.md b/docs/source/index.md index 1f3a0005..75252651 100644 --- a/docs/source/index.md +++ b/docs/source/index.md @@ -24,7 +24,7 @@ Lacth SDK allows developers to upload workflows to the full-featured [Latch Plat With Latch SDK, developers can write the description to their workflow and customize input parameters using plain Markdown. Latch automatically parses the written text and Python function headers to compile a type-safe UI. -**Specifying arbitrary cloud compute and storage resources for bioinformatics pipelines is difficult.** With Latch SDK, there are several Python task decorators that easily allow you to define the resources available at runtime. The framework starts at 2 CPUs and 4 GBs of memory and goes all the way to 95 CPUs, 490 GBs of memory, 5TB of storage, and 1 GPU (24 GBs of VRAM, 9,216 CUDA cores) to easily handle all processing needs. +**Specifying arbitrary cloud compute and storage resources for bioinformatics pipelines is difficult.** With the Latch SDK, there are several Python task decorators that easily allow you to define the resources available at runtime. The framework starts at 2 CPUs and 4 GiBs of memory and goes all the way to 95 CPUs, 490 GBs of memory, 4949 GiB of storage, and 1 GPU (24 GBs of VRAM, 9,216 CUDA cores) to easily handle all processing needs. **Bioinformatics tools face the challenges of irreproducibility.** The lack of proper versioning and dependencies management results in a long tail of poorly documented and unusable bioinformatics software tools. From 4a0bc04c95bc7ec2f2710918b26031285b96e648 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Sat, 29 Jul 2023 11:13:36 -0700 Subject: [PATCH 140/356] use job iop instead of rule iop Signed-off-by: maximsmol --- latch_cli/snakemake/workflow.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index cf923f60..11e440d3 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1083,12 +1083,10 @@ def get_fn_code( } for job in jobs: - rule = job.rule - snakemake_data["rules"][job.rule.name] = { - "inputs": named_list_to_json(job.rule.input), - "outputs": named_list_to_json(job.rule.output), - "params": named_list_to_json(job.rule.params), + "inputs": named_list_to_json(job.input), + "outputs": named_list_to_json(job.output), + "params": named_list_to_json(job.params), } if remote_output_url is None: From 0908621704f9a85ca5b73d6c6287bc8102eedfeb Mon Sep 17 00:00:00 2001 From: maximsmol Date: Sat, 29 Jul 2023 12:04:35 -0700 Subject: [PATCH 141/356] fix launching workflows with no inputs Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index c5273557..27721828 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -377,7 +377,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 72 && pip install" + "run echo 73 && pip install" " 'git+https://github.com/latchbio/latch.git@kenny/snakekit'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 11e440d3..ce6e7ae8 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -546,7 +546,7 @@ class _WorkflowInfoNode(TypedDict): lp.upload(file.local_path, file.remote_path) wf_id = nodes[0]["id"] - params = json.loads(gpjson.MessageToJson(wf.literal_map.to_flyte_idl()))["literals"] + params = gpjson.MessageToDict(wf.literal_map.to_flyte_idl()).get("literals", {}) _interface_request = { "workflow_id": wf_id, From 8c84397759b8920fbadc8f09c27010cb1770d1bb Mon Sep 17 00:00:00 2001 From: maximsmol Date: Sat, 29 Jul 2023 17:04:30 -0700 Subject: [PATCH 142/356] replace benchmark and log with pre-computed values too Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/single_task_snakemake.py | 14 ++++++++++++++ latch_cli/snakemake/workflow.py | 2 ++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 27721828..f98e0acc 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -377,7 +377,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 73 && pip install" + "run echo 75 && pip install" " 'git+https://github.com/latchbio/latch.git@kenny/snakekit'\n" ) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index eabdc112..02b70adc 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -10,7 +10,9 @@ from snakemake.io import AnnotatedString from snakemake.parser import ( INDENT, + Benchmark, Input, + Log, Output, Params, Rule, @@ -59,6 +61,12 @@ def eprint_named_list(xs): eprint(" Params:") eprint_named_list(rule_data["params"]) + eprint(" Benchmark:") + eprint_named_list(rule_data["benchmark"]) + + eprint(" Log:") + eprint_named_list(rule_data["log"]) + eprint("\nExpected outputs:") for x in outputs: eprint(repr(x)) @@ -125,6 +133,10 @@ def emit_overrides(self, token): xs = cur_data["outputs"] elif isinstance(self, Params): xs = cur_data["params"] + elif isinstance(self, Benchmark): + xs = {"positional": cur_data["benchmark"]} + elif isinstance(self, Log): + xs = {"positional": cur_data["log"]} else: raise ValueError(f"tried to emit overrides for unknown state: {type(self)}") @@ -192,6 +204,8 @@ def skip_block(self, token, force_block_end=False): Input.block = skip_block Output.block = skip_block Params.block = skip_block +Benchmark.block = skip_block +Log.block = skip_block # Run snakemake snakemake.main() diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index ce6e7ae8..da66ce50 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1087,6 +1087,8 @@ def get_fn_code( "inputs": named_list_to_json(job.input), "outputs": named_list_to_json(job.output), "params": named_list_to_json(job.params), + "benchmark": job.benchmark, + "log": job.log, } if remote_output_url is None: From 5992acaaa2f46008543b1958e79ddd27fd3de693 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Sat, 29 Jul 2023 17:09:12 -0700 Subject: [PATCH 143/356] oops Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/single_task_snakemake.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index f98e0acc..5e38f10c 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -377,7 +377,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 75 && pip install" + "run echo 76 && pip install" " 'git+https://github.com/latchbio/latch.git@kenny/snakekit'\n" ) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 02b70adc..eebc2e5a 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -62,10 +62,10 @@ def eprint_named_list(xs): eprint_named_list(rule_data["params"]) eprint(" Benchmark:") - eprint_named_list(rule_data["benchmark"]) + eprint(f" {rule_data['benchmark']}") eprint(" Log:") - eprint_named_list(rule_data["log"]) + eprint(f" {rule_data['log']}") eprint("\nExpected outputs:") for x in outputs: From 9df37cc7c94ec5ff9ed6d83500fb1fb0f3202ef9 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 31 Jul 2023 09:34:17 -0700 Subject: [PATCH 144/356] fix oopsie Signed-off-by: maximsmol --- latch_cli/snakemake/single_task_snakemake.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index eebc2e5a..d968ea72 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -134,9 +134,9 @@ def emit_overrides(self, token): elif isinstance(self, Params): xs = cur_data["params"] elif isinstance(self, Benchmark): - xs = {"positional": cur_data["benchmark"]} + xs = {"positional": cur_data["benchmark"], "keyword": {}} elif isinstance(self, Log): - xs = {"positional": cur_data["log"]} + xs = {"positional": cur_data["log"], "keyword": {}} else: raise ValueError(f"tried to emit overrides for unknown state: {type(self)}") From 62084cd11bfa5fd0aeabe43cec1071858c284635 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 31 Jul 2023 09:38:31 -0700 Subject: [PATCH 145/356] oopsie 2 Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/single_task_snakemake.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 5e38f10c..0ac21caf 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -377,7 +377,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 76 && pip install" + "run echo 77 && pip install" " 'git+https://github.com/latchbio/latch.git@kenny/snakekit'\n" ) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index d968ea72..72c5a6e1 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -134,9 +134,9 @@ def emit_overrides(self, token): elif isinstance(self, Params): xs = cur_data["params"] elif isinstance(self, Benchmark): - xs = {"positional": cur_data["benchmark"], "keyword": {}} + xs = {"positional": [cur_data["benchmark"]], "keyword": {}} elif isinstance(self, Log): - xs = {"positional": cur_data["log"], "keyword": {}} + xs = {"positional": [cur_data["log"]], "keyword": {}} else: raise ValueError(f"tried to emit overrides for unknown state: {type(self)}") From c3aa0783821f5cc018ee9e61b8b413540b3fd6cd Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 31 Jul 2023 09:48:18 -0700 Subject: [PATCH 146/356] add debug logs Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/single_task_snakemake.py | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 0ac21caf..6f26c4a4 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -377,7 +377,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 77 && pip install" + "run echo 78 && pip install" " 'git+https://github.com/latchbio/latch.git@kenny/snakekit'\n" ) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 72c5a6e1..3ca96ba0 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -126,6 +126,7 @@ def render_annotated_str_list(xs) -> str: def emit_overrides(self, token): cur_data = rules[self.rulename] + eprint(f"\nOverriding {self.rulename} {self.__class__.__name__}") if isinstance(self, Input): xs = cur_data["inputs"] @@ -147,6 +148,8 @@ def emit_overrides(self, token): data = chain(positional_data, keyword_data) for x in data: + eprint(f" {x}") + yield x, token yield ",", token yield "\n", token From 4ae74e108e6203c6f283b8477384b6c194bef9ce Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 31 Jul 2023 09:54:16 -0700 Subject: [PATCH 147/356] fix benchmark override Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/single_task_snakemake.py | 29 ++++++++++++-------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 6f26c4a4..c3955346 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -377,7 +377,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 78 && pip install" + "run echo 79 && pip install" " 'git+https://github.com/latchbio/latch.git@kenny/snakekit'\n" ) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 3ca96ba0..92dab641 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -161,8 +161,7 @@ def emit_overrides(self, token): emitted_overrides_per_type: dict[str, set[str]] = {} -# Skip @workflow.input and @workflow.output for non-target tasks -def skip_block(self, token, force_block_end=False): +def replace_block(self, token, force_block_end=False): if self.lasttoken == "\n" and is_comment(token): # ignore lines containing only comments self.line -= 1 @@ -190,11 +189,17 @@ def skip_block(self, token, force_block_end=False): type(self).__name__, set() ) - if ( - self.rulename in rules - and self.rulename not in emitted_overrides - ): - yield from emit_overrides(self, token) + if self.rulename not in emitted_overrides: + if self.rulename in rules: + yield from emit_overrides(self, token) + elif isinstance(self, Benchmark): + # benchmark can't have no arguments + # todo(maximsmol): do this by disabling the decorator entirely + yield repr(""), token + yield ",", token + yield "\n", token + yield INDENT * self.base_indent, token + emitted_overrides.add(self.rulename) yield "#", token @@ -204,11 +209,11 @@ def skip_block(self, token, force_block_end=False): yield from self.block_content(token) -Input.block = skip_block -Output.block = skip_block -Params.block = skip_block -Benchmark.block = skip_block -Log.block = skip_block +Input.block = replace_block +Output.block = replace_block +Params.block = replace_block +Benchmark.block = replace_block +Log.block = replace_block # Run snakemake snakemake.main() From 5e133e12614f387797d3cfc27a02fcf01d5680a3 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 31 Jul 2023 10:23:47 -0700 Subject: [PATCH 148/356] try a nuclear rule skipper Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/single_task_snakemake.py | 42 +++++++++++++++----- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index c3955346..406b5f2f 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -377,7 +377,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 79 && pip install" + "run echo 80 && pip install" " 'git+https://github.com/latchbio/latch.git@kenny/snakekit'\n" ) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 92dab641..71ae5a62 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -15,6 +15,7 @@ Log, Output, Params, + Python, Rule, StopAutomaton, is_comment, @@ -189,17 +190,11 @@ def replace_block(self, token, force_block_end=False): type(self).__name__, set() ) - if self.rulename not in emitted_overrides: - if self.rulename in rules: - yield from emit_overrides(self, token) - elif isinstance(self, Benchmark): - # benchmark can't have no arguments - # todo(maximsmol): do this by disabling the decorator entirely - yield repr(""), token - yield ",", token - yield "\n", token - yield INDENT * self.base_indent, token - + if ( + self.rulename in rules + and self.rulename not in emitted_overrides + ): + yield from emit_overrides(self, token) emitted_overrides.add(self.rulename) yield "#", token @@ -215,5 +210,30 @@ def replace_block(self, token, force_block_end=False): Benchmark.block = replace_block Log.block = replace_block + +class SkippingRule(Rule): + def start(self, aux=""): + if self.rulename not in rules: + yield "#" + return super().start(aux) + + def end(self): + if self.rulename not in rules: + yield "#" + + return super().end() + + def block_content(self, token): + if self.rulename in rules: + return super().block_content(token) + + for t in super().block_content(token): + yield t + if is_newline(t): + yield "#" + + +Python.subautomata["rule"] = SkippingRule + # Run snakemake snakemake.main() From 4f7ab060c6541c8af3a81e935b481dcf8c9f17dd Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 31 Jul 2023 10:38:54 -0700 Subject: [PATCH 149/356] oopsie Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/single_task_snakemake.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 406b5f2f..fb52494e 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -377,7 +377,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 80 && pip install" + "run echo 81 && pip install" " 'git+https://github.com/latchbio/latch.git@kenny/snakekit'\n" ) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 71ae5a62..0c5d784b 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -229,8 +229,8 @@ def block_content(self, token): for t in super().block_content(token): yield t - if is_newline(t): - yield "#" + if t[0] == "\n": + yield "#", token Python.subautomata["rule"] = SkippingRule From d80c7dd901ea7fc501bd0f9bf3e22d52a3a50d32 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 31 Jul 2023 11:15:14 -0700 Subject: [PATCH 150/356] try commenting-out every line in a token Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/single_task_snakemake.py | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index fb52494e..1dbf917c 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -377,7 +377,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 81 && pip install" + "run echo 82 && pip install" " 'git+https://github.com/latchbio/latch.git@kenny/snakekit'\n" ) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 0c5d784b..d21da97f 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -228,9 +228,7 @@ def block_content(self, token): return super().block_content(token) for t in super().block_content(token): - yield t - if t[0] == "\n": - yield "#", token + yield t.replace("\n", "\n#") Python.subautomata["rule"] = SkippingRule From 8eb6acb3088991acf5fde7012e1d2c9abc757c6d Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 31 Jul 2023 11:15:25 -0700 Subject: [PATCH 151/356] try commenting-out every line in a token Signed-off-by: maximsmol --- latch_cli/snakemake/single_task_snakemake.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index d21da97f..46e8227d 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -228,7 +228,7 @@ def block_content(self, token): return super().block_content(token) for t in super().block_content(token): - yield t.replace("\n", "\n#") + yield t.replace("\n", "\n# ") Python.subautomata["rule"] = SkippingRule From 60836cc2fc458c732721b80b1a94b61766fa9911 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 31 Jul 2023 11:52:24 -0700 Subject: [PATCH 152/356] bruh Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/single_task_snakemake.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 1dbf917c..790489fa 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -377,7 +377,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 82 && pip install" + "run echo 83 && pip install" " 'git+https://github.com/latchbio/latch.git@kenny/snakekit'\n" ) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 46e8227d..b7fe6f66 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -228,7 +228,7 @@ def block_content(self, token): return super().block_content(token) for t in super().block_content(token): - yield t.replace("\n", "\n# ") + yield t[0].replace("\n", "\n# "), t[1] Python.subautomata["rule"] = SkippingRule From 8f74702f44eac909c1f1a3a6fe6060c38a881b39 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 31 Jul 2023 14:33:23 -0700 Subject: [PATCH 153/356] use unexpanded output defs so we preserve wildcards Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/single_task_snakemake.py | 2 -- latch_cli/snakemake/workflow.py | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 790489fa..9be86842 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -377,7 +377,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 83 && pip install" + "run echo 85 && pip install" " 'git+https://github.com/latchbio/latch.git@kenny/snakekit'\n" ) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index b7fe6f66..f2acde10 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -4,10 +4,8 @@ import traceback from itertools import chain from textwrap import dedent -from typing import Union import snakemake -from snakemake.io import AnnotatedString from snakemake.parser import ( INDENT, Benchmark, diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index da66ce50..861fba7e 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1085,7 +1085,7 @@ def get_fn_code( for job in jobs: snakemake_data["rules"][job.rule.name] = { "inputs": named_list_to_json(job.input), - "outputs": named_list_to_json(job.output), + "outputs": named_list_to_json(job.rule.output), "params": named_list_to_json(job.params), "benchmark": job.benchmark, "log": job.log, From 168724fabea18f9678a8529e56ebd7a6eb29f8d6 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 1 Aug 2023 10:41:31 -0700 Subject: [PATCH 154/356] override shellcmd with expanded version Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/single_task_snakemake.py | 15 +++++++++++++++ latch_cli/snakemake/workflow.py | 5 +++-- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 9be86842..23a77cc9 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -377,7 +377,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 85 && pip install" + "run echo 86 && pip install" " 'git+https://github.com/latchbio/latch.git@kenny/snakekit'\n" ) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index f2acde10..82975e55 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -15,6 +15,7 @@ Params, Python, Rule, + Shell, StopAutomaton, is_comment, is_dedent, @@ -66,6 +67,9 @@ def eprint_named_list(xs): eprint(" Log:") eprint(f" {rule_data['log']}") + eprint(" Shellcmd:") + eprint(f" {rule_data['shellcmd']}") + eprint("\nExpected outputs:") for x in outputs: eprint(repr(x)) @@ -231,5 +235,16 @@ def block_content(self, token): Python.subautomata["rule"] = SkippingRule + +class ReplacingShell(Shell): + def __init__(self, snakefile, rulename, base_indent=0, dedent=0, root=True): + if self.rulename in rules: + self.overwrite_cmd = rules[self.rulename]["shellcmd"] + + super().__init__(snakefile, rulename, base_indent, dedent, root) + + +SkippingRule.subautomata["shell"] = ReplacingShell + # Run snakemake snakemake.main() diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 861fba7e..20362d3d 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1046,7 +1046,7 @@ def get_fn_code( 1, ) - jobs = [self.job] + jobs: List[Job] = [self.job] if isinstance(self.job, GroupJob): jobs = self.job.jobs @@ -1085,10 +1085,11 @@ def get_fn_code( for job in jobs: snakemake_data["rules"][job.rule.name] = { "inputs": named_list_to_json(job.input), - "outputs": named_list_to_json(job.rule.output), + "outputs": named_list_to_json(job.output), "params": named_list_to_json(job.params), "benchmark": job.benchmark, "log": job.log, + "shellcmd": job.shellcmd, } if remote_output_url is None: From b58b1a8279133780713f68cd5b1679d3567d1af4 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 1 Aug 2023 10:51:40 -0700 Subject: [PATCH 155/356] oopsie Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/single_task_snakemake.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 23a77cc9..60458008 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -377,7 +377,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 86 && pip install" + "run echo 87 && pip install" " 'git+https://github.com/latchbio/latch.git@kenny/snakekit'\n" ) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 82975e55..b691e356 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -238,8 +238,8 @@ def block_content(self, token): class ReplacingShell(Shell): def __init__(self, snakefile, rulename, base_indent=0, dedent=0, root=True): - if self.rulename in rules: - self.overwrite_cmd = rules[self.rulename]["shellcmd"] + if rulename in rules: + self.overwrite_cmd = rules[rulename]["shellcmd"] super().__init__(snakefile, rulename, base_indent, dedent, root) From 54117749b074f4c051ffdee810d717a95db29716 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 1 Aug 2023 11:06:34 -0700 Subject: [PATCH 156/356] escape formatting chars Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/single_task_snakemake.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 60458008..2b064acd 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -377,7 +377,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 87 && pip install" + "run echo 88 && pip install" " 'git+https://github.com/latchbio/latch.git@kenny/snakekit'\n" ) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index b691e356..8fbc609c 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -239,7 +239,8 @@ def block_content(self, token): class ReplacingShell(Shell): def __init__(self, snakefile, rulename, base_indent=0, dedent=0, root=True): if rulename in rules: - self.overwrite_cmd = rules[rulename]["shellcmd"] + cmd: str = rules[rulename]["shellcmd"] + self.overwrite_cmd = cmd.replace("{", "{{").replace("}", "}}") super().__init__(snakefile, rulename, base_indent, dedent, root) From 6a5b4e832a8aaed350b03c486f6d58a63a438fb3 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 1 Aug 2023 13:04:19 -0700 Subject: [PATCH 157/356] use conda Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 2b064acd..046100d7 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -377,7 +377,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 88 && pip install" + "run echo 89 && pip install" " 'git+https://github.com/latchbio/latch.git@kenny/snakekit'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 20362d3d..595660fd 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1055,6 +1055,7 @@ def get_fn_code( "latch_cli.snakemake.single_task_snakemake", "-s", snakefile_path_in_container, + "--use-conda", "--target-jobs", *jobs_cli_args(jobs), "--allowed-rules", From ffb9e9ef8ce27c808121ad8b55f7b312825f6b16 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 1 Aug 2023 13:23:02 -0700 Subject: [PATCH 158/356] redo skippingrule Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/single_task_snakemake.py | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 046100d7..a39bec97 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -377,7 +377,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 89 && pip install" + "run echo 90 && pip install" " 'git+https://github.com/latchbio/latch.git@kenny/snakekit'\n" ) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 8fbc609c..a4be5617 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -215,19 +215,19 @@ def replace_block(self, token, force_block_end=False): class SkippingRule(Rule): def start(self, aux=""): - if self.rulename not in rules: - yield "#" - return super().start(aux) + yield "#" + for t in super().start(aux): + yield t.replace("\n", "\n# ") def end(self): - if self.rulename not in rules: - yield "#" - - return super().end() + yield "#" + for t in super().end(): + yield t.replace("\n", "\n# ") def block_content(self, token): if self.rulename in rules: - return super().block_content(token) + yield from super().block_content(token) + return for t in super().block_content(token): yield t[0].replace("\n", "\n# "), t[1] From 7781dbc18ef5ec21b558a3747f830d1988e0f53b Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 1 Aug 2023 13:33:49 -0700 Subject: [PATCH 159/356] fix checkpoint Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/single_task_snakemake.py | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index a39bec97..179f0f90 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -377,7 +377,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 90 && pip install" + "run echo 91 && pip install" " 'git+https://github.com/latchbio/latch.git@kenny/snakekit'\n" ) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index a4be5617..41124057 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -215,11 +215,19 @@ def replace_block(self, token, force_block_end=False): class SkippingRule(Rule): def start(self, aux=""): + if self.rulename in rules: + yield from super().start(aux) + return + yield "#" for t in super().start(aux): yield t.replace("\n", "\n# ") def end(self): + if self.rulename in rules: + yield from super().end() + return + yield "#" for t in super().end(): yield t.replace("\n", "\n# ") @@ -233,7 +241,13 @@ def block_content(self, token): yield t[0].replace("\n", "\n# "), t[1] +class SkippingCheckpoint(SkippingRule): + def start(self): + yield from super().start(aux=", checkpoint=True") + + Python.subautomata["rule"] = SkippingRule +Python.subautomata["checkpoint"] = SkippingCheckpoint class ReplacingShell(Shell): From c700d57807eb9b863dd38fe428a09afde0083698 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Wed, 2 Aug 2023 10:31:33 -0700 Subject: [PATCH 160/356] support latchdir Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 40 ++++++++++++++++-------------- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 179f0f90..8aa2d26b 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -377,7 +377,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 91 && pip install" + "run echo 94 && pip install" " 'git+https://github.com/latchbio/latch.git@kenny/snakekit'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 595660fd..c33b6ca3 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1022,29 +1022,31 @@ def get_fn_code( code_block += self.get_fn_interface() for param, t in self._python_inputs.items(): - if t == LatchFile: - code_block += reindent( - rf""" - {param}_dst_p = Path("{self._target_file_for_input_param[param]}") + if not issubclass(t, (LatchFile, LatchDir)): + continue - print(f"Downloading {param}: {{{param}.remote_path}}") - {param}_p = Path({param}).resolve() - print(f" {{file_name_and_size({param}_p)}}") + code_block += reindent( + rf""" + {param}_dst_p = Path("{self._target_file_for_input_param[param]}") - """, - 1, - ) + print(f"Downloading {param}: {{{param}.remote_path}}") + {param}_p = Path({param}).resolve() + print(f" {{file_name_and_size({param}_p)}}") - code_block += reindent( - rf""" - print(f"Moving {param} to {{{param}_dst_p}}") - check_exists_and_rename( - {param}_p, - {param}_dst_p - ) - """, - 1, + """, + 1, + ) + + code_block += reindent( + rf""" + print(f"Moving {param} to {{{param}_dst_p}}") + check_exists_and_rename( + {param}_p, + {param}_dst_p ) + """, + 1, + ) jobs: List[Job] = [self.job] if isinstance(self.job, GroupJob): From 0abe10adbcb90c0ceee3a32498bc8d06a84424c8 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Wed, 2 Aug 2023 11:47:54 -0700 Subject: [PATCH 161/356] always print dir listing Signed-off-by: maximsmol --- latch_cli/snakemake/workflow.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index c33b6ca3..a14148ce 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1192,8 +1192,8 @@ def get_fn_code( else: print(" Does not exist") - except CalledProcessError: - ignored_paths = {{".cache"}} + finally: + ignored_paths = {{".cache", ".snakemake/conda/"}} ignored_names = {{".git", ".latch", "__pycache__"}} print("Recursive directory listing:") @@ -1210,8 +1210,6 @@ def get_fn_code( for x in cur.iterdir(): stack.append((x, indent + 1)) - sys.exit(1) - """, 1, ) From e373d3fee1d03165dc66a1a9b5c1741858fe09de Mon Sep 17 00:00:00 2001 From: maximsmol Date: Thu, 3 Aug 2023 10:27:15 -0700 Subject: [PATCH 162/356] resolve some weird diffs Signed-off-by: maximsmol --- latch/types/metadata.py | 25 +++++++++++++++++++------ latch_cli/centromere/ctx.py | 15 ++++++++++----- latch_cli/centromere/utils.py | 7 ------- latch_cli/docker_utils/__init__.py | 19 ++++--------------- 4 files changed, 33 insertions(+), 33 deletions(-) diff --git a/latch/types/metadata.py b/latch/types/metadata.py index ab88da2e..c6531c23 100644 --- a/latch/types/metadata.py +++ b/latch/types/metadata.py @@ -7,9 +7,10 @@ import yaml -from latch.types.directory import LatchDir -from latch.types.file import LatchFile -from latch_cli.utils import identifier_from_str, identifier_suffix_from_str +from latch_cli.utils import identifier_suffix_from_str + +from .directory import LatchDir +from .file import LatchFile @dataclass @@ -128,8 +129,6 @@ class Section(FlowBase): display_name="Paired-end reads", description="FASTQ files", batch_table_column=True, - ), - batch_table_column=True, ), "single_end": LatchParameter( display_name="Single-end reads", @@ -356,6 +355,20 @@ class LatchMetadata: ```python from latch.types import LatchMetadata, LatchAuthor, LatchRule, LatchAppearanceType + metadata = LatchMetadata( + parameters={ + "read1": LatchParameter( + display_name="Read 1", + description="Paired-end read 1 file to be assembled.", + hidden=True, + section_title="Sample Reads", + placeholder="Select a file", + comment="This is a comment", + output=False, + appearance_type=LatchAppearanceType.paragraph, + rules=[ + LatchRule( + regex="(.fasta|.fa|.faa|.fas)$", message="Only .fasta, .fa, .fas, or .faa extensions are valid" ) ], @@ -381,7 +394,7 @@ def wf(read1: LatchFile): """ display_name: str - """The display name of the workflow""" + """The human-readable name of the workflow""" author: LatchAuthor """ A `LatchAuthor` object that describes the author of the workflow""" documentation: Optional[str] = None diff --git a/latch_cli/centromere/ctx.py b/latch_cli/centromere/ctx.py index 545f0e52..ee8f31a6 100644 --- a/latch_cli/centromere/ctx.py +++ b/latch_cli/centromere/ctx.py @@ -88,11 +88,11 @@ def __init__( snakefile: Optional[Path] = None, use_new_centromere: bool = False, ): - with self: - self.use_new_centromere = use_new_centromere - self.remote = remote - self.disable_auto_version = disable_auto_version + self.use_new_centromere = use_new_centromere + self.remote = remote + self.disable_auto_version = disable_auto_version + try: self.token = retrieve_or_login() self.account_id = current_workspace() @@ -192,7 +192,9 @@ def __init__( raise ValueError(f"Version {self.version} has already been registered.") self.default_container = _Container( - dockerfile=get_default_dockerfile(self.pkg_root, self.workflow_type), + dockerfile=get_default_dockerfile( + self.pkg_root, wf_type=self.workflow_type + ), image_name=self.image_tagged, pkg_dir=self.pkg_root, ) @@ -235,6 +237,9 @@ def _patched_create_paramiko_client(self, base_url): else: self.dkr_client = _construct_dkr_client() + except (Exception, KeyboardInterrupt) as e: + self.cleanup() + raise e @property def image(self): diff --git a/latch_cli/centromere/utils.py b/latch_cli/centromere/utils.py index 7cb1986f..f3e7f6cb 100644 --- a/latch_cli/centromere/utils.py +++ b/latch_cli/centromere/utils.py @@ -232,7 +232,6 @@ def _construct_ssh_client( class MaybeRemoteDir: - """A temporary directory that exists locally or on a remote machine.""" def __init__(self, ssh_client: Optional[paramiko.SSHClient] = None): @@ -271,9 +270,3 @@ def build_random_string(k: int = 8) -> str: string.ascii_uppercase + string.ascii_lowercase + string.digits, k=k ) ) - - -def is_snakemake_project(pkg_root: Path) -> bool: - if pkg_root.joinpath("Snakefile").exists() and not pkg_root.joinpath("wf").exists(): - return True - return False diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index f7803334..cdd59e8c 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -312,7 +312,7 @@ def infer_commands(pkg_root: Path) -> List[DockerCmdBlock]: def generate_dockerfile( - pkg_root: Path, outfile: Path, wf_type: WorkflowType = WorkflowType.latchbiosdk + pkg_root: Path, outfile: Path, *, wf_type: WorkflowType = WorkflowType.latchbiosdk ) -> None: """Generate a best effort Dockerfile from files in the workflow directory. @@ -323,7 +323,7 @@ def generate_dockerfile( Example: - >>> generate_dockerfile(Path("test-workflow"), Path("test-workflow/Dockerfile"), WorkflowType.latchbiosdk) + >>> generate_dockerfile(Path("test-workflow"), Path("test-workflow/Dockerfile")) # The resulting file structure will look like # test-workflow # ├── Dockerfile @@ -370,17 +370,6 @@ def generate_dockerfile( block.write_block(f) - f.write("run apt-get update --yes && apt-get install --yes git\n") - f.write( - "run pip install" - " 'git+https://github.com/latchbio/latch.git@kenny/snakekit'\n" - ) - f.write("run pip uninstall --yes latch\n") - f.write( - "run echo 95 && pip install" - " 'git+https://github.com/latchbio/latch.git@kenny/snakekit'\n" - ) - f.write("# Copy workflow data (use .dockerignore to skip files)\n") f.write("copy . /root/\n\n") @@ -393,11 +382,11 @@ def generate_dockerfile( f.write("\n".join(get_epilogue(wf_type)) + "\n") -def get_default_dockerfile(pkg_root: Path, wf_type: WorkflowType): +def get_default_dockerfile(pkg_root: Path, *, wf_type: WorkflowType): default_dockerfile = pkg_root / "Dockerfile" if not default_dockerfile.exists(): default_dockerfile = pkg_root / ".latch" / "Dockerfile" - generate_dockerfile(pkg_root, default_dockerfile, wf_type) + generate_dockerfile(pkg_root, default_dockerfile, wf_type=wf_type) return default_dockerfile From ef90943c47782436a4a822b8b6edfe7c2c8e05e0 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Thu, 3 Aug 2023 10:42:19 -0700 Subject: [PATCH 163/356] diff fixes Signed-off-by: maximsmol --- latch/types/metadata.py | 4 ++-- latch_cli/main.py | 18 ++++++++++-------- latch_cli/utils/__init__.py | 2 +- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/latch/types/metadata.py b/latch/types/metadata.py index c6531c23..ca974a3d 100644 --- a/latch/types/metadata.py +++ b/latch/types/metadata.py @@ -3,7 +3,7 @@ from enum import Enum from pathlib import Path from textwrap import indent -from typing import Dict, List, Optional, Tuple, Union +from typing import Dict, List, Optional, Tuple, Type, Union import yaml @@ -336,7 +336,7 @@ def dict(self): @dataclass class SnakemakeFileParameter(LatchParameter): - type: Optional[Union[LatchFile, LatchDir]] = None + type: Optional[Union[Type[LatchFile], Type[LatchDir]]] = None """ The python type of the parameter. """ diff --git a/latch_cli/main.py b/latch_cli/main.py index 93ef4bb6..3d319126 100644 --- a/latch_cli/main.py +++ b/latch_cli/main.py @@ -1,6 +1,7 @@ """Entrypoints to service functions through a latch_cli.""" import os +import sys import textwrap from collections import OrderedDict from pathlib import Path @@ -96,13 +97,13 @@ def dockerfile(pkg_root: str): help="Use a remote server to build workflow.", ) @click.option( - "--progress-plain", - is_flag=True, - default=False, - type=bool, + "--docker-progress", + type=click.Choice(["plain", "tty", "auto"], case_sensitive=False), + default="auto", help=( - "No special Docker build log handling. Equivalent to `docker build" - " --progress=plain`." + "`tty` shows only the last N lines of the build log. `plain` does no special" + " handling. `auto` chooses `tty` when stdout is a terminal and `plain`" + " otherwise. Equivalent to Docker's `--progress` flag." ), ) @click.option( @@ -123,7 +124,7 @@ def register( pkg_root: str, disable_auto_version: bool, remote: bool, - progress_plain: bool, + docker_progress: str, yes: bool, snakefile: Optional[Path], ): @@ -145,7 +146,8 @@ def register( remote=remote, skip_confirmation=yes, snakefile=snakefile, - progress_plain=progress_plain, + progress_plain=(docker_progress == "auto" and sys.stdout.isatty()) + or docker_progress == "plain", use_new_centromere=use_new_centromere, ) diff --git a/latch_cli/utils/__init__.py b/latch_cli/utils/__init__.py index 5423aa58..7544fd35 100644 --- a/latch_cli/utils/__init__.py +++ b/latch_cli/utils/__init__.py @@ -328,7 +328,7 @@ def cleanup(self): and self._ssh_key_path.with_suffix(".pub").exists() ): subprocess.run( - ["ssh-agent", "ssh-add", "-d", self._ssh_key_path], + ["ssh-add", "-d", self._ssh_key_path], check=True, capture_output=True, ) From e444b4ccb6b762b1ca79c73a3ded9ee380e6108d Mon Sep 17 00:00:00 2001 From: maximsmol Date: Thu, 3 Aug 2023 10:53:53 -0700 Subject: [PATCH 164/356] finishing touches Signed-off-by: maximsmol --- latch_cli/snakemake/serialize.py | 2 +- latch_cli/snakemake/single_task_snakemake.py | 3 +- latch_cli/snakemake/workflow.py | 38 ++++++++++++-------- pyproject.toml | 7 ++-- setup.py | 2 +- 5 files changed, 33 insertions(+), 19 deletions(-) diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index 834f7e53..c159c317 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -99,7 +99,7 @@ def extract_dag(self): self._rules[x] for x in targets if self.is_rule(x) ) - target_files: set[str] = set() + target_files: Set[str] = set() for f in targets: if self.is_rule(f): continue diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 41124057..5916509e 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -4,6 +4,7 @@ import traceback from itertools import chain from textwrap import dedent +from typing import Dict, Set import snakemake from snakemake.parser import ( @@ -161,7 +162,7 @@ def emit_overrides(self, token): yield INDENT * self.base_indent, token -emitted_overrides_per_type: dict[str, set[str]] = {} +emitted_overrides_per_type: Dict[str, Set[str]] = {} def replace_block(self, token, force_block_end=False): diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index a14148ce..c18aac56 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -107,13 +107,13 @@ class RemoteFile: def snakemake_dag_to_interface( dag: DAG, wf_name: str, docstring: Optional[Docstring] = None -) -> (Interface, LiteralMap, List[RemoteFile]): +) -> Tuple[Interface, LiteralMap, List[RemoteFile]]: outputs: Dict[str, LatchFile] = {} for target in dag.targetjobs: for desired in target.input: param = variable_name_for_value(desired, target.input) - jobs: list[snakemake.jobs.Job] = dag.file2jobs(desired) + jobs: List[snakemake.jobs.Job] = dag.file2jobs(desired) producer_out: snakemake.io._IOFile = next( x for x in jobs[0].output if x == x ) @@ -227,7 +227,7 @@ def interface_to_parameters( inputs_vars = transform_types_in_variable_map( interface.inputs, interface.docstring.input_descriptions ) - params: Dict[str, interface_models.ParameterMap] = {} + params: Dict[str, interface_models.Parameter] = {} for k, v in inputs_vars.items(): val, default = interface.inputs_with_defaults[k] required = default is None @@ -331,9 +331,12 @@ def get_fn_code( for param, t in self.python_interface.inputs.items(): if t in (LatchFile, LatchDir): + param_meta = self.parameter_metadata[param] + assert isinstance(param_meta, metadata.SnakemakeFileParameter) + code_block += reindent( rf""" - {param}_dst_p = Path("{self.parameter_metadata[param].path}") + {param}_dst_p = Path("{param_meta.path}") print(f"Downloading {param}: {{{param}.remote_path}}") {param}_p = Path({param}).resolve() @@ -568,8 +571,11 @@ def __init__( dag: DAG, version: Optional[str] = None, ): + assert metadata._snakemake_metadata is not None name = metadata._snakemake_metadata.name + assert name is not None + native_interface, literal_map, return_files = snakemake_dag_to_interface( dag, name, None ) @@ -630,7 +636,7 @@ def compile(self, **kwargs): else: python_outputs[param] = LatchFile - dep_outputs: dict[SnakemakeInputVal, JobOutputInfo] = {} + dep_outputs: Dict[SnakemakeInputVal, JobOutputInfo] = {} for dep, dep_files in self._dag.dependencies[job].items(): for o in dep.output: if o in dep_files: @@ -740,6 +746,8 @@ def find_upstream_node_matching_output_var(self, out_var: str): if variable_name_for_file(f) == out_var: return depen.jobid, variable_name_for_value(f, depen.output) + raise RuntimeError(f"could not find upstream node for output: {out_var}") + def execute(self, **kwargs): return exception_scopes.user_entry_point(self._workflow_function)(**kwargs) @@ -769,8 +777,10 @@ def build_jit_register_wrapper() -> JITRegisterWorkflow: task_resolver=JITRegisterWorkflowResolver(), ) - task_bindings: List[literals_models.Binding] = [] typed_interface = transform_interface_to_typed_interface(python_interface) + assert typed_interface is not None + + task_bindings: List[literals_models.Binding] = [] for k in python_interface.inputs: var = typed_interface.inputs[k] promise_to_bind = Promise( @@ -812,7 +822,7 @@ def build_jit_register_wrapper() -> JITRegisterWorkflow: class AnnotatedStrJson(TypedDict): value: str - flags: dict[str, bool] + flags: Dict[str, bool] MaybeAnnotatedStrJson: TypeAlias = Union[str, AnnotatedStrJson] @@ -827,16 +837,16 @@ def annotated_str_to_json( return {"value": str(x), "flags": dict(x.flags.items())} -IONamedListItem = Union[MaybeAnnotatedStrJson, list[MaybeAnnotatedStrJson]] +IONamedListItem = Union[MaybeAnnotatedStrJson, List[MaybeAnnotatedStrJson]] class NamedListJson(TypedDict): - positional: list[IONamedListItem] - keyword: dict[str, IONamedListItem] + positional: List[IONamedListItem] + keyword: Dict[str, IONamedListItem] def named_list_to_json(xs: snakemake.io.Namedlist) -> NamedListJson: - named: dict[str, IONamedListItem] = {} + named: Dict[str, IONamedListItem] = {} for k, vs in xs.items(): if not isinstance(vs, list): named[k] = annotated_str_to_json(vs) @@ -854,7 +864,7 @@ def named_list_to_json(xs: snakemake.io.Namedlist) -> NamedListJson: v = v["value"] named_values.add(v) - unnamed: list[IONamedListItem] = [] + unnamed: List[IONamedListItem] = [] for vs in xs: if not isinstance(vs, list): vs = [vs] @@ -957,8 +967,8 @@ def {self.name}( return res def get_fn_return_stmt(self, remote_output_url: Optional[str] = None): - print_outs: list[str] = [] - results: list[str] = [] + print_outs: List[str] = [] + results: List[str] = [] for out_name, out_type in self._python_outputs.items(): target_path = self._target_file_for_output_param[out_name] diff --git a/pyproject.toml b/pyproject.toml index 6ddbf555..b9fec2c4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,15 +3,18 @@ black = "^23.3.0" isort = "^5.12.0" ruff = "^0.0.261" +[tool.pyright] +pythonVersion = "3.8" + [tool.black] preview = true -target-version = ["py39"] +target-version = ["py38"] [tool.isort] profile = "black" [tool.ruff] -target-version = "py39" +target-version = "py38" pydocstyle = { convention = "google" } extend-select = ["W", "D", "U", "N", "C", "B", "A", "T", "Q", "RUF100"] extend-ignore = [ diff --git a/setup.py b/setup.py index ddc72d5b..3fb1956a 100644 --- a/setup.py +++ b/setup.py @@ -49,7 +49,7 @@ "websockets==11.0.3", "watchfiles==0.19.0", ], - extras_require={"snakemake": ["snakemake>=7.25.4"]}, + extras_require={"snakemake": ["snakemake>=7.18.0"]}, classifiers=[ "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", From 8811af1db3dd341ecb254c03f5a2459323fc9f45 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 4 Aug 2023 13:44:43 -0700 Subject: [PATCH 165/356] resources support Signed-off-by: maximsmol --- latch/resources/tasks.py | 7 +++---- latch_cli/main.py | 2 +- latch_cli/services/register/register.py | 11 ++++------- latch_cli/snakemake/workflow.py | 10 ++++++++-- latch_cli/utils/__init__.py | 2 +- 5 files changed, 17 insertions(+), 15 deletions(-) diff --git a/latch/resources/tasks.py b/latch/resources/tasks.py index 933db777..6220ddf3 100644 --- a/latch/resources/tasks.py +++ b/latch/resources/tasks.py @@ -125,8 +125,7 @@ def _get_large_pod() -> Pod: def _get_medium_pod() -> Pod: - """[ "m5.8xlarge", "m5ad.8xlarge", "m5d.8xlarge", "m5n.8xlarge", "m5dn.8xlarge", "m5a.8xlarge" ] - """ + """[ "m5.8xlarge", "m5ad.8xlarge", "m5d.8xlarge", "m5n.8xlarge", "m5dn.8xlarge", "m5a.8xlarge" ]""" primary_container = V1Container(name="primary") resources = V1ResourceRequirements( @@ -360,7 +359,7 @@ def custom_memory_optimized_task(cpu: int, memory: int): ), primary_container_name="primary", ) - return functools.partial(task(task_config=task_config)) + return functools.partial(task, task_config=task_config) def custom_task(cpu: int, memory: int, *, storage_gib: int = 500): @@ -463,4 +462,4 @@ def custom_task(cpu: int, memory: int, *, storage_gib: int = 500): " 4949 GiB)" ) - return functools.partial(task(task_config=task_config)) + return functools.partial(task, task_config=task_config) diff --git a/latch_cli/main.py b/latch_cli/main.py index 3d319126..0343cafe 100644 --- a/latch_cli/main.py +++ b/latch_cli/main.py @@ -146,7 +146,7 @@ def register( remote=remote, skip_confirmation=yes, snakefile=snakefile, - progress_plain=(docker_progress == "auto" and sys.stdout.isatty()) + progress_plain=(docker_progress == "auto" and not sys.stdout.isatty()) or docker_progress == "plain", use_new_centromere=use_new_centromere, ) diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index 730f5d95..6fae6481 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -340,8 +340,6 @@ def register( snakefile=snakefile, use_new_centromere=use_new_centromere, ) as ctx: - click.echo("") - assert ctx.workflow_name is not None, "Unable to determine workflow name" assert ctx.version is not None, "Unable to determine workflow version" @@ -389,9 +387,9 @@ def register( click.secho("Cancelled", bold=True) return else: - click.secho("Skipping confirmation because of --yes\n", bold=True) + click.secho("Skipping confirmation because of --yes", bold=True) - click.secho("Initializing registration", bold=True) + click.secho("\nInitializing registration", bold=True) transport = None scp = None @@ -403,11 +401,10 @@ def register( ] ) ) - - print() + click.echo() if remote: - print("Connecting to remote server for docker build...") + click.secho("Connecting to remote server for docker build\n", bold=True) assert ctx.ssh_client is not None transport = ctx.ssh_client.get_transport() diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index c18aac56..017afa9b 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -951,10 +951,16 @@ class Res{self.name}(NamedTuple): ).replace("__output_fields__", output_fields) outputs_str = f"Res{self.name}:" + limits = self.job.resources + cores = limits.get("cpus", 4) + + # convert MB to GiB + mem = limits.get("mem_mb", 8589) * 1000 * 1000 // 1024 // 1024 // 1024 + res += ( reindent( rf""" - @small_task(cache=True) + @custom_task({cores}, {mem})(cache=True) def {self.name}( __params__ ) -> __outputs__ @@ -1203,7 +1209,7 @@ def get_fn_code( print(" Does not exist") finally: - ignored_paths = {{".cache", ".snakemake/conda/"}} + ignored_paths = {{".cache", ".snakemake/conda"}} ignored_names = {{".git", ".latch", "__pycache__"}} print("Recursive directory listing:") diff --git a/latch_cli/utils/__init__.py b/latch_cli/utils/__init__.py index 7544fd35..a08f6ceb 100644 --- a/latch_cli/utils/__init__.py +++ b/latch_cli/utils/__init__.py @@ -170,7 +170,7 @@ def hash_directory(dir_path: Path) -> str: exclude: List[str] = ["/.latch", ".git"] try: with ignore_file.open("r") as f: - click.echo("Using .dockerignore") + click.secho(" Using .dockerignore", italic=True) for l in f: l = l.strip() From 40b966c5e0ab2a8c2e05493073b3b4d2986d58a9 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 4 Aug 2023 13:55:33 -0700 Subject: [PATCH 166/356] fix missing import Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 11 +++++++++++ latch_cli/snakemake/serialize.py | 2 +- latch_cli/snakemake/workflow.py | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index cdd59e8c..d723b702 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -370,6 +370,17 @@ def generate_dockerfile( block.write_block(f) + f.write("run apt-get update --yes && apt-get install --yes git\n") + f.write( + "run pip install" + " 'git+https://github.com/latchbio/latch.git@kenny/snakekit'\n" + ) + f.write("run pip uninstall --yes latch\n") + f.write( + "run echo 97 && pip install" + " 'git+https://github.com/latchbio/latch.git@kenny/snakekit'\n" + ) + f.write("# Copy workflow data (use .dockerignore to skip files)\n") f.write("copy . /root/\n\n") diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index c159c317..d38c9a4f 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -286,7 +286,7 @@ def generate_snakemake_entrypoint( from flytekit.extras.persistence import LatchPersistence import traceback - from latch import small_task + from latch.resources.tasks import custom_task from latch.types.directory import LatchDir from latch.types.file import LatchFile diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 017afa9b..06037b2a 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -960,7 +960,7 @@ class Res{self.name}(NamedTuple): res += ( reindent( rf""" - @custom_task({cores}, {mem})(cache=True) + @custom_task(cpu={cores}, memory={mem})(cache=True) def {self.name}( __params__ ) -> __outputs__ From 10ba369a281902ace39c854f1ab8077f19a6abc2 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 7 Aug 2023 10:18:16 -0700 Subject: [PATCH 167/356] change custom task generation Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index d723b702..e41d07bc 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -377,7 +377,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 97 && pip install" + "run echo 99 && pip install" " 'git+https://github.com/latchbio/latch.git@kenny/snakekit'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 06037b2a..b23812c3 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -960,7 +960,8 @@ class Res{self.name}(NamedTuple): res += ( reindent( rf""" - @custom_task(cpu={cores}, memory={mem})(cache=True) + task = custom_task(cpu={cores}, memory={mem}) + @task(cache=True) def {self.name}( __params__ ) -> __outputs__ From 44fef0df8328fe056aa0c857a4551a8c79332a7c Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 7 Aug 2023 10:36:52 -0700 Subject: [PATCH 168/356] god rest my weary soul Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 20 ++++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index e41d07bc..8d1f2288 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -377,7 +377,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 99 && pip install" + "run echo 101 && pip install" " 'git+https://github.com/latchbio/latch.git@kenny/snakekit'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index b23812c3..b2b02678 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -21,6 +21,7 @@ from flytekit.core.python_auto_container import ( DefaultTaskResolver, PythonAutoContainerTask, + Resources, ) from flytekit.core.type_engine import TypeEngine from flytekit.core.workflow import ( @@ -43,6 +44,7 @@ from latch.types.directory import LatchDir from latch.types.file import LatchFile +from ...latch.resources.tasks import custom_task from ..utils import identifier_suffix_from_str SnakemakeInputVal: TypeAlias = snakemake.io._IOFile @@ -908,11 +910,19 @@ def __init__( self._task_function = task_fn_placeholder + limits = self.job.resources + cores = limits.get("cpus", 4) + + # convert MB to GiB + mem = limits.get("mem_mb", 8589) * 1000 * 1000 // 1024 // 1024 // 1024 + + task_config = custom_task(cpu=cores, memory=mem).keywords["task_config"] + super().__init__( task_type=task_type, name=name, interface=interface, - task_config=None, + task_config=task_config, task_resolver=SnakemakeJobTaskResolver(), ) @@ -951,16 +961,10 @@ class Res{self.name}(NamedTuple): ).replace("__output_fields__", output_fields) outputs_str = f"Res{self.name}:" - limits = self.job.resources - cores = limits.get("cpus", 4) - - # convert MB to GiB - mem = limits.get("mem_mb", 8589) * 1000 * 1000 // 1024 // 1024 // 1024 - res += ( reindent( rf""" - task = custom_task(cpu={cores}, memory={mem}) + task = custom_task(cpu=-1, memory=-1) # these limits are a lie and are ignored when generating the task spec @task(cache=True) def {self.name}( __params__ From ba61f578801b633a65b608e1f91f16f495de3b07 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Mon, 7 Aug 2023 10:38:10 -0700 Subject: [PATCH 169/356] update black in pre-commit Signed-off-by: Ayush Kamat --- .pre-commit-config.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 58b5b1b2..bb801d91 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,9 +36,10 @@ repos: # - id: sort-simple-yaml # - id: trailing-whitespace - repo: https://github.com/psf/black - rev: 23.3.0 + rev: 23.7.0 hooks: - id: black + args: [--preview] - repo: https://github.com/PyCQA/isort rev: 5.12.0 hooks: From ff07e50e7a7d35892979f5525531956c8cb8b056 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 7 Aug 2023 10:38:22 -0700 Subject: [PATCH 170/356] fixie Signed-off-by: maximsmol --- latch_cli/snakemake/workflow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index b2b02678..e1815b43 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -41,10 +41,10 @@ from typing_extensions import TypeAlias, TypedDict import latch.types.metadata as metadata +from latch.resources.tasks import custom_task from latch.types.directory import LatchDir from latch.types.file import LatchFile -from ...latch.resources.tasks import custom_task from ..utils import identifier_suffix_from_str SnakemakeInputVal: TypeAlias = snakemake.io._IOFile From e21b7d18bc77a036c4fdb5520fec14cb49bf08fb Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Mon, 7 Aug 2023 10:40:28 -0700 Subject: [PATCH 171/356] reformat Signed-off-by: Ayush Kamat --- latch/registry/table.py | 6 ++---- latch/resources/tasks.py | 3 +-- latch_cli/auth/csrf.py | 1 - latch_cli/centromere/utils.py | 1 - latch_cli/main.py | 14 ++++++-------- latch_cli/services/move.py | 6 ++---- 6 files changed, 11 insertions(+), 20 deletions(-) diff --git a/latch/registry/table.py b/latch/registry/table.py index a3c9386d..7dcff1a1 100644 --- a/latch/registry/table.py +++ b/latch/registry/table.py @@ -592,10 +592,8 @@ def upsert_column( raise InvalidColumnTypeError( key, type, - ( - f"Enum value for {repr(f.name)} ({repr(f.value)}) is not a" - " string" - ), + f"Enum value for {repr(f.name)} ({repr(f.value)}) is not a" + " string", ) members.append(f.value) diff --git a/latch/resources/tasks.py b/latch/resources/tasks.py index 933db777..6de6d50a 100644 --- a/latch/resources/tasks.py +++ b/latch/resources/tasks.py @@ -125,8 +125,7 @@ def _get_large_pod() -> Pod: def _get_medium_pod() -> Pod: - """[ "m5.8xlarge", "m5ad.8xlarge", "m5d.8xlarge", "m5n.8xlarge", "m5dn.8xlarge", "m5a.8xlarge" ] - """ + """[ "m5.8xlarge", "m5ad.8xlarge", "m5d.8xlarge", "m5n.8xlarge", "m5dn.8xlarge", "m5a.8xlarge" ]""" primary_container = V1Container(name="primary") resources = V1ResourceRequirements( diff --git a/latch_cli/auth/csrf.py b/latch_cli/auth/csrf.py index 3db614be..eced4e4c 100644 --- a/latch_cli/auth/csrf.py +++ b/latch_cli/auth/csrf.py @@ -4,7 +4,6 @@ class CSRFState: - """Context manager to hold state preventing CSRF attacks. Outlined in detail `here`_, this object holds a state string as a diff --git a/latch_cli/centromere/utils.py b/latch_cli/centromere/utils.py index 4aa85334..26e01f3f 100644 --- a/latch_cli/centromere/utils.py +++ b/latch_cli/centromere/utils.py @@ -232,7 +232,6 @@ def _construct_ssh_client( class MaybeRemoteDir: - """A temporary directory that exists locally or on a remote machine.""" def __init__(self, ssh_client: Optional[paramiko.SSHClient] = None): diff --git a/latch_cli/main.py b/latch_cli/main.py index 0638452a..136a2df9 100644 --- a/latch_cli/main.py +++ b/latch_cli/main.py @@ -41,12 +41,10 @@ def main(): latest_ver = parse_version(get_latest_package_version()) if local_ver < latest_ver: click.secho( - textwrap.dedent( - f""" + textwrap.dedent(f""" WARN: Your local version of latch ({local_ver}) is out of date. This may result in unexpected behavior. Please upgrade to the latest version ({latest_ver}) using `python3 -m pip install --upgrade latch`. - """ - ).strip("\n"), + """).strip("\n"), fg="yellow", ) @@ -582,8 +580,7 @@ def preview(pkg_root: Path): @main.command("workspace") def workspace(): - """Spawns an interactive terminal prompt allowing users to choose what workspace they want to work in. - """ + """Spawns an interactive terminal prompt allowing users to choose what workspace they want to work in.""" crash_handler.message = "Unable to fetch workspaces" crash_handler.pkg_root = str(Path.cwd()) @@ -595,8 +592,7 @@ def workspace(): @main.command("get-executions") def get_executions(): - """Spawns an interactive terminal UI that shows all executions in a given workspace - """ + """Spawns an interactive terminal UI that shows all executions in a given workspace""" crash_handler.message = "Unable to fetch executions" @@ -604,11 +600,13 @@ def get_executions(): get_executions() + @main.group() def pods(): """Manage pods""" pass + @pods.command("stop") @click.argument("pod_id", nargs=1, type=int, required=False) def stop_pod(pod_id: Optional[int] = None): diff --git a/latch_cli/services/move.py b/latch_cli/services/move.py index 18aa1be5..07788f04 100644 --- a/latch_cli/services/move.py +++ b/latch_cli/services/move.py @@ -91,10 +91,8 @@ def move( elif msg.startswith("Refusing to move already moved node"): raise get_path_error( src, - ( - "copy in progress. Please wait until the node has finished copying" - " before moving." - ), + "copy in progress. Please wait until the node has finished copying" + " before moving.", acc_id, ) from e elif msg == "Conflicting object in destination": From 9c2cae1343bd2d553ad5e6c8fd44d03667fd6edc Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 7 Aug 2023 10:55:30 -0700 Subject: [PATCH 172/356] upload all specs Signed-off-by: maximsmol --- latch_cli/snakemake/serialize.py | 29 +++++++++++++++++++++++++++-- latch_cli/snakemake/workflow.py | 7 +++---- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index d38c9a4f..98db7b6e 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -1,10 +1,14 @@ import os +import sys import textwrap from pathlib import Path from textwrap import dedent from typing import List, Optional, Set, Union, get_args import click +from flyteidl.admin.launch_plan_pb2 import LaunchPlan as _idl_admin_LaunchPlan +from flyteidl.admin.task_pb2 import TaskSpec as _idl_admin_TaskSpec +from flyteidl.admin.workflow_pb2 import WorkflowSpec as _idl_admin_WorkflowSpec from flytekit import LaunchPlan from flytekit.configuration import Image, ImageConfig, SerializationSettings from flytekit.models import launch_plan as launch_plan_models @@ -200,8 +204,11 @@ def serialize_snakemake( registrable_entity_cache: EntityCache = {} + spec_dir = Path("spec") + spec_dir.mkdir(parents=True, exist_ok=True) + wf_spec = get_serializable_workflow(wf, settings, registrable_entity_cache) - Path("wf_spec.json").write_text(MessageToJson(wf_spec.to_flyte_idl())) + (spec_dir / "wf.json").write_text(MessageToJson(wf_spec.to_flyte_idl())) parameter_map = interface_to_parameters(wf.python_interface) lp = LaunchPlan( @@ -219,7 +226,25 @@ def serialize_snakemake( ) + [admin_lp] ] - persist_registrable_entities(registrable_entities, output_dir) + for idx, entity in enumerate(registrable_entities): + cur = spec_dir + + if isinstance(entity, _idl_admin_TaskSpec): + cur = cur / "tasks" / f"{entity.template.id.name}_{idx}.json" + elif isinstance(entity, _idl_admin_WorkflowSpec): + cur = cur / "wfs" / f"{entity.template.id.name}_{idx}.json" + elif isinstance(entity, _idl_admin_LaunchPlan): + cur = cur / "lps" / f"{entity.id.name}_{idx}.json" + else: + click.secho( + f"Entity is incorrect formatted {entity} - type {type(entity)}", + fg="red", + ) + sys.exit(-1) + + cur.write_text(MessageToJson(entity)) + + persist_registrable_entities(registrable_entities, str(output_dir)) def serialize_jit_register_workflow( diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index e1815b43..c4317fe8 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -513,10 +513,9 @@ def get_fn_code( reg_resp = register_serialized_pkg(protos, None, version, account_id) _print_reg_resp(reg_resp, new_image_name) - wf_spec_remote = f"latch:///.snakemake_latch/workflows/{wf_name}/spec.json" - lp.upload("wf_spec.json", wf_spec_remote) - print(f"wf_spec.json -> {wf_spec_remote}") - + wf_spec_remote = f"latch:///.snakemake_latch/workflows/{wf_name}/spec/" + lp.upload_directory("spec", wf_spec_remote) + print(f"spec -> {wf_spec_remote}") class _WorkflowInfoNode(TypedDict): id: str From 26a991280eb1360598879e2b91baf6e5b3cfcebf Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 7 Aug 2023 11:23:48 -0700 Subject: [PATCH 173/356] redo spec upload Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 8d1f2288..5b8f5a9d 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -377,7 +377,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 101 && pip install" + "run echo 102 && pip install" " 'git+https://github.com/latchbio/latch.git@kenny/snakekit'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index c4317fe8..26a4f6d4 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -514,8 +514,12 @@ def get_fn_code( _print_reg_resp(reg_resp, new_image_name) wf_spec_remote = f"latch:///.snakemake_latch/workflows/{wf_name}/spec/" - lp.upload_directory("spec", wf_spec_remote) - print(f"spec -> {wf_spec_remote}") + spec_dir = Path("spec") + for x_dir in spec_dir.iterdir(): + for x in x_dir.iterdir(): + dst = f"{wf_spec_remote}/{x_dir.name}/{x.name}" + lp.upload(str(x), dst) + print(f"{x} -> {dst}") class _WorkflowInfoNode(TypedDict): id: str From 71fd7b1967a2fcfbdec34bcdb9c7613259d0ef27 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 7 Aug 2023 11:27:32 -0700 Subject: [PATCH 174/356] mkdir Signed-off-by: maximsmol --- latch_cli/snakemake/serialize.py | 1 + 1 file changed, 1 insertion(+) diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index 98db7b6e..bf612898 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -242,6 +242,7 @@ def serialize_snakemake( ) sys.exit(-1) + cur.parent.mkdir(parents=True, exist_ok=True) cur.write_text(MessageToJson(entity)) persist_registrable_entities(registrable_entities, str(output_dir)) From 17ab1ebc593bf5442058d74546993ad4f3d301da Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 7 Aug 2023 11:32:59 -0700 Subject: [PATCH 175/356] fixie Signed-off-by: maximsmol --- latch_cli/snakemake/workflow.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 26a4f6d4..8edd81a5 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -513,13 +513,21 @@ def get_fn_code( reg_resp = register_serialized_pkg(protos, None, version, account_id) _print_reg_resp(reg_resp, new_image_name) - wf_spec_remote = f"latch:///.snakemake_latch/workflows/{wf_name}/spec/" + wf_spec_remote = f"latch:///.snakemake_latch/workflows/{wf_name}/spec" spec_dir = Path("spec") for x_dir in spec_dir.iterdir(): + if not x.is_dir(): + dst = f"{wf_spec_remote}/{x_dir.name}" + print(f"{x_dir} -> {dst}") + lp.upload(str(x_dir), dst) + print(" done") + continue + for x in x_dir.iterdir(): dst = f"{wf_spec_remote}/{x_dir.name}/{x.name}" - lp.upload(str(x), dst) print(f"{x} -> {dst}") + lp.upload(str(x), dst) + print(" done") class _WorkflowInfoNode(TypedDict): id: str From cf086266f87c79aab4267d087653fd2577d39314 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 7 Aug 2023 11:35:40 -0700 Subject: [PATCH 176/356] fix! Signed-off-by: maximsmol --- latch_cli/snakemake/workflow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 8edd81a5..c024b5cd 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -516,7 +516,7 @@ def get_fn_code( wf_spec_remote = f"latch:///.snakemake_latch/workflows/{wf_name}/spec" spec_dir = Path("spec") for x_dir in spec_dir.iterdir(): - if not x.is_dir(): + if not x_dir.is_dir(): dst = f"{wf_spec_remote}/{x_dir.name}" print(f"{x_dir} -> {dst}") lp.upload(str(x_dir), dst) From f9424be6fb0a64884abab61fdba329bee8d2506b Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 8 Aug 2023 09:25:11 -0700 Subject: [PATCH 177/356] try setting resources a new way Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 2 +- latch_cli/snakemake/workflow.py | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 5b8f5a9d..191dbc44 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -377,7 +377,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 102 && pip install" + "run echo 106 && pip install" " 'git+https://github.com/latchbio/latch.git@kenny/snakekit'\n" ) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index c024b5cd..cdf3b713 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -21,7 +21,6 @@ from flytekit.core.python_auto_container import ( DefaultTaskResolver, PythonAutoContainerTask, - Resources, ) from flytekit.core.type_engine import TypeEngine from flytekit.core.workflow import ( @@ -33,9 +32,11 @@ from flytekit.exceptions import scopes as exception_scopes from flytekit.models import interface as interface_models from flytekit.models import literals as literals_models +from flytekit.models import task as _task_model from flytekit.models import types as type_models from flytekit.models.core.types import BlobType from flytekit.models.literals import Blob, BlobMetadata, Literal, LiteralMap, Scalar +from flytekitplugins.pod.task import PodFunctionTask from snakemake.dag import DAG from snakemake.jobs import GroupJob, Job from typing_extensions import TypeAlias, TypedDict @@ -927,16 +928,20 @@ def __init__( # convert MB to GiB mem = limits.get("mem_mb", 8589) * 1000 * 1000 // 1024 // 1024 // 1024 - task_config = custom_task(cpu=cores, memory=mem).keywords["task_config"] - super().__init__( task_type=task_type, name=name, interface=interface, - task_config=task_config, + task_config=custom_task(cpu=cores, memory=mem).keywords["task_config"], task_resolver=SnakemakeJobTaskResolver(), ) + def get_k8s_pod( + self, settings: SerializationSettings + ) -> Optional[_task_model.K8sPod]: + # todo(maximsmol): this is very awful + return PodFunctionTask.get_k8s_pod(self, settings) + def get_fn_interface(self): res = "" From f976fe1d648b940698f74c571fcc0b7531ee3392 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 8 Aug 2023 09:29:14 -0700 Subject: [PATCH 178/356] fix Signed-off-by: maximsmol --- latch_cli/snakemake/workflow.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index cdf3b713..f4de93ee 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -936,6 +936,8 @@ def __init__( task_resolver=SnakemakeJobTaskResolver(), ) + _serialize_pod_spec = PodFunctionTask._serialize_pod_spec + def get_k8s_pod( self, settings: SerializationSettings ) -> Optional[_task_model.K8sPod]: From e40d621f8e44f96b1da800d0c8c587ea87f4dd98 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 8 Aug 2023 09:48:29 -0700 Subject: [PATCH 179/356] give up on nice things Signed-off-by: maximsmol --- latch_cli/snakemake/workflow.py | 76 +++++++++++++++++++++++++++++---- 1 file changed, 67 insertions(+), 9 deletions(-) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index f4de93ee..ac87e046 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -32,11 +32,13 @@ from flytekit.exceptions import scopes as exception_scopes from flytekit.models import interface as interface_models from flytekit.models import literals as literals_models -from flytekit.models import task as _task_model +from flytekit.models import task as _task_models from flytekit.models import types as type_models from flytekit.models.core.types import BlobType from flytekit.models.literals import Blob, BlobMetadata, Literal, LiteralMap, Scalar -from flytekitplugins.pod.task import PodFunctionTask +from flytekitplugins.pod.task import Pod, _sanitize_resource_name +from kubernetes.client import ApiClient +from kubernetes.client.models import V1Container, V1EnvVar, V1ResourceRequirements from snakemake.dag import DAG from snakemake.jobs import GroupJob, Job from typing_extensions import TypeAlias, TypedDict @@ -897,7 +899,7 @@ def named_list_to_json(xs: snakemake.io.Namedlist) -> NamedListJson: return {"positional": unnamed, "keyword": named} -class SnakemakeJobTask(PythonAutoContainerTask[T]): +class SnakemakeJobTask(PythonAutoContainerTask[Pod]): def __init__( self, wf: SnakemakeWorkflow, @@ -936,13 +938,69 @@ def __init__( task_resolver=SnakemakeJobTaskResolver(), ) - _serialize_pod_spec = PodFunctionTask._serialize_pod_spec + # todo(maximsmol): this is very awful + def _serialize_pod_spec(self, settings: SerializationSettings) -> Dict[str, Any]: + containers = self.task_config.pod_spec.containers + primary_exists = False + for container in containers: + if container.name == self.task_config.primary_container_name: + primary_exists = True + break + if not primary_exists: + # insert a placeholder primary container if it is not defined in the pod spec. + containers.append(V1Container(name=self.task_config.primary_container_name)) + + final_containers = [] + for container in containers: + # In the case of the primary container, we overwrite specific container attributes with the default values + # used in the regular Python task. + if container.name == self.task_config.primary_container_name: + sdk_default_container = super().get_container(settings) + + container.image = sdk_default_container.image + # Spawn entrypoint as child process so it can receive signals + container.command = [ + "/bin/bash", + "-c", + ( + "exec 3>&1 4>&2 && (" + f" {' '.join(sdk_default_container.args)} 1>&3 2>&4 )" + ), + ] + container.args = [] + + limits, requests = {}, {} + for resource in sdk_default_container.resources.limits: + limits[_sanitize_resource_name(resource)] = resource.value + for resource in sdk_default_container.resources.requests: + requests[_sanitize_resource_name(resource)] = resource.value + + resource_requirements = V1ResourceRequirements( + limits=limits, requests=requests + ) + if len(limits) > 0 or len(requests) > 0: + # Important! Only copy over resource requirements if they are non-empty. + container.resources = resource_requirements + + container.env = [ + V1EnvVar(name=key, value=val) + for key, val in sdk_default_container.env.items() + ] + + final_containers.append(container) + + self.task_config._pod_spec.containers = final_containers - def get_k8s_pod( - self, settings: SerializationSettings - ) -> Optional[_task_model.K8sPod]: - # todo(maximsmol): this is very awful - return PodFunctionTask.get_k8s_pod(self, settings) + return ApiClient().sanitize_for_serialization(self.task_config.pod_spec) + + def get_k8s_pod(self, settings: SerializationSettings) -> _task_models.K8sPod: + return _task_models.K8sPod( + pod_spec=self._serialize_pod_spec(settings), + metadata=_task_models.K8sObjectMetadata( + labels=self.task_config.labels, + annotations=self.task_config.annotations, + ), + ) def get_fn_interface(self): res = "" From f2bc3dc336bb903e3e9ff7973cdd9f5ecfa5ecff Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 8 Aug 2023 09:56:20 -0700 Subject: [PATCH 180/356] do not set container Signed-off-by: maximsmol --- latch_cli/snakemake/workflow.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index ac87e046..67f284eb 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1002,6 +1002,9 @@ def get_k8s_pod(self, settings: SerializationSettings) -> _task_models.K8sPod: ), ) + def get_container(self, settings: SerializationSettings) -> _task_models.Container: + return None + def get_fn_interface(self): res = "" From 568166e36e6efceffa29f4a0cd1457f5aa93d53a Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Tue, 8 Aug 2023 10:08:42 -0700 Subject: [PATCH 181/356] add proper messaging for no auth found Signed-off-by: Ayush Kamat --- latch_cli/main.py | 22 +++++++++++++++++++++- latch_cli/services/cp/download.py | 9 ++------- latch_cli/services/cp/exceptions.py | 4 ---- latch_cli/services/cp/main.py | 3 --- latch_cli/services/cp/path_utils.py | 5 ++--- latch_cli/services/cp/upload.py | 8 ++------ latch_cli/services/cp/utils.py | 18 ------------------ latch_cli/services/stop_pod.py | 2 +- latch_cli/utils.py | 18 ++++++++++++++++++ 9 files changed, 46 insertions(+), 43 deletions(-) diff --git a/latch_cli/main.py b/latch_cli/main.py index 136a2df9..b264bb64 100644 --- a/latch_cli/main.py +++ b/latch_cli/main.py @@ -4,6 +4,7 @@ import textwrap from collections import OrderedDict from pathlib import Path +from textwrap import dedent from typing import List, Optional, Union import click @@ -17,7 +18,12 @@ from latch_cli.services.cp.config import Progress from latch_cli.services.init.init import template_flag_to_option from latch_cli.services.local_dev import TaskSize -from latch_cli.utils import get_latest_package_version, get_local_package_version +from latch_cli.utils import ( + AuthenticationError, + get_auth_header, + get_latest_package_version, + get_local_package_version, +) from latch_cli.workflow_config import BaseImageOptions latch_cli.click_utils.patch() @@ -37,6 +43,20 @@ def main(): Collection of command line tools for using the Latch SDK and interacting with the Latch platform. """ + try: + get_auth_header() + except AuthenticationError: + click.secho( + dedent(""" + Unable to authenticate with Latch. + + If you are on a machine with a browser, run `latch login`. + If not, navigate to `https://console.latch.bio/settings/developer` on a different machine, select `Access Tokens`, and copy your `API Key` to `~/.latch/token` on this machine. + """), + fg="red", + ) + raise click.exceptions.Exit() + local_ver = parse_version(get_local_package_version()) latest_ver = parse_version(get_latest_package_version()) if local_ver < latest_ver: diff --git a/latch_cli/services/cp/download.py b/latch_cli/services/cp/download.py index 9a42d1a3..a8175b5e 100644 --- a/latch_cli/services/cp/download.py +++ b/latch_cli/services/cp/download.py @@ -1,4 +1,3 @@ -import os import time from concurrent.futures import ProcessPoolExecutor from contextlib import closing @@ -20,12 +19,8 @@ ProgressBars, get_free_index, ) -from latch_cli.services.cp.utils import ( - get_auth_header, - get_max_workers, - human_readable_time, -) -from latch_cli.utils import with_si_suffix +from latch_cli.services.cp.utils import get_max_workers, human_readable_time +from latch_cli.utils import get_auth_header, with_si_suffix class GetSignedUrlData(TypedDict): diff --git a/latch_cli/services/cp/exceptions.py b/latch_cli/services/cp/exceptions.py index 2ea10a99..0e4645d4 100644 --- a/latch_cli/services/cp/exceptions.py +++ b/latch_cli/services/cp/exceptions.py @@ -1,6 +1,2 @@ class PathResolutionError(ValueError): ... - - -class AuthenticationError(RuntimeError): - ... diff --git a/latch_cli/services/cp/main.py b/latch_cli/services/cp/main.py index dc04f368..555485b7 100644 --- a/latch_cli/services/cp/main.py +++ b/latch_cli/services/cp/main.py @@ -1,9 +1,6 @@ -from glob import glob from pathlib import Path from typing import List -import click - from latch_cli.services.cp.config import CPConfig, Progress from latch_cli.services.cp.download import download from latch_cli.services.cp.glob import expand_pattern diff --git a/latch_cli/services/cp/path_utils.py b/latch_cli/services/cp/path_utils.py index 02d567a7..037d70b2 100644 --- a/latch_cli/services/cp/path_utils.py +++ b/latch_cli/services/cp/path_utils.py @@ -1,13 +1,12 @@ import re -import urllib.parse from pathlib import Path -from urllib.parse import urljoin, urlparse +from urllib.parse import urlparse import click from latch_sdk_config.user import user_config from latch_cli.services.cp.exceptions import PathResolutionError -from latch_cli.services.cp.utils import get_auth_header +from latch_cli.utils import get_auth_header latch_url_regex = re.compile(r"^(latch)?://") diff --git a/latch_cli/services/cp/upload.py b/latch_cli/services/cp/upload.py index b2ecf89e..2832942d 100644 --- a/latch_cli/services/cp/upload.py +++ b/latch_cli/services/cp/upload.py @@ -20,12 +20,8 @@ from latch_cli.services.cp.ldata_utils import LDataNodeType, get_node_data from latch_cli.services.cp.path_utils import normalize_path from latch_cli.services.cp.progress import ProgressBarManager, ProgressBars -from latch_cli.services.cp.utils import ( - get_auth_header, - get_max_workers, - human_readable_time, -) -from latch_cli.utils import urljoins, with_si_suffix +from latch_cli.services.cp.utils import get_max_workers, human_readable_time +from latch_cli.utils import get_auth_header, urljoins, with_si_suffix if TYPE_CHECKING: QueueType: TypeAlias = Queue[Optional[Path]] diff --git a/latch_cli/services/cp/utils.py b/latch_cli/services/cp/utils.py index 11790d97..c32add04 100644 --- a/latch_cli/services/cp/utils.py +++ b/latch_cli/services/cp/utils.py @@ -1,10 +1,6 @@ import os from typing import List -from latch_sdk_config.user import user_config - -from latch_cli.services.cp.exceptions import AuthenticationError - def get_max_workers() -> int: try: @@ -19,20 +15,6 @@ def get_max_workers() -> int: return min(max_workers, 16) -def get_auth_header() -> str: - sdk_token = user_config.token - execution_token = os.environ.get("FLYTE_INTERNAL_EXECUTION_ID") - - if sdk_token is not None and sdk_token != "": - header = f"Latch-SDK-Token {sdk_token}" - elif execution_token is not None: - header = f"Latch-Execution-Token {execution_token}" - else: - raise AuthenticationError("Unable to find authentication credentials.") - - return header - - def pluralize(singular: str, plural: str, selector: int) -> str: if selector == 1: return singular diff --git a/latch_cli/services/stop_pod.py b/latch_cli/services/stop_pod.py index 1c80e5c9..da579ed3 100644 --- a/latch_cli/services/stop_pod.py +++ b/latch_cli/services/stop_pod.py @@ -4,7 +4,7 @@ from latch_sdk_config.latch import NUCLEUS_URL from .. import tinyrequests -from .cp.utils import get_auth_header +from ..utils import get_auth_header def stop_pod(pod_id: int) -> None: diff --git a/latch_cli/utils.py b/latch_cli/utils.py index 9238ac25..aa2a49da 100644 --- a/latch_cli/utils.py +++ b/latch_cli/utils.py @@ -55,6 +55,24 @@ def urljoins(*args: str, dir: bool = False) -> str: return res +class AuthenticationError(RuntimeError): + ... + + +def get_auth_header() -> str: + sdk_token = user_config.token + execution_token = os.environ.get("FLYTE_INTERNAL_EXECUTION_ID") + + if sdk_token is not None and sdk_token != "": + header = f"Latch-SDK-Token {sdk_token}" + elif execution_token is not None: + header = f"Latch-Execution-Token {execution_token}" + else: + raise AuthenticationError("Unable to find authentication credentials.") + + return header + + def retrieve_or_login() -> str: """Returns a valid JWT to access Latch, prompting a login flow if needed. From 068a3176655f1feb1c025bf38313a2cd5dd509ae Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 8 Aug 2023 10:13:40 -0700 Subject: [PATCH 182/356] fix task type Signed-off-by: maximsmol --- latch_cli/snakemake/workflow.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 67f284eb..8360cdfe 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -910,7 +910,6 @@ def __init__( target_file_for_output_param: Dict[str, str], is_target: bool, interface: Interface, - task_type="python-task", ): name = f"{job.name}_{job.jobid}" @@ -931,7 +930,8 @@ def __init__( mem = limits.get("mem_mb", 8589) * 1000 * 1000 // 1024 // 1024 // 1024 super().__init__( - task_type=task_type, + task_type="sidecar", + task_type_version=2, name=name, interface=interface, task_config=custom_task(cpu=cores, memory=mem).keywords["task_config"], From f15e924091741adb643cefa71ef3d9ac19db0bc3 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Tue, 8 Aug 2023 10:21:53 -0700 Subject: [PATCH 183/356] need task config Signed-off-by: maximsmol --- latch_cli/snakemake/workflow.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 8360cdfe..8d513c8f 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -36,7 +36,11 @@ from flytekit.models import types as type_models from flytekit.models.core.types import BlobType from flytekit.models.literals import Blob, BlobMetadata, Literal, LiteralMap, Scalar -from flytekitplugins.pod.task import Pod, _sanitize_resource_name +from flytekitplugins.pod.task import ( + _PRIMARY_CONTAINER_NAME_FIELD, + Pod, + _sanitize_resource_name, +) from kubernetes.client import ApiClient from kubernetes.client.models import V1Container, V1EnvVar, V1ResourceRequirements from snakemake.dag import DAG @@ -1005,6 +1009,9 @@ def get_k8s_pod(self, settings: SerializationSettings) -> _task_models.K8sPod: def get_container(self, settings: SerializationSettings) -> _task_models.Container: return None + def get_config(self, settings: SerializationSettings) -> Dict[str, str]: + return {_PRIMARY_CONTAINER_NAME_FIELD: self.task_config.primary_container_name} + def get_fn_interface(self): res = "" From b79290e22ba6a6e012f5ba73e2b33f9b34368640 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Tue, 8 Aug 2023 10:29:21 -0700 Subject: [PATCH 184/356] 2.31.1 Signed-off-by: Ayush Kamat --- CHANGELOG.md | 325 ++++++++++++++++++++++++++------------------------- setup.py | 2 +- 2 files changed, 166 insertions(+), 161 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cebbe72a..4a5e884d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,631 +16,636 @@ Types of changes # Latch SDK Changelog +## 2.31.1 - 2023-08-08 + +### Changed + +* Any CLI command will now display a message if no authentication token is found + ## 2.31.0 - 2023-07-28 ### Changed -- `latch stop-pod` renamed to `latch pods stop` +* `latch stop-pod` renamed to `latch pods stop` ## 2.30.0 - 2023-07-27 ### Added -- Support for python 3.11 +* Support for python 3.11 ### Dependencies -- pinned `lytekit` to `v0.15.2` to remove numpy + pandas + pyarrow dependencies -- pinned `lytekitplugins-pods` to `v0.6.1` to remove dependency on numpy -- pinned `latch-sdk-gql` to `0.0.6` which supports 3.11 -- pinned `latch-sdk-config` to `0.0.4` which supports 3.11 +* pinned `lytekit` to `v0.15.2` to remove numpy + pandas + pyarrow dependencies +* pinned `lytekitplugins-pods` to `v0.6.1` to remove dependency on numpy +* pinned `latch-sdk-gql` to `0.0.6` which supports 3.11 +* pinned `latch-sdk-config` to `0.0.4` which supports 3.11 ## 2.29.0 - 2023-07-26 ### Added -- `stop-pod` command to the CLI. Allows the user to stop a pod in which the CLI resides or to stop a pod using its id. +* `stop-pod` command to the CLI. Allows the user to stop a pod in which the CLI resides or to stop a pod using its id. ## 2.28.0 - 2023-07-25 ### Added -- Tasks explicitly request ephemeral storage -- `custom_task` and `custom_memory_optimized_task` allow selecting storage size -- `custom_memory_optimized_task` functionality merged into `custom_task` +* Tasks explicitly request ephemeral storage +* `custom_task` and `custom_memory_optimized_task` allow selecting storage size +* `custom_memory_optimized_task` functionality merged into `custom_task` ### Deprecated -- `custom_memory_optimized_task` +* `custom_memory_optimized_task` ## 2.27.4 - 2023-07-18 ### Changed -- changed beta register implementation +* changed beta register implementation ## 2.27.3 - 2023-07-18 ### Dependencies -- pinned `lytekit` to `v0.14.15` to bring in `marshmallow-enum` as a dependency. +* pinned `lytekit` to `v0.14.15` to bring in `marshmallow-enum` as a dependency. ## 2.27.2 - 2023-07-17 ### Fixed -- fixed bug where `LatchFile`s/`LatchDir`s would provide `file://` URIs instead of Unix paths, which was causing errors in, e.g., calls to `open()`. +* fixed bug where `LatchFile`s/`LatchDir`s would provide `file://` URIs instead of Unix paths, which was causing errors in, e.g., calls to `open()`. ## 2.27.1 - 2023-07-15 ### Fixed -- fixed bug where `LatchFile`s/`LatchDir`s wouldn't respect the workspace selected using `latch workspace`. +* fixed bug where `LatchFile`s/`LatchDir`s wouldn't respect the workspace selected using `latch workspace`. ## 2.27.0 - 2023-07-15 ### Added -- Added `.iterdir()` method to `LatchDir` to iterate through subdirectories +* Added `.iterdir()` method to `LatchDir` to iterate through subdirectories ## 2.26.2 - 2023-07-11 ### Fixed -- Fix unclosed file in `lytekit` upload code +* Fix unclosed file in `lytekit` upload code ## 2.26.1 - 2023-07-10 ### Fixed -- LatchFiles accessed through registry are downloaded to a file with the same name as the file on latch +* LatchFiles accessed through registry are downloaded to a file with the same name as the file on latch ## 2.26.0 - 2023-07-07 ### Changed -- Gated `latch develop` resource selection behind an environment variable due to its slow performance +* Gated `latch develop` resource selection behind an environment variable due to its slow performance ### Dependencies -- Added back several dependencies to allow the old `latch develop` infrastructure to work properly. +* Added back several dependencies to allow the old `latch develop` infrastructure to work properly. ## 2.25.2 - 2023-07-05 ### Fixed -- Dockerfile generation uses `\` escaping: fixes bug in Conda and R template +* Dockerfile generation uses `\` escaping: fixes bug in Conda and R template ## 2.25.1 - 2023-06-28 ### Dependencies -- Upgraded `paramiko` dependency to `>=3.2.0` which fixes a `PKey` issue. +* Upgraded `paramiko` dependency to `>=3.2.0` which fixes a `PKey` issue. ## 2.25.0 - 2023-06-28 ### Changed -- `latch register` experimental features (2.24.xx) are now gated behind an environment variable, and by default we use the old (pre 2.24) register backend. +* `latch register` experimental features (2.24.xx) are now gated behind an environment variable, and by default we use the old (pre 2.24) register backend. ## 2.24.12 - 2023-06-27 ### Dependencies -- Upgraded lytekit to version 0.14.13 to support uploading files up to 5 TiB from within a task +* Upgraded lytekit to version 0.14.13 to support uploading files up to 5 TiB from within a task ## 2.24.11 - 2023-06-27 ### Fixed -- Internal bug in `latch register` which caused an API call to be made when not necessary, resulting in an irrelevant exception being thrown +* Internal bug in `latch register` which caused an API call to be made when not necessary, resulting in an irrelevant exception being thrown ## 2.24.10 - 2023-06-27 ### Fixed -- Bug in `latch cp` upload path where URLs would be generated but files would not be uploaded +* Bug in `latch cp` upload path where URLs would be generated but files would not be uploaded ## 2.24.9 - 2023-06-27 ### Changed -- Added client side rate limiting to `latch cp` upload API calls so as to not throttle our backend. +* Added client side rate limiting to `latch cp` upload API calls so as to not throttle our backend. ## 2.24.8 - 2023-06-27 ### Fixed -- `latch register` provision timeout bug -- catch `KeyboardInterrupt`s during register provisioning -- updated `latch-base` image to fix docker-in-docker workflows which use the host machine's network interface +* `latch register` provision timeout bug +* catch `KeyboardInterrupt`s during register provisioning +* updated `latch-base` image to fix docker-in-docker workflows which use the host machine's network interface ## 2.24.7 - 2023-06-26 ### Fixed -- `latch develop` and `latch register` provision timeout increased to 30 minutes +* `latch develop` and `latch register` provision timeout increased to 30 minutes ## 2.24.6 - 2023-06-26 ### Fixed -- `latch develop` and `latch register` SSH connections timeout on inactivity +* `latch develop` and `latch register` SSH connections timeout on inactivity ## 2.24.5 - 2023-06-26 ### Fixed -- Bug in `latch develop` where rsync would continually flood stdout with requests to confirm host key authenticity +* Bug in `latch develop` where rsync would continually flood stdout with requests to confirm host key authenticity ## 2.24.3 - 2023-06-24 ### Added -- Rename `--no-glob` option shorthand to `-G` for `latch cp` +* Rename `--no-glob` option shorthand to `-G` for `latch cp` ### Fixed -- Bug in `latch register` where SSH connections were going stale +* Bug in `latch register` where SSH connections were going stale ## 2.24.0 - 2023-06-23 ### Added -- Glob support for latch cp -- latch cp autocomplete -- ability to choose task size in latch develop +* Glob support for latch cp +* latch cp autocomplete +* ability to choose task size in latch develop ### Changed -- Backend implementations of latch register and latch develop +* Backend implementations of latch register and latch develop ## 2.23.5 - 2023-06-19 ### Fixed -- Fix limits and imports +* Fix limits and imports ## 2.23.3 - 2023-06-19 ### Added -- Memory optimized task type +* Memory optimized task type ## 2.23.2 - 2023-06-14 ### Fixed -- Template generation bug in empty wfs +* Template generation bug in empty wfs ## 2.23.1 - 2023-06-12 ### Fixed -- NFCore template using wrong Latch version +* NFCore template using wrong Latch version ## 2.22.5 - 2023-06-10 ### Added -- When a CLI command fails, metadata (`latch` version, current python, os info, etc) is printed. -- There is now a prompt on failure to generate a crash report. Previously reports were generated automatically which was slow and sometimes error-prone. +* When a CLI command fails, metadata (`latch` version, current python, os info, etc) is printed. +* There is now a prompt on failure to generate a crash report. Previously reports were generated automatically which was slow and sometimes error-prone. ### Fixed -- Bugs that broke support for Python 3.8 users: - - Fixed imports of `functools.cache` - - Fixed `with` statements with multiple contexts +* Bugs that broke support for Python 3.8 users: + + Fixed imports of `functools.cache` + + Fixed `with` statements with multiple contexts ### Dependencies -- Removed `awscli`, `uvloop`, and `prompt-toolkit` as they were unused. +* Removed `awscli`, `uvloop`, and `prompt-toolkit` as they were unused. ## 2.22.4 - 2023-06-08 ### Fixed -- `catalogMultiCreateExperiments` instead of `catalogMultiUpsertExperiments` in registry API +* `catalogMultiCreateExperiments` instead of `catalogMultiUpsertExperiments` in registry API ## 2.22.3 - 2023-06-08 ### Fixed -- `catalogMultiCreateProjects` instead of `catalogMultiUpsertProjects` in registry API +* `catalogMultiCreateProjects` instead of `catalogMultiUpsertProjects` in registry API ## 2.22.2 - 2023-06-08 ### Fixed -- `workspace_id` failing when file is empty +* `workspace_id` failing when file is empty ## 2.22.1 - 2023-06-05 ### Fixed -- `latch cp` failing when uploading a file into a directory without specifying the resulting filename. +* `latch cp` failing when uploading a file into a directory without specifying the resulting filename. ## 2.22.0 - 2023-05-31 ### Fixed -- `latch cp` occasionally throwing an error when finalizing uploads for directories. +* `latch cp` occasionally throwing an error when finalizing uploads for directories. ### Added -- `latch cp` now supports remote -> remote copying (i.e. both source and destination are remote paths). This enables copying files across workspaces -- `latch mv` for moving remote files. +* `latch cp` now supports remote -> remote copying (i.e. both source and destination are remote paths). This enables copying files across workspaces +* `latch mv` for moving remote files. ## 2.21.7 - 2023-05-29 ### Fixed -- Semver violation related to removed `__init__.py` files. These will happen again in the future but a proper major release will be created, communicated, and marketed. +* Semver violation related to removed `__init__.py` files. These will happen again in the future but a proper major release will be created, communicated, and marketed. ## 2.21.6 - 2023-05-29 ### Dependencies -- Upgraded dependency `lytekit` to version `0.14.11`. +* Upgraded dependency `lytekit` to version `0.14.11`. ## 2.21.5 - 2023-05-29 ### Fixed -- More imports in docker/NF-core template workflows have been updated to reflect the import changes outlined in the previous version. +* More imports in docker/NF-core template workflows have been updated to reflect the import changes outlined in the previous version. ## 2.21.4 - 2023-05-29 ### Fixed -- Imports in docker/NF-core template workflows have been updated to reflect the import changes outlined in the previous version. +* Imports in docker/NF-core template workflows have been updated to reflect the import changes outlined in the previous version. ## 2.21.3 - 2023-05-26 ### Added -- NFCore example workflow +* NFCore example workflow ### Changed -- Replace docker example workflow with blastp -- Docker image selection when creating an empty workflow -- Workflow Name, Author Name prompts when creating an empty workflow +* Replace docker example workflow with blastp +* Docker image selection when creating an empty workflow +* Workflow Name, Author Name prompts when creating an empty workflow -- `latch cp` has been rewritten and now allows for latch paths of the form - - `latch:///a/b/c` - - `latch://xxx.account/a/b/c` where `xxx` is the account ID - - `latch://shared.xxx.account/a/b/c` - - `latch://shared/a/b/c` - - `latch://mount/a/b/c` - - `latch://xxx.node` where `xxx` is the data ID (viewable in Latch Console) +* `latch cp` has been rewritten and now allows for latch paths of the form + + `latch:///a/b/c` + + `latch://xxx.account/a/b/c` where `xxx` is the account ID + + `latch://shared.xxx.account/a/b/c` + + `latch://shared/a/b/c` + + `latch://mount/a/b/c` + + `latch://xxx.node` where `xxx` is the data ID (viewable in Latch Console) ### Removed -- Unnecessary imports in `__init__.py` files have been removed. Statements like `from latch.types import LatchFile` will no longer work, and such objects should be imported from their defining files instead (in this example, the correct import is `from latch.types.file import LatchFile`) +* Unnecessary imports in `__init__.py` files have been removed. Statements like `from latch.types import LatchFile` will no longer work, and such objects should be imported from their defining files instead (in this example, the correct import is `from latch.types.file import LatchFile`) ## 2.19.11 - 2023-05-16 ### Fixed -- Revert an undocumented change that caused custom task settings to not work +* Revert an undocumented change that caused custom task settings to not work ## 2.19.10 - 2023-05-16 ### Fixed -- Typo in `latch init` R template +* Typo in `latch init` R template ## 2.19.9 - 2023-05-12 ### Fixed -- `latch cp` should automatically detect file content type +* `latch cp` should automatically detect file content type ## 2.19.8 - 2023-05-11 ### Fixed -- Registry API crashes when resolving paths if `~/.latch/workspace` does not exist +* Registry API crashes when resolving paths if `~/.latch/workspace` does not exist ## 2.19.7 - 2023-05-09 ### Added -- `latch register` will ask for confirmation unless `--yes` is provided on the command line +* `latch register` will ask for confirmation unless `--yes` is provided on the command line ### Changed -- `latch register --remote` is now the default. Use `--no-remote` to build the workflow image locally +* `latch register --remote` is now the default. Use `--no-remote` to build the workflow image locally ### Fixed -- `latch register --remote` will no longer ask for host key fingerprint verification +* `latch register --remote` will no longer ask for host key fingerprint verification ## 2.19.6 - 2023-05-08 ### Fixed -- Registry APIs should properly resolve files when using workspaces instead of always using the signer account +* Registry APIs should properly resolve files when using workspaces instead of always using the signer account ## 2.19.5 - 2023-05-06 ### Fixed -- `latch workspace` options should be ordered alphabetically +* `latch workspace` options should be ordered alphabetically ## 2.19.4 - 2023-05-04 ### Fixed -- Conda template registration issue and run in correct environment issue - +* Conda template registration issue and run in correct environment issue # Latch SDK Changelog ## 2.19.3 - 2023-04-26 ### Fixed -- Tasks stuck initializing on nodes that ran multiple tasks before +* Tasks stuck initializing on nodes that ran multiple tasks before ## 2.19.2 - 2023-04-24 ### Dependencies -- Upgrades lytekit to `0.14.10` +* Upgrades lytekit to `0.14.10` ## 2.19.1 - 2023-04-21 ### Changed -- `latch cp` now has a progress bar for downloads (previously they only showed for uploads) +* `latch cp` now has a progress bar for downloads (previously they only showed for uploads) ## 2.19.0 - 2023-04-14 ### Added -- Functions for creating/deleting Projects and Tables, and creating Table columns in the Registry API +* Functions for creating/deleting Projects and Tables, and creating Table columns in the Registry API ## 2.18.3 - 2023-04-12 ### Fixed -- Registry table updates should work with columns that have spaces in names +* Registry table updates should work with columns that have spaces in names ## 2.18.2 - 2023-04-11 ### Changed -- Improved Registry API `__str__` and `__repr__` +* Improved Registry API `__str__` and `__repr__` ## 2.18.1 - 2023-04-08 ### Fixed -- Registry API should work in an running asyncio event loop +* Registry API should work in an running asyncio event loop ## 2.18.0 - 2023-04-08 ### Added -- A new API for interacting with Latch Registry +* A new API for interacting with Latch Registry ### Dependencies -- Added `gql` and `aiohttp` as dependencies +* Added `gql` and `aiohttp` as dependencies ## 2.17.2 - 2023-04-07 ### Fixed -- Prevent `latch cp` from hitting the s3 part limits which causes large +* Prevent `latch cp` from hitting the s3 part limits which causes large file uploads to fail ## 2.17.1 - 2023-04-05 ### Fixed -- Switched a dictionary union from `|=` notation to a manual for-loop to +* Switched a dictionary union from `|=` notation to a manual for-loop to maintain support for Python 3.8. ## 2.17.0 - 2023-04-01 ### Added -- Option to disable default bulk execution mechanism when an alternative (e.g. using a samplesheet parameter) is supported by the workflow itself +* Option to disable default bulk execution mechanism when an alternative (e.g. using a samplesheet parameter) is supported by the workflow itself ## 2.16.0 - 2023-04-01 ### Added -- Verified Trim Galore adapter trimming workflow stub +* Verified Trim Galore adapter trimming workflow stub ## 2.15.1 - 2023-03-30 ### Fixed -- Custom tasks with less than 32 cores receiving incorrect toleration +* Custom tasks with less than 32 cores receiving incorrect toleration ## 2.15.0 - 2023-03-29 ### Added -- Verified MAFFT alignment workflow stub +* Verified MAFFT alignment workflow stub ## 2.14.2 - 2023-03-24 ### Fixed -- Parameter flow forks should preserve the order of branches +* Parameter flow forks should preserve the order of branches ## 2.14.1 - 2023-03-21 ### Fixed -- `latch` commands which require authentication prompt user for token when no browser is present on machine +* `latch` commands which require authentication prompt user for token when no browser is present on machine ## 2.14.0 - 2023.03-18 ### Added -- SampleSheet metadata to `LatchParameter` -- allows for importing samples from Registry +* SampleSheet metadata to `LatchParameter` -- allows for importing samples from Registry ## 2.13.5 - 2023-02-21 ### Fixed -- `latch register` ssh-keygen bug when `.latch` folder does not exist +* `latch register` ssh-keygen bug when `.latch` folder does not exist ## 2.13.4 - 2023-02-21 ### Dependencies -- Upgrades lytekit to `0.14.9` +* Upgrades lytekit to `0.14.9` ## 2.13.3 - 2023-02-21 ### Fixed -- Docker template uses correct base image +* Docker template uses correct base image ## 2.13.2 - 2023-02-21 ### Fixed -- Internal state file should be automatically created when running `latch register` and `latch develop` +* Internal state file should be automatically created when running `latch register` and `latch develop` ### Added -- `latch init`: Docker in Docker template workflow -- `latch init`: Docker base image -- Small, medium, and large tasks use the [Sysbox runtime](https://github.com/nestybox/sysbox) to run Docker and other system software within task containers +* `latch init`: Docker in Docker template workflow +* `latch init`: Docker base image +* Small, medium, and large tasks use the [Sysbox runtime](https://github.com/nestybox/sysbox) to run Docker and other system software within task containers ## 2.13.1 - 2023-02-17 ### Fixed -- Add latch/latch_cli/services/init/common to pypi release +* Add latch/latch_cli/services/init/common to pypi release ## 2.13.0 - 2023-02-17 ### Added -- The `latch dockerfile` command which auto-generates a Dockerfile from files in the workflow directory. -- The `latch init` command can use base images with hardware acceleration using the `--cuda` and the `--opencl` flags -- The `latch init` command does not populate the workflow directory with a Dockerfile by default -- The `latch init` command will populate the workflow directory with a Dockerfile if passed `--dockerfile` -- The `latch register` and `latch develop` commands auto-generate a dockerfile from files in the workflow directory if no Dockerfile is present -- Documentation for the auto-generated Dockerfile feature +* The `latch dockerfile` command which auto-generates a Dockerfile from files in the workflow directory. +* The `latch init` command can use base images with hardware acceleration using the `--cuda` and the `--opencl` flags +* The `latch init` command does not populate the workflow directory with a Dockerfile by default +* The `latch init` command will populate the workflow directory with a Dockerfile if passed `--dockerfile` +* The `latch register` and `latch develop` commands auto-generate a dockerfile from files in the workflow directory if no Dockerfile is present +* Documentation for the auto-generated Dockerfile feature ### Fixed -- Quickstart tutorial is written factually -- Getting started docs are written factually +* Quickstart tutorial is written factually +* Getting started docs are written factually ## 2.12.1 - 2023-02-08 ### Added -- `latch develop` documentation updates +* `latch develop` documentation updates ### Fixed -- `latch develop` throws error if user does not have rsync installed -- `pip install latch` installs the `watchfiles` package for `latch develop` +* `latch develop` throws error if user does not have rsync installed +* `pip install latch` installs the `watchfiles` package for `latch develop` ## 2.11.1 - 2023-01-25 ### Fixed -- LatchDir initialized with local path initialized to Path object fails on upload +* LatchDir initialized with local path initialized to Path object fails on upload ## 2.12.0 - 2023-02-06 ### Added -- `latch develop` drops users directly into a shell in their docker environment. Local changes in the workflow directory and any subdirectories are automatically synced into the environment. Deleted local files are not deleted in the environment. However, any additions or modifications to files and directories are propagated. +* `latch develop` drops users directly into a shell in their docker environment. Local changes in the workflow directory and any subdirectories are automatically synced into the environment. Deleted local files are not deleted in the environment. However, any additions or modifications to files and directories are propagated. ### Removed -- latch develop no longer drops user into REPL with multiple options -- it goes straight to a shell. +* latch develop no longer drops user into REPL with multiple options -- it goes straight to a shell. ## 2.11.1 - 2023-01-25 ### Fixed -- LatchDir initialized with local path initialized to Path object fails on upload +* LatchDir initialized with local path initialized to Path object fails on upload ## 2.11.0 - 2023-01-20 ### Added -- Use best practices in `latch init` templates - - `LatchOutputDir` used to indicate output location on Latch - - Regex rules used to validate files - - Splits tasks into files - - Include empty template - - Remove yaml metadata from docstring - - Use messages in examples - - Error handling - - Add LICENSE file - - Add README file -- Allow user to select template in GUI or pass flag -- Allow user to run `latch init .` +* Use best practices in `latch init` templates + + `LatchOutputDir` used to indicate output location on Latch + + Regex rules used to validate files + + Splits tasks into files + + Include empty template + + Remove yaml metadata from docstring + + Use messages in examples + + Error handling + + Add LICENSE file + + Add README file +* Allow user to select template in GUI or pass flag +* Allow user to run `latch init .` ### Fixed -- LatchDir type transformer bug with Annotated types - - LatchOutputDir is fixed +* LatchDir type transformer bug with Annotated types + + LatchOutputDir is fixed ## 2.10.0 - 2023-01-14 ### Added -- The `latch develop` command, and with it an ecosystem supporting local +* The `latch develop` command, and with it an ecosystem supporting local development and faster debugging. -- The `latch cp` command now displays a x number of files out of n indicator +* The `latch cp` command now displays a x number of files out of n indicator and displays which stage of the download is going on (network request to get presigned urls vs downloading blob data). -- A new error that is thrown when there is an inconsistency between a - `LatchMetadata` object and its associated workflow's parameters. -- The function `get_secret` which allows users to reference secrets they've +* A new error that is thrown when there is an inconsistency between a +`LatchMetadata` object and its associated workflow's parameters. +* The function `get_secret` which allows users to reference secrets they've uploaded to the Latch platform from within a workflow. ### Deprecated -- The commands `latch rm`, `latch mkdir`, and `latch touch`. -- The operators `left_join`, `right_join`, `inner_join`, `outer_join`, - `group_tuple`, `latch_filter`, and `combine` +* The commands `latch rm`, `latch mkdir`, and `latch touch`. +* The operators `left_join`, `right_join`, `inner_join`, `outer_join`, +`group_tuple` , `latch_filter` , and `combine` ### Removed -- Removed a broken SDK test (launching CRISPResso2) +* Removed a broken SDK test (launching CRISPResso2) ### Fixed -- `requests` library given higher version lower bound to fix warning with one of its dependencies -- `lytekit` version updated to - - pin `numpy` to version `1.22` (breaking changes in later versions of this library) - - have better behavior when downloading directories during local development - - force retry on connection closed on file uploads (POST requests more generally) -- `latch get-params` will escape class attribute names (representation of Enum +* `requests` library given higher version lower bound to fix warning with one of its dependencies +* `lytekit` version updated to + + pin `numpy` to version `1.22` (breaking changes in later versions of this library) + + have better behavior when downloading directories during local development + + force retry on connection closed on file uploads (POST requests more generally) +* `latch get-params` will escape class attribute names (representation of Enum type) if they are python keywords -- `latch preview` now requires a directory argument instead of a workflow name +* `latch preview` now requires a directory argument instead of a workflow name argument, and now behaves consistently with regular parameter interface generation. -- The crash reporter now prints stack traces of caught exceptions in the +* The crash reporter now prints stack traces of caught exceptions in the correct order -- `latch develop` now throws an error when run on a workflow that hasn't been +* `latch develop` now throws an error when run on a workflow that hasn't been registered yet. -- Reworked how internal configs are stored, eschewing a flat dictionary of API +* Reworked how internal configs are stored, eschewing a flat dictionary of API endpoints in favor of a nested dataclass. This removes a small class of potential mistakes arising from misspelling, and gives the benefit of IDE intellisense. -- Made both configs singletons. +* Made both configs singletons. ## 2.10.1 - 2023-01-18 ### Fixed -- Fixed issue with registering libraries containing nested imports used as - subclasses (eg. `torch`) +* Fixed issue with registering libraries containing nested imports used as + subclasses (eg. `torch` ) diff --git a/setup.py b/setup.py index 051325ab..5aa0de68 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ setup( name="latch", - version="v2.31.0", + version="v2.31.1", author_email="kenny@latch.bio", description="The Latch SDK", packages=find_packages(), From c5934ff384496c41ec08e901659515cf1402aaf8 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Thu, 10 Aug 2023 16:38:51 -0700 Subject: [PATCH 185/356] improve automatic snakemake metadata example Signed-off-by: maximsmol --- latch_cli/centromere/ctx.py | 46 ++++++++++++++++++++++++++++++-- latch_cli/snakemake/serialize.py | 41 ++++++++++++++-------------- 2 files changed, 64 insertions(+), 23 deletions(-) diff --git a/latch_cli/centromere/ctx.py b/latch_cli/centromere/ctx.py index ee8f31a6..d2bd1dca 100644 --- a/latch_cli/centromere/ctx.py +++ b/latch_cli/centromere/ctx.py @@ -128,7 +128,7 @@ def __init__( import latch.types.metadata as metadata from ..snakemake.serialize import ( - snakemake_metadata_example, + get_snakemake_metadata_example, snakemake_workflow_extractor, ) @@ -158,11 +158,53 @@ def __init__( fg="red", ) click.secho("\nExample ", fg="red", nl=False) + + snakemake_metadata_example = get_snakemake_metadata_example( + pkg_root.name + ) click.secho(f"`{meta}`", bold=True, fg="red", nl=False) click.secho( - f" file:{snakemake_metadata_example}", + f" file:\n```\n{snakemake_metadata_example}```", fg="red", ) + if click.confirm( + click.style( + "Generate example metadata file now?", + bold=True, + fg="red", + ), + default=True, + ): + meta.write_text(snakemake_metadata_example) + + import platform + + system = platform.system() + if system in { + "Windows", + "Linux", + "Darwin", + } and click.confirm( + click.style( + "Open the generated file?", bold=True, fg="red" + ), + default=True, + ): + import subprocess + + if system == "Linux": + res = subprocess.run(["xdg-open", meta]).returncode + elif system == "Darwin": + res = subprocess.run(["open", meta]).returncode + elif system == "Windows": + import os + + res = os.system(str(meta.resolve())) + else: + res = None + + if res is not None and res != 0: + click.secho("Failed to open file", fg="red") sys.exit(1) assert metadata._snakemake_metadata is not None diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index bf612898..2968a221 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -42,28 +42,27 @@ def should_register_with_admin(entity: RegistrableEntity) -> bool: return isinstance(entity, get_args(RegistrableEntity)) -snakemake_metadata_example = """ -``` -from pathlib import Path -from latch.types.metadata import SnakemakeMetadata, SnakemakeFileParameter -from latch.types.file import LatchFile -from latch.types.metadata import LatchAuthor, LatchMetadata - -SnakemakeMetadata( - display_name="My Snakemake Workflow", - author=LatchAuthor( - name="John Doe", - ), - parameters={ - "foo" : SnakemakeFileParameter( - display_name="Some Param", - type=LatchFile, - path=Path("foo.txt"), +def get_snakemake_metadata_example(name: str) -> str: + return dedent(f""" + from pathlib import Path + from latch.types.metadata import SnakemakeMetadata, SnakemakeFileParameter + from latch.types.file import LatchFile + from latch.types.metadata import LatchAuthor, LatchMetadata + + SnakemakeMetadata( + display_name={repr(name)}, + author=LatchAuthor( + name="Anonymous", + ), + parameters={{ + "foo": SnakemakeFileParameter( + display_name="Some Param", + type=LatchFile, + path=Path("foo.txt"), + ) + }}, ) - } -) -``` -""" + """).lstrip() def ensure_snakemake_metadata_exists(): From f932b19db90a780d9ebf9bfbcbc9b1897a365a88 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Thu, 10 Aug 2023 17:11:39 -0700 Subject: [PATCH 186/356] improve DX Signed-off-by: maximsmol --- latch_cli/snakemake/serialize.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index 2968a221..a2a8bb11 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -1,6 +1,7 @@ import os import sys import textwrap +import traceback from pathlib import Path from textwrap import dedent from typing import List, Optional, Set, Union, get_args @@ -55,10 +56,10 @@ def get_snakemake_metadata_example(name: str) -> str: name="Anonymous", ), parameters={{ - "foo": SnakemakeFileParameter( - display_name="Some Param", + "example": SnakemakeFileParameter( + display_name="Example Parameter", type=LatchFile, - path=Path("foo.txt"), + path=Path("example.txt"), ) }}, ) @@ -135,7 +136,7 @@ def __enter__(self) -> Self: return self - def __exit__(self, typ, value, traceback): + def __exit__(self, typ, value, tb): os.chdir(self._old_cwd) if typ is None: @@ -144,6 +145,18 @@ def __exit__(self, typ, value, traceback): if not isinstance(value, WorkflowError): return False + msg = str(value) + if ( + "Workflow defines configfile config.yaml but it is not present or" + " accessible" + in msg + ): + # todo(maximsmol): print the expected config path + traceback.print_exception(typ, value, tb) + click.secho("\n\n\nHint: ", fg="red", bold=True, nl=False, err=True) + click.secho("Snakemake could not find a config file", fg="red", err=True) + sys.exit(1) + # todo(maximsmol): handle specific errors # WorkflowError: Failed to open source file /Users/maximsmol/projects/latchbio/latch/test/CGI_WGS_GATK_Pipeline/Snakefiles/CGI_WGS_GATK_Pipeline/Snakefiles/calc_frag_len.smk # FileNotFoundError: [Errno 2] No such file or directory: '/Users/maximsmol/projects/latchbio/latch/test/CGI_WGS_GATK_Pipeline/Snakefiles/CGI_WGS_GATK_Pipeline/Snakefiles/calc_frag_len.smk' From ac96ab876efa1810d6f88b2172e6577e9565e885 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Thu, 10 Aug 2023 17:21:17 -0700 Subject: [PATCH 187/356] try rewriting some stuff Signed-off-by: maximsmol --- latch_cli/snakemake/single_task_snakemake.py | 60 +++++--------------- 1 file changed, 15 insertions(+), 45 deletions(-) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 5916509e..76c3b830 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -165,53 +165,25 @@ def emit_overrides(self, token): emitted_overrides_per_type: Dict[str, Set[str]] = {} -def replace_block(self, token, force_block_end=False): - if self.lasttoken == "\n" and is_comment(token): - # ignore lines containing only comments - self.line -= 1 - if force_block_end or self.is_block_end(token): - yield from self.decorate_end(token) - yield "\n", token - raise StopAutomaton(token) - - if is_newline(token): - self.line += 1 - yield token.string, token - - elif not (is_indent(token) or is_dedent(token)): - if is_comment(token): - yield token.string, token - else: - try: - at_newline = self.lasttoken == "\n" - - # old snakemake sometime does not put a newline after the decorate parenthesis - at_start = self.line == 0 and self.lasttoken[-1] == "(" +def skipping_block_content(self, token): + if self.rulename not in rules: + return - if at_newline or at_start: - emitted_overrides = emitted_overrides_per_type.setdefault( - type(self).__name__, set() - ) - - if ( - self.rulename in rules - and self.rulename not in emitted_overrides - ): - yield from emit_overrides(self, token) - emitted_overrides.add(self.rulename) - - yield "#", token - except: - traceback.print_exc() + emitted_overrides = emitted_overrides_per_type.setdefault( + type(self).__name__, set() + ) + if self.rulename not in emitted_overrides: + return - yield from self.block_content(token) + yield from emit_overrides(self, token) + emitted_overrides.add(self.rulename) -Input.block = replace_block -Output.block = replace_block -Params.block = replace_block -Benchmark.block = replace_block -Log.block = replace_block +Input.block_content = skipping_block_content +Output.block_content = skipping_block_content +Params.block_content = skipping_block_content +Benchmark.block_content = skipping_block_content +Log.block_content = skipping_block_content class SkippingRule(Rule): @@ -220,7 +192,6 @@ def start(self, aux=""): yield from super().start(aux) return - yield "#" for t in super().start(aux): yield t.replace("\n", "\n# ") @@ -229,7 +200,6 @@ def end(self): yield from super().end() return - yield "#" for t in super().end(): yield t.replace("\n", "\n# ") From 85dd7ec7cf6cc1c77f0330ba543228a54c969632 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Thu, 10 Aug 2023 17:38:04 -0700 Subject: [PATCH 188/356] fixies Signed-off-by: maximsmol --- latch_cli/snakemake/single_task_snakemake.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 76c3b830..faa95e12 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -192,6 +192,7 @@ def start(self, aux=""): yield from super().start(aux) return + yield "#" for t in super().start(aux): yield t.replace("\n", "\n# ") @@ -203,6 +204,8 @@ def end(self): for t in super().end(): yield t.replace("\n", "\n# ") + yield "\n" + def block_content(self, token): if self.rulename in rules: yield from super().block_content(token) From dedd88c975b40ee5b23650a4e93687a80f1a7cfc Mon Sep 17 00:00:00 2001 From: maximsmol Date: Thu, 10 Aug 2023 17:45:11 -0700 Subject: [PATCH 189/356] try another thing Signed-off-by: maximsmol --- latch_cli/snakemake/single_task_snakemake.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index faa95e12..6a22fab0 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -214,6 +214,8 @@ def block_content(self, token): for t in super().block_content(token): yield t[0].replace("\n", "\n# "), t[1] + yield "\n" + class SkippingCheckpoint(SkippingRule): def start(self): From d3b2c486701c0c53f6c189396fc00074fa0cea5f Mon Sep 17 00:00:00 2001 From: maximsmol Date: Thu, 10 Aug 2023 18:04:30 -0700 Subject: [PATCH 190/356] going nuclear Signed-off-by: maximsmol --- latch_cli/snakemake/single_task_snakemake.py | 25 ++++++-------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 6a22fab0..c75d0942 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -172,7 +172,7 @@ def skipping_block_content(self, token): emitted_overrides = emitted_overrides_per_type.setdefault( type(self).__name__, set() ) - if self.rulename not in emitted_overrides: + if self.rulename in emitted_overrides: return yield from emit_overrides(self, token) @@ -188,33 +188,22 @@ def skipping_block_content(self, token): class SkippingRule(Rule): def start(self, aux=""): - if self.rulename in rules: - yield from super().start(aux) + if self.rulename not in rules: return - yield "#" - for t in super().start(aux): - yield t.replace("\n", "\n# ") + yield from super().start(aux) def end(self): - if self.rulename in rules: - yield from super().end() + if self.rulename not in rules: return - for t in super().end(): - yield t.replace("\n", "\n# ") - - yield "\n" + yield from super().end() def block_content(self, token): - if self.rulename in rules: - yield from super().block_content(token) + if self.rulename not in rules: return - for t in super().block_content(token): - yield t[0].replace("\n", "\n# "), t[1] - - yield "\n" + yield from super().block_content(token) class SkippingCheckpoint(SkippingRule): From 31c545610b3bc7d18134b21f4f42e877eb4dbf84 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 11 Aug 2023 10:09:33 -0700 Subject: [PATCH 191/356] only --use-conda if necessary Signed-off-by: maximsmol --- latch_cli/snakemake/workflow.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 8d513c8f..a70d53c6 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1159,12 +1159,14 @@ def get_fn_code( if isinstance(self.job, GroupJob): jobs = self.job.jobs + need_conda = any(x.conda_env is not None for x in jobs) + snakemake_args = [ "-m", "latch_cli.snakemake.single_task_snakemake", "-s", snakefile_path_in_container, - "--use-conda", + *(["--use-conda"] if need_conda else []), "--target-jobs", *jobs_cli_args(jobs), "--allowed-rules", From 6e437c27cfef28c6cf3ba141f247d85733e5e69a Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 11 Aug 2023 10:26:53 -0700 Subject: [PATCH 192/356] add mkdir for logs Signed-off-by: maximsmol --- latch_cli/main.py | 2 +- latch_cli/snakemake/workflow.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/latch_cli/main.py b/latch_cli/main.py index 0343cafe..3592edb9 100644 --- a/latch_cli/main.py +++ b/latch_cli/main.py @@ -73,7 +73,7 @@ def dockerfile(pkg_root: str): return generate_dockerfile(source, dest) - click.secho(f"Successfully generated dockerfile `{dest}`", fg="green") + click.secho(f"\nSuccessfully generated dockerfile `{dest}`", fg="green") @main.command("register") diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index a70d53c6..07c9246f 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1240,6 +1240,7 @@ def get_fn_code( tail = None if len(log_files) == 1: log = Path(log_files[0]) + log.parent.mkdir(parents=True, exist_ok=True) log.touch() print(f"Tailing the only log file: {{log}}") From 248f223bdc2b3d409cd6090e1e46ec768857e9ba Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 11 Aug 2023 11:29:16 -0700 Subject: [PATCH 193/356] keep outputs unexpanded so we can infer wildcards. does this break anything else? Signed-off-by: maximsmol --- latch_cli/main.py | 2 +- latch_cli/snakemake/single_task_snakemake.py | 6 ------ latch_cli/snakemake/workflow.py | 2 +- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/latch_cli/main.py b/latch_cli/main.py index 3592edb9..0343cafe 100644 --- a/latch_cli/main.py +++ b/latch_cli/main.py @@ -73,7 +73,7 @@ def dockerfile(pkg_root: str): return generate_dockerfile(source, dest) - click.secho(f"\nSuccessfully generated dockerfile `{dest}`", fg="green") + click.secho(f"Successfully generated dockerfile `{dest}`", fg="green") @main.command("register") diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index c75d0942..598ac465 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -1,7 +1,6 @@ import json import os import sys -import traceback from itertools import chain from textwrap import dedent from typing import Dict, Set @@ -17,11 +16,6 @@ Python, Rule, Shell, - StopAutomaton, - is_comment, - is_dedent, - is_indent, - is_newline, ) sys.stdout.reconfigure(line_buffering=True) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 07c9246f..a9eb1085 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1197,7 +1197,7 @@ def get_fn_code( for job in jobs: snakemake_data["rules"][job.rule.name] = { "inputs": named_list_to_json(job.input), - "outputs": named_list_to_json(job.output), + "outputs": named_list_to_json(job.rule.output), "params": named_list_to_json(job.params), "benchmark": job.benchmark, "log": job.log, From dea6c57a53eb23d79cd6e0b360d801697ceaa8c7 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 11 Aug 2023 12:45:50 -0700 Subject: [PATCH 194/356] add debug Signed-off-by: maximsmol --- latch_cli/snakemake/single_task_snakemake.py | 12 ++++++++++++ latch_cli/snakemake/workflow.py | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 598ac465..480ef78a 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -6,6 +6,7 @@ from typing import Dict, Set import snakemake +from snakemake.dag import DAG from snakemake.parser import ( INDENT, Benchmark, @@ -220,5 +221,16 @@ def __init__(self, snakefile, rulename, base_indent=0, dedent=0, root=True): SkippingRule.subautomata["shell"] = ReplacingShell +_dag_init = DAG.init + + +def dag_init(self: DAG, progress=False): + res = _dag_init(self, progress) + print(self.jobs) + return res + + +DAG.init = _dag_init + # Run snakemake snakemake.main() diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index a9eb1085..07c9246f 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1197,7 +1197,7 @@ def get_fn_code( for job in jobs: snakemake_data["rules"][job.rule.name] = { "inputs": named_list_to_json(job.input), - "outputs": named_list_to_json(job.rule.output), + "outputs": named_list_to_json(job.output), "params": named_list_to_json(job.params), "benchmark": job.benchmark, "log": job.log, From b071e5b2225da297981193fcadf20e0f17d1569f Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 11 Aug 2023 12:51:54 -0700 Subject: [PATCH 195/356] oops Signed-off-by: maximsmol --- latch_cli/snakemake/single_task_snakemake.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 480ef78a..a4bd5978 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -226,11 +226,13 @@ def __init__(self, snakefile, rulename, base_indent=0, dedent=0, root=True): def dag_init(self: DAG, progress=False): res = _dag_init(self, progress) + print("\n\n\n >>> DAG INIT \n\n\n") print(self.jobs) + print("\n\n\n <<< DAG INIT \n\n\n") return res -DAG.init = _dag_init +DAG.init = dag_init # Run snakemake snakemake.main() From 93eb00a4cfae06faaf5b8dd22f8fc3faa02224c8 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 11 Aug 2023 13:03:03 -0700 Subject: [PATCH 196/356] print more stuff Signed-off-by: maximsmol --- latch_cli/snakemake/single_task_snakemake.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index a4bd5978..9663db32 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -227,7 +227,10 @@ def __init__(self, snakefile, rulename, base_indent=0, dedent=0, root=True): def dag_init(self: DAG, progress=False): res = _dag_init(self, progress) print("\n\n\n >>> DAG INIT \n\n\n") - print(self.jobs) + for j in self.jobs: + print(j.rule) + print(j.wildcards) + print() print("\n\n\n <<< DAG INIT \n\n\n") return res From bcea52225b9bfb5971bbeb588cdacf246d45c92b Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 11 Aug 2023 13:22:03 -0700 Subject: [PATCH 197/356] log more Signed-off-by: maximsmol --- latch_cli/snakemake/single_task_snakemake.py | 59 ++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 9663db32..c47be53b 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -221,6 +221,65 @@ def __init__(self, snakefile, rulename, base_indent=0, dedent=0, root=True): SkippingRule.subautomata["shell"] = ReplacingShell +_dag__init__ = DAG.__init__ + + +def dag__init__( + self, + workflow, + rules=None, + dryrun=False, + targetfiles=None, + targetrules=None, + target_jobs_def=None, + forceall=False, + forcerules=None, + forcefiles=None, + priorityfiles=None, + priorityrules=None, + untilfiles=None, + untilrules=None, + omitfiles=None, + omitrules=None, + ignore_ambiguity=False, + force_incomplete=False, + ignore_incomplete=False, + notemp=False, + keep_remote_local=False, + batch=None, +): + print("\n\n\n >>> DAG __INIT__ \n\n\n") + print(target_jobs_def) + print("\n\n\n <<< DAG __INIT__ \n\n\n") + + _dag__init__( + self, + workflow, + rules=None, + dryrun=False, + targetfiles=None, + targetrules=None, + target_jobs_def=None, + forceall=False, + forcerules=None, + forcefiles=None, + priorityfiles=None, + priorityrules=None, + untilfiles=None, + untilrules=None, + omitfiles=None, + omitrules=None, + ignore_ambiguity=False, + force_incomplete=False, + ignore_incomplete=False, + notemp=False, + keep_remote_local=False, + batch=None, + ) + + +DAG.__init__ = dag__init__ + _dag_init = DAG.init From 7a4901b7d74c65064a3bb62aeda95695dfd0a02e Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 11 Aug 2023 13:27:01 -0700 Subject: [PATCH 198/356] is it dag cleanup? Signed-off-by: maximsmol --- latch_cli/snakemake/single_task_snakemake.py | 60 +++++++++++++------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index c47be53b..85397a68 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -255,26 +255,26 @@ def dag__init__( _dag__init__( self, workflow, - rules=None, - dryrun=False, - targetfiles=None, - targetrules=None, - target_jobs_def=None, - forceall=False, - forcerules=None, - forcefiles=None, - priorityfiles=None, - priorityrules=None, - untilfiles=None, - untilrules=None, - omitfiles=None, - omitrules=None, - ignore_ambiguity=False, - force_incomplete=False, - ignore_incomplete=False, - notemp=False, - keep_remote_local=False, - batch=None, + rules, + dryrun, + targetfiles, + targetrules, + target_jobs_def, + forceall, + forcerules, + forcefiles, + priorityfiles, + priorityrules, + untilfiles, + untilrules, + omitfiles, + omitrules, + ignore_ambiguity, + force_incomplete, + ignore_incomplete, + notemp, + keep_remote_local, + batch, ) @@ -296,5 +296,25 @@ def dag_init(self: DAG, progress=False): DAG.init = dag_init +_dag_cleanup = DAG.cleanup + + +def dag_cleanup(self: DAG): + print("\n\n\n >>> DAG CLEANUP BEFORE \n\n\n") + for j in self.jobs: + print(j.rule) + print(j.wildcards) + print() + print("\n\n\n <<< DAG CLEANUP BEFORE \n\n\n") + _dag_cleanup(self) + print("\n\n\n >>> DAG CLEANUP AFTER \n\n\n") + for j in self.jobs: + print(j.rule) + print(j.wildcards) + print() + print("\n\n\n <<< DAG CLEANUP AFTER \n\n\n") + + +DAG.cleanup = dag_cleanup # Run snakemake snakemake.main() From 879fcadb3710dcceacb85635b783f399088b56a2 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 11 Aug 2023 13:48:06 -0700 Subject: [PATCH 199/356] is it wildcard getter Signed-off-by: maximsmol --- latch_cli/snakemake/single_task_snakemake.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 85397a68..a9b8c07a 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -18,6 +18,7 @@ Rule, Shell, ) +from snakemake.rules import Rule as RRule sys.stdout.reconfigure(line_buffering=True) sys.stderr.reconfigure(line_buffering=True) @@ -316,5 +317,13 @@ def dag_cleanup(self: DAG): DAG.cleanup = dag_cleanup + + +def get_wildcards(self, requested_output, wildcards_dict=None): + return wildcards_dict + + +RRule.get_wildcards = get_wildcards + # Run snakemake snakemake.main() From 377a9f9db7bb749e30b67ef5fecd6d0390d21b32 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 11 Aug 2023 14:14:47 -0700 Subject: [PATCH 200/356] i have become monkey, the patcher of snakes Signed-off-by: maximsmol --- latch_cli/snakemake/single_task_snakemake.py | 97 -------------------- 1 file changed, 97 deletions(-) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index a9b8c07a..3fe17fab 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -6,7 +6,6 @@ from typing import Dict, Set import snakemake -from snakemake.dag import DAG from snakemake.parser import ( INDENT, Benchmark, @@ -222,102 +221,6 @@ def __init__(self, snakefile, rulename, base_indent=0, dedent=0, root=True): SkippingRule.subautomata["shell"] = ReplacingShell -_dag__init__ = DAG.__init__ - - -def dag__init__( - self, - workflow, - rules=None, - dryrun=False, - targetfiles=None, - targetrules=None, - target_jobs_def=None, - forceall=False, - forcerules=None, - forcefiles=None, - priorityfiles=None, - priorityrules=None, - untilfiles=None, - untilrules=None, - omitfiles=None, - omitrules=None, - ignore_ambiguity=False, - force_incomplete=False, - ignore_incomplete=False, - notemp=False, - keep_remote_local=False, - batch=None, -): - print("\n\n\n >>> DAG __INIT__ \n\n\n") - print(target_jobs_def) - print("\n\n\n <<< DAG __INIT__ \n\n\n") - - _dag__init__( - self, - workflow, - rules, - dryrun, - targetfiles, - targetrules, - target_jobs_def, - forceall, - forcerules, - forcefiles, - priorityfiles, - priorityrules, - untilfiles, - untilrules, - omitfiles, - omitrules, - ignore_ambiguity, - force_incomplete, - ignore_incomplete, - notemp, - keep_remote_local, - batch, - ) - - -DAG.__init__ = dag__init__ - -_dag_init = DAG.init - - -def dag_init(self: DAG, progress=False): - res = _dag_init(self, progress) - print("\n\n\n >>> DAG INIT \n\n\n") - for j in self.jobs: - print(j.rule) - print(j.wildcards) - print() - print("\n\n\n <<< DAG INIT \n\n\n") - return res - - -DAG.init = dag_init - -_dag_cleanup = DAG.cleanup - - -def dag_cleanup(self: DAG): - print("\n\n\n >>> DAG CLEANUP BEFORE \n\n\n") - for j in self.jobs: - print(j.rule) - print(j.wildcards) - print() - print("\n\n\n <<< DAG CLEANUP BEFORE \n\n\n") - _dag_cleanup(self) - print("\n\n\n >>> DAG CLEANUP AFTER \n\n\n") - for j in self.jobs: - print(j.rule) - print(j.wildcards) - print() - print("\n\n\n <<< DAG CLEANUP AFTER \n\n\n") - - -DAG.cleanup = dag_cleanup - def get_wildcards(self, requested_output, wildcards_dict=None): return wildcards_dict From 31bf2ece25497c61d362c99523f24b8ae39b7ad1 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Wed, 16 Aug 2023 13:05:15 -0700 Subject: [PATCH 201/356] del extra import Signed-off-by: Ayush Kamat --- latch_cli/main.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/latch_cli/main.py b/latch_cli/main.py index b264bb64..5e7685ee 100644 --- a/latch_cli/main.py +++ b/latch_cli/main.py @@ -1,7 +1,6 @@ """Entrypoints to service functions through a latch_cli.""" import os -import textwrap from collections import OrderedDict from pathlib import Path from textwrap import dedent @@ -61,7 +60,7 @@ def main(): latest_ver = parse_version(get_latest_package_version()) if local_ver < latest_ver: click.secho( - textwrap.dedent(f""" + dedent(f""" WARN: Your local version of latch ({local_ver}) is out of date. This may result in unexpected behavior. Please upgrade to the latest version ({latest_ver}) using `python3 -m pip install --upgrade latch`. """).strip("\n"), From 95e69548af6cfcdffb4bebe94bca530f87822377 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 18 Aug 2023 15:18:23 -0700 Subject: [PATCH 202/356] small fixies Signed-off-by: maximsmol --- latch_cli/centromere/ctx.py | 8 +++++++- latch_cli/docker_utils/__init__.py | 4 +++- latch_cli/services/register/register.py | 3 +-- latch_cli/services/register/utils.py | 12 ++++++++++-- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/latch_cli/centromere/ctx.py b/latch_cli/centromere/ctx.py index d2bd1dca..976251ac 100644 --- a/latch_cli/centromere/ctx.py +++ b/latch_cli/centromere/ctx.py @@ -231,7 +231,13 @@ def __init__( click.echo(f" {self.version}\n") if self.nucleus_check_version(self.version, self.workflow_name): - raise ValueError(f"Version {self.version} has already been registered.") + click.secho( + f"\nVersion ({self.version}) already exists." + " Make sure that you've saved any changes you made.", + fg="red", + bold=True, + ) + sys.exit(1) self.default_container = _Container( dockerfile=get_default_dockerfile( diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 191dbc44..80b90db4 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -363,6 +363,8 @@ def generate_dockerfile( f.write("\n".join(get_prologue(config)) + "\n\n") commands = infer_commands(pkg_root) + if len(commands) > 0: + click.echo() for block in commands: if block.order != DockerCmdBlockOrder.precopy: @@ -377,7 +379,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 106 && pip install" + "run echo 126 && pip install" " 'git+https://github.com/latchbio/latch.git@kenny/snakekit'\n" ) diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index 6fae6481..bfc75971 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -4,9 +4,8 @@ import sys import tempfile import time -from collections.abc import Iterable from pathlib import Path -from typing import List, Optional +from typing import Iterable, List, Optional import click import gql diff --git a/latch_cli/services/register/utils.py b/latch_cli/services/register/utils.py index fe868b6a..2ef8fa65 100644 --- a/latch_cli/services/register/utils.py +++ b/latch_cli/services/register/utils.py @@ -5,9 +5,17 @@ import os import sys import typing -from collections.abc import Iterable from pathlib import Path -from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, TypedDict, Union +from typing import ( + TYPE_CHECKING, + Dict, + Iterable, + List, + Optional, + Tuple, + TypedDict, + Union, +) import boto3 import docker From 0c087081a024ff9999695a2f376b55a1d48acb69 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 18 Aug 2023 15:33:11 -0700 Subject: [PATCH 203/356] upgrade lytekit Signed-off-by: maximsmol --- latch_cli/services/register/register.py | 7 +++---- setup.py | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index bfc75971..f72a7e92 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -183,7 +183,7 @@ def _print_reg_resp(resp, image): def print_serialize_logs(serialize_logs, image): - click.echo(f"Serializing workflow in {image}:") + click.secho(f"\nSerializing workflow", bold=True) for x in serialize_logs: click.echo(x, nl=False) @@ -238,9 +238,8 @@ def _build_and_serialize( assert ctx.dkr_client is not None exit_status = ctx.dkr_client.wait(container_id) if exit_status["StatusCode"] != 0: - raise ValueError( - f"Serialization exited with nonzero exit code: {exit_status['Error']}" - ) + click.secho("\nWorkflow failed to serialize", fg="red", bold=True) + sys.exit(1) click.echo() upload_image_logs = upload_image(ctx, image_name) diff --git a/setup.py b/setup.py index e56a3f17..f5efb40e 100644 --- a/setup.py +++ b/setup.py @@ -34,7 +34,7 @@ "scp>=0.14.0", "boto3>=1.26.0", "tqdm>=4.63.0", - "lytekit==0.15.2", + "lytekit==0.15.3", "lytekitplugins-pods==0.6.1", "typing-extensions==4.7.1", "apscheduler==3.9.1", From 6394876408d6545ea75c054a4799b2e69e63ad39 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 18 Aug 2023 15:35:40 -0700 Subject: [PATCH 204/356] upgrade lytekit_plugin_pods Signed-off-by: maximsmol --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index f5efb40e..3042bc40 100644 --- a/setup.py +++ b/setup.py @@ -35,7 +35,7 @@ "boto3>=1.26.0", "tqdm>=4.63.0", "lytekit==0.15.3", - "lytekitplugins-pods==0.6.1", + "lytekitplugins-pods==0.6.2", "typing-extensions==4.7.1", "apscheduler==3.9.1", "gql==3.4.0", From eb6d97ebaed3f0cf1e51582e619e417816637582 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 18 Aug 2023 15:48:10 -0700 Subject: [PATCH 205/356] fix r Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 80b90db4..a1189c73 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -134,17 +134,18 @@ def infer_commands(pkg_root: Path) -> List[DockerCmdBlock]: comment="Install rig the R installation manager", commands=[ dedent(r""" - curl \ - --location \ - --fail \ - --remote-name \ - https://github.com/r-lib/rig/releases/download/latest/rig-linux-latest.tar.gz && \ - tar \ - --extract \ - --gunzip \ - --file rig-linux-latest.tar.gz \ - --directory /usr/local/ && \ - rm rig-linux-latest.tar.gz + run \ + curl \ + --location \ + --fail \ + --remote-name \ + https://github.com/r-lib/rig/releases/download/latest/rig-linux-latest.tar.gz && \ + tar \ + --extract \ + --gunzip \ + --file rig-linux-latest.tar.gz \ + --directory /usr/local/ && \ + rm rig-linux-latest.tar.gz """).strip(), ], order=DockerCmdBlockOrder.precopy, @@ -379,7 +380,7 @@ def generate_dockerfile( ) f.write("run pip uninstall --yes latch\n") f.write( - "run echo 126 && pip install" + "run echo 128 && pip install" " 'git+https://github.com/latchbio/latch.git@kenny/snakekit'\n" ) From e748973e3baebe6bfbc57ba7f27e13e609e152d8 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 18 Aug 2023 15:54:20 -0700 Subject: [PATCH 206/356] del debug stuff Signed-off-by: maximsmol --- latch_cli/docker_utils/__init__.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index a1189c73..1abff553 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -373,17 +373,6 @@ def generate_dockerfile( block.write_block(f) - f.write("run apt-get update --yes && apt-get install --yes git\n") - f.write( - "run pip install" - " 'git+https://github.com/latchbio/latch.git@kenny/snakekit'\n" - ) - f.write("run pip uninstall --yes latch\n") - f.write( - "run echo 128 && pip install" - " 'git+https://github.com/latchbio/latch.git@kenny/snakekit'\n" - ) - f.write("# Copy workflow data (use .dockerignore to skip files)\n") f.write("copy . /root/\n\n") From 82453d32e0313b1ae05b08e5a6d4fbb215b49d00 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 18 Aug 2023 16:01:51 -0700 Subject: [PATCH 207/356] add snakemake preview docs Signed-off-by: maximsmol --- docs/source/index.md | 33 +++-- docs/source/manual/snakemake.md | 255 ++++++++++++++++++++++++++++++++ 2 files changed, 275 insertions(+), 13 deletions(-) create mode 100644 docs/source/manual/snakemake.md diff --git a/docs/source/index.md b/docs/source/index.md index be1ee2d9..af036bb6 100644 --- a/docs/source/index.md +++ b/docs/source/index.md @@ -6,11 +6,11 @@ The Latch SDK is an open-source toolchain to define serverless bioinformatics wo Bioinformatics workflows developed with the SDK automatically receive: -* Instant no-code interfaces for accessibility and publication -* First class static typing -* Containerization and versioning of every registered change -* Reliable and scalable managed cloud infrastructure -* Single line definition of arbitrary resource requirements (eg. CPU, GPU) for serverless execution +- Instant no-code interfaces for accessibility and publication +- First class static typing +- Containerization and versioning of every registered change +- Reliable and scalable managed cloud infrastructure +- Single line definition of arbitrary resource requirements (eg. CPU, GPU) for serverless execution ![SDK Overview](./assets/sdk-intro.png) @@ -32,7 +32,7 @@ Latch SDK containerizes and versions workflow code in the background each time a ## What the Latch SDK is not -* **A self-hosted solution**: Currently, you cannot write your workflow using Latch SDK and host it in your own AWS instance or an HPC. The infrastructure serving bioinformatics pipelines is fully managed by Latch. This allows us to rapidly iterate to bring on high quality features, give cost and performance guarantees, and ensure that security is offered out-of-the-box. +- **A self-hosted solution**: Currently, you cannot write your workflow using Latch SDK and host it in your own AWS instance or an HPC. The infrastructure serving bioinformatics pipelines is fully managed by Latch. This allows us to rapidly iterate to bring on high quality features, give cost and performance guarantees, and ensure that security is offered out-of-the-box. ## Examples @@ -44,13 +44,13 @@ Visit [Examples](../examples/workflows_examples.md) to see real-world bioinforma To get started with Latch SDK, view the following resources: -* **[Quickstart](./getting_started/quick_start.md)** is the fastest way to get started with the Latch SDK. -* **[Concepts](./basics/what_is_a_workflow.md)** describes all important Latch SDK concepts. -* **[Examples](./examples/workflows_examples.md)** show full examples of using Latch SDK for various bioinformatics pipelines. -* **[Troubleshooting](./troubleshooting/troubleshooting)** provides a guide to debug common errors. -* **[Reference](./api/modules.rst)** contains detailed API and design documents. -* **[Subcommands](./subcommands.md)** contains details about the Latch command line toolchain to register workflows and upload data to Latch. -* Join the SDK open-source community on Slack! +- **[Quickstart](./getting_started/quick_start.md)** is the fastest way to get started with the Latch SDK. +- **[Concepts](./basics/what_is_a_workflow.md)** describes all important Latch SDK concepts. +- **[Examples](./examples/workflows_examples.md)** show full examples of using Latch SDK for various bioinformatics pipelines. +- **[Troubleshooting](./troubleshooting/troubleshooting)** provides a guide to debug common errors. +- **[Reference](./api/modules.rst)** contains detailed API and design documents. +- **[Subcommands](./subcommands.md)** contains details about the Latch command line toolchain to register workflows and upload data to Latch. +- Join the SDK open-source community on Slack! --- @@ -144,6 +144,13 @@ cli/cp cli/mv ``` +```{toctree} +:hidden: +:maxdepth: 2 +:caption: Manual +manual/snakemake.md +``` + ```{toctree} :hidden: :maxdepth: 2 diff --git a/docs/source/manual/snakemake.md b/docs/source/manual/snakemake.md new file mode 100644 index 00000000..98a0a06d --- /dev/null +++ b/docs/source/manual/snakemake.md @@ -0,0 +1,255 @@ +# [Alpha Preview] Snakemake Integration + +## Technical preview. Currently not ready for production use + +Latch support for Snakemake is in active development. Some workflows already work but a lot of common use cases need minor work. New documentation is also in development. + +This preview was created to integrate miscelanneous improvements that accumulated over the course of developing the integration and to prevent the codebase from further diverging from the main branch. + +## Getting Started + +Register using the Latch CLI. Example: `latch register workflow_folder/ --snakefile workflow_folder/src/Snakefile` + +Modify the Snakefile to make it compatible with cloud execution: + +- Add basic workflow metadata: name and author +- Find input files and specify them as workflow parameters + - If necessary, include a `config.yaml` file in the workflow image that matches the parameter specification +- Add missing runtime dependencies (conda, pip, system packages) +- Add missing rule inputs that are implicitly fulfiled when executing locally. Index files for biological data are commonly expected to always be alongside their matching data. +- Make sure shared code does not rely on input files. This is any code that is not under a rule and so gets executed by every task +- Add `resources` directives if tasks run out of memory or disk space +- Optimize data transfer by merging tasks that have 1-to-1 dependencies + +## Overview + +Snakemake support is currently based on JIT (Just-In-Time) registraton. This means that the workflow produced by `latch register` will only register a second workflow, which will run the actual pipeline tasks. + +### JIT Workflow + +The first ("JIT") workflow does the following: + +1. Download all input files +2. Import the Snakefile, calculate the dependency graph, determine which jobs need to be run +3. Generate a Latch SDK workflow Python script for the second ("runtime") workflow and register it +4. Run the runtime workflow using the same inputs + +Debugging: + +- The generated runtime workflow entrypoint is uploaded to `latch:///.snakemake_latch/workflows/snakemake_arcadia__prehgt__workflow/entrypoint.py` +- Internal workflow specifications are uploaded to `latch:///.snakemake_latch/workflows/snakemake_arcadia__prehgt__workflow/spec` + +### Runtime Workflow + +The runtime workflow contains a task per each Snakemake job. This means that there will be a separate task per each wildcard instatiation of each rule. This can lead to workflows with hundreds of tasks. Note that the execution graph can be filtered by task status. + +Each task runs a modified Snakemake executable using a script from the Latch SDK which monkey-patches the appropriate parts of the Snakemake package. This executable is different in two ways: + +1. Rules that are not part of the task's target are entirely ignored +2. The target rule has all of its properties (currently inputs, outputs, benchmark, log, shellcode) replaced with the job-specific strings. This is the same as the value of these directives with all wildcards expanded and lazy values evaluated + +Debugging: + +- The Snakemake-compiled tasks are uploaded to `latch:///.snakemake_latch/workflows/snakemake_arcadia__prehgt__workflow/compiled_tasks` + +#### Example + +Snakefile rules: + +```Snakemake +rule all: + input: + os.path.join(WORKDIR, "qc", "fastqc", "read1_fastqc.html"), + os.path.join(WORKDIR, "qc", "fastqc", "read2_fastqc.html") + +rule fastqc: + input: os.path.join(WORKDIR, "fastq", "{sample}.fastq") + output: os.path.join(WORKDIR, "qc", "fastqc", "{sample}_fastqc.html") + shellcmd: "fastqc {input} -o {output}" +``` + +Produced jobs: + +1. Rule: `fastqc` Wildcards: `sample=read1` +1. Rule: `fastqc` Wildcards: `sample=read2` + +Resulting single-job executable for job 1: + +```py +# @workflow.rule(name='all', lineno=1, snakefile='/root/Snakefile') +# @workflow.input( # os.path.join(WORKDIR, "qc", "fastqc", "read1_fastqc.html"), +# # os.path.join(WORKDIR, "qc", "fastqc", "read2_fastqc.html"), +# ) +# @workflow.norun() +# @workflow.run +# def __rule_all(input, output, ...): +# pass + +@workflow.rule(name='fastqc', lineno=6, snakefile='/root/Snakefile') +@workflow.input("work/fastq/read1.fastq" # os.path.join(WORKDIR, "fastq", "{sample}.fastq") +) +@workflow.shellcmd("fastqc work/fastq/read1.fastq -o work/qc/fastqc/read1_fastqc.html") +@workflow.run +def __rule_fastqc(input, output, ...): + shell("fastqc {input} -o {output}", ...) +``` + +Note: + +- The "all" rule is entirely commented out +- The "fastqc" rule has no wildcards in its decorators + +### Limitations + +1. The workflow will execute the first rule defined in the Snakefile (matching standard Snakemake behavior). There is no way to change the default rule other than by moving the desired rule up in the file +1. The workflow will output files that are not used by downstream tasks. This means that intermediate files cannot be included in the output. The only way to exclude an output is to write a rule that lists it as an input +1. Input files and directories are downloaded fully, even if they are not used to generate the dependency graph. This commonly leads to issues with large directories being downloaded just to list the files contained within, delaying the JIT workflow by a large amount of time and requiring a large amount of disk space +1. Only the JIT workflow downloads input files. Rules only download their individual inputs, which can be a subset of the input files. If the Snakefile tries to read input files outside of rules it will usually fail at runtime +1. Large files that move between tasks will need to be uploaded by the outputting task and downloaded by each consuming task. This can take a large amount of time. Frequently it's possible to merge the producer and the consumer into one task to improve performance +1. Environment dependencies (Conda packages, Python packages, other software) must be well-specified. Missing dependencies will lead to JIT-time or runtime crashes +1. Config files are not supported and must be hard-coded into the workflow Docker image +1. `conda` directives will frequently fail with timeouts/SSL errors because Conda does not react well to dozens of tasks trying to install conda environments over a short timespan. It is recommended that all conda environments are included in the Docker image +1. The JIT workflow hard-codes the latch paths for rule inputs, outputs and other files. If these files are missing when the runtime workflow task runs, it will fail + +## Metadata + +Workflow metadata is read from the Snakefile. For this purpose, `SnakemakeMetadata` should be instantiated at the beginning of the file outside of any rules. + +### Dependency Issues + +Some Snakefiles import third-party dependencies at the beginning. This will cause the metadata extraction to fail if the dependencies are not installed. There are two ways of dealing with this problem: + +1. Install the missing dependencies on the registering computer (the computer running the `latch` command) +2. Use a `latch_metadata.py` file + +If registration fails before metadata can be pulled, the CLI will generate an example `latch_metadata.py` file. + +### Input Parameters + +Since there is no explicit entrypoint (`@workflow`) function in a Snakemake workflow, parameters are instead specified in the metadata file. + +Currently only `LatchFile` and `LatchDir` parameters are supported. Both directory and file inputs are specified using `SnakemakeFileParameter` and setting the `type` field as appropriate. + +Parameters must include a `path` field which specifies where the data will be downloaded to. This usually matches some file location expected by a Snakemake rule. Frequently, instead of simple paths, a rule with use a `configfile` to dynamically find input paths. In this case the only requiremtn is that the path matches the config file included in the workflow Docker image. + +Example: + +```py +parameters = { + "example": SnakemakeFileParameter( + display_name="Example Parameter", + type=LatchFile, + path=Path("example.txt"), + ) +} +``` + +## Troubleshooting + +| Problem | Common Solution | +| -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `The above error occured when reading the Snakefile to extract workflow metadata.` | Snakefile has errors outside of any rules. Frequently caused by missing dependencies (look for `ModuleNotFoundError`). Either install dependencies or add a `latch_metadata.py` file | +| `snakemake.exceptions.WorkflowError: Workflow defines configfile config.yaml but it is not present or accessible (full checked path: /root/config.yaml)` | Include a `config.yaml` in the workflow Docker image. Currently, config files cannot be generated from workflow parameters. | +| `Command '['/usr/local/bin/python', '-m', 'latch_cli.snakemake.single_task_snakemake', ...]' returned non-zero exit status 1.` | The runtime single-job task failed. Look at logs to find the error. It will be marked with the string `[!] Failed`. | +| Runtime workflow task fails with `FileNotFoundError in file /root/workflow/Snakefile` but the file is specified in workflow parameters | Wrap the code that reads the file in a function. **See section "Input Files Referenced Outside of Rules"** | +| MultiQC `No analysis results found. Cleaning up..` | FastQC outputs two files: the raw data and the HTML report. Include the raw `.zip` outputs of FastQC in the MultiQC rule inputs. | + +## Known Issues + +- Task caching does not work, tasks always re-run when a new version of the workflow is run even if nothing specific has changed +- It is not possible to configure the amount of available ephemeral storage +- Remote registration is not supported +- Snakemake tasks are serialized using a faulty custom implementation which does not support things like caching. Should use actual generated python code instead +- JIT workflow image should run snakemake extraction as a smoketest before being registered as a workflow +- Workflows with no parameters break the workflow params page on console UI +- Cannot set parameter defaults +- Parameter keys are unusued but are required in the metadata +- Log file tailing does not work + +## Future Work + +- Warn when the Snakefile reads files not on the docker image outside of any rules +- FUSE +- File/directory APIs + +## Troubleshooting: Input Files Referenced Outside of Rules + +Only the JIT workflow downloads every input file. Tasks at runtime will only download files their target rules explicitly depend on. This means that Snakefile code that is not under a rule will usually fail if it tries to read input files. + +**Example:** + +```python +# ERROR: this reads a directory, regardless of which rule is executing! +samples = Path("inputs").glob("*.fastq") + +rule all: + input: + expand("fastqc/{sample}.html", sample=samples) + +rule fastqc: + input: + "inputs/{sample}.fastq" + output: + "fastqc/{sample}.html" + shellcmd: + fastqc {input} -o {output} +``` + +Since the `Path("inputs").glob(...)` call is not under any rule, _it runs in all tasks._ Because the `fastqc` rule does not specify `input_dir` as an `input`, it will not be downloaded and the code will throw an error. + +### Solution + +Only access files when necessary (i.e. when computing dependencies as in the example, or in a rule body) by placing problematic code within rule definitions. Either directly inline the variable or write a function to use in place of the variable. + +**Example:** + +```python +rule all_inline: + input: + # This code will only run in the JIT step + expand("fastqc/{sample}.html", sample=Path("inputs").glob("*.fastq")) + +def get_samples(): + # This code will only run if the function is called + samples = Path("inputs").glob("*.fastq") + return samples + +rule all_function: + input: + expand("fastqc/{sample}.html", sample=get_samples()) +``` + +This works because the JIT step replaces `input`, `output`, `params`, and other declarations with static strings for the runtime workflow so any function calls within them will be replaced with pre-computed strings and the Snakefile will not attempt to read the files again. + +**Same example at runtime:** + +```python +rule all_inline: + input: + "fastqc/example.html" + +def get_samples(): + # Note: this function is no longer called anywhere in the file + samples = Path("inputs").glob("*.fastq") + return samples + +rule all_function: + input: + "fastqc/example.html" +``` + +**Example using multiple return values:** + +```python +def get_samples_data(): + samples = Path("inputs").glob("*.fastq") + return { + "samples": samples, + "names": [x.name for x in samples] + } + +rule all: + input: + expand("fastqc/{sample}.html", sample=get_samples_data()["samples"]), + expand("reports/{name}.txt", name=get_samples_data()["names"]), +``` From d031295727d60dea8ad817886e4a5e6d731c4e3d Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Mon, 21 Aug 2023 10:56:43 -0700 Subject: [PATCH 208/356] docs improvements --- docs/source/manual/snakemake.md | 98 ++++++++++++++++++++++++++++----- 1 file changed, 83 insertions(+), 15 deletions(-) diff --git a/docs/source/manual/snakemake.md b/docs/source/manual/snakemake.md index 98a0a06d..4e8fc17b 100644 --- a/docs/source/manual/snakemake.md +++ b/docs/source/manual/snakemake.md @@ -1,29 +1,97 @@ -# [Alpha Preview] Snakemake Integration +# [Alpha Pre-release] Snakemake Integration -## Technical preview. Currently not ready for production use +## Pre-release Disclaimer - Currently not ready for production use -Latch support for Snakemake is in active development. Some workflows already work but a lot of common use cases need minor work. New documentation is also in development. +Latch support for Snakemake is in active development. Some workflows already work but a lot of common use cases need minor work. This documentation is also in active development. -This preview was created to integrate miscelanneous improvements that accumulated over the course of developing the integration and to prevent the codebase from further diverging from the main branch. +This pre-release was created to integrate miscellaneous improvements that accumulated over the course of developing the integration and to prevent the codebase from further diverging from the main branch. ## Getting Started -Register using the Latch CLI. Example: `latch register workflow_folder/ --snakefile workflow_folder/src/Snakefile` +Latch's snakemake integration allows developers to build graphical interfaces to expose their workflows to wet lab teams and managed cloud execution of snakemake jobs. -Modify the Snakefile to make it compatible with cloud execution: +A primary design goal for integration is to allow developers to register existing projects with minimal added boilerplate and modifications to code. Here we outline exactly what these changes are and why they are needed. + +Recall a snakemake project consists of a `Snakefile`, which describes workflow rules using an ["extension"](https://snakemake.readthedocs.io/en/stable/snakefiles/rules.html) of Python, and associated python code imported and called by these rules in the `Snakefile`.To make this project compatible with Latch, we need to do the following: + +1. Identify and construct explicit parameters for each file dependency in `latch_metadata.py` +2. Build a container with all runtime dependencies +3. Ensure your `Snakefile` is compatible with cloud execution + +### Constructing a `latch_metadata.py` file + +The snakemake framework was designed to allow developers to both define and execute their workflows. This often means that the workflow parameters are sometimes ill-defined and scattered throughout the project as configuration values, static values in the `Snakefile` or command line flags. + +To construct a graphical interface from a snakemake workflow, the parameters need to be explicitly identified and defined so that they can be presented to scientist to be filled out through a web application. The `latch_metadata.py` file holds these parameter definitions, along with any styling or cosmetic modifications the developer wishes to make to each parameter. + +Asking the question, "what are the minimum set of files needed to run my workflow to completion" is a good way to begin identifying what these parameters might be. + +An example of this `latch_metadata.py` file: + +``` +# latch_metadata.py + +from pathlib import Path + +from latch.types.directory import LatchDir +from latch.types.file import LatchFile +from latch.types.metadata import LatchAuthor, SnakemakeFileParameter, SnakemakeMetadata + +SnakemakeMetadata( + display_name="fgbio Best Practise FASTQ -> Consensus Pipeline", + author=LatchAuthor( + name="Fulcrum Genomics", + ), + parameters={ + "r1_fastq": SnakemakeFileParameter( + display_name="Read 1 FastQ", + type=LatchFile, + path=Path("r1.fq.gz"), + ), + "r2_fastq": SnakemakeFileParameter( + display_name="Read 2 FastQ", + type=LatchFile, + path=Path("r2.fq.gz"), + ), + "genome": SnakemakeFileParameter( + display_name="Reference Genome", + type=LatchDir, + path=Path("hs38DH"), + ), + }, +) +``` + +### Defining all dependencies in a container + +When snakemake jobs are executed on Latch, they will run in an environment defined by a `Dockerfile`. Any dependencies, such as third-party binaries, python libraries, shell scripts, need to be installed and configured correctly in this `Dockerfile` so the job has access to them. + +To generate a `Dockerfile` that can be modified, the following command is available: + +`latch dockerfile ` + +A container is automatically built from the `Dockerfile` generated by this command when your snakemake project is registered with Latch. + +### Ensure your `Snakefile` is compatible with cloud execution + +When snakemake workflows are executed on Latch, each generated job is run in a separate container on a potentially isolated machine. This means your `Snakefile` might need to be modified to address problems that arise from this type of execution that were not present when executing locally: -- Add basic workflow metadata: name and author -- Find input files and specify them as workflow parameters - - If necessary, include a `config.yaml` file in the workflow image that matches the parameter specification -- Add missing runtime dependencies (conda, pip, system packages) - Add missing rule inputs that are implicitly fulfiled when executing locally. Index files for biological data are commonly expected to always be alongside their matching data. - Make sure shared code does not rely on input files. This is any code that is not under a rule and so gets executed by every task - Add `resources` directives if tasks run out of memory or disk space - Optimize data transfer by merging tasks that have 1-to-1 dependencies -## Overview +### Register your project + +When the above steps have been taken, it is safe to register your project with the Latch CLI. + +Example: `latch register / --snakefile /Snakefile` + +This command will build a container and construct a graphical interface from your `latch_metdata.py` file. When this process has completed, a link to view your workflow on the Latch console will be printed to `stdout`. + +## Lifecycle of a Snakemake Execution on Latch -Snakemake support is currently based on JIT (Just-In-Time) registraton. This means that the workflow produced by `latch register` will only register a second workflow, which will run the actual pipeline tasks. +Snakemake support is currently based on JIT (Just-In-Time) registraton. This means that the workflow produced by `latch register` will only register a second workflow, which will run the actual pipeline tasks. This is because the actual structure of the workflow cannot be specified until parameter values are provided. ### JIT Workflow @@ -36,8 +104,8 @@ The first ("JIT") workflow does the following: Debugging: -- The generated runtime workflow entrypoint is uploaded to `latch:///.snakemake_latch/workflows/snakemake_arcadia__prehgt__workflow/entrypoint.py` -- Internal workflow specifications are uploaded to `latch:///.snakemake_latch/workflows/snakemake_arcadia__prehgt__workflow/spec` +- The generated runtime workflow entrypoint is uploaded to `latch:///.snakemake_latch/workflows//entrypoint.py` +- Internal workflow specifications are uploaded to `latch:///.snakemake_latch/workflows//spec` ### Runtime Workflow @@ -50,7 +118,7 @@ Each task runs a modified Snakemake executable using a script from the Latch SDK Debugging: -- The Snakemake-compiled tasks are uploaded to `latch:///.snakemake_latch/workflows/snakemake_arcadia__prehgt__workflow/compiled_tasks` +- The Snakemake-compiled tasks are uploaded to `latch:///.snakemake_latch/workflows//compiled_tasks` #### Example From 34325d4f0b67415875eda5f507b676508edec22d Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Mon, 21 Aug 2023 10:56:57 -0700 Subject: [PATCH 209/356] upper bound on sm --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 3042bc40..53280f30 100644 --- a/setup.py +++ b/setup.py @@ -49,7 +49,7 @@ "websockets==11.0.3", "watchfiles==0.19.0", ], - extras_require={"snakemake": ["snakemake>=7.18.0"]}, + extras_require={"snakemake": ["snakemake>=7.18.0, <7.30.2"]}, classifiers=[ "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", From 9332f6376971d505546d2e854e0e6fa961aa58e1 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Mon, 21 Aug 2023 10:57:11 -0700 Subject: [PATCH 210/356] issue with typed list --- latch_cli/snakemake/serialize.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index a2a8bb11..1b702f51 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -48,7 +48,7 @@ def get_snakemake_metadata_example(name: str) -> str: from pathlib import Path from latch.types.metadata import SnakemakeMetadata, SnakemakeFileParameter from latch.types.file import LatchFile - from latch.types.metadata import LatchAuthor, LatchMetadata + from latch.types.metadata import LatchAuthor SnakemakeMetadata( display_name={repr(name)}, @@ -72,16 +72,18 @@ def ensure_snakemake_metadata_exists(): if metadata._snakemake_metadata is None: click.secho( dedent(""" - No `SnakemakeMetadata` object was detected in your Snakefile. This + No `SnakemakeMetadata` object was detected in your project. This object needs to be defined to register this workflow with Latch. - You can paste the following in the top of your Snakefile to get - started: + Create a file named `latch_metadata.py` with the following + code to get started: __example__ Find more information at docs.latch.bio. - """).replace("__example__", snakemake_metadata_example), + """).replace( + "__example__", get_snakemake_metadata_example("example_name") + ), bold=True, fg="red", ) From 9a9bfcfcaa8260ca30dd63ddf63c8b8e9c8f8f26 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Mon, 21 Aug 2023 11:57:33 -0700 Subject: [PATCH 211/356] fix --- latch_cli/snakemake/workflow.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 07c9246f..7ca1c7c8 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -880,7 +880,7 @@ def named_list_to_json(xs: snakemake.io.Namedlist) -> NamedListJson: vs = [vs] for v in vs: - if not isinstance(v, str): + if isinstance(v, dict): v = v["value"] named_values.add(v) @@ -893,7 +893,7 @@ def named_list_to_json(xs: snakemake.io.Namedlist) -> NamedListJson: obj = annotated_str_to_json(v) rendered = obj - if not isinstance(rendered, str): + if isinstance(rendered, dict): rendered = rendered["value"] if rendered in named_values: continue From 6cf8444b0ed0302201de7ad54db5c9605bf4bfe3 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Tue, 22 Aug 2023 09:30:25 -0700 Subject: [PATCH 212/356] del vestigial asyncssh.connet Signed-off-by: Ayush Kamat --- latch_cli/services/local_dev_old.py | 85 ++++++++++++++--------------- 1 file changed, 41 insertions(+), 44 deletions(-) diff --git a/latch_cli/services/local_dev_old.py b/latch_cli/services/local_dev_old.py index ce4a1f14..cb4f7763 100644 --- a/latch_cli/services/local_dev_old.py +++ b/latch_cli/services/local_dev_old.py @@ -328,54 +328,51 @@ async def _run_local_dev_session(pkg_root: Path): # todo(aidan): edit known hosts file with centromere ip and address to allow strict host checking try: - async with asyncssh.connect( - centromere_ip, username=centromere_username, known_hosts=None + async for ws in websockets.connect( + f"ws://{centromere_ip}:{port}/ws", + close_timeout=0, + extra_headers=headers, ): - async for ws in websockets.connect( - f"ws://{centromere_ip}:{port}/ws", - close_timeout=0, - extra_headers=headers, - ): + try: + await aioconsole.aprint( + "Successfully connected to remote instance." + ) try: - await aioconsole.aprint( - "Successfully connected to remote instance." - ) - try: - await aioconsole.aprint("Setting up local sync...") - watch_task = asyncio.create_task( - _watch_and_rsync( - pkg_root, centromere_ip, ssh_port, key_path - ) + await aioconsole.aprint("Setting up local sync...") + watch_task = asyncio.create_task( + _watch_and_rsync( + pkg_root, centromere_ip, ssh_port, key_path ) - await aioconsole.aprint("Done.") - - image_name_tagged = _get_latest_image(pkg_root) - await _send_message(ws, docker_access_token) - await _send_message(ws, image_name_tagged) - await aioconsole.aprint(f"Pulling {image_name_tagged}... ") - - await _get_messages(ws, show_output=False) - await aioconsole.aprint("Image successfully pulled.\n") - - await _get_messages(ws, show_output=True) - - await _shell_session(ws) - rsync_stop_event.set() - await watch_task - - except websockets.exceptions.ConnectionClosed: - continue - except Exception as e: - await aioconsole.aprint(traceback.format_exc()) - finally: - await aioconsole.aprint("Exiting local development session") - await ws.close() - close_resp = post( - config.api.centromere.stop_local_dev, - headers={"Authorization": f"Bearer {retrieve_or_login()}"}, ) - close_resp.raise_for_status() - return + await aioconsole.aprint("Done.") + + image_name_tagged = _get_latest_image(pkg_root) + await _send_message(ws, docker_access_token) + await _send_message(ws, image_name_tagged) + await aioconsole.aprint(f"Pulling {image_name_tagged}... ") + + await _get_messages(ws, show_output=False) + await aioconsole.aprint("Image successfully pulled.\n") + + await _get_messages(ws, show_output=True) + + await _shell_session(ws) + rsync_stop_event.set() + await watch_task + + except websockets.exceptions.ConnectionClosed: + continue + except Exception as e: + await aioconsole.aprint(traceback.format_exc()) + finally: + await aioconsole.aprint("Exiting local development session") + await ws.close() + close_resp = post( + config.api.centromere.stop_local_dev, + headers={"Authorization": f"Bearer {retrieve_or_login()}"}, + ) + close_resp.raise_for_status() + return except asyncssh.ProtocolError as e: if "Too many authentication failures" in str(e): click.secho( From 15c0cd5fc710025c00748aea3e618d6db83c02a1 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Tue, 22 Aug 2023 10:46:35 -0700 Subject: [PATCH 213/356] add retries Signed-off-by: Ayush Kamat --- latch_cli/services/cp/upload.py | 64 +++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/latch_cli/services/cp/upload.py b/latch_cli/services/cp/upload.py index 640c853b..ebb4a13a 100644 --- a/latch_cli/services/cp/upload.py +++ b/latch_cli/services/cp/upload.py @@ -5,6 +5,7 @@ from concurrent.futures import Future, ProcessPoolExecutor, wait from contextlib import closing from dataclasses import dataclass +from json import JSONDecodeError from multiprocessing import Queue from multiprocessing.managers import DictProxy, ListProxy, SyncManager from pathlib import Path @@ -305,6 +306,9 @@ class StartUploadReturnType: dest: str +MAX_RETRIES = 5 + + def start_upload( src: Path, dest: str, @@ -345,40 +349,48 @@ def start_upload( math.ceil(file_size / latch_constants.maximum_upload_parts), ) - if throttle is not None: - time.sleep(throttle.get_delay()) + retries = 0 + while retries < MAX_RETRIES: + if throttle is not None: + time.sleep(throttle.get_delay()) + + start = time.monotonic() + res = tinyrequests.post( + latch_config.api.data.start_upload, + headers={"Authorization": get_auth_header()}, + json={ + "path": dest, + "content_type": content_type, + "part_count": part_count, + }, + ) + end = time.monotonic() - start = time.monotonic() - res = tinyrequests.post( - latch_config.api.data.start_upload, - headers={"Authorization": get_auth_header()}, - json={ - "path": dest, - "content_type": content_type, - "part_count": part_count, - }, - ) - end = time.monotonic() + if latency_q is not None: + latency_q.put(end - start) - json_data = res.json() + try: + json_data = res.json() + except JSONDecodeError: + retries += 1 + continue - if res.status_code != 200: - raise ValueError(json_data["error"]) + if res.status_code != 200: + raise ValueError(json_data["error"]) - if latency_q is not None: - latency_q.put(end - start) + if progress_bars is not None: + progress_bars.update_total_progress(1) - if progress_bars is not None: - progress_bars.update_total_progress(1) + if "version_id" in json_data["data"]: + return # file is empty, so no need to upload any content - if "version_id" in json_data["data"]: - return # file is empty, so no need to upload any content + data: StartUploadData = json_data["data"] - data: StartUploadData = json_data["data"] + return StartUploadReturnType( + **data, part_count=part_count, part_size=part_size, src=src, dest=dest + ) - return StartUploadReturnType( - **data, part_count=part_count, part_size=part_size, src=src, dest=dest - ) + raise ValueError(f"Unable to generate upload URL for {src}") @dataclass(frozen=True) From c2cb661f8b62b2510335becaf0331aa4ca5a3ec2 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Wed, 23 Aug 2023 12:48:29 -0700 Subject: [PATCH 214/356] major simplification Signed-off-by: Ayush Kamat --- latch_cli/services/cp/download.py | 11 +- latch_cli/services/cp/manager.py | 14 + latch_cli/services/cp/progress.py | 8 - latch_cli/services/cp/throttle.py | 8 +- latch_cli/services/cp/upload.py | 511 +++++++++++++++--------------- 5 files changed, 277 insertions(+), 275 deletions(-) create mode 100644 latch_cli/services/cp/manager.py diff --git a/latch_cli/services/cp/download.py b/latch_cli/services/cp/download.py index a8175b5e..f91ada28 100644 --- a/latch_cli/services/cp/download.py +++ b/latch_cli/services/cp/download.py @@ -13,12 +13,9 @@ from latch_cli.constants import Units from latch_cli.services.cp.config import CPConfig, Progress from latch_cli.services.cp.ldata_utils import LDataNodeType, get_node_data +from latch_cli.services.cp.manager import CPStateManager from latch_cli.services.cp.path_utils import normalize_path -from latch_cli.services.cp.progress import ( - ProgressBarManager, - ProgressBars, - get_free_index, -) +from latch_cli.services.cp.progress import ProgressBars, get_free_index from latch_cli.services.cp.utils import get_max_workers, human_readable_time from latch_cli.utils import get_auth_header, with_si_suffix @@ -128,7 +125,7 @@ def download( num_bars = min(get_max_workers(), num_files) show_total_progress = True - with ProgressBarManager() as manager: + with CPStateManager() as manager: progress_bars: ProgressBars with closing( manager.ProgressBars( @@ -165,7 +162,7 @@ def download( else: num_bars = 1 - with ProgressBarManager() as manager: + with CPStateManager() as manager: progress_bars: ProgressBars with closing( manager.ProgressBars( diff --git a/latch_cli/services/cp/manager.py b/latch_cli/services/cp/manager.py new file mode 100644 index 00000000..b3da8d20 --- /dev/null +++ b/latch_cli/services/cp/manager.py @@ -0,0 +1,14 @@ +from multiprocessing.managers import SyncManager +from typing import Type + +from .progress import ProgressBars +from .throttle import Throttle + + +class CPStateManager(SyncManager): + ProgressBars: Type[ProgressBars] + Throttle: Type[Throttle] + + +CPStateManager.register("ProgressBars", ProgressBars) +CPStateManager.register("Throttle", Throttle) diff --git a/latch_cli/services/cp/progress.py b/latch_cli/services/cp/progress.py index 43385838..80feba58 100644 --- a/latch_cli/services/cp/progress.py +++ b/latch_cli/services/cp/progress.py @@ -1,6 +1,5 @@ from contextlib import contextmanager from multiprocessing import BoundedSemaphore -from multiprocessing.managers import BaseManager from typing import Dict, List, Optional import tqdm @@ -128,13 +127,6 @@ def close(self): bar.close() -class ProgressBarManager(BaseManager): - ... - - -ProgressBarManager.register("ProgressBars", ProgressBars) - - @contextmanager def get_free_index(progress_bars: ProgressBars): try: diff --git a/latch_cli/services/cp/throttle.py b/latch_cli/services/cp/throttle.py index 03663927..c17c099f 100644 --- a/latch_cli/services/cp/throttle.py +++ b/latch_cli/services/cp/throttle.py @@ -1,4 +1,5 @@ from multiprocessing.managers import BaseManager +from typing import Type from attr import dataclass @@ -12,10 +13,3 @@ def get_delay(self): def set_delay(self, d: float): self.delay = d - - -class ThrottleManager(BaseManager): - ... - - -ThrottleManager.register("Throttle", Throttle) diff --git a/latch_cli/services/cp/upload.py b/latch_cli/services/cp/upload.py index ebb4a13a..9565a314 100644 --- a/latch_cli/services/cp/upload.py +++ b/latch_cli/services/cp/upload.py @@ -1,14 +1,19 @@ +import datetime +import json +import logging import math import mimetypes +import multiprocessing import os +import random import time -from concurrent.futures import Future, ProcessPoolExecutor, wait +from concurrent.futures import Future, ProcessPoolExecutor, as_completed, wait from contextlib import closing from dataclasses import dataclass from json import JSONDecodeError -from multiprocessing import Queue -from multiprocessing.managers import DictProxy, ListProxy, SyncManager +from multiprocessing.managers import DictProxy, ListProxy from pathlib import Path +from queue import Queue from typing import TYPE_CHECKING, List, Optional, TypedDict import click @@ -19,18 +24,22 @@ from latch_cli.constants import latch_constants, units from latch_cli.services.cp.config import CPConfig, Progress from latch_cli.services.cp.ldata_utils import LDataNodeType, get_node_data +from latch_cli.services.cp.manager import CPStateManager from latch_cli.services.cp.path_utils import normalize_path -from latch_cli.services.cp.progress import ProgressBarManager, ProgressBars -from latch_cli.services.cp.throttle import Throttle, ThrottleManager +from latch_cli.services.cp.progress import ProgressBars +from latch_cli.services.cp.throttle import Throttle from latch_cli.services.cp.utils import get_max_workers, human_readable_time from latch_cli.utils import get_auth_header, urljoins, with_si_suffix if TYPE_CHECKING: - PathQueueType: TypeAlias = Queue[Optional[Path]] - LatencyQueueType: TypeAlias = Queue[Optional[float]] + PathQueueType: TypeAlias = "Queue[Optional[Path]]" + LatencyQueueType: TypeAlias = "Queue[Optional[float]]" PartsBySrcType: TypeAlias = DictProxy[Path, ListProxy["CompletedPart"]] UploadInfoBySrcType: TypeAlias = DictProxy[Path, "StartUploadReturnType"] +logging.basicConfig() +multiprocessing.get_logger().setLevel(logging.DEBUG) + start_upload_batch_size = 100 @@ -93,196 +102,186 @@ def upload( num_bars = get_max_workers() show_total_progress = True - with ProcessPoolExecutor(max_workers=get_max_workers()) as executor: - with ProcessPoolExecutor(max_workers=get_max_workers()) as end_upload_executor: - with ProgressBarManager() as pbar_manager: - with SyncManager() as state_manager: - parts_by_src: "PartsBySrcType" = state_manager.dict() - upload_info_by_src: "UploadInfoBySrcType" = state_manager.dict() - - if src_path.is_dir(): - if dest_exists and not src.endswith("/"): - normalized = urljoins(normalized, src_path.name) - - jobs: List[UploadJob] = [] - total_bytes = 0 - - for dir_path, _, file_names in os.walk( - src_path, followlinks=True - ): - for file_name in file_names: - rel_path = Path(dir_path) / file_name - - parts_by_src[rel_path] = state_manager.list() - jobs.append( - UploadJob( - rel_path, - urljoins( - normalized, - str(rel_path.relative_to(src_path)), - ), - ) - ) - - total_bytes += rel_path.stat().st_size + with ProcessPoolExecutor(max_workers=get_max_workers()) as exec: + with CPStateManager() as man: + parts_by_src: "PartsBySrcType" = man.dict() + upload_info_by_src: "UploadInfoBySrcType" = man.dict() - num_files = len(jobs) + throttle: Throttle = man.Throttle() + latency_q: "LatencyQueueType" = man.Queue() + throttle_listener = exec.submit(throttler, throttle, latency_q) - with ThrottleManager() as throt_man: - throttle: Throttle = throt_man.Throttle() - latency_q: "LatencyQueueType" = state_manager.Queue() - - url_generation_bar: ProgressBars - with closing( - pbar_manager.ProgressBars( - 0, - show_total_progress=( - config.progress != Progress.none - ), - ) - ) as url_generation_bar: - url_generation_bar.set_total( - num_files, "Generating URLs" - ) + if src_path.is_dir(): + if dest_exists and not src.endswith("/"): + normalized = urljoins(normalized, src_path.name) - start_upload_futs: List[ - Future[Optional[StartUploadReturnType]] - ] = [] + jobs: List[UploadJob] = [] + total_bytes = 0 - throttle_listener = executor.submit( - throttler, throttle, latency_q - ) + for dir_path, _, file_names in os.walk(src_path, followlinks=True): + for file_name in file_names: + rel_path = Path(dir_path) / file_name - start = time.monotonic() - for job in jobs: - start_upload_futs.append( - executor.submit( - start_upload, - job.src, - job.dest, - url_generation_bar, - throttle, - latency_q, - ) - ) - - wait(start_upload_futs) - - latency_q.put(None) - wait([throttle_listener]) - - for fut in start_upload_futs: - res = fut.result() - if res is not None: - upload_info_by_src[res.src] = res - - queue: "PathQueueType" = state_manager.Queue() - listeners = [ - end_upload_executor.submit( - end_upload_listener, - queue=queue, - parts_by_src=parts_by_src, - upload_info_by_src=upload_info_by_src, + parts_by_src[rel_path] = man.list() + jobs.append( + UploadJob( + rel_path, + urljoins( + normalized, + str(rel_path.relative_to(src_path)), + ), ) - for _ in range(get_max_workers()) - ] - - chunk_upload_bars: ProgressBars - with closing( - pbar_manager.ProgressBars( - min(num_bars, num_files), - show_total_progress=show_total_progress, - verbose=config.verbose, + ) + + total_bytes += rel_path.stat().st_size + + num_files = len(jobs) + + url_generation_bar: ProgressBars + with closing( + man.ProgressBars( + 0, + show_total_progress=(config.progress != Progress.none), + ) + ) as url_generation_bar: + url_generation_bar.set_total(num_files, "Generating URLs") + + start_upload_futs: List[Future[Optional[StartUploadReturnType]]] = ( + [] + ) + + start = time.monotonic() + for job in jobs: + start_upload_futs.append( + exec.submit( + start_upload, + job.src, + job.dest, + url_generation_bar, + throttle, + latency_q, + ) + ) + + for fut in as_completed(start_upload_futs): + e = fut.exception() + if e is not None: + print(e) + raise e + + res = fut.result() + if res is not None: + upload_info_by_src[res.src] = res + + latency_q.put(None) + wait([throttle_listener]) + + queue: "PathQueueType" = man.Queue() + listeners = [ + exec.submit( + end_upload_listener, + queue=queue, + parts_by_src=parts_by_src, + upload_info_by_src=upload_info_by_src, + exec=exec, + ) + ] + + chunk_upload_bars: ProgressBars + with closing( + man.ProgressBars( + min(num_bars, num_files), + show_total_progress=show_total_progress, + verbose=config.verbose, + ) + ) as chunk_upload_bars: + chunk_upload_bars.set_total(num_files, "Uploading Files") + + # todo(ayush): async-ify + chunk_futs: List[Future[CompletedPart]] = [] + for data in start_upload_futs: + res = data.result() + + if res is None: + chunk_upload_bars.update_total_progress(1) + continue + + pbar_index = chunk_upload_bars.get_free_task_bar_index() + chunk_upload_bars.set( + pbar_index, + res.src.stat().st_size, + res.src.name, + ) + chunk_upload_bars.set_usage(str(res.src), res.part_count) + + for part_index, url in enumerate(res.urls): + chunk_futs.append( + exec.submit( + upload_file_chunk, + src=res.src, + url=url, + part_index=part_index, + part_size=res.part_size, + progress_bars=chunk_upload_bars, + pbar_index=pbar_index, + queue=queue, + parts_by_source=parts_by_src, + ) ) - ) as chunk_upload_bars: - chunk_upload_bars.set_total(num_files, "Uploading Files") - - # todo(ayush): async-ify - chunk_futs: List[Future[CompletedPart]] = [] - for data in start_upload_futs: - res = data.result() - - if res is None: - chunk_upload_bars.update_total_progress(1) - continue - pbar_index = chunk_upload_bars.get_free_task_bar_index() - chunk_upload_bars.set( + wait(chunk_futs) + + queue.put(None) + if config.progress != Progress.none: + print("\x1b[0GFinalizing uploads...") + + wait(listeners) + else: + if dest_exists and dest_is_dir: + normalized = urljoins(normalized, src_path.name) + + num_files = 1 + total_bytes = src_path.stat().st_size + + progress_bars: ProgressBars + with closing( + man.ProgressBars( + num_bars, + show_total_progress=show_total_progress, + verbose=config.verbose, + ) + ) as progress_bars: + pbar_index = progress_bars.get_free_task_bar_index() + + start = time.monotonic() + res = start_upload(src_path, normalized) + + if res is not None: + progress_bars.set( + pbar_index, res.src.stat().st_size, res.src.name + ) + + chunk_futs: List[Future[CompletedPart]] = [] + for part_index, url in enumerate(res.urls): + chunk_futs.append( + exec.submit( + upload_file_chunk, + src_path, + url, + part_index, + res.part_size, + progress_bars, pbar_index, - res.src.stat().st_size, - res.src.name, ) - chunk_upload_bars.set_usage( - str(res.src), res.part_count - ) - - for part_index, url in enumerate(res.urls): - chunk_futs.append( - executor.submit( - upload_file_chunk, - src=res.src, - url=url, - part_index=part_index, - part_size=res.part_size, - progress_bars=chunk_upload_bars, - pbar_index=pbar_index, - queue=queue, - parts_by_source=parts_by_src, - ) - ) - - wait(chunk_futs) - - queue.put(None) - if config.progress != Progress.none: - print("Finalizing uploads...") - wait(listeners) - else: - if dest_exists and dest_is_dir: - normalized = urljoins(normalized, src_path.name) - - num_files = 1 - total_bytes = src_path.stat().st_size - - progress_bars: ProgressBars - with closing( - pbar_manager.ProgressBars( - num_bars, - show_total_progress=show_total_progress, - verbose=config.verbose, ) - ) as progress_bars: - pbar_index = progress_bars.get_free_task_bar_index() - - start = time.monotonic() - res = start_upload(src_path, normalized) - if res is not None: - progress_bars.set( - pbar_index, res.src.stat().st_size, res.src.name - ) + wait(chunk_futs) - chunk_futs: List[Future[CompletedPart]] = [] - for part_index, url in enumerate(res.urls): - chunk_futs.append( - executor.submit( - upload_file_chunk, - src_path, - url, - part_index, - res.part_size, - progress_bars, - pbar_index, - ) - ) - - wait(chunk_futs) - - end_upload( - normalized, - res.upload_id, - [fut.result() for fut in chunk_futs], - ) + end_upload( + normalized, + res.upload_id, + [fut.result() for fut in chunk_futs], + ) end = time.monotonic() total_time = end - start @@ -316,81 +315,84 @@ def start_upload( throttle: Optional[Throttle] = None, latency_q: Optional["LatencyQueueType"] = None, ) -> Optional[StartUploadReturnType]: - if not src.exists(): - raise ValueError(f"Could not find {src}: no such file or link") - - if src.is_symlink(): - src = src.resolve() - - content_type, _ = mimetypes.guess_type(src) - if content_type is None: - with open(src, "rb") as f: - sample = f.read(units.KiB) - - try: - sample.decode() - content_type = "text/plain" - except UnicodeDecodeError: - content_type = "application/octet-stream" - - file_size = src.stat().st_size - if file_size > latch_constants.maximum_upload_size: - raise ValueError( - f"File is {with_si_suffix(file_size)} which exceeds the maximum upload size" - " (5TiB)" + try: + if not src.exists(): + raise ValueError(f"Could not find {src}: no such file or link") + + if src.is_symlink(): + src = src.resolve() + + content_type, _ = mimetypes.guess_type(src) + if content_type is None: + with open(src, "rb") as f: + sample = f.read(units.KiB) + + try: + sample.decode() + content_type = "text/plain" + except UnicodeDecodeError: + content_type = "application/octet-stream" + + file_size = src.stat().st_size + if file_size > latch_constants.maximum_upload_size: + raise ValueError( + f"File is {with_si_suffix(file_size)} which exceeds the maximum upload" + " size (5TiB)" + ) + + part_count = min( + latch_constants.maximum_upload_parts, + math.ceil(file_size / latch_constants.file_chunk_size), + ) + part_size = max( + latch_constants.file_chunk_size, + math.ceil(file_size / latch_constants.maximum_upload_parts), ) - part_count = min( - latch_constants.maximum_upload_parts, - math.ceil(file_size / latch_constants.file_chunk_size), - ) - part_size = max( - latch_constants.file_chunk_size, - math.ceil(file_size / latch_constants.maximum_upload_parts), - ) + retries = 0 + while retries < MAX_RETRIES: + if throttle is not None: + time.sleep(throttle.get_delay()) - retries = 0 - while retries < MAX_RETRIES: - if throttle is not None: - time.sleep(throttle.get_delay()) - - start = time.monotonic() - res = tinyrequests.post( - latch_config.api.data.start_upload, - headers={"Authorization": get_auth_header()}, - json={ - "path": dest, - "content_type": content_type, - "part_count": part_count, - }, - ) - end = time.monotonic() + start = time.monotonic() + res = tinyrequests.post( + latch_config.api.data.start_upload, + headers={"Authorization": get_auth_header()}, + json={ + "path": dest, + "content_type": content_type, + "part_count": part_count, + }, + ) + end = time.monotonic() - if latency_q is not None: - latency_q.put(end - start) + if latency_q is not None: + latency_q.put(end - start) - try: - json_data = res.json() - except JSONDecodeError: - retries += 1 - continue + try: + json_data = res.json() + except JSONDecodeError: + retries += 1 + continue - if res.status_code != 200: - raise ValueError(json_data["error"]) + if res.status_code != 200: + raise ValueError(json_data["error"]) - if progress_bars is not None: - progress_bars.update_total_progress(1) + if progress_bars is not None: + progress_bars.update_total_progress(1) - if "version_id" in json_data["data"]: - return # file is empty, so no need to upload any content + if "version_id" in json_data["data"]: + return # file is empty, so no need to upload any content - data: StartUploadData = json_data["data"] + data: StartUploadData = json_data["data"] - return StartUploadReturnType( - **data, part_count=part_count, part_size=part_size, src=src, dest=dest - ) + return StartUploadReturnType( + **data, part_count=part_count, part_size=part_size, src=src, dest=dest + ) - raise ValueError(f"Unable to generate upload URL for {src}") + raise ValueError(f"Unable to generate upload URL for {src}") + except Exception as e: + raise e.__class__(f"{src}", *e.args) @dataclass(frozen=True) @@ -410,6 +412,8 @@ def upload_file_chunk( queue: Optional["PathQueueType"] = None, parts_by_source: Optional["PartsBySrcType"] = None, ) -> CompletedPart: + time.sleep(0.1 * random.random()) + with open(src, "rb") as f: f.seek(part_size * part_index) data = f.read(part_size) @@ -474,19 +478,20 @@ def end_upload_listener( queue: "PathQueueType", parts_by_src: "PartsBySrcType", upload_info_by_src: "UploadInfoBySrcType", + exec: ProcessPoolExecutor, ): while True: src = queue.get() if src is None: - queue.put(None) return upload_info = upload_info_by_src[src] - end_upload( - upload_info.dest, - upload_info.upload_id, - list(parts_by_src[src]), + exec.submit( + end_upload, + dest=upload_info.dest, + upload_id=upload_info.upload_id, + parts=list(parts_by_src[src]), ) From 4b634fb4632f374bb9206a349a96f926d3c3a21c Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Wed, 23 Aug 2023 15:27:16 -0700 Subject: [PATCH 215/356] finish Signed-off-by: Ayush Kamat --- latch_cli/services/cp/upload.py | 54 ++++++--------------------------- 1 file changed, 10 insertions(+), 44 deletions(-) diff --git a/latch_cli/services/cp/upload.py b/latch_cli/services/cp/upload.py index 9565a314..e2d6fb44 100644 --- a/latch_cli/services/cp/upload.py +++ b/latch_cli/services/cp/upload.py @@ -164,11 +164,6 @@ def upload( ) for fut in as_completed(start_upload_futs): - e = fut.exception() - if e is not None: - print(e) - raise e - res = fut.result() if res is not None: upload_info_by_src[res.src] = res @@ -176,17 +171,6 @@ def upload( latency_q.put(None) wait([throttle_listener]) - queue: "PathQueueType" = man.Queue() - listeners = [ - exec.submit( - end_upload_listener, - queue=queue, - parts_by_src=parts_by_src, - upload_info_by_src=upload_info_by_src, - exec=exec, - ) - ] - chunk_upload_bars: ProgressBars with closing( man.ProgressBars( @@ -224,18 +208,16 @@ def upload( part_size=res.part_size, progress_bars=chunk_upload_bars, pbar_index=pbar_index, - queue=queue, parts_by_source=parts_by_src, + upload_id=res.upload_id, + dest=res.dest, ) ) wait(chunk_futs) - queue.put(None) if config.progress != Progress.none: print("\x1b[0GFinalizing uploads...") - - wait(listeners) else: if dest_exists and dest_is_dir: normalized = urljoins(normalized, src_path.name) @@ -409,8 +391,9 @@ def upload_file_chunk( part_size: int, progress_bars: ProgressBars, pbar_index: Optional[int], - queue: Optional["PathQueueType"] = None, parts_by_source: Optional["PartsBySrcType"] = None, + upload_id: Optional[str] = None, + dest: Optional[str] = None, ) -> CompletedPart: time.sleep(0.1 * random.random()) @@ -439,8 +422,12 @@ def upload_file_chunk( progress_bars.update_total_progress(1) progress_bars.write(f"Copied {src}") - if queue is not None: - queue.put(src) + if dest is not None and parts_by_source is not None and upload_id is not None: + end_upload( + dest=dest, + upload_id=upload_id, + parts=list(parts_by_source[src]), + ) return ret @@ -474,27 +461,6 @@ def end_upload( progress_bars.update_total_progress(1) -def end_upload_listener( - queue: "PathQueueType", - parts_by_src: "PartsBySrcType", - upload_info_by_src: "UploadInfoBySrcType", - exec: ProcessPoolExecutor, -): - while True: - src = queue.get() - if src is None: - return - - upload_info = upload_info_by_src[src] - - exec.submit( - end_upload, - dest=upload_info.dest, - upload_id=upload_info.upload_id, - parts=list(parts_by_src[src]), - ) - - def throttler(t: Throttle, q: "LatencyQueueType"): ema = 0 From 81945a5fae62a75e26f4cdc0ef1a1bd47f12a97c Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Wed, 23 Aug 2023 16:18:57 -0700 Subject: [PATCH 216/356] small fixes to local dev post snakemake merge Signed-off-by: Ayush Kamat --- latch_cli/services/local_dev_old.py | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/latch_cli/services/local_dev_old.py b/latch_cli/services/local_dev_old.py index cb4f7763..9a1d8e38 100644 --- a/latch_cli/services/local_dev_old.py +++ b/latch_cli/services/local_dev_old.py @@ -17,12 +17,11 @@ import asyncssh import boto3 import click -import websockets.client as websockets +import websockets.client as client import websockets.exceptions from latch_sdk_config.latch import config from watchfiles import awatch -from latch_cli.constants import latch_constants from latch_cli.tinyrequests import post from latch_cli.utils import ( TemporarySSHCredentials, @@ -124,7 +123,7 @@ class _MessageType(Enum): async def _get_messages( - ws: websockets.WebSocketClientProtocol, + ws: client.WebSocketClientProtocol, show_output: bool, ): async for message in ws: @@ -140,7 +139,7 @@ async def _get_messages( async def _send_message( - ws: websockets.WebSocketClientProtocol, + ws: client.WebSocketClientProtocol, message: Union[str, bytes], typ: Optional[_MessageType] = None, ): @@ -156,7 +155,7 @@ async def _send_message( async def _send_resize_message( - ws: websockets.WebSocketClientProtocol, + ws: client.WebSocketClientProtocol, term_width: int, term_height: int, ): @@ -173,7 +172,7 @@ async def _send_resize_message( async def _shell_session( - ws: websockets.WebSocketClientProtocol, + ws: client.WebSocketClientProtocol, ): old_settings_stdin = termios.tcgetattr(sys.stdin.fileno()) tty.setraw(sys.stdin) @@ -238,9 +237,10 @@ async def output_task(): return message = obj.get("Body") - if isinstance(message, str): - message = message.encode("utf-8") - writer.write(message) + if message is not None: + if isinstance(message, str): + message = message.encode("utf-8") + writer.write(message) await writer.drain() await asyncio.sleep(0) @@ -259,7 +259,7 @@ async def _run_local_dev_session(pkg_root: Path): # doing anything _get_latest_image(pkg_root) - key_path = pkg_root / latch_constants.pkg_ssh_key + key_path = pkg_root / ".latch" / "ssh_key" with TemporarySSHCredentials(key_path) as ssh: headers = {"Authorization": f"Bearer {retrieve_or_login()}"} @@ -290,7 +290,6 @@ async def _run_local_dev_session(pkg_root: Path): try: cent_data = cent_resp.json() centromere_ip = cent_data["ip"] - centromere_username = cent_data["username"] except KeyError as e: raise ValueError(f"Malformed response from provision endpoint: missing {e}") @@ -328,7 +327,7 @@ async def _run_local_dev_session(pkg_root: Path): # todo(aidan): edit known hosts file with centromere ip and address to allow strict host checking try: - async for ws in websockets.connect( + async for ws in client.connect( f"ws://{centromere_ip}:{port}/ws", close_timeout=0, extra_headers=headers, From 63c962b773ecfb5ca839e6d0422365dd0bc08f9f Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Wed, 23 Aug 2023 17:27:00 -0700 Subject: [PATCH 217/356] actually do retries lolmao Signed-off-by: Ayush Kamat --- latch_cli/services/cp/upload.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/latch_cli/services/cp/upload.py b/latch_cli/services/cp/upload.py index e2d6fb44..13ca547f 100644 --- a/latch_cli/services/cp/upload.py +++ b/latch_cli/services/cp/upload.py @@ -334,7 +334,7 @@ def start_upload( retries = 0 while retries < MAX_RETRIES: if throttle is not None: - time.sleep(throttle.get_delay()) + time.sleep(throttle.get_delay() * math.exp(retries * 1 / 2)) start = time.monotonic() res = tinyrequests.post( @@ -358,7 +358,8 @@ def start_upload( continue if res.status_code != 200: - raise ValueError(json_data["error"]) + retries += 1 + continue if progress_bars is not None: progress_bars.update_total_progress(1) From 96db3afc670d7caa4ffd194fa8b0c66c98ca9594 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Wed, 23 Aug 2023 17:35:46 -0700 Subject: [PATCH 218/356] bump ver + changelog Signed-off-by: Ayush Kamat --- CHANGELOG.md | 16 +++++++++++++--- setup.py | 2 +- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a5e884d..9c843564 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,16 @@ Types of changes # Latch SDK Changelog +## 2.32.0 - 2023-08-23 + +### Changed + +* `latch cp` can now handle directories with up to `50k` objects + +### Fixed + +* Various vestigial bugs in `latch develop` that blocked certain users + ## 2.31.1 - 2023-08-08 ### Changed @@ -240,7 +250,7 @@ Types of changes ### Dependencies -* Removed `awscli`, `uvloop`, and `prompt-toolkit` as they were unused. +* Removed `awscli`, `uvloop`, and `prompt-toolkit` as they were unused. ## 2.22.4 - 2023-06-08 @@ -613,8 +623,8 @@ Types of changes ### Deprecated -* The commands `latch rm`, `latch mkdir`, and `latch touch`. -* The operators `left_join`, `right_join`, `inner_join`, `outer_join`, +* The commands `latch rm`, `latch mkdir`, and `latch touch`. +* The operators `left_join`, `right_join`, `inner_join`, `outer_join`, `group_tuple` , `latch_filter` , and `combine` ### Removed diff --git a/setup.py b/setup.py index 3042bc40..a31288a5 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ setup( name="latch", - version="v2.31.1", + version="v2.32.0", author_email="kenny@latch.bio", description="The Latch SDK", packages=find_packages(), From c17304f352578c436c8d7043a7c5d12f8748e859 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Thu, 24 Aug 2023 09:24:33 -0700 Subject: [PATCH 219/356] typos Signed-off-by: Ayush Kamat --- latch_cli/services/cp/throttle.py | 5 +---- latch_cli/services/cp/upload.py | 10 ---------- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/latch_cli/services/cp/throttle.py b/latch_cli/services/cp/throttle.py index c17c099f..30d95ecf 100644 --- a/latch_cli/services/cp/throttle.py +++ b/latch_cli/services/cp/throttle.py @@ -1,7 +1,4 @@ -from multiprocessing.managers import BaseManager -from typing import Type - -from attr import dataclass +from dataclasses import dataclass @dataclass diff --git a/latch_cli/services/cp/upload.py b/latch_cli/services/cp/upload.py index 13ca547f..78a88130 100644 --- a/latch_cli/services/cp/upload.py +++ b/latch_cli/services/cp/upload.py @@ -1,9 +1,5 @@ -import datetime -import json -import logging import math import mimetypes -import multiprocessing import os import random import time @@ -37,12 +33,6 @@ PartsBySrcType: TypeAlias = DictProxy[Path, ListProxy["CompletedPart"]] UploadInfoBySrcType: TypeAlias = DictProxy[Path, "StartUploadReturnType"] -logging.basicConfig() -multiprocessing.get_logger().setLevel(logging.DEBUG) - - -start_upload_batch_size = 100 - class EmptyUploadData(TypedDict): version_id: str From d7e043b6bff8afeeaf26bbe1d7d00735d065ca52 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Thu, 24 Aug 2023 09:26:13 -0700 Subject: [PATCH 220/356] bump ver + changelog Signed-off-by: Ayush Kamat --- CHANGELOG.md | 12 +++++++++--- setup.py | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c843564..ffc1c3e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,12 @@ Types of changes # Latch SDK Changelog +## 2.32.1 - 2023-08-24 + +### Fixed + +* Corrected `dataclass` import and removed `multiprocessing` logging from `latch cp`. + ## 2.32.0 - 2023-08-23 ### Changed @@ -250,7 +256,7 @@ Types of changes ### Dependencies -* Removed `awscli`, `uvloop`, and `prompt-toolkit` as they were unused. +* Removed `awscli`, `uvloop`, and `prompt-toolkit` as they were unused. ## 2.22.4 - 2023-06-08 @@ -623,8 +629,8 @@ Types of changes ### Deprecated -* The commands `latch rm`, `latch mkdir`, and `latch touch`. -* The operators `left_join`, `right_join`, `inner_join`, `outer_join`, +* The commands `latch rm`, `latch mkdir`, and `latch touch`. +* The operators `left_join`, `right_join`, `inner_join`, `outer_join`, `group_tuple` , `latch_filter` , and `combine` ### Removed diff --git a/setup.py b/setup.py index a31288a5..a75efa08 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ setup( name="latch", - version="v2.32.0", + version="v2.32.1", author_email="kenny@latch.bio", description="The Latch SDK", packages=find_packages(), From bfa91250d5f4bdd45cfc9855bfd44bf236b8f001 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Thu, 24 Aug 2023 17:05:28 -0700 Subject: [PATCH 221/356] fix autocomplete lol Signed-off-by: Ayush Kamat --- latch/types/directory.py | 2 +- latch/types/file.py | 2 +- latch_cli/click_utils.py | 4 + latch_cli/main.py | 102 ++------- latch_cli/services/cp/autocomplete.py | 20 +- latch_cli/services/cp/download.py | 2 +- latch_cli/services/cp/ldata_utils.py | 2 +- latch_cli/services/cp/main.py | 2 +- latch_cli/services/cp/remote_copy.py | 2 +- latch_cli/services/cp/upload.py | 2 +- latch_cli/services/ls.py | 214 +++++++++++++++--- latch_cli/services/move.py | 6 +- .../cp/path_utils.py => utils/path.py} | 14 +- 13 files changed, 226 insertions(+), 148 deletions(-) rename latch_cli/{services/cp/path_utils.py => utils/path.py} (91%) diff --git a/latch/types/directory.py b/latch/types/directory.py index 225a017e..0570a58c 100644 --- a/latch/types/directory.py +++ b/latch/types/directory.py @@ -17,8 +17,8 @@ from latch.types.file import LatchFile from latch.types.utils import _is_valid_url -from latch_cli.services.cp.path_utils import normalize_path from latch_cli.utils import urljoins +from latch_cli.utils.path import normalize_path class Child(TypedDict): diff --git a/latch/types/file.py b/latch/types/file.py index 7ebe07e7..6af46837 100644 --- a/latch/types/file.py +++ b/latch/types/file.py @@ -13,7 +13,7 @@ from typing_extensions import Annotated from latch.types.utils import _is_valid_url -from latch_cli.services.cp.path_utils import normalize_path +from latch_cli.utils.path import normalize_path is_absolute_node_path = re.compile(r"^(latch)?://\d+.node(/)?$") diff --git a/latch_cli/click_utils.py b/latch_cli/click_utils.py index e334a580..ff5fb627 100644 --- a/latch_cli/click_utils.py +++ b/latch_cli/click_utils.py @@ -102,6 +102,10 @@ def patch(): click.UsageError.show = colored_usage_error_show +def bold(s: str) -> str: + return f"{AnsiCodes.bold}{s}{AnsiCodes.reset}" + + class AnsiCodes: bold = "\x1b[1m" reset = "\x1b[22m" diff --git a/latch_cli/main.py b/latch_cli/main.py index 268f21b5..aaf932d4 100644 --- a/latch_cli/main.py +++ b/latch_cli/main.py @@ -5,7 +5,7 @@ from collections import OrderedDict from pathlib import Path from textwrap import dedent -from typing import List, Optional, Union +from typing import List, Optional, Tuple, Union import click from packaging.version import parse as parse_version @@ -52,7 +52,7 @@ def main(): If you are on a machine with a browser, run `latch login`. If not, navigate to `https://console.latch.bio/settings/developer` on a different machine, select `Access Tokens`, and copy your `API Key` to `~/.latch/token` on this machine. - """), + """).strip("\n"), fg="red", ) raise click.exceptions.Exit() @@ -357,103 +357,29 @@ def mv(src: str, dest: str): is_flag=True, default=False, ) -# todo(maximsmol): enable once ls uses gql and supports new paths -# @click.argument("remote_directories", nargs=-1, shell_complete=remote_complete) -@click.argument("remote_directories", nargs=-1) -def ls(group_directories_first: bool, remote_directories: Union[None, List[str]]): +@click.argument("paths", nargs=-1, shell_complete=remote_complete) +def ls(paths: Tuple[str], group_directories_first: bool): """ List the contents of a Latch Data directory """ - crash_handler.message = f"Unable to display contents of {remote_directories}" + crash_handler.message = f"Unable to display contents of {paths}" crash_handler.pkg_root = str(Path.cwd()) - from datetime import datetime - from latch_cli.services.ls import ls - from latch_cli.utils import with_si_suffix # If the user doesn't provide any arguments, default to root - if not remote_directories: - remote_directories = ["latch:///"] - - for remote_directory in remote_directories: - if len(remote_directories) > 1: - click.echo(f"{remote_directory}:") - - output = ls(remote_directory) - - output.sort(key=lambda row: row["name"]) - if group_directories_first: - output.sort(key=lambda row: row["type"]) - - formatted = [] - for row in output: - vals = { - "contentSize": ( - click.style( - with_si_suffix(int(row["contentSize"]), suffix="", styled=True), - fg="bright_green", - ) - if row["contentSize"] != "-" and row["type"] != "dir" - else click.style("-", dim=True) - ), - "modifyTime": ( - click.style( - datetime.fromisoformat(row["modifyTime"]).strftime( - "%d %b %H:%M" - ), - fg="blue", - ) - if row["modifyTime"] != "-" and row["type"] != "dir" - else click.style("-", dim=True) - ), - "name": ( - row["name"] if len(row["name"]) <= 50 else f"{row['name'][:47]}..." - ), - } - - if row["type"] == "dir": - vals["name"] = ( - click.style(row["name"], fg="bright_blue", bold=True) + "/" - ) - - formatted.append(vals) - - columns = OrderedDict( - contentSize="Size", modifyTime="Date Modified", name="Name" - ) + if len(paths) == 0: + paths = ("",) - column_width = {key: len(title) for key, title in columns.items()} - for row in formatted: - for key in columns: - column_width[key] = max(column_width[key], len(click.unstyle(row[key]))) - - def pad_styled(x: str, l: int, align_right=False): - cur = len(click.unstyle(x)) - - pad = " " * (l - cur) - if align_right: - return pad + x - return x + pad - - click.echo( - " ".join( - pad_styled( - click.style(title, underline=True), - column_width[key], - key == "contentSize", - ) - for key, title in columns.items() - ) + for path in paths: + if len(paths) > 1: + click.echo(f"{path}:") + + ls( + path, + group_directories_first=group_directories_first, ) - for row in formatted: - click.echo( - " ".join( - pad_styled(row[k], column_width[k], k == "contentSize") - for k in columns - ) - ) @main.command("launch") diff --git a/latch_cli/services/cp/autocomplete.py b/latch_cli/services/cp/autocomplete.py index 531086b3..da77f053 100644 --- a/latch_cli/services/cp/autocomplete.py +++ b/latch_cli/services/cp/autocomplete.py @@ -1,10 +1,6 @@ -try: - from functools import cache -except ImportError: - from functools import lru_cache as cache - import os import re +from functools import lru_cache from pathlib import Path from typing import List @@ -16,13 +12,17 @@ _get_known_domains_for_account, ) +cache = lru_cache(maxsize=None) completion_type = re.compile( r""" ^ (latch)? :/?/? (?P[^/]*) - (?P/.*)? + ( + (?P(/[^/]*)*)? + (?P/[^/]*) + )? $ """, re.VERBOSE, @@ -30,7 +30,10 @@ def complete( - ctx: click.Context, param: click.Argument, incomplete: str, allow_local: bool = True + ctx: click.Context, + param: click.Argument, + incomplete: str, + allow_local: bool = True, ) -> List[sc.CompletionItem]: match = completion_type.match(incomplete) @@ -81,9 +84,10 @@ def _complete_local_path(incomplete: str) -> List[sc.CompletionItem]: @cache def _complete_remote_path(match: re.Match[str]) -> List[sc.CompletionItem]: domain = match["domain"] + parent = match["parent"] path = match["path"][1:] - parent = f"://{domain}" + parent = f"://{domain}{parent}" if match[0].startswith("latch"): parent = f"latch{parent}" diff --git a/latch_cli/services/cp/download.py b/latch_cli/services/cp/download.py index f91ada28..d9e9dc5f 100644 --- a/latch_cli/services/cp/download.py +++ b/latch_cli/services/cp/download.py @@ -14,10 +14,10 @@ from latch_cli.services.cp.config import CPConfig, Progress from latch_cli.services.cp.ldata_utils import LDataNodeType, get_node_data from latch_cli.services.cp.manager import CPStateManager -from latch_cli.services.cp.path_utils import normalize_path from latch_cli.services.cp.progress import ProgressBars, get_free_index from latch_cli.services.cp.utils import get_max_workers, human_readable_time from latch_cli.utils import get_auth_header, with_si_suffix +from latch_cli.utils.path import normalize_path class GetSignedUrlData(TypedDict): diff --git a/latch_cli/services/cp/ldata_utils.py b/latch_cli/services/cp/ldata_utils.py index 236ab4c4..5215d7ec 100644 --- a/latch_cli/services/cp/ldata_utils.py +++ b/latch_cli/services/cp/ldata_utils.py @@ -12,7 +12,7 @@ from latch_sdk_gql.execute import execute from latch_sdk_gql.utils import _name_node, _parse_selection -from latch_cli.services.cp.path_utils import get_path_error, normalize_path +from latch_cli.utils.path import get_path_error, normalize_path class LDataNodeType(str, Enum): diff --git a/latch_cli/services/cp/main.py b/latch_cli/services/cp/main.py index 555485b7..e158f01a 100644 --- a/latch_cli/services/cp/main.py +++ b/latch_cli/services/cp/main.py @@ -4,9 +4,9 @@ from latch_cli.services.cp.config import CPConfig, Progress from latch_cli.services.cp.download import download from latch_cli.services.cp.glob import expand_pattern -from latch_cli.services.cp.path_utils import is_remote_path from latch_cli.services.cp.remote_copy import remote_copy from latch_cli.services.cp.upload import upload +from latch_cli.utils.path import is_remote_path # todo(ayush): come up with a better behavior scheme than unix cp diff --git a/latch_cli/services/cp/remote_copy.py b/latch_cli/services/cp/remote_copy.py index 1eeac672..eb481130 100644 --- a/latch_cli/services/cp/remote_copy.py +++ b/latch_cli/services/cp/remote_copy.py @@ -4,7 +4,7 @@ from latch_sdk_gql.execute import execute from latch_cli.services.cp.ldata_utils import LDataNodeType, get_node_data -from latch_cli.services.cp.path_utils import get_name_from_path, get_path_error +from latch_cli.utils.path import get_name_from_path, get_path_error # todo(ayush): figure out how to do progress for this diff --git a/latch_cli/services/cp/upload.py b/latch_cli/services/cp/upload.py index 78a88130..a642660d 100644 --- a/latch_cli/services/cp/upload.py +++ b/latch_cli/services/cp/upload.py @@ -21,11 +21,11 @@ from latch_cli.services.cp.config import CPConfig, Progress from latch_cli.services.cp.ldata_utils import LDataNodeType, get_node_data from latch_cli.services.cp.manager import CPStateManager -from latch_cli.services.cp.path_utils import normalize_path from latch_cli.services.cp.progress import ProgressBars from latch_cli.services.cp.throttle import Throttle from latch_cli.services.cp.utils import get_max_workers, human_readable_time from latch_cli.utils import get_auth_header, urljoins, with_si_suffix +from latch_cli.utils.path import normalize_path if TYPE_CHECKING: PathQueueType: TypeAlias = "Queue[Optional[Path]]" diff --git a/latch_cli/services/ls.py b/latch_cli/services/ls.py index 5b6a32e0..1c8b2564 100644 --- a/latch_cli/services/ls.py +++ b/latch_cli/services/ls.py @@ -1,25 +1,66 @@ """Service to list files in a remote directory.""" -import os -from typing import Dict, List +from dataclasses import dataclass +from datetime import datetime +from textwrap import dedent, shorten +from typing import List, Optional, TypedDict -from latch_sdk_config.latch import config +import click +import gql +from latch_sdk_gql.execute import execute -import latch_cli.tinyrequests as tinyrequests -from latch_cli.utils import _normalize_remote_path, current_workspace, retrieve_or_login +from latch_cli.click_utils import bold +from latch_cli.services.cp.ldata_utils import LDataNodeType +from latch_cli.utils import with_si_suffix +from latch_cli.utils.path import is_remote_path, normalize_path -def ls(remote_directory: str) -> List[Dict[str, str]]: - """Lists the remote entities inside of a remote_directory +class LdataObjectMeta(TypedDict): + modifyTime: Optional[str] + contentSize: Optional[int] + + +class Child(TypedDict): + name: str + ldataObjectMeta: Optional[LdataObjectMeta] + type: str + + +class Node(TypedDict): + child: Child + + +class ChildLdataTreeEdges(TypedDict): + nodes: List[Node] + + +class FinalLinkTarget(TypedDict): + childLdataTreeEdges: ChildLdataTreeEdges + + +class LdataResolvePathData(TypedDict): + name: str + type: str + ldataObjectMeta: Optional[LdataObjectMeta] + finalLinkTarget: FinalLinkTarget + + +@dataclass(frozen=True) +class Row: + name: str + type: LDataNodeType + size: Optional[int] + modify_time: Optional[datetime] + + +def ls(path: str, *, group_directories_first: bool = False): + """Lists the children of a remote directory in Latch. Args: - remote_directory: A valid path to a remote destination, of the form - ``[latch://]/dir_1/dir_2/.../dir_n/dir_name``, where `dir_name` - is the name of the directory to list under. Every directory in the - path must already exist. + path: A valid remote path This function will list all of the entites under the remote directory - specified in the path `remote_directory`. Will error if the path is invalid + specified in the path `path`. Will error if the path is invalid or the directory doesn't exist. Examples: @@ -30,26 +71,129 @@ def ls(remote_directory: str) -> List[Dict[str, str]]: >>> ls("latch:///dir1/dir2/dir_name") # Lists all entities inside dir1/dir2/dir_name """ - remote_directory = _normalize_remote_path(remote_directory) - - url = config.api.data.list - - token = os.environ.get("FLYTE_INTERNAL_EXECUTION_ID", "") - if token != "": - auth_header = f"Latch-Execution-Token {token}" - ws_id = {} - else: - auth_header = f"Bearer {retrieve_or_login()}" - ws_id = {"ws_account_id": current_workspace()} - - headers = {"Authorization": auth_header} - data = {"directory": remote_directory, **ws_id} - - response = tinyrequests.post(url, headers=headers, json=data) - - if response.status_code == 400: - raise ValueError(f"The directory {remote_directory} does not exist.") - - output = list(response.json().values()) - - return output + if path == "": + path = "/" + + normalized_path = normalize_path(path, assume_remote=True) + + query = execute( + gql.gql(""" + query LdataInfo ($argPath: String!) { + accountInfoCurrent { + id + } + ldataResolvePathData(argPath: $argPath) { + name + ldataObjectMeta { + modifyTime + contentSize + } + type + finalLinkTarget { + childLdataTreeEdges(filter: { + child: { + removed: { equalTo: false }, + pending: { equalTo: false } + } + }) { + nodes { + child { + name + ldataObjectMeta { + modifyTime + contentSize + } + type + } + } + } + } + } + } + """), + {"argPath": normalized_path}, + ) + + res: Optional[LdataResolvePathData] = query["ldataResolvePathData"] + acc_id: str = query["accountInfoCurrent"]["id"] + + if res is None: + click.secho( + dedent(f""" + {bold(path)}: no such file or directory. + + {bold("Check that:")} + 1. The target directory exists, + 2. Account {bold(acc_id)} has permissions to view the target directory, and + 3. The correct workspace is selected. + + For privacy reasons, non-viewable objects and non-existent objects are indistinguishable. + """).strip("\n"), + fg="red", + ) + return + + nodes = res["finalLinkTarget"]["childLdataTreeEdges"]["nodes"] + if LDataNodeType(res["type"].lower()) == LDataNodeType.obj: + # ls object should just display the object's info + nodes.append({"child": res}) + + rows: List[Row] = [] + for node in nodes: + child = node["child"] + + meta = child["ldataObjectMeta"] + size = modify_time = None + if meta is not None: + if meta["contentSize"] is not None: + size = int(meta["contentSize"]) + if meta["modifyTime"] is not None: + modify_time = datetime.fromisoformat(meta["modifyTime"]) + + rows.append( + Row( + name=child["name"], + type=LDataNodeType(child["type"].lower()), + size=size, + modify_time=modify_time, + ) + ) + + rows.sort(key=lambda row: row.name) + if group_directories_first: + rows.sort(key=lambda row: 1 if row.type == LDataNodeType.obj else 0) + + headers = [ + click.style(f"{'Size': >6}", underline=True), + click.style(f"Date Modified", underline=True), + click.style(f"Name", underline=True), + ] + + click.echo(" ".join(headers)) + + for row in rows: + mt_str = f'{"-": <13}' + size_str = f'{"-": >6}' + if row.type == LDataNodeType.obj: + if row.modify_time is not None: + mt_str = click.style( + f'{row.modify_time.strftime("%d %b %H:%M"): <13}', fg="blue" + ) + + if row.size is not None: + size_str = with_si_suffix(row.size, suffix="") + size_str = click.style(f"{size_str: >6}", fg="bright_green") + + name_str = shorten(row.name, 50) + if row.type != LDataNodeType.obj: + color = "bright_blue" + if row.type == LDataNodeType.link: + color = "bright_magenta" + + name_str = click.style(f"{name_str}/", bold=True, fg=color) + + click.echo(f"{size_str} {mt_str} {name_str}") + + +if __name__ == "__main__": + ls("/", group_directories_first=False) diff --git a/latch_cli/services/move.py b/latch_cli/services/move.py index 07788f04..1a135c7b 100644 --- a/latch_cli/services/move.py +++ b/latch_cli/services/move.py @@ -4,11 +4,7 @@ from latch_sdk_gql.execute import execute from latch_cli.services.cp.ldata_utils import LDataNodeType, get_node_data -from latch_cli.services.cp.path_utils import ( - get_name_from_path, - get_path_error, - is_remote_path, -) +from latch_cli.utils.path import get_name_from_path, get_path_error, is_remote_path def move( diff --git a/latch_cli/services/cp/path_utils.py b/latch_cli/utils/path.py similarity index 91% rename from latch_cli/services/cp/path_utils.py rename to latch_cli/utils/path.py index 037d70b2..2d5ee841 100644 --- a/latch_cli/services/cp/path_utils.py +++ b/latch_cli/utils/path.py @@ -52,7 +52,11 @@ def is_remote_path(path: str) -> bool: # ://domain/a/b/c => latch://domain/a/b/c # /a/b/c => file:///a/b/c # a/b/c => file://${pwd}/a/b/c -def append_scheme(path: str) -> str: +# +# if assume_remote = True (i.e. in the ls case): +# /a/b/c => latch:///a/b/c +# a/b/c => latch:///a/b/c +def append_scheme(path: str, *, assume_remote: bool = False) -> str: match = scheme.match(path) if match is None: raise PathResolutionError(f"{path} is not in a valid format") @@ -60,9 +64,9 @@ def append_scheme(path: str) -> str: if match["implicit_url"] is not None: path = f"latch{path}" elif match["absolute_path"] is not None: - path = f"file://{path}" + path = f"latch://{path}" if assume_remote else f"file://{path}" elif match["relative_path"] is not None: - path = f"file://{Path.cwd()}/{path}" + path = f"latch:///{path}" if assume_remote else f"file://{Path.cwd()}/{path}" return path @@ -108,8 +112,8 @@ def is_account_relative(path: str) -> bool: return match["account_relative"] is not None -def normalize_path(path: str) -> str: - path = append_scheme(path) +def normalize_path(path: str, *, assume_remote: bool = False) -> str: + path = append_scheme(path, assume_remote=assume_remote) if path.startswith("file://"): return path From 8cac2415a22d202f84a166a919dd518837b98d7c Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Fri, 25 Aug 2023 11:11:50 -0700 Subject: [PATCH 222/356] fixies Signed-off-by: Ayush Kamat --- latch_cli/main.py | 14 ++++++++------ latch_cli/services/ls.py | 13 ++++++++----- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/latch_cli/main.py b/latch_cli/main.py index aaf932d4..7e18d0e8 100644 --- a/latch_cli/main.py +++ b/latch_cli/main.py @@ -2,7 +2,6 @@ import os import sys -from collections import OrderedDict from pathlib import Path from textwrap import dedent from typing import List, Optional, Tuple, Union @@ -45,7 +44,7 @@ def main(): """ try: get_auth_header() - except AuthenticationError: + except AuthenticationError as e: click.secho( dedent(""" Unable to authenticate with Latch. @@ -55,7 +54,7 @@ def main(): """).strip("\n"), fg="red", ) - raise click.exceptions.Exit() + raise click.exceptions.Exit() from e local_ver = parse_version(get_local_package_version()) latest_ver = parse_version(get_latest_package_version()) @@ -370,7 +369,7 @@ def ls(paths: Tuple[str], group_directories_first: bool): # If the user doesn't provide any arguments, default to root if len(paths) == 0: - paths = ("",) + paths = ("/",) for path in paths: if len(paths) > 1: @@ -381,6 +380,9 @@ def ls(paths: Tuple[str], group_directories_first: bool): group_directories_first=group_directories_first, ) + if len(paths) > 1: + click.echo("") + @main.command("launch") @click.argument("params_file", nargs=1, type=click.Path(exists=True)) @@ -502,7 +504,7 @@ def mkdir(remote_directory: str): from latch_cli.services.deprecated.mkdir import mkdir click.secho( - f"Warning: `latch mkdir` is deprecated and will be removed soon.", + "Warning: `latch mkdir` is deprecated and will be removed soon.", fg="yellow", ) mkdir(remote_directory) @@ -519,7 +521,7 @@ def touch(remote_file: str): from latch_cli.services.deprecated.touch import touch click.secho( - f"Warning: `latch touch` is deprecated and will be removed soon.", + "Warning: `latch touch` is deprecated and will be removed soon.", fg="yellow", ) touch(remote_file) diff --git a/latch_cli/services/ls.py b/latch_cli/services/ls.py index 1c8b2564..67b60c1d 100644 --- a/latch_cli/services/ls.py +++ b/latch_cli/services/ls.py @@ -2,7 +2,7 @@ from dataclasses import dataclass from datetime import datetime -from textwrap import dedent, shorten +from textwrap import TextWrapper, dedent, shorten from typing import List, Optional, TypedDict import click @@ -58,16 +58,16 @@ def ls(path: str, *, group_directories_first: bool = False): Args: path: A valid remote path + group_directories_first: Option to display directories/links before + objects This function will list all of the entites under the remote directory specified in the path `path`. Will error if the path is invalid or the directory doesn't exist. Examples: - >>> ls("") # Lists all entities in the user's root directory - >>> ls("latch:///dir1/dir2/dir_name") # Lists all entities inside dir1/dir2/dir_name """ @@ -164,7 +164,7 @@ def ls(path: str, *, group_directories_first: bool = False): rows.sort(key=lambda row: 1 if row.type == LDataNodeType.obj else 0) headers = [ - click.style(f"{'Size': >6}", underline=True), + " " + click.style(f"Size", underline=True), click.style(f"Date Modified", underline=True), click.style(f"Name", underline=True), ] @@ -184,7 +184,10 @@ def ls(path: str, *, group_directories_first: bool = False): size_str = with_si_suffix(row.size, suffix="") size_str = click.style(f"{size_str: >6}", fg="bright_green") - name_str = shorten(row.name, 50) + name_str = row.name + if len(name_str) > 50: + name_str = f"{name_str[:47]}..." + if row.type != LDataNodeType.obj: color = "bright_blue" if row.type == LDataNodeType.link: From 5f8d3adc70d0a94ef67c0f91df86202cb8c72329 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Fri, 25 Aug 2023 11:23:42 -0700 Subject: [PATCH 223/356] bump changelog + ver Signed-off-by: Ayush Kamat --- CHANGELOG.md | 13 +++++++++--- latch_cli/services/ls.py | 46 ++++++++++++++++++---------------------- setup.py | 2 +- 3 files changed, 32 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ffc1c3e1..a711c721 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,13 @@ Types of changes # Latch SDK Changelog +## 2.32.2 - 2023-08-25 + +### Fixed + +* Fixed `latch ls` to work with all latch URLs +* Fixed autocomplete bug where no completion results would be returned for longer paths + ## 2.32.1 - 2023-08-24 ### Fixed @@ -256,7 +263,7 @@ Types of changes ### Dependencies -* Removed `awscli`, `uvloop`, and `prompt-toolkit` as they were unused. +* Removed `awscli`, `uvloop`, and `prompt-toolkit` as they were unused. ## 2.22.4 - 2023-06-08 @@ -629,8 +636,8 @@ Types of changes ### Deprecated -* The commands `latch rm`, `latch mkdir`, and `latch touch`. -* The operators `left_join`, `right_join`, `inner_join`, `outer_join`, +* The commands `latch rm`, `latch mkdir`, and `latch touch`. +* The operators `left_join`, `right_join`, `inner_join`, `outer_join`, `group_tuple` , `latch_filter` , and `combine` ### Removed diff --git a/latch_cli/services/ls.py b/latch_cli/services/ls.py index 67b60c1d..7a8c5c69 100644 --- a/latch_cli/services/ls.py +++ b/latch_cli/services/ls.py @@ -2,7 +2,7 @@ from dataclasses import dataclass from datetime import datetime -from textwrap import TextWrapper, dedent, shorten +from textwrap import dedent from typing import List, Optional, TypedDict import click @@ -12,41 +12,41 @@ from latch_cli.click_utils import bold from latch_cli.services.cp.ldata_utils import LDataNodeType from latch_cli.utils import with_si_suffix -from latch_cli.utils.path import is_remote_path, normalize_path +from latch_cli.utils.path import normalize_path -class LdataObjectMeta(TypedDict): +class _LdataObjectMeta(TypedDict): modifyTime: Optional[str] contentSize: Optional[int] -class Child(TypedDict): +class _Child(TypedDict): name: str - ldataObjectMeta: Optional[LdataObjectMeta] + ldataObjectMeta: Optional[_LdataObjectMeta] type: str -class Node(TypedDict): - child: Child +class _Node(TypedDict): + child: _Child -class ChildLdataTreeEdges(TypedDict): - nodes: List[Node] +class _ChildLdataTreeEdges(TypedDict): + nodes: List[_Node] -class FinalLinkTarget(TypedDict): - childLdataTreeEdges: ChildLdataTreeEdges +class _FinalLinkTarget(TypedDict): + childLdataTreeEdges: _ChildLdataTreeEdges -class LdataResolvePathData(TypedDict): +class _LdataResolvePathData(TypedDict): name: str type: str - ldataObjectMeta: Optional[LdataObjectMeta] - finalLinkTarget: FinalLinkTarget + ldataObjectMeta: Optional[_LdataObjectMeta] + finalLinkTarget: _FinalLinkTarget @dataclass(frozen=True) -class Row: +class _Row: name: str type: LDataNodeType size: Optional[int] @@ -114,7 +114,7 @@ def ls(path: str, *, group_directories_first: bool = False): {"argPath": normalized_path}, ) - res: Optional[LdataResolvePathData] = query["ldataResolvePathData"] + res: Optional[_LdataResolvePathData] = query["ldataResolvePathData"] acc_id: str = query["accountInfoCurrent"]["id"] if res is None: @@ -138,7 +138,7 @@ def ls(path: str, *, group_directories_first: bool = False): # ls object should just display the object's info nodes.append({"child": res}) - rows: List[Row] = [] + rows: List[_Row] = [] for node in nodes: child = node["child"] @@ -151,7 +151,7 @@ def ls(path: str, *, group_directories_first: bool = False): modify_time = datetime.fromisoformat(meta["modifyTime"]) rows.append( - Row( + _Row( name=child["name"], type=LDataNodeType(child["type"].lower()), size=size, @@ -164,9 +164,9 @@ def ls(path: str, *, group_directories_first: bool = False): rows.sort(key=lambda row: 1 if row.type == LDataNodeType.obj else 0) headers = [ - " " + click.style(f"Size", underline=True), - click.style(f"Date Modified", underline=True), - click.style(f"Name", underline=True), + " " + click.style("Size", underline=True), + click.style("Date Modified", underline=True), + click.style("Name", underline=True), ] click.echo(" ".join(headers)) @@ -196,7 +196,3 @@ def ls(path: str, *, group_directories_first: bool = False): name_str = click.style(f"{name_str}/", bold=True, fg=color) click.echo(f"{size_str} {mt_str} {name_str}") - - -if __name__ == "__main__": - ls("/", group_directories_first=False) diff --git a/setup.py b/setup.py index a75efa08..cf02b6e7 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ setup( name="latch", - version="v2.32.1", + version="v2.32.2", author_email="kenny@latch.bio", description="The Latch SDK", packages=find_packages(), From b20b16401267e6874b670f585c712ae5294583ca Mon Sep 17 00:00:00 2001 From: hannahle Date: Fri, 25 Aug 2023 19:34:37 +0000 Subject: [PATCH 224/356] more examples --- docs/source/manual/snakemake.md | 167 ++++++++++++++++++++++++++------ 1 file changed, 137 insertions(+), 30 deletions(-) diff --git a/docs/source/manual/snakemake.md b/docs/source/manual/snakemake.md index 4e8fc17b..5ac8c883 100644 --- a/docs/source/manual/snakemake.md +++ b/docs/source/manual/snakemake.md @@ -18,17 +18,28 @@ Recall a snakemake project consists of a `Snakefile`, which describes workflow r 2. Build a container with all runtime dependencies 3. Ensure your `Snakefile` is compatible with cloud execution -### Constructing a `latch_metadata.py` file +### Step 1: Construct a `latch_metadata.py` file The snakemake framework was designed to allow developers to both define and execute their workflows. This often means that the workflow parameters are sometimes ill-defined and scattered throughout the project as configuration values, static values in the `Snakefile` or command line flags. To construct a graphical interface from a snakemake workflow, the parameters need to be explicitly identified and defined so that they can be presented to scientist to be filled out through a web application. The `latch_metadata.py` file holds these parameter definitions, along with any styling or cosmetic modifications the developer wishes to make to each parameter. -Asking the question, "what are the minimum set of files needed to run my workflow to completion" is a good way to begin identifying what these parameters might be. +It's worth noting that many Snakemake workflows come with a `config.yaml` file that enumerates input files and other parameters. -An example of this `latch_metadata.py` file: +Below is an example of how to create the `latch_metadata.py` file based on the `config.yaml` file: +Example of `config.yaml` file: + +```yaml +# config.yaml +r1_fastq: "tests/r1.fq.gz" +r2_fastq: "tests/r2.fq.gz" +path: "tests/hs38DH" ``` + +Example of `latch_metadata.py` file: + +```python # latch_metadata.py from pathlib import Path @@ -46,33 +57,48 @@ SnakemakeMetadata( "r1_fastq": SnakemakeFileParameter( display_name="Read 1 FastQ", type=LatchFile, - path=Path("r1.fq.gz"), + path=Path("tests/r1.fq.gz"), ), "r2_fastq": SnakemakeFileParameter( display_name="Read 2 FastQ", type=LatchFile, - path=Path("r2.fq.gz"), + path=Path("tests/r2.fq.gz"), ), "genome": SnakemakeFileParameter( display_name="Reference Genome", type=LatchDir, - path=Path("hs38DH"), + path=Path("tests/hs38DH"), ), }, ) ``` -### Defining all dependencies in a container +### Step 2: Define all dependencies in a container +When executing snakemake jobs on Latch, the jobs run within an environment specified by a `Dockerfile`. It is important to ensure that all required dependencies, whether they are third-party binaries, python libraries, or shell scripts, are correctly installed and configured within this `Dockerfile` so the job has access to them. -When snakemake jobs are executed on Latch, they will run in an environment defined by a `Dockerfile`. Any dependencies, such as third-party binaries, python libraries, shell scripts, need to be installed and configured correctly in this `Dockerfile` so the job has access to them. +**Key Dependencies to Consider**: +* Python Packages: + * Specify these in a `requirements.txt` or `environment.yaml` file. +* Conda Packages: + * List these in an `environment.yaml` file. +* Bioinformatics Tools: + * Often includes third-party binaries. They will need to be manually added to the Dockerfile. +* Snakemake Wrappers and Containers: + * Note that while many Snakefile rules use singularity or docker containers, Latch doesn't currently support these wrapper or containerized environments. Therefore, all installation codes for these must be manually added into the Dockerfile. -To generate a `Dockerfile` that can be modified, the following command is available: +**Generating a Customizable Dockerfile:** + +To generate a `Dockerfile` that can be modified, use the following command: `latch dockerfile ` -A container is automatically built from the `Dockerfile` generated by this command when your snakemake project is registered with Latch. +The above command searches for the `environment.yaml` and `requirements.txt` files within your project directory. Based on these, it generates Dockerfile instructions to install the specified Conda and Python dependencies. + +Once the Dockerfile is generated, you can manually append it with third-party Linux installations or source codes related to Snakemake wrappers or containers. + +When you register your snakemake project with Latch, a container is automatically built from the generated Dockerfile. -### Ensure your `Snakefile` is compatible with cloud execution +### Step 3: Ensure your `Snakefile` is compatible with cloud execution When snakemake workflows are executed on Latch, each generated job is run in a separate container on a potentially isolated machine. This means your `Snakefile` might need to be modified to address problems that arise from this type of execution that were not present when executing locally: @@ -81,7 +107,7 @@ When snakemake workflows are executed on Latch, each generated job is run in a s - Add `resources` directives if tasks run out of memory or disk space - Optimize data transfer by merging tasks that have 1-to-1 dependencies -### Register your project +### Step 4: Register your project When the above steps have been taken, it is safe to register your project with the Latch CLI. @@ -89,6 +115,7 @@ Example: `latch register / --snakefile /Snakef This command will build a container and construct a graphical interface from your `latch_metdata.py` file. When this process has completed, a link to view your workflow on the Latch console will be printed to `stdout`. +--- ## Lifecycle of a Snakemake Execution on Latch Snakemake support is currently based on JIT (Just-In-Time) registraton. This means that the workflow produced by `latch register` will only register a second workflow, which will run the actual pipeline tasks. This is because the actual structure of the workflow cannot be specified until parameter values are provided. @@ -220,25 +247,8 @@ parameters = { | `snakemake.exceptions.WorkflowError: Workflow defines configfile config.yaml but it is not present or accessible (full checked path: /root/config.yaml)` | Include a `config.yaml` in the workflow Docker image. Currently, config files cannot be generated from workflow parameters. | | `Command '['/usr/local/bin/python', '-m', 'latch_cli.snakemake.single_task_snakemake', ...]' returned non-zero exit status 1.` | The runtime single-job task failed. Look at logs to find the error. It will be marked with the string `[!] Failed`. | | Runtime workflow task fails with `FileNotFoundError in file /root/workflow/Snakefile` but the file is specified in workflow parameters | Wrap the code that reads the file in a function. **See section "Input Files Referenced Outside of Rules"** | -| MultiQC `No analysis results found. Cleaning up..` | FastQC outputs two files: the raw data and the HTML report. Include the raw `.zip` outputs of FastQC in the MultiQC rule inputs. | - -## Known Issues - -- Task caching does not work, tasks always re-run when a new version of the workflow is run even if nothing specific has changed -- It is not possible to configure the amount of available ephemeral storage -- Remote registration is not supported -- Snakemake tasks are serialized using a faulty custom implementation which does not support things like caching. Should use actual generated python code instead -- JIT workflow image should run snakemake extraction as a smoketest before being registered as a workflow -- Workflows with no parameters break the workflow params page on console UI -- Cannot set parameter defaults -- Parameter keys are unusued but are required in the metadata -- Log file tailing does not work +| MultiQC `No analysis results found. Cleaning up..` | FastQC outputs two files for every FastQ file: the raw `.zip` data and the HTML report. Include the raw `.zip` outputs of FastQC in the MultiQC rule inputs. **See section "Input Files Not Explicitly Defined in Rules"** " -## Future Work - -- Warn when the Snakefile reads files not on the docker image outside of any rules -- FUSE -- File/directory APIs ## Troubleshooting: Input Files Referenced Outside of Rules @@ -321,3 +331,100 @@ rule all: expand("fastqc/{sample}.html", sample=get_samples_data()["samples"]), expand("reports/{name}.txt", name=get_samples_data()["names"]), ``` + +## Troubleshooting: Input Files Not Explicitly Defined in Rules +When running the snakemake workflow locally, not all input files must be explicitly defined in every rule because all files are generated on one computer. However, tasks on Latch only download files specified by their target rules. Thus, unspecified input files will cause the Snakefile rule to fail due to missing input files. + +**Example** +```python +# ERROR: the .zip file produced by the the fastqc rule is not found in the multiqc rule! + +WORKDIR = "/root/" + +rule fastqc: + input: join(WORKDIR, 'fastq', 'raw', "{sample}.fastq") + output: + html = join(WORKDIR, "QC", "fastqc", 'raw', "Sample_{sample}") + params: + join(WORKDIR, "QC","fastqc", 'raw', "Sample_{sample}") + run: + if not os.path.exists(join(WORKDIR, str(params))): + os.makedirs(join(WORKDIR, str(params))) + shell("fastqc -o {params} --noextract -k 5 -t 8 -f fastq {input} 2>{log}") + +rule multiqc: + input: + aligned_sequences = join(WORKDIR, "plasmid_wells_aligned_sequences.csv") + output: directory(join(WORKDIR, "QC", "multiqc_report", 'raw')) + params: + join(WORKDIR, "QC", "fastqc", 'raw') + benchmark: + join(BENCHMARKDIR, "multiqc.txt") + log: + join(LOGDIR, "multiqc.log") + shell: + "multiqc {params} -o {output} --force" +``` + +### Solution +For programs that produce multiple types of input files (e.g. `.zip` and `.html` in the case of FastQC), explicitly specify these files in the outputs of the previous rule and in the inputs of the subsequent rule. + +**Example** +```python +def get_samples(): + samples = Path("/root").glob("*fastqc.zip") + return samples + +WORKDIR = "/root/" +rule fastqc: + input: join(WORKDIR, 'fastq', 'raw', "{sample}.fastq") + output: + html = join(WORKDIR, "QC", "fastqc", 'raw', "Sample_{sample}", "_{sample}_fastqc.html") + # Specify zip as the output for every sample from fastqc + zip = join(WORKDIR, "QC", "fastqc", 'raw', "Sample_{sample}", "_{sample}_fastqc.zip") + params: + join(WORKDIR, "QC","fastqc", 'raw', "Sample_{sample}") + run: + if not os.path.exists(join(WORKDIR, str(params))): + os.makedirs(join(WORKDIR, str(params))) + shell("fastqc -o {params} --noextract -k 5 -t 8 -f fastq {input} 2>{log}") + +rule multiqc: + input: + aligned_sequences = join(WORKDIR, "plasmid_wells_aligned_sequences.csv") + # Specify zip as the input for every sample from fastqc + zip = expand( + join(WORKDIR, "QC", "fastqc", 'raw', "Sample_{sample}", "_{sample}_fastqc.zip"), sample=get_samples() + ) + output: directory(join(WORKDIR, "QC", "multiqc_report", 'raw')) + params: + join(WORKDIR, "QC", "fastqc", 'raw') + benchmark: + join(BENCHMARKDIR, "multiqc.txt") + log: + join(LOGDIR, "multiqc.log") + shell: + # Explicitly pass the input into the script instead of the Snakefile rule `params` + # Before: "multiqc {params} -o {output} --force" + # After + "multiqc {input.zip} -o {output} --force" +``` + +## Snakemake Roadmap +### Known Issues + +- Task caching does not work, tasks always re-run when a new version of the workflow is run even if nothing specific has changed +- It is not possible to configure the amount of available ephemeral storage +- Remote registration is not supported +- Snakemake tasks are serialized using a faulty custom implementation which does not support things like caching. Should use actual generated python code instead +- JIT workflow image should run snakemake extraction as a smoketest before being registered as a workflow +- Workflows with no parameters break the workflow params page on console UI +- Cannot set parameter defaults +- Parameter keys are unusued but are required in the metadata +- Log file tailing does not work + +### Future Work + +- Warn when the Snakefile reads files not on the docker image outside of any rules +- FUSE +- File/directory APIs From c6d6d5c136871b124bdb98c5f53bcc0cdfd79762 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Sat, 26 Aug 2023 11:45:21 -0700 Subject: [PATCH 225/356] small fixes --- docs/source/manual/snakemake.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/docs/source/manual/snakemake.md b/docs/source/manual/snakemake.md index 5ac8c883..3a5f5bcb 100644 --- a/docs/source/manual/snakemake.md +++ b/docs/source/manual/snakemake.md @@ -8,11 +8,12 @@ This pre-release was created to integrate miscellaneous improvements that accumu ## Getting Started -Latch's snakemake integration allows developers to build graphical interfaces to expose their workflows to wet lab teams and managed cloud execution of snakemake jobs. +Latch's snakemake integration allows developers to build graphical interfaces to expose their workflows to wet lab teams. It also provides managed cloud infrastructure for execution of the workflow's jobs. A primary design goal for integration is to allow developers to register existing projects with minimal added boilerplate and modifications to code. Here we outline exactly what these changes are and why they are needed. -Recall a snakemake project consists of a `Snakefile`, which describes workflow rules using an ["extension"](https://snakemake.readthedocs.io/en/stable/snakefiles/rules.html) of Python, and associated python code imported and called by these rules in the `Snakefile`.To make this project compatible with Latch, we need to do the following: +Recall a snakemake project consists of a `Snakefile`, which describes workflow +rules in an ["extension"](https://snakemake.readthedocs.io/en/stable/snakefiles/rules.html) of Python, and associated python code imported and called by these rules. To make this project compatible with Latch, we need to do the following: 1. Identify and construct explicit parameters for each file dependency in `latch_metadata.py` 2. Build a container with all runtime dependencies @@ -22,9 +23,14 @@ Recall a snakemake project consists of a `Snakefile`, which describes workflow r The snakemake framework was designed to allow developers to both define and execute their workflows. This often means that the workflow parameters are sometimes ill-defined and scattered throughout the project as configuration values, static values in the `Snakefile` or command line flags. -To construct a graphical interface from a snakemake workflow, the parameters need to be explicitly identified and defined so that they can be presented to scientist to be filled out through a web application. The `latch_metadata.py` file holds these parameter definitions, along with any styling or cosmetic modifications the developer wishes to make to each parameter. +To construct a graphical interface from a snakemake workflow, the file parameters need to be explicitly identified and defined so that they can be presented to scientist to be filled out through a web application. The `latch_metadata.py` file holds these parameter definitions, along with any styling or cosmetic modifications the developer wishes to make to each parameter. -It's worth noting that many Snakemake workflows come with a `config.yaml` file that enumerates input files and other parameters. +*Currently, only file and directory parameters are supported*. + +To identify the file "dependencies" that should be pulled out as parameters, it +can be useful to start with the `config.yaml` file that is used to configure +many Snakemake projects. Thinking about the minimum set of files needed to run +a successful workflow on fresh machine can also help identify these parameters. Below is an example of how to create the `latch_metadata.py` file based on the `config.yaml` file: @@ -74,7 +80,7 @@ SnakemakeMetadata( ``` ### Step 2: Define all dependencies in a container -When executing snakemake jobs on Latch, the jobs run within an environment specified by a `Dockerfile`. It is important to ensure that all required dependencies, whether they are third-party binaries, python libraries, or shell scripts, are correctly installed and configured within this `Dockerfile` so the job has access to them. +When executing Snakemake jobs on Latch, the jobs run within an environment specified by a `Dockerfile`. It is important to ensure that all required dependencies, whether they are third-party binaries, python libraries, or shell scripts, are correctly installed and configured within this `Dockerfile` so the job has access to them. **Key Dependencies to Consider**: * Python Packages: @@ -83,7 +89,7 @@ When executing snakemake jobs on Latch, the jobs run within an environment speci * List these in an `environment.yaml` file. * Bioinformatics Tools: * Often includes third-party binaries. They will need to be manually added to the Dockerfile. -* Snakemake Wrappers and Containers: +* Snakemake wrappers and containers: * Note that while many Snakefile rules use singularity or docker containers, Latch doesn't currently support these wrapper or containerized environments. Therefore, all installation codes for these must be manually added into the Dockerfile. **Generating a Customizable Dockerfile:** From 92acd6347906595a38081ed88785f29b3e5a0f83 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Mon, 28 Aug 2023 11:42:03 -0700 Subject: [PATCH 226/356] fix on 3.8 Signed-off-by: Ayush Kamat --- latch_cli/services/cp/autocomplete.py | 4 ++-- latch_cli/services/ls.py | 3 ++- setup.py | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/latch_cli/services/cp/autocomplete.py b/latch_cli/services/cp/autocomplete.py index da77f053..24acc6e7 100644 --- a/latch_cli/services/cp/autocomplete.py +++ b/latch_cli/services/cp/autocomplete.py @@ -82,7 +82,7 @@ def _complete_local_path(incomplete: str) -> List[sc.CompletionItem]: @cache -def _complete_remote_path(match: re.Match[str]) -> List[sc.CompletionItem]: +def _complete_remote_path(match: re.Match) -> List[sc.CompletionItem]: domain = match["domain"] parent = match["parent"] path = match["path"][1:] @@ -108,7 +108,7 @@ def _complete_remote_path(match: re.Match[str]) -> List[sc.CompletionItem]: @cache -def _complete_domain(match: re.Match[str]) -> List[sc.CompletionItem]: +def _complete_domain(match: re.Match) -> List[sc.CompletionItem]: stub = match["domain"] res: List[sc.CompletionItem] = [] diff --git a/latch_cli/services/ls.py b/latch_cli/services/ls.py index 7a8c5c69..799f75d1 100644 --- a/latch_cli/services/ls.py +++ b/latch_cli/services/ls.py @@ -6,6 +6,7 @@ from typing import List, Optional, TypedDict import click +import dateutil.parser as dp import gql from latch_sdk_gql.execute import execute @@ -148,7 +149,7 @@ def ls(path: str, *, group_directories_first: bool = False): if meta["contentSize"] is not None: size = int(meta["contentSize"]) if meta["modifyTime"] is not None: - modify_time = datetime.fromisoformat(meta["modifyTime"]) + modify_time = dp.isoparse(meta["modifyTime"]) rows.append( _Row( diff --git a/setup.py b/setup.py index cf02b6e7..e471d63b 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ setup( name="latch", - version="v2.32.2", + version="v2.32.3", author_email="kenny@latch.bio", description="The Latch SDK", packages=find_packages(), @@ -43,6 +43,7 @@ "requests-toolbelt==0.10.1", "latch-sdk-gql==0.0.6", "latch-sdk-config==0.0.4", + "python-dateutil>=2.8", # for old latch develop, to be removed "aioconsole==0.6.1", "asyncssh==2.13.2", From 90330c479b0cf8d918943a8d63609bd8d3c9d6b7 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Mon, 28 Aug 2023 11:53:58 -0700 Subject: [PATCH 227/356] bump version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index c4ad684f..5f467e39 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ setup( name="latch", - version="v2.32.3", + version="v2.32.4", author_email="kenny@latch.bio", description="The Latch SDK", packages=find_packages(), From 37e3f9940279d0ccc563afe2c0bfe92579d7b618 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Mon, 28 Aug 2023 12:07:51 -0700 Subject: [PATCH 228/356] changelog Signed-off-by: Ayush Kamat --- CHANGELOG.md | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a711c721..002a85b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,21 @@ Types of changes # Latch SDK Changelog +## 2.32.4 - 2023-08-28 + +### Fixed + +* Fixed a bug in `latch ls` where `datetime.isoformat` was called on strings with timestamps (which is not supported on python < 3.11) + +## 2.32.3 - 2023-08-26 + +### Fixed + +* Snakemake issues + + bounded snakemake versions to prevent compatibility issues that arise in later versions + + small bugs in list json encoder + + mishandled http issues. + ## 2.32.2 - 2023-08-25 ### Fixed @@ -263,7 +278,7 @@ Types of changes ### Dependencies -* Removed `awscli`, `uvloop`, and `prompt-toolkit` as they were unused. +* Removed `awscli`, `uvloop`, and `prompt-toolkit` as they were unused. ## 2.22.4 - 2023-06-08 @@ -636,8 +651,8 @@ Types of changes ### Deprecated -* The commands `latch rm`, `latch mkdir`, and `latch touch`. -* The operators `left_join`, `right_join`, `inner_join`, `outer_join`, +* The commands `latch rm`, `latch mkdir`, and `latch touch`. +* The operators `left_join`, `right_join`, `inner_join`, `outer_join`, `group_tuple` , `latch_filter` , and `combine` ### Removed From 52a49cd54af3586c5060631421ed4d1c92cac9a8 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Mon, 28 Aug 2023 12:10:12 -0700 Subject: [PATCH 229/356] del weird autoformatting issue Signed-off-by: Ayush Kamat --- CHANGELOG.md | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 002a85b2..f7b96ff1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -278,7 +278,7 @@ Types of changes ### Dependencies -* Removed `awscli`, `uvloop`, and `prompt-toolkit` as they were unused. +* Removed `awscli`, `uvloop`, and `prompt-toolkit` as they were unused. ## 2.22.4 - 2023-06-08 @@ -651,9 +651,18 @@ Types of changes ### Deprecated -* The commands `latch rm`, `latch mkdir`, and `latch touch`. -* The operators `left_join`, `right_join`, `inner_join`, `outer_join`, -`group_tuple` , `latch_filter` , and `combine` +* The commands + + `latch rm`, + + `latch mkdir`, and + + `latch touch`. +* The operators + + `left_join`, + + `right_join`, + + `inner_join`, + + `outer_join`, + + `group_tuple`, + + `latch_filter`, and + + `combine`. ### Removed From 58fb589fe17d864a8e318863c2c45a03e4254659 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Mon, 28 Aug 2023 19:27:53 -0700 Subject: [PATCH 230/356] delete temporary key --- latch_cli/snakemake/single_task_snakemake.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 3fe17fab..969f1fae 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -109,6 +109,10 @@ def render_annotated_str(x) -> str: res = f"directory({res})" del flags["directory"] + # TODO (kenny) ~ handle temporary values + if "temp" in flags: + del flags["temp"] + if len(flags) != 0: raise RuntimeError(f"found unsupported flags: {repr(flags)}") From 9d9a93c4d54279a1e6b4c1e81da7bc9058adde41 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Mon, 28 Aug 2023 19:51:42 -0700 Subject: [PATCH 231/356] ignore global rule order --- latch_cli/snakemake/single_task_snakemake.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 969f1fae..a92380cb 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -15,6 +15,7 @@ Params, Python, Rule, + Ruleorder, Shell, ) from snakemake.rules import Rule as RRule @@ -183,6 +184,8 @@ def skipping_block_content(self, token): Params.block_content = skipping_block_content Benchmark.block_content = skipping_block_content Log.block_content = skipping_block_content +# TODO (kenny) - enforce rule order instead of ignoring it +Ruleorder.block_content = skipping_block_content class SkippingRule(Rule): From 9115b0503def225c6e19bf7578cf74af728e721f Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Mon, 28 Aug 2023 20:01:52 -0700 Subject: [PATCH 232/356] ignore ruleorder in skip block fn --- latch_cli/snakemake/single_task_snakemake.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index a92380cb..60b7a709 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -166,7 +166,7 @@ def emit_overrides(self, token): def skipping_block_content(self, token): - if self.rulename not in rules: + if type(self) in (Ruleorder) or self.rulename not in rules: return emitted_overrides = emitted_overrides_per_type.setdefault( From 23ff3639916a82a499d9291fd4ff6e2cb7f0d09f Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Mon, 28 Aug 2023 20:32:13 -0700 Subject: [PATCH 233/356] fix --- latch_cli/snakemake/single_task_snakemake.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 60b7a709..4a88b226 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -166,7 +166,7 @@ def emit_overrides(self, token): def skipping_block_content(self, token): - if type(self) in (Ruleorder) or self.rulename not in rules: + if type(self) == Ruleorder or self.rulename not in rules: return emitted_overrides = emitted_overrides_per_type.setdefault( From a2d9bd926df6b408caba4cb58ba95e72826b51af Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Mon, 28 Aug 2023 20:36:47 -0700 Subject: [PATCH 234/356] changelog --- CHANGELOG.md | 8 ++++++++ setup.py | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f7b96ff1..f4769186 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,14 @@ Types of changes # Latch SDK Changelog +## 2.32.5 - 2023-08-28 + +### Fixed + +* Snakemake: + * Ignore global ruleorder directive + * Ignore temporary condition on output values + ## 2.32.4 - 2023-08-28 ### Fixed diff --git a/setup.py b/setup.py index 5f467e39..f90d5595 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ setup( name="latch", - version="v2.32.4", + version="v2.32.5", author_email="kenny@latch.bio", description="The Latch SDK", packages=find_packages(), From 030f282fa8499203634f0bf6f2891d27a9073d98 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Tue, 29 Aug 2023 13:38:16 -0700 Subject: [PATCH 235/356] empty function for rule order --- latch_cli/snakemake/single_task_snakemake.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 4a88b226..be4e6b7b 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -166,7 +166,7 @@ def emit_overrides(self, token): def skipping_block_content(self, token): - if type(self) == Ruleorder or self.rulename not in rules: + if self.rulename not in rules: return emitted_overrides = emitted_overrides_per_type.setdefault( @@ -184,8 +184,8 @@ def skipping_block_content(self, token): Params.block_content = skipping_block_content Benchmark.block_content = skipping_block_content Log.block_content = skipping_block_content -# TODO (kenny) - enforce rule order instead of ignoring it -Ruleorder.block_content = skipping_block_content +# todo(kenny): enforce rule order instead of ignoring it +Ruleorder.block_content = lambda self, token: None class SkippingRule(Rule): From b3da24e659403c6308f605f66ce39d566c3bed57 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Thu, 7 Sep 2023 13:34:46 -0700 Subject: [PATCH 236/356] fix develop Signed-off-by: Ayush Kamat --- latch_cli/centromere/ctx.py | 4 +- latch_cli/constants.py | 2 + latch_cli/services/local_dev_old.py | 78 +++++++++++++++++++++++++---- 3 files changed, 72 insertions(+), 12 deletions(-) diff --git a/latch_cli/centromere/ctx.py b/latch_cli/centromere/ctx.py index 976251ac..c6abb712 100644 --- a/latch_cli/centromere/ctx.py +++ b/latch_cli/centromere/ctx.py @@ -22,6 +22,7 @@ _construct_ssh_client, _import_flyte_objects, ) +from latch_cli.constants import docker_image_name_illegal_pat from latch_cli.docker_utils import get_default_dockerfile from latch_cli.utils import ( WorkflowType, @@ -43,9 +44,6 @@ class _Container: image_name: str -docker_image_name_illegal_pat = re.compile(r"[^a-z0-9]+") - - class _CentromereCtx: """Manages state for interaction with centromere. diff --git a/latch_cli/constants.py b/latch_cli/constants.py index ca43e3c5..3cc61d79 100644 --- a/latch_cli/constants.py +++ b/latch_cli/constants.py @@ -65,3 +65,5 @@ class OAuth2Constants: oauth2_constants = OAuth2Constants() + +docker_image_name_illegal_pat = re.compile(r"[^a-z0-9]+") diff --git a/latch_cli/services/local_dev_old.py b/latch_cli/services/local_dev_old.py index 9a1d8e38..041aa956 100644 --- a/latch_cli/services/local_dev_old.py +++ b/latch_cli/services/local_dev_old.py @@ -9,6 +9,7 @@ import traceback import tty from enum import Enum +from http.client import HTTPException from pathlib import Path from textwrap import dedent from typing import Callable, Optional, Tuple, Union @@ -22,20 +23,52 @@ from latch_sdk_config.latch import config from watchfiles import awatch +from latch_cli.constants import docker_image_name_illegal_pat from latch_cli.tinyrequests import post from latch_cli.utils import ( TemporarySSHCredentials, current_workspace, + identifier_suffix_from_str, retrieve_or_login, ) +def _get_workflow_name(pkg_root: Path) -> str: + from flytekit.core.context_manager import FlyteEntities + from flytekit.core.workflow import PythonFunctionWorkflow + + from latch_cli.centromere.utils import _import_flyte_objects + + _import_flyte_objects([pkg_root]) + for entity in FlyteEntities.entities: + if isinstance(entity, PythonFunctionWorkflow): + return entity.name + + click.secho( + dedent(f""" + Unable to find a workflow in {pkg_root}: Check that + + 1. {pkg_root} is a valid workflow directory, and + 2. Your workflow function has the @workflow decorator. + """).strip("\n"), + fg="red", + ) + raise click.exceptions.Exit(1) + + def _get_latest_image(pkg_root: Path) -> str: + click.secho("Image name: ", fg="blue", nl=False) + ws_id = current_workspace() if int(ws_id) < 10: ws_id = f"x{ws_id}" - registry_name = f"{ws_id}_{pkg_root.name}" + wf_name = identifier_suffix_from_str(_get_workflow_name(pkg_root)).lower() + wf_name = docker_image_name_illegal_pat.sub("_", wf_name) + + registry_name = f"{ws_id}_{wf_name}" + + click.secho(registry_name, italic=True, bold=True) resp = post( config.api.workflow.get_latest, @@ -48,14 +81,43 @@ def _get_latest_image(pkg_root: Path) -> str: try: resp.raise_for_status() + click.secho("Found image. Using version ", nl=False) latest_version = resp.json()["version"] - except: - raise ValueError( - "There was an issue getting your workflow's docker image. Please make sure" - " you've registered your workflow at least once." + click.secho(latest_version, italic=True, bold=True) + except HTTPException: + click.secho("Could not find any images. Retrying with new image name.") + click.secho("Image name: ", fg="blue", nl=False) + + registry_name = f"{ws_id}_{pkg_root.name}" + + click.secho(registry_name, italic=True, bold=True) + + resp = post( + config.api.workflow.get_latest, + headers={"Authorization": f"Bearer {retrieve_or_login()}"}, + json={ + "registry_name": registry_name, + "ws_account_id": current_workspace(), + }, ) - return f"{config.dkr_repo}/{ws_id}_{pkg_root.name}:{latest_version}" + try: + resp.raise_for_status() + click.secho("Found image. Using version ", nl=False) + latest_version = resp.json()["version"] + click.secho(latest_version, italic=True, bold=True) + except HTTPException as e: + click.secho( + dedent(""" + There was an issue getting your workflow's docker image. + + Please make sure you've registered your workflow at least once. + """).strip("\n"), + fg="red", + ) + raise click.exceptions.Exit(1) + + return f"{config.dkr_repo}/{registry_name}:{latest_version}" rsync_stop_event = asyncio.Event() @@ -257,8 +319,7 @@ async def output_task(): async def _run_local_dev_session(pkg_root: Path): # hit the endpoint to make sure that a workflow image exists in ecr before # doing anything - _get_latest_image(pkg_root) - + image_name_tagged = _get_latest_image(pkg_root) key_path = pkg_root / ".latch" / "ssh_key" with TemporarySSHCredentials(key_path) as ssh: @@ -345,7 +406,6 @@ async def _run_local_dev_session(pkg_root: Path): ) await aioconsole.aprint("Done.") - image_name_tagged = _get_latest_image(pkg_root) await _send_message(ws, docker_access_token) await _send_message(ws, image_name_tagged) await aioconsole.aprint(f"Pulling {image_name_tagged}... ") From 643bf0628f5bb5b300ee0015406f79006282be32 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Thu, 7 Sep 2023 15:09:22 -0700 Subject: [PATCH 237/356] small edits to prints Signed-off-by: Ayush Kamat --- latch_cli/services/local_dev_old.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/latch_cli/services/local_dev_old.py b/latch_cli/services/local_dev_old.py index 041aa956..27a53bbe 100644 --- a/latch_cli/services/local_dev_old.py +++ b/latch_cli/services/local_dev_old.py @@ -85,7 +85,7 @@ def _get_latest_image(pkg_root: Path) -> str: latest_version = resp.json()["version"] click.secho(latest_version, italic=True, bold=True) except HTTPException: - click.secho("Could not find any images. Retrying with new image name.") + click.secho("Could not find any images. Retrying with new image name.\n") click.secho("Image name: ", fg="blue", nl=False) registry_name = f"{ws_id}_{pkg_root.name}" @@ -107,6 +107,8 @@ def _get_latest_image(pkg_root: Path) -> str: latest_version = resp.json()["version"] click.secho(latest_version, italic=True, bold=True) except HTTPException as e: + click.secho("Could not find any images.\n") + click.secho( dedent(""" There was an issue getting your workflow's docker image. From 3f3d6b8975639d78111f1ab9554f843a67fc2d8d Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Thu, 7 Sep 2023 15:29:18 -0700 Subject: [PATCH 238/356] bump setup + changelog Signed-off-by: Ayush Kamat --- CHANGELOG.md | 12 +++++++++--- setup.py | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f4769186..d3c54c60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,13 +16,19 @@ Types of changes # Latch SDK Changelog +## 2.32.6 - 2023-09-07 + +### Fixed + +* A bug in `latch develop` where images for newly registered workflows could not be found. + ## 2.32.5 - 2023-08-28 ### Fixed * Snakemake: - * Ignore global ruleorder directive - * Ignore temporary condition on output values + + Ignore global ruleorder directive + + Ignore temporary condition on output values ## 2.32.4 - 2023-08-28 @@ -286,7 +292,7 @@ Types of changes ### Dependencies -* Removed `awscli`, `uvloop`, and `prompt-toolkit` as they were unused. +* Removed `awscli`, `uvloop`, and `prompt-toolkit` as they were unused. ## 2.22.4 - 2023-06-08 diff --git a/setup.py b/setup.py index f90d5595..cf91c836 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ setup( name="latch", - version="v2.32.5", + version="v2.32.6", author_email="kenny@latch.bio", description="The Latch SDK", packages=find_packages(), From f1ac81b56ae4b432adbfaf6c1b1339f9f2bacdd5 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Thu, 7 Sep 2023 15:32:13 -0700 Subject: [PATCH 239/356] del weird formatting in changelog Signed-off-by: Ayush Kamat --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d3c54c60..aa118d63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -292,7 +292,10 @@ Types of changes ### Dependencies -* Removed `awscli`, `uvloop`, and `prompt-toolkit` as they were unused. +* Removed unused packages + + `awscli` + + `uvloop` + + `prompt-toolkit` ## 2.22.4 - 2023-06-08 From 421b4039eb55eab54c15ce12a70982531007f795 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Thu, 7 Sep 2023 16:33:54 -0700 Subject: [PATCH 240/356] i am become codeowner Signed-off-by: Ayush Kamat --- .github/CODEOWNERS | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 00000000..7c451f28 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @ayushkamat From d02ae985f25c55f7e4a0eb44b96e2c0f8286b528 Mon Sep 17 00:00:00 2001 From: Hannah Le Date: Wed, 13 Sep 2023 15:35:32 -0700 Subject: [PATCH 241/356] tutorial --- docs/source/assets/snakemake/tutorial.png | Bin 0 -> 651172 bytes docs/source/manual/tutorial.md | 107 ++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 docs/source/assets/snakemake/tutorial.png create mode 100644 docs/source/manual/tutorial.md diff --git a/docs/source/assets/snakemake/tutorial.png b/docs/source/assets/snakemake/tutorial.png new file mode 100644 index 0000000000000000000000000000000000000000..de8f0b5a05fbc6a57ce13fbbbac2989484907d60 GIT binary patch literal 651172 zcmeFZ2{@GB|2IyFP*IAa3|edm5fNrHX(*AqwIUx z89QTVY%^ol`+tx6em>vd?{{7Q=ehpZ^ZftM^M5|BYwr7Y&VAlzxzBl@bKdXQ>pZ=2 zU1v9sFb^9W+ipEwEh9EIE_pUKj@X@?U`Y1vd+BU!yIh?#HE-x?YKqWS`j*p6xi`VBKB!r1@>^gM3;uxt-iriEK}y7?dfMk=fEHVX|>k85V5&BY88q z$G<;Ubeh}Msq}zt-_LF5Jn(Dw`%J8?&OA6B0F+mhv**3H@-^~ccr&q4d*EV|><{cO zrqm^^@`yqAuvNW~j1$~;@#d_Yq|lZ90m`-Cj1G#`${skU^VDC;BXJ)@^o!n=+nOPV z*v`r%$+odyoD}U=iV8R%t23!oD{ot+yX(R9&dBWn8uAcZ?Zu-!JSSv4j@SDAwArTk zoagla+;R!y8s={TqwEgeZB+Q*+gxBp|%wTDJ1-vMceLD&iYwt|ZlkX)! zWi9vDhaFrN^ojZu`--E0y_T1w@TXQn+ljeajs%6TP|N1KpEqVoJK3>3aK5R)rjrK% zk@pWWCK}E}J=XioZ!A_KvoEvuVlI0@(MbixD-KH8W{ocneT{1t*uQFdDMgGwf=iZC zknZAS_OQ7s_o8yLLW!Q#MD3>)rp6tk@Iq+6w5Y#WXfm&#x!B#~d}}-H?b5lt$9Xk0 z63Xm4c1%oZ9q8cFyW{cDOYVByRKw>*Pu@$Rr5f(+1rfPYhQ)#g(&2B7n_?XGc_v@R zdrs7q4K946m&rIRoZY8$k{6)5un{U1!_`F@o zHsBgZ-56ga$3^9@@&UI^*rL*yEwLtnzS{=27in*oU8^>ZQwiVpJ{g zX)mKjRcMdsa}~&*Iy$zG&l&4vc0(Yqvyn^v^cgO>r|)a|Z8;R5--{6$XD@|_?nYno zC>_5#VY8j8w36*|VWeetBK;IUTQ#?s%yutlyGQ<0 z$s|E(-_i+<2f)5JD<2MRGrrBecpK_g&AS;U#?K>h>7?#9r`u||h5XCj(#g9%K02Sa zKmJkX?E_}K$`9pkbM@~gJ>v8@n8M~*t?hBhipzg|d5%Nj5?=rpm7hag{7m?ZgA#Wm z&rU>^ieEj(#;u(m$8l_Tla?31qJ+-Jquy~|_U8))2cCC}(PB?bad?S3>9`%`i<6() zy~bU4Lniy#n>6KF-T0@4Kc&uaABmVwd-c=SNA%mlJguBx*7wwdwpB*j=&1fox~IT- z%J(WnsUhXmiTZlm0-uv2uWXeHPUmjRsh|IHcQXZTd&EqIv{!P%CnZev`;o(8l9Os7 z`=A2waCDvj7;#gYF2m#}e8=v)$6@#I==Y>*@#o@G{3isia32VF4Sy8gwQ|yT-^kvl zT8MPHUm~e>XKdv?g+2Frs(bRSo-25_ncS~05w}b4#WAGO$*1}<#}Z!l#`?v*h|7i*H)*;DI$-1&gBYR`*oYs27=y*j-Tmah;^1@_QDnLzG9*|OImPlxoD zGwvC?NHgP)U6FU#lljs}=lr!Yoxq&@e7E<@8KP);BUGNv=PFZ13RROBbMr{{_JnI~ zY0aOXea3xm_>B4N?sVqOZn?#`r@KKA^)-YNPMdhh4il(XlAL!!-vZwV8HP0!dk zy*!(D*8I)n*=J{E&+y%|>0IoUxIb{Opt#gRsW|)Vo3C!pMCYzz>tefN-mgMVgl;IB zVHNSgE<+%@rtfuDk@n1ocDoCgF&~QN)TmZe6RJ~Cmb_t~Nm9n!9LxN2OUyNlj)6{x zrh>M6lug3O-pW0QtD~1u87MSX3yEd!W*F35eNym*`-$9P6P3m0FJ#V|-4Azha5``X z@5&bmIcZ{71&$cwaowOQm|NXx=7gd>~MDP{EM># zZ=B@5+PETmsg==r*RtC}-g3U3Dd8+RjI+gA;DY_mlwT~@^Xu{JTYO5oN>if|Nl8a; za2asD*G#B6uG9Ui#c-;0qyWKjC%j|lYUKQ0m3N=6pUjfTvdD^Pr?&rUKikeQ z5nt$6V6&r~L;n#UC)SZx==dcj;xP!Rs`wQ=z-rv`Rgqw%s!+V|(!-Jm~@WMnd zMMg%M33|S=`!Vk6d`>-XBu+`fK-(~5UqDVX#}zI(1O-?o{$2JNb`?GM{z|cj?VZ&*3_Q8=kzdK3k$xqm*%Gvi=;-)42W} z#Qh8uNsr@xBTy=^$9~^wVT1gFX9>q)k=U1`$5(_-3aPb_ zI&4xIY7H<)?dwUWZkUNL3KnSJ*G79E^-`Ix>Uh?MOYK9U-e9vX=7|-h>E#}67eKwa zcfqr{*6(S?hnt;>P5zzPdg`50bIOM#L?rK@?0yU(=6R`74AvsF*|l$JLr!E}g`Uz5 zjtaQ4a5LgFZx&Q`k1W$c7#gjT=kSfPalQ-Ee!Hz-P2lzGvqcVx_}svv3yu*TBZ?8H zCEeTIkINr#(PzGSdjS)e+Eg*HE(+{t8oPeJ{Q2v~bO@FrA~eRU#XBhYO~I;Y<^Cb; zqDGm1pf+VjyFyzi)Q?fNHp8qNc!o<1kQ?|CUwX4*qrR}(K{fHdf`Sb*plDMsI5$^fulF#}58bd~3@pHZLd5*|COrxTZ3kY>5(6kj*PnX&Ng z(Z(YOqAsJGn#y@cQ^(H2F4)-KSicCq{#~;@q6DH0v+~s=3^V1x0(+;aitMUN#=^$G4lnBP{?$Bas9hOM< zV=ndiM=fs*zeB`$pckup8BtvIeA!40fG~(KZHS8y=d*+yhkm0alQ;1K1Ft&Xt*3UT zny4uSo2(BlQO5JXog#g-G3)Q;Rb&UqF4*E`BRzm*JfG!=cm;a}H4QBQI_YQU7b=+#nW5aK%||x( zSC3sRDq;^PI>Kfl%;wXNF|3yf{?2|Wp0U8T4d9lg)v>Q`OWPBQZSb!_zkSQLILw1n zXhd@d_nZ@E(}S}4`a^_e;vCA$rOQ5jF%VaqB_Mf&l{{4vox5Brvu|+tsar}AbI(TRO#ezRpn&0>BFQ2e+ zf&c9Te*tOR{`EGOeA@PZJ#(<$WV>Xnsiz0tjqSV~9NfI`x%&j0J=6sQxIJ{uz1i3V zkF$R4dPc`qK>7VnH_d#^u3f!g=k6+h$KKu6K|a9MgC&PeE#Lz9=<48eM=ZeA#m)Od zfV#xi8yCQ5RlIj|D5!ew}Y3a zyDONf5A^R3_9x$ekNlHRO@USSe`|~14ZRf#wltJSP2sPv2Ibikn!N~q$iq%r1~h~Rd=GdGz4lM{|W4p+vr*-LO0Q+Jkcd47+t>XbUC+uIwihX>3`swY5 zQpYWB-@?e<7{1;rHRv#DI=IW?!S0>P+%N36HOCG%Pd)gAO1yP0foIRfagKXA@y9LN zB2Jq{wVoFfJ8l1x;8#0RV3K=e?@U!I{Nl?Y7{n1>*&7uZOpflK8KRF?l4}hEU7wjA zH;{ryW@tRf$+-Ttw(|70pA*0QZeG5VV!-`Ko_}>pN-G~lY=Aa1l4cZWF@DB#$qxjJ zfN6##0bA-m`}C>7Va1xg5|)u6%*GkM#SGRhCWQIZP3DNePg^K*YF!749IJXS`J_XT z_rX!E&-@g6TnD6IXX{3xzaPGN;Y3>9pJdetO@m!1IYBm^NF(tz%25>TOANCN1-m{L z-SW9|L8pEg_kD_Bbg7>dc}*)y7k)(XYo8Ss_WJQ)(CHr8fE%}KbFsJB@E2Pdrp*(1 z_XZ6DnQQcM)r_B(YOhK9D`OADmG?^9reckf)sVjaS838T0}^Txmgm`i=Yqobhn&y) zwLU}+AocGQ0=>hEOIeH90b~(SQhz>Tu7ZPC_@u2soWxx~?r{^-(!b#=st~vfv@vnQ zGlxH}?>l+#3#(Ac49xx$H22{nU7^j)w+t1U`~4K}*0pHcWDM3<6yqSRn$F6Tf)9<#LVICkh^YKZ@^|CQX^tNu^39zRoNmHq z?h}Z2YDiYC@RS^DO_~Nl;>8J9u_xV}hcNu{&CFK}Nmi8xPkmJg=$q@)6NwZr4y%{r z$SefxfhI6IOL^B4Z{_;AH($dJ8j08sY21+c-39|l=bE2YW7b)4$t`)p|5@Hf`{cb& zPFr2qSa9q9c@Z{%G+{)*Jj+Hx@9-XY2Dwd6%xT^}XH+)dAyiXDLm#T=K5II3!s5ne znw3nS6_Q$*;Ge;(5+axP!S2#o(-a~+QC}BrQZ~(OVW@}}t04!Fg+R&M$S13!8D$g7 zcQ4@?qtAZaA3?4$Uy&iMr!%$VyW$usy|sk}@166{(FlcB8bQU)XKC)F(M4?Doiz7& zZ&tikkdDyT8JWvR^beCwXfa;P@_mai@8~rq3hciI?n+vAF~6)lNsyfC^kbA!NQG1d zt1rVQm6{vInD^bS=F0~|SLO>`at8KHDSus$ipeO7Q+#EUT>!ly=Psx%joLYKtBsgv zmT6;-#A%c?E!xIRB|Ix{JG-7gs^@N*z3Bx6zJ78)70YU&;+*d7FByG#{3Hh2~P zNYEcaevmq{RkuK(%$W=Up6V~Ck3879Q1-)$@q8)$LVlHtu5L=-!ZGh(ej>@cE(Ar_ z#KyKV_432%4SJ7!%|e;ptA5Ehx?)?mpE$pOqA7Hs&K?$h9OP06w6@traH}6bw*Elx z?yq%bjZt?Yp7~a#V~+sortUQRtJd@xrk%9&fEUpA)-i%RSmyVe-ax_rVwW;tx~-@t zT>Zey!0KZ~vt@u;ltsx9a(#N>&W}`{Cbioy%{PXSC$;4)m$8BCi>K}wJhm4-)pRmw z8J3uyC`TTx2=q(-lBIE)FWFvDoea@8Y)J&0P)+q}zp?mhuB)e?rP5+DKRJN?%02bS ziN(*X3cS|tU^IZmMC>DA1@Hz|y^!gIB*d&-l7eT(t-KQ*{#vaTQyFXZwcIA#igKB? zl4n|N>?k|^6Fq`-T8Wk0GS$q1A#mXRoU_16UDNj8!KXiKoX`f2C>59OqcZq6WK__F zHSi-oe7jwYfMsbnY^K2!qt8+UiZsKXBu9rZ=d&c1qu=x(jNlY{898!X^7A{%!?Fq% zSV1Tj=y~--15fG7-h6V&)!D=ofv2>r3zdW|MFp)6caomF9l0+lJ9sAV8^P&ntdMVcHh%||RrOu6beFpM zO27Yo`S^aR=N;7GVlSZBda}GG|4zonwPH>G8tEGc;jgI8)Zim)bllx9>id+h$Qp2~ z`lzIAd%Sw~GkOSV6ETD=Iph)(9^Kh&{A17X?yQS?&zJ2uWRvN z{uaiV@oi){zWq+p?U%|^JHGgH*n?+(ecy*FaEKl80tWuS%O;1yT!$a9gvG54+|sbw zw0l!mM77MBNV$#jBQBTpmm4;6dNT@tHD7O`&M;+h57Zr@(gIyEw^Febc#>{e(ED(g zQ(I~m9LY_;hyU9S$hyD}`7Vg;8bua`tw-g@yLPEW#qOS7cZ4GU)1}>DXZclRZsSZx z2(xvjV;Jxo;cE^_T%*ulEmMM5b8LxkGo$+8^OIHWq!UtA^pw4uMsB_U|3^|z2xGokpu%T;UpZ1!&K-#VYX_K689NiBBi@1X=k$q6*6uA11*6SXR{Yg& z=2fxwd(y$;G`<)O5`?g;AXrS(=ikz^X8icdSVn}7I4$Nsrk`3j_^iE9W|F|#{I;BL zV&Y=7)%W2KlyjZdB0o3H=1hLN+bWuvFr&}`AK(pS2JBy>G^lRBpxr95V1YF{Tb(P? z-;-?u|DDCD4U~Y6WQ$0Wq=`r)W_SL5E;FrC^64amPjR3mK=LXpY4Rxj%Dk#_*MFE9e zr(j1s)@Y~-V0v9A7%COROJN|PNc?&h;=YaY4=TkR^|5cym&gkeDC{~#_3sN7Xe3~v z#Z`a|a$%T#Wp^Eu*m+vu;XNCB4_j+3i#uX_FU7v**IJi&B(NaS$+P|G&WEkxVsC^F zrI-oDnH<#B;v*B=)p9*QZ6M^0;VO7?1hH~_A7I9_vKI-_vuIFYl%Dr!@g7xe9xq5Qt<%xH4Q(rAngi5bPQe-~PZmE7 zA&a*)2ZbSC$c}SKzCnu8wCwu9VyA-hH4_Kk(Dp9<(~LOp9nDhwH9R z!y}@yQI;X$9MfGV|7FX|mAq#c`{E@d%Vey7Lbtf~cXnIm%D0TZpohwwb5eU^4%Ep( zH6AX)GPhYo-}eHJjFcYcG3F^Ix1UL|&>aX9@PYe_%u6$_NPi5g?wM3SgHZ@z1w{W9 zFhkAUPdByOVL2>VXMDvIeJnPoA$aVae@?XJE|V*sDDFlu*~&E4uJ|N;zkzgJ<;#ot zqJ%J&1(-?8n)YhE(U2_n)cmSwKoRr*@K;`J*5j+Vk^Q$0hjY|a1cww~(%g8j*fr;c z0BQ=2#5K0bC3gp;$<-ayBG+DRa9|WMiF~x?J>tiH?lxW#g}eUbN8D>odGwOl0a_eh z325l1aeW+9uNq7fr~XVn&vl&DnbeS88auf+s`pnkn2Mayf(R?kq)mZlrlc8z>pR86 zM3WzqH=Q3nnbowLJ{Gw7{L zC(jy1AM$a+_$KnONWhUo=K_b@f7}(hdqAHBXr(xR2vRe{$E?i^X>d_RW5!>69I5QW z=?ItURL(#5INxWwq&xg%lE3+A^iYP)`44QRDGND%AKYp@cjDtNFB_r{8?jln6K|;+ zVaCseujw8oe=^-8%_cuX%|7xO=W$pg@Izd1w`|0Iwj^&v&x>x?b9>&abvCNcCus6K zXeq05)|pp69C1U`X-bsXEWV=}Zv`(t>MQa>Q!3_+S49YS*tbbbTpT70K&`2cJ9}ne`HnSJCZvJwwBn?ko>OOrIXu4$mk$(wJol8I3PGrC@ zIWX{}C!1`%q)dN#0SUHd>T7fdK>FQT8hXfPen4sm_u0K=-?wbAOxY=xLQ4Yfnx!fp zZoc(3gek?^8L3%E#QvkCx+u&sOzgJqBv-#&x{T77~RE+VoeYfL1PRDX3M#{1cP}X`R##XBVF|X zH_lV$@r}Rzq9e#F9Xo;dA4#!W8k&IhI~mY&4D=$)KJK;)SiF4!e3Ru%-nvK)OQ2x= zr;ltIkMUa;WVdRa6Awd}UqQJ~mYaMEr9fAjVc`4m-trsqIE0>_67QX#>p^+wP=y7k zn3n&1&w-w&++#vN(q@PjaF$c!`W|e)(fMSH#j{$B+2hsx;=6)u(8R~9Wua&R{&dqT z==@LDud-qJIn~j9TdoZ+fQZ-@9?3(Tjhe6J@c1MDw`&7|ViQl-Q2&;GL6Ln()b!6i?Rg*QDup9vpzhTET8U*wGpEti~tV;<@-j%vu`g z=vxPSaY0vg#-#_EofC};-m!A^u?#N!C8wf)xub7B$O~h;mR=VJpBA%xeo63qN?k0i zBPy(!sG!x$68U39+LIc}|54DckrA<$_9YPL0G)1q*SE)TvhUG*b`;xsspOz02@=nh z$@0c+xxbCrOE|Zkc`B$A`udTJBBwcrx1i=SOqNro56f>3++Y{n8Jty1XJ#Zd&OeeU zK3LN;PbZ>E<0Imk1Eh`}s6yvz>xG@d>C&%GYUOvF09|&GJmT4$L&Y!B#NV85(y#|t zUrXZb!5=R#@@w@xDDT~SM$7nwdE^k1wI3NTJv9+7X2k!q_=T48z2;-QTLU5$yV^g+ zK;Qfj3P`@Q#awPE0}U`2u50g?`0c^ZOYx}k8Q+myl54};9`nZT30M?mVz_ENt%v?!T@Ta?X?%LZ_ zvmEoF^PCJ+02xQ?&nf>>%nBB~`(%1glr##tMv-J)vQ&0lvJ*JuZSg1TzrY6no#FY* z49O}_C)AC=$pff~_VS;xMA)gI?@tQFi_H`=ZxdljXG9Cz{cj3(5G}O}nJvg2X|x@0 z>&Ts7GGZ-qlUROPR+e(nX+!ouMROGcyron&SlSY^6v@&p{;TK*#qg>12-BM2xu1q{ zV48nh2<~L*NEkw-8}|^~EXOht(PHS#?KAHWgP;~I|KtpH(?Z{P%P9VY%gzNhpyouu z)>#+*qm45LB|7(?j~qrTcfgtT$A#5kk4Dzt?R#{w0K%y#l-{~ex``u-aVoNm-yu;~ z@5GJ8h)b=HrHZt!oDQ>v?Xs2EdVSpJCHH>X9e!`|=96(Rucr0$Jxb;^y!$lXep_AW z!CI@x)A}Ed2}qG@#HKak%_WY%{zvpb4f5aJLxi8hJe$I7IWTEgPupl|Y^y55y=(#KG}T*OBo)9jsk-5()G`Db*p_Hs1Qy_{bX$HL*7Ahe@Qpz&*RSv!M z+O{GxoWlyER94liAxj8&FaIeQ`T0SQc9f=WEDa5=G+?$JbLBM#Ru%HyI~?qu3&q8X zk>ShWcF}=vLtw9`TJTw8M`NKsWf{0oWc6O|=A#QDm1$QMS+!~JeU0aFeJ|WSFuTJc zid77clJ=9P_jr5K+Ak|e8M6dFDDu5qreXPs(^om@Pl;0Ulv)l9YMlL4^ozH7|D^V@ zV`DDw%=3Q=W?y<2ZFA$}K?MnMcE^QQug4`fcF((PJUm^;s`)uf$3)q$kDYHgX8ixB zNPIT~C)cKa8B!RBH={Woxn)#~&v!Q$AAgdzr|!!U*DV|x3Kc=*9su}YvasvDYLm_H zSU@TkY|a~V5pt>TVy@aLi3;zV5w_?4HLEw!zJJr4TJIPULFNR#FKRzvUB)uIv5Z#! z%Yw59<4=NHd>Bd}z@;epR4yRJXkk@`|X240zcXE7lLEXHq>h=<=s%4+<^`sFCL?Pyj4 zmI+05gWe>PWKSf%ur3Mn3DSA zskDcvQ7C=9rQ#U8G`fZ23KAM zU_<%6UKv1UmbDus$q2VIalvvtFUcsISF9OV5}-Z8Tq7iODzeK>lR+F*0=OBVXU3S_ z<8RhhJI@1RKPmJu?|4?|R@5!oF)~k?9h(JxQw_Nm-QpCqbagfL?!XjZ>PnoyL;9s| zgV2DAR${Q@;(=pt=Cw1ob@xm*y^_SZhc1#2A$%<23=#p{k)2R9@_0unsknp?Fr?y& z@@;vGZ0$uu;wrx!mVmX(l8M-l_JrcI62dwbD)$v(nVOw}l zLl)i>daDn)>R#zZYf-^E1do{x+m%n2VYu;hGbB^eK-85lc(JQFiE^*Jd>2Gh^v%*Y(lV&1Cl>=!_qR`hiM?hcwYjByCm>)A|)E#uRam zDeF$TZ+ml*Uhy@locHZMhLr)u$57cb=;bgvH3^D_FZ!K|Z$=|WfHh`J!~)YQJa}h% z>Y+&xM_TS6F16)EWDSPmJNMvUI3<#{DiHTy0IQurK?;Umr}&&8MgIxqdN0S^`B9** zYw5p0sjP*dIq9I2#-LJ=_uLabg_pl$7ML}t(v5xhn`AP|Z2h^)3=d8&d-aSeuyrh# zH%$t^k*x|s1J50SR#H8dsVdvEo#0DeVv?&G+9f}riYAVf|5~0b?gl>5Bk?thlJW*F zF+sC^F8-A*GxDQtp$+BogQ?W*uu5xETnol>Wa0#FhXHl^bcTvth&8TRR1mT+`{&jv4R1wOjCwLZ9*psdx1E<;Gce&@}bY6mo_`8z#Ix2N{d5L z@#*jSZB~GgKEJ%K7DA#cEYSge**IiYlDdFg%_J1V4+N)&s0pP4{YxoeqcM{%cms2$ zwFOq|^aNWLviTWQ+%aSM`Td^^$15x{-II(>%H zP_(*YU4?k%E(CO(%MAOZgat^00q|QV-<5Py7+DOm@Mh-q%L zPaPF(OLVk~KwW!(509xlh52ZIW)15#v>T%jInmi(4hj144gE`>COWF^YlRqyjXj6% z)0Eyy;V&cXeeN={*1pV|q8R?^^rtPrtQCdY(i(N-arwr*p=+xD->3Rv*lnWsea3@vy06_b)<6qrqb42k-;D)k zX3&ytguY@v=><7n;cu4F1HgU0xYOO~{Vj7x46l{}K3R8S@XW64*%$Mr=`6R<59O65 z!~6l{{9NO2@N`-{=#w3ET4&nPGE+oA5VO!0h}m=mNwRoun$vStf9CP}{qc4B+;z?O zUVziBQuF!1BGWwMe@9He>TVZ!aiE8j2lY2(x_rkLWcn-_1u789XEKDZ>5i10f?`O}ujP$046bTy9qL%V?AtzML;I%U1`s=J+y|H3f?Jl#MFIYr@kxay1^OVt zMFAKtyi7URUbXC70)BX3S0Z-7I>`kcfWKeTq5yn~4jwvM6F$eOGlHeOWp<6A0m;@FNk~s4W3tJ`YCi(ceg$7E4xgE@l?&S z`*^b(=oi+S?}GyW0}%ZEyFEFE{{{s|>meK%m3u%c#I6#ZAD5l*(sv@3pBSf|syabT zpmi*OwmjuWOL1QeEdsCnL63t;@XYlKQ_P~a+rh_N;!RTb`TYeyF9Ry}lmRYE{i56= znF(3pN4|+%5BstCrrUHGh6ZhT|F37GO+!cJr6xobkY0H>WF6?3cOU*y5``G-DQ`KQ zF7nuA#kqp1lxiH>xpvK6?y)TFo!Q82@I(gIv)qnB{4%*Pxk>3Ge}piTvj(Ze=$3MD zCKG{%7ltCbRMzU06%1%~`Zx&|~LhC1f~CK;F{Z4xNsOZI_BHx?JH{b@`>;LWFw zkDY8*Y3KoF7rJ6-B#rSsD-`EfBVvOkN&!@090E{C#=vTyYpXgltFZo2!R7bOg24bR z{%jSlue3+b&0^#MJ<+Iq?Rx^Mv0~~aRUoOOm?B>>R)CMz2W}M*y?FCh!P2th+u{kLA#6DXH@r{f7k)+g zTlg?nfk7A%MM(j^RF1bH?at;p1pKgD`G}V!t;5VmO6k)L(6*|R{-q4plDDI|Ri90v z=_UZCl99gTN(jI(zS`oeR@!IWMyX%Wxa+Ewq1~&zn;)^E3nU#hg@8)}+yUou$~Cu} z8=Kki5_f6XusO1M-4epYCZRr7Y~O7f4>zYpHoy?&6SGlEy_ix8sS+U9ln7*@lykqh zVgW9|l{SC^u31t)k5U?!1XZvFZNGqee2IDyy%rx0&I~5YO&uZMN$=M%=NAktpp*)* z;me<5otz#`M2tcc4O|%JY!9vAZ z;PGZ)^00giEgv#8LT2*0k<0s%+~5d8a3@I!9lTDefiWd4fzP810>*MEw@UnJ(}i3} z@51Pc3cjY?wj3|#Rx-T8>4>Wkf>X)3SMA8q@s`ojkY>9pYUWJQ8H3HYi9~mcwQKq) z0i~mZ$B6rO>T&!KVNnvoU;oy@xc)q>0SC`wcJC4gf8rvt))!iJLXSG<1?&G8#aEm@!{#N^b@2`iP_kAhVv3q7_M9JLQ(6tnDX7X1UBGT) zY>F#4Gtp~&SS!el5w?(vfk(eotqh#MefJHV#ccpKI@a5=zAF%DHhBI0nPp1=Gk zIxq_#`W^-}tI{(NORdkuhOW(oB503bflGeR-i`zW5BjSYhBy!N#^gQj7-(ct;A^RC z_4rpHV*#I~z3`LzD)*K;ZLz4t5eZDTh`cA+eTXjp-t|~k`1T2?$Jt&}IOM0T;n*3G zqQ-B%=$pGwEj&48km-%c`MQYB#kwbz2FHpwC+^ejVJmu^;SBDH6v%&A6QIY#F>-kO zq4eN-*<0INYdQ1lsVoA2*5czum>SOjvO+1%xb|dWK9LpuO&o>Qm$T?7&fda3w(F5b zLr>1fNum4IW5vHYR)D;Vt1e^CxoFm=y4j|2y&)sE12%H#r?jo0c^@?)oBi%^b-qdQ zf6k(IIc(Q2^+{H|?RHZ;L>{fXDVl?22nDbSz3xP-$JMHcNYKL+T&?n9~T zlh_-jRNp$w2pwG3=t@`fXnVykKN@btmbNsCY$JW=L)w>jBq5qeX*2*`Hvt97s&Z4`XN;R7JPbsgZLhIGn9*Srn009n-_Ee6*6Rf%Wf4 zMM-H(ZbV6W{NvTj2_LHFECA&6YezR2b-Tfb^>;$ng@`_5WcOOvbye5kYE#4|c^yaAd3_w|67@m!S)9)Zjy zN{;E`&Bh#4Ymlh(o6oS|Ef93Ah(n&`iKn6;p*LFm4T?o%l2|?&vfqu_v#v2awjvi{ zrr&5K`S+P1qi~jWGyxVr4O*aldAZ4h6#%Jf&H$bHE|CW`S+3M)CS4oa!J}dy@I+DP z>%e}7S8l)SH^B)0WP_rd7HY_Pp=kda_Yh!1mO`$tEw2S`Z+6tt^#E&HNYCz%fRSi< zmi;10AgsmKHzW^kGjf~$c#YGJfs5-1tj7oq;97Y@r~67^)GoliyvK3GKKM%DBad4E z2D>n^6kJ7UaA{_$$TPf4XF-2;)g*l;0loHg={ua9fJ+)?xFMW0muV4vAs)fKMM%H$ zbh>N1j@ncX#&UFR`lF2zsJ8{$k@<)-FpuwcB?iETK@n;t#F8@C&YQ{)u_X&BflpeG+?V>n#-bzHw3(oQQ+M=zy9dW}H+OQkrkm%xtGAXv5xgt2`kS&8 zOH=^aM=Y$5DK?^5{k@3h_4pb)ZO>;hvDG1OK-2&uiFHcMZ&p$v(9Lt$^6=+GmaHuE z-~O~Bz{22Xz1WeuKP0GFM%K-XIpDcHzflFh$xgn1$WCB`|AvOx0|lvR(U&eXH{<}j z+^zQTU3TcH^sgURBTXh4R3nC6KV|vIWF~WNGmRnt91`99hPz?lbn}YhZVr%b^gfVQ zymsFXZWIch`*)4t+sbG`M(gM&ptA}3<)zNv2%;7#ii6Ck&k^>}M= z1*q(%xT#J+0Hh-Z2&Ny!0W!QyRUmv-p9ezt1&3@5nSKt8r!5Of@GfeN0Wu`8Yvrqn zDaOjPu4(DV3_W5g8ki(JpLMq)4SRi8f|pj}T?vJrLTcmVxIFhI_baw>RB;9!%}iQ4 zfTc-VGJL3GF3? z>j0|3#>O+mX4;Dp8ol^fl%hclSm6PGTxs3y%>Cro53JNjw!5QY$|?WwvHm+4W-tbsZ(AhK{|*AqVI-8naM2wzBh8EFBDID><`7HeVcHqw>BC1P*F-hGbJ)g z?_I*umm#i_Ee01%h@LSaD}FPo2*2-4zXfd}tbcH)F$&`=t9ttNO$K|c4Zq}WWuh5e2|%D<5Hnq&_OvlBm=&`ZZ;pEe**Ji+ zUJhwk`qro3HFA=HPok4Zs%Sd8gqg%#D0ktbJfV3p^yLFb{YH#a?{@*!#-io#yxWN_ zxr{s_u&J+r3!S-zv?zUrL$r*J(%;bNA}3|{CS3NBzH6(HGr2xvaYkVF!N0S|tRU`W z4EpRd?X(@T|JGnlR7VC8qVB=#nuFh1W3$yNrEU8_ zMj9;l0Yrfy@HZoEZN7jBZf|l*k}4K&;f+^S$f7q!ZUkBAGg% z_JHPAc?MbxFsoc%e-5MW_zXwV@RK_d(Oq*{s1gJ&qbihEp*rMd=83aeQNn&>tfH#g zH!rL`zYlL&!6(7p;1k}^r6;&zG=l2)OPjEYWo=uh?|3%%0j}=Yd%?|*75ei(-Nz6+ zsz!WE_~?@nv*p8%qqf2Hqu4vD3l|&*>BMxb4C%*Oj%~;JEPA$CwvI!UE3Jwb=}g06 zs%jELT8}c9{E|9gm~#_UVgrtrbMLhNsNeQcE`IF>aR0-|#V&(KU8!m8s5S2H3hNW! zt)r6)LsnZK*!oIAF$!6EF5nh*@T#p)6Vuq)u0u!D`m248pfOJpBP;Y#rOfr;x}N3Z z8D-Ho&>_rPO^xUpZ$aa2XSog^VIjXz6#DCq(LC+&=^Ohf1OkY(h<>7>rz#3E@nk$h z0U9@hiGq1b!xd?T8@Ss#U43pd_f=WsxLc0l|4nY34(=J8n!T1|2e+<@$$|L>lEM9x zdb3$+$QzJVXT>JAhh4Sx>%eFfJrQgsgTw;{vhFu}Md*f3_DuOIz8rVuR7B;%fPr1; zfI2pyeC}GibWr8))&=Z`5IUAwXzDK6f_{?6_zCFu{UX)DeX^EBuuLfKaR;MpNzNTH zL+T-y&G=#0>Q6$i#(=KA(F#QHFNMml6-}Gh0k$^_xkc?mRa4Kfw`myoIvzI%_M3Ss z=$u!Of_a*M+83Wl^6zoL|{jK(SeXlio3VTH{SM(2n_W-JRegHg)&g>O)h&#RmWy+u!hfeHsa8Vpe zk;&2ut~HFR!LLSKxb*h2*9(zqdqasnjLua#?v^Ct%%sYKCI}I^B2FBuI>d@%tpnEN zQr)=Swou`N7+?s(F@Vh5Z^W1Smi?;W@!y#0w`5eO(jd}tarh_;SM&V*qdKIi@YFX~`DDJP`6#vT{vUwM z0*zzm-UIW$ws?zze|U>q02wNjT|?_}kdL;n?Y7d#r)C2ydw&CD{@2Q;ywX!IHSN%f zQtt6gtp|Ezas>plLunT{F$ZgGuPT1U9(xwY*xp3c++ik`hdFmO;&a`>LZ%d7b0Q7a z0VhFJcdH3=oI57>f_|E7z;@RF@`h-<@^8@n0P@O?e&L-zk69e1IP58`J7~YR)qGbO zkbCg|V(-19n(F#>Q5B^~mENnMNE1Pj8j45) z(u;%=q<09Rg_Ly?_5HqY?|sHN`<$`Qy?2lM{ZJ!v~O|+Yjc;YAp z49NM7D+C1tBcY zT|=(|)mQp<-<+}|-{dw#JnSX-$qBi&Cx-JU$aJ@jrs&7ak8UlW`$mKi{7yFk$v=E$ z%fRK`_y-^O2R2B+4hG$&la_fcS?v18VEWNAnN~YK8OfI)ZwBky;aoBZkR) z^+~tBvPZ~9d#Mi)cfzT-ZX)Lk3vk{HqoE85xZa#b!^K3b^M^ko1b-!#mxz@fsZ;$d zc3e8mzlT;J@=1X_xO<-xkbyqYa&T`!OU;Ht@;goi%o~D#V1p?1Cuss~*)F)cbM-s& zF$zma49)wBl3G-&%eOozdoTV%$SE{svmsbJ_@A%4 zOo#U#=$jrFQeEAKs!|;>WUDt4_eKM8umGS)>@ArQZ6{(UU zD{jcmm4X;}iqN{cDs!GQ&!F7O@*z0^(>FDg`U_@`4m5)%;DFsvdkc2or9MpmhH3ZU zrTi)PFZfWm_mT*-Drov%j*|Lo-*4tAQ@E)NY<@=8y=Rf%uo_BH_zQ2g;`UTI{KHeT z!234?R!V3(JRT7~X+*$({85B&boUA@1ix{V)p+-#A)Tk}n|yi3wl}|1Ojp+ZfY;D^ zmuPr6x5v`P15@f~pjVTC-@_`Ad~+skJP9fw|A5V#CjjugLLt1nd)2*W_fx9y55VI( zPOi;frc1p;=YBc8d9-k2eo^PP6ZwU~+3(TarCv*fIz++4MUUjKyeck$${L+z4M^eF zWJ&nVlf()2yC%AuyoheYF_S;iouOej^JB5Qk0J zA7r6$-riU#d#4S$n=p)DbWOAlngeWx+93A=@~gYQDiHN%^#N$JC)*K^EbHone6AG5 z7F`j6Q(~!*q1)Wp6Ed?)&rT-|czQ9a$p#TlbQr*`taJ{%%wkoE`TbVDW8!CRhj^1? z0=yXccVIYG0>b?dMkwFpOK_o&o=VIgjh}$qI|+#-&9!Pz$|oG>K=^rsaGb*%qEBZ{ zY2@D&jl@Ldq#w6mkmBU4iu^_7@kRM$B@92uk#;wDBK}oVT|^I}F#O}zh0N!SuUq6F zI#x7O1+%nS zyAZ#|H@qc*yt-~X&Ix4y3!++gyUK5GKd#LgjVzp;25)>auP<|6FrZ+l58j&6?L)%2^Z0%U)1Zhu%8N~zT`;n(RJ^x!H~ z?_#Ch2naZW0RIBh5)p6-<0HW@5(#iNOnT&7)8Jh z{DG=2Er#Kop-f#_y`a~x{^gG0)IaF~G* zwtKwbVB)=7-W}UCUinu$XO`ZBz*Ga!cPPvk>ila7fZp2LKuqZjXUnOR0 z$>M^>*U~elcTRJhsTJYRD~psMT1ENv!rN)#p8SGF%ms_ zAvIWClEhm=B5dQ6%$Aua&!*Up$KIcNF#!h~Xfc)pHOS&vSeWro{7@&DO%Q&ptDl<< zsRwy52OyO+%7^kq>r%t3AFqJZlFv+`>#`wJ=!tl~X<0bh^cK0?LHGMuSYY?QSYbA# z+ST!~Vt>!Wua9hMP!gB&K2@XK6@Xe)1<$>Pm}*o772~yn_4+Gqjy@1 zUS0Nc*5)jSqq_tPzxd&uR-k@(^Ga0wtf#PTJdFxz1334?a2M%?v;~cqXEnCMW;`ti zL)cg8Le|1KU!E=O+o_+NYsq5l?ttU{lVtBx$WiOmsdUZkA>iN*$hA2$(>b@1PU!ZW zb^E0+4ZO6K|UDRgwOrUGyx*~(6)LU>zf%}ikU#!x>@{$e#c`c<0GtRt#o zSmfc<{n#lA30J(FbjM&$GKQfsMX0>2XI2?F$%(pIgJ1cSM@`!BAXZX>AW(RgjHlJ- zZJeBYTsvjCY%jly1+^6O-EqYt&4+{{rayM3r^(=}k(Z=NoS2%2#}lVsxyyInHsXMU z7^>&Nj~71W>Hlua8F8%cZzWz>?roak#Iez_qqAknt(5HFFj%#o;>(+wLG~^3>iP3a z=07_Q?|!bLxmkz|`eH?%|MqqclZ{2l_XwUK^}MRg_9qQ=w^VaO`e2VrYhcrlt9`rW zrIUwCNdKx`xCBNGp1`C@odj}o7xxobud=jWzMSk3nKq7>rY*;5+a}1+v+EepzBuj8 z_bOa1&?LZV%MdjPhyHh}5*&aT(d^iZd-mBj!gBYT)BOJDjWJ1ukH%B}zEeY#Lu^tm z$alGSbe+-eTk#oBW94RYhAWfZ#!kRT6N2K_f_M7UA8E0XVVS%|6L);K!()8aMn5 zs>BR<@WKa< zf;7|p@I5cqz8i2rqN7Z>g8~COhBI4a@U_S^_FD=-HH!9n1fDOPJ^Dt_XIE??vIZoz z=(r%!uS}x-c!ft>j{`DwtQ(=Vb7OcJkdyp8`D+ha+mQ`f{`HI+q(RZ~GJqqB_A#p~ zery>$N_7%V{+M%q^*|`txa^fwpyJo`wrd$xqyhyJyk=Y;>g-~yS@XR0L&?`!`BY`z z(bV&a_?u);sCwiJJ6}}`cQGQAG1)GYuZWntb$9&!v$K;0@^evT)8@W5WM5;8%D$3Q zRB8Kup*C;$wBAe;&Y^D}L10)-T7SY(<>fFI$aPkh*xAKyp|R7lc1!*5QS#(&()QH1 zv=a2+lel&FX5U-!rJHu_Wq*~xn`uloosgnX+Q0Glfc~DLzh&tEkyS>&6sLQY_fD1O z75nrb2cxNZ9A}!quo#yutIW1<4N{PTaM8 z=|+Bv{%cUdKZ|zf)L#|;XFE4Pa=-g$(W*=0djHbSg|ff9{Ci^mdyCKQ)S)vGI?2!8 zxQ|_Y<!_#rQ_B>;~9DDO{GEJnxj!?)cLF5 zhwj_<=x#vDfjgFtxPeBs4T$`;`vuP}s^3?XeHZyst@hDD@nifi$)IukR*do zb^B@^p86je!4uT(n#gg0&ZQxz<6QO zd6yDRk|dG&jhhL#&V8l2aJEjEl)pifgu#<9_Ix-SKe^jos+(T%q(bv*>`Z5+ZqiK` zu|8kqrq*kZl)gg#=s9n_z9e0b5_|e{N+)BwZ*;02nGbmrgQc%tU>PpqP3H@rlj%^o zc;tAWU%cRs>Q(i#UtM25)!H8Va??sHKm2|adH56~$?NI-r!VUN9>Cu-@b?V-%M8dl zd;J^^PUfaOXX#KHvZidcPJdGbQ)5r7)ZUA~?~FWH_b}W((a%siq{zG12Wz?w78I+l z*`y@6J}fXvO#!7*QYDW!9@Oz#)DU(s=uGIHn#`-?cHoahKM}!g@Gj`P*84;5N91|; zh?dh-Cjzg`(0~06y~`GMq#s1MAOeHR;lV!ypPT&k&y;y}{Ni=iEo>W3Fkax76Ke|_ zllwrLwF_+0yowby*g7nV(+K{|o%Mr8&0!ZCtE8N` zWt_v{lilX=6M{>K=p>Q?)P_l=bvN(n8fz04X*3fHUz^@T<0nZ8#6>^z%HAo5i*Y zIjSVC*j%b(m$HEcci*2?I#hy>S9_(?m0y22=l6E+yyfjXu{-+Q9ABRVX)d$M@$9xT z8ygD*C3W4p`gZoU+$}exFwTAu~H zzqledTwcs3DZ1~~+tL622VL<=FvxJPxo06!oA)5@+v&O`SbyrOQV&WfURUVpsKPa} z=~O`8GVkc(K&GPjo3lnc-JBkl`2SxtWb~Twtrhy&@geTPpvt|Sglwl>)yG36=yi*b z(8{vD1XU8{2jX2R=EliSjSWUa8d8B&NLXcsGao7SF{ye$cfa&8Z;j*VD5+r|qz~c@ z`4G)2J*PnRlTTq}E@CwA&Rq^gq7RI)b~cDrX#P!=UlNF433{$d($Yr9T_r`WtR=>N zodDhZEu9VA4+o#@TzwY3sTVdo8z?*8`p z3L_i&eWX=Q`!_PKy1LZ&55;Q1=NKPHKI~xzlhvm}dQ==a%W*Y$O3AcI?5~mq= zHInzYxbF$%6Ze;&6ecrqX6_4yzgHzbAK26HJ5)+$p8BiVvxOj^Diy{XOX|($O{X)AD(?r$vUGkk%yxa@58hLw6O*TojjoEdOQPu-Q=aNhF=gK~+C1_xMKqeaBkSXQ16j87&gU+M`b}y^ z-A9FWhyhyQJ{a|d53#~N&MPCzv%i95Pwv@LUr(078_PK@xMx586@-%keo8rILaNc4 zIb}_9shNRm#t1YV8?!=ifln?&UGeX5Uj{zZyWh6iOPE*U{$)wl5Y5RNqR;=A`Peu8 zCA9PQ>Uh7uKLno+oBJRQnGKhI5P@_W(U-}0l5lpr&)D*W; zx~-yi;EOL9!Pw-O^nhN`sg9bkjuoe+W`%7n!nSRY>82>`st1wNNahpG;^6n1*ECzl zQr;WcddqI7FXG>2fA5n>3AcN9@eTK?`R#p&Fp|KPEVrdAgSi2OXlSt+lwOxG2l^mU z5Gg_3HLedaYkH>=Jx@*iWNY5FLR>6E|1$s43-L9y1pO_ASOoT~$X{9>I=b^!e{|~~ zr8ULvL9rf*E1vJ22fCz)tH|&2>>$zT9{R_{-r*G$9Q)}z$P|ISyHjhGB~uiW$}yCk z+IM`0pE)CMx5;end(z3FPG*(emn5|Y-gmBy9XAu>ySyLm@!trkt?KPAUFwp8D8<2^ z%}NAyg$Fv31letl_SA3eZLa~_t%cm_0Rej}58ad7)~U|iTe&W=6u`nwS8xqyp)~9M zZj)bPAB_g=B|odij(t1m_6ZsK1#pK@`aE0M1VR7Eqx7AeS$q?RVukzsA5 zU;Ig*zDH%Gr9!@|J3|VyPpR^&YrOBmP;;D`Vmtf3-`U0jGoo01XbPvGyLipGAgCGf z@$|=R)wk=-%Y`+d|E85p9578=hjLD9!-Y1Mw zNbuGkU1xTpTVIM6=}%OL7XRK1#7jz$?M)xcrE?z*AVHo`>IT;PFlA zIC>e^7~w>r-dp{b1Pr*VN=wXs?64dJz#fpyjoh*Bq+B!l{8aCYQdU7m->EC7(+b@3 z*&pYuUVX$CNf|Ex;!AlPbFwI}H}9(i>d*48%y0b+e@nw(eVj;T_hAV-{BtVM?MimD zS?geGJtyJr5S(Y&R!&fT1CmIs8+-bqa36fOv@PA9u^h*zq~)qW)J=)j%xzK^$E#0N z`Tx2tPQHFo%^5;$mGgNjkZ@X;4o;&DGGqd2{cbd(y%q%_YGopyzcxml_DK|V4z8fF zO}$f%BwJH`JoT566n*W!dcd&b--NjSS1zP8p@X>2)*z zH7VNjIoy!L&B>~!k+oL)qkt8wkE}l+;t^$x34O5%fLB+cK!b-#+P&@U5~!VTfI`{F znPuOa+T(F;QKhp9d|Eps;w|BG5sZdiTU26z7!a6nEAzn%<}+)dUph?bLK5cJ>a%le zU_^6R-Cyzr_ZcS|vX>RSE6kU3;-=Uv0B0P*^VT?3jpDI?wsPoJ!1`@StBf$6+zQ%0 zQN*xgT`VlZHfBROB1;BO<)E#|RVVdpOL4`raavj#vMp949d79U>V~NBIxP$k4nqv; z<#h;Ug*=*-vE)9d;M;45v9j<|e?CP=*-JlV|A1lYhf4i%)l=<2tgy21J81BooIaxq z;vJOrh0JOj=2&x|pNU71QZcleSI^m%E(v1m56*P~UO%fCI@qjm{W>2vRxKV<3_Y)Y zWuX#A@0E7j)M&#bkMQR!t5dIu0oHMR!0MLyx`FYANx@%#|9;qUp!eIqF+{oUkUlfVDyBMeIH5f_Q5Z}b~C0X8KDo*R$JM%43t8bO< z>$VsBzT_f03uNhHXo zKKc9s>xRjqz&L{?u6j8_n^KZu-GZtkJ$utOor684^vA=56>`d?p7vEV6X|rznex*2 z7v5{x)EtWe<+vV|sS_xVvX53SUtTOorl1Z<$c2HU>%N10TsAFj!vs<9WdLUsc!Ib7 zvkFsBsSMzT+96)t*~#H6v>e>__eZ~0hT`A)sRF)Ee{StZeQ3wNR6L*kbn>>w-uv$` zIJT5{i6IRSUd3*hG%h5vgc*w((q1*cefhKH^6hJfuU{MT^x8&NIs*j@c>=0G(L0c} zdDgKG?mF^2ZMDbyaeZ<=ikF>6ijZ6%x1V_QzJ0mKlxc<6rkxagIRN8KkOzz?d1S*n z1kczB#5j6oM8qk}Ja6Q+78_cWCgTcqq4QO3w8-mmqLDxO!Mh&rQ*$$EgwtogQg!s) z+T#~O#d52wwh<+i!(;UN2Ht~1U8Hwd3Q7etvXlW=U!xtS!;FzWUm*hX!?>Pu@dgt>Mfk z&J>M5E-Z3$A_(bW@h>}O#ftYa0~DT=R*$_bqL6XABCF3o9;CMm`mIPieqmRwG^Qqz z)C+nfbC_-s()(nwL$K@Z(^QB~5|2v#O!DSO6A7hR?xbY;CU17>`;{*XJB}JkJ|Qx* zbI&~VH;5p$zzcsZ$90+9v(T(N(0Fu6%S1;kIS2USKttnZ3v>zW>xUvKFOim&UsDA=)`MM`bv+A+-W z)%Cf$DS0dj6=VM|i`LZw2nDha`NLQLqYc{(h> zPh(x-^WO0=^0VeO8UiyV9N1BMnxJ3P_^PG~BLxtD5(#J$tp+Yv}Ba5B~Q7z82V4(jt9&uv87msLb~RLdJr zc`vcv$=hc;U?qGUs|lMW07rwnBJdaT6vm&By%;JGQEIcj`VXan;9JgmioZ}53p=o4 z2@G$a{BxfevVs#YK8mY6d~l+_Il%3f!qfj)Aaw^TB?Y>YDq#grr+UICsCzw4Qd9iu zUX9S+r+X}1kj|vnt|6YoAmvm!uOvati!b(ps^$EX-ES>Msf1FND9bj?u;!oES_QXc zXFbgepNv)k7b4_pk%$@3HzdzjDIN)tJa1MT)?rAv^|0`h=CjJ~jV--HWs&CTFFFj4 zNL|h9W}R?RT|va7YagfOj&6$Rzg>bY@mvZY$9oOXJ@{O30D5(lN>37IX71)vNbyG{ zP@U*eQh#=kNSvc+_^AVWXL`~>4-+j5r!&r&n{cx`j4e7EGgYA!%ZFK>O08Y1YZTU^L_r5(@XmBNZ zIkT_}wEQ4X0^rtMR&oM-`z8tA~gm>P8)d1tb)bT_o>;Q!tfZxC)f~G`s zVvB|MOUwehF1lWXM7Mpe{`BRv_Sxm0yALRKS7=-A_uOg>x%Gtc0^28vsX+Wd$oSIm zrMqu#QD#ap&X{e{bqbky9!P7q@crENuVDQ@j&87GO>m*>D6$aIb4os;pS0YeaeNziHeoB8mU z2DbR(F{6`Y5n4L_5Jd1!x^l>L?(zf~WhCuQbi^HJ;Ar#^sER@f+d`bp zchnwJjte|Xxv_vN7VHZJ9?crC^p=42bM*YJ8j=1XEtwZqt~AIC*XbNqgXZJ%li2(R zf?mt_@M&Zxy&PPDDdHJEzyM3|0!l%=A=JHQX*pTUU&RDf4&Fw$p&v<{>!Vvy6U4fn*9uMRr$?Ch_| z;A@Z-v4D)v*xM2CnbQmGc7AG+oNefxmk^tz7F-*mfK3*WQ9Jd>BB(PgzJG-tcAETD z!}`2HZ|^oRT&O#;WQvV>FS0OT*O>2Eyj3?&_e%kOOwfF%<)vn1yv6lh8_r4SG6?Bu z(FT3_d@ee^&iO44ha501NHPSBG8Ejy@?;$cD?HcQ#QbTuJIAWVOe_lw!;VXOGlmld zbw?2Iz_Iy;{e62~h@MP$ot2<vh0}d$XLi@AajV6SlPsXNLmkiYDRj;CfzHDOZceBZH}eY`+2+ zS8WQ?AzzzgkQw7z7;8nn0M?5U48Jzi0yv`Mw|2x&hT01W0@8>D@F{LB2Zuf!p-z2} z>AKn<4^h=yCYHn5G?oQqvykHIBkrc67YvuQWH;o7O1QpLdkJC?S#tgbVDK^7I#{;Q zk|3LgLg^{Xvyvd!o1onvFKeAo_TM>WmKPO<9>K+CoV#3uW%^_aes2>~{h&ZBzho;m zLOUB}FDyJ;^8kN`w7J=nb(`1J3roGycVGvgxzd{Ta;`N<0iwc#4UBacT*(6U*RSQ| z3?Ee})}X?i4R4$qS%GWatUm_Qa6fm}NO*8%u^=p;<3#ojbk=*(nd}JRo+g-k$-#c*d}&45k08$3 z>c&H8U0Fx5%w|$HZJKO(FBT!_U1?i($0O^7Pwv9>C*}Jxq@^NZz8TbAfPVwX!-w6o zMuI?ac=|5Fu+=hc7(Xy0@%b2Sc;TCf3(6i+uNba+ zvE}$`K)iX2a%z0y7!33ej7)-Y4{qQq0y|Kv(O2U4-d)>_f5R%$b|B@Z?+}LPSc``= z@Tc}Dx_M6T)eCxJraU5EtStff{r&w*+qNth-(M-`CglR#mlz9+)N)75j&%V?5NxnK zIti?UT76g=;@)OwVb;7-UZLHzbD}b|LA~dDh0onPzAbb8*q4LG*M5mKs2Rlu;HWeF z!F;%Q*v+A`lMG!fwMX3ulnDVZl`eOJK zSpbKF07xs4=7ynqa8I%$0XCuG`Ke?J z9ZUsB(aQK%yuv7&1*?pkTVW}JSOw~DgYV&{2hn{$L+}f!AXj+ue)Xlz>>Olr=tyVM zJ{cQ*7g-<2vc502kv1~)Y3s1*@V&^%`H|P}_Kb@^EJ1LD^z|giE*KY3vxH%BOWTXn zJ%cSF9BXCE6L#&=$|n!}S{9A`0tjkaPh(@&8yIDRL_y(SU6FS)IzR<^&-C&&J9PRl zMkv2{{4uMQR);W6QJp-5;1cZQ_PIN)MGXR*wL(08V%p9?2*u#>h$7EH|NKJb$OiXH zxROxv9hP!SZ2yC#$>pF#Akbe_t3rPB23K;4*skUePoIgYw1JcR#Rs`tjM47*x$6!u zv8`%Tc$J7-)Zx>_8#fKt+6_bQczxZ9hlo^R#A%ab&K8zSzGqnXjrV@X&9Hu(&^mr% z16jcZ$#59G8!OolvhhB~jAY573ZT7d-x}OqTPB6pJ{8Z0zdBHqn#SHDD<(8_7-zpASEq9tKFZSx*^u*IE|v&e!mJgq04DG=%MeGvimelj==8YY-MjdG#2Jj9t{xEZ zPYHVC-sjaWkzy%4nZ~pQgqW_bK`}v%bMqi0jb>lQX&I{x<&%#jBLYVOgw##IIqqs# z0DjA-_A#*1pAA(8mUfDu*^oC&(1pHpj5OcU756N+6!CVSIOm0Z9QK`Q18m?912c9~ zfgoMI_~7ZuXV-d*d{YE+%ZqRm`X9T47%i|~t z4$kq*AArqhOu1DC&n$dfm8`)RYgZmzQN(A*jqV||wVfg3du0H_^F9lC{QQrU*aPb6 z1sS{+X^>Gkr-g`F$HKt3spaklhu&mia{Fjq1OJfzp;UrDy;T>7HEa?AQzaz{P-OA@ zLaNKg+nC2vj6-(6h}k>UD0i+9Aqi;;;@1spZ92LTUixIOS>(I3{A_MqlrT>d`}lpA z8*#JUjZEHIs6fZUoC-zmNZjR3F$)rXG$C!3qy1i({72tmd!Xp;`u1U>aaLN2^Wn zgqw360QIHL+-I5+Gb8_+n8H8aij&}&=tMMaV5QuZzjx3m8DuaVv28Pi{M^funuXm0 zL9i1&K(=_k=AIL#s7Bhu;tm;1R;ku|C3{CCzIj2@4j;=sRcF_e=resMnw%%iv06z? zceuh}fk)WsdNcGS;*|VE-2kX%imjyyPT*LCNOB?4nh&kLuxn|b_XFP9JE8Pt^&OUY zibZ#hWrGi=eSQpGDnz4pl5540@2=7oI|9?=SMi56pmxYtsUuy98Q@*wr=?gh{kP{F z7j-f;zc`|S8K^{Y3=*s}jSpN?04i~-ZM0hPA?@N+3;YT)hsS;1_&3)var;nBNc#5K zLf6HaMGt;Q{jR}7=;+WM5bgky{Ja@yI1xIRw}tJ}o=fg+4P4SNN}8C>`%zxVTi*Et zKOT(*>wzv}R@YVr8|)>EGnn1#_6wc4A*`18NyC>=$YYA^7_T9+k%b8azKCR`DAO&E z>?LK{O+4hVv~PF~z+DeyJh=_5h$VZ9xkJxe9PPt!+%W&3nbI81%$tSX2xY*dHlQ-! zYLwuj6}Q4neA6l#UH2x-(iXi~C^CV!BzQjGJJcR(T5oJ`LkJtTGN701Z*`ar*u?~p z&uwovwy<}%0zJ{TJtw;hJ z7b_Yp;@*h|X=?ei;6|Qke$}--1vi=co~J6}hpYEV3yWO!}P}2(pH8e`>v+|Q*O{qnm~q*I@;nB zdr9!^&;{os!}zJApY~+8RDLYQlz>AQM?bxI$I{$6bo_BjoK|bc)88uGdCi^>rOG<% z#F2QuzeezR%Ima*k+(j5zSH;cfL^?}()Kecoe+53rOi*8^7{$6rWAYKk|f5KZvXaR z1B1Hhkfw2xGf1Yru25G1`yoq1m-%(X5qJt}9D}>mv$dK)0!_==YyTWvcX~|s^;@4c zE?JHsIHFl$M-MvRB)TU4FmAv>$%Zin#nWY_(~?gEv4?M5P_QNQg%#ek5_1nZUv1SF ze$Ky87KT~$L5bBlU4WY)fOaj_21As>4K!zeSU=3gP8mRBdA#OOBX^;r(2bVZ^Mn^9 z-n8&Y-4O5V(71#V&Fz2dGs)#21G|MHoQaMX3*B9Sa?}v$XcvluMGKEEZ=4H~_ZS@? z0*V@zVxqevOGlbsQ8kQN&@WL&+?v6T>W) z$P=<#&&Lt@wwmpH+K}x>o)ns*Frlb%{L-qY+xR}ZqGKRbL;h}OKDo5}7DOP8)~X1u zx{@;%M@WDYsDo}&^AmuSXEQEy)m?9_f#G^0b>T5RAzgz0GH^fU{U$GSHK6U2t(3&w zf_TX&OR7V3MKN$Euv%N2DJ6w-Imo=M0_iZ2A%I4B_4Q;KeNDY@pf|wZAkfqx_%6dd z!m6KqMyGSg_O4yVT`P;H>#qWH*{ddlC-YC9BvCXc1ha7kWP0wNNaSIfB1XVVAp|KDH^eTo zEcWrNB}y~z1y{_XYA0?}TH%m^31(mnY_W+*vc4WaJORT=Wq2%NN7AAP0#9s5M8H_8 zE8$W?v?a~cr~wcdyG~0egQA?|2+=;Yf+I|ukIifA))zxkNkl;CL9_C0pNPUqj3YXGH^w7IfvX;4X{~4x3>ckAo-&Z5RMxrY!_@#CW4` zb+_#;=H;`z3SF?IoG_$LqsI$m^o|glCW|<1GbikV!UfarzI6_WM9XHy{;@)kyBNTp zEOCGLlJUt+pFxqF>>TuB=ymM*_B0-0wC2^jzJ!I!%@oY|c_3rsb>vYDGGhY}!+YRC z{)he}{$V~X+*i!wbu|}{SQom#z6+{-^woc{1r-X_1CA$r;iEnM{;s`g$HpET<+WN8 zdHx04OuV~%{?W8Z>F6zG+QGG`V~cY;bQ0n%j~^~E zA-FK&L1jBkrq=Fq;YqL`KOUW=IspzK;jPaTADoi3liIKE^rP3-ogWn-tlD?hn{Mub zk02jjNwjbGusqa!ULibjJ?_GMrd2EkF^?K*SXl-te8>Pvo@2(Xvvr>E_z(gZI%}9_ z$~EOMc-qDZq2zBkQf%0f(`)^50ui8l(jy^J2#Z;Km@DVqwr~iD2DxvjN{(j1l%dlXOS6wyo*8aB6%N|Ow6^`HtDS{3kA{PpA$Hfu+ z+0;%DFuKa2*kL4Ct}ijZkd+nH+CZUJ)@+1&!XWBZv3gvr(O_dk4Ac!$72Ml>Ujy3a zDhJTNaJw83lSzWFaLd~cFU%sYxe5tkPo%U=4puG{FGL>&T=UR9Sb^^0c&;Qxbck9! z(;ton&MvVRA4g+=6MD$FXbXuS+l;3iQ&0CBPc@@;*xGWlPSoYLrMs1>PvUEGuq%nu z{%=>FJy=EBS2LT_rgPcavG#syrF5?oCE{>fL0R#wtZb2w&3_hlOektCbQk9&lxzw~ z-WPv%=k{fY>_!Pi=UnJPvXTz@i<0n~?Wg7QxI%0b=j$8wv zo%NFzfaS-GzRwR~Hbt|YT1uE<+)n-IX1Dysmr})jPuRBa*k2wvFR>AbQNWaf^uUEnc@Gq(@3nDXfsn-CUBB&}iRG79bHCd3dA%sypnOlN)%8`_A&%o}(>l z{n6e((ZbuyING0`tPo)(i9<*~&gMkfy19MN_+;$(sYIYj#*NoJ3{$YOSd0XV+2ZTe zM&IVyZ1IoHD+Ere`l*zUxc-*rt3*#AmfLjne48y2CfCN^?CW?~`6fEnWiaUB> zk>41yhI@E!@Nd=Q#`9e?JXdCnNJN_NN4!5qt%>&;h8;TZcQ1hKZDjGaQ+j>qA=gBG zfy37%EaIjY!zRV42R3fEq@T<7B3(L}fF(T)yyEa`f_ry*->27?__hK8An?F9c|)R* zV=VxcaJI?A(RYsw!Os#eYVA?>glfzLS?S+O(N2H=9|&%j=uwdk6=U{_f55y8I}CMG z#kDKK7LZQLO0#BOi}cr>hHtGMRD`Jp?a$J3T?Z&xW(ECk0qfy_Z=jfy@^VSUlIPMx z^VitB(Lvucl@lHf2~^;Y+YVgRK=n8FKAH}S7;?XTddm!P(_al0A3<;q#{NV_SD$|A zxlW;3y9&u#{u)ABS8*z`(Vot&Y=eUt@c_8;cZ5Ehj!;?3G?zXx-JaR zx#g#IF35+F!Gy-${y=hoYEIngw`=((DFPy6cB>8kdgv>M7Y*wY6kFm-%Zo}`WM(!A z_}Si_XJbyrkHz5(d6@dLo~l{M%AqbSMLm?%orx$ho;uoiXj(>>EvfD%Cf354p9(NJ zL;QEs?Du~@;kMIra_(1Q;5;vL{v_T;HFNMZFs6V5Vd!jk4nX2Y2+C}!-% ze#EH;a<%Io6^PIkNWM2t_1QW&EtSp{uiY@nP@}68C6WL%dN`T%$>RGz+lB>=<#tUK z?FzYSvaBoPbL)B>o((BOkPA9s$Rfqh;}NBoK2Mbk>+WU-{Sc=ulf83Lm79l(x0^+Q zq1tHx;@+rC&)PCiuu{m1&nTp&3YODr@t!Lbkia2eMe(8QSw5Gn$-m~_Ut1t}q%IZX zps0fVy@}77++^mhvH1#&wB7!fnKxdx*S#&Q&wC71x@K+2Hg7%qCghAad5mpG61>qt zzCo)WXnkfL2LNezKE$Kv9EK4e>UH8J$DXrhZ3s9K7=?b8%6>8gXJZg76}2_TH&WZW zz+NWw_lgq~zC4!0Bl3B^WFJJjYg;bR?QLD|5v$8eRQ8(w>4f?&JLYQMe~fLriMJB4 zWt`BY+&M5C0KtkB1VM*ApVWbs#=5LVIb6WJ7$Hq>pXO2QC~W!r99~UUtAI9pFLHkh zfvZsuY0c+(O%u8WTTt=EmWlv;bTZPcpQ^IZJ7PMwxFp6~4q0mJwm>w-S}~Wmj_NEUyKj%xqsvOXI(zO8KnjHf&7Qwa(q(TwAYO|oy5oy zmWpXYk~ipTkL3Oi7Bi*K1l+ImTy;*Cwl^Ou(8Xp_-)(j4*%$l_Mr{y zT)aP@b-m&m1Nh@%mxEy#loNLJJ{D360$9(-Sl!~;g(SD!ihsGJ$@7!EFR~9Zz#=|T ziK0b#qVJtNRA)wq$MeKu>U~blJa~zdK=W0{Z9#s>?#~_sU{@s91PIYH1ir257>)$n zFF;&^%kH!-*wp3JfSMPKB(Cn_N3!jFioJ-TvGJKveE;!$-7u{O*>&1yK6-c_rN-@h z5~1ViaUc+L%e1F9(_TXk4<%&Lc`vTg3=|L1{sM0TU=7E#Yxz)YVzvG^VDZA9kLhRd z9(O>}96=tZeUuUCi!t1gDEEK^%8?{)SaC)g>Ubc3Ks=h;_u+iZy9TGc@qHx2EFo$W z6!f8jzS+~P{=UQ7GSFN4L06Lt@?J)N*%ap1#3O(c%%_8_T~!7ltI>&Gl)?_BUjhj)48G?@0=Y(|`>JWytb|N_WZokAD zzex6FV%(X-Q`+-}3HP6UpVposj~5FgVm*lPp-Z$Vdk+)otAy|<2kh?a*@G;?cK#`X zXS>itru&V0G@D$?;vHxwR&m#XPf=Wp7b?ECuWn%cRy?Nd(X>WS`UbVG%-b8Kb1$r- z=Lfc%7KSg~Or)z)*XbvJQCSNiP)ZobQZ?NeGCmU}@bmb5N_17iElN@X@&A84$3sA< zLx8a;ZD8MUJ938LeICj=$s}34UG} zCiN7LIb&kz+Ix1FmkXRrAit2dxO$`Ge?gG3zx@eT#3H_>>*E!rKqn=a`kg>~m0Y3k4Dl1(G>>SlEPmi9Kz1ZxWhl@sg|KKgY@!a))lcZx&F|cc?QU<@9mc$@5 zod0lO?kINTOx|OqBE3_z!$>9qYll|8T-zHkR*0Y`=Q1tiA_XM^&d=Pdh5q17*(Z$H ziRn^c`?7ZN5bc=~es1Tk5wgPF60_wfF9T1yd;cdSA{1epBSDg{AY7oFmiu!o?>Hg* zd`@X(i1_0-G5iS)MN_Ldh3IB9$^L?i{NDC4$mfWx(4PzWm@@wH=-d@gx?;~K@Bt@X;P;!DlIS7<{6ZnRkLe>{4ZkrNg*zDAw`Lu@69lXsYJ?*o+q4o`h@sxX z+KcP-30Fea_;z&sXKKvCp2r3CDe##pwu}x<-tG&ac};QgQGcG*h^;6(dN(Za#?nc) zX7fwEX+T;jp_4Ky&k8-TG5p#GnOaK7{)yjEoIgl*9(~ULmn^W1m2Cf)(5B4dOdFF< z(rNda#CrNJaoLb_2kqk5DB>s8eXnZ=8>@eyU{YgO5af=q@o&ep9k+q2TCkCZx)K40 z4C>dpI>!7lS%GT_KuEkO%~3m@SDXO_g<~scqgVId-l{M1B*~06+=@F z+{j1$R08?9K*}|}&7jA+L)52L4%;KOh1=Rc6xTA&(4D#%exOAt>O2schJU@?dShzr zS<}_kINd6pzOzq!HrfA${-Z2H-uj;v3t~*wfA^8NQ;(&Y@oae2Vv*WIY26*ntaQZ> z(zsAX#pLTaWU3Kzwo;7b$!2U>XJvbuf}UrWy_+vKu8(AOsJ0cup-8lQF%NcMmK_TEHe5WN*1Rjcrh#s?M?6{;I&?2lymH7uP-XV{ z^0sQFV1#I*={;d*@>9c=&L#iCM?$mi^DmPpZbSW#$+Q2mla;ApxYM|xe#5Qx88M$G zv$LryTx3iKzMPG3s3?SD=jmO0w~ryqi~a>-MFui9PMb8j@>*SZ=`oDJ`!p6mRBPIj z0kEn-$n9;6cU(8QWBHQC2aQ;3U4mrWgy|Sa`c1o)?lT9uFBwd^3rbebUz1Qc&UPA_ z7u*v#8$=PEbIx=;kC^3ZFHyXgr`;Y(4!8pjIg~@UG)&5Fhb8o@Afb27Jw-y zQkZ9MlS1>3g7L>`8O|SUg~!@=jxdYb?sZ4Um&bG-lh-2}r`8WeE%S&ZF=za(#2_oy2gQ8De7i-^RdlD-s;ar46D)2FjTP4fD9o2F4uOKN6 z%=@rH-OCaSYm{A{SWg>S?P0q=6eLeT^}7`otNk&^kny>5RH@C=O6ZlYAG;M!LPk>` z(@QV6K%ksEOc3#zgRdd}3<%F2%u3qzPk=q8PDofhPrN0E>rI@Om=k1N(J`X3uyJdU zw~ssU?9Sv0?rP{(6G(t%2_!3t+r?7VXm43vQ`q^5iT4lM!+T@$e@4!(q0NGd9YW69 z^jwh&G_S$@59Z!7tjRb28x{)@0Yw4HiGYB_Ksu)=CDJGjQqtWy5orMl8AuES1VOrU z64Kp0VRVfiV{zU4{qN^~UfwUC<9W5?*l``_cAfP-&+jL`Bj!FHcnYr>+`K4JFdq{z z1V?-wj^uT2SW&Vc=agqSs&c@9_BENy?U`OrR|w>RBmCbmm0OKJb%7qMs5ObaIR~SE zEW1Yw+n=#O_m+G+XEju4FU>!aXlZ~Q^!)i5q_UXS^6s~Jvt-+rICLSpP$> z9PduvnWGT6`JX*ZqJ>r8z!t7t*4zb~fItF_rv_b}@$#WM$yPdlX|VOU0!$m~u5^oa zn3R4(6brO3iOY*&wRu7(sco3VfRbZ9ihv0#((`fr5p7WI=uU#UpK<|1+lP4?Pmk~s`)5ZmncOXf8}-m-05<*?$Dl<(*=2(l^!9;)E$vFm zZS6{0)#Iu!%QyVrlRzUHc4ABqcp*xFA7|cUu8<6a>EabdA!kRJx!v4t0oQ*r96fC2 z9>JpPMzmeVTrx1T!{6Kmuzk(O?hPBI=}^7|VGAMIk{!@gUK;`fl(7F&;Od{4+WPUdbhzsUzpkAD8@{1#^` z_-uV(>fPBlvHnb-ZvF9*kYHXZ9)#52AX_wv_(c2P6m$7|0>q(-PlH!l(4H2?Y<@u2 zI60EgT{Tq2KFgGMPitXh7$KVFv!Sm7KB`|181R~>P%iFESrN;!T(FF=n!n08t> z^v=DI#Wh!tGnI&!8P3F$!pVQVX+Y}u+L}*Q3fI%#CpvTa=Vu~BmVjdlC`dS%l4$XS zmeX)$(2L&M-lhlc?nM?WUufW+^<3ywHBO(B;rvrmO~y$=PVP)K;WcK?zWG}W1WNpLS}eh) zhKeUjhhaW}{JjngPt(}T40UE;rWB5RBNsEZ660MNZF^O@x~&UiM?vk?*;@VlzBu#m zf(>inZ5k*M;nk^LKQ8<|{ln46N5&0b+Fl`roK+FOL$1r+B;i5mOg6kLCO5d(oX1)N zJ;umRd|N|<#8CwM<%~gDsAQx6hfa`tBFGSe8S>qFc@upym|i`Omtp87I#(Ta+wYeC z9F=jc%Tv~nf3k#GmYEH?c6x>&k$(G6QRXK6IDg98PV6a72E*;tgof$VP75w>Z zVEiVt1_`)xO01i6i1h++2PxS~&Tf>KH!%HOh^T`G{Gq+=u8>+!Y`tT>DO+0nI>t=( zFQFE<^ox;{tI^!XK-)5T7GtVm^B37P1>#jbWjZykz|;$_qBK{4gve?@2vc0!F;G)j zS@Q}#6NgKlFW*x7u7*7-j+-lFWXvpKmP;;a{$H!lnlGzG$)f@v<5CrT+qolMqsnq! z%Ms#)gegFm-0rW#F=<2|0D?QSAu&eSV7~}Qq|~?Ek$VDXyXZd^czw^9g-UlTokZ~fAa=?GF04bYBDT%g`16X1h!=cAOD-iLf5QZW1;&wuVOVW|LjTM`3{-!$_2yd z;#&Shn@Y3RJYtzqi9{aZ=jvRh;LFFjH`Nf1e9GS7Ha$l%P#^8#ithRMt6g5bp(6z! zGcj}t=5SyXpb6R*nfQ?5MC)rUsSpK0Z7ht>Yzew7v(zA1>ldWu5)Rhb28c)>+~R*g zYD!sah*DF?%`wz6=zvDtA z^m4N?sK=&g2_3!~%JJqTiBXgRSDU&iteymKUjHWff4l(3>lQTBMxYz_dA`)q3`3CW zwV&r@FjoHc^i)w0VBJ*)1%hmxs3r&`?4kso2bBRiFo^z!_21jBuNh2>(G6Wkn-|R! zBy!eI89@PP3q^jEprV@p(!#-a#+D@*{s1ic4sUv3knVmmw0&;qTMZg@@NpL?Rp%ikZG*qT*A z72|<1G~rd#YQLlQwLW)I&1JzXx4o6mCqx-=CkaOy0Ne%So}Sm#Tw5~5)^$?nHw&O} zBD=T1au-XJoBsT(ty*YpuN4o?Mz_8(eg3xTy!Fdzd3k7v?B&HoRQKi{Es%$vG0DTn z>>&~WAL)3Y;h0I^_cf+8$4HMk>iKXL;4K9LG%oM$jf?;S z`!n9hjhjy{_q@rGhM6NkhI12R94L9>pjq~jT>Qas^N7Ym#LheMkR_r&@$7z6^_kJ7 zi4@CT!{giRbFMj)O;^X7$mZMzuTt zbWN;7hU}i!5Y9C)xoGfdn0CE)T=)1UG^L_%L}nq z03vHY;(V+Hql~mw^^X}|l&^t56*`T7XLLpJF z`mMGIyyO$GPZ{Syp)*S{RRz5=oDC!e(;EiFa3NSQB>BUbqKVn)664HK0hJA(dG9Kw zWRK8mdcyfxt?S16J%%JhkDhhr_`;7|0REFdzz0o%8Ieo_Kbfk7YU1UI_fKzNSMh01 zmoXeOt!OivJo7hgX%_+7e{P@abNN;uMb?8SB0o!cih^4fLV!l4yOyT`0qrmPU`$}uD66MEybe$8R=b!JEM-Zm;&|@Mvf6ri+ddoBBeq#s$No%qXf@$+&_* zIs>jp{c%SSOW_4@!p5^ptzyK3O^=ow*%WCYs4@*nbNmsv&zTYsejG(fu^di9Ro1o+ zo^0o}plS{y|5?RP#$M+EQ|sP|nj-<+47nOos1^+zDjB^?6JR!vb`LZL61*>s9*m^R zfP)Evi2OFJW0T{@;nfFq%TSqjH)#p8mJ6rfVGx=9%da?NVg>Rmy|bTwQ--a{wRb~z zuaNv2+aZ?*m*Z&jnFxHdY2|)T_vt$(nGZsFu(5rO`ME8I+%&$6^ zXU#HrJY4^49TR%Gk^q%AePeC_3w=}|!E*ZJl(Vh(HD%f?Ixk*M%v6;j$9W|=o*9^x zpC=|1f)X#pT2bq1g;a3@V*EjV=XR@2Yg-U$pq|!Es1D0tYdibqbHU`;eFU} zryFr1k9je~%~-H+ZO@g?QbNn1*?~BBW=bxCfPV_B(oe3`^~Zk;<%F=!!n^Zv6KS7! z-0|$S3Pxe?Z?^u?Ng(+La3!c#mCA*i_|vqL{3cN!{~y1}ZMfIUu}Z*5hHK59+)+d4 z8o9`S{*;Pj?RR*yu>Jw{E1GAkUwlC!hp`hVHiDaFKndUMwRYKr4a3bK0{QrIBkN%Y zLl)xn7slR7Th})3c=b^@_&ppK2hs(wC24yV%%i0*ah-T8xE$#FIdu8{_E`Kv#5rWX z?Be2NtLJIC^r_@io!<-2A_7^*B;dL(2f(LZYON55#+nf&9Nibu`1vavNv0y~t2ye`CFzVD1qk7AR|K+>-$E9F|CvDIz(Wz{`93 zC>=wEs<4J&6huE%0Ug)_?M>*J?V_wpSy=ktjMFCNze&*gNLe9>>5Hu_y8hVC2iKm7 zAENjW3RZvj=A<>P(ON`z;tI%QA6O)z-)z;k-z&(faWL9wd_F#Tm{pn0_cm`P*TTM6 z$5CVfZmDFG+~J?rT<#J2P5}QZ&Gu1LP?X;bA`N8i?{+0lURL>Wr1KZD6-;T{>yt)s z@P3b;Ef!zh9)X&en?#-le`%cLdD|Y0r?AZ@9ra^KAvge;agtDTS@+!8gt&Y9@En|t z;g}b8hGvozEBm%VQuF(|P}V508EH*nEd#iZA~gx0rWNVWkMGGv4vz(ur3NLr^8j4! zI;IBhrn2^%lx#uN)5>qVFLJN&f(vBWu$hYK^>~mfgDhqq#ol@XjIC~dSn&{J0UR@T z%ke@rKNuhcmHdaR6XKD4q9!ynjR_ghjKAUFeQ7C zY^dLFjnouIpMfYJjMv>vQSchAN4gkYUO=~58YCa&w%8eB(sc;$Gg5?M5=KUWiHT{dK<*2HC+5Ot)m>DLb<1z;U} zDE8reM;zN`lv9uV5k_sK5DhzT$EeXye|#%){ZCiOOD53&EtZjX-2eX=%6=t;t9@DV z_pA5k?twKw^;8W)-CFT)D+2ign&~{jh`10>KwGN!ON?xiYHM7=PYaFnS1O3pVWcwKP%i z6+R@F+I?`fzwOqKZ$YEyEt#>l6EZz!yl56a8>M+@kSgC_UV7HS8Y;s4rQT&yG^n}5 z{EgW;0>94Ssxpkab=26?|JGwZc1Qv#+PWJxGs?;)^IMMycwoP6zq)*Ed%${9o4x*} ze4*pM*5$32R3G}+)W?sMS(AM7&HMX$9|wwFI}2)<1s$QSJ) za3BD{7P8|jl|nxJ>51N%O=?REz!;m!^fT}gj<8`U)k*o;*mZl&Wr^0*gQ}*rD##d& zb1m;tFVsB9{%z662Sh~_4taL7k?)rGF-MICVbFgY9~*)`HxHzMDZ8&UpGOiPA49?~ zGi_zFHD38cx<>(org>WMff`aZ7CWY+H>3qH3jj1Be_DTOvZRPFThscuO08Apqmw60 zIEV)_6R>n_M?v{3%rms3kKY2Aq^~U;4~I1o+!+9xCXUrU&DjNg<%UU;7b*`T0fzf4IL%!MA*d*@*OFop(J5#J|!%Od-8Y_DxBr1A-%7*t<%)oU)jwBj0Nte zQWsWwJq}Jh0p@VjA4_8L_Wv#iq6L_&Vq1OVOsyCmyig>2p;#Q_rPnlm{Q)Jt){Fbi zm5zII4tuQ_K_4XG|G~#+GcyoveD`D>2cciCu5PXtX|7(+Y_^Fgdz2iorfI^aXTOwd z9tx>tKFqoh*O1XX2*7;qp>^sI^D7 zo=dFbbE4w1l<%kK^BeHji#o>2*HeGmG@GqN`Werxji?`Vo+E3S7#U!@kG0m2WhaI! zB2FwKf>OOu&&9*7=_9vSs=Kd~bVhB1QHVge_DZb;GC5O$fz!__-?1k(otoBR3gB+x zQ~pDLocD0|oaksrRHwTF4guV)Jx@ZJ6G{zZ=M};4@*1?xum}Uw@$8F?ENci zNIVvHv5D(sZ$Nvn=Ktv3x&VI;d)wmvOQYd7PmO!gpAkgMJ(YcijR!KD7D4QS=LiY+ zjMYh^m7A`#%Y_Wl*tIQWR9)>=_hP>1dq*dyk7=8l^L=6@@$KGRTZMc2@wFVIi&Ims zJ+<@S;fSaKTQ#@bvZ&wg zb~)lGdn4`)8I*h`wERqNAZzQRK~mO63ilL+&J^EU)BrxRO^8Nx#6;W-$z`wMg*QDP zb=~SZ+(Vcv8J?gKa=uHq>pd}KOvaq4`8T02gji;51(0CBdU03JfE65EZ=?$&jwGwi zdOflwT1O}yUS{OvZTA8q2F+mBc{y%l37c($(wdSz69_#lng;02>_SH|DOQzjHKP6BPDHy9 zCJX&;KfhrYqJD>GoeZv;Lvi}AD_D|kq|}I8zIPRB(V*n-ulWX?-T@g?!0q54qJR9TAgGagc8f2{gQHbf2QcrBM}^zM@Yj?%^Zi0djX zG=`v5NqEkK#p>m*9Y0>Rt3*ERggCt>HzHCo%kTQ+ROF*ba*dVl?6NGGbB`z00b@sD z+aH5{B7zeUUGF|9>|a8YHG0%u-Ue(cdcCOiHoQ6?&o5|2&gl{Hs_cSQthaE2(9c;6 zo^7I3wSYHi3~BL2`cRD?rFOn@#0}{O^2D(C8euZ&9>hC> zeWa_o(++dfgIL2viB@x!9@^{4`zMZ)yP0Yo$(oSzXpvs?Tgmckn%+)ffxfq5`R|;; zsSXqV{;}Mcu#lwB4<^hQ+n$XU8Z*C)ZYz0p_5R(1;D3EW$1QvX-=~RB03T(d*j|&a z|HOE&Ez=i^MsBls=DRKKUHMxMeaIQaBG3zE$8ROSyrC8SZix=7-(&H+Q|P>lAA$MIrpQq4p&J#=Mcw14=dbAsCqWB`{bqp30*57m%Rr#XgcBxyvAMCr5{d?H}XV{ z$3fC<$Jw9h4_|-sJZ9)F%~y8~fGi_bnxs@t5Rmv=ZxFa#W6e9n8y6NI!wic@^u?x$ z6S?#)naKjQiMCzLur`7-9&%SgFg!x``$~p`7>iB}>M6HgD6Q_jxusER;SZ~C|GYG1 z0V3ASIo~*C0WvQH7yiT>Im56C*=}ze$WcS{@pyd`_w7H-QBUR^&dQZCp2jbDGxAU6 zWCr1M*Q>us^rd0dg2NMI2MQ>Voi~?Odd_~?0U8(d%Qu;46!r79-%O0EmAB9ZP_vZS zSUsq6YNMdXY5sdsG$pC}@)`EB{?E@t{wL;uhf!f1rJe& zv}spf*hIDXtMrFJD2{fpy6$zQm=B5eCv8>`qv5V7%x5Jef4sGK{2 zjEZAraV*9^cxyi6;BWgvMn1%SVjK$a+>@^*u3r0H4h)56>;?zcOubZ%*1q~VpJvF8 z;5pa-H81-6Wle7v<G7@G>ix2dWpk%`!HiuM%&uCjTfoC)P{;@a$CQS+PJO!!MhWNF`kY0L4Pj z=xCr4opA%Sv+@Xozq$GDl{6zpG3f! zHZtJ#%PFaopj?Mxmw#KD66>0^2|u#=g?pufQ`%iSsedfjd|sjyxGAf?{?mqm|5o3d z)IPoEF{TV>|JHC)g4Tyr&Lb7+%^vaBpC(DZt@^ll8++G>sSSU;`?+vS zNjtAO%kR}}5QpH`cfN{ycN_lrh`YX(CdxQfR~Gr=&sf#dF8Y z%JK8mef=HMFLhMEwRO^iyEXf5?WctpaZnixzPSKWYftTewiV{ZKR{m5gE^ZyiV)&3 z1+2nnx`zhH3hS*D${WqabZ}cus|{K?)Cz_hH>M=#ScpG^)m&vj_DPX6^=}g0Fd}} zgMmRDqUPT57wHndJ$k_nhvXM1SGv>+r4O9X<@-Bta8lSg5G23HX0VO4To}C|g7P$` zx{<3|fZhR=Uqr&&Z$P;DHPN~G&TV){e4eYWV8vm#4Wn_#+uP{8J8YlM1FjdZT6V_H z5Yw)?Uj|KlYWeMyr;UW>we8f5R8j>49M045Gj(cGmB!ujRwcWH%hV=Yh1%4|SqTs# z|Ea7e%f^0r3I8Kr;6s|HeR9GH)5&Nmx-e}fB(+@gmC*PR_n_1#iPy#O4a;N6O^gOX z^=AT6v|s-9(kL->%rzwTH_n_ST-PPQ{$Q-4Zor%al+mD5BUEKS@~VL9OSPWEGDVSuFK^h?viMyDWXWu!q@ zd{x{X`PGYd_3jbj5GTC$g)k%4%p1K)Z86q;hG#2;1o;SoGO%9k6-x5#b7JjH6Bbk? z(_P7sly^UhR#@IlB^xJd(WzZmd!p&`QD;e-3=cfPNF zHD8RCP%oy=+$FTGxzAvBLt^4h5SvnsBwP0`St-L*8>HCP$U%NwI=AQRA>|a;)eR69 ziZ{$Gx61E>i_1JLuo+|G;5kUSpV0M~SoM(*HC{sw3N1F6k5@0FM#qa;psM_m4ee}i zQXBi5Ve1#VK7Tv}2Se@bbLebBvDaKX1>-?+@YM|L5(YwnZ2uWZo1;bI-nKz$BBRNQ zyB(t-2%2GO+oU89Jh)x`6l>jLzfz*dKK1ts+gE8CRNOe}YD69S?$gwdI4{kSPNe}n z4upjb7Eq8YSO5swc!^FC^CMaxMM8PQ#ybL9(T)ydjTyN^e5Z6dl&~L-tVVPNuwOk! z$1}q+-Yzywnux>#GGEX73SUffMQb!(sftLAGAjFp$5MG?u03_c5ep5kv)%kb% zVx{I^qZR(;|Ew{_NG6wy)(gq*@}|{``lFtg8hnyNPg>4^^7ctVg}M)q;w*Z>s1R7X`xy})O|6tbbus?*YRxaV0O(bmw{R{?{# zikvjJPn@`=?>PHHzMK^xY=XQ#9b;%{w2m-5G$$k1;y6LUc;2=G3qDzg`9pm8-G{?+ z;Axmr=2N81*^z|mR6?>^sUM?p4$GS;Qg>3YlYKXWXeh*c^v_;hf3I+=&8BgSVs!G- zo%WcYcsCp{deHdxUN-3!QuAMso{V34cmA$VpR1bm%}?vEq`+#`P<;U_;97awaiYyO zoFw``v2_uEu7Qg!we6Q1YVL92!tu9qgo-7f%%MRzBD=$1e1c@6Z9W%LA*y18Cd956 z9oT;VO*?=Xgi8qW!gn0K?&^6N8a;4Hsa8_Da~6~mNvU!xKW<=N1^=pgU_j;|_`1)P@^m5v^_lR_L^3zm9G_wM~4csYJ9WTj3`0s#Z zxLSxC%}G5Ds?zyx#NKR=lGqia<3gs%Y1YcSYZsnJTMXIwZ(~1g4DJ8gbdm+`Kd4*u zV&xZfPc!t-=!>{FWgORh;SiKx<dtv9pq6pjo+mNUwhxY{f1C~nf+EU-yZ>YlB*c_IR{ZuoT;S1&AZv`n`p4_~SxoD) znal>gB@9_M{ntW7Ds`(z%6vg@%TVi-neog?p{dOCgGB>>790ST|{zIK;<_^|fO|TVw(2CzN z?m%K7Nlw0#p;`k?6kE#ac73bWD(VYa5>AXX*iR6K7kGg$meiWRsU3Xa6dXO~@hXRp zWf*nli9L0fd`@Lf+ag!W)SX%Mj66-g;Xnm%=%51Bi&Rx}*9nOZH@AP={!`vODR1{# zVO>EU79bmm%ChrbOwmIFjhmLs4j$S8-{0|D3BQu{Oo#qR|9by@?^rqAh_!l#>^}Wz zVxUf%$$8l8RSudZj&Y&#Bm9B|DvA4BFr0ZBUY`Jyuskev+HlknUK&9Q9DiK89T+wLNT z`O2ye`3=6-eZRd#TqIRagkF}r4$x<7_DLXX*IJ&Pffp`I7s$)c8OOHBdcxfKCQ^i! zanw(Cf-3M!r4br*zT{u|uNF6KY~`}R$shhV?v>6KM;Ct80|$Jvj-m07}t0*ZhyO zSIl`cr*cFW?m_L6@Ec(44j zHBVg-lXc1yJh27L9r_eI(%6@B987QC)#9(lejiZq8I842Tfx=ii72HF7a3PUg0m_M z{-}(a`E-aDk@+L?_9gu#uxF`O@0TpM`6y)_7;Xkdx)7AY;qOIS7lHakuccA!1wAc% z*C0Qiz2w(rW?<3lMlvqAZF;)8hrI}U2!<#!I&L6RuG^=%9sfRB|-;N zjlx%;N<+85cPG)UBQ}Q@o+};;&OXm%=Bd==sVcf`-Epmt$as~ZPzf$F*-@CGR{pn8 z>qj~JnyxR3No!u%nr#H&~8DI^j@JUDUUjuW$2bb~`P`5wwi-22t!VXOL_2+~!qZy3^pynq{wTWws%MOEYEU3ozDrg;0I>O@N8Y z{*@d08Ahd-GsB5kZhx}I8es$Xk&0a+fmd#*{`#}sZY6w@&nd&Nx4-sBQNC@cTB#^Kg~4nauB zr=JQLU09N@!)7KcQMJ$9@0l-&TWWTy8;d-F;}%`kVP=D!u&#->2!cs%GUw9ZFC$zRdYwwT~IHzpd|hZ}_iZVP@CfZMdG$NI)=1$H%gQ4IHoTd?Cv;mfkT&jx@q}_*G%j7L3C?GPs9oy_RsRWzC1~=I5BSF z7G)uAbs1mpU#DAupEcWgfr{>IqMxCxL!61p<;2L@_x0z6hqgU0^6n8dsRzLI`FS>6 zLI{-w%U?#9YZJ=7N)-U1as2jx<^C$Cy;0{-hz-F!fUzD`*|xS`er72+M>&{PP7HbLI~{l(3v$CIIun`$DHCpE*Rol3i<>s>KP?|uR0 z2LBqjj(2TVUez5N=0?>o2pWI3O1N-r><_P)=h$IDJ%iq}d@$S&4LAKxXt)&?UJ|ed z{M9!fp!neOTE+L@*ws`nX~I2oJw*n?S6}#n;X?SeZ=nX)qvoWx<{CG<5(?Uu5-1%@ z$z<63=zd+CL$66FXtKJM&FiR|r0@?^3r%`&(0(9(V(QybFfm`zjBUN!xX2@dbAHUH z{PzS(z61T`q3_g~a^Xrg^*gK5UW%E!w^z&DjW=yalMSg32(v7#zc~_%9SZTbKtTXr zF9+yDmwF5Kr_mf_i8%o+yh<{<@NV6(?kq+IL$7ur3j<9j4UW36tf4wU@{s8Aov$}I z|EUFrDR&uDIJ94S$-x=@bHj?zLNFH*O^P zzW%ApW9N5zwCT>_ro*pU#(JcjJ*DUpVzg{Iyht>M5}fTk#~DK<^0$7IY~%ckeV>o` zSR{sTBv{Ajc{GY;b1ycA+7DOwXV}PUeE6R(aE!Vo`*}gKv-`aT-#MfXBH=pKUGUPn z`+?ra*cFop60oFu?sq14_sA9=?KqswoZHcx1?)S|-jI>#hhQMDi*C^0Jx6+yKj+ER z>-T(iumd?+^)Gxrw}R}8({zw{5&x&+g04-*8;}gBoyWyJS%gcR++Bn zvsV7_&Dc3yu(%!fERB|Mv57|voM%LcD<3esc1phD(yb;y+nv{6#*Z<>*xovuOe29d zqC|h?&XsT_zbZ$yXjTWDcn+evxj>4PevrkLKfitd&Hn z-2`o|t!z(n31ztT;KDd3N*hWTz{f?DR48%%pin7VyyDN~nNTYwTsQC4>gQMFj)!)~ zHFqwYdqg%r24RROXX*Hb$xt1Nn2+Fvg`s9o*`U{!W+oj~N;_ zd8ylcm8Q_2_~R2JQipTqD_%;IB@*2Q4~bBs+*V8HqLIm(Jr}BU9-ei;mv*&mccCLT zD=D|)Q4%of>_;l)T!769YALLc#n%z=yNr9_(j4fLBt9R>|bbI5U#~t+;1<@=tD%YS3 z=wke0!EIV;LbAgJ(aQIP=p{PMm~n{!(bVc2T}MtEt5w7$mfQs%r}&Wb5i% z*mU=+b!Xew%EiMA$2Y)$lkN)>if6s*&JcRumIE#BEEf~{Dh{m#JhL&>L*LMx`-U*R z3z3p=!fH(VLJg+9;Mq4ift65pso0w|3LIK=!b?{d*U}J>=VF4*x2Vm{g4jJQ@1|K$T_O>0eu#`S^%pS_5q&@j z*k3zLLa;FrkE=)YGYy3+Cd{%;TYgU|%)MjybB&>T@{73W89~H`?7aaKtnovy6{X2w zQqsT}{W~N?m;OpbfqS}RgzPybxb^nl*5$0-lT%xF49gWY<&x#lM)R22VMu!(#O{?d34^y@<|CK&ME6M z$rjK|8KvDdVpWg{ySO+T)_>gX`NAu$=}ae>dGLG>aflM1)Hq zp0EYDgX1Ml)sR1!gg`7FQrPh#^f^S3Z)ZA!=F?WK{3}yak3?zMzi1( zux&1DUk^M$!!PM|V;A%i<&X>T_OQ#>2W@l1)O; zzv9s*RTWv)Gx`ruHNvlX%vcXRS%;Bb+lrhSR@RrlXmoBV>KJrG{9&O**w_dJXCV(c z)+$AR=>=G4zwdfo&gGQVR!dhAg9BL@raKjy!3i)#M-mIjyTO_8`k~O?r?kjc!31E; z)|+ymueo#m7w2Pf!Gx|LG&1c~H5PGgqbExU^6rB`_nP?NT?RK2x~sk7B5R zn2QP?DYgA>P}PjcLfOLAb?tG$IO2!^-McX%#J#dnW8HVWS&F06H~2X!@LP6gw|X9r zc8yp!vgMf(Qc!A0(TcCDxFl|iFr{|elrhqtog|lOhhB|4hF{ANN*-Z0F!&;%)4$(- zLE?M8-jaD(+`o#GfaRp^CbJlnx1&> zRh)INTz85Z73(tJW=swLJxzkThl;w>4c-XeM?;+iJORBxSY)9)$h zQ8EO7T2p8S<=$bkt>4n-)1z5@jYk=k(8uVh@;;Bl>Ra^os%nV=E`Kp#8t ztj}J}TV}96aoK9Y{~C%e{sJ?-xf7B8AJM+QJu<@uO3$njsN58N8*z539 zP?AlzOK~2C72e%U;m2Qep`!_sP3*C7b=5g?q~4$1;3t5QBs9- zErS#W!H(lFmv7%-u~gtU58i3f+Z$UXPG2a$vUZ`bL+*^Md`2C1Hbx&8N;f5IFbm?} zvL>9z&>dY{VJQlIFrA2)zE4JxH+l#PK5lel)8GoBUg}xx1#t^R{yVLls~r1`cPb*_ z-sc`QZkpf3Ud)kwcl_NJ^l&nR`+F>2(I;9|gX;KZI|U)MTcJ2FZlFX^a)MOXQuXNU z{x=7OW(*^1$OVaRa-5*H^)zzmJ*38%oIl0=$pd`|v>&)pw%qyldj!$tU)X`FqS~Bq(E#2;66hg zQno%30+R(bUtiy-R3z$<11Vc&Yowtfj*?t*iJ zVeJ*^k&au(nxu@J;KJu=<-I)cy{fxC(pTLm?e&TK=ZC(Fg2~|;)1ayxs;QF^d4WNy zvw9o-4Oi>Zc;w0}qI=dQ>NB9(|JrUkJnVc*{$KQ{xt5W)>^t&8!23S!e!F!D*&i|6gZ#7-Qu+?mON3WX=y*{xe7G1^_fA7c3 zC9O8wavtvNqCc|{l=Kf_iesn@zCtDfxQe0Nh``)wZl5Eh!>0Evm2ct$)9MjoZ>_sv z@xk@mqmncG)ji_5Q@Me>#d!reflZRLFU!+DR0diVc9_;h)=*TZV;XL z^7~SQx}9TXOOI^8O7pP$jEjy$p?qhk;lxC-+iOno=#j-?C?GKT<$tmEmSItSZ`i0H zAs`^#Al)D!B?y9qfTVPHNOv=Ir?ep5jUWw!bR*r2v~<3(JY#J9|y3l`%xMf(Z?u3$qDefP@QHGHQH%>155)j zYw(^v^-L&se3QhF*@&jnU~_b2>d;B)KMPF2Qtcf^q!~% zfj2IPqr{yYTz7uKl|pC`Th^n1`%yKTUPQ40Y>YzL^H0o7Y# zZl54T=Gk$1nc#KZ{rwj`lJI*vFvu(H>z;*+kFDGq=$#OcUFrr|K2@g9XYnR$0CfI* zz4=6p1r{B2b|6W~HuKyvs<>V49%IO)aY%F^VLZp_Bj`hrJ*eHa{a!_Y38be>BS!J^ z>VDc!Ep?+DsR47%YIz0177oL}>r{Jq_fX$~tyz$_Nh)l3pt<6U!Y|jiiik)|K->KO z?l#`NpUSx>GfUr#mSv}qf2ZE0t>7ajQJg!jReY$qpuXvfFIPv=kRu` zOpI<`afrIQ?q`4xP2BSSNInZ$%esS+qY}#tzKK@6@%mD$U~Fa?e{tl;7d9Rr>E^(f6h89I21JDqCvn z9(B$zdx{WLjD&2!S07eT%n6aq%v)1+Ao0s)cO1h&SGE#Nlm$1!6h2vo$X~aV$0^GY z^vDSH%VB5^I>A`w1NN`MfB9|M`h2vW%UWuY;Y9}i{`fGJ>Lzj*pY{83juck-r%nxl z=&>{e!7{SON7KZ6-7ya6Dp9V4%i!HG_Z$v@^CHKFvgcAT54Y}mdh?CsY{%fHF&l|X z?H!pTZ`+^_E#P?ZWRZjs1p0^auT=|i`4kuL?I^Temj4fU$Fvt2JWx-7_&qiba!q{J;7&$H-;cE2qxul#3*P+M(5F5_!c<=05|9 zF+GV=KP8+3Nq_HuKd5cNL^bCX0v~z-`aj8yl*(=mN27eTx@Bp*!4hFC+aK1dUl&76 zN*XbGuug}%GM3(x#1oG^{|j6|kvrN1ZCf%S{I#;JyZU-Sp5q^(qG2Ao#4cYo+~yXn z2S1nOLr5S_kOH{v7e#Hj)2_qvA9s@MZ+oS1>`1NM>%dX5J; zmEF_}!0eCpCBG2uVTXq}VbqdNViz=WP|~Z^4+?R)?%s+tI44-NuWKX>5~In+8CPV9 z;&(?p(HsMNnY!m_RNt}U7!=o;x4plEHWHMElL}f=<8BBpS?iJ%v(65j6;(f!9QU!C zU{!p$Bmk~qygl1xF3(j^6w9M!A#Oxf-1aClqpZ29g`AziJk-~l9>dSKI&#h;R{#9! zw{F;Ko6@fi7v0b8#~M7Cc?1npWwPFki+tF^X`wioGkVuj&lSypI<-ggC&K*<%}D%V z$faNM44v=vGByGIo#={EDDF5QSW((_dM4i=m?Tc(wfvQ_g7m3+))@^X+FlRsmta)Q7Bo`9NV|g$8EP7xt{0-)OgVEMPD*fuZKV1M}$2|>A zPn3R>8(et9cH<8mZM_+d#?C@VZam+zKRQdoVWM=aaJb-z@5(tc+u1lbe78tYaJkdCm-9hulRUzU;31e ze<3>TBR7qbVqD2Bv_@@Ljv6j5pkH{y*UX|a?i4z<(HjrtbfdpAfd| zryzPQQHyxgaCcvH53@}DWP@k#SE`pJNtu3uR|C2@ZDd66H;ja@m}Z-*qbsKJ zg?J=?rEZM$;}@AdFRIeztoT#=I&a)8`Qw({K(XtNhP=9wExv!fm`=B=UN<7Od;?>l z&6{);BE*wm_1haJxGDdSyF#V>Z!ivKhiHLA(}N#BK%BGjpY3qhUq@|69`+}_|1tv% z5f6}Q=&R;4$_b}{!J@Vtw9KlH0-o@jVl9#6R4m! z-x9_(5l2@xz>Xc9wSeO|(Vq@ab=!;Dak5gmAx-qT7PMS~`dHErmcC`Y?5l+5+p=aJ z<|5s>uYH;|NI=x^2m{kPL08PMB`wo?iq(@~sSa7}Rtg{D-M2KMglZv01gt;aiFZ9A z$ROwEtrUmSLqd!RAd%wPVxan=FiACv)tw=L8*-?nuYrLzv zc}R*(n6*NRX4`nyPD-XHSTg3^zcE%3_YAl8J_oqB9kq(I+p;nPZ+_fMVjOVkRL#66 z=C9gJ;HQ0PJ$2J=2F3r}0Z#sXfvbuNAu)Z@A$yBittvxZ>4p)}ZZb=o2jNR*NgB{E ze_XD3c6{9TnjcxEUa5~*>c@Xwqp*r+ZKtr7Vof?H+vf<#c@md>ND3E92T4TxlCudR z3_hm*mVoA&{-D}cjmJJ%Q7DqTfcLL?1|h_}b(0$Ax8vjpWgn&;5Mw1g)ENH#U9N`^ z;HPVh^NBu^GhAHc)_5{i{bA-sRVrY!F4K5dzW5@jvogo`R8kg9Z`9YSlYW5r=B0cJQQrb9(BMJeRvlb4q5ffhst-cL_CR zBc}W%&iS@*BOO3hcOT`VpK0+m5xAFpkl1ai0(tzcFAecGZUH=$Ic31UcJ_ zrtKdk#kyH|IWLzt$1glWydiKVAy?<_YqKtY$?%N>S~EVLphY(=C@Y2ZrhLAS9Q0`1 z85<5}>>2f5wl2-RE02AM)$iKtmVrd;ay|U;(0Lc>C@X<&eO83u3+9;fYIl)3SNoNGr=E zlcpz$>hK`#<^kwZu@gj!h=$KJvs3L0>E(R_Uo@%Elp9Qw27xjS}Xh05ZLT z58yds+=Y5@@amIrx0n_AQ=?&;F}7BLZTNCqcs!ZD55fCRQZT?wrv|&nUxM63kf7Wn z%qVd1q=HllQ&s+=Dl$ZBI$GrZ!1Wa91r01KgtYP`7-S~ay12XT$z6gG8UB5^(56f9 zQr=oj3};4m1faSET-Sq%6?hu|^=Y7`CPeeZaG~g1J-G0`5Z?F98!u{fvA9m~x^ zw)Q^NQy2AXmTHG#NxV(+L+oMx_w6~N+-LpX1pm7Xpn>vWUFfX$o-Ut+u?>b~%aK&8SKfL!QOb!=lWVIA+HQhi;{CGls(y#Pq7%niK%Q3c692-dga z6z?tA82!bstLv8E_K7bePdX+E>MQznSstKr z9N@8R3l~iHWZ7lTF&kD9*o~G@L%%yGGm&j~dvc%CAe9t|K+{uMX$z;+sASWy>I;jX z`nO_S*N~dDW&NSOGwsD-8@FhbDkK1pT?FR(=J2tL2EVg0nU9L>Kxrc^^Jrwwe1#H{Nun-&Pnd>l~A|`qgm^ zMi=_HTiEvgaLr_a-;HQ7cM+NNUB!rSruPu?LGm;`_zvj~2`^(gMbYQqU$8{ z|5Vm8KB#?0{K=(>qb&chMY&baQ0bUR%{c+Ru!nFaJJ_Z|$664+DHIUVhgt~mFLy?Bgl zUQ29z<*n-`)t(oQow(l!A1*;`4%0O822zaN?{nhLBFShz{ z>=TPvjoCCb`QY+Z{Qd+ojXj^VmS-Z4vw9;1wNts-K}E^Xee%7O|7*L8(e`|-Mt*~n zrdbf+SmxJyY_(kge5qPImd9(vioJi9}DPxx=vF^6eI|<#1w`C0@1cSc!YoCO){m^_}s&}DDSu~a2 z$`CR@P6aA*YWS{iH(KWVP%?fanCBXPGE`c&gY__t_Y3~jS$xj)5p%iuBvg5vuJNw} zB%f)5uNBJ)SwSRcU^19eGM+&8v%{jY43Y_UlwQpO)A_pm#o%W!$64Qe_bO)#Isc4t z*%uXN627T=S{DZoQL7|=Qd(T&dv26`m!L?>b<)$Pv8Ocn^e&jwVeVI$pS?~cLpmXd zuv!~XC#uK3-yAj&$k_aRQei9+WV*imCoQ+m>PKvjp$;4_WQnSU!0f{wKlWkdWzM?h zAA^E0PM;4;;e?E4_yX~3+V54J5-u0lRxWG86#LuzOI-hX^MFE$Ubz%pU@jM*aPQH- z_XjQ(Z@+eVo?Z?2DdeWSF=4obp2XD`D(}Q=%8{CSZmOJloAW4%eo-MHwTW+g7PVu{ z697;zJqBN7(g-P)@)7P+0Vnpcs;Vxi(zfg^?_I|?CqZFPUN5TaJBrd`Z$2XuDnVZ! zID?FArxKLD;wS$+d@85X9K3oxbv_DAY>`E>y1bfM0@@ZqxS$o+xNKvfe`b2@divE} zla_1K_*aVK={HgxkS4^~Z_gLOygiQ?Zy)1%ZzMB{Se?$C+a#RM`t|Ux(-T2oV^vuv z)&h_?Ck(d=5`gjBYCv7vtJYl#dZg}GzQ>osz`q7W$})22a~EP2A_^^g&$gfP1}V;1&*k_}v)=zhC{m z!0RqB0voyl(?wZLhfwPB0$2B}RD&SUN%Z7gKmIBsSH}pdY4Plvo_*mA@UAt>r~5O^ zycarug?nt%U9VNM!HMB8gvD|__`+K$Cj*4*{_)huOP}AQ2aUD2!6-bKazC}M@>JCz zbEDzR;vCcivI$ePoI#TcO{58nh|cbX%-z%w<~|$D9fV-Xe89a{Sen0EGR%(LTOu!E z`M`%m@Gaw-u>ZSyHZuYJj7B7-s*hu zzih(wP)!|_gt%u9>c4(H*%!yd;I_Xgv-c!Vg_2`H-r<8^D8-=f%GOl)$9C1Y7o7oe zfVd|UX5}UVrH(q|jWU@?y7hR-LGg#J$}%rDtigcY*)Bdvx6~N1gxJY*A>xTye#*yW zyhn`R0mZjKD5eB`8ner*n4+RDzJ%uS3Oa?<{T}CU2g_MSP$HAG_lB%uRX@m>VjIx# zFf+g2&eBP&r)(MdNA`Z0i4e}a4_Y(AkHS*ZOQH6=HIL(AW2LV2;=q|WLe1|sru?bv z8dp0JmgcwXd>0-59Ll+7av8Qq&NX88h3mdRmv%=}63D*@OB4ERNi2%!zpx0>;_4&& zH*}wPV-O15Tu*N`2$gdhFrt*O6Jg4U#lL9t8Kvu2kmEldxrtEDvDW44 zH+LT>yx)?~kKM>UFQgS}Uj}?|TApIK8%HA9YbS=2$1nM6?%Y}E=_re{uMY5Iucr$G zQdYdvu_>cnt}^$zw$|_efN!D_>;ZJLEV?^&f3h`&E4_W6oyZmjUFM&^!7GO%ykteTg+a{N@H=9?zb{B*o6Iagk(J)wL-TeS3~{uagX?zlCSr<_!i+l`;}6=k?iSf&}Q<;z&^ ze5;Bze40xvtQh_L_5)K3h%=XC^MH4a7)tdWnrI@*)vD;^-_Q%fTwmP5GMk1hDce~h zVggY4@A-(zBRhcy8Ds`U7&ylE6SW2A=8{;w#lWJM)5JBfG)hiT za%g!%fX~mCN5ULacfXH-1DAd`xIR$)Tr2pB;R#_K87j>XyS@)?U5@RLMKt^0T@V3_ zPIM`QL(IZFlgtc!MZ|gHx7zD%19CBHGcxUFv5zeCXymvu^I4$X3~UL8)P7hKrW5Ly z^pZAg{b3e^y&EY(nq zAu6%_{9!_WUy(mBB`__%rQziFxEB0vnty34gUs2+0=BG)GSqqAjQ;k^@+1l=5w!Ht zU?#oOpYo7g5FuRw?#lGa%l=SL;b6!^IrQ>u>KWoHj@1gifRf{pPd)_r8>EKc!B2WZ z^s}hMMzlu}x^_5MOnH#?!ud{=lkA1$-&S%`!gd9%I$(&ZhQ=>~c=6{4Dqr<4}IZ zVEE&wqSgEJm@Dr?crZToDV}c8!WWZ3(a8JUaek z9Sk(84I)IH7k=w``fZhMVYIpGZoT|XSQW|5|0v5Vpzt>MPc*`tc9GsGLQw?*XzK?Z zzS)jfkz=2AdI!+`84|t@7GjI>K`E$wE{HwyF3R=O3!n17#eI1Zv>GcLR418p3`ds9 z`)4v71nvJyZMWm9X8{P3j2q<|JuQ5@9mh@G5^n&?gFp(D46;U$02}x(y-kS+Ba4<1T`?MLHy*7YsfJ`JS;5DIdTf+XWl0Bc@Fa zy)cny5E%r+RF-^92h#Tb3tV*Fbd5dpMasNsm;`l`Wx0~CCy;>Yz5zG=Y#JMMBI(bS z|4R$qOi41GiU9JkcGlG~%}Og)Se**_@Skixaka^(Tn}VJz_}p8dQ{TukSTiE4tZ`H zi@3)M61aY{AXskW5*bl}NV14QgYsUjd=D<37KcuL;6B!R@*>)UXd?O>jS;i<&Sgt@ zT0K|$R&I%aXPcGp4)=YT_rT_I^SaIbDG|p(UD;KpIJgmE5>#m)?6&h$db8cLE;^$enyj1!=zMU>bX+ndYFE;7e_mFnFOu77?Ex(c3C=0$=uOx9Gta3F` zNY7A3wqn<`c~ZDz{~B{(>(uWzf|Bn-p0Hw9q$0vVW1fSfY}Z@HBjl8yNiL7AU>U2( zi06PS?tzCrGI^U1Lsm)X_9Y!K!C}Rf$LLaHI{oO)Q%*#X_S0k2P z_FtYFmVKko8+<=)2m;9-BtwbX3-lATtAo?2=CVIvZ z!?WY&Wy{^O9pbUF*T0K-wJzy5Y-c60b29wR=6>qhGs)PriDs5ofOanf8(-rJY9s=| zbEZjFlUl*ADuvX5iQ-Q=g$E{nj5qIysz~*|e*4IL5C!j1*m-0qP`T21Ar z(`~JgC$`*x)fX4LZByr9sqQ3v`P02-f2PX45JGl=_*;U-x*tlZqF)=QMwQT-d=>6Ew?q_CoO=E2D`Lm4*pSu z{QI97vMoSGz@2}&DG)w7t{oIs?2BKH9u3QvOJh!Egxw&XaI+lnoV zRaS~i`(W;r6Ah_K8CQVUXX9IkxSS`xt^VHbb{5Ioj3bwPZ>564GRCxxzHPglV=R=A zpF6it*GXc>zRieKjd)m>OXm#U@@uYyYLGDPl`msp<$Ih2#w& z<0oVjr&+brOQ(>s zE7ZaVsm_S!dve{b)9=T8auY7S=rqrpN`w%tA>UV2imVqK+=9ZGN*O392?{nss~!TM z@)tUvZ(49FYLA=u%v=YR=P~w)od<=pnIeJ5qZ+5&3y|-r|9N2ei;50d1k;O|^I+vd zd&f1P*>13JJ_Uh;2 z0AX0TVAHXx!HO^hVOj{B|Ad#d(SS_14?`&SK)jl2NueBHk3j)ZX<$iFjMJwu4g+C` zPj>?jp2f^rNjt?J@56`P!r?sJgYErOZ)i_l5?H7!oyF|{ib4-Or5;;ip0_gMrA!xo z0>Vy#_ir6&W?IOwv&JX=Ox&F4YIrAe9{H=(7qa88Y-?qRa^uMf3vE7R<4IpHj_=VFpDPhsaPs!W_xU(qGX z#FLdmJjdq>i);`k^mRY^gM1pjd+nA=liF55)OOHGE z{7H!#{Nqh9)XOUNGK!ttcW2gy%_6-YtChcypM~D$*{8QWb@^DL@1(34_FR+)LfHtl z(cch3K>%EJE843~kW7rjw?P72#CNyinDYnLyHSAsQPmz!3sbl@Sib%mAuDbN8V1H< zY(Bt=9DEnt5-Na7oA?NnmDY6B3%$uH8hrfboopkke$64v6Ewk4aQs--e|lATnsLLj z-nE?V6Bt@f-N=RAWabDV+qJ4N4-Kiaim@yG!bd?Ix~(WXot0*o#B5?QaZbs4$sYUm zisg_C8lmpK_9%o@4+-|QXoL3LnD;@3S=&ChQ1j5|#nW9ok0<$_f{4E)RkW}d`aQd$ z^*K3oxm#vWCX4B(pZi{2Pdp_KhmI+}?ag2D+;MBZ0bP~vl<^B^a#H^jw1&~mzjG== zHHoBnp*lEZC2?q=*D#iaeWn2(x@gT^r#=&~MO7I#6;BQkx9-PUir^5!s=8cK4joU( zwKO3+N_dp+Cit;FMkC5TE5|GvQw*diSNGrb1^ldSPI^s7o4!8Ar)i|P7PmPWMJ1Iw zbf1kZA_&jmg`6_y05x#loIjEi0{4b_zxvoLzwGjE3l*V%-CM1CQC;*HFyi&F&>9Yg z1dGZ>GZJJYt6}^rZXz=rEX`55l7w1~1SoHPm3~lVqDMI>R|3f?$Q>4w!(yYkWz6v9 zFm-6cc)~L>djl>4*M&p5QzOdPpntv4<1?}FjHoN(fYJ1rw7yozwF^0D29koMM1Bbu zWCbf}tR(niO0|P1-ReFzf|&fj-E2=jTru{j@%Jj0b;8$*mjzbAjQAOcRiNT$oHE zc+ll2Nc!+1W}5X4R3`^WO&E7$9@~;>_`ha~`wJxaK!s9O*SWJfOfUg=j#FNYpxI$8 zv8uY2Y%#*&YB2zr113(D%>Dm<8%3NfK{MVdp4iZP=Yn($e9_nEPb;o!<%ri4dy6jb zoA=Oct|9EV-ToooVopT~IUa)Z4O1A{X}T}mr5#syv7X;-Xp@?Ya*0AKJ~xm%{S=OR zTr&xZjL$t@#@N9WD*QT{Uv+D+RS<`C-*ku)y7J4IJXa+GEyc9C*;ewO>WCV^p$NYH zS!&j~amF0=_ciN`G6FXIho<%Uo&i^i10^Vb^2o$)=O@KU=@}*7s&jd`ai>N)jP8|I zY*}Y_LTaCjmtiRg5>{T0M>8)8~E*C-s_JD7ltK}GC_mgb-~d)ST%^RLavIl1%l2G@gQ zNd1$m*^gg3L>hu|M-*@jgj{5mIp`7V+Bg6ZK%@~FL?oE)%qmR%i9K0JUGTDx^^?(vBR2gJYhnyVuS=V+bI;ol!BZdsl=XRIN8Qkv7;e1adk6=7> zOGOAU*?@J+>L4w(=b}}(7?D(%*dBQBTY7C%QikSvXWL%?c;&Mc$;;{vw_jshX_fq2 zUKJTMpqYhOsjCm!_)+A%u2JL^Haom2$d3-9xh|YU92SIb7{NCN&@a`BnRAzUk4}Eb z{L=xq-V&*}t)pL{*j8O@XEYmMf6TulSmeJ4C0LM+f`L(ori7)C(X4$v&h+#GtlRSU z8&U^`p*b16r2D|o1({Ssg_S(Q2jKm+Y#xGX>$_a{H)|NDky>RW9V?v=OZ54Nt5eX5 zmT(+9c{(Hc@TIUFSF?{P?#JywU&2yFr~iG086iq9{a@G~Q_EJPNKF=a#$*EIzAEHT zaTBqs_*@aMFhcQcmJ0!NE`fjXaT;{;vk3c#TK@uS5GIfC)JKdEH&!<@q?A~vnOVDQ z3|bet6o)8cRr!k`ijqKUwh*xzCRP;}13p<3-P0S39I&Jjc>R*0ewp0O|C?4eGSK+s2) zNE=tN!o(b}Sq*xRkc|m$Gf4r_!fJYSBeY`f|DIL_hJz5dnHN|Nxvq?7BwQHlxK#N0 z+rxTp$=rvtJKWE{=#hY%O+m*IP)1^^gCRr_r>_)}kkVYAwUov{QYuTl<4ZU9I#VvoYZfOqKM@p_*9pZNC zAjQZI^x6cqkWxP?oXf;(m>k((-woH10-1b~DuaFB&jI`TMr=*&UrO5wH&O%RCX|gS z*XL%-#851+j)12mxeMRy{kHWkLAMnOL|mB-hA zv5xESMOT%+8=$&GjMzgA4?;h#<+2Q>SVzMidIS*yO^7^6)d+WsgM?NH{xldS*M=#a z5d^zD7~uhdxZ0sbBA*N0H3%Ds6O#;q?Dqh$d7IfcjOpx(JK)Ge(J{Mmsgm#R<&b+n z?D6|N{a>@%tTD2`hRp@CA^WxSF9c|oy}w^fO`V5HD%8Edln5izcRzcMjTE*73C;-V zDUQZcPtCrmtLfXkTvDkg*D-SU&+^+iU0o_A)U{l9F;bU5e*!xLs1`Wnfm=1D(KOO; zrpSX*cto&iX)AP*$}aerZm?%wE9ndjJs}$&Yfu~b1H8QI*3*4PH}3oe+dqbAQ>n{i z8Qjy9;o^jnZ;!QtmtqceCZCu711CLGRv@kQ)cmCkzyB=sXD_Bv@Z zx1DZ#1Ol2o9b#T9i#ezJMdRNtWHixpwyH+5wnP4NiMA+0dD{&3ySC6sdY4}?s4kTS53;HC2z#%%utBNj00_-U$$fz+Zd(E|h$?1D2Q%zKcB4a%DzP9_FP0dW<}H zN$-td2npCKb&}yzHB&bGG#$_@n)%kZ`+3b-#kyUV4VCAy+cVOz8HtdJUMF z>RpqLJ+cqcGg?%3Fv#!kK98`{Hvx?8>&vx=e9ybVE!O}6q#L7j?l%7xYdQwK#rqH# zagLR-y54}&px3kgld}0y_T?4$ug3a7Cz0@F@({~CJU`;@obCrkddsaOFK7zX?C-%c z57PD=d1N5%^6Tp<1p!>xse%Xj8(-qML#5BM=K<_J(-{RimEZ4{Te?0vs69P8x9-Vp zg|}eJcZnkmy%ZP;Oh6>&mIdU4<&37VFCo!(huhb`E6T2s$a3fYr#6Mh)tvK48`C9? z=KSQ0nan&LGB0jOTk{R17r+eI3A|O-)QLx5st3b`0#I%TO{9%(#_M}%X#HS%w)s%J zTLvOH;!jYSat~5XG8`#?g&P;$Jzll|=ujt81-GAOA3$+wjZRdzL-r`EYlHoqX&3eF z(;Ltn)}{rf*SE-OwgMg>bhb`gC0=-Mw_aPQO7Obs^Ni88&(Ixmqj~Q1W9Ctl8ld6i z7u@@|0@Kh)VArCCxBK1<3G{94@4lDh0k2dgfR%>s@UG2h>dR8S7Bv5F3Q$f3KuSPn zsE)rbyu_H=mnRfTN}QjhcblK`AdjYVYIa4^KJ^WmE)U+JJ;fno>kbHjJ~4e~Evj0E zA%0aIA*=MSD#fY{;ZHb+y)pIlu@O>*2N21}r&RVS+0{s1ijGhRt%`rK^ z)8_jyJ6<1kEKAef@}nYZ&l!6$PCUJmSmigxf%8qgWQe}EI@1S{x`S`^ z@%G0v8EhZoV#AS;NU{E&8GZ->hg^H|bDGEa5V`RH`BL&dX}prtL9Yg_n?0RJGm59? z;-c4%TaKvd#mBWx*3h}{oKfwkq~DNt?s5Hh=N#5uRuasnnC63e*irNXYC^^XUOlfc z&t-}VYv<0t+%DI4lKJFiQ_p|O7?OzH>x)&Y^GKabi@&F>lGtyzbPv{(+US3}-c$-kOj|3d4BtV1G>nCPhDkWZLqJ&3gm;GtsuBd8RsA0k$EIaeR zmYa#C>)ztMrTrD4Ww5OC?LF|LWusZ-G7T#5F$5Rnp}3dw_sDs#o9OG=zqF{}2IehN zs9@DazzgB$6+M~)cJR3bDpOMElNulWOaM(zz{XSjPX+~8fZC+bXqyC9IqDnzeK9mS z8fs_5$GiMUSrr2=cjQcbl`ekVOAIB=c=y@YgUL4G{}`7=;h%#BE+R{Lza8KU&~OMu z$796Iu}HmV{>vTTRLGxIPh#JDYj*$DdA+2hYS;~6tbFga!a?mm(34Wdneg1gygP5> zZoVhw;r!)O^x@z=)e{{~uSA8on=8isA-T4RX9Tr+WDU=L=Z$$9j_994VTxRST&hg9 zA4gB14p*$NvO+w&z5HJ`+hF9vJlz6XjS@V+kua1rwO!TD@@5dnmk%c(5+NR=&94RX z_mQ0`C1}gqZ_l`e-c$WGVZ(J9-jadSw1wIYb zgg)^Bu8m>0kicQ?{>Dwbg7J?HFcnL~!2~6_SqhVD!ItC__1M?KJV|{+%n=9g{NJ(d zUI}Br?U^|k`q$a8bwfEX+7s)|cnZ_d+F)%nyS`3R8^_EGLR?<4N|GW)BuS`*d5+l! zCh~w|GcB=7O;D1p0_B19v-UTO+ik{v{n$KRcAjinf3&_BZdq5|Ce)Lk8%m19Zkn9o zG881>SUn5~9eVr7-YP0~gCar7tAO2Xoo^w;=lG{o7%zD=;Ulw+gNRo-QiLEUyP^y7>;wKTR;b+VLUW7uOR8>$&$1K@TKCy@{tZK||celEBNz z$6@{R`#8Q$r-mGxK7y+6g_9Pwg4&9MKlpKXPBG$zRUFh2?=}}N2{C&ztg-PX3=#I42nwLYL!kK4K)@=&td z+Zs#Lu@ zQ9lStbqkuYY?>#$eaSuX9K7cuTLDDNqx)v5quwf+;|Tm>M-`d@7Buw6ac0oD0|v>A znBr*`aajVc=r7GvkXCnl34dX)V3_Jd0+~gkGwB`bf;d)PdJg>X!?`U6ZQJjYW-JM{ z2B&zBl_H}*VN#yGeEKg?SNs>KJ^l$`Ag4!@{(l0(G`THuAeyo2Ji8yFBrFP$F4_^d7JHN7Ff-9EIT>Znp@)C?N83-B28T z*mzH&&JM2-Z>13F)b+uWH&W7Xm^tGVq=PWd%R|zuRFSNzOBz#8)gC@RNoL|>lNYjv z8*LsG#16?CQ}h*hk|9{15|S;jWk;I{clj(V)7cbKd@{3o(O`8j6W`k(NKO6l3mVPg zSy#HOHCPo|~AmGq___&p1C{pdxe!^ajxxl@_Z42Oeqox*Uf))}mEFv(d5ru!FR;=at($QUH1DmYwtl zN%=?NJ45iO1dTJiQ2)zch70B59sD4keB={=y8KuZR;62U^{UeG#a&#$uEDf;ryn~u@9r6 z$y}CSl4LDf2TCizq8;;%IL12$>+=UKMCQ)W9;D3`%O>k-+v_-`ZST7UlOA2TMqwWKhQPGpttsQ^P`ZtZ8zh`0%#oo_;FaM*wHu!S6?!c{Z?!`A1pWGBN- z=DpXnYamG{L&ZSma{t{f_F36Or2(GXhIA>y6@z+?lrT!VMu#byl&CRdS0bhp7nKcWLv9Z<9#WF zyjdp$z*}>mt}qr9EaG&qS$`F9?6_>;4l!}mKcn)3_;Q+(JlN;Y6wTyq5l#2y(W^69 zM-}tsRnkitPEj$6w-cwU(*z-v=8;on*co1m!u%%^M5v!a>BL0_&dlPX0*GdYm3<_V z{%7UE1LM`M`!I{!e6lJuaM&WwyYw#^lDTzijI1tqC>QOg!MxS9Ps_8 z>Auva?pE~UPKx&L9k@Q%XI5@rdb8;_;xn$?$v9*XC4@<@b(v*C&F^t0NEr9$oE0%( zH+NM}?ws?SdAq!bsXz@>JT{;Ayl|U@Qjnj;seSvy&a6^lJ;i&o#3=cnB9GDe9)q_c z6q6qbUJRW>HoVulsBuWj2%|6`{0M1DOZtixzs4g0`LnSEwj<-LH@NOQWvOjxf+#W0 ziR>Ary&a#JSRW>$9fKTH9gg6r(hv7hS>?+Ys_Gu1VN(046;T32VO1qV6>;V3ubc+h zJ*MpXUckK9?BAzd!75o9%oLRIa^y+WC12cd2%$Bm7z>botGGZ>W?G2tp{s z@q;HpqOG^7;=tk1-lZT;!1KqA685D+3B_!Tfuvf`Gn?-zF^1;rQAqDbj+A)L< zG1D>6qke1iZaVfLPA{E`@ABidn%*@&qiyoi6hvezl$j+zOx)wd%Sqe~xQA3Z`hGg8 z?%TTN0!EBh$3UPbgv~i%)Zn^;$5EtplAVK`N?BBb{9W~bKOPXXBr`Q_lk|g2AEyhZ zr(H$m6y@~^j-QP?6@XiXGmUIq@J|dH5XUwTW^C?02@b2@rUs~4(r_GJfk61dKU}}I zU7gdFor9O|wqC4j=-7ywCmSOpd^)tF7yUHnk`{yt2|wTNHKEa5FXN+En*#yHxyXdE zpI?$amL05lL;a=mokn@u$B*rKJPxKcNU&m~Fe^RlYXyPfiErS{2+z_J9fev#W+>q~ zAyHPa-c?k=vRIQ$tV>3x6s^FJ*8dxawsR~H_g4oAN@H&H>LfVN(!WOHv*#Sw{>(k) zo;q@r*xQFlzI?iy$$jiGrKABbWXYR~e^R0j&K?D!%@6fJ$Ees;_otCHwX+sDC>%Ui zxOktWy<$1|C(|T=`Iv5Af{h1D6lIZVl+{>e!C}xQeO`lDhzB&-$^#0pUDW81(a(K| zf4dwoX>@wXC+^Vpj|CWi09{Ys^bYPJ!37%}=nuV-NdY};r0>54oF@?)x`g=lBclSx zSGkP-NNZ0ldd{CuZ~G2~=&6zx*Fv;>J4SvG+Odn)spsucjZIuv)f6}JrwDSnI~aZ%CGrfM+)cB7ITU> zKIdquPS%t~{DRJ%^;I-=gtwcPr*-L)UXKo#UQ_6JO-tN={U^37E@Q9!y)VC+vI@kJ zY7gS~zl=uGhsd2%DcC~-7&0XJC7>Eqvy zRrQq*K}tnQ@nQOM#s40x+wjVZ@^Sl-6y?fO@J0qzB+(k}D%*oiknF!%PUrBzWzbhk zqDM&q+wRz_){gJ%gY~n(>xDnJKGYt|@t8DY?ad;OH5-UXt-mCU)q@m4Gs2&TtVPxW zCQemrXg8DqXVE2F4i}+ca@ShoT!eZU-gquBq*)6$#`)Z z_;b;Y)at#~%iSUi+(VX(E~lgc2pMZzVtB%MSr4e)?0R2}?uAKV;@yGu$Pg8*aYSFb zXNp#6e)SY!o8Q5s@T9hn}(zkAtYD403+!%pX;mV={ByL%lS2+Fta3s_{Op5fC4Ku2GKf#oyljReV_*4Wlw z&W9!@0e=MRM?u>oc}OWdvUuH_ zfJ%}KTvdl&UHon6@k+br@{65e3o3#*0mzqI*GOkXv2GTP_*cTv8m#V)29AA(#QYOC zI0aH~+WnVAPd$@8Pe9V>DOdp8N}y+7DY7alo-gq6=7Uz_5ts495^{UhSzC;;W$-e` zq>-hPORki|KIVp;c9ELQ(95w6OPJ?9K)T#^(>lzZ`7mME@Sw<@#5vCq2-M$~ONL88 z>&Dt&<^<8;U3U{sk>f24zbxdve9F|Dk!XnTy!W>o#IH z8oj(N%)`#_pMD6~Sf2%+U1Mw`?$-h_H^n^nb46{oH*L0aQ^j!8EW?UT*6x$Gw7~l} z2`u9?Z+lVaK5rj@^N^L|OzuY4Y*)L=w+w6oF6s zrDkE=Wq?+)=iSqirDN8Fu!GkQp{@Yj1Q0gu&+k`8f7z8rX*1I7>#|2ql3Y8t-_)i(?9FD?owp>Zvs^){?G5DT zI0=a8C%KIuBLyE<^sf#6E{f3&nWba81c#kJRP9Y`e*#N7hEr)@1_BTqjxVa5?XGso zHR_Ztlsv`=Nf^|9sdk#}USPs&cPW49<>`^O{ml9ce{hb8~b*sbNtb|h4xJ)MOT*CJIWy;-`+a`T^Ywf?d-kle_gdHW zza9n}YFjCh?TaJj*_WisXinI`!JV0Nyh6V4%!S>NvfM&2-AP4>g9?ui+Xo845v>P# zZsH-OtVtc*9JfU!I59mQrS%*55&}`Ot@33zhhO=B9_7N0w#{0AK7H1Y7g+T|QQF!n zVbCF_c&tv0SXz&4s&`|U453bTy;oNt`+6*@&3$V-41!Kq>1+!UP`n22X2mFGobW4U zGkI$5xv$eSsCZ7bTf0o-G_7YpPf?sr##k_M-X;F2`waPZun-N@b`K3P9a;%;mw0By z%%#UUEQXP~Ao|^`1)t~2vzsc>s;X}ktDMlF@}Zf?{EEH@awSUq7gmN>R9isLo)SVe z$3)ZbDMqg*X*h|+v(;Uvz6ZnBO=K3G;=WukO@A_VY*uixUZiMO5R2`V&iqlK^dFCs zDfGo7;p?tdQFn$ME>QFvKO$sGqwfl2_ekrFzIIf*whHX?xgx=SnuE|E zji8-%|AUg1XiDS&qhZMLlwFhI^;7<0D}Ruuu8#auFQ=r&*mO>0&EX^HAbuhI3Gde#R=9g8EJU|YTKEa) zg6-w)ia<5ms$6J-*gC_2m#{G325htkyE_ChE*bp%!{`@Pq0Sqo`1(g3d668UA%6Bz zmD;3kVukw!%FOrWC7s){|JMPkmPdIAqy+jQF~1X+pO|iczXEK|(2dPTiideCH@@Tt&<# zbWDk%?f)3bG4QoEPt=z#)RrNDA&V8P`Y1Ptup+S&iI0Hh00f&>+Z@O2Ql zG>n)gTt@sp(C9oi`}jx5l4>oA^R`(x8;ch-^WI4k)f=>uPd(P(?i>Gbpfe)sRQ6l^yqi2SmK? zZME3C?ML!`m>D$A}}-&LFN+(PnY9 z7VqZ9^5QgvLU4p9x6%#|?s3&3S_geAP4lU|dUkFh#4*0LEk1!l#O#fI+Gb(jXx4+D z-Qw2Ki<=k=1W7`7BuN6*vp_#dz8=O}a>*=&?%G46c$Oap8U zZ4mGi{V8t`$=y^ov=S&$ui*@dR*|MNLpxiK78dq+Anx`W@u)9S?K3Oz)%lJs7o7Nt z65LgHDvC%+Qdk0H02$IbJ3%9y7KfS7EY}YqV6rv0-+KD^j-UNFs!D}ruZ)-0%Xi>2 z_b$R`xQs=YW515Tw`{Ifu;?F8T?e?SpN4CvGU!@--Yqm3RmYC4$JE$rNtr35TVn(8 zIq#C4mEE@wSI|k2Od>mk2rWm=)g;5&1V_OiCUy@-Z>9{or6J>BKGDF3oGm0iPZJ0F ze$4(^c(LYH=OBV2#1K*N9*B`HlI7^643XQY5Jc4qc=+1#Hd&QD6_R}@jItl{@tH@p zzEQrP`?(WJhUny$PplJWXOj;II7V~Tt45u5c5`ywH za4sx<4Wv5(nD}koxe=9rZaRY;!}7i5$KS5stsUQGGDizVcx$XHmv~Z?e)hgac0RA4 za@eo~<%$|!T&2o53lxI;YrHImY+a~KjER^eFV;&b&J$r>@8eRCAG(_OpSKse@u z{tG1K>0j$?wWv=Nu7Y31|8mo=LvwEr{Pfxtb#$Ljo>6;$9=jDLv5+1eQaza z$Y#N_N%wpK?V>asUbK`44Mo*#lf+xv{(4K4*}MDtN46{B%(IGnzxO-I7;5AZ(OiX- zvTYEWx*Sdv<7P_+E|yB-3h6H&9G8LPA)9VM$hA{v8d2PbQ#BL#sGXOAMWgErvHU8w zlg}c&9}AI~o2&nny>T1PRb_?0tdFyM&@jNzis6syhRV!c`FV~az!^sq4>;?53O`y~ zSV!v1---#D;!tK1Jt@L@TO-$HWZc7b!_Psvi5ow% ztNcdD-KkQXrtoSQgZ%Gp)&dGDDz z%A1&BEBIYk$Lnjv`WnzmKO);xBe*UpeDOt-URoq)i|(qjmvQU7q)NUl)~Gl zQ$;LcGTp&>BrFk!<-%th`#lCWpwr{wna*G-6!LMo zzcAE^gRQhq5gYe&ElgXN(=9so3aO7&iPs&}n*ie{Lg>X4wnNaee7(q9=fGLF8iG3@pTc)GaRHb8?VM4cfoo8>Zc3MAXFH zZ60#z_kN#66H3S+LaYaz$^33})NhqI>=PYLRMs@ZOK0ryp5^Yx)grxvnGqov(zNPd zb76gzq@@EPDzafGejsAOMDWtbEma?j#VgP&NA7$Afy}&D)}9xyom)42_1DDDM;csb z2ROp`{y?Z0OmvhF%-;HD1bq+`*8N=!-VfKv#SSvnqQhC4nH-161Mg0`5@>95#E91Q zmR(EM^;FV+WE>D_JxC*7PBzomei6A(KV6FTHNu zudHQ-P=z!;Rndin3tex?Kk%K+{*+mHzxZ2q2ZSZmF4!~ibC&#bN_3j~v?zdWu1jU3a6CLm1A9g@p; zS!NjVJU`gAdK)va35=e$k-An^OCn~BlpdN_gs z@wWU1G`(;qCNw9qzd?!)7ds1CQSH1x3`@FFPy3qTr!ALP_tWw|8|T9WgRg4vd9Td$sr&_1RU=ynDY!$~n;G%3 z9RLn_GbICy3y#%KQD1+arNsRpHM$({1Se1|Jj)g^MveJ;A5@p+6t^A@LpZk0SKh03 z6o*|1&DnUlzT9R7#QiRWxV^5)7Vc~Dfc~LB*D-Ibp5$Fj^rWD|N6A^j%d2-IGlDq^ zPuz0_;W>hZeFA+_*zHRrkXYdJ6?4a4MHGjJ$@A>fxuVS3SJ*?Kx!#u)p&q+;$OB-oSx` z2mMDh>H{Q%{8h>1;$8B@a^xL31?N?DC4h^G0%Pd}7jyg1UgS4^!x&7ya&vY>k7aw% zzbtW}k}z?VC9k~45Gc4RP7u@$Lo9b$Xt)t_+y z{8hrmM5~(vDyg6HnliGF2)H`{kO5}TLY8>TW!Ap-*rD(WB#SVOW=K+dtsX%lB~BhY zV~K261_DnX7FM3}gEJC7a{|sT%|dPzrjdigI~itzW87pvI_--t{JE!@)j(>`>6os+ ze{MU5lfo zK{de_D;Q65RCI-bJr>EdWE0G8ib0F$G4e99u~l|+oJ&${=j_6TR44l#s^qQh)O40z z9>REW5i0#ll&~_n*^n@29B$PX8LD~@f<-p)!INWmpXt`OJBz8Xd}bR4k&Uz|nkT`8+@c3%T?x}$Ig3nw zrza{iriE6Mx>v8v<}S3LlipBtNHK8xPENT}R;J!U(Z|G|Iw`P%t&BXC} zUvv+G`{YW?(E>q!w~vvOnL{lP0^4RfgVHXJhplf1F)A(Xp8eKG(n0u@pVoT~s3fT4 z2fUe13^4#1d9y9*h(n_+8b!3zVko}H(`kK|9GY2bx3$463`JiB*cGGpoZ*H@b)*fe zP>y##m}!~i*XA&g#14j&k~$~+e3+Y>oCKRJZUn_9T_*z5l$mlp!FwN0PV6~dhaIs= zkHC#poxSZ&<3YC2M8wAYaAK8tiwdhPO)OsXzez80>_5x_Nq3vcWCp`o_ z&e-Cx>El zM2~8GaZ0Q_na21WZXJ()tfDYe2e<;#z7OhD?>-M z@i!$+{f}S57_TEFJA;#Y!Uv)jH%J{ed(S|IX6!|OtE@Y%4>hC}yp+Fi6-wsW+zavg zT*vR_^M2w^GhqR|VY+v4yO8A2k3iKCI1BN`H;Ljm@bJ)54EmY{+{5Ktg41?v5G-s- zTh%kobZSTIytPF004KCcd;U;&8`^GLrkrIqpT27i-hH@t($032(rk>hKv z#UE5Gue*@z@ysP&1e}rPu z<-&NPWQ%bNO3QW)N1aqS)(fOb&2rps@Sn zTzU4iu{wXh7}_a$|B4xw230Lkif;aNt8l5!!^D zTui%soN<+wGl*gBc~9u{q_&t0wa4DC3BeBTwKn}0)&=yo~x;igl zUx)N(etLGrt;&mN^Z17+q%?zQ;Z@sN8nQ8xn_|S4nlH>yie(9ClWgI4-I#{oLnnV; ziIACl$lXLYG>`*Mn~i4yA!1TKIv)5cBW#}e=ige0${Rj2dlKd0_7HNgy|z*OFa(Lb zU@gt#l3Apxda!@?0Qvzss$5>3TWnQ%0;GPWwt!22Hf@^eNKOxxoB`hfdv#>GD2B76 zk(6Bahew&ZLip@eZ2{Lcm(->v-ZizD8<*!c0~bSF+cVd5lN{$+!e}9G<9J6CHUesg zzx0SQ%fe$)&TpfBl;N8n5{cb%vXoP4xyVRZ6*)%ginH|Bj(>I>bk~JRBk-5(h6h5^ z2;%Q;y2~8hyY=Y6vFf`k9Hr8O-p^_YLeNTJS8!xe6{m(G0l#{7`6L{S!tTb^AI&Y?e#(mA7bXzKfjl(Q1tc$MK`cjbpfa4Fj7rP z<*ighWW~&ffE=)$DtWA*9J)i7(0btd%|1wQ2FM)RVj*k)G`^`?^!Fu2Fn z_n-vssG84!B!|A-bojQ`3Rc_cZd)u;v^$9$LWm^L6s8fPGY(H)EVibb9zM9m`t6Wt zBl(tZv2VY~E1GhLYc5&um6nU3_7)Mm6vpcvdb=LutwJ;ERzIANduiu|%%hFVakiQi zn-Pdw9iPSi$xf(ri8|iszz4+PeU9m=9gD4yFLa~AZ1VSR`U;xMdzl|5qdf|fA%TSi zeJ|%FseVimMV6ZZEA^A-V=901lpZGAUguaS7@0sI?DZA?&-gRH@jZU0d=R%*n+{>z zL0;%2{Br9z?UJr&h6k$S>v}(99dSYv*#(IZ53U=k*1KhY_Whz%oA1^D#(scA13Xr* z^61tD4?lWmUfl=@0eduTezEQ>@gb#Xi{y87EKQW)Xcl$;ob=}(F;iYTKrBD@ynnc< z${hqdFJey9JYT1diN9Tx#U~^As(Rog6;fKq27f8ecrjV&<-QsYDZNyzJ$FXGeB>&|E@pGrp4S;e8!aH~e#@407C$5u zsU0)r6joQ%02;c^P`O0X<);OI!Y%*eYp%plqlNcC0F@p$7lXt9Ewaz`U&_V58(M7& z(wD5G<4oH>w6vyic&Cd+9~MR-KY_sup=8R;*R(n$Ir%_aU|&50PsR3AgyO+B%kOH_ z!I*3chRQ4`geUMa2#BPqcmA*6DaTq^lw^5*iYGQV%eje84`U52gDSfa5Jj1(^p>kH zoj)&{L^SOrtvW#(dO(&UEr!cjsVR26OlunZ= z*e!t&3Qas^!1AjheRiHE`B@O7qGC13M8qdHlkr(&?B&^HqVl3>iYXgIla`CgBhnSd z&jOr5p8mdBD9o<~DYL_wG95SA-JMc}$Qr4po&F+V={ik??381l0NVs*H3bga_f1;2 zFjqu!-NcNU78~w-T+j{wGj)>SiYE-rlQ#Q@Q5G|l&##GbaeB)`w7;L9W*ctQ9}~xX zefKEee1Z|E0ac<^&-bOtjQ+f=wRaGefP7JLNhz(o(6(Ffecaxvdu{h@`$%bP$YSmA zXn6bPbR?RkA|djQs5(`9U#5kerX90Xo;4D4@R6tDAL7W!r?@P{z9^IMA_~ zXhfWyndhFxl}W>S@$U;cr|@R##i}l2iw7HGeXd6u4@d&W`C8q$)EX-p!l`-sv+GuD zLqg*nx{V||Ts|*S965430N)hcUh=M#Z4z(62#NvgRla$b9n0x$W4+8RnUjukGah2w%9J| zxt7G?C_%sL$}C1w+S6+E-=3k)MY>s4!mr}H{Gw%-KuB31B4ueT`L*t*&ldLAJz}eeSRh(wkQA= zUust0B!ztBCyuXr{ooY;sG1Ho*$T7ugPz>QzjsEIRL+8yS`?~$xUkp{BMrm)1s;YU6CU=Qr)8m6>4S{c;kb$2{83^wMbcLw+piiE%}K)5%omo7MK$Zr)^O9z`7&^Us47OF)f3 z&@YXZy5D=kCWriUyu^o$r-$tPcKo4eLE_{b`u!QTqtQ1@Z*CoyWj?lFWYCfc*VIf; z_Q#6uD`s*8h1rtrbeJ`972{PJ5c^Tw&VFHB;}6<$p!%TN4ZaIwzkA6-Jo|1KGCY*M zQTq+ias}~X@g4|&F`9gqPw@J=Q?oOH=7&*q!uu~5WMQP?q1~=4t+1#ZdPSefPe@%= z%N7+|I#}p&Q_rk#`ScrDY~yX_oHkRNJ#2D#;#}}O%=$!%nvM^FFea*8iWnElw0<@Q zp#<3ALTjNkw=ag32%j*YXih9mqx+xX6$C!rIRcS$8gDSSSEKK&QqY#{BW@PFBhHsO zS_h|qXZm>CAQxuW+4Tv^8~1YDAm%;Do0ca&6+Mj{+C0aZ&zd-@N)~cVw z-_x&wF2BLE1|mfCG}6__Q*Fwf+H{hzjz<&9&vS)vi?{>Abvpsb{h_hnA-M^N9&?h< zzY_~WrjHB}G#L4X?tpEdb*?gGA9i)(M&XEtHLWg+aKp$pHqdIatN3^&3}_^(52A4rLkmQW$X0ZTD$s2OF zSKpMMXmnG(MT3NAwJZp*-I2fx2Y;2L^*!pCI2dTFZA(usth4j)Bm-sn z-jT~b!(1d`A}RH`m73MR(P(oEka?fmUXCB~&(TKYrxBeP!rv<`!+)!Nog&qSP`i{U z6llpj>X0lKt=ns$O6$Gav0n_uR39XgPm<97{S^w-2?{@CU4woURvNVZNUqbF0FmgI zbl4C1oZbe}=z5}|chveTs`g<*adc9(H^%;wY0zmM>`L4xP>KgMGseA6T_YCaW|5jO zO3^LlPEA?qdu3SVd@rGEm|xC_oW|YH2+QJiL_Z*gE4|+zxVJp189Ru)N8XyvLIu`y z69(b5U_I1W=EUPDnjhnAc~l{a>2kA{T0Pp9)H#_+Hx)^tD2(3I0OKmikse$$Kp!6= z;bvmmPZ=v|3kPV+KZ_$qLPBcZlUVS28j-+X+P(D2556tYOF2gSb{o=6*3lFH2N?bM zyqyQ~o#&GDQF5jG#KNF+wSDMvPYx;|w94_-^2zJ_m>d@=uOkQWoH}GFG4HLh#QmXH zFix4l?_SjwOuU&y|9R4+Eoc$x2>?}xjBpjh?#tRe8!|sMBHyc@Z`kW^>ULyh67a88 zSBLV^$f(K%4i48Raf0TrTW^E^49cJ?lnG3`2dlN;8!gs`d^jk2f&6GS{#LZC_58aF zJW&TOC3eN$z8+`%4*s^r+QxYojN=Nx%H9-GmEu0a&IshTSyT)%AKPz))^T89{#mhmalX|8x2L zb5SGc46e=x&#!!FUUU|(z&NlqQA6B;KKWrED>&qyN9sNAp0QP>j+7OKjS=p(SsVJk z-sDbWu$;I9_x-)NMR=6mkOb_1qH+(DYe~|$gWQyU9sy}1Y@lYOC*i|aW)KT;p`g#y z(N?KCh@E{q?6Sjy$W(aT4<9^=P*Q4ocX(l6QTu9|Z? z)GoP7e`y9HclWVAV2ue5Ju62cC@+9hh7ndV#0nDcOT4f8KZg zlczwPA|0ssh$+TR5%Y;vfAtRHS*5;}`m4|f`PnRD=CfUY(UEj#x4r&CNWVhhhXSI| zxev7C!yy)=^ zyHnshpsHs|gmx-M5v$g6v$ReKEu*Z=e+L(VY^R-t?l$d;yNSt$*HP>X3jU$cv3eU= z2us!S-xptrHs|8Rbjnz^BLGap>pp(RYcFys$E8EfxHUCU7XRo%IQB zNF#JzJ20VRm}M~-oXGf1qIe6EDA7jB-=lon>hZwmYEpUzG>E?0YmPqLAZ+<|u#ToX zy^`_^A)h7m0o37a3F_3ROix+(yzm`(vRHS!F6N;7BMk6p(wyO~wC@SCIf9v#?U?Z$L6bBvDVSNZXo%+x0~O6FJhJ1`&**k zW#9cqk$T~cU8|PjBal!J|7c~e@uP|@1a+5T7*gWbSF?*hV>~fZFtG*R2q7$Ign>Sx zBlgU&xHPL#rd?on``a!@fpM=98<~Y}4`!h^iDEl1jLp#M-WsUm4|#<+5bU_!k6*Yw zRKU9GQg%wdpYu2mP)*jL`0F?<*7aw8@;8W4|Mj}Mh~^2Yn#r3*e*07D&m#uVrOveJ#OWg0 zh+wB|9#(Sd`7^LV7VK#c*)eP}L#hzxuP8IqUzOx}(F>0?(c%}xUm|+jX}gUg^9b>z zrnyVgs=mq@CaHb4rq9lkQ2vFk36SfdrDSlwv_n2BIcNH(q9CEhIARGfBShT)?2E62 zoNw+;W49V8-|eX`c!jiE^%f-%1${WFXAKJmm#M26{%KxjvN=Rfr=ReVx-jKhHk*yY z!=|5aj4&uOAJ_@@kW#;W?mQp#Kzi&VV~d^^`}x_#;gg}+xybIGr$-3vQS9erPu#$M z8hK^1>bvi;SAyJp!f6T`Z|og&R#xz~EKH{nlkg(}zf%lttEV7@;?0M}qs8P~ zQO`e9xPKUVT@Q6n^PcAw2!C4kwh|9FOF}@30E~|KbhIbRCC3@Ois@rU5)3Cw_ScoB zf=HEcqelho3VW{lzL3u=SXPmoNLF$(@&jTB35EEKPWwc&<0i;`rGU4$K`^sAGui#w zSu%npW7#g*WtD9h5GQ`Oc(`ANbeo;zo{k-zUC;eREL0m33H@De{k`$~L#KFKy}|G6 zq<@V;x~PWnR?g!?#{z^8^;Si0S5XtI-2Dr@mBRvT`=vKf6xX( zFRA0~eM`hX2s+;FX|NrD(F{uAd*G)xuJvBM#2A`9pDy4s0_w&V?+nigq_QrRK%?9R z05XS03S;R-1?I(TfN$uopKZTHKsFZe6@QFs*U!^&H;505 zmu6;M-o7ug{M10}IVlFUB>@BHNBI5BB$|8=Nrv$sRq~l}&53Pn4ZpE7d?)alb5`60 zdF3)ATM-F1D@9Of#D!Pi0nC+w9|41Tsgb#cTJn{CkktFtna}oV1ghS(|A$gcW+*Y` z0)+~c2)|ElCuF*cv=={*q0IE0ig);3T)Cq~nVC(LAMp5v2#fW5P%at~UzCFy`4uxHJbzKnq(UB2Ed)Lt5f55v2S^_dj&ONlFRxq{Jx(j9K6((A86r5?&czDSSO%-M`;wyOe;4kJFAmn(mS5U%109kbMEZ9<38;m&7Md z!S4p!Lp^i2gvNB4r<yHmcahe2p*TEd=552Kr?A|3EGpeFmGMQyta7YxCVG~VmyvPCS^akVp>IrqtG6y zIM>Yxp1Bo*Z^JHLC!e9!{-Hkx8a@6cRaz>){ym?uB$O9vOPd3}N31)~__$hzz6He4fIWtDm*hE|QO+l0c3&?cIQKs9 z%cI&UlOMl(52JlPkh--FDT9(8|6F#;i_Pq-;@Ffg;^slQYAGBguyNC6J_DT8<* zk1zQ%6Ed6ATYi86EnVloZi$>i6nuHl?3lH1K7N^a2Ea)^aoUn_%4&Z3f?S>SFk73! zV@dCeWQf*bTep!sL=E8sM~*8O+!1Ms%D>6SuZEcRN#*bo*I0vU4DnFGGzb=)*8&8?q=FKuP z7(dUMf?glhoNjWKz)K}U8#?dR0vae5n-;W_ zURJ*MCinw(RTQ&hj}aZQG<-r>5aiq#q4}cO$>eh57He7L(X}1s`^mid?UKFyAoM5` zm`keTUjj3xxrrJG3da?fF}K1cVjwdcC`{zZ_5bPAsMG)Jnj~fMV8nkYO-G`#h$jqX z><(OsL-p=fOXWUPNBZZcEy{tR)J0Vpfb=G`@p(8(5X-g=X~ZZuwN_i_b)#iuf<`MV z4WjAc92V+HJXBr*hz{ud-tt)}<3D1d7;X6#wPli=_YfPz!8Y0RX@q=`Cy{$cMI~bR z^ZC#Y29diKzXS4*eCW3uhZHDL>V;Tvd=@OyLMTE;d6nbEOLsC{OptCsfjvRLn~BD~ z{bdqqL$5^L)mSgF%n}|n;^P;x4^^E4nUkF`Y@;odM%I(s#Wh=Ag}*n#Y0t%EUI&r+ zF@!_V@ocWrL!&@2MpAsOUY=U=l&~xyTO$u>m>iToq&%}(0wyV;1$d9%ap>7gmy;9a zWTv70MOqJTt-YeIJtAechgD5CKG7^O0iAEeDS^%l&q4mBR(>_{_m26^O4}k)R+ZCc z3X~o!H#lcByRT;E8fEt^(6DU-7rG|x@8+L0{$(XVUa}lc94t*urtN#rW1OOwzf#-F zw{68RMP^;`0E6Oy{vaqSy^QC)DIJ^#{+#LJ$w|7TBZEd5JTvinVL|+I0N1tex~e4g z7_OX%EheLC;&Uyp_HBnc_}cJG*vu^rSPK7c`sl2^KFxnz_YHia5T{Yyk4oBNpgn1l ztTqg2c%I}}i>@yUz{n|0LfTtYQ(lvlm<>R_Tt{}vXOp}J0f9TJ0YDs5K2U!V2u`^m z;xJkQAWzhl8So*<>>K=5lYt>{b+k=DhVsF46wH)~TOhopP(%<8>qif~sq+Z1*$on~ zkggN+n**JB=$m(wK91heXyQkT&Vi&RTrGC6B=-);5&^c>HYOpgaDBlP&6Xm3copQP zw|z=>XlCi1JXC^YtzX?7`o(cGE5_2=X9mwhqlU%BgkI`J_*wO15!aW-3c zC1{`3U4FUePwtLr49kJL)y!pg9BHuvfrJ5R*@L|l*B)vS7}tt?az+LqX|%HO3mP~w7$B5%+@Zj z7FqDsuTRBi3p6^&H1)18j_&|ZR#aQBA5|>R!2u}W_6?@L4}~~N@S!R_uzci}Y&jBT zyn^=+5jSl)wOljBrKmlS<=nNbD09CzT~1v`92v0bt%17IM2I#0!iM*^pev&4kK%C;=pAkVge`lADs) z7LQBBS4G*wI0Z(G2yOMR0XwIkoc$M77Au+Ae>i7=>E%mCkafOO0c# zx)n^SVpIxkIh@-eZYqOr68%>HAOay)wyQ{{AFQ0|{{>Tr{E;iMivn>t&l+&Wj z>v(};(CCrHHi`9705<-gfpj~W=-ik_JW`0HdAx#L+xl^PYg%{lg~F<@vCDD0#ioQz z5=vI&CESg!eea#YHUP3)DgX$HJ5yA zf6sr%zqEKS^q6>FyROsgMapH4a|=gh;Zvf^hrX{Ly%yf zjy)u^*mma&Hc8aAOvJrOVJd^S0p&`o$|Fs`z8WRkq|r>de16N?c4MPD{q|@LaC-YM z#8{OMuRTmUj`Xj-aSzYRoqF!vd8z#EM%_J1;ISM zHLsXPnXt9(5HqXN0)cTw?c1ZRBEJ~PQubpLen!Lcu{-MBy5UlaPcwPcCx>$bsoOi2 z(968Hz}ud89!f_LMVrWB-UL#nb&pA;%jQLQZ4Va8$V*v~a&yo4M2Pk>Y~qB=>x*S(8NnDGt5PVL7opqz_Kw;A?5&lpJb=XMq9Ha^_auM# z3tRr=2N(?3PFfX?E0~V)V}?zBYzV47*_|+0zqrax9`A-p1uIVq)hVHTTE`xyN|?A7 zS}iIlc_|?C)DjWcD(?3Xug-D9dt>+P^kq3;zV~R8sJ#Yxc(2vlA@xS5^17_cY@Hpx zHy|q8A;@oXv4;z7Ti8V|Lr%OLDr{~zvGHvvXBTPr9I|Pla{vznmB|@@xpj zt2OKW>vhY?_dsQ{$4ISrA_bT3Ns9p{7lU^mP@!=afUARtoACVoBhAx&qB6!r`a6}L}j$p-$MZ>I2lrAZ1Jm2f+vq1XW#+6tbrQHno%A8!k@~V?b-Juk9XH+1UX<< zU?;=rxYTT9S)d*uAwWh-U6fj(h=d}}5-#MHQ`IHzJWDMz&1JkC5`=hMZ8BeFMFy&M zr8>tu^@W54_8s8dX*cd_f9)sI#E2qO-J6+{E4 z$iv?JR7Txqhz4IpZMf84#P4Vozk@B)gy&y%QWuy#Fz;CKVW!=Pb5^^AVKSkB{`Q;6 zfm*bZy6ael%*&yHq-EGYpVWyegJ?R0D`+dS0X?MD13?+nUpnE@qnwM}ij=AN*x!WpF3r=^k1YxvPHxIOixAYJEGqo;7^4+U z@04HcZvwV9&GtS?|GL=VFybD+uiI=1et02C@3H;H0+Dk7mZi*e|2tIjfe$~mrsP`+ z>uZl}j>#7VJIj>3L*#u!CBY&jdlZ~f!SSAaqEn49c9=otkJY(i^JglAA?Kh32{O&R zXwkooRbzOS)Fmyd^v1eZAm2+WzcU$i93_s1+w7`#Tug5{3N4)N{Ex*p{XMp?1b-qs z8qx8wGva52bn=p;)0CODPxUp|6{j{GF297hwcp>Z0FgzGItL5`&xbh%$VQ*Lo$Na~ z?EQosNDQa>mcaTk!(XfO=u+C-98B(68pfcS(~Oy%qo)(;7alfH0i4QWnz`m12;A?N zBQtx6O;?4#(poD$KZscz&Yijj7gL5rfNI^I-wlKAXQD8!@qU^-@j-woHjRTPQE8nH zy-Am@hiF&7a_ptR29V-KtRM&A9iE8f!>j0IXFY1MozU1kn&Hrw^>N5GITf>mQ`(`yeQ15Yv}$X(xN6vbeiJe9YdL4y(Z}+F;EF==|vt~FT49t5y zopnVxDGRvi3d<-{8s%RZfrvVt8fU+_UhbQ^Iv_OoCC63Z>`VV$_&EH^N_3qg!Y`CF7~&DS=;?oW+fiW7yKCAUmD-}!|Mthw6eHtwO51l$|fxVytWH@ zEDhp20W!IIc+~#H^Yu7;3c9><`GOYELFqM!!YR0Z8sU; z0DNux)BbE(MAZgsdt#|E0oD0wj_8YB+2TItH9Iu!Pq${RVM5#$>=|l~%!O6%xSih_ zjFIkH?v}Xehy0vBD+)N=o1kLDf&w5aLKd_CG0Y(^SlP`)uF>#66$MC#fs9oi^jvQd zKvzKp=MeLFgqn;0N~J*Eawdd4)h&o@P)SScZlVXwJ}L*RC%zZDogjWL8Y5Vt zzTN3dMcP>WRUD4DU_9J)dmH2$z9JZZGKm+tlVQvp@rRzkMGv7P!m-Yj$EjGC{cyqH zU%9z%pQTQzOA}ml?UJXEn5;-2qF? z&U-+4eKw6b(MtbOU;>Q+L83ajp{PE^>A|9i`#cc{*zN)G7wv-lukDW8E6WCgTWnRt z_64i62{p5C^Lrhx?MV+G)R&PZSCh7sH9XDzRXG5Q7150#r{J(CM&E8Hwl*8UNhjKJFV(@w=NRsG(xFki9-E$q1MU=_>tIH z)WWK(3bXZ0YsTF_95SN4U>u+l^Y461=Es~psF{s$eWSv-j`L1eOK7dhKb0bua+(;- zn8G3+sZ|YL2LP#k{MY2*BZ+26_4~@q`0-Oy81Tc`P`vQd6%SG}*18^#zz4yOm%OV} z5T)BaqzU~ewgL%G~N92i4Rua_J#I?iu%B9?vL6n5WhJ)9Y2DorhkFq0Z)OQ``nRLuR#%k z;?jVLbZ;-`{~Ye>+Kzlxx;!uT9d9hGq(BCbY01qK8&8kmg0=vh}JPS4!ShnB0q{@3;c1s54aJrh3yz8Gh&z07`mY!bR zb?+V3-<-+=sC$m7Qirqb2V6SE#iXg$?6K!{Wa~|PjRl#-hkun4^me{H8-Qeb1%`+e zc$wh2>_xSrU)==YgT%3#kIaMIz+ifrvAyY2TV>$Pw!?3?y7>Mc%DYq8ox^=3<(G#3GGV1$i%A zO?>pT6rgUD=Fglrc_z-=BVH(z;|}Cnr0TpZR#r8_jIoyoMi|&mt+P^U&f<3UDj%-M zutmr&qc+pnl!3itBoz=a)GJUO;Vtce=e@$B&8M#1 z`1X|+nWjpq9Ke=vl|JoV*M^CV=4uJ+nOz1DL9EApS;4thojhEXz5ixx7;15&CfrPq(qNIxV=wW@rqQ=&wy*~a(j#y-D?GIQy`4`zKx$msWUy@A8aj>2S{$}y&9i%AGInsxU?p#I-xY9k&e5If4TSnc$ zTwK0)mYu)wnQM@BEk>1G32CR3WSP#UjX2uVZGVM!BSo0Bq)L~5*@MtCeScTD5);eJ z!A3F#aK%c;KNn<&nxe6xEjQke(Y{b8a93Xw40zYs<8=dnIpY!%JPxeU_kC9_kiH~I zOO`@@ijf*XXJ_AG?z<7olv-R`Sy^UsLPEyykX4A#ubm8%`f|~dU-XqOBlLX1@A~`C zX~nd9TCu~Ujiy(Eh*II{ca6N>wj2sPWWj;L>o;r$)Y{(HI;zdf{Zk>IyGg@#Q3?g@ z<@wuC0?{(W!d@5OIKilE_Y?;>xJr08he9U&?mcfndq zTrzgG69R1PTwZb7WO`RX-K?qC)8fOG&)?BecT0~JO!%>KZn+y|$EM_{@3)FNd(x9y z`i1i2s>5U5o6jqnsKJJX1iKIA@ti!33}xml_$x}TNGkI_Q^pyeKYCne5b~&)E_mkA z`7Sla^R+8{2afkU^i_Qp z2v%PQeP`p2S$$sQP&nLq<^0p+EbqAqee9`*J^MEjH~mwo%VXOa^T#l2WI23yEmqmP zjQQ&mWom^UjN8Klwy72`nq!8?_8Q79D${=+g#2*Pi_(c^2#pOZI{1tP8@GRz`aGwZ zs>^FTGOE7{;&dqBCF_8Zy<|@L%6}i~KrqX8UrD!z#n@lVzevPqY=#lK1P`ll>0z#K z1ziwn?yRuEIbkPOoxfjBTMrdVQQeY7S8YQcd!*Co$Q~Qv=`_0dE)cx~LT?H)m{d3p z^NL%p2mx5H4q}Ia6vHPL{w87d2{nKP-+@$HufvjG zZ#v_`l^?8_in<+hP&2)$yu6i>w51F!*@YEs)VNl zqQQgNeJ^0>``Km6*FWLE`Nze)t)57uP=t3?{}E_e)N0&d9RqaFt%ta`JbuyI2?6{$ zcHs<6=4z|o5+EMcS@Z9Ip57h~?e(}@P5Q$&vCIE4VUS>Q2!W|?PdR@gV*2sz4t)T3 zoowTHEzH#F0vR=#YMyFL;nd8?Y(9E^AvliLM&+z4{h*$ouIoMPZ7mITff1@y@q(-L z!0FO?NiW$vs2(MZn!--j;|oTq7-gH+=~09u?mxmbGuW75k*v(IwT5O>K;PGtoT43A zMaLCixW)kt4pU2ytP@!Fu$m1N<%q^`jrp5HSyWLGySPP81)+znNbo)KO{4oVsro7T z4%3Semj*}7GR?1B{LwcuaDc`!65QbB5|$(J_#$)Okk0wVoFRys$)BIHj3P3XS_!tl zZ*%ywh-G|}g@ihBBtGSknSPTPXOV-a=M5Sxe}jEDqnfrVtoCtG*kxBU<5W2-U&V{= zruE?lJ)_4{FhatEhOl#R(aFn^^BSe0_2hwHP7&h#PuW}gn!c@)6$=##d~=Hqm_NOs> z^)4T21zve>@@KM;=9=5f4dc#Bk)K+!9TR7NG+xP;2=2@7(9#g&xtfrj3p;@vgbfZT zX$afzL9M2oz?>CT$nqnt{Zp>w@1`R24#9I@MmYvGf4{Lh<+*7)NztK#S_c@fnrc5k z{E^)M`2N-qUr4*f4~ph=aXv9AZBq1pwBmED_u^(0RkF)5>!z8(p*jQS7#h(M(u$vG zI%pGFxIX_$&M*&t3bBcUe*)?L(!0#vP#|VX1kJ&WrZsY7`ipQPHXUucBC{*nThdiD za;gd&)mF_KhA|Ss9bQANjQiiFP-;mZZ=!%{3QzkfH&?)Fa)4fzsc8c7x^nCukNb}u za6KmFQz<=ko!_f9 zYU=$ix#N)XD&*m=Ey#uW&7Tm1F~GDvY}q1nuFhx5LPf49StlO1Mf>$n|zhj0T;{7i-@mt6N}+9U+dMS$Wr@1it5$;swxC^ZtlNW(K=IY*jyF zAW0DUdR8TWHc@`ii+jacctNTuv)f7ON3Xg|h>5Luy{0_B9-78_v~362a`M0HiZZ98 z%zN^0G%5oz1*I>#;uatE3F*cQypprWlU>kdG_0h8Yiw+;8Uts?x%u2FZWKRzbfwTS zjQJLCb%)!KXx*Teb11c6i#};Dah;eZdn6wdm5PSJzd<9y-oI_=O)C6wF*bQdl(FBG zE+^^}conhE@K-tSe9a-+>nY>cKY){QCx;w$BntTNN!HPX`Mnl{RrYxlF4HO1uj`sc zt|jGYU8Vh?ubM6*AJ`JU&b~6DsI~!@>*n8N{Y(G;aS97Z8d#^jd+CJt+&7X(3mi|* zz5TEg2EZXp-iV>J;tkK$geRBGI!Z}@T;DWxQZ~|GT&jKG4J|lYux8Mbc%9c=Ms1hs zPJh50sh@(_o8(cOSUP$!bdK}Q%q>vWV=O1mBYP6*mQVBJ6oKD}C;R$z^H)gC((<}| z{OK5Wi!tPQi>nkB&*;w2O5I_-qs%bfFj-~Sr-d5}E;*h`LCCw{zrtf3BaiI&P&pPx zetHNw_ZXA+@nUL;=Mx0M>8lQhv8uo1-P^%E)yOpduRJ$RCxbe)5+QasGa2CjnQ$1Z zeI9L^(ca%Jb+gi$HjqiBj*ms+Y5KuDW9IQoc-y!$pyZFTUbv^ZD-vE=scg`irwJ?}AE_r-8a>fpe z;oP+LRF~sDep_)IsfD1d?h~)^&SqF*$TL?E;f14WtRI9mN?Nu%vhJ;CBzan5opF;u z39wh&VOok74JQi53uuLXiPJ*aNxNT{i5ppePa!ulwPZg)cR5Xp3aLtU?X~fE-PH&* zCsDTN_n%HTEb_85j^28OlZZf8iFC-VWu7U=R40rz&0}KxXGn`6>xpAO;rs2hgUeXk;iUwwMtxOslOv^{f@h+cl|DncH$hrPow-Ro>D*xXx#G-&pvzuAps0^0r)eWOh*Tvk^kwH;my#M_a zJg1p7|Npn2=4s0xFa_lo__KH7MajN#+<2F;!1yMHh zv?TqABlgNr`~`1GEww(nl=W33d*x3Owk?;%4;k;jTv^)>xgNO@XS>*mg{!)MyQXUm zEtq=)-nRJT$zRw7>0(&N6;3s9L7&SeZ{5k|izv(u6hZuDPK`;`mbm}?WHOXF*xkzJ zo{wiiT#DH5;ih;8nggQ?TUZ0N$Px?VD9DH7t~FK#mqG#4hoaL-Vsrj<;z1*v%(vyf zxG~LU8#KmOyt#-!r(3%C9_3ID_boY$A2WNV9RX2$X=@aXAYi~tkH2JL${zN-_*!H? zQOePO!JO&)@W5Z|`^1-L`fvW-O^-e9y)_4W1;p;Nx!S3>HyU0s4`qO64y{K#52|J; zig$Giexo|^F26?g-(KbTHTQ@BojeoS3AaHhe4KUKIHsBvCNYf$n7DjglW2XTII zO;PlWBg% z^9XM1orhvZTowL}NS7(jd&vf&@VeVA$#{GEGNJP>rjMMNFpV%DhD*Dxd8xy}d$4{< zWb}NNd0MT`67#pmiC4D64<259)Z``bxEiP+7uqLAG5%LS79o6X__Jy&o1=RGlGrA4 z8w*kcLYDaVzjvH!X|K6nK?^$4V3Wr1Kf{t4BnEr)m*nX5uEK?0m)ipfJYvs_K|N-X z^?jwF&DG!`Yfjr@1qkrNfbH|F`QjsL&omfFpI^i;-Sj&-IkUYN7Zv?N2n8_ePtj1d zaChFJ?=Kk}D951MR67N#$@2u{TnhT>FM*7HI`sJSwGptoE-Fm}B z>?(P_=yWS??F{|4kGyf;jNxg@5J@+5+JL&=Y<)>iaj<9MjNt11N-4wduZs=+g_K5RQ zAn_Fkj20cv;C4&&Og!qeEl!CbFeNmN);`h{1KE+Rl$p@ob1##4cg}r1-u4YcOXh9b z&#+@Y9N*1|L4LvL_I7w~Uy(_!UR_FEf2CdL#f|HJ;z_12w`7?&?IDGh$lRqv*~{C0 z)Ni4Ci$Zn$Y=Q9wMR5~fJcyI&q83EZFof|B^Z>7#8Yu}yk%J~`I-0yLwFQx%Rd&27 zGu}66t5g+fqNpulz>x!=lwG!W7+Ce73K^y5+K0s0CN~N0DLOY>L33yGKwWwWo+UP1 zBG>b({h;iNy5*5$HOuAqgnMn}-v|=#&?WEq=BVbu;UfdkfUVmLRD-s=m$(XE$wY+n zo?j$xa!#%7CdkP?3 zsP&$S5YL%pmrgrcBulvi)i0G-+v)r*%q2(?$P6Bsnm*zdYtrxIq#|u{B>!L3_NvW( z>IH+2%xK75-LoxMe315SR@6X3z%L{ON1kw;aa!=_ZDI_!ViNl~ef-1Sm#1JgRFt27 z?-EwnHEQ9+*p#0xL|mDKV=Cys8Zdre9ssjg#BtAd^v{-Cx{AeqzoGt15ubdWO_1q3 zX!P5sD|uH8S`LPJFP&^&m+b<#jTGn}1rHCF|EHv0nFP^Z1L3xJ@RjwBh$~dcqWj*2 zBPoKEHy9ut7tk|wVy|Y zr5iW15&N#JWvBymr|l7SH%A!m?dA(3kQHlxY5v6ByjsdQ@3}*_FUA|oIvryjMx%&= z$mr*QQ&Y4;?=XDMZFmrVa@$Z%1c7%>f{@#MT;fh{54d(|OWZK3Q}qwnRr zm6U7?{v)tPqw@|UdXN9nwYv~a=@_x6?_0+*g0%nlB^cNLzqkYkWniw(D!UgGLYXrA z5_*^!jtLVwqlgCpRnG*vAG%Yh@(g0=%z8C*7KVaH{RUVDHp!6(sm3OM`nvNpApfU* z<16*$p-UQi5HHiQ#1i>deM^qp%!W*s1Elj#9L)6`7b|Elu8)$P$6yRaq=rYb!mjxy ze>K@@Pu28^b}%Jdv*&KNi%c2ohw}1Q3_O~BTrs->; z8FI#sv<|~E?_EwvagBe|N0ayWLWGXMUk(M`9SE~8)yhGN{Q}vYFI&uaM^~0nac1mB zAkd*d&uw60IJ6fr-p*ia^iu=-(!KCkxjEDCkj{26BzZ&iIJpsj$}lfqr&Tl^@rz&X zquH2IK)Xod-L^wZ*aPEE@Z7WW`b%>D0xn0k^M~ug#uy38^N0HBhe&zx(Lf z)ZL=Z0G6yJo8Y~LhbX4dR6@kL{G=DY<^P9(hCmwCU^9n|%#7yngOS5_WC_iH5eEJlN zGYe!o2G1=Ik5h5JBCpd9)g)A_egfR!N6jZg45ficCK^5?Cp4AoRmk*Tx1awzCdTJx zwZ1j{gStlxYHQ_olrv={^0M^{A%8o=S#HRAYN}f=)mpl(n0AGgy9toPG;-KfasQ~` zk_7`;@0`hYG7KzJLH<-gJq@u-vNbfg>RNLTGN!xNdoOiwn5TjqkoM>1o7Kp8@8=Y# zgLFz!N8~IF%`)kARYm^@^48+_^n!1kS;C7Ez}((xdT+H0O%Hn$p<2hW3zZ8Cu7KOR zVmX(Ai7C`o%O>6jRD~YiW1+^ZV{1RQ)Avm%F)ex(M-SIE3X7dWr0MR$Bfk*UKVKxr) zdE3wLnO;*Anz$}>WdpPrfTMGVjy>sDE)We|tMQx9r-s|6xSv&!CAZki^m>tsHbL)* zbL290%lYI_McdP3raai2x=bu>F1sRG!S$XL3qJ2;)XTSYyOQ%a*4kO;pxcI>II2lx zCEGH)K7k^gcI>CAQb_ySXa3Nf5s^FtK!_yq=h-S$`PqE%_p@L4bFLV~r%VKjLuA{_ zsNoVpTL-@`q~$s*qi0pLegA)2{?PJ9aKkikZRM~v!L7n;s~dR&Yxeq)5>=9;kTK1? z(seT%gN1e6=Bc~MHZ$kOP%~(ZHiOF5h*#W=R%EQbdeDuPhU2D@8?VDVBoqg zq1r{GX13-REU1xE_k34>jVG{$oZ2Dz!NnmU@cx$>QgQ%uxE158XWemprX#-9l;N%g zJ|1x;veP>WOsRy}7wg~*<;=6I#*mQxeHhLK5>joI1!US0#hVihA44W%#cor@;E--M z!L5J3weyiOl&y{nRzJ+;Oe#qoR2>}|I-xN4;S%i&{8Q*y;t@0=WSnP~&ZevJX_3&0 zAtkkKIn%2=*K~+J$Ik5jH}~yd@^zL!dt0Y}kz&Kr-qlZtoSZ%rIsW$QPhn;LcO5p- z<%j0>!w>YK3}yCrl@FGc@&ZxM?Wr(vcXoA^Ad@sX*Ogdhe<{SZ#hPNoE3o`%Vao|M zp&zc>bGGnpYGKRd!f$`sfpo)MFD0jmYtwH47W6^YFw#4Jnf*#}-bvpngvSGa!?+u^ z<4Z2rYUAnolt%?FhYdd9UpLO_#0=+)u?A;F9E{5!Wu~1Xsa5ukSF>3J9~9e(1{Z7V zZW^&1HyhAp`u)`=Si08=8iPwe=$^`Ywt9#vdSb7wV=NDXMuI=5f6^e0Gxv;y%gh?6Pv2kdHP2nT<%ZQMiy^g?lM=My{Ax zk3VUU)R>%)CeiSyc&r5OU*k2$rBx1%itzLM-grS{(N8aZ$3zWYGtj4-m(yFHKVi|y zYtNYcYcwDGjS3Wf?ev3IX=jah?+(V&p(Lfa?_ir=;ch1ib7#(hW_z#q6ud3*hv|JACp;(r!KcwQO%hCqU1&_>7FmOQjxROTbeWOr*! zwa6Ve*%31eswl*P-7{5}vM5}A>zieC_~wWsu^jfwZ*`2#l5*kM>#~~Ai$u+MR$9~w zy`A45!NHFU;KJ|811$hPJtVzE&fC(h;c~T$Oj}xOWqEcZdwL;Cf!{m;H@dN)Q-+Md z%;4pJam!x5!(CWqeCwYu4MOJoc3b187XhmX&sZ3%bqFwKb;+Z-^rOe<)r$S{)x^5n zk<9L)uuo^BALCSZYy#2Eq44SP)BHbrf9X#{lodq5V^eh=M*2W-6VLFb%A?<`WBO~u zUXAjTsiz$T4wQ$^N@H4Vcu0Mrev&v9e1IIN`I9>cDgHBdWk&~lJ_XBmWMKFjU0Lx- zdQa*xr-gQJ^&}VwZ!K7j(P==n!vH%Ys{aOk#T~G+%bb1S zd|mX=Yp0g=fwuPE-JR@f6IlHpB<+w3Cadt*;9j8Y83h}t- zHQG4UdK3l)8GM-cevj0O|K;&e7|`_mxF0kP*CGPHdCE4#0&LNSk=Ih?m5*6gCgc~r zHZqiGM3cXey~pR(E0(9l>bG7UTRg~w9W-$vXr;PhUaCF!0nj)!?e|e<>wn+IJi4BJlbQaDPZbG|PvLg~B$lFC8dx@Z8%sT2?q$Xwu=q4swwjuF3tz>`ZctzT8(39_ z!&&acdS&)Ut|PZshwlZey0ahs?#b0}7LatWo`d@Z@qOQ_XgROx+ z$6Oke3mo*^zl*%}cI2)UIkqIfnx*U}IWNsQX%^Mz)A{ReLH#dZ>#V5AN`-9gR}rDM zaoYwO*8@}I+3#x+H`d@|W!_8+)4fxnLrLv=^>~qfh{Ft?Y7uugpS0J4HjRx+;dM3{ z)kgyF1JSrsy4D!4XFL@eFO)y2E9a1YBsK(5=|Q`6_sK9uW4(z}=X#x^yKibLyxqfm zcNPD^qVQHr_RT=u=?!-S)ak`{vEzhqXqebFyhk%p?Vo4}4CJ#3U9dCOOsi849;`IR zW(J-wvUj2SXTZ{zyPQDt{*1h|%5H!$z+0TIrro=l2A?#?=QDRbYiM6!GwIwq0Lg_U zkm?nYwlvPJ9a>1^c6&{}?NY@oop%$dTuH{nZ$w1W5O@6V{_$b(Vr0y*|?5wYF&_w19*N5cO!^=48Ozz+|F zS*#^-B7$4$He&O4SGL^1*TZ>49!DU5)OpQNEvut8d4QZOW+tyI@x74d4>u<|Zhq~L zzwqbN*L}D7>NQcVuq{I_)qa(Ia{2PJnkeCL1F@xlSM*wf>2*VIq?g?iOp1Bh2cdaJ zx%ZRALv~8FoMmZsYfLFFGejSCU#Mj&Z++r?OqJ39;|-sY*Vb6-Q!%Hw72MrhJbRQJ zLx#-P$fj#HfcaCsEoa6%DgVK`L*i53XotOVBZ9Wdfbf)3vsBK7%6_?`T7U<%?ySI)z<#&9 zvPJFp9+VIG5}og<36)Vg^%fBC2HFf{gQ&vQ4eQInv*=~51E{CC-E#uUFy=mf8*hkkX?xEG8{46Z7VH2Agc9V{Ur(1B!yGiKBrZ>ZAZl# z@ENaK`=uYIe}fd@6)PLgKt!?rv7z~FlLFUgI}XRaRQJ`m?k*>7SVXigx;pPmNz>m) zx6VKM@Y(#LN@dBA)ikSdlGiFuouU9qdxo_{2kfa zU5-`sDd>_pXJz)y&F=_GYAv!E7N@vdb{*0ve*0#8uIs2wdXYT<3iP1$)iE`WSZ|g! zFffo#x_JLimns<7?0}7PDdGb&{EMNrY z8F1WN!Uxe0xj;_yr%#*yR9w+`rg9)0+0sXr_b%&>o4bi25sNH?EE*fzo207cJ?@03 z#`Tqro%9=S^t%mCD6gYz4j^%58*u40p@s3)pttLub9Q@jU!G}K7CG0DYn6>o;#RMH zt|A2~Sib>a=Ex(aEKUYbP})kh ziVdMy?xn?H1ANZAqOj-MnUTZ9}*dhuM! z7q8UVkCRV0!5P7hk<*H3D$4zD58#3CD*GliyAX&XA-EnY1;6Q(hM}GM=N7?!b%|Ux zs3TXS;Jv^J7`bK{o%eDRedA8D%fDY*HoL9)_%HzUFb z2NEl9Z*HTDlqvYP%Z5{ssT8H|V8I=@b={kTGDaBZxaG{Hz^dg5uUr+cgZ}v4-I&E! z=-tI9F1^0Yu|OB1$pJseg?x>#v-&#r*?1N4Aw=SfqcfBBdhfk$X%>F$S0WhEcw+W7 zA2G9oI}$8;>uvB}dQa}1lq<4MM(JdtyF1yN{vg;9Ut1pZ@x<+IvAOaqQ)Jp9P7~7O z?wneDAF*#P6^_)-`iLDv!Ac}9)=ZtMUdrG@Ue2?BrKCbh??J4e;BQSKhq!&up9M~H zrgn_QS-&*P;w`hT%TPv-5neY^ivOun)bOSo{YKFNOuP`yJ2R^%TarJsj+#*8@qzhb zmLw3dfPocs*WcCP`QwvGn}D5GWV|JB=acTTd$k@m+H{ujI;1t1pe>vasd0X*wjUO< zq$1}LGZ{PkrQA$NDJC<-ldMDN54~>X?jnq&{l~^4LkZ*qcF8a}$qU<|PcdVM@i=y=?UC z4GN6WWQR3R|3)xI)5TAH#FrrrCO3$gg96w};K3`v6lO4>#C2l_ z%j*_a(v2#nz=aWXL7(OyY`b~@CP$UAFN4TAed=r6sk8KGv~Tic+-}zygq|b5>ow~% zYcGDIC1BYQorl#WuN+%;%3-wqcb-_Q1|Qw-e+NAd_qCK`V#9{xhS%YXDLa?hTH+S? zG32*9p5zN9ZiIlv+ZtSDNQJGqk)38bIgbXZ9rfeKW3nA9#xfl z39y5ZVThD|vSqppYL;#h7QDVZ-2V<(;qbv=`YVb4}@@5x6B_2-UQFxh#EqjBC{M^jL%*%Eu7pK?G;Aa3lh4cb+D@woP| zqO|fcZcCDK=rF}!MD$Rqzau-VIR9Lcfk8A%HS!P3-@TTA;T>%{Ib!K`FQznGtanJS9yI6&J@SCg4A)nK^=v2-{1SP~TEv4$4V3Shu=qXd6t^z{z2v|8@nFFQ z?mLDkIVus}{wfK0=b4e&s4E_fa6vOzMN^?=2uSZsGdK|NT{w-_1MGt+#DmYn7^v0n zDQ`s#s2fzV6V7)hX5vq;DSB@HYv>-6a)5R*ZihEP!FFHIKJ{%0KB)v#hS49=)ogix zdIuH13)ZJ(=0Z*rkoEfCknc`RUOkw7d4i0|_LZe?gB~cf)R%b8MYN4sTJGF?@zH%; zmQEFzXenuCS#_A1Z!e#9V!u+o|0xbFk9a?;$81)8Gz>w(XaZA|X1v}j?u)}w8(<60edaGLGu>lzykxY}8c(Rd;K~@(YH=$T(Jro>a|T7qQrc4~qnO`_ zmi~}?iu_0)luZm+?*wnd)&eJe5EvF!_z6vag@)`B;SE-Y5&G2;lFOV^Sh(nLU20dTPXIK>}LAi-ygprW!XZfX(L~q{EqwebOg&}E8(p|63(4-15B@dQ zbL=o9OIZ2V_kec!s$K8Jtn*-i= zpeX7=*va(jS|Q(Fq&h~ElD|16|9+ey4OyojJeUXm<(s+iEOOGe=Fn;gCSeB<@LU@3F(u>^K_zk(9dT71h$}?rSco$p8EZuvGb?*v}4lgpRM}6#xBoN#( zIC&vh!F{5{b+t)^@~`Szy2okaf-lh$W&eH!7X0)E>>A($f34W0jA4LHX5G$r3ICtn z=G*$&2oXchfJ_>?>v1)?+)!9BzG$i?1Rq@AnO#!xf(qiPF$<--IKpO5p4RWJrY;^w zY3v*VkrK9mlxaM}ZwSB5CMUeLgLFRl!s7WC&2w+>EvWa~m6Z$3w$CPOV+#|gF0#Bw5E0Y();X4~mrDeJ zfun#O>obY>6777eIm_}-_p{immY>GK6MGZaYcLnSn6<1+IgxLH!nSo>d16uj{CmSw zr5a~qQUF2^gT#~zG-q-KM_+%DC_em6sm6c;E1rKqdCtZsW%b%)^oLJ#vyud&SEagX z&Fvu32M>|(2-;DaEopa)R~ZJTQrK9LYwmtl`-Brjk`hg(Dzn!rx;v0hm)0B(Pn1d_ zWoDplq@ar->B`z)<6z1FA!_6mU!v5QO~ z{6weDz2>PeQW3#*m%2a}ifQ(Vc>5zW996N$*1a2;3CcKOk5Qf z@txI ztJ$ax3D7s^m<$n6H2m#gv6OSqr*V%?=s|-s*pIYbW?uR}GNfQcem{4d+RN{jeZ__9w*%ODkJG@r?LkG$N{t(7xXM7=2&A&)yV$X3qNyKld_ZLLwL)8 zA0ddZeY9wn{ox*X7VM3VdowOVS03R7;Sf06AEe>x9-H~n@R}`tifIubjK=j>xeQsW z3SpXs_^(A(kjwS>qXwD2l5%4|o|I64R3t_#Yi=|DNFt~WP0cT-oMtEZ z9@X>1QIb1>_s^wYFJtR%4ty6-Ol{_fxs=3f*6oacQ9qn@_-%wibz9*x`B?#&w+*XH zK5KDjb2U+OT>0xts>barKaTH@q zj7m;;z456C1mC-M6O=IBC!M7#2J?gqpm-ZgGZL;GOD)|6GLcsKFtTN)F1lpLz5Y!RJtLd{i8g{zV();>DJ zo(+8lS%RB3?Rl^=g?MPtf~(Y2Bjv}b+OLrEY@V}j{{><~Oq}n{x#Qk*Z|tK(8oUn{ zGu&!xk`^>Ddjw>__*}|azjT-^1zuzMLrXW&xiS+R)yAWxOPHNQ^?`R!7q0}ncOeut z_^?NJDM?dgDPri;aFsFq#=>m(?B3WfhdncZua^YtWC}^K;ZukCv^W!a{|l6unZN!E z#erw*$EMV~YdOe?PC`3j29t@Pl=@t#Vf|9O{_N-Cas9^MLD&8HEH$YTuQFE<^Xceh z4{@)VXZy8`?f;Jb#SDS6%86Os8&wfr2aG+`2i%5r@$8*^%c47> z8FS$e8|*Pg?e%H+nsUsXkhOk@%3Hd^LV{CmdLN(8aZs3BP|a_B8|C!txp448qr7vv z+nzA>pVpn7UtMfg98v*D`Vwq`8KegSV zG&b3SHgEQaufqF^dkK`s^#bp5r5YA7o%d5cJjqqNVcQ#Tg0?n;G0F!~YxdcyeiUJX z6IgK=`+~8%+u{Bfqz-lb%)GQzsy`%C*fN_pxo+qsGWDF^mJYTqnOO`5&ERghlE(%i zFx>9iN09Pdm!g_|N!$dELlI#Eb}<9$gC zl(n0N(nATeUPGA6`230y)uBYo;7mcTl8tFtJFQiq}|vLq09gQvC2C{w`*)<`)$#w2NogU z@b?;t-$Jt2*X4o4HCK;7o%bQ*yHn>=VI=Z8+~#ZGStCRM&X9o!vRZ7!-cluep3rf0 z^N$R2&l^^R7_E4#*Q+y44vRj{i!Ph=mgivd>C@$u_hRekdJd@~jRyiwiu#lk)eREU z8h(YVNBSlk7~ZhT5xD-%=BKjyWVw8T)COG8FOC}pkYlN-%o_iXSc~^>+Idizp*8D+ z0My%|_gvE`_W;#@!;8lrF|Pd^I(|)ilB-cL`6Q`s(6R5UjMySLhw%Q@cOH8AN@f4A zN!Xk6ytpP^<|QY3ku#ne%ArwB+i%pZS%lKBGYE!KKR90>3w<=|tkVpn$S1AZaiX)d z9#W@oI`=i;y5zV>n**oA#!)hcJCiV0R==rX$dK5kj?=CK}qQb>29PMLIr6-I);>PkY=Q$yQI5Int@^Fok8#C zxu3oF@xIS*?{~j@|Mqbo^Ve0Yt~KjA*Z2IKYtb$(1Z-qZ4%{LZE!Ugc$5E;6z1AMP z@TrF+>mSCalq=b+O~vUs(1W#em1jWM3Z_i}q7NyEYi^Jnvk>z4O~d^uj+)%?!B(~=W3=h3=IHc!RG-sbEB zuf}J~7}yVXuRRMd0~5seiONIZv}#GcK7Z=OV6#8IWHKb6y(DuIB^c$T!$a@ z9!o^NUnxCh@1OKTEr8`<+H^?0{3-6)R^(`|24_2f!m;Xn5HZZ>A%tF~fCa`uU=!R2 zrgyu3c>$Ik5{#k>)0>A%(CR%IrK;p{Rx7;FfU?6E3`9z!+@kiowaqnPtULBxjpBNANnY{vW}IeQ1be8cpQUFc!@#pOoi zH30yz9Tpa#!yxrShUU_0<1@;&In z4kV-S&{VAP>&bI9#OGlH_%b31uF-UPjx~6(w`RX^f>_}>?aVk*+s?O={gbO?$rHWD zyKRD!<9&Hxz|O&-Abbo`^C(1>Tr&Sux)@+}{d$L;@y_Wv1N#@{jBKfK!wvdMeCEP( zZJ;h>lCoB9H$OM6ULQEK0o+;L1Oa3`J2oO)M>|4b;(6c7w)^cs(gnkMOyeD7d3J3Z zk>TP4%*Pi*`hMoRX-9Wbfrp{Ju!xQss)HPGaz2#}*m)`Ayw7Gx??^NW6Q$R-3EQ>Z zrmgN}tu&WQd}Ad2t#3{`l+`q5WCQZ8B1styt3KR#C~-5Fd5<|~9PIG-hq34A4zfO? zl+8{^?*&hNaE@_^G}~nJpp?JuxAs-kO1h6XCHb8fw}e~wmBkYjmYUPoLPlSgW@%@$ zNa|(hr3p|C>xv_%@hWjP=$9z^|5gs4v4{j)e!jcs79aMb&xa*ZH0^e>-u}mnHcokb zkvqexjN20+HppODmZ7ufVq_uVbOhN0C>z3@ont z0gY6TW$g#(z=NNy<6*uOTTu8lk#O-m@MH2siuG;JF(Ip^J)_5x$Kl8}U1+F()(LN*JY8Mmaw78{0|jD4>gZo4D^}|4 zo?%kGvfFxnkmpR+^FQNF{WtDJ|7k_brf9;cRX%Msg+p6r7P)x$U)nkqk5GVZo{0iC ziD;X6YDTDk=EqPqQ-z3UzYYhpZ1i%m@kB#Id&#?D1NEur6cC>k00i2`rn{`ub=@Cb zV&Ov3!vP7isBg^bE@79(-b*%vEw5jZ8q9lQQPPJ7-3O_AXj+1ni#Q3J-O>dllP}w& zY*y{cmLq?vL04#$dpLut7(j!LFSC2Vytp2|FVn4HTGx;&VcfOn9%&#uMjuroiP_6X z9k0Udjw_?}FNUTpZF#=D4ZNI4Cg~u2Y~3PMrMt6g&7uL=q9rp()X^CS$So8A)!@@c z)a%iT%-4(X=N>Pnhx-7@_A!^zdO}jzl@Op(TD;2_VX|&WmEz-IBf&vnpUdgTrpNe2 zSw#?oWAMa+V0el5DI5)cG`xlZf-*ZfXw!Nloaw$>N1rq)FH_7MEu zrmX)V)Lw7tgF~^r7gL4a?eW9CS9z}VLa`ddhwQbB-a@d-RcF#jiO50{QAH4Vh@H(t ztmVwCEF7n}y^=9c71l;_cxRrIh#f)1B&gh{y_H>et1WI;R@^6=hW6Yx_8I$x&KUv!I~c(Fr)n#A1myPxUR3dO>sXo*zE?UKVJ4 zG&4G3YGY%sdz_8?B=(CA5bPyEC1ZXxFS3hEj^h1{*hTNWe*A(W=xjY9AXq$L*ff%Q znP?WpFs3Dar+yM=&l*a>KqV9T@L;YD_6_wLL!kJiYpG7h!io}P^7u9;KHm1oO;R?$ zl2U_tkTbzO(@?~pJlCray7ou&lSdCM+0n1*0Yply84MCo$w=nOo|gd}P|CUuhg|1& z)FB&=dC(n?Tem-Ax^7XNVcbXICBd#Q@tR|T3*S!yvio-I#A(0|LF_@RWWyJR%UXc* zi#5+l0fKCLFKj$OO|TG3Qq=F_)=_JV3C5f^;a1_=q5S-n!G|**-$;T7+0r5B`)`1Y zD2u=9R=j-hzsWZiD5B^`g_pthtKRg#>b(Z)%s49Dxch+i$ykop4@!QNA0`}|_4}@c z&|`jGlH-HfNCPS&THIcCHpR+wEs$0|mY3GtOeyusbv$iUsE#k5yhGMnP9uE?ZTLp0 z!|ler)Y}bEZ%NCvZ5^ru z?0?mv_lospSv?1i+pL5%_Aswl8F|=Q{(a*Zts$yndmqzF0^O;hiooywn9sT7T#1wW z0?@@NpXVL25(n#c7_@RGd*D&64t(PR$jF<$h6MerdZ2#&$xrpV+$MMo(~s8DsY(&~ zROUKmYv9lXqy}ll6#x+XVd0=E(I%1asXYEpUzsjGl>2}Q&Voo2NW%nUyoE?JqU);y zz(qz>uT1gruF8kCMRC_Ia1Y?VL_5v0HX_m$@z=5yl=Qg!pt8Ni0<_J+n<&)}c!!Zu ze5rDpyRA4*`BCii2b8Dy@)3VjXHx|;7D$LKSpvp`^Bw{=bn6@#WzR=fN#ZT7?PHr2 zW|r?%A}ao5)snlHI`&my1CPM;Ac#k;3TsB)=c5`}z>XcP1Q-C5m7+mQ&Djr|?3>HOUGg&Yyy0PY}Fna^W($w^~h&|Bsvv0qu8=3W)$ zz~@5Grqz=ynCHIjHDT6=gaey(YsXf=X9!!rPWt&uTQV|Ba?|SrA~ubzDE~`_!f(~a zw%x391S4;{QQ+l!v-Vo3lV-WroznpdG7}e%;630ZV1C!?Wt48RlCoMM_fk z+oU4?Vc^A9tm=f`Vk5=!Jc~_kIWN2C^^K4%w{YJ#+Z(dkKJsY%+I z-NP-m_uZ_pFa0MkM2(+_p{1h;(n^Gy%XRTKFvDVjarb!O1u&U#83qzYN;M!Oy(=vL zII={uhF5TI0-~{jb4St`eLQ>L>RJQY8snF;_r!|qSW;Z(zJfty&-p562#nD{Ws(cll^=;C#35>_5z9}`}!() zI?;>)di z3>d6Sdu;1V$B8UrJF_T&T^BUM~uCszbsSPFUqk1ZLqO2^)K%hptxfkmE zwQuuX9E$T#9MvAfD?v>zbr&&2>;UH zZn}#kXau_!qvGO^o3JLf5cmD@G0DHo!b{NTDgdu&6FCO7PyM=z6l`(_0Isk@Pma$}bAZB=kmcNb`V3fU1&K`3VaCMxIF(;jambfgFgJ zORk*-k6|XZSF}pRiKO_>FY^P}IcP(xFIse=^&tvQ@Z%z=K&V34DySnLdg=hn4H#_?k*+(=d zvinjwHcY!EWw%^lJ9lJxdg!E3GZQR+T)KFRmFP1W+Elm`R#v(X|W1+`7u7E=e#-7mG%3Q zu6(}Ht)!w~nxOwN`e1^ljvUGtrP_9-ok(pURV0jck}|%#6pC<7sq~sU9V%Chl(0Yk z%p7{zD>B3FaT<~hV=0?^L0CEiH4>uI&4CDQca52iV!3$xiah-+F_K%2KMSODAAbyg zw-TvS;@V%>TWWyosk@6`a$Bh_AC(UR5rBVx->Y_>l6YpeJ{JO--HLS^?7>DGi5w~X z9?u6_9?r7JTL$Y#oIao~rAo$NGU+Sp0jr7L2*jtk@t;wP*JY2gzKN+{mt#_qN2vkn zSbQT4)>Ot93czYW6*W^+9)lkwu5|apy)vGomrei+-PLc5EC#hl>gvbuQ(tRj4yj%b zBOiW~ciGUBi+rvS_NAbw$EvxEYx~th((~u>K6VsMuTfQm&HibhKRc(8@IR}s?o5uhjssX9K+L|YQ;Lae0cW3;j6F# zqGM~mLiuowfkRvw;Rqpj2Z2MYPWDOut?cnn4dRgoH0V4G5WZ6lI^mg$}h{a0A|s$STB~7JBiPGe^q?Xmi|8PAJ%6iA$AFt zuGN=jf8o4|SsMb3WTf4DW3X!*=V3bbZ+7GmsQWr5{zGzfOZ7v{p;cl3lxbm&wLP)0#?J=DMeDq-@VTt4s`j$s6h%N_-}W=leM`riUNvI+M^uJn5XZ zqI@N&bEXEI;4C->_Ja!mO?|gXt+98)3SpYJ>8bMvDTSYwmmUvptU-;5*dPTZ3~66X zb?|-&J+Kd4W1hG-m&E#FIThbkoRc+f`4a(S^SIKAP8qHKBcLp`?6aAvXjNN*nOXB$ zNbE_Raw}po&4F{31Vm0IoYaQzDxXgFNRAu4d@l&!^d5S;`JJnycxsttT1R4P91{YE=;VT6j70ir)NHDo~hDm^)0TOf^r-%@sB-R`gX6j+oC5 zfOXYeL&hMJ_uj{bXnt*f~8<$(*Im&rqrR;7)CB(PNkON2l@!)VO0uPE; z_i9ABGv@KW`I3A_a$14UI{IPFvF}=h_>85Y)Z&D5N)oMUzd_x&7^MQ~n3*edXVF$u zSuUo+uFOdT%8VFnwOT&rr;mQw9;|n_(Nvay*;C)r^H{v}Sn=KSHg!miLK=>2Pkwe0 zSwF{fFWs`&41FxX&stwfHpaXf|Vkc=vF0))oXkcv%>8qmd~~4>7}^JS6?v z19m+^B&tAXI%l{Rk*)!gddh7Ri||iOm1U>A`kfOrRLSB86MUk(^36+u*w3zku|fg* z5TcBsGBsFnjCotM6BFYOI0 zcncUOijlA3U)-4rbpJxFqz2??N_!R@ZWZEMh?p)jzx^Rf_e!w<$C+U_P}xh(rSQUw z+zO`iOfw=|(sBu}{BKFb0x5!e0I~?&?NsWzt-UA*c`>eB;by{n^LW3de;xbU&A!g)I+GUh(GlN<<6tlFFEYYR@Z7frM`py zYON=dT6J+q<)Lx{R1GUSH7^EOUu*3Qp5A*iIuifr_bEPr&;fy|NW9gxPhT;Zp(e!k zAh}5^WW)Yc|DaOucE=3Bc3wO5N8;mCsq0dxf;;%Yzk93 z707b)^eeo?iBFeTxp&M+Q<282xv2d~-%ahF+!{T4jkGvqjK+{!Ks5R>K6Uq-h&);auPZXZ5Q<% zD&Oj&9h1l1fMj|3Ks@}_sC_>&CkMXR#@j9ZU%s?p-gT03`-US>oBT>YV9`uv)bQPH zfo!4059G7*bnM~|mHCz&&jZLu5Lw;d{}LTfRXa7tO-wC*f9rlNHHMo?x9o#i8!OVV zD5@YAjM=EbhWu5!zl!r$>-^Ps{|Wf7nC%>>Bm-ggnbrMJx2eFXQrW|^yg zl49c6ZL9epyrhqS-S2zA3HK6QJkG=dPo}u`+pMX$Gh4nW*CZh{ELtKfSchsJWFrc5^dsssE55_5NYH=p1r-_(?bKl0YS6J5u9=u1LDLp!sajq?m`{lQTWuYKDAzemwJUBo=T9bkmKh;#sgD^RR} z2U}Zt0|0#N(4bVojSa-=?gJ!c&z(XM78pWH0an9`Pr+#p+Xo2s4RN9v*Q8Df2%kjQ zETFU8I@(t6>%PJ*0W@_PyVpAh+Q7-nhKYr0Sjnl|_4R8YP_GUKi#FHY-fCjabe%&) zSvQgp%z2h*6n$5V~ zwfYgA{`-4uCd@ZoRCN+}qq+%jR3EfPi8}@1Q^hclCJ+<-Re--*;I9_=Qw#9* zv*}iJZq>c6DAs>eleRP;Pd(L9!^&{Nt$xg)6Mmo(#894`EbO_>McWVp(95F?h(iR3 zMk5162Yow)Xa~M*Pi5IjR3Jw#c3&UPRrvy*{&<^TE@Tq3e*J<$3RB`}yk700ZyHZ;3gNep3q2F9k%R8bn#$`7H^3{y-CDJC8XUg^+V} zkkiD0+=#(AQS;BSHl1A%^IC_O?EHo(Ldp{k*k;C^O!QuYALSeUP!TQ{6zQzx18d^Y zyBHsy^(>_+7!j}|q7ci~5eqx)kd8P75ClFeI8vl3Gk18Z-Ht{4&AsS1k-Hr^ewz(j z^)>na7A-F#_$Kd?25-^gmyf?@yY$z^$G1cduSrt=8FG)WZoKeyU z9Hjp)j=6{+{l)F<-OUj}1`np%`7u#v8~7Nyc$(imY38B-vCMmyBANJH=GIMM&W=s> z+nDb*MzdbGoDSy69ju|8+Fuj{I_bZQME^p)JAh$vTQQ5}9~~oUZy<4w4jnTX}qHQu|pZ|PoqLy-Xg0bzfi8^3@VYK16$Lm}q~ zIW**bWJ{GA!(*p`>^^}$j1srd7vJGEnre`GN6m9v+Xdz>8z7}I5_}F6MdE*Cxsm-! znhOyFo5m4Pv->I#cO==Y-}dJ(r%t4q%r_L_H@EGlV$mtH`TCP)7W04kiTb1bP~BTG z=PQ_TL}l!gcxqZy5bh&`en1j6D%#I~%p7qVL33~;OLdpVy|;w>f~v`KVisKyd71}q z@c|RzT@6w_NyLYt%<-l7eY;cg;+4Yd>F}Jxm~k zBfWar-?wb_=pLP%5&Fn}R6b>B#Y+#e5=(rIkeW-`IA-FaB|ZznH4w5nVl6MmJFYOP zPpXOc=<)+oletq!Tw%pXr=9gRC-Z$}#v4iJ2AX&!UJQ2UjMaGUBf$HkuDhuHRoic8 zO=b6uMAF@NL0$q_CW=2Hsx;MSZ+l#9b^gMZ63I2EdEM@{{m;Uh|I>)n|2T2|SJD25 zA@qN}(ErL8O2l@^oGqE*>;ANDwGvf+vNwOk)q71W2v6eb3ni}LGU)>Nj@n`F0n2MP zfou^76P%WqFcRs{%C1nq&KV6Iz_}|Ea<`7G=vXloc%svFGt_yTCrl9Ew^VFKh`byu z6ukZ)vbr}K*U|W;O2C`Lyi;=@7+qlxuaCD+ zejQ>awVLp=r$Oo^f-XUzW_q6{3{FCOsWbLWzVY%_Ntmc8ZT&=m(Wxdfk#BF<=9L-z zcnSQa!i&x$z%oJl(cp9O!{9~|Bs7iu0IVv?{SA!n#Qj8x2x-!O`jmpx9=$BHEaR7r z;tKne^hq>tnDlp9C%;IgJVP71Y(peP9QQb*GAF(yK`GnQ5;OMP%B<*%npKQ|h zXhyMO0Ft-P@cdApSticZ_hw4T;gsd`++Jh*3!2~5E~r-!7jq=B(GB+s4Fd&)jjlJ@ zbmLPoQ)n!GC=ivj%P9#BAVZPwx}l5zU%|hsuv1~w0LgdtE;r>${#C9UM-4cQK`bg* zDgFlB{S8+C^3?o4A*lZa$!tf&)<%(z=YUK3y6q84svmQOISY>=fRrz>BRl-TbWHYe z1vrWnAVqbn{gD0xMBM6GXb7M+5aA!3gce>JS5kj@fg%@8FMXvNRNl=}0HYGdwEe?h zE^|AR`?lC8i{JDxf;k2~&x2MPQaN3R=UwDtO8P|!J<$N-28@{y#sV>MZ|VFdf_d8! z)bY!a)!#($IORV}1V4g5^v8VQByDniJuG2zC?1v6w~W9rFWK2FKaE6wrNp|Q=<{uE z63;toU8}BJX+`?ei$2vS&;J414FPt5S@Hk9Fz*8J{}RmmC-ArK`8ddTDLNOe31mib zx>)kqS~g1P!N?m3bMxHY`WgT43NIcvc6Tx+k6F;9e=kLN$i|_v2HhFAIRBB9Exa_? z0Ki`9f+z|{FW0lRg(e8MiOP^t&hJ=^ykM;eDVMRprr$JfH7x&Bu^4D|J^Js%ai49A z>j_Q7QMplNGkacl6S3|2t+q1XcU)oOo`s@jVc1}jsm9dD_-%F4_21_^chf{KJ=Bq8 zf{ogvIy6&h3CDj33$Rjl`$dGQUdKMCVj%g9!Hlg>zWPodInVnVmWMP785VA>d%oVm zjr=eB!AG;J15>ip0RUwBHf*6k*8aK1XE-_*VUAYCxy8bR_*-x^y4HoAJ3#ZvQ~%-r%>@u&Mf=e4#{4JA#>9Z-41^g|L#sJKLBA=-Jc$)Gd0l2n@LL zkC=`|iaut^Vz|}y-0NYG9Zwo=n zp5W9}P&aTDfz!$ia*2UoV5(EHBfwd2B_kxw+RTnAEX?|h{>iIH@Xzt2j1l3|`xa-z z+G1-4YalimA8Q24S|O=xqd|YwxHi0tfLwpY>-15inRCisdLvj}Zegas^RlD4{n!MY zvWT?=yeX;g`h9yGi@N?7wZy_l^e=slcn}l@pZJ zup48W`<6cQFM<^@XFzHw?D_^7Vr8r=k0h{>mN(J*>t95SVrk+(-1#2Kx;8F%k$zFq z?D&IqEuN%wTyj#Ihr~*qy)9dIi>JyKF>ywqpJ`u-d#uA3G|U*kmJ}_=@?&zCbSyma za}ZO9z0_=cSbUU^6rP}_pRGcf3%y^G%W-tAzq_Y(tawZ1Sh3PLR`HhzYWd!oRsERm zwUQxqG69pxxWQeyafAK{HBq&j2&tM!1J#=S@si^H?`;(Fq7Wb}f|}tGQirJiW*7M< zjd%?3@7y7*5Xg9raF%^jy&m7y{DXAWS<($1_kQ{Cp(ZkO4}t9iRG)U!LOo8G6J|mW zlrPW<{0cZ| zM4qOORYy1<#H(MJCG-E8RIO!mAK$wA#gB6Ti61?w@ss#MI6)#LRF{0$Higv-=EKRK zykJJ$X_)F5ZjYDnE_?Yv{G-p>!sQG)51hAIo?GGR1PM}lqrpqaz8$t7?SnMpoA>Rd zB#vJk8C}{ob7p9o&(6wA}+g(6-izE)P0d`+?4=h`p$*)UFa z4-xTjhc@(Yj40&w>14rQjOc$uMl|7HF`_|ht?mB7w>=X@mI*{pN|g1NzCW;=cbK@K zK)tJY<7=j5(kmoVR^?|ls>l}1nLvgjsF1oBbTtnE1ckPty*y8%(bAD5f8J^7*hfLQ z=gYj)pmA9NdjuOd7?MI(V41e5zB5=%_hB%b7sOF4Y~jOxc6k+VPI^o2I5KPbZs3o+ zFPb+_du38h_056GoHguR1&$Qe(;(zMr$JfEjKA(d=KX)V$G8;M#m8Igf`e(qLcl*=on_OXPFdx`4 zd(+%0>>v?-;CT*UKY-?*vmW>?V8oxpj)UTR*&1vhnL8ohO&ea0yxb&{hf1vXZCu?&u^ zv^=};1@9ER*RW$ZsTuin{BB-hEj@+UcasyLm;GSoboF`^2B&N~!|4UV))rV79CBw^ z&YLD{Ja?7Fi!QB^Kx^)gzw@k6k^8o9wZoLtlXU(>xgyRYi1Pm`ELLb8w7{g^ATw<1 z^L+8mNNb|V&ZDZt-MN7hJC#rcTH`>TX4-m_%MC^t@a&S0jUCoB$rh^1BDhq$5^oM) zj_ksC$60BjOX5xpkJ4TBzAy$^*$)v=o)4|{+P!T%y`qnUeWhqPfOil9tvuiu1Nsqw z!`iiVzNX)@eLt(lyOkP^d4tVMF;R?8;FM`lypS+7)3+)5#jxBcH8-65jY8eJ z{~8^@_vlE+QF5n01=SKVlpDoZEGg z%+&{9U69y%Q+z?W136EW1vEe>4xooeZuTBt*#U#{9zdTI zs@r5a3O8>_@GiXI^ml;o}26-?b_Bm#5&G z!{}@xHUW4VJd83Kho}0qxg_OuBa2eV9?_9D*mKjISQ8_6*dz5kr!v;OD9^d`mxAKj zD!zEF4~qHk$w+|kHE`{};qMsWXBE43x<4c>@;=g8W9KcP3?z2X^?<&qTG}b%h+p~YQJT~6Bh9mY@pIC#i zLsr(dCu^sVigMv);G-U}$O8QA{<7YH(-Dla-bQQxXBk$w+j*&oZ(T=t#Hh6gFPyz$ z_uJ9gxgH{dStOp7NH;rIqt4yqr~00xK;#(~A2k#~!6RUJ0x&7l9C$LjwgG|&^?GbT z$eS)-GO)Q_U(R%QMD4J|ca?4r#)i@WuhwhWH&THa@>q4)6~b$Wk(zeiSvwnzulMdn z!!HHF2X}p!jxungu;SgmV8zG64WgjH8KLXeoG<+%;A^(tmkcR+L%ycnry9F7<=Wg*e*Wd$vJI@$) zecuxdc#MPgiKOoQ;be>bT$>{{2+ob|3bjpIxeh40Jin8Vn2W{&kMS8hy2(}8nfT4D z)>rSQK|c zd~g%OATHD_d{&&6zMj{Il`4*d#$GK9!Aw^L)0cN*oz28d#PXi|HR^|ZNKjo65V|w9u%JoT;Pdo0QMh-V%FQV>^{+!Gvs))>EpAPDZnq+k@DG50f0TjF_a>g4@aT+TM1X9{#{%-gg(>T^RgY}IdL=`={rlP3_ldwub(|$nCtL$9kgBh zdem#sjMyKAs0qsRU1+PFAP(elloda!(4_9Nx48K|@?LLXM6bS;Habk*f6!Tc z6fG-Snc~6&e(H_bk;t+6(rZ_GpcC|khx`TodnzZozgYgiLJR)cz>EJ79u9`80h=4o z6ya9LC8yaIJWB2L^^ctDOpCmGj;+Bz-@(L*(Cw6UDC3x4!Odm3Q)O~(2qx2pM_i@OLVJmjYvdsIM?pl0vW@2I?hq{&dr{ID?~$AjUPl!3G{kt0)J!nn90}k+7KuwqWRHcU{i%!FY-Y%!~@J?R<1lw?eYwqr?Oj@qY z;Jc@^iAo%~LSb%B=EBbHegfuq(ALGw+}N%{Hv ziK(82^|vBq$@+QB98{)r8bXU&7GKPb+&xWIR3ELIWPf(iz)+PrzW8mdqv92Ye7Qqf zbjQ1|LARp>0Y#mfaYtbuuLudIDe%Rt*jaIZ9~;l?)&u1iV$?WB)x+mIdktgbxRr>&{JzS^$q@A5`lcw zH(EVh>x^1*7G5$a`GK|MCVxJ5Rz_>B_-x*%^1E>`90j`me7up3{?3$fFd^53Gh>e$ zHT(XuQ`Dc22VUY}{<%Vr+t;Z6e4H9X`rwboym@!Qz2g6H%)mp%BJ1&8m@f3LE$&?^ z*9Y-||8T5eCHCicy-mf2q4lSC|8FH&PWMv+C(JFTw%?X^k?>g2Eke;*_9*oQ!_)1dx9NkefD(&NCE|n2F+kLS^EtUAN zu3^I6I~3v8AS$bwmMv`xta={|6?YkAVlEa-wy8q3ZR+?wR(6X~B9$?L6wT>?NZ&JA z-)F~XyKFv5=CmfU?U}KzUE`X5K|x6dV7KZ{wGP@A&M+i@LqEf99`x~Hu>FsgA=5%T zvcw(p_Kd58SFAcu%o(}hK_?*iD`vr^q~3!zSbS};>;N~w&Vg&Xj!Zd5y{mefxw;cy zZBlh84$Ulied;<{<-is%HE|da*?E5;exW!g(SSWeO0Bx;@)eHdOgP!dya=hv=ywmY zZ|ZMdS{4YCHU~dRbLW88$49c*Su+^)_2fXlYO?0!Q=h+12dj*RWPEbmox5~+)WjFF zHm1DNgI={>@Mz3y=S5XNeeA=p0kPJM!x*6Pk?`~Jp#q26`=aT0n}i6S>1)Z2&TBsJ zPkOL7Rvqp6Ha}Y}OyX-mfg>w>Q)NQhcaKIPXHK=}FLJAy^9Ix8Ev5+VRtEb{E1fi# zTcspx0NPUQO$`a6@Gp|gEE1bKcS*wYd(rJ8mCW9n@+!AQfGUD(gtM;F3egECLx5g3 zmMR@~6B(#`lLQQwFE$j^iK?p~oqRhX^*nh`$9~?mE|rP5s>3-k(mJeyv#8@wO&T;jK-jYh%KzG>sf;CBA~KHB zoRe_7lP4Zt1nmg5-um&0;DM{A>Dl>XM<^(;PjJ=1xBv0Uvh{(oX&|}_3Auv&10TkX zo_uBluNAcISxb@W#+?r*glTt68xKXBuII6}9p9_F97O@@k{Kpnom}cr4k5N>m91=s z#H|nL$S|`^hD_*rxlY$@5dHw;T08i|a_7%)`&{)$R?V>Kj3gD78ciH&=mX1} zP1n;!jR78rj=&`u5^v#$k3%7P-#M>`pRH!jiNF)ymUyz>K)E7t#>pf8PCNH(M=AHd z^>F>(bkEupDcWUu-{MHLHtqN7T+(kf4`UW<*N;F=aF|gM2RYnr4UF2kCZ#cJ)2=|? zcEx@)y;3rjqB1uLJP1@AEh=r!iraMSf;F_ovuzx(cS(}LPS39Tg}$Tj)a2~d>~FJi z{q%*m*?4Z2Z&2DBDS7#rS2I*_8OYd->j#{N^ZOj{DOO2DmQ=x}%h*-k1zKkwe5!{~ zx`|k=o{JO_@f5UIJ~*-mT|T(xHy0IwKbhC-^N6+RwIj=t{-|ATB_6a}Q@Ax4lpA#q zo_cORgzhfA%-yhl5>EW-eHiAcH~bQMT)G952IWk+|JKk-qol$NM@3jwGz$ zQ%Y_9TeykLY1&i^&#*8ibyJ3NX5q93JNP|fHmOaEo4tenJU!$)*RAi19 z2Cx$u9htvtYx5&VL}reQM@g2tBT(66T*UN`67Xo`(pckz`)O3%SR8}bi7MJfoDl)} zr0&RN%mn3+=h{H1s?1KL9*Id#@Sl5j6I_hQuAfI6a-a)jepT(DOX$7(+HJ&7s^$kv z9_$I^)=I1BYX!Om&YHNm$texQyf!oa0`=}%@eN!*tiz|v-0a*6gA?S3Z zt|PC1losKHgQ4~pL&9hSO=_D(D(LR-&3O7K>n|yVNKftwdTcJ8TvWwxz1Nr*$4Y_X z@{xTtT|NJXu|#u!rf~P#pv(d_ToAFVFbLiJ(Yb{A4rckX&R2^U=HbK^qGneF&%{2m zHLM?;JWENPt9Qv1zkc=!unjv0>chY30`phNC11gQ zR0b^v&N?YXrw(XA-b8!toUwGnTA>Emos;X*PVJ_5lskBHQu*vn_F9P5C+Zhvgd8b+ zPJKR}ZN0u5WW?1V$KNj+;Zk9)+Z4Rcs%!L}3%xVzP4Sxs%P{)}zSOCJ37sZ!6L@8F zan3x$pgCF=*`Uo!=`;W+ZfueK4cr?(2&iY=TPJsC*+#6oIy&yg`n)PHesRFB@E-qi zu$@2y-J2Pn(RG^m{78+_O){ckre2L9N1)BCTzP%5YHvI5MDMhyh4hL5n6JL9c9!d% zYs(X1{uhbC@Yrjfpway#mE_k!Z*dS(%j?=k$f41;*Zi#%&?ury;&~2i1Bsf@A|m9x&mnbt6I8 z$ejy+|E9 zQ#9yGI{YZ1Ar{&eT!5>P0Sd22NsnCmK3%;&m*;zkU#@aY$N#{~rjD_%P;&Gq8lD_* zcKsf|i}tY828H=<%o_0Y^c=Zu>1HK+vjmp1UtbB_2X{|?#%{dhM=8-Q!=Db>9(tPL zu0UYY;a0rMLfc?K5c_?&JNY?u3I$Lg0I3zdIK+~bbab)95hd}`RcFlvP|hMg_A4Tu zI0G?7-uq5N%?(3#LU!HhOvGI&v11{(Ii?my_71{p$~xC#Rl=_2$(^I8+MZ2h+QtrZ zh@3AcyNrhi!#aF6on`Ey?)jkyY?ok2#MM?tu0F?^+XSOD2?O6uP&qm_v`b~wvga{w zCMBtu*#TVqYFDmdd7kgV)m{9sSw%Bn@eKoaG*D^FDub+`dN>m@# za9bkV2?t6un}haV&e(PU>U-i7K|UWn-r~4rbTeUn=VSmZe`1EL57Ho5^_Y|%;4^B%syEo^)BT}_|)H{r#yOJPl_j9Ee zYMfeBKi$K<-R_H6pLPFI%C~>nsz_XAtD0|teGHiOB9?o-D5HuzrNt5PqN|KwgmyW> zA@6#MfnN*52wWpcJIDiK1-F+^L8}bc3|Ey0AhQpK^_!;}^YG;Lt7FA3ZurP0nlZZLWE$G%-wIMD7EYiq2MvyWqtn1!kmNM* zKE$uH1AcN%>7{$L(jn6BuDkHlFGjr?Ux6Zck}=;0_s!2>;^404CI5uFbh?x$8dif$ z*c5nZcvF1B54eb`-l?p<+S7X9LSsbryHj<)y9>r!|; zGi;VBG_ssT>UohL|KRn{rt*=t`u5S0_M=_lc@~@676$&q1PJ`JFSV& zPxdiDBiz}Xt9QY-23BTABOO19ydi$8+kA2&-EzFP z@u~&;l5{vVQuI1H9@tKKUS+)4^L2M(O7iY)%Z{i#jT5%&4MOzDVE^D_SEfAr1e?lJ@P{0Sm>?B8v|fGUmvj! z&K%Tnno}Q@PX6>TODB|Pwt!{g7uTR?qVpAHt7%yHS@gcrHs>Lx7&zR|E!^s}zG&m1 z_DrzA`e{>RNn`avjf}U5L!pCEo^)tm zM`PrLHD5L#K+6p^i+Sm99ncl7 zu|$73VW>40{pLDJkHnNgX$4#jd$7`jVNqXD81k-$fB9%GcXXZl{ zeTi*yICFTmTY7xkpjqy-*P&*Q#+*k#RO!XP2u5cg2B#Hqdaj6VEpT{Zr(wLtehPi=8Qrq(Mnw9`x&2m8G$y5A`z6 zdrO*ux)k3F%ZT#MSRLng*O&C3h&AzjGp{H-Kdko~SXi`0UUOxZPAB?05kK>0Vf9;a z%EFn<;aj+Ta1Or3*gMIgF!rji$#QfdJ<{Ae!n#20a;C)PLcBp%!vL4pST%76#O2lu z$#^v>KRvo#SS)GadyOUnZFdpwB_y-nbhcpMZn-ivdv$gxg_|b-Z`Q6|O!5o|x4rKU z>(awIWiNHa5P;&~GXFltp7;ERq%Q9Y*DKqEo8?UKX7mOq;nkt-2SJ3x1C4ThxmVz-l-D5NM z!hHiF|{&)o;Aif%V!P(g)&cTy#Ql4zY&h?@5@J$tCpzWk);sAxC>KMp2 zvJS{kj47f@#VkuRxy=^4AVs%yYYSVu%JnOy@0fUuz5nTP=uq9^ED%J zT0lh8i!#4}9J;dL)t|POPnNE)n?8*aJ8v0mi8O{fYGDcM@$HG(s%w1`O%w>Fa9V?!T&~8sZ#vtwKyAg`{d{wYKJ^9Ef|x_}%TTQN3t;hiP=9BO}E~*kAZl zp!HZq&Y-vYpMp&e@kw2l?^F>}zW2O-qmvDpZgI)yyZ|R``p-9n5OYbYKF%fV0Eq(9uQw12HwvJ z|6!Rgs_lEU#e!Iwp*lT2udRO1;-U=DlHbinqr)cgzu0^4pr*dIZ4^YoLPvTB5s;?z z9;$#el_DJhkzPXY0YN}IA|PG5^o|rE^dh}?0t5)XlRzNJiNEK0zBy;!?>%SE%$Yg= zy#Hh-d-h)SUe{jhzOU=v9%DnQhVxESal-fGh5~9}BU<|Hv#coMf{_-F=gjP%Q*}yA zK|=5*rIzNQKEn7-p?F5t_MqL?i^a<%;P~`h&LQ)lThDz2eFMlV*t44{^)}@46YGfW zyRD{a$u$SmQLz!S`}91P-F|X##8zFLsP`#cxqfZ9sxvIaS-R~r@M;%*9M}>@EQ1#q zBJD3HwAV%?ZGYqpii;d-)A}?;0Us0E*;LG!WNkHy$cpJi1%201ZMR+x4OYhO{ zs?FMiBBPeGO{#idPI00cWcTP0lt0{td;_6Wzqf<^3IsKQaC{r;W3q72^UUAUciDAm zZ+dtJ-3JcY+UhLeD>8`Pfw9E$McICW2^O?mT>hLx-YvIEpF+A`*zvQ?!Gp% zxtORxPv6;T(XHwF7}0%wm1oD~du3LCxSerzJ*FDhw5eNTBI(k^#5PGRs^wcVE^)q1 z58G4N{9qQCoV>G~s1o|E!ECB+cpZF$w$Wb9b`rNKQfV^3zV412ie78l6eN4|X(UnI zc-Akp$HMLmi~)+qir)x+&^1t4V*B&!*rKhFCo|~X6rmD99V%AF|2wdH5Gl4lb zsIn{GevQW1!Bg@ujD4hn@;cM`YWcw&xeE2UVT_DBS4BOW;Pa*%b5m1I_OZ4*yCydD zH&V=ia-#>M-lonONEVrsopXH8$#KA&;>)=+xDDg6st#elH3_UKrjoKv-1E@TsuEW> zkEbub8nFBpE=D`?O@Kv22t0Mts@eVna;Y=I0J$4CWJPd0F=Vrf*}a*g7^nwAD-h|s zZ@-*NQc7+a4_zQFcTaoENQ#MN5is){Vz7-vP@ zRk>l~{0D&s!OB;g@11rE&O4G{qKr>{$ML{C*Hej-F#x0U!1lFa)_S-7EnpzrXr%x7 z0b}z)E#Ge5c^sbX_h#Er#1CmVE_l=3FTmope1>D#H@@Y~R;z(A@uFF63D^|4_56`a7d>1K>r zt=UsQ1ZkkKX>rf<_?RJ8m8WHB`{4C3)sXi^)Ajs$BKvJ*k?90EnQ-TqOKy1DEhoJ3 z;I~#GFpP2#;CFB*9Syf!bh+vC@MHG6znFBhAq8vd>1eBV*_J?Aab}#H8nz)<$y;D) zbdmvxm-YG?r0c~3b@Xo`8yRA;^oyUo7I}T3zoFz%6Y=tUqe)|s1rd_CT8Q0wWWI{# z=0<`3{LR;0iwh$YG?mK83$hHa9Bq2LZicxPQ{|)>og~{ohI|R74Y|PkHcI2;4;~G- zrw?`QBIm8=Zv}O{Xe3iVj?KgkvE*of&gUfoWU%Y<>FYR;g<@RUkN;4tsg~05SZiwnJNd ztn9e7s6xz6)wqs5Qg7v#akk%&DTIOkW{#KeCb`wet8+hu#>k{NeP zu9S&n?!D6CUhpUoyPcXx%%sLB{V{ZafFo|IJaeCB-DzVZEOSQD%~dg``mYn{j-MNO>ZSSe~(VVxG2F^frxH7{qK(v4wVyq^Rs$l>+S0*)ZGz`@{F@C zHps#CJ4*KL@v0+R>n1i49zwTQ&m1t1sQC+YRJ4mE=Cy16e`$FLXTqGr$5${x=|!tI z-)q1Wak4$)?bePZz9b72TK%#c_hW7PuTIyJ1i$O_cAYXYq`qn;&b(gWEr@EHU5;0y zHtH`NfbD}f!a*I}*P@ei#hXd?^NP8eXPZ=DJqRD_;tMQ|-~G!5)0){bfh(G0R01k$AUuy2Ur_ zT_ukzJ(sXd{!6=gA)k)7``f3(qicA-LKLQi?7xM}gc9&JI5Ul9CXMYjuYy3~*OxcG zk&hF)pl#=9PT`;ph(?Z()*dzLli8L1y5TN~4a>Q=+(WQV!k;P=--8nB-J+%A2tEt# zS4zU7{YAmc#~;_2a4Xa(#0mQ|9rLIzE^V)R-lSsP{WcjS9-%kq1d{4mk@03#)3iXl zv8a5->&%Gv@k1kPO~P$iI6#y1w%k5oPa&UCyJE>7Y-1lB7&=e!@07oxBW8c_p~Un2 zewFQi?a)&{;CWD8?$W~+oDxfkm7nPOrs~o#-758+^wzT7&)%f#5g~}rP~bP9bU5&i zt{HlOhiVcvHZ%TG75jBqt^ze>3umvG!_PAOv`k|45}C2C*?&epK7A}@&(ug0$U8CG zy*+_&f8}wps%g8{t||RSia#fP`A>oDNcQ20+M`{v0!LEO9!(iN|k%$B6O}b12uq5>sUnWr~v=i8=Y`#B)il?W#)t34Od8m#1_T;ljm?t@n!S z)hHk3Y`04Z=S{`GXEgjwFY#*L!e)e1i@H^#?4jR9t^QM@DmLT9iHX0%$ymEwWIAq` zFU;_gd;oia%xuD8P4u;`-^0q5*5| z3RVC4{~z-gtKyp?i4a?r@7bahGsdqUsghq%qIqdu-h1mAM@1LNvB#eeYV4m{dw)yk zU*wh!nbMa28rLmTR$7`@(ZZU36&W~;@@AjBvwWUA&-r!hQt`==sIjA^*6dJy@%v4P z=%s~{rmT8}ad$SEr(JY1VoMA%^^$Qmmx6$K`{a5L8-9MW?XXxt<`i5`W@0e|pZe41yliNRu3 zJOCxQ;*k;C#NaLJ!k2&vAsnKYS(ilK-Szf`EXhVjium<~=^v}08nX02UjgFJGV;mvWf6&L%FWFn@$V|{(+zkq?1@l@51x|eq1 zF;5b(7Qz18axP>^E_at!UBeY&(@ z44u-vLe7L=b;~E+F|=Qi?#j5xnMtvu=F-O6oiO*mid6gm<2G7?!5Uj4>5_KoHvdM@tC7R(xO+aF%{=GNXG5;yqM!oIUlGmD{TVVVk9NGvTpL4c{;fLx z1Cb0;5MCOV$?h-GE1TI_;{${0c^t*+xjweU{2A;e1`Ac1$ssh16-=dsf0U^-38&Y* zKd_L9mql7WxLhiuC0dPV=RYhiu2eY@A1uFzTio^^X0I4<#8 zEXL6e-b(0Yp2rwIT)c2@pZKhi_K={T4Kdv-PGQ4a#3!aex5GNRYa8C5rC|Drp*<)C z41hDDko`uIevl%M=~cLiFRz!$Xt!BjF(M=;J0`W6yCK;J)utzWN?g!*FR<78*-wm_ zrftbA3rE^0NGMZv=#`a(w9tJ``z3DY>kvZBu_5}@^=SB|@WQIo#@_h==HIRF7Om%&o#6xrEoz)}%Oty|`E2Pai{yp9 z{zs@_6d(8+&51n0zH&SJvp+MQXP0B+ui0cTNSI{t$xQZB+EAKLaP~BTr}Wj!=WIkjc&z$q^Ve|+te4Z#!_Us9kQLn?uVN!hwN6tzESgAK#+Az0nz?g52s`Dz0C7CahUEJ>Cw zcjiMFJnel;tF>XkVpFB)wfEa~d$Wb?moGP+jFpBL&vF_7oKJr0lD2D|fyTxF%_F|i zMBhA6yC|MEP$}((JjuWZpr?d%(&wiQhvdJOpBKH_cQFF}6I*Xk@EOPR>-@h$1vYMl zjm&G0kYZ6po2FyyWcaCYiPKz@HBbQ?{u}`x+=fEGdXqx6@hg2Eodv&k^BiUs_`U#a zBGN)P#eq(|)8bbxs(l{2%;DZIr{y|I+gy5Z^zAV>0Z}0)f+n|Oo$ z;2XQ;5FY;==cY?%h)tk{7~)Cfy4!pH!+S9cZ+!_P>uWX1fk>!V72BWK>h;mR!jhE=v zj4){5TkHJJzF^*bGln#;r75u_V0ku%oc^I`8}C9TaG#Lod$kRF=58xChbn|dVQWoCHERn=rpJOPVTPAMJG)CKE%M+0Hl8hvA@zI&cB8A@N8X1 z|Fk}TD9$fY!J0!7wvkf~!bbMT3-S&Zvl&zWG;@dMjfJqox`Bq#wnI-NTk4rtL2`el zvl2IwqisAZ4lakjoaF&ZUECK5;uI6dOdU%N_M5)R@OS^<5SM{jfZwE$N2Qcl$kL~P z9T0uOA786p+OzXJtT#Ev-Cs0lXPk-a8r_$NQqlC+of1}i<477i%-~Pwt8*N-nOYh7 zi?o~PZf-(9T_0tTlN}luVY*Ug^4ig^#dyEM*~kJ=VEJpC*ybo%)UCr}P)4Pz>{0GC zS!LYZ>J78+)8g6YD_p|;CHTsUIrvLcz|5hPW01z%UueM9j=SGQ$?nB^zxg-yix#a{_^ni z`#1YevBIh7TABAg@eGoS(+q~cSlJGmdKkbXH#u!lu5V6f(jJX6SjHhuG4w8=NEv>Y zP8orTo=4&Al8g=!X+5Vqv=c?N?grObJ0_L6n0H6l;&-Oa5oxs@Aa8EfT_%&owC=6O zS{@K}w|Fj=%WoT!t26nJKDTeXt)2Jw#3hpQ{3J00jh9cK*V z+@3t39)x88Dc|zBPs94MX2(ziYZcyr+-Ne-A%GDnO3ZHYewy@b9$y08_o+2e`(c3J z7xf900H=B1%osq*NcxpNrlzNf5>cLms&meR#klyfP?Z|JQ2B~chvn#DcbcwJfBbxKZim0cKOIXM!&7(9<;xAxek>LUjrHZr#%CVoLIC$B~@{QsIuf{tS zU#R>GZvJ&1v}G}3n7B%wGiL^t=sR-0OUWJnbdc(VGckBifr`(`c;9L#iIG>8C}CT) znlO{~!^Gt5*L&10ecxF`SOZ$3|AaC&f*I9)YXUIfBB zW%aURH(9Svev>k1BaYkH;RaA!YVbh_(-Nc}MoKBM#oz6=QkY-P72{6}Zwk0>5Z@5w z$yvgS$9{9cl}(X=K`z5-d18RtPE?PVA@$1k8Cj~~br;W^?Or*H%5YxcPiOr2|KtL| zHhnt(L255*bu)F%@gOR42>(j%H$|o~X#NvpQou-Ky`z3!@;h5qhsxz(x{iZCrhsD| zU-8MP+B(52(P#IUYOs_!;U7fnR3gnD>xo-{?dBbEerom&a;Q{4hdJmt$p@mQagWd%TygGs zqPOryiRt_#%)&G~JdmAaUd_W<1PmoT06vh3>p>^qux|)TVf>hcAP3qdRggy(M|ZB5 zyekS$Rl9l8w`BNX{N;s0H=_A%>*5Vxw+3LGz1f#CQ}zkjjp3`eVfhCKNcOW|i$7Vj z06%H@9z|4hpML%$*JKpPAzw#T72p0Sxapn5&6JFwsWdkecT72ljqjaQ#%+)~n&aK- ztE#qZ+=`HkbXcZeeM`6xD*0xY7AG@UwIpYIG~Wy~9|zxWXyepW>e=G?sM*)v?P~I; z;bRpDIATdBby{^n#>R7b>ArU|s|r|hj-44cI(art+Sx&xYVQs)llsoZ z#~LNQA`9I7e8JA9jzD&c*1J?Oq9g{HQdfbylGc|Hm!0Mx-yD0a{r8(LLL*rqVhcHq z)XmHbH)GNk@#^CIi7(slO%AvZ?wQBi(D3S%+phVHDaBnS16Vm@WLJ-)e{KO}4=G!A zXZ>$qFQN~|9WkfKZs|<@oGCU?MC6*zXr}Ef`Z0# zrCH=oD-J1t^rN?U1}C|| zT))NxxMGo;@f>B6*KyV}rE!VbhW%^5@OsQ+9$sK5;YO047f)yxmmija&`Bw#(c)z2 zAbidoO#*|w*b|;>ia3eypAFt5yo<&lyMcpUB*9Q1iBg+E9_=LK)$+3)seo^EL9(D*l@^$8DA3!Pr0Vn`c>QA?z{N4KjVdgQ8h_JDn`34h?}5_4Sl zVJr3}u&D3mWeu%{VpZsYOo5TA!$EDNKwli$rq&w}3@YMrMD%FA>4~2kIsDe`Y|F1% zlq}VCvIcrqs$-;dM#S7F2xZ@xl;p3l0^&|?IQu_l;|HQZo#+(M{2kbbO@+uL=1rV8 z5vap8hSXwIGc98^dmig)PQVGQ2Ht6wo)bi*!kx!BcGORnV}Xuvu%y*^mI8t9_zIK2 zhW(R|9NzYZ*HLhlf%*gt4D#k=O%$}j?cbgK>%(6~_N{+Q%vyim4tz3+@ynX!16S@> zskgU19kSpbV_hPC+J-~HCYxbukGVjF} zn{B+ux~zCR3ihHsc9xvl9%#+brX+R75W=y$&um6cLfK4FdvIgR(-horL3qvq3G%`{ zxq+72%fw84_oEdkHBN%;&7Og9^M?!OK-YJ|-8&cNrr02CmhXd+3>T1VS9iU+H{XWv z#lqR2{o{$AG8eHO^-;iImN$OlDUuWB)LX*dVLy+Vus#3`+_7TZuM!`L?^unKsrhA< zc>52}l4V482~%)d{MPCqX%Ik@=$t)SX=#@ztjsG0nqj~R#esU9i@M#1uQWzsRc2~?vH+dFhC>w;n zi7(f*L#<2TTfN$^nhH%futTZsyZE6CVA_lz4Azg54L-Y49fP<*Ahp;ehCPKrYtZbeV@w~c#D)+h5|FNE{&t2ZLAn5 z?EsiIRq^u44F#&-;Vz{0H#)YBSH5%}J?}zh7FMH}J~j3T9mDKLqdQ^9Co+?;%_8`u&kUVi@X*(V>_7z}-zS*{-xu$q=) zX&C%-R;S89PP@IOC$p0g*6_nqzu(L!it_?}J;#iEEZ1BkvH>#(>!s~E$j$JRI=#kD z_|@g+Seg{G|FEg8^I_$ZONdOocY{qq@0QljyTx7m9xLW#xbY>x?Gtol+_y*}rO{5{ z^)og|i=}|Ys*ZTN)JGGks}73MVmc*L=Lt`Cx}6+m{ofj5S`I&Yc3DW^fEidGdDrM^_zHm8~i8Sg8ibYiQ=LFIwmbsd25LovC4Y4ui%~JZrXH>hs zVx948aUwSp+l2kQV|qu+fDS3hwGRTi5BWLecZIu>yWO>kyhitJ!S(@1sdl?dPO5Zd z7de|Y7y8@ij4uP_FJp~T7tobiRuhp0m=75EF<2N=d(K$_T0j6WEFbg=FZ%(Qx)h3r zOE-u6bcwT&dUVmH7z!2fnY9h1GV~Pie)7D(Ip>zW8*lg8K{xjzv4#mUTw|-`hkn*y zsHaiR^o!rFV4_@sX1wuwfTP?xM4P3AuUOV7s>pvHud9j_zurmKP3^3L>EcoA1QBtl zcFoNvPx-}ai>FQo!ww>LKnUAgx1O}rb!xJPd5oj>Vvz9yJz-7SRa%%DWi;_fx>!+k z!q*o#j6Pf(&Yfq+xcrb~aMN^O~s2F~|znP~i zx#K@X$@XZvt}p&uVLGVmFSk1d8r0ffs4V;32LIS(UL>Rgfi;gc5!D0*5&!D+7WfU? zQk+)|;1)O0J+IMID6{WMY`iyK;0)sBuEWpEb(mdUOE;y z$)G*NHBO_4lOh;iGA>nZ^^>Ar9CIYO6wX2Xm|tz_*6=Gg(Z}jIxz&H@4yW|!G*q;^ zcOWyMjEtU^LSH{$LG09hM8TN%Pe^nN2(i++-9OZC%&}ThMuyjJK^lnX!R!*26nHtp zJJ0u~Eu3CwJ?{P>fn5+hIlvV5>6mDB8bzc!Gi1U0P=cq^Z!y@_((AL^MDJjrEVk$nY2c(Eh@&+!(s;8mtBq=*9C2kg1%}{PHmfPMNg@|FrDX z&$o*WBPmdvbpQOdnjs%cFH&#{V~oG=6IWUf>j$4PgrPLcsAf7&o46T)15Dv;9w|>w zG8fK=<139^pHy?Fba|mC%Z}d+rD)pSF7&4aVwwp6=yXw(=HmOT#%WmfDjL~mju!K~ zS)r}({g`F@9uoM%?Kisin|f6fQAs8Q54#oT>;T#Y**>)i*R7eu0{ugH+_Ed4_+6(b z`8(Q`Yp)8D0*T{>G{tJkQWY?N_e4H)C6+F&1c(Z5O%DL_>#4GASqy?Akcljno_*s? zoDyjGnG1_enesydbEOA25aq~$KxkIHZ7*d?KG24w*LEGbg^oTl&`%85WfeK^?R_h} z(#@2>^lxK%0@;&?a87)m?jqa!p*WEPy9{>a3Bz^Dh&L$!ePzCQk}$2WgS6#NKe8aX z5B@i5?Lzig7tE_ELJFveJ}>@LAgS}`=Rcgz6V+=0Wf31homzLl8VNtPSD)}8@t13& z>Bv=nm$fMltdiA=p@zlvG!RoH1S!qfa9ad8DL>plYG*x zxgO>?P&l;Du8SrN!35>Zvt0A z>T$1#%9qZfZ`7yGfqu`mDEgRxdau+-vH78Kn4|^*l;{~E+WM*3i8kGa>I)u?(kN&q zJRG5326-jKDbx@12JqUbWA!Z474J+&>rMpDFrUmf&#wYc-?+9`h}H;WS(X6^_ADv1 zQMwq(F7%nW-hq7NU3-#j*L49F)AbJpe4A4(o1ZA0N)?zm79dq0LF!Z#Z2UI#ZSl0r zk4r4qecTWOdhH{nVjTGx?T<5)xW#NUJkBeDs+WuSH=4)|{N}S9J&!Fw*+|=dlNX1k z#899kJ}UY+<@IqAEMI+4lK-6?<~_a{dSt%U?RF&E*6=Q^tlNU%eCkvZVTaayh}HHK z&oTQld9RAer}$_!N`D!wuFpkITWhvNZ0nV2&(>6A)4}H3UN;q1p%}L{JNI37aaD

(yLqaDGU%TieHuJM3_&&sf)S5+$&!p9FYk_}dpCKK3(E7H zGh?3w+aBE<+f30~RSNr4)MX<+h#2Ys2R6m0R4R9VCV}%&2b{{fhJAh9g$K; zRlu!qs+Pq5+a$Kt_8eFJ$ZGVm?4<=#tX8}FJ38W6bIGwCc!WN`At=^GQTZD=cXA&} z2+l7INF9&;0M6$pt7FwwQ>UT24|Tn}&bRq~Kvm4bn)UM95X*7!K9Z`jr9eo$*TCff%~wO)+wKObtMxv`u?qfKkL!0L3ZYzcq%6Cak@3G)x=8E zoaT3ZMth9Txbw_Yoo2ekK|Jdp;JquD2_Mjn&o*z;1|Wxc4rsHvbJv712pj=FAU5-h8AM9I2x_M>(8 zxgb2zGJ-|rRpqC6w|o`Cf}QTieqik63BxBdTyr_>!DyptjJ7{C^-|O=e2V5wrRLoU zZu}OB#6vqXvABGWvN8wT@j{Z+Nkx-ijNd@k#ps1l#(8lCtk{uz#Z!D}> zIzO2CY<7j+v)Svfb$Z!;VCR2y0a{Z%$bI082M>q3K}f&!Kus?N#BGc9p@bIaOCoup zUXG6Ni_JhgSXZ$`&>w{s`V!k_2Astbkh4A8=%yPjXf^iHE^|EJOW`+P_!$;s8uykX zOUu+Fvw@PhV;A03QxjHXTT$0@c3I)VkLQ|c^OPh`im4D6+YzO^8&XuXO^44Yg*`QR zMw#}afhKG-`@4apzy-XluJN^+hn;Uf4Gc@D-l*w*8KnppDL%@2cAA*IqjF#)c^KO( zyj`R$3@%l2N^y}xnC@hDYQ1{x5PbWx-;smyi-kb!9I+0yHg1Cb(@8=n};>RFfb6dPtvKq@R}qyMNM~ zCZN6N=UA7XqZ)vmbK6y~%TIpi7UXuqDgA0Jt1;d3Xy&*%zsj+$dGxwszUR{zi1 zYRKIj;P8VUYHRdx3;`YiVm1b3MENa58d@>8Vvo_Rf4mLL4G9;zM!_ZCfVh_rM!OZ) zl}yIooZzKKWaok*sL1Bu6mj@Y-JUYB5Q{!D{D3?F9@?LH9orJ;+$E)(EMyGivFkoh7Ial z)MjFHfSm!@PO9j*>@B|P^F2R5MDlkFQ z@NkOA&%Dn1Q@Xw~K3RfiorOvF2@&9EVCFXK&Yj13+F z{$-Xpya$ABOw3!UYl>U%#ra#kjuKii6i+pCu@U`w__i|PS%f9vr)G`7H_Sfmbd$j~ zU24B=X=vvKXar3QYIRPyK3r@yQ77Wz`N{p; z^ql&1^rPz!=trli=C9cyb!F^qn4(Nt*~b|&e?xJ{Fd6E`A2a&86O2egIcDD(g%;)# zJ0hV)2F?2*E(ZS;U@|3Lm+w3EoWM}u@iK0rMP|a3rQ#^31%|jGwb5-SG5;Q){7O?f zgiKqQ=>9lP+>mQrIIf5ONC^81Q>tqW@!Jwh>z{Al@%``z#!-sD@LJW~unKa&t2LU| zkN4w!jAvr|W#5~~Z#_X7?ZLxv#H#RmHUFlOFaSG;93n zFfPs%2zm=T93dGt>rof)q1w+`c9;MxfqRo}TlvKD0gS)t9kq@=w@J67ha@)0iIbf( zx@vqkaZ`T8A0YuZ2M&_QdHW->soO=k5OQwtbsGEGLJ0CsUhfs!d|#(`v2z&xExObW zEYn!*&m0t9x_+{GnUj@sYnA>vdhG#>LP28x8*Y7(ddQIY1X#%lE-|faA}EBIcp2se zD2UqH7sCco_!quf4|{vY01G$!@6P=p&TzWX`nT~vZAJ&{zV=FRT&mlC;2UE@jPqTo zeHA*n%EPrV0&4a)IY&|7KnE5ZRe4AV0}OVEN0;KH`tfhUlg&Z=dBCrO$yLulZth8WWpbBOabZ zc}EvJ+!oMR5f&z!sEBo|`Q1i4PW%xcHcU1_c9GPv@9<(qlE55IG2^bn9=RU4~-fH{n1NV)6MQ7(!|E`{`hD9X40Z6u@SXCUWQS)xikU zD>EY|iYA$F%|Y?hEK;hCd;#~~8K=x3a1%CfZmMQB*2~H34r^m(!!B+S<#eh@EJ{I` zPcpfLbZXD}mf-H(+5=Y7?l>IAoK-r-lM1T5J8?D-SXn6i_KmuQ0a(bDhKdNPx9o9=ZRq!X`;xl~B z`dux(Xd5s8xhbRBK=}JFuWi2`7oS)C#Jq!S)LZ>p&oH=`6%=4@z=p5N%0xxb@ys&!Uu!PS!D`HAH;Mm9-fk2d8$2n6iZcr3?WHezUVMg(fxNSo24ur{13MU`3aVdE&|jgc2p}YIRcquJ0tNa<6kJKN!$0Ks~xBZx94-bR>&na!n=R) z#^%O3e!ZJ`2YB!NgWbwEt`1`Vt^g%-8ToWxF;0RHpg26|K5pWkGs-ys4L+ZaXyOH< z!I3+oz+bx9Okx{duYJ&|C#Tu$3Swate#0+DY?D7-bPNy8u_0lN+*G@f%kQgy2QVo? zK!Kc*aj8Y-6y{il@s82;4B4f`h7?OK6h-L^+3hZxN|Ht68bAF9pd zkco9z9VyeZf8GB&_)BRYka7E}A~l~~?s(dQZ;IO=6Y)N$`?D*O;Sz@Wn=dN44Wq)Q z$D67XcO%qb{wphF$P~=6!G(Mw!c3EVpbf^feStNuK*?`TS}s-eNz*X;i7x{``qBpO z$r%Oeeeev%rZe84QgRBqui}YU5Xty*h(AAwYvTel7-J~x*CkSP%+%_rPH?d}(GjPS zxv<_S#oU+}NLsli5GrGG!_>kFPcVUG1(z=4WbUDveGop_BwCK!1cV(9?B+1KvWhT| zKmIycN!El>00x5^5W488f4A$PEYRuyts6egr6SRmr_OIC4rKK8?~gp{|4%B+MvIF7qnjQ7fj?PVZlL%1Q6GN1Bo zo0%K>l;#nhIvMWIs&1wYZ2;z3&~P;?(O&4q#4A~wk*4$P{@uj>;wj6plt1?aFvj(c z@_*%QDBPQr?Wh=%PxmN4r4`!Q%Rb(Rkn+|X+#;mu5>7+veke4Z4)@XsGk?9UM;Bh2 zS78L_RyI}7Ngkd`z91ok2tJD1cE)Ta3}w$$lGXV+rS@%}a=WuwTe5;l1D6F?;R_ zH3j-sJzO(ye^^#Ab6KfXy!`T}v{0_s4Dh<|t5Ga@zOH&mR9nywtm~SN<7G+89m-Y$ ziNn1ZZE#O}Fs17CjHHsGAMw2bgUW4K&#$Wl6ja-NxILAJA52)W?DtvYmGMQD72j6i zVtY@}_cFE>gYIzT-1V!h>b9V&3xIdj>~_2&PQif1@chdUzWo`gWxgIKUk*RqvoW)cxivItu&P9xqqpU>bxs z_aCah!M%$3`!BOz>3Lpn{h$d7U%)&7`6tDY!v0u#cBb_EYc*rC8`Q%*_7<(LZ;AXm$zZ= zMg&MR3cHXI0^cGVpVVjh{P@@g_tO8@LHl=C9_DX%<(~7w?^l+VVC7B5vjr#4J=uH6 zRTq(VTxEXyl+y`Lb5fP}6|+Sm6~W&&fB!1y>xxXd6IlP`So=$)I6s5D*nZiuEm

w` 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

i4yGr;jk74x8LN5nAi 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∨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 M6IRAWM(1z;2L;)jRsaA1 literal 0 HcmV?d00001 diff --git a/docs/source/manual/tutorial.md b/docs/source/manual/tutorial.md new file mode 100644 index 00000000..7c775a74 --- /dev/null +++ b/docs/source/manual/tutorial.md @@ -0,0 +1,107 @@ +# A simple Snakemake example + +In this guide, we will walk through how you can upload a simple Snakemake workflow to Latch. + +## Prerequisites + +* Install the [Latch SDK](https://github.com/latchbio/latch#installation) +* Install [snakemake](https://snakemake.readthedocs.io/en/stable/getting_started/installation.html) +* Install [Docker](https://www.docker.com/get-started/) and have Docker run locally + +## Step 1 +First, clone the Snakemake example repository: + +```console +git clone https://github.com/latchbio/snakemake-short-tutorial.git &&\ +cd snakemake-short-tutorial +``` + +The directory tree consists of a simple Python script and a Snakefile: +``` +snakemake-short-tutorial +├── scripts +│ └── plot-quals.py +└── workflow + └── Snakefile +``` + +## Step 2: Add a metadata file +Next, add a `latch_metadata.py` file in the `snakemake-short-tutorial` directory like so: + +```python +# latch_metadata.py +from latch.types.metadata import SnakemakeMetadata, SnakemakeFileParameter +from latch.types.directory import LatchDir +from latch.types.metadata import LatchAuthor, LatchMetadata, LatchParameter +from pathlib import Path + +SnakemakeMetadata( + display_name="snakemake_tutorial_workflow", + author=LatchAuthor( + name="latchbio", + ), + parameters={ + "samples" : SnakemakeFileParameter( + display_name="Sample Input Directory", + description="A directory full of FastQ files", + type=LatchDir, + path=Path("data/samples"), + ), + "ref_genome" : SnakemakeFileParameter( + display_name="Indexed Reference Genome", + description="A directory with a reference Fasta file and the 6 index files produced from `bwa index`", + type=LatchDir, + path=Path("genome"), + ), + }, +) +``` + +The `latch_metadata.py` is used to specify the input parameters that the Snakemake workflow needs to run. + +For example, by parsing the Snakefile, we determine there are two parameters that the workflow needs: a reference genome and a list of samples to be aligned against the reference genome. + +For each parameter, the `path` key specifies the location of the input data; hence, values defined here must match the paths of the inputs for each rule in the Snakefile. + +## Step 3: Add dependencies + +Next, create an `environment.yaml` file to specify the dependencies that the Snakefile needs to run successfully: + +```python +# environment.yaml +channels: + - bioconda + - conda-forge +dependencies: + - snakemake=7.25.0 + - jinja2 + - matplotlib + - graphviz + - bcftools =1.15 + - samtools =1.15 + - bwa =0.7.17 + - pysam =0.19 + - pygments +``` + +## Step 3: Upload the workflow to Latch + +Finally, type the following command to register the workflow to Latch: + +```console +latch register . --snakefile workflow/Snakefile +``` + +During registration, a workflow image is built based on dependencies specified in the `environment.yaml` file. Once the registration finishes, the `stdout` provides a link to your workflow on Latch. + +![Snakemake workflow interface on Latch](../assets/snakemake/tutorial.png) + +## Step 4: Run the workflow +Snakemake support is currently based on JIT (Just-In-Time) registration. This means that the workflow produced by `latch register` will only register a second workflow, which will run the actual pipeline tasks. + +Once the workflow finishes running, results will be deposited to [Latch Data](https://console.latch.bio/data) under the `Snakemake Outputs` folder. + +## Next Steps + +* Learn more in-depth about how Snakemake integration works on Latch by reading our [manual](../manual/snakemake.md). +* Visit the repository of [public examples](https://github.com/latchbio/latch-snakemake-examples) of Snakemake workflows on Latch. From 1a06540f6f65473fce9cd84cb7a388b5f5513dfa Mon Sep 17 00:00:00 2001 From: Hannah Le Date: Wed, 13 Sep 2023 15:38:42 -0700 Subject: [PATCH 242/356] added source --- docs/source/manual/tutorial.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/source/manual/tutorial.md b/docs/source/manual/tutorial.md index 7c775a74..fe22e11d 100644 --- a/docs/source/manual/tutorial.md +++ b/docs/source/manual/tutorial.md @@ -2,6 +2,8 @@ In this guide, we will walk through how you can upload a simple Snakemake workflow to Latch. +The example being used here comes from the [short tutorial in Snakemake's documentation](https://snakemake.readthedocs.io/en/stable/tutorial/short.html). + ## Prerequisites * Install the [Latch SDK](https://github.com/latchbio/latch#installation) From dc6f1f1ce3cc21ecc7938fce9a0a794e1293cada Mon Sep 17 00:00:00 2001 From: Hannah Le Date: Wed, 13 Sep 2023 15:41:02 -0700 Subject: [PATCH 243/356] added to toc --- docs/source/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/source/index.md b/docs/source/index.md index af036bb6..1b6564e0 100644 --- a/docs/source/index.md +++ b/docs/source/index.md @@ -149,6 +149,7 @@ cli/mv :maxdepth: 2 :caption: Manual manual/snakemake.md +manual/tutorial.md ``` ```{toctree} From 82277e6bfeb62f8f08ecf8a3652291cfdea768fd Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Mon, 18 Sep 2023 19:49:06 -0700 Subject: [PATCH 244/356] snakemake flag for dockerfile generation --- latch_cli/main.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/latch_cli/main.py b/latch_cli/main.py index 7e18d0e8..471e50d6 100644 --- a/latch_cli/main.py +++ b/latch_cli/main.py @@ -19,6 +19,7 @@ from latch_cli.services.local_dev import TaskSize from latch_cli.utils import ( AuthenticationError, + WorkflowType, get_auth_header, get_latest_package_version, get_local_package_version, @@ -72,7 +73,15 @@ def main(): @main.command("dockerfile") @click.argument("pkg_root", type=click.Path(exists=True, file_okay=False)) -def dockerfile(pkg_root: str): +@click.option( + "-s", + "--snakemake", + is_flag=True, + default=False, + type=bool, + help="Generate a Dockerfile with arguments needed for Snakemake compatability", +) +def dockerfile(pkg_root: str, snakemake: bool = False): """Generates a user editable dockerfile for a workflow and saves under `pkg_root/Dockerfile`. Visit docs.latch.bio to learn more. @@ -89,7 +98,10 @@ def dockerfile(pkg_root: str): f"Dockerfile already exists at `{dest}`. Overwrite?" ): return - generate_dockerfile(source, dest) + workflow_type = WorkflowType.latchbiosdk + if snakemake is True: + workflow_type = WorkflowType.snakemake + generate_dockerfile(source, dest, wf_type=workflow_type) click.secho(f"Successfully generated dockerfile `{dest}`", fg="green") @@ -427,8 +439,10 @@ def get_params(wf_name: Union[str, None], version: Union[str, None] = None): if version is None: version = "latest" click.secho( - f"Successfully generated python param map named {wf_name}.params.py with" - f" version {version}\n Run `latch launch {wf_name}.params.py` to launch it.", + ( + f"Successfully generated python param map named {wf_name}.params.py with" + f" version {version}\n Run `latch launch {wf_name}.params.py` to launch it." + ), fg="green", ) From 9f8c2f926e47f8dcdb80f50046c11da3470678ee Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Mon, 18 Sep 2023 19:50:53 -0700 Subject: [PATCH 245/356] snakemake init example --- latch_cli/services/init/init.py | 9 + .../.latch/latch_entrypoint | 85 + .../.latch/latch_entrypoint.py | 85 + .../docker-build-logs.txt | 743 ++++ .../docker-build-logs.txt | 514 +++ .../docker-build-logs.txt | 757 ++++ .../docker-build-logs.txt | 100 + .../docker-build-logs.txt | 65 + .../docker-build-logs.txt | 100 + .../docker-build-logs.txt | 100 + .../docker-build-logs.txt | 98 + .../docker-build-logs.txt | 2627 +++++++++++ .../docker-build-logs.txt | 100 + .../docker-build-logs.txt | 105 + .../docker-build-logs.txt | 2083 +++++++++ .../docker-build-logs.txt | 1541 +++++++ .../docker-build-logs.txt | 61 + .../init/new_example_snakemake/Dockerfile | 25 + .../init/new_example_snakemake/Snakefile | 88 + .../init/new_example_snakemake/config.yaml | 5 + .../init/new_example_snakemake/data/genome.fa | 3838 +++++++++++++++++ .../new_example_snakemake/data/genome.fa.amb | 228 + .../new_example_snakemake/data/genome.fa.ann | 3 + .../new_example_snakemake/data/genome.fa.bwt | Bin 0 -> 230320 bytes .../new_example_snakemake/data/genome.fa.fai | 1 + .../new_example_snakemake/data/genome.fa.pac | Bin 0 -> 57556 bytes .../new_example_snakemake/data/genome.fa.sa | Bin 0 -> 115160 bytes .../data/samples/A.fastq | 1000 +++++ .../data/samples/B.fastq | 1000 +++++ .../data/samples/C.fastq | 1000 +++++ .../new_example_snakemake/environment.yaml | 13 + .../scripts/plot-quals.py | 9 + .../init/new_example_snakemake/version | 1 + 33 files changed, 16384 insertions(+) create mode 100644 latch_cli/services/init/new_example_snakemake/.latch/latch_entrypoint create mode 100644 latch_cli/services/init/new_example_snakemake/.latch/latch_entrypoint.py create mode 100644 latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-1d8b2c/docker-build-logs.txt create mode 100644 latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-2dd65d/docker-build-logs.txt create mode 100644 latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-46aaed/docker-build-logs.txt create mode 100644 latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-56df45/docker-build-logs.txt create mode 100644 latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-62524a/docker-build-logs.txt create mode 100644 latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-6975e7/docker-build-logs.txt create mode 100644 latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-87b6a8/docker-build-logs.txt create mode 100644 latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-89875a/docker-build-logs.txt create mode 100644 latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-a00131/docker-build-logs.txt create mode 100644 latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-a98450/docker-build-logs.txt create mode 100644 latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-b1b9b5/docker-build-logs.txt create mode 100644 latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-cdb14b/docker-build-logs.txt create mode 100644 latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-cddce8/docker-build-logs.txt create mode 100644 latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-dc4ace/docker-build-logs.txt create mode 100644 latch_cli/services/init/new_example_snakemake/Dockerfile create mode 100644 latch_cli/services/init/new_example_snakemake/Snakefile create mode 100644 latch_cli/services/init/new_example_snakemake/config.yaml create mode 100644 latch_cli/services/init/new_example_snakemake/data/genome.fa create mode 100644 latch_cli/services/init/new_example_snakemake/data/genome.fa.amb create mode 100644 latch_cli/services/init/new_example_snakemake/data/genome.fa.ann create mode 100644 latch_cli/services/init/new_example_snakemake/data/genome.fa.bwt create mode 100644 latch_cli/services/init/new_example_snakemake/data/genome.fa.fai create mode 100644 latch_cli/services/init/new_example_snakemake/data/genome.fa.pac create mode 100644 latch_cli/services/init/new_example_snakemake/data/genome.fa.sa create mode 100644 latch_cli/services/init/new_example_snakemake/data/samples/A.fastq create mode 100644 latch_cli/services/init/new_example_snakemake/data/samples/B.fastq create mode 100644 latch_cli/services/init/new_example_snakemake/data/samples/C.fastq create mode 100644 latch_cli/services/init/new_example_snakemake/environment.yaml create mode 100644 latch_cli/services/init/new_example_snakemake/scripts/plot-quals.py create mode 100644 latch_cli/services/init/new_example_snakemake/version diff --git a/latch_cli/services/init/init.py b/latch_cli/services/init/init.py index f08f9381..6686243f 100644 --- a/latch_cli/services/init/init.py +++ b/latch_cli/services/init/init.py @@ -173,6 +173,13 @@ def _gen_example_docker(pkg_root: Path): _get_boilerplate(pkg_root, source_docker_path) +def _gen_example_snakemake(pkg_root: Path): + pkg_root = pkg_root.resolve() + source_path = Path(__file__).parent / "example_snakemake" + + _get_boilerplate(pkg_root, source_path) + + def _gen_example_nfcore(pkg_root: Path): pkg_root = pkg_root.resolve() source_path = Path(__file__).parent / "example_nfcore" @@ -186,6 +193,7 @@ def _gen_example_nfcore(pkg_root: Path): "R Example": _gen_example_r, "Conda Example": _gen_example_conda, "Docker Example": _gen_example_docker, + "Snakemake Example": _gen_example_snakemake, "NFCore Example": _gen_example_nfcore, } @@ -196,6 +204,7 @@ def _gen_example_nfcore(pkg_root: Path): "subprocess": "Subprocess Example", "r": "R Example", "conda": "Conda Example", + "snakemake": "Snakemake Example", "nfcore": "NFCore Example", } diff --git a/latch_cli/services/init/new_example_snakemake/.latch/latch_entrypoint b/latch_cli/services/init/new_example_snakemake/.latch/latch_entrypoint new file mode 100644 index 00000000..7f30e6fd --- /dev/null +++ b/latch_cli/services/init/new_example_snakemake/.latch/latch_entrypoint @@ -0,0 +1,85 @@ +import subprocess +from pathlib import Path +from typing import NamedTuple + +from latch import small_task +from latch.types import LatchFile + +def ensure_parents_exist(path: Path): + path.parent.mkdir(parents=True, exist_ok=True) + return path + + +@small_task +def bwa_map_4(data_genome_fa: LatchFile, data_samples_A_fastq: LatchFile, data_genome_fa_amb: LatchFile, data_genome_fa_ann: LatchFile, data_genome_fa_bwt: LatchFile, data_genome_fa_fai: LatchFile, data_genome_fa_pac: LatchFile, data_genome_fa_sa: LatchFile) -> NamedTuple('bwa_map_4_output', mapped_reads_A_bam=LatchFile): + Path(data_genome_fa).resolve().rename(ensure_parents_exist(Path("data/genome.fa"))) + Path(data_samples_A_fastq).resolve().rename(ensure_parents_exist(Path("data/samples/A.fastq"))) + Path(data_genome_fa_amb).resolve().rename(ensure_parents_exist(Path("data/genome.fa.amb"))) + Path(data_genome_fa_ann).resolve().rename(ensure_parents_exist(Path("data/genome.fa.ann"))) + Path(data_genome_fa_bwt).resolve().rename(ensure_parents_exist(Path("data/genome.fa.bwt"))) + Path(data_genome_fa_fai).resolve().rename(ensure_parents_exist(Path("data/genome.fa.fai"))) + Path(data_genome_fa_pac).resolve().rename(ensure_parents_exist(Path("data/genome.fa.pac"))) + Path(data_genome_fa_sa).resolve().rename(ensure_parents_exist(Path("data/genome.fa.sa"))) + + subprocess.run(["snakemake", "--target-jobs", "bwa_map:sample=A", "--allowed-rules", "bwa_map", "--cores", "8", "--attempt", "1", "--force-use-threads"], check=True) + return (LatchFile('mapped_reads/A.bam')) + +@small_task +def bwa_map_6(data_genome_fa: LatchFile, data_samples_B_fastq: LatchFile, data_genome_fa_amb: LatchFile, data_genome_fa_ann: LatchFile, data_genome_fa_bwt: LatchFile, data_genome_fa_fai: LatchFile, data_genome_fa_pac: LatchFile, data_genome_fa_sa: LatchFile) -> NamedTuple('bwa_map_6_output', mapped_reads_B_bam=LatchFile): + Path(data_genome_fa).resolve().rename(ensure_parents_exist(Path("data/genome.fa"))) + Path(data_samples_B_fastq).resolve().rename(ensure_parents_exist(Path("data/samples/B.fastq"))) + Path(data_genome_fa_amb).resolve().rename(ensure_parents_exist(Path("data/genome.fa.amb"))) + Path(data_genome_fa_ann).resolve().rename(ensure_parents_exist(Path("data/genome.fa.ann"))) + Path(data_genome_fa_bwt).resolve().rename(ensure_parents_exist(Path("data/genome.fa.bwt"))) + Path(data_genome_fa_fai).resolve().rename(ensure_parents_exist(Path("data/genome.fa.fai"))) + Path(data_genome_fa_pac).resolve().rename(ensure_parents_exist(Path("data/genome.fa.pac"))) + Path(data_genome_fa_sa).resolve().rename(ensure_parents_exist(Path("data/genome.fa.sa"))) + + subprocess.run(["snakemake", "--target-jobs", "bwa_map:sample=B", "--allowed-rules", "bwa_map", "--cores", "8", "--attempt", "1", "--force-use-threads"], check=True) + return (LatchFile('mapped_reads/B.bam')) + +@small_task +def samtools_sort_5(mapped_reads_B_bam: LatchFile) -> NamedTuple('samtools_sort_5_output', sorted_reads_B_bam=LatchFile): + Path(mapped_reads_B_bam).resolve().rename(ensure_parents_exist(Path("mapped_reads/B.bam"))) + + subprocess.run(["snakemake", "--target-jobs", "samtools_sort:sample=B", "--allowed-rules", "samtools_sort", "--cores", "8", "--attempt", "1", "--force-use-threads"], check=True) + return (LatchFile('sorted_reads/B.bam')) + +@small_task +def samtools_sort_3(mapped_reads_A_bam: LatchFile) -> NamedTuple('samtools_sort_3_output', sorted_reads_A_bam=LatchFile): + Path(mapped_reads_A_bam).resolve().rename(ensure_parents_exist(Path("mapped_reads/A.bam"))) + + subprocess.run(["snakemake", "--target-jobs", "samtools_sort:sample=A", "--allowed-rules", "samtools_sort", "--cores", "8", "--attempt", "1", "--force-use-threads"], check=True) + return (LatchFile('sorted_reads/A.bam')) + +@small_task +def samtools_index_7(sorted_reads_A_bam: LatchFile) -> NamedTuple('samtools_index_7_output', sorted_reads_A_bam_bai=LatchFile): + Path(sorted_reads_A_bam).resolve().rename(ensure_parents_exist(Path("sorted_reads/A.bam"))) + + subprocess.run(["snakemake", "--target-jobs", "samtools_index:sample=A", "--allowed-rules", "samtools_index", "--cores", "8", "--attempt", "1", "--force-use-threads"], check=True) + return (LatchFile('sorted_reads/A.bam.bai')) + +@small_task +def samtools_index_8(sorted_reads_B_bam: LatchFile) -> NamedTuple('samtools_index_8_output', sorted_reads_B_bam_bai=LatchFile): + Path(sorted_reads_B_bam).resolve().rename(ensure_parents_exist(Path("sorted_reads/B.bam"))) + + subprocess.run(["snakemake", "--target-jobs", "samtools_index:sample=B", "--allowed-rules", "samtools_index", "--cores", "8", "--attempt", "1", "--force-use-threads"], check=True) + return (LatchFile('sorted_reads/B.bam.bai')) + +@small_task +def bcftools_call_2(data_genome_fa: LatchFile, sorted_reads_A_bam: LatchFile, sorted_reads_B_bam: LatchFile, sorted_reads_A_bam_bai: LatchFile, sorted_reads_B_bam_bai: LatchFile) -> NamedTuple('bcftools_call_2_output', calls_all_vcf=LatchFile): + Path(data_genome_fa).resolve().rename(ensure_parents_exist(Path("data/genome.fa"))) + Path(sorted_reads_A_bam).resolve().rename(ensure_parents_exist(Path("sorted_reads/A.bam"))) + Path(sorted_reads_B_bam).resolve().rename(ensure_parents_exist(Path("sorted_reads/B.bam"))) + Path(sorted_reads_A_bam_bai).resolve().rename(ensure_parents_exist(Path("sorted_reads/A.bam.bai"))) + Path(sorted_reads_B_bam_bai).resolve().rename(ensure_parents_exist(Path("sorted_reads/B.bam.bai"))) + + subprocess.run(["snakemake", "--target-jobs", "bcftools_call:", "--allowed-rules", "bcftools_call", "--cores", "8", "--attempt", "1", "--force-use-threads"], check=True) + return (LatchFile('calls/all.vcf')) + +@small_task +def plot_quals_1(calls_all_vcf: LatchFile) -> NamedTuple('plot_quals_1_output', plots_quals_svg=LatchFile): + Path(calls_all_vcf).resolve().rename(ensure_parents_exist(Path("calls/all.vcf"))) + + subprocess.run(["snakemake", "--target-jobs", "plot_quals:", "--allowed-rules", "plot_quals", "--cores", "8", "--attempt", "1", "--force-use-threads"], check=True) + return (LatchFile('plots/quals.svg', 'latch:///plots/quals.svg')) \ No newline at end of file diff --git a/latch_cli/services/init/new_example_snakemake/.latch/latch_entrypoint.py b/latch_cli/services/init/new_example_snakemake/.latch/latch_entrypoint.py new file mode 100644 index 00000000..0419cdad --- /dev/null +++ b/latch_cli/services/init/new_example_snakemake/.latch/latch_entrypoint.py @@ -0,0 +1,85 @@ +import subprocess +from pathlib import Path +from typing import NamedTuple + +from latch import small_task +from latch.types import LatchFile + +def ensure_parents_exist(path: Path): + path.parent.mkdir(parents=True, exist_ok=True) + return path + + +@small_task +def bwa_map_4(data_genome__fa: LatchFile, data_samples_A__fastq: LatchFile, data_genome__fa__amb: LatchFile, data_genome__fa__ann: LatchFile, data_genome__fa__bwt: LatchFile, data_genome__fa__fai: LatchFile, data_genome__fa__pac: LatchFile, data_genome__fa__sa: LatchFile) -> NamedTuple('bwa_map_4_output', mapped_reads_A__bam=LatchFile): + Path(data_genome__fa).resolve().rename(ensure_parents_exist(Path("data/genome.fa"))) + Path(data_samples_A__fastq).resolve().rename(ensure_parents_exist(Path("data/samples/A.fastq"))) + Path(data_genome__fa__amb).resolve().rename(ensure_parents_exist(Path("data/genome.fa.amb"))) + Path(data_genome__fa__ann).resolve().rename(ensure_parents_exist(Path("data/genome.fa.ann"))) + Path(data_genome__fa__bwt).resolve().rename(ensure_parents_exist(Path("data/genome.fa.bwt"))) + Path(data_genome__fa__fai).resolve().rename(ensure_parents_exist(Path("data/genome.fa.fai"))) + Path(data_genome__fa__pac).resolve().rename(ensure_parents_exist(Path("data/genome.fa.pac"))) + Path(data_genome__fa__sa).resolve().rename(ensure_parents_exist(Path("data/genome.fa.sa"))) + + subprocess.run(["snakemake", "-s", "Snakefile", "--target-jobs", "bwa_map:sample=A", "--allowed-rules", "bwa_map", "--local-groupid", "4", "--cores", "1", "--force-use-threads"], check=True) + return (LatchFile('mapped_reads/A.bam')) + +@small_task +def bwa_map_6(data_genome__fa: LatchFile, data_samples_B__fastq: LatchFile, data_genome__fa__amb: LatchFile, data_genome__fa__ann: LatchFile, data_genome__fa__bwt: LatchFile, data_genome__fa__fai: LatchFile, data_genome__fa__pac: LatchFile, data_genome__fa__sa: LatchFile) -> NamedTuple('bwa_map_6_output', mapped_reads_B__bam=LatchFile): + Path(data_genome__fa).resolve().rename(ensure_parents_exist(Path("data/genome.fa"))) + Path(data_samples_B__fastq).resolve().rename(ensure_parents_exist(Path("data/samples/B.fastq"))) + Path(data_genome__fa__amb).resolve().rename(ensure_parents_exist(Path("data/genome.fa.amb"))) + Path(data_genome__fa__ann).resolve().rename(ensure_parents_exist(Path("data/genome.fa.ann"))) + Path(data_genome__fa__bwt).resolve().rename(ensure_parents_exist(Path("data/genome.fa.bwt"))) + Path(data_genome__fa__fai).resolve().rename(ensure_parents_exist(Path("data/genome.fa.fai"))) + Path(data_genome__fa__pac).resolve().rename(ensure_parents_exist(Path("data/genome.fa.pac"))) + Path(data_genome__fa__sa).resolve().rename(ensure_parents_exist(Path("data/genome.fa.sa"))) + + subprocess.run(["snakemake", "-s", "Snakefile", "--target-jobs", "bwa_map:sample=B", "--allowed-rules", "bwa_map", "--local-groupid", "6", "--cores", "1", "--force-use-threads"], check=True) + return (LatchFile('mapped_reads/B.bam')) + +@small_task +def samtools_sort_3(mapped_reads_A__bam: LatchFile) -> NamedTuple('samtools_sort_3_output', sorted_reads_A__bam=LatchFile): + Path(mapped_reads_A__bam).resolve().rename(ensure_parents_exist(Path("mapped_reads/A.bam"))) + + subprocess.run(["snakemake", "-s", "Snakefile", "--target-jobs", "samtools_sort:sample=A", "--allowed-rules", "samtools_sort", "--local-groupid", "3", "--cores", "1", "--force-use-threads"], check=True) + return (LatchFile('sorted_reads/A.bam')) + +@small_task +def samtools_sort_5(mapped_reads_B__bam: LatchFile) -> NamedTuple('samtools_sort_5_output', sorted_reads_B__bam=LatchFile): + Path(mapped_reads_B__bam).resolve().rename(ensure_parents_exist(Path("mapped_reads/B.bam"))) + + subprocess.run(["snakemake", "-s", "Snakefile", "--target-jobs", "samtools_sort:sample=B", "--allowed-rules", "samtools_sort", "--local-groupid", "5", "--cores", "1", "--force-use-threads"], check=True) + return (LatchFile('sorted_reads/B.bam')) + +@small_task +def samtools_index_7(sorted_reads_A__bam: LatchFile) -> NamedTuple('samtools_index_7_output', sorted_reads_A__bam__bai=LatchFile): + Path(sorted_reads_A__bam).resolve().rename(ensure_parents_exist(Path("sorted_reads/A.bam"))) + + subprocess.run(["snakemake", "-s", "Snakefile", "--target-jobs", "samtools_index:sample=A", "--allowed-rules", "samtools_index", "--local-groupid", "7", "--cores", "1", "--force-use-threads"], check=True) + return (LatchFile('sorted_reads/A.bam.bai')) + +@small_task +def samtools_index_8(sorted_reads_B__bam: LatchFile) -> NamedTuple('samtools_index_8_output', sorted_reads_B__bam__bai=LatchFile): + Path(sorted_reads_B__bam).resolve().rename(ensure_parents_exist(Path("sorted_reads/B.bam"))) + + subprocess.run(["snakemake", "-s", "Snakefile", "--target-jobs", "samtools_index:sample=B", "--allowed-rules", "samtools_index", "--local-groupid", "8", "--cores", "1", "--force-use-threads"], check=True) + return (LatchFile('sorted_reads/B.bam.bai')) + +@small_task +def bcftools_call_2(fa: LatchFile, sorted_reads_A__bam: LatchFile, sorted_reads_B__bam: LatchFile, sorted_reads_A__bam__bai: LatchFile, sorted_reads_B__bam__bai: LatchFile) -> NamedTuple('bcftools_call_2_output', calls_all__vcf=LatchFile): + Path(fa).resolve().rename(ensure_parents_exist(Path("data/genome.fa"))) + Path(sorted_reads_A__bam).resolve().rename(ensure_parents_exist(Path("sorted_reads/A.bam"))) + Path(sorted_reads_B__bam).resolve().rename(ensure_parents_exist(Path("sorted_reads/B.bam"))) + Path(sorted_reads_A__bam__bai).resolve().rename(ensure_parents_exist(Path("sorted_reads/A.bam.bai"))) + Path(sorted_reads_B__bam__bai).resolve().rename(ensure_parents_exist(Path("sorted_reads/B.bam.bai"))) + + subprocess.run(["snakemake", "-s", "Snakefile", "--target-jobs", "bcftools_call:", "--allowed-rules", "bcftools_call", "--local-groupid", "2", "--cores", "1", "--force-use-threads"], check=True) + return (LatchFile('calls/all.vcf')) + +@small_task +def plot_quals_1(calls_all__vcf: LatchFile) -> NamedTuple('plot_quals_1_output', plots_quals__svg=LatchFile): + Path(calls_all__vcf).resolve().rename(ensure_parents_exist(Path("calls/all.vcf"))) + + subprocess.run(["snakemake", "-s", "Snakefile", "--target-jobs", "plot_quals:", "--allowed-rules", "plot_quals", "--local-groupid", "1", "--cores", "1", "--force-use-threads"], check=True) + return (LatchFile('plots/quals.svg', 'latch:///plots/quals.svg')) \ No newline at end of file diff --git a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-1d8b2c/docker-build-logs.txt b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-1d8b2c/docker-build-logs.txt new file mode 100644 index 00000000..5b55c987 --- /dev/null +++ b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-1d8b2c/docker-build-logs.txt @@ -0,0 +1,743 @@ +Step 1/14 : from 812206152185.dkr.ecr.us-west-2.amazonaws.com/latch-base:b733-kenny--snakemake + + + ---> 77471241d7a3 + +Step 2/14 : run mkdir /opt/latch + + + ---> Using cache + + ---> 6d1d7399ec34 + +Step 3/14 : RUN curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh && mkdir /root/.conda && bash Mambaforge-Linux-x86_64.sh -b && rm -f Mambaforge-Linux-x86_64.sh + + + ---> Using cache + + ---> e5d7f1c377ad + +Step 4/14 : copy environment.yaml /root/environment.yaml + + + ---> Using cache + + ---> f1895bb6bb01 + +Step 5/14 : run /root/mambaforge/bin/mamba env create --name snakemake-tutorial --file environment.yaml + + + ---> Using cache + + ---> 1c115b179fb8 + +Step 6/14 : env PATH /root/mambaforge/envs/snakemake-tutorial/bin:$PATH + + + ---> Using cache + + ---> 38bcbc3eaccf + +Step 7/14 : copy latch /root/latch + + + ---> 0a6841ad1519 + +Step 8/14 : run cd /root/latch && python3 -m pip install -e . + + + ---> Running in dd7f0cbc398c + +Obtaining file:///root/latch + + Installing build dependencies: started + + Installing build dependencies: finished with status 'done' + Checking if build backend supports build_editable: started + + Checking if build backend supports build_editable: finished with status 'done' + + Getting requirements to build editable: started + + Getting requirements to build editable: finished with status 'done' + + Preparing editable metadata (pyproject.toml): started + + Preparing editable metadata (pyproject.toml): finished with status 'done' + +Collecting asyncssh==2.12.0 (from latch==2.19.11) + + Downloading asyncssh-2.12.0-py3-none-any.whl (346 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 346.7/346.7 kB 8.6 MB/s eta 0:00:00 + + +Collecting aioconsole==0.5.1 (from latch==2.19.11) + + Downloading aioconsole-0.5.1-py3-none-any.whl (30 kB) + +Collecting kubernetes>=24.2.0 (from latch==2.19.11) + + Downloading kubernetes-26.1.0-py2.py3-none-any.whl (1.4 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.4/1.4 MB 44.9 MB/s eta 0:00:00 + + +Collecting pyjwt>=0.2.0 (from latch==2.19.11) + + Downloading PyJWT-2.7.0-py3-none-any.whl (22 kB) + +Requirement already satisfied: requests>=2.28.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from latch==2.19.11) (2.29.0) + +Collecting click>=8.0 (from latch==2.19.11) + + Downloading click-8.1.3-py3-none-any.whl (96 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 96.6/96.6 kB 12.5 MB/s eta 0:00:00 + + +Collecting docker>=5.0 (from latch==2.19.11) + + Downloading docker-6.1.2-py3-none-any.whl (148 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 148.1/148.1 kB 19.4 MB/s eta 0:00:00 + + +Collecting paramiko>=2.11.0 (from latch==2.19.11) + + Downloading paramiko-3.1.0-py3-none-any.whl (211 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 211.2/211.2 kB 24.6 MB/s eta 0:00:00 + + +Collecting scp>=0.14.0 (from latch==2.19.11) + + Downloading scp-0.14.5-py2.py3-none-any.whl (8.7 kB) + +Collecting boto3>=1.24.22 (from latch==2.19.11) + + Using cached boto3-1.26.137-py3-none-any.whl (135 kB) + +Collecting tqdm>=4.63.0 (from latch==2.19.11) + + Downloading tqdm-4.65.0-py3-none-any.whl (77 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 77.1/77.1 kB 10.9 MB/s eta 0:00:00 + + +Collecting lytekit==0.14.10 (from latch==2.19.11) + + Downloading lytekit-0.14.10-py3-none-any.whl (391 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 391.8/391.8 kB 39.4 MB/s eta 0:00:00 + + +Collecting lytekitplugins-pods==0.4.0 (from latch==2.19.11) + + Downloading lytekitplugins_pods-0.4.0-py3-none-any.whl (4.3 kB) + +Requirement already satisfied: typing-extensions==4.5.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from latch==2.19.11) (4.5.0) + +Collecting apscheduler==3.9.1 (from latch==2.19.11) + + Downloading APScheduler-3.9.1-py2.py3-none-any.whl (59 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 59.5/59.5 kB 9.0 MB/s eta 0:00:00 + + +Collecting uvloop==0.17.0 (from latch==2.19.11) + + Downloading uvloop-0.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.1 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.1/4.1 MB 69.9 MB/s eta 0:00:00 + + +Collecting websockets==10.3 (from latch==2.19.11) + + Downloading websockets-10.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (111 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 111.5/111.5 kB 15.2 MB/s eta 0:00:00 + + +Collecting prompt-toolkit==3.0.33 (from latch==2.19.11) + + Downloading prompt_toolkit-3.0.33-py3-none-any.whl (383 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 383.6/383.6 kB 36.6 MB/s eta 0:00:00 + + +Collecting watchfiles==0.18.1 (from latch==2.19.11) + + Downloading watchfiles-0.18.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.2 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.2/1.2 MB 63.8 MB/s eta 0:00:00 + + +Collecting gql==3.4.0 (from latch==2.19.11) + + Downloading gql-3.4.0-py2.py3-none-any.whl (65 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 65.2/65.2 kB 9.5 MB/s eta 0:00:00 + + +Collecting graphql-core==3.2.3 (from latch==2.19.11) + + Downloading graphql_core-3.2.3-py3-none-any.whl (202 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 202.9/202.9 kB 24.1 MB/s eta 0:00:00 + + +Collecting requests-toolbelt==0.10.1 (from latch==2.19.11) + + Downloading requests_toolbelt-0.10.1-py2.py3-none-any.whl (54 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 54.5/54.5 kB 7.2 MB/s eta 0:00:00 + + +Requirement already satisfied: snakemake>=7.25.4 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from latch==2.19.11) (7.25.4) + +Requirement already satisfied: setuptools>=0.7 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from apscheduler==3.9.1->latch==2.19.11) (67.7.2) + +Requirement already satisfied: six>=1.4.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from apscheduler==3.9.1->latch==2.19.11) (1.16.0) + +Collecting pytz (from apscheduler==3.9.1->latch==2.19.11) + + Downloading pytz-2023.3-py2.py3-none-any.whl (502 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 502.3/502.3 kB 43.0 MB/s eta 0:00:00 + + +Collecting tzlocal!=3.*,>=2.0 (from apscheduler==3.9.1->latch==2.19.11) + + Downloading tzlocal-5.0.1-py3-none-any.whl (20 kB) + +Requirement already satisfied: cryptography>=3.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from asyncssh==2.12.0->latch==2.19.11) (39.0.0) + +Collecting yarl<2.0,>=1.6 (from gql==3.4.0->latch==2.19.11) + + Downloading yarl-1.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (268 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 268.8/268.8 kB 29.6 MB/s eta 0:00:00 + + +Collecting backoff<3.0,>=1.11.1 (from gql==3.4.0->latch==2.19.11) + + Downloading backoff-2.2.1-py3-none-any.whl (15 kB) + +Collecting lyteidl==0.2.0a0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading lyteidl-0.2.0a0-py3-none-any.whl (162 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 162.2/162.2 kB 21.9 MB/s eta 0:00:00 + + +Requirement already satisfied: wheel<1.0.0,>=0.30.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (0.40.0) + +Collecting pandas<2.0.0,>=1.0.0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading pandas-1.5.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (12.1 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 12.1/12.1 MB 75.4 MB/s eta 0:00:00 + + +Collecting pyarrow<7.0.0,>=4.0.0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading pyarrow-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (25.6 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 25.6/25.6 MB 53.3 MB/s eta 0:00:00 + + +Collecting croniter<4.0.0,>=0.3.20 (from lytekit==0.14.10->latch==2.19.11) + + Downloading croniter-1.3.14-py2.py3-none-any.whl (18 kB) + +Collecting deprecated<2.0,>=1.0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading Deprecated-1.2.13-py2.py3-none-any.whl (9.6 kB) + +Collecting docker>=5.0 (from latch==2.19.11) + + Downloading docker-5.0.3-py2.py3-none-any.whl (146 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 146.2/146.2 kB 20.1 MB/s eta 0:00:00 + + +Requirement already satisfied: python-dateutil>=2.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (2.8.2) + +Collecting grpcio!=1.45.0,<2.0,>=1.43.0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading grpcio-1.54.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.1 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 5.1/5.1 MB 75.4 MB/s eta 0:00:00 + + +Collecting grpcio-status!=1.45.0,>=1.43 (from lytekit==0.14.10->latch==2.19.11) + + Downloading grpcio_status-1.54.2-py3-none-any.whl (5.1 kB) + +Collecting protobuf<4,>=3.6.1 (from lytekit==0.14.10->latch==2.19.11) + + Downloading protobuf-3.20.3-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (1.1 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.1/1.1 MB 63.2 MB/s eta 0:00:00 + + +Collecting python-json-logger>=2.0.0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading python_json_logger-2.0.7-py3-none-any.whl (8.1 kB) + +Collecting pytimeparse<2.0.0,>=1.1.8 (from lytekit==0.14.10->latch==2.19.11) + + Downloading pytimeparse-1.1.8-py2.py3-none-any.whl (10.0 kB) + +Requirement already satisfied: pyyaml in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (6.0) + +Collecting keyring>=18.0.1 (from lytekit==0.14.10->latch==2.19.11) + + Downloading keyring-23.13.1-py3-none-any.whl (37 kB) + +Collecting responses>=0.10.7 (from lytekit==0.14.10->latch==2.19.11) + + Downloading responses-0.23.1-py3-none-any.whl (52 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 52.1/52.1 kB 7.7 MB/s eta 0:00:00 + + +Collecting sortedcontainers<3.0.0,>=1.5.9 (from lytekit==0.14.10->latch==2.19.11) + + Downloading sortedcontainers-2.4.0-py2.py3-none-any.whl (29 kB) + +Collecting statsd<4.0.0,>=3.0.0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading statsd-3.3.0-py2.py3-none-any.whl (11 kB) + +Requirement already satisfied: urllib3<2.0.0,>=1.22 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (1.26.15) + +Requirement already satisfied: wrapt<2.0.0,>=1.0.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (1.15.0) + +Collecting retry==0.9.2 (from lytekit==0.14.10->latch==2.19.11) + + Downloading retry-0.9.2-py2.py3-none-any.whl (8.0 kB) + +Collecting dataclasses-json>=0.5.2 (from lytekit==0.14.10->latch==2.19.11) + + Downloading dataclasses_json-0.5.7-py3-none-any.whl (25 kB) + +Requirement already satisfied: jsonschema>=4.5.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (4.17.3) + +Collecting marshmallow-jsonschema>=0.12.0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading marshmallow_jsonschema-0.13.0-py3-none-any.whl (11 kB) + +Collecting natsort>=7.0.1 (from lytekit==0.14.10->latch==2.19.11) + + Downloading natsort-8.3.1-py3-none-any.whl (38 kB) + +Collecting docker-image-py>=0.1.10 (from lytekit==0.14.10->latch==2.19.11) + + Downloading docker-image-py-0.1.12.tar.gz (8.2 kB) + + Preparing metadata (setup.py): started + + Preparing metadata (setup.py): finished with status 'done' + +Collecting docstring-parser>=0.9.0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading docstring_parser-0.15-py3-none-any.whl (36 kB) + +Collecting diskcache>=5.2.1 (from lytekit==0.14.10->latch==2.19.11) + + Downloading diskcache-5.6.1-py3-none-any.whl (45 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 45.6/45.6 kB 6.8 MB/s eta 0:00:00 + + +Collecting cloudpickle>=2.0.0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading cloudpickle-2.2.1-py3-none-any.whl (25 kB) + +Collecting cookiecutter>=1.7.3 (from lytekit==0.14.10->latch==2.19.11) + + Downloading cookiecutter-2.1.1-py2.py3-none-any.whl (36 kB) + +Collecting numpy<1.22.0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading numpy-1.21.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (15.9 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 15.9/15.9 MB 72.9 MB/s eta 0:00:00 + + +Collecting wcwidth (from prompt-toolkit==3.0.33->latch==2.19.11) + + Downloading wcwidth-0.2.6-py2.py3-none-any.whl (29 kB) + +Collecting anyio>=3.0.0 (from watchfiles==0.18.1->latch==2.19.11) + + Downloading anyio-3.6.2-py3-none-any.whl (80 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 80.6/80.6 kB 11.6 MB/s eta 0:00:00 + + +Collecting googleapis-common-protos (from lyteidl==0.2.0a0->lytekit==0.14.10->latch==2.19.11) + + Downloading googleapis_common_protos-1.59.0-py2.py3-none-any.whl (223 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 223.6/223.6 kB 28.8 MB/s eta 0:00:00 + + +Collecting protoc-gen-swagger (from lyteidl==0.2.0a0->lytekit==0.14.10->latch==2.19.11) + + Downloading protoc_gen_swagger-0.1.0-py2.py3-none-any.whl (9.4 kB) + +Collecting decorator>=3.4.2 (from retry==0.9.2->lytekit==0.14.10->latch==2.19.11) + + Downloading decorator-5.1.1-py3-none-any.whl (9.1 kB) + +Collecting py<2.0.0,>=1.4.26 (from retry==0.9.2->lytekit==0.14.10->latch==2.19.11) + + Downloading py-1.11.0-py2.py3-none-any.whl (98 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 98.7/98.7 kB 14.9 MB/s eta 0:00:00 + + +Collecting botocore<1.30.0,>=1.29.137 (from boto3>=1.24.22->latch==2.19.11) + + Using cached botocore-1.29.137-py3-none-any.whl (10.8 MB) + +Collecting jmespath<2.0.0,>=0.7.1 (from boto3>=1.24.22->latch==2.19.11) + + Using cached jmespath-1.0.1-py3-none-any.whl (20 kB) + +Collecting s3transfer<0.7.0,>=0.6.0 (from boto3>=1.24.22->latch==2.19.11) + + Using cached s3transfer-0.6.1-py3-none-any.whl (79 kB) + +Collecting websocket-client>=0.32.0 (from docker>=5.0->latch==2.19.11) + + Downloading websocket_client-1.5.2-py3-none-any.whl (56 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 56.6/56.6 kB 9.0 MB/s eta 0:00:00 + + +Requirement already satisfied: certifi>=14.05.14 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from kubernetes>=24.2.0->latch==2.19.11) (2023.5.7) + +Collecting google-auth>=1.0.1 (from kubernetes>=24.2.0->latch==2.19.11) + + Downloading google_auth-2.18.1-py2.py3-none-any.whl (178 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 178.9/178.9 kB 24.0 MB/s eta 0:00:00 + + +Collecting requests-oauthlib (from kubernetes>=24.2.0->latch==2.19.11) + + Downloading requests_oauthlib-1.3.1-py2.py3-none-any.whl (23 kB) + +Collecting bcrypt>=3.2 (from paramiko>=2.11.0->latch==2.19.11) + + Downloading bcrypt-4.0.1-cp36-abi3-manylinux_2_28_x86_64.whl (593 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 593.7/593.7 kB 49.7 MB/s eta 0:00:00 + + +Collecting pynacl>=1.5 (from paramiko>=2.11.0->latch==2.19.11) + + Downloading PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl (856 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 856.7/856.7 kB 58.5 MB/s eta 0:00:00 + + +Requirement already satisfied: charset-normalizer<4,>=2 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from requests>=2.28.1->latch==2.19.11) (3.1.0) + +Requirement already satisfied: idna<4,>=2.5 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from requests>=2.28.1->latch==2.19.11) (3.4) + +Requirement already satisfied: appdirs in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.4.4) + +Requirement already satisfied: configargparse in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.5.3) + +Requirement already satisfied: connection-pool>=0.0.3 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (0.0.3) + +Requirement already satisfied: datrie in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (0.8.2) + +Requirement already satisfied: docutils in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (0.20.1) + +Requirement already satisfied: gitpython in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (3.1.31) + +Requirement already satisfied: humanfriendly in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (10.0) + +Requirement already satisfied: jinja2<4.0,>=3.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (3.1.2) + +Requirement already satisfied: nbformat in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (5.8.0) + +Requirement already satisfied: psutil in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (5.9.5) + +Requirement already satisfied: pulp>=2.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (2.7.0) + +Requirement already satisfied: reretry in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (0.11.8) + +Requirement already satisfied: smart-open>=3.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (6.3.0) + +Requirement already satisfied: stopit in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.1.2) + +Requirement already satisfied: tabulate in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (0.9.0) + +Requirement already satisfied: throttler in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.2.1) + +Requirement already satisfied: toposort>=1.10 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.10) + +Requirement already satisfied: yte<2.0,>=1.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.5.1) + +Collecting sniffio>=1.1 (from anyio>=3.0.0->watchfiles==0.18.1->latch==2.19.11) + + Downloading sniffio-1.3.0-py3-none-any.whl (10 kB) + +Collecting binaryornot>=0.4.4 (from cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) + + Downloading binaryornot-0.4.4-py2.py3-none-any.whl (9.0 kB) + +Collecting jinja2-time>=0.2.0 (from cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) + + Downloading jinja2_time-0.2.0-py2.py3-none-any.whl (6.4 kB) + +Collecting python-slugify>=4.0.0 (from cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) + + Downloading python_slugify-8.0.1-py2.py3-none-any.whl (9.7 kB) + +Requirement already satisfied: cffi>=1.12 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from cryptography>=3.1->asyncssh==2.12.0->latch==2.19.11) (1.15.1) + +Collecting marshmallow<4.0.0,>=3.3.0 (from dataclasses-json>=0.5.2->lytekit==0.14.10->latch==2.19.11) + + Downloading marshmallow-3.19.0-py3-none-any.whl (49 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 49.1/49.1 kB 7.0 MB/s eta 0:00:00 + + +Collecting marshmallow-enum<2.0.0,>=1.5.1 (from dataclasses-json>=0.5.2->lytekit==0.14.10->latch==2.19.11) + + Downloading marshmallow_enum-1.5.1-py2.py3-none-any.whl (4.2 kB) + +Collecting typing-inspect>=0.4.0 (from dataclasses-json>=0.5.2->lytekit==0.14.10->latch==2.19.11) + + Downloading typing_inspect-0.8.0-py3-none-any.whl (8.7 kB) + +Collecting regex>=2019.4.14 (from docker-image-py>=0.1.10->lytekit==0.14.10->latch==2.19.11) + + Downloading regex-2023.5.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (769 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 769.7/769.7 kB 56.9 MB/s eta 0:00:00 + + +Collecting cachetools<6.0,>=2.0.0 (from google-auth>=1.0.1->kubernetes>=24.2.0->latch==2.19.11) + + Downloading cachetools-5.3.0-py3-none-any.whl (9.3 kB) + +Collecting pyasn1-modules>=0.2.1 (from google-auth>=1.0.1->kubernetes>=24.2.0->latch==2.19.11) + + Downloading pyasn1_modules-0.3.0-py2.py3-none-any.whl (181 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 181.3/181.3 kB 21.8 MB/s eta 0:00:00 + + +Collecting rsa<5,>=3.1.4 (from google-auth>=1.0.1->kubernetes>=24.2.0->latch==2.19.11) + + Downloading rsa-4.9-py3-none-any.whl (34 kB) + +INFO: pip is looking at multiple versions of grpcio-status to determine which version is compatible with other requirements. This could take a while. + +Collecting grpcio-status!=1.45.0,>=1.43 (from lytekit==0.14.10->latch==2.19.11) + + Downloading grpcio_status-1.54.0-py3-none-any.whl (5.1 kB) + + Downloading grpcio_status-1.53.1-py3-none-any.whl (5.1 kB) + + Downloading grpcio_status-1.53.0-py3-none-any.whl (5.1 kB) + + Downloading grpcio_status-1.51.3-py3-none-any.whl (5.1 kB) + + Downloading grpcio_status-1.51.1-py3-none-any.whl (5.1 kB) + + Downloading grpcio_status-1.50.0-py3-none-any.whl (14 kB) + + Downloading grpcio_status-1.49.1-py3-none-any.whl (14 kB) + +INFO: pip is looking at multiple versions of grpcio-status to determine which version is compatible with other requirements. This could take a while. + + Downloading grpcio_status-1.48.2-py3-none-any.whl (14 kB) + +Requirement already satisfied: MarkupSafe>=2.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from jinja2<4.0,>=3.0->snakemake>=7.25.4->latch==2.19.11) (2.1.2) + +Requirement already satisfied: attrs>=17.4.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from jsonschema>=4.5.1->lytekit==0.14.10->latch==2.19.11) (23.1.0) + +Requirement already satisfied: pyrsistent!=0.17.0,!=0.17.1,!=0.17.2,>=0.14.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from jsonschema>=4.5.1->lytekit==0.14.10->latch==2.19.11) (0.19.3) + +Collecting jaraco.classes (from keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) + + Downloading jaraco.classes-3.2.3-py3-none-any.whl (6.0 kB) + +Requirement already satisfied: importlib-metadata>=4.11.4 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) (6.6.0) + +Collecting SecretStorage>=3.2 (from keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) + + Downloading SecretStorage-3.3.3-py3-none-any.whl (15 kB) + +Collecting jeepney>=0.4.2 (from keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) + + Downloading jeepney-0.8.0-py3-none-any.whl (48 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 48.4/48.4 kB 7.6 MB/s eta 0:00:00 + + +Collecting types-PyYAML (from responses>=0.10.7->lytekit==0.14.10->latch==2.19.11) + + Downloading types_PyYAML-6.0.12.9-py3-none-any.whl (14 kB) + +Collecting multidict>=4.0 (from yarl<2.0,>=1.6->gql==3.4.0->latch==2.19.11) + + Downloading multidict-6.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (114 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 114.5/114.5 kB 15.6 MB/s eta 0:00:00 + + +Requirement already satisfied: dpath<3.0,>=2.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from yte<2.0,>=1.0->snakemake>=7.25.4->latch==2.19.11) (2.1.6) + +Requirement already satisfied: plac<2.0.0,>=1.3.4 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from yte<2.0,>=1.0->snakemake>=7.25.4->latch==2.19.11) (1.3.5) + +Requirement already satisfied: gitdb<5,>=4.0.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from gitpython->snakemake>=7.25.4->latch==2.19.11) (4.0.10) + +Requirement already satisfied: fastjsonschema in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from nbformat->snakemake>=7.25.4->latch==2.19.11) (2.16.3) + +Requirement already satisfied: jupyter-core in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from nbformat->snakemake>=7.25.4->latch==2.19.11) (5.3.0) + +Requirement already satisfied: traitlets>=5.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from nbformat->snakemake>=7.25.4->latch==2.19.11) (5.9.0) + +Collecting oauthlib>=3.0.0 (from requests-oauthlib->kubernetes>=24.2.0->latch==2.19.11) + + Downloading oauthlib-3.2.2-py3-none-any.whl (151 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 151.7/151.7 kB 20.8 MB/s eta 0:00:00 + + +Collecting chardet>=3.0.2 (from binaryornot>=0.4.4->cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) + + Downloading chardet-5.1.0-py3-none-any.whl (199 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 199.1/199.1 kB 24.7 MB/s eta 0:00:00 + + +Requirement already satisfied: pycparser in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from cffi>=1.12->cryptography>=3.1->asyncssh==2.12.0->latch==2.19.11) (2.21) + +Requirement already satisfied: smmap<6,>=3.0.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from gitdb<5,>=4.0.1->gitpython->snakemake>=7.25.4->latch==2.19.11) (3.0.5) + +Requirement already satisfied: zipp>=0.5 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from importlib-metadata>=4.11.4->keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) (3.15.0) + +Collecting arrow (from jinja2-time>=0.2.0->cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) + + Downloading arrow-1.2.3-py3-none-any.whl (66 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 66.4/66.4 kB 8.8 MB/s eta 0:00:00 + + +Requirement already satisfied: packaging>=17.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from marshmallow<4.0.0,>=3.3.0->dataclasses-json>=0.5.2->lytekit==0.14.10->latch==2.19.11) (23.1) + +Collecting pyasn1<0.6.0,>=0.4.6 (from pyasn1-modules>=0.2.1->google-auth>=1.0.1->kubernetes>=24.2.0->latch==2.19.11) + + Using cached pyasn1-0.5.0-py2.py3-none-any.whl (83 kB) + +Collecting text-unidecode>=1.3 (from python-slugify>=4.0.0->cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) + + Downloading text_unidecode-1.3-py2.py3-none-any.whl (78 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 78.2/78.2 kB 11.7 MB/s eta 0:00:00 + + +Collecting mypy-extensions>=0.3.0 (from typing-inspect>=0.4.0->dataclasses-json>=0.5.2->lytekit==0.14.10->latch==2.19.11) + + Downloading mypy_extensions-1.0.0-py3-none-any.whl (4.7 kB) + +Collecting more-itertools (from jaraco.classes->keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) + + Downloading more_itertools-9.1.0-py3-none-any.whl (54 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 54.2/54.2 kB 7.8 MB/s eta 0:00:00 + + +Requirement already satisfied: platformdirs>=2.5 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from jupyter-core->nbformat->snakemake>=7.25.4->latch==2.19.11) (3.5.1) + +WARNING: The candidate selected for download or install is a yanked version: 'apscheduler' candidate (version 3.9.1 at https://files.pythonhosted.org/packages/e4/9f/c3937d4babe62504b874d4bf2c0d85aa69c7f59fa84cf6050f3b9dc5d83e/APScheduler-3.9.1-py2.py3-none-any.whl (from https://pypi.org/simple/apscheduler/) (requires-python:>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4)) +Reason for being yanked: Not compatible with Python 2.7 + +Building wheels for collected packages: latch, docker-image-py + + Building editable for latch (pyproject.toml): started + + Building editable for latch (pyproject.toml): finished with status 'done' + + Created wheel for latch: filename=latch-2.19.11-0.editable-py3-none-any.whl size=3728 sha256=45c37325a5f77f85cab10dbf6078b5c6c13a16e244e658684de17b426a03da77 + + Stored in directory: /tmp/pip-ephem-wheel-cache-2rp2kq11/wheels/66/25/3a/f25ede02a4206d090762dd0ca4dbdc81da4d61e154ed692990 + + Building wheel for docker-image-py (setup.py): started + + Building wheel for docker-image-py (setup.py): finished with status 'done' + + Created wheel for docker-image-py: filename=docker_image_py-0.1.12-py3-none-any.whl size=8812 sha256=60010da77a8bfeaf7239633bb9e48b81ba0a2431b6a10d6a13a137d18ed8bc30 + + Stored in directory: /root/.cache/pip/wheels/fb/45/02/503244da15fbcecde5c3edabb744ed0c4f9a7643126b2d222c + +Successfully built latch docker-image-py + +Installing collected packages: wcwidth, types-PyYAML, text-unidecode, statsd, sortedcontainers, pytz, pytimeparse, websockets, websocket-client, uvloop, tzlocal, tqdm, sniffio, regex, python-slugify, python-json-logger, pyjwt, pyasn1, py, protobuf, prompt-toolkit, oauthlib, numpy, natsort, mypy-extensions, multidict, more-itertools, marshmallow, jmespath, jeepney, grpcio, graphql-core, docstring-parser, diskcache, deprecated, decorator, cloudpickle, click, chardet, cachetools, bcrypt, backoff, aioconsole, yarl, typing-inspect, rsa, retry, responses, requests-toolbelt, requests-oauthlib, pynacl, pyasn1-modules, pyarrow, protoc-gen-swagger, pandas, marshmallow-jsonschema, marshmallow-enum, jaraco.classes, googleapis-common-protos, docker-image-py, docker, croniter, botocore, binaryornot, arrow, apscheduler, anyio, watchfiles, SecretStorage, s3transfer, paramiko, lyteidl, jinja2-time, grpcio-status, gql, google-auth, dataclasses-json, asyncssh, scp, kubernetes, keyring, cookiecutter, boto3, lytekit, lytekitplugins-pods, latch + + Attempting uninstall: numpy + + Found existing installation: numpy 1.24.3 + + Uninstalling numpy-1.24.3: + + Successfully uninstalled numpy-1.24.3 + +Successfully installed SecretStorage-3.3.3 aioconsole-0.5.1 anyio-3.6.2 apscheduler-3.9.1 arrow-1.2.3 asyncssh-2.12.0 backoff-2.2.1 bcrypt-4.0.1 binaryornot-0.4.4 boto3-1.26.137 botocore-1.29.137 cachetools-5.3.0 chardet-5.1.0 click-8.1.3 cloudpickle-2.2.1 cookiecutter-2.1.1 croniter-1.3.14 dataclasses-json-0.5.7 decorator-5.1.1 deprecated-1.2.13 diskcache-5.6.1 docker-5.0.3 docker-image-py-0.1.12 docstring-parser-0.15 google-auth-2.18.1 googleapis-common-protos-1.59.0 gql-3.4.0 graphql-core-3.2.3 grpcio-1.54.2 grpcio-status-1.48.2 jaraco.classes-3.2.3 jeepney-0.8.0 jinja2-time-0.2.0 jmespath-1.0.1 keyring-23.13.1 kubernetes-26.1.0 latch-2.19.11 lyteidl-0.2.0a0 lytekit-0.14.10 lytekitplugins-pods-0.4.0 marshmallow-3.19.0 marshmallow-enum-1.5.1 marshmallow-jsonschema-0.13.0 more-itertools-9.1.0 multidict-6.0.4 mypy-extensions-1.0.0 natsort-8.3.1 numpy-1.21.6 oauthlib-3.2.2 pandas-1.5.3 paramiko-3.1.0 prompt-toolkit-3.0.33 protobuf-3.20.3 protoc-gen-swagger-0.1.0 py-1.11.0 pyarrow-6.0.1 pyasn1-0.5.0 pyasn1-modules-0.3.0 pyjwt-2.7.0 pynacl-1.5.0 python-json-logger-2.0.7 python-slugify-8.0.1 pytimeparse-1.1.8 pytz-2023.3 regex-2023.5.5 requests-oauthlib-1.3.1 requests-toolbelt-0.10.1 responses-0.23.1 retry-0.9.2 rsa-4.9 s3transfer-0.6.1 scp-0.14.5 sniffio-1.3.0 sortedcontainers-2.4.0 statsd-3.3.0 text-unidecode-1.3 tqdm-4.65.0 types-PyYAML-6.0.12.9 typing-inspect-0.8.0 tzlocal-5.0.1 uvloop-0.17.0 watchfiles-0.18.1 wcwidth-0.2.6 websocket-client-1.5.2 websockets-10.3 yarl-1.9.2 + +WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv + + ---> 987ca2488773 + +Step 9/14 : copy Snakefile config.yaml /root/ + + + ---> ff2efbf9c325 + +Step 10/14 : copy scripts/plot-quals.py /root/scripts/plot-quals.py + + + ---> efa63cf5aa2d + +Step 11/14 : copy .latch/latch_entrypoint.py /root/latch_entrypoint.py + + + ---> 5222bb3def10 + +Step 12/14 : arg tag + + + ---> Running in 0d5670080d49 + + ---> 2b44d6814bf9 + +Step 13/14 : env FLYTE_INTERNAL_IMAGE $tag + + + ---> Running in 7c86bbffcaba + + ---> d60334da0de6 + +Step 14/14 : workdir /root + + + ---> Running in 04fe88e9f8bb + + ---> 2fde7c305cbd + +Successfully built 2fde7c305cbd + +Successfully tagged 812206152185.dkr.ecr.us-west-2.amazonaws.com/x1_test_latch_register:0.0.0-1d8b2c + diff --git a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-2dd65d/docker-build-logs.txt b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-2dd65d/docker-build-logs.txt new file mode 100644 index 00000000..c645afa0 --- /dev/null +++ b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-2dd65d/docker-build-logs.txt @@ -0,0 +1,514 @@ +Step 1/14 : from 812206152185.dkr.ecr.us-west-2.amazonaws.com/latch-base:9c8f-main + + + ---> b253e8cdab51 + +Step 2/14 : run mkdir /opt/latch + + + ---> Running in b1d3040ec8a1 + + ---> 89e0ab657f0d + +Step 3/14 : RUN curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh && mkdir /root/.conda && bash Mambaforge-Linux-x86_64.sh -b && rm -f Mambaforge-Linux-x86_64.sh + + + ---> Running in 67b55c21f5aa + + % Total % Received % Xferd Aver +age Speed Time Time Time Current + Dload Upload Total Spent Left Speed + 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 + 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 + + 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 + + 0 82.9M 0 718k 0 0 1250k 0 0:01:07 --:--:-- 0:01:07 1250k + 73 82.9M 73 61.0M 0 0 38.7M 0 0:00:02 0:00:01 0:00:01 60.3M + 100 82.9M 100 82.9M 0 0 42.4M 0 0:00:01 0:00:01 --:--:-- 59.7M + +PREFIX=/root/mambaforge + +Unpacking payload ... + +Extracting _libgcc_mutex-0.1-conda_forge.tar.bz2 + +Extracting ca-certificates-2022.12.7-ha878542_0.conda + +Extracting ld_impl_linux-64-2.40-h41732ed_0.conda + +Extracting libstdcxx-ng-12.2.0-h46fd767_19.tar.bz2 + +Extracting pybind11-abi-4-hd8ed1ab_3.tar.bz2 + +Extracting python_abi-3.10-3_cp310.conda + +Extracting tzdata-2023c-h71feb2d_0.conda + +Extracting libgomp-12.2.0-h65d4601_19.tar.bz2 + +Extracting _openmp_mutex-4.5-2_gnu.tar.bz2 + +Extracting libgcc-ng-12.2.0-h65d4601_19.tar.bz2 + +Extracting bzip2-1.0.8-h7f98852_4.tar.bz2 + +Extracting c-ares-1.18.1-h7f98852_0.tar.bz2 + +Extracting fmt-9.1.0-h924138e_0.tar.bz2 + +Extracting icu-72.1-hcb278e6_0.conda + +Extracting keyutils-1.6.1-h166bdaf_0.tar.bz2 + +Extracting libev-4.33-h516909a_1.tar.bz2 + +Extracting libffi-3.4.2-h7f98852_5.tar.bz2 + +Extracting libiconv-1.17-h166bdaf_0.tar.bz2 + +Extracting libnsl-2.0.0-h7f98852_0.tar.bz2 + +Extracting libuuid-2.38.1-h0b41bf4_0.conda + +Extracting libzlib-1.2.13-h166bdaf_4.tar.bz2 + +Extracting lz4-c-1.9.4-hcb278e6_0.conda + +Extracting lzo-2.10-h516909a_1000.tar.bz2 + +Extracting ncurses-6.3-h27087fc_1.tar.bz2 + +Extracting openssl-3.1.0-h0b41bf4_0.conda + +Extracting reproc-14.2.4-h0b41bf4_0.conda + +Extracting xz-5.2.6-h166bdaf_0.tar.bz2 + +Extracting yaml-cpp-0.7.0-h27087fc_2.tar.bz2 + +Extracting libedit-3.1.20191231-he28a2e2_2.tar.bz2 + +Extracting libnghttp2-1.52.0-h61bc06f_0.conda + +Extracting libsolv-0.7.23-h3eb15da_0.conda + +Extracting libsqlite-3.40.0-h753d276_0.tar.bz2 + +Extracting libssh2-1.10.0-hf14f497_3.tar.bz2 + +Extracting libxml2-2.10.3-hfdac1af_6.conda + +Extracting readline-8.2-h8228510_1.conda + +Extracting reproc-cpp-14.2.4-hcb278e6_0.conda + +Extracting tk-8.6.12-h27826a3_0.tar.bz2 + +Extracting zstd-1.5.2-h3eb15da_6.conda + +Extracting krb5-1.20.1-h81ceb04_0.conda + +Extracting libarchive-3.6.2-h3d51595_0.conda + +Extracting python-3.10.10-he550d4f_0_cpython.conda + +Extracting certifi-2022.12.7-pyhd8ed1ab_0.conda + +Extracting charset-normalizer-3.1.0-pyhd8ed1ab_0.conda + +Extracting colorama-0.4.6-pyhd8ed1ab_0.tar.bz2 + +Extracting idna-3.4-pyhd8ed1ab_0.tar.bz2 + +Extracting libcurl-7.88.1-hdc1c0ab_1.conda + +Extracting pluggy-1.0.0-pyhd8ed1ab_5.tar.bz2 + +Extracting pycosat-0.6.4-py310h5764c6d_1.tar.bz2 + +Extracting pycparser-2.21-pyhd8ed1ab_0.tar.bz2 + +Extracting pysocks-1.7.1-pyha2e5f31_6.tar.bz2 + +Extracting ruamel.yaml.clib-0.2.7-py310h1fa729e_1.conda + +Extracting setuptools-65.6.3-pyhd8ed1ab_0.conda + +Extracting toolz-0.12.0-pyhd8ed1ab_0.tar.bz2 + +Extracting wheel-0.40.0-pyhd8ed1ab_0.conda + +Extracting cffi-1.15.1-py310h255011f_3.conda + +Extracting libmamba-1.4.1-hcea66bb_0.conda + +Extracting pip-23.0.1-pyhd8ed1ab_0.conda + +Extracting ruamel.yaml-0.17.21-py310h1fa729e_3.conda + +Extracting tqdm-4.65.0-pyhd8ed1ab_1.conda + +Extracting brotlipy-0.7.0-py310h5764c6d_1005.tar.bz2 + +Extracting cryptography-40.0.1-py310h34c0648_0.conda + +Extracting libmambapy-1.4.1-py310h1428755_0.conda + +Extracting zstandard-0.19.0-py310hdeb6495_1.conda + +Extracting conda-package-streaming-0.7.0-pyhd8ed1ab_1.conda + +Extracting pyopenssl-23.1.1-pyhd8ed1ab_0.conda + +Extracting conda-package-handling-2.0.2-pyh38be061_0.conda + +Extracting urllib3-1.26.15-pyhd8ed1ab_0.conda + +Extracting requests-2.28.2-pyhd8ed1ab_1.conda + +Extracting conda-23.1.0-py310hff52083_0.conda + +Extracting mamba-1.4.1-py310h51d5547_0.conda + + +Installing base environment... + + + + __ + __ ______ ___ ____ _____ ___ / /_ ____ _ + / / / / __ `__ \/ __ `/ __ `__ \/ __ \/ __ `/ + / /_/ / / / / / / /_/ / / / / / / /_/ / /_/ / + / .___/_/ /_/ /_/\__,_/_/ /_/ /_/_.___/\__,_/ + /_/ + + +Transaction + + Prefix: /root/mambaforge + + Updating specs: + + - conda-forge/linux-64::_libgcc_mutex==0.1=conda_forge[md5=d7c89558ba9fa0495403155b64376d81] + - conda-forge/linux-64::ca-certificates==2022.12.7=ha878542_0[md5=ff9f73d45c4a07d6f424495288a26080] + - conda-forge/linux-64::ld_impl_linux-64==2.40=h41732ed_0[md5=7aca3059a1729aa76c597603f10b0dd3] + - conda-forge/linux-64::libstdcxx-ng==12.2.0=h46fd767_19[md5=1030b1f38c129f2634eae026f704fe60] + - conda-forge/noarch::pybind11-abi==4=hd8ed1ab_3[md5=878f923dd6acc8aeb47a75da6c4098be] + - conda-forge/linux-64::python_abi==3.10=3_cp310[md5=4eb33d14d794b0f4be116443ffed3853] + - conda-forge/noarch::tzdata==2023c=h71feb2d_0[md5=939e3e74d8be4dac89ce83b20de2492a] + - conda-forge/linux-64::libgomp==12.2.0=h65d4601_19[md5=cedcee7c064c01c403f962c9e8d3c373] + - conda-forge/linux-64::_openmp_mutex==4.5=2_gnu[md5=73aaf86a425cc6e73fcf236a5a46396d] + - conda-forge/linux-64::libgcc-ng==12.2.0=h65d4601_19[md5=e4c94f80aef025c17ab0828cd85ef535] + - conda-forge/linux-64::bzip2==1.0.8=h7f98852_4[md5=a1fd65c7ccbf10880423d82bca54eb54] + - conda-forge/linux-64::c-ares==1.18.1=h7f98852_0[md5=f26ef8098fab1f719c91eb760d63381a] + - conda-forge/linux-64::fmt==9.1.0=h924138e_0[md5=b57864c85261a0fbc7132d2cc17478c7] + - conda-forge/linux-64::icu==72.1=hcb278e6_0[md5=7c8d20d847bb45f56bd941578fcfa146] + - conda-forge/linux-64::keyutils==1.6.1=h166bdaf_0[md5=30186d27e2c9fa62b45fb1476b7200e3] + - conda-forge/linux-64::libev==4.33=h516909a_1[md5=6f8720dff19e17ce5d48cfe7f3d2f0a3] + - conda-forge/linux-64::libffi==3.4.2=h7f98852_5[md5=d645c6d2ac96843a2bfaccd2d62b3ac3] + - conda-forge/linux-64::libiconv==1.17=h166bdaf_0[md5=b62b52da46c39ee2bc3c162ac7f1804d] + - conda-forge/linux-64::libnsl==2.0.0=h7f98852_0[md5=39b1328babf85c7c3a61636d9cd50206] + - conda-forge/linux-64::libuuid==2.38.1=h0b41bf4_0[md5=40b61aab5c7ba9ff276c41cfffe6b80b] + + - conda-forge/linux-64::libzlib==1.2.13=h166bdaf_4[md5=f3f9de449d32ca9b9c66a22863c96f41] + - conda-forge/linux-64::lz4-c==1.9.4=hcb278e6_0[md5=318b08df404f9c9be5712aaa5a6f0bb0] + - conda-forge/linux-64::lzo==2.10=h516909a_1000[md5=bb14fcb13341b81d5eb386423b9d2bac] + - conda-forge/linux-64::ncurses==6.3=h27087fc_1[md5=4acfc691e64342b9dae57cf2adc63238] + - conda-forge/linux-64::openssl==3.1.0=h0b41bf4_0[md5=2d833be81a21128e317325a01326d36f] + - conda-forge/linux-64::reproc==14.2.4=h0b41bf4_0[md5=0f51393e019df1f0047ef864cd9ddeec] + - conda-forge/linux-64::xz==5.2.6=h166bdaf_0[md5=2161070d867d1b1204ea749c8eec4ef0] + - conda-forge/linux-64::yaml-cpp==0.7.0=h27087fc_2[md5=0449d47d8457feaa3720d4779616dde2] + - conda-forge/linux-64::libedit==3.1.20191231=he28a2e2_2[md5=4d331e44109e3f0e19b4cb8f9b82f3e1] + - conda-forge/linux-64::libnghttp2==1.52.0=h61bc06f_0[md5=613955a50485812985c059e7b269f42e] + - conda-forge/linux-64::libsolv==0.7.23=h3eb15da_0[md5=122332e6deb4aea9eaf22021d2ecd256] + - conda-forge/linux-64::libsqlite==3.40.0=h753d276_0[md5=2e5f9a37d487e1019fd4d8113adb2f9f] + - conda-forge/linux-64::libssh2==1.10.0=hf14f497_3[md5=d85acad4b47dff4e3def14a769a97906] + - conda-forge/linux-64::libxml2==2.10.3=hfdac1af_6[md5=7eecaadc2eaeef464c5fe17702f17c86] + - conda-forge/linux-64::readline==8.2=h8228510_1[md5=47d31b792659ce70f470b5c82fdfb7a4] + - conda-forge/linux-64::reproc-cpp==14.2.4=hcb278e6_0[md5=ede8e0f849f2fee2f78cb488b4ea3b33] + - conda-forge/linux-64::tk==8.6.12=h27826a3_0[md5=5b8c42eb62e9fc961af70bdd6a26e168] + - conda-forge/linux-64::zstd==1.5.2=h3eb15da_6[md5=6b63daed8feeca47be78f323e793d555] + - conda-forge/linux-64::krb5==1.20.1=h81ceb04_0[md5=89a41adce7106749573d883b2f657d78] + - conda-forge/linux-64::libarchive==3.6.2=h3d51595_0[md5=9f915b4adeb9dcfd450b9ad238e2db4c] + - conda-forge/linux-64::python==3.10.10=he550d4f_0_cpython[md5=de25afc7041c103c7f510c746bb63435] + - conda-forge/noarch::certifi==2022.12.7=pyhd8ed1ab_0[md5=fb9addc3db06e56abe03e0e9f21a63e6] + - conda-forge/noarch::charset-normalizer==3.1.0=pyhd8ed1ab_0[md5=7fcff9f6f123696e940bda77bd4d6551] + - conda-forge/noarch::colorama==0.4.6=pyhd8ed1ab_0[md5=3faab06a954c2a04039983f2c4a50d99] + - conda-forge/noarch::idna==3.4=pyhd8ed1ab_0[md5=34272b248891bddccc64479f9a7fffed] + - conda-forge/linux-64::libcurl==7.88.1=hdc1c0ab_1[md5=3d1189864d1c0ed2a5919cb067b5903d] + + - conda-forge/noarch::pluggy==1.0.0=pyhd8ed1ab_5[md5=7d301a0d25f424d96175f810935f0da9] + - conda-forge/linux-64::pycosat==0.6.4=py310h5764c6d_1[md5=0e565d732f6660374b45d76761c09b06] + - conda-forge/noarch::pycparser==2.21=pyhd8ed1ab_0[md5=076becd9e05608f8dc72757d5f3a91ff] + - conda-forge/noarch::pysocks==1.7.1=pyha2e5f31_6[md5=2a7de29fb590ca14b5243c4c812c8025] + - conda-forge/linux-64::ruamel.yaml.clib==0.2.7=py310h1fa729e_1[md5=2f9b517412af46255cef5e53a22c264e] + - conda-forge/noarch::setuptools==65.6.3=pyhd8ed1ab_0[md5=9600fc9524d3f821e6a6d58c52f5bf5a] + - conda-forge/noarch::toolz==0.12.0=pyhd8ed1ab_0[md5=92facfec94bc02d6ccf42e7173831a36] + - conda-forge/noarch::wheel==0.40.0=pyhd8ed1ab_0[md5=49bb0d9e60ce1db25e151780331bb5f3] + - conda-forge/linux-64::cffi==1.15.1=py310h255011f_3[md5=800596144bb613cd7ac58b80900ce835] + - conda-forge/linux-64::libmamba==1.4.1=hcea66bb_0[md5=e512a4c95ff1eca1684642fa32bd2f55] + - conda-forge/noarch::pip==23.0.1=pyhd8ed1ab_0[md5=8025ca83b8ba5430b640b83917c2a6f7] + - conda-forge/linux-64::ruamel.yaml==0.17.21=py310h1fa729e_3[md5=97204ae92b703d74a983db0e6d07d009] + - conda-forge/noarch::tqdm==4.65.0=pyhd8ed1ab_1[md5=ed792aff3acb977d09c7013358097f83] + - conda-forge/linux-64::brotlipy==0.7.0=py310h5764c6d_1005[md5=87669c3468dff637bbd0363bc0f895cf] + - conda-forge/linux-64::cryptography==40.0.1=py310h34c0648_0[md5=deafd9206c2e307874f3777a33cafb79] + - conda-forge/linux-64::libmambapy==1.4.1=py310h1428755_0[md5=323e09e9947b6a415f9d73562e4ca862] + - conda-forge/linux-64::zstandard==0.19.0=py310hdeb6495_1[md5=2cce1a48e6687f64d371d2e7fc9c7fbf] + - conda-forge/noarch::conda-package-streaming==0.7.0=pyhd8ed1ab_1[md5=1a2fa9e53cfbc2e4d9ab21990805a436] + - conda-forge/noarch::pyopenssl==23.1.1=pyhd8ed1ab_0[md5=0b34aa3ab7e7ccb1765a03dd9ed29938] + - conda-forge/noarch::conda-package-handling==2.0.2=pyh38be061_0[md5=44800e9bd13143292097c65e57323038] + - conda-forge/noarch::urllib3==1.26.15=pyhd8ed1ab_0[md5=27db656619a55d727eaf5a6ece3d2fd6] + - conda-forge/noarch::requests==2.28.2=pyhd8ed1ab_1[md5=3bfbd6ead1d7299ed46dab3a7bf0bc8c] + - conda-forge/linux-64::conda==23.1.0=py310hff52083_0[md5=c2f5cd14bf4a8cc673f66fd9839e6602] + - conda-forge/linux-64::mamba==1.4.1=py310h51d5547_0[md5=49170d6752d2326fe16dc2b6e74f9e54] + + + + Package Version Build Channel Size +─────────────────────────────────────────────────────────────────────────────────────── + Install: +─────────────────────────────────────────────────────────────────────────────────────── + + + _libgcc_mutex 0.1 conda_forge conda-forge Cached + + _openmp_mutex 4.5 2_gnu conda-forge Cached + + brotlipy 0.7.0 py310h5764c6d_1005 conda-forge Cached + + bzip2 1.0.8 h7f98852_4 conda-forge Cached + + c-ares 1.18.1 h7f98852_0 conda-forge Cached + + ca-certificates 2022.12.7 ha878542_0 conda-forge Cached + + certifi 2022.12.7 pyhd8ed1ab_0 conda-forge Cached + + cffi 1.15.1 py310h255011f_3 conda-forge Cached + + charset-normalizer 3.1.0 pyhd8ed1ab_0 conda-forge Cached + + colorama 0.4.6 pyhd8ed1ab_0 conda-forge Cached + + conda 23.1.0 py310hff52083_0 conda-forge Cached + + conda-package-handling 2.0.2 pyh38be061_0 conda-forge Cached + + conda-package-streaming 0.7.0 pyhd8ed1ab_1 conda-forge Cached + + cryptography 40.0.1 py310h34c0648_0 conda-forge Cached + + fmt 9.1.0 h924138e_0 conda-forge Cached + + icu 72.1 hcb278e6_0 conda-forge Cached + + idna 3.4 pyhd8ed1ab_0 conda-forge Cached + + keyutils 1.6.1 h166bdaf_0 conda-forge Cached + + krb5 1.20.1 h81ceb04_0 conda-forge Cached + + ld_impl_linux-64 2.40 h41732ed_0 conda-forge Cached + + libarchive 3.6.2 h3d51595_0 conda-forge Cached + + libcurl 7.88.1 hdc1c0ab_1 conda-forge Cached + + libedit 3.1.20191231 he28a2e2_2 conda-forge Cached + + libev 4.33 h516909a_1 conda-forge Cached + + libffi 3.4.2 h7f98852_5 conda-forge Cached + + libgcc-ng 12.2.0 h65d4601_19 conda-forge Cached + + libgomp 12.2.0 h65d4601_19 conda-forge Cached + + libiconv 1.17 h166bdaf_0 conda-forge Cached + + libmamba 1.4.1 hcea66bb_0 conda-forge Cached + + libmambapy 1.4.1 py310h1428755_0 conda-forge Cached + + libnghttp2 1.52.0 h61bc06f_0 conda-forge Cached + + libnsl 2.0.0 h7f98852_0 conda-forge Cached + + libsolv 0.7.23 h3eb15da_0 conda-forge Cached + + libsqlite 3.40.0 h753d276_0 conda-forge Cached + + libssh2 1.10.0 hf14f497_3 conda-forge Cached + + libstdcxx-ng 12.2.0 h46fd767_19 conda-forge Cached + + libuuid 2.38.1 h0b41bf4_0 conda-forge Cached + + libxml2 2.10.3 hfdac1af_6 conda-forge Cached + + libzlib 1.2.13 h166bdaf_4 conda-forge Cached + + lz4-c 1.9.4 hcb278e6_0 conda-forge Cached + + lzo 2.10 h516909a_1000 conda-forge Cached + + mamba 1.4.1 py310h51d5547_0 conda-forge Cached + + ncurses 6.3 h27087fc_1 conda-forge Cached + + openssl 3.1.0 h0b41bf4_0 conda-forge Cached + + pip 23.0.1 pyhd8ed1ab_0 conda-forge Cached + + pluggy 1.0.0 pyhd8ed1ab_5 conda-forge Cached + + pybind11-abi 4 hd8ed1ab_3 conda-forge Cached + + pycosat 0.6.4 py310h5764c6d_1 conda-forge Cached + + pycparser 2.21 pyhd8ed1ab_0 conda-forge Cached + + pyopenssl 23.1.1 pyhd8ed1ab_0 conda-forge Cached + + pysocks 1.7.1 pyha2e5f31_6 conda-forge Cached + + python 3.10.10 he550d4f_0_cpython conda-forge Cached + + python_abi 3.10 3_cp310 conda-forge Cached + + readline 8.2 h8228510_1 conda-forge Cached + + reproc 14.2.4 h0b41bf4_0 conda-forge Cached + + reproc-cpp 14.2.4 hcb278e6_0 conda-forge Cached + + requests 2.28.2 pyhd8ed1ab_1 conda-forge Cached + + ruamel.yaml 0.17.21 py310h1fa729e_3 conda-forge Cached + + ruamel.yaml.clib 0.2.7 py310h1fa729e_1 conda-forge Cached + + setuptools 65.6.3 pyhd8ed1ab_0 conda-forge Cached + + tk 8.6.12 h27826a3_0 conda-forge Cached + + toolz 0.12.0 pyhd8ed1ab_0 conda-forge Cached + + tqdm 4.65.0 pyhd8ed1ab_1 conda-forge Cached + + tzdata 2023c h71feb2d_0 conda-forge Cached + + urllib3 1.26.15 pyhd8ed1ab_0 conda-forge Cached + + wheel 0.40.0 pyhd8ed1ab_0 conda-forge Cached + + xz 5.2.6 h166bdaf_0 conda-forge Cached + + yaml-cpp 0.7.0 h27087fc_2 conda-forge Cached + + zstandard 0.19.0 py310hdeb6495_1 conda-forge Cached + + zstd 1.5.2 h3eb15da_6 conda-forge Cached + + Summary: + + Install: 70 packages + + Total download: 0 B + +─────────────────────────────────────────────────────────────────────────────────────── + + + + +Transaction starting + +Linking _libgcc_mutex-0.1-conda_forge + +Linking ca-certificates-2022.12.7-ha878542_0 + +Linking ld_impl_linux-64-2.40-h41732ed_0 + +Linking libstdcxx-ng-12.2.0-h46fd767_19 + +Linking pybind11-abi-4-hd8ed1ab_3 + +Linking python_abi-3.10-3_cp310 + +Linking tzdata-2023c-h71feb2d_0 + +Linking libgomp-12.2.0-h65d4601_19 + +Linking _openmp_mutex-4.5-2_gnu + +Linking libgcc-ng-12.2.0-h65d4601_19 + +Linking bzip2-1.0.8-h7f98852_4 + +Linking c-ares-1.18.1-h7f98852_0 + +Linking fmt-9.1.0-h924138e_0 + +Linking icu-72.1-hcb278e6_0 + +Linking keyutils-1.6.1-h166bdaf_0 + +Linking libev-4.33-h516909a_1 + +Linking libffi-3.4.2-h7f98852_5 + +Linking libiconv-1.17-h166bdaf_0 + +Linking libnsl-2.0.0-h7f98852_0 + +Linking libuuid-2.38.1-h0b41bf4_0 + +Linking libzlib-1.2.13-h166bdaf_4 + +Linking lz4-c-1.9.4-hcb278e6_0 + +Linking lzo-2.10-h516909a_1000 + +Linking ncurses-6.3-h27087fc_1 + +Linking openssl-3.1.0-h0b41bf4_0 + +Linking reproc-14.2.4-h0b41bf4_0 + +Linking xz-5.2.6-h166bdaf_0 + +Linking yaml-cpp-0.7.0-h27087fc_2 + +Linking libedit-3.1.20191231-he28a2e2_2 + +Linking libnghttp2-1.52.0-h61bc06f_0 + +Linking libsolv-0.7.23-h3eb15da_0 + +Linking libsqlite-3.40.0-h753d276_0 + +Linking libssh2-1.10.0-hf14f497_3 + +Linking libxml2-2.10.3-hfdac1af_6 + +Linking readline-8.2-h8228510_1 + +Linking reproc-cpp-14.2.4-hcb278e6_0 + +Linking tk-8.6.12-h27826a3_0 + +Linking zstd-1.5.2-h3eb15da_6 + +Linking krb5-1.20.1-h81ceb04_0 + +Linking libarchive-3.6.2-h3d51595_0 + +Linking python-3.10.10-he550d4f_0_cpython + +Linking certifi-2022.12.7-pyhd8ed1ab_0 + +Linking charset-normalizer-3.1.0-pyhd8ed1ab_0 + +Linking colorama-0.4.6-pyhd8ed1ab_0 + +Linking idna-3.4-pyhd8ed1ab_0 + +Linking libcurl-7.88.1-hdc1c0ab_1 + +Linking pluggy-1.0.0-pyhd8ed1ab_5 + +Linking pycosat-0.6.4-py310h5764c6d_1 + +Linking pycparser-2.21-pyhd8ed1ab_0 + +Linking pysocks-1.7.1-pyha2e5f31_6 + +Linking ruamel.yaml.clib-0.2.7-py310h1fa729e_1 + +Linking setuptools-65.6.3-pyhd8ed1ab_0 + +Linking toolz-0.12.0-pyhd8ed1ab_0 + +Linking wheel-0.40.0-pyhd8ed1ab_0 + +Linking cffi-1.15.1-py310h255011f_3 + +Linking libmamba-1.4.1-hcea66bb_0 + +Linking pip-23.0.1-pyhd8ed1ab_0 + +Linking ruamel.yaml-0.17.21-py310h1fa729e_3 + +Linking tqdm-4.65.0-pyhd8ed1ab_1 + +Linking brotlipy-0.7.0-py310h5764c6d_1005 + +Linking cryptography-40.0.1-py310h34c0648_0 + +Linking libmambapy-1.4.1-py310h1428755_0 + +Linking zstandard-0.19.0-py310hdeb6495_1 + +Linking conda-package-streaming-0.7.0-pyhd8ed1ab_1 + +Linking pyopenssl-23.1.1-pyhd8ed1ab_0 + +Linking conda-package-handling-2.0.2-pyh38be061_0 + +Linking urllib3-1.26.15-pyhd8ed1ab_0 + +Linking requests-2.28.2-pyhd8ed1ab_1 + +Linking conda-23.1.0-py310hff52083_0 + +Linking mamba-1.4.1-py310h51d5547_0 + +Transaction finished + +installation finished. + +WARNING: + You currently have a PYTHONPATH environment variable set. This may cause + + unexpected behavior when running the Python interpreter in Mambaforge. + For best results, please verify that your PYTHONPATH only points to + directories of packages that are compatible with the Python interpreter + in Mambaforge: /root/mambaforge + + ---> 7741d9d31977 + +Step 4/14 : copy environment.yaml /root/environment.yaml + + +COPY failed: file not found in build context or excluded by .dockerignore: stat environment.yaml: file does not exist diff --git a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-46aaed/docker-build-logs.txt b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-46aaed/docker-build-logs.txt new file mode 100644 index 00000000..1e3ee461 --- /dev/null +++ b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-46aaed/docker-build-logs.txt @@ -0,0 +1,757 @@ +Step 1/16 : from 812206152185.dkr.ecr.us-west-2.amazonaws.com/latch-base:1393-kenny--snakemake + + + ---> cf4e007bf7d3 + +Step 2/16 : run mkdir /opt/latch + + + ---> Using cache + + ---> afed690b224b + +Step 3/16 : RUN curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh && mkdir /root/.conda && bash Mambaforge-Linux-x86_64.sh -b && rm -f Mambaforge-Linux-x86_64.sh + + + ---> Using cache + + ---> 6505a24fc87d + +Step 4/16 : copy environment.yaml /root/environment.yaml + + + ---> Using cache + + ---> 2c2042a80716 + +Step 5/16 : run /root/mambaforge/bin/mamba env create --name snakemake-tutorial --file environment.yaml + + + ---> Using cache + + ---> 3c11703ad114 + +Step 6/16 : env PATH /root/mambaforge/envs/snakemake-tutorial/bin:$PATH + + + ---> Using cache + + ---> 48b5620a8619 + +Step 7/16 : copy latch /root/latch + + + ---> ffdf315ee81e + +Step 8/16 : run cd /root/latch && python3 -m pip install -e . + + + ---> Running in d53ee957c71f + +Obtaining file:///root/latch + + Installing build dependencies: started + + Installing build dependencies: finished with status 'done' + + Checking if build backend supports build_editable: started + + Checking if build backend supports build_editable: finished with status 'done' + + Getting requirements to build editable: started + + Getting requirements to build editable: finished with status 'done' + + Preparing editable metadata (pyproject.toml): started + + Preparing editable metadata (pyproject.toml): finished with status 'done' + +Collecting asyncssh==2.12.0 (from latch==2.19.11) + + Downloading asyncssh-2.12.0-py3-none-any.whl (346 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 346.7/346.7 kB 9.5 MB/s eta 0:00:00 + +Collecting aioconsole==0.5.1 (from latch==2.19.11) + + Downloading aioconsole-0.5.1-py3-none-any.whl (30 kB) + +Collecting kubernetes>=24.2.0 (from latch==2.19.11) + + Downloading kubernetes-26.1.0-py2.py3-none-any.whl (1.4 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.4/1.4 MB 50.5 MB/s eta 0:00:00 + + +Collecting pyjwt>=0.2.0 (from latch==2.19.11) + + Downloading PyJWT-2.7.0-py3-none-any.whl (22 kB) + +Requirement already satisfied: requests>=2.28.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from latch==2.19.11) (2.29.0) + +Collecting click>=8.0 (from latch==2.19.11) + + Downloading click-8.1.3-py3-none-any.whl (96 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 96.6/96.6 kB 14.1 MB/s eta 0:00:00 + + +Collecting docker>=5.0 (from latch==2.19.11) + + Downloading docker-6.1.2-py3-none-any.whl (148 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 148.1/148.1 kB 18.9 MB/s eta 0:00:00 + + +Collecting paramiko>=2.11.0 (from latch==2.19.11) + + Downloading paramiko-3.1.0-py3-none-any.whl (211 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 211.2/211.2 kB 26.1 MB/s eta 0:00:00 + + +Collecting scp>=0.14.0 (from latch==2.19.11) + + Downloading scp-0.14.5-py2.py3-none-any.whl (8.7 kB) + +Collecting boto3>=1.24.22 (from latch==2.19.11) + + Using cached boto3-1.26.137-py3-none-any.whl (135 kB) + +Collecting tqdm>=4.63.0 (from latch==2.19.11) + + Downloading tqdm-4.65.0-py3-none-any.whl (77 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 77.1/77.1 kB 11.5 MB/s eta 0:00:00 + + +Collecting lytekit==0.14.10 (from latch==2.19.11) + + Downloading lytekit-0.14.10-py3-none-any.whl (391 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 391.8/391.8 kB 41.2 MB/s eta 0:00:00 + + +Collecting lytekitplugins-pods==0.4.0 (from latch==2.19.11) + + Downloading lytekitplugins_pods-0.4.0-py3-none-any.whl (4.3 kB) + +Requirement already satisfied: typing-extensions==4.5.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from latch==2.19.11) (4.5.0) + +Collecting apscheduler==3.9.1 (from latch==2.19.11) + + Downloading APScheduler-3.9.1-py2.py3-none-any.whl (59 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 59.5/59.5 kB 8.7 MB/s eta 0:00:00 + + +Collecting uvloop==0.17.0 (from latch==2.19.11) + + Downloading uvloop-0.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.1 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.1/4.1 MB 81.6 MB/s eta 0:00:00 + + +Collecting websockets==10.3 (from latch==2.19.11) + + Downloading websockets-10.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (111 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 111.5/111.5 kB 15.6 MB/s eta 0:00:00 + + +Collecting prompt-toolkit==3.0.33 (from latch==2.19.11) + + Downloading prompt_toolkit-3.0.33-py3-none-any.whl (383 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 383.6/383.6 kB 39.2 MB/s eta 0:00:00 + + +Collecting watchfiles==0.18.1 (from latch==2.19.11) + + Downloading watchfiles-0.18.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.2 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.2/1.2 MB 67.6 MB/s eta 0:00:00 + + +Collecting gql==3.4.0 (from latch==2.19.11) + + Downloading gql-3.4.0-py2.py3-none-any.whl (65 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 65.2/65.2 kB 9.4 MB/s eta 0:00:00 + + +Collecting graphql-core==3.2.3 (from latch==2.19.11) + + Downloading graphql_core-3.2.3-py3-none-any.whl (202 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 202.9/202.9 kB 27.8 MB/s eta 0:00:00 + + +Collecting requests-toolbelt==0.10.1 (from latch==2.19.11) + + Downloading requests_toolbelt-0.10.1-py2.py3-none-any.whl (54 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 54.5/54.5 kB 8.8 MB/s eta 0:00:00 + + +Requirement already satisfied: snakemake>=7.25.4 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from latch==2.19.11) (7.25.4) + +Requirement already satisfied: setuptools>=0.7 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from apscheduler==3.9.1->latch==2.19.11) (67.7.2) + +Requirement already satisfied: six>=1.4.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from apscheduler==3.9.1->latch==2.19.11) (1.16.0) + +Collecting pytz (from apscheduler==3.9.1->latch==2.19.11) + + Downloading pytz-2023.3-py2.py3-none-any.whl (502 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 502.3/502.3 kB 48.1 MB/s eta 0:00:00 + + +Collecting tzlocal!=3.*,>=2.0 (from apscheduler==3.9.1->latch==2.19.11) + + Downloading tzlocal-5.0.1-py3-none-any.whl (20 kB) + +Requirement already satisfied: cryptography>=3.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from asyncssh==2.12.0->latch==2.19.11) (39.0.0) + +Collecting yarl<2.0,>=1.6 (from gql==3.4.0->latch==2.19.11) + + Downloading yarl-1.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (268 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 268.8/268.8 kB 31.5 MB/s eta 0:00:00 + + +Collecting backoff<3.0,>=1.11.1 (from gql==3.4.0->latch==2.19.11) + + Downloading backoff-2.2.1-py3-none-any.whl (15 kB) + +Collecting lyteidl==0.2.0a0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading lyteidl-0.2.0a0-py3-none-any.whl (162 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 162.2/162.2 kB 22.9 MB/s eta 0:00:00 + + +Requirement already satisfied: wheel<1.0.0,>=0.30.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (0.40.0) + +Collecting pandas<2.0.0,>=1.0.0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading pandas-1.5.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (12.1 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 12.1/12.1 MB 67.0 MB/s eta 0:00:00 + + +Collecting pyarrow<7.0.0,>=4.0.0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading pyarrow-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (25.6 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 25.6/25.6 MB 47.4 MB/s eta 0:00:00 + + +Collecting croniter<4.0.0,>=0.3.20 (from lytekit==0.14.10->latch==2.19.11) + + Downloading croniter-1.3.14-py2.py3-none-any.whl (18 kB) + +Collecting deprecated<2.0,>=1.0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading Deprecated-1.2.13-py2.py3-none-any.whl (9.6 kB) + +Collecting docker>=5.0 (from latch==2.19.11) + + Downloading docker-5.0.3-py2.py3-none-any.whl (146 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 146.2/146.2 kB 20.6 MB/s eta 0:00:00 + + +Requirement already satisfied: python-dateutil>=2.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (2.8.2) + +Collecting grpcio!=1.45.0,<2.0,>=1.43.0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading grpcio-1.54.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.1 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 5.1/5.1 MB 73.0 MB/s eta 0:00:00 + + +Collecting grpcio-status!=1.45.0,>=1.43 (from lytekit==0.14.10->latch==2.19.11) + + Downloading grpcio_status-1.54.2-py3-none-any.whl (5.1 kB) + +Collecting protobuf<4,>=3.6.1 (from lytekit==0.14.10->latch==2.19.11) + + Downloading protobuf-3.20.3-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (1.1 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.1/1.1 MB 63.5 MB/s eta 0:00:00 + + +Collecting python-json-logger>=2.0.0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading python_json_logger-2.0.7-py3-none-any.whl (8.1 kB) + +Collecting pytimeparse<2.0.0,>=1.1.8 (from lytekit==0.14.10->latch==2.19.11) + + Downloading pytimeparse-1.1.8-py2.py3-none-any.whl (10.0 kB) + +Requirement already satisfied: pyyaml in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (6.0) + +Collecting keyring>=18.0.1 (from lytekit==0.14.10->latch==2.19.11) + + Downloading keyring-23.13.1-py3-none-any.whl (37 kB) + +Collecting responses>=0.10.7 (from lytekit==0.14.10->latch==2.19.11) + + Downloading responses-0.23.1-py3-none-any.whl (52 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 52.1/52.1 kB 7.5 MB/s eta 0:00:00 + + +Collecting sortedcontainers<3.0.0,>=1.5.9 (from lytekit==0.14.10->latch==2.19.11) + + Downloading sortedcontainers-2.4.0-py2.py3-none-any.whl (29 kB) + +Collecting statsd<4.0.0,>=3.0.0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading statsd-3.3.0-py2.py3-none-any.whl (11 kB) + +Requirement already satisfied: urllib3<2.0.0,>=1.22 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (1.26.15) + +Requirement already satisfied: wrapt<2.0.0,>=1.0.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (1.15.0) + +Collecting retry==0.9.2 (from lytekit==0.14.10->latch==2.19.11) + + Downloading retry-0.9.2-py2.py3-none-any.whl (8.0 kB) + +Collecting dataclasses-json>=0.5.2 (from lytekit==0.14.10->latch==2.19.11) + + Downloading dataclasses_json-0.5.7-py3-none-any.whl (25 kB) + +Requirement already satisfied: jsonschema>=4.5.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (4.17.3) + +Collecting marshmallow-jsonschema>=0.12.0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading marshmallow_jsonschema-0.13.0-py3-none-any.whl (11 kB) + +Collecting natsort>=7.0.1 (from lytekit==0.14.10->latch==2.19.11) + + Downloading natsort-8.3.1-py3-none-any.whl (38 kB) + +Collecting docker-image-py>=0.1.10 (from lytekit==0.14.10->latch==2.19.11) + + Downloading docker-image-py-0.1.12.tar.gz (8.2 kB) + + Preparing metadata (setup.py): started + + Preparing metadata (setup.py): finished with status 'done' + +Collecting docstring-parser>=0.9.0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading docstring_parser-0.15-py3-none-any.whl (36 kB) + +Collecting diskcache>=5.2.1 (from lytekit==0.14.10->latch==2.19.11) + + Downloading diskcache-5.6.1-py3-none-any.whl (45 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 45.6/45.6 kB 6.7 MB/s eta 0:00:00 + + +Collecting cloudpickle>=2.0.0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading cloudpickle-2.2.1-py3-none-any.whl (25 kB) + +Collecting cookiecutter>=1.7.3 (from lytekit==0.14.10->latch==2.19.11) + + Downloading cookiecutter-2.1.1-py2.py3-none-any.whl (36 kB) + +Collecting numpy<1.22.0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading numpy-1.21.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (15.9 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 15.9/15.9 MB 63.6 MB/s eta 0:00:00 + + +Collecting wcwidth (from prompt-toolkit==3.0.33->latch==2.19.11) + + Downloading wcwidth-0.2.6-py2.py3-none-any.whl (29 kB) + +Collecting anyio>=3.0.0 (from watchfiles==0.18.1->latch==2.19.11) + + Downloading anyio-3.6.2-py3-none-any.whl (80 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 80.6/80.6 kB 11.5 MB/s eta 0:00:00 + + +Collecting googleapis-common-protos (from lyteidl==0.2.0a0->lytekit==0.14.10->latch==2.19.11) + + Downloading googleapis_common_protos-1.59.0-py2.py3-none-any.whl (223 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 223.6/223.6 kB 28.2 MB/s eta 0:00:00 + + +Collecting protoc-gen-swagger (from lyteidl==0.2.0a0->lytekit==0.14.10->latch==2.19.11) + + Downloading protoc_gen_swagger-0.1.0-py2.py3-none-any.whl (9.4 kB) + +Collecting decorator>=3.4.2 (from retry==0.9.2->lytekit==0.14.10->latch==2.19.11) + + Downloading decorator-5.1.1-py3-none-any.whl (9.1 kB) + +Collecting py<2.0.0,>=1.4.26 (from retry==0.9.2->lytekit==0.14.10->latch==2.19.11) + + Downloading py-1.11.0-py2.py3-none-any.whl (98 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 98.7/98.7 kB 13.5 MB/s eta 0:00:00 + + +Collecting botocore<1.30.0,>=1.29.137 (from boto3>=1.24.22->latch==2.19.11) + + Using cached botocore-1.29.137-py3-none-any.whl (10.8 MB) + +Collecting jmespath<2.0.0,>=0.7.1 (from boto3>=1.24.22->latch==2.19.11) + + Using cached jmespath-1.0.1-py3-none-any.whl (20 kB) + +Collecting s3transfer<0.7.0,>=0.6.0 (from boto3>=1.24.22->latch==2.19.11) + + Using cached s3transfer-0.6.1-py3-none-any.whl (79 kB) + +Collecting websocket-client>=0.32.0 (from docker>=5.0->latch==2.19.11) + + Downloading websocket_client-1.5.2-py3-none-any.whl (56 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 56.6/56.6 kB 8.5 MB/s eta 0:00:00 + + +Requirement already satisfied: certifi>=14.05.14 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from kubernetes>=24.2.0->latch==2.19.11) (2023.5.7) + +Collecting google-auth>=1.0.1 (from kubernetes>=24.2.0->latch==2.19.11) + + Downloading google_auth-2.18.1-py2.py3-none-any.whl (178 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 178.9/178.9 kB 24.4 MB/s eta 0:00:00 + + +Collecting requests-oauthlib (from kubernetes>=24.2.0->latch==2.19.11) + + Downloading requests_oauthlib-1.3.1-py2.py3-none-any.whl (23 kB) + +Collecting bcrypt>=3.2 (from paramiko>=2.11.0->latch==2.19.11) + + Downloading bcrypt-4.0.1-cp36-abi3-manylinux_2_28_x86_64.whl (593 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 593.7/593.7 kB 50.9 MB/s eta 0:00:00 + + +Collecting pynacl>=1.5 (from paramiko>=2.11.0->latch==2.19.11) + + Downloading PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl (856 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 856.7/856.7 kB 60.3 MB/s eta 0:00:00 + + +Requirement already satisfied: charset-normalizer<4,>=2 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from requests>=2.28.1->latch==2.19.11) (3.1.0) + +Requirement already satisfied: idna<4,>=2.5 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from requests>=2.28.1->latch==2.19.11) (3.4) + +Requirement already satisfied: appdirs in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.4.4) + +Requirement already satisfied: configargparse in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.5.3) + +Requirement already satisfied: connection-pool>=0.0.3 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (0.0.3) + +Requirement already satisfied: datrie in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (0.8.2) + +Requirement already satisfied: docutils in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (0.20.1) + +Requirement already satisfied: gitpython in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (3.1.31) + +Requirement already satisfied: humanfriendly in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (10.0) + +Requirement already satisfied: jinja2<4.0,>=3.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (3.1.2) + +Requirement already satisfied: nbformat in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (5.8.0) + +Requirement already satisfied: psutil in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (5.9.5) + +Requirement already satisfied: pulp>=2.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (2.7.0) + +Requirement already satisfied: reretry in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (0.11.8) + +Requirement already satisfied: smart-open>=3.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (6.3.0) + +Requirement already satisfied: stopit in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.1.2) + +Requirement already satisfied: tabulate in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (0.9.0) + +Requirement already satisfied: throttler in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.2.1) + +Requirement already satisfied: toposort>=1.10 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.10) + +Requirement already satisfied: yte<2.0,>=1.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.5.1) + +Collecting sniffio>=1.1 (from anyio>=3.0.0->watchfiles==0.18.1->latch==2.19.11) + + Downloading sniffio-1.3.0-py3-none-any.whl (10 kB) + +Collecting binaryornot>=0.4.4 (from cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) + + Downloading binaryornot-0.4.4-py2.py3-none-any.whl (9.0 kB) + +Collecting jinja2-time>=0.2.0 (from cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) + + Downloading jinja2_time-0.2.0-py2.py3-none-any.whl (6.4 kB) + +Collecting python-slugify>=4.0.0 (from cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) + + Downloading python_slugify-8.0.1-py2.py3-none-any.whl (9.7 kB) + +Requirement already satisfied: cffi>=1.12 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from cryptography>=3.1->asyncssh==2.12.0->latch==2.19.11) (1.15.1) + +Collecting marshmallow<4.0.0,>=3.3.0 (from dataclasses-json>=0.5.2->lytekit==0.14.10->latch==2.19.11) + + Downloading marshmallow-3.19.0-py3-none-any.whl (49 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 49.1/49.1 kB 7.4 MB/s eta 0:00:00 + + +Collecting marshmallow-enum<2.0.0,>=1.5.1 (from dataclasses-json>=0.5.2->lytekit==0.14.10->latch==2.19.11) + + Downloading marshmallow_enum-1.5.1-py2.py3-none-any.whl (4.2 kB) + +Collecting typing-inspect>=0.4.0 (from dataclasses-json>=0.5.2->lytekit==0.14.10->latch==2.19.11) + + Downloading typing_inspect-0.8.0-py3-none-any.whl (8.7 kB) + +Collecting regex>=2019.4.14 (from docker-image-py>=0.1.10->lytekit==0.14.10->latch==2.19.11) + + Downloading regex-2023.5.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (769 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 769.7/769.7 kB 56.4 MB/s eta 0:00:00 + + +Collecting cachetools<6.0,>=2.0.0 (from google-auth>=1.0.1->kubernetes>=24.2.0->latch==2.19.11) + + Downloading cachetools-5.3.0-py3-none-any.whl (9.3 kB) + +Collecting pyasn1-modules>=0.2.1 (from google-auth>=1.0.1->kubernetes>=24.2.0->latch==2.19.11) + + Downloading pyasn1_modules-0.3.0-py2.py3-none-any.whl (181 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 181.3/181.3 kB 24.9 MB/s eta 0:00:00 + + +Collecting rsa<5,>=3.1.4 (from google-auth>=1.0.1->kubernetes>=24.2.0->latch==2.19.11) + + Downloading rsa-4.9-py3-none-any.whl (34 kB) + +INFO: pip is looking at multiple versions of grpcio-status to determine which version is compatible with other requirements. This could take a while. + +Collecting grpcio-status!=1.45.0,>=1.43 (from lytekit==0.14.10->latch==2.19.11) + + Downloading grpcio_status-1.54.0-py3-none-any.whl (5.1 kB) + + Downloading grpcio_status-1.53.1-py3-none-any.whl (5.1 kB) + + Downloading grpcio_status-1.53.0-py3-none-any.whl (5.1 kB) + + Downloading grpcio_status-1.51.3-py3-none-any.whl (5.1 kB) + + Downloading grpcio_status-1.51.1-py3-none-any.whl (5.1 kB) + + Downloading grpcio_status-1.50.0-py3-none-any.whl (14 kB) + + Downloading grpcio_status-1.49.1-py3-none-any.whl (14 kB) + +INFO: pip is looking at multiple versions of grpcio-status to determine which version is compatible with other requirements. This could take a while. + + Downloading grpcio_status-1.48.2-py3-none-any.whl (14 kB) + +Requirement already satisfied: MarkupSafe>=2.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from jinja2<4.0,>=3.0->snakemake>=7.25.4->latch==2.19.11) (2.1.2) + +Requirement already satisfied: attrs>=17.4.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from jsonschema>=4.5.1->lytekit==0.14.10->latch==2.19.11) (23.1.0) + +Requirement already satisfied: pyrsistent!=0.17.0,!=0.17.1,!=0.17.2,>=0.14.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from jsonschema>=4.5.1->lytekit==0.14.10->latch==2.19.11) (0.19.3) + +Collecting jaraco.classes (from keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) + + Downloading jaraco.classes-3.2.3-py3-none-any.whl (6.0 kB) + +Requirement already satisfied: importlib-metadata>=4.11.4 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) (6.6.0) + +Collecting SecretStorage>=3.2 (from keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) + + Downloading SecretStorage-3.3.3-py3-none-any.whl (15 kB) + +Collecting jeepney>=0.4.2 (from keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) + + Downloading jeepney-0.8.0-py3-none-any.whl (48 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 48.4/48.4 kB 7.8 MB/s eta 0:00:00 + + +Collecting types-PyYAML (from responses>=0.10.7->lytekit==0.14.10->latch==2.19.11) + + Downloading types_PyYAML-6.0.12.9-py3-none-any.whl (14 kB) + +Collecting multidict>=4.0 (from yarl<2.0,>=1.6->gql==3.4.0->latch==2.19.11) + + Downloading multidict-6.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (114 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 114.5/114.5 kB 15.4 MB/s eta 0:00:00 + + +Requirement already satisfied: dpath<3.0,>=2.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from yte<2.0,>=1.0->snakemake>=7.25.4->latch==2.19.11) (2.1.6) + +Requirement already satisfied: plac<2.0.0,>=1.3.4 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from yte<2.0,>=1.0->snakemake>=7.25.4->latch==2.19.11) (1.3.5) + +Requirement already satisfied: gitdb<5,>=4.0.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from gitpython->snakemake>=7.25.4->latch==2.19.11) (4.0.10) + +Requirement already satisfied: fastjsonschema in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from nbformat->snakemake>=7.25.4->latch==2.19.11) (2.16.3) + +Requirement already satisfied: jupyter-core in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from nbformat->snakemake>=7.25.4->latch==2.19.11) (5.3.0) + +Requirement already satisfied: traitlets>=5.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from nbformat->snakemake>=7.25.4->latch==2.19.11) (5.9.0) + +Collecting oauthlib>=3.0.0 (from requests-oauthlib->kubernetes>=24.2.0->latch==2.19.11) + + Downloading oauthlib-3.2.2-py3-none-any.whl (151 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 151.7/151.7 kB 20.3 MB/s eta 0:00:00 + + +Collecting chardet>=3.0.2 (from binaryornot>=0.4.4->cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) + + Downloading chardet-5.1.0-py3-none-any.whl (199 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 199.1/199.1 kB 27.3 MB/s eta 0:00:00 + + +Requirement already satisfied: pycparser in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from cffi>=1.12->cryptography>=3.1->asyncssh==2.12.0->latch==2.19.11) (2.21) + +Requirement already satisfied: smmap<6,>=3.0.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from gitdb<5,>=4.0.1->gitpython->snakemake>=7.25.4->latch==2.19.11) (3.0.5) + +Requirement already satisfied: zipp>=0.5 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from importlib-metadata>=4.11.4->keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) (3.15.0) + +Collecting arrow (from jinja2-time>=0.2.0->cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) + + Downloading arrow-1.2.3-py3-none-any.whl (66 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 66.4/66.4 kB 9.6 MB/s eta 0:00:00 + + +Requirement already satisfied: packaging>=17.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from marshmallow<4.0.0,>=3.3.0->dataclasses-json>=0.5.2->lytekit==0.14.10->latch==2.19.11) (23.1) + +Collecting pyasn1<0.6.0,>=0.4.6 (from pyasn1-modules>=0.2.1->google-auth>=1.0.1->kubernetes>=24.2.0->latch==2.19.11) + + Using cached pyasn1-0.5.0-py2.py3-none-any.whl (83 kB) + +Collecting text-unidecode>=1.3 (from python-slugify>=4.0.0->cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) + + Downloading text_unidecode-1.3-py2.py3-none-any.whl (78 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 78.2/78.2 kB 11.0 MB/s eta 0:00:00 + + +Collecting mypy-extensions>=0.3.0 (from typing-inspect>=0.4.0->dataclasses-json>=0.5.2->lytekit==0.14.10->latch==2.19.11) + + Downloading mypy_extensions-1.0.0-py3-none-any.whl (4.7 kB) + +Collecting more-itertools (from jaraco.classes->keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) + + Downloading more_itertools-9.1.0-py3-none-any.whl (54 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 54.2/54.2 kB 8.2 MB/s eta 0:00:00 + + +Requirement already satisfied: platformdirs>=2.5 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from jupyter-core->nbformat->snakemake>=7.25.4->latch==2.19.11) (3.5.1) + +WARNING: The candidate selected for download or install is a yanked version: 'apscheduler' candidate (version 3.9.1 at https://files.pythonhosted.org/packages/e4/9f/c3937d4babe62504b874d4bf2c0d85aa69c7f59fa84cf6050f3b9dc5d83e/APScheduler-3.9.1-py2.py3-none-any.whl (from https://pypi.org/simple/apscheduler/) (requires-python:>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4)) +Reason for being yanked: Not compatible with Python 2.7 + +Building wheels for collected packages: latch, docker-image-py + + Building editable for latch (pyproject.toml): started + + Building editable for latch (pyproject.toml): finished with status 'done' + + Created wheel for latch: filename=latch-2.19.11-0.editable-py3-none-any.whl size=3728 sha256=6e5c6944ce29c7a23983c6b112f2a456fe4624db742ee953550c0a9a217fde91 + + Stored in directory: /tmp/pip-ephem-wheel-cache-5_26ion1/wheels/66/25/3a/f25ede02a4206d090762dd0ca4dbdc81da4d61e154ed692990 + + Building wheel for docker-image-py (setup.py): started + + Building wheel for docker-image-py (setup.py): finished with status 'done' + + Created wheel for docker-image-py: filename=docker_image_py-0.1.12-py3-none-any.whl size=8812 sha256=22b7f08420622d740b9ecca0b8dd40a71e752393484752d465fe0bbd8f16c29c + + Stored in directory: /root/.cache/pip/wheels/fb/45/02/503244da15fbcecde5c3edabb744ed0c4f9a7643126b2d222c + +Successfully built latch docker-image-py + +Installing collected packages: wcwidth, types-PyYAML, text-unidecode, statsd, sortedcontainers, pytz, pytimeparse, websockets, websocket-client, uvloop, tzlocal, tqdm, sniffio, regex, python-slugify, python-json-logger, pyjwt, pyasn1, py, protobuf, prompt-toolkit, oauthlib, numpy, natsort, mypy-extensions, multidict, more-itertools, marshmallow, jmespath, jeepney, grpcio, graphql-core, docstring-parser, diskcache, deprecated, decorator, cloudpickle, click, chardet, cachetools, bcrypt, backoff, aioconsole, yarl, typing-inspect, rsa, retry, responses, requests-toolbelt, requests-oauthlib, pynacl, pyasn1-modules, pyarrow, protoc-gen-swagger, pandas, marshmallow-jsonschema, marshmallow-enum, jaraco.classes, googleapis-common-protos, docker-image-py, docker, croniter, botocore, binaryornot, arrow, apscheduler, anyio, watchfiles, SecretStorage, s3transfer, paramiko, lyteidl, jinja2-time, grpcio-status, gql, google-auth, dataclasses-json, asyncssh, scp, kubernetes, keyring, cookiecutter, boto3, lytekit, lytekitplugins-pods, latch + + Attempting uninstall: numpy + + Found existing installation: numpy 1.24.3 + + Uninstalling numpy-1.24.3: + + Successfully uninstalled numpy-1.24.3 + +Successfully installed SecretStorage-3.3.3 aioconsole-0.5.1 anyio-3.6.2 apscheduler-3.9.1 arrow-1.2.3 asyncssh-2.12.0 backoff-2.2.1 bcrypt-4.0.1 binaryornot-0.4.4 boto3-1.26.137 botocore-1.29.137 cachetools-5.3.0 chardet-5.1.0 click-8.1.3 cloudpickle-2.2.1 cookiecutter-2.1.1 croniter-1.3.14 dataclasses-json-0.5.7 decorator-5.1.1 deprecated-1.2.13 diskcache-5.6.1 docker-5.0.3 docker-image-py-0.1.12 docstring-parser-0.15 google-auth-2.18.1 googleapis-common-protos-1.59.0 gql-3.4.0 graphql-core-3.2.3 grpcio-1.54.2 grpcio-status-1.48.2 jaraco.classes-3.2.3 jeepney-0.8.0 jinja2-time-0.2.0 jmespath-1.0.1 keyring-23.13.1 kubernetes-26.1.0 latch-2.19.11 lyteidl-0.2.0a0 lytekit-0.14.10 lytekitplugins-pods-0.4.0 marshmallow-3.19.0 marshmallow-enum-1.5.1 marshmallow-jsonschema-0.13.0 more-itertools-9.1.0 multidict-6.0.4 mypy-extensions-1.0.0 natsort-8.3.1 numpy-1.21.6 oauthlib-3.2.2 pandas-1.5.3 paramiko-3.1.0 prompt-toolkit-3.0.33 protobuf-3.20.3 protoc-gen-swagger-0.1.0 py-1.11.0 pyarrow-6.0.1 pyasn1-0.5.0 pyasn1-modules-0.3.0 pyjwt-2.7.0 pynacl-1.5.0 python-json-logger-2.0.7 python-slugify-8.0.1 pytimeparse-1.1.8 pytz-2023.3 regex-2023.5.5 requests-oauthlib-1.3.1 requests-toolbelt-0.10.1 responses-0.23.1 retry-0.9.2 rsa-4.9 s3transfer-0.6.1 scp-0.14.5 sniffio-1.3.0 sortedcontainers-2.4.0 statsd-3.3.0 text-unidecode-1.3 tqdm-4.65.0 types-PyYAML-6.0.12.9 typing-inspect-0.8.0 tzlocal-5.0.1 uvloop-0.17.0 watchfiles-0.18.1 wcwidth-0.2.6 websocket-client-1.5.2 websockets-10.3 yarl-1.9.2 + +WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv + + ---> 307c5bcbc386 + +Step 9/16 : copy Snakefile config.yaml /root/ + + + ---> b0ba7cf91375 + +Step 10/16 : copy scripts/plot-quals.py /root/scripts/plot-quals.py + + + ---> 86119263c970 + +Step 11/16 : copy .latch/latch_entrypoint.py /root/latch_entrypoint.py + + + ---> f989dc012176 + +Step 12/16 : arg tag + + + ---> Running in 82457c66aeec + + ---> aaac32c25a4e + +Step 13/16 : env FLYTE_INTERNAL_IMAGE $tag + + + ---> Running in 3489041d8300 + + ---> be966f41400f + +Step 14/16 : env LATCH_SDK_DOMAIN "ligma.ai" + + + ---> Running in 3e7720cf8a94 + + ---> 58f221b01142 + +Step 15/16 : env LATCH_AUTHENTICATION_ENDPOINT https://nucleus.ligma.ai + + + ---> Running in 9ed5e43f9d93 + + ---> 12187158e97a + +Step 16/16 : workdir /root + + + ---> Running in df8101cc4364 + + ---> aa63893ed987 + +Successfully built aa63893ed987 + +Successfully tagged 812206152185.dkr.ecr.us-west-2.amazonaws.com/x1_test_latch_register:0.0.0-46aaed + diff --git a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-56df45/docker-build-logs.txt b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-56df45/docker-build-logs.txt new file mode 100644 index 00000000..eb027596 --- /dev/null +++ b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-56df45/docker-build-logs.txt @@ -0,0 +1,100 @@ +Step 1/14 : from 812206152185.dkr.ecr.us-west-2.amazonaws.com/latch-base:b733-kenny--snakemake + + + ---> 77471241d7a3 + +Step 2/14 : run mkdir /opt/latch + + + ---> Using cache + + ---> 6d1d7399ec34 + +Step 3/14 : RUN curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh && mkdir /root/.conda && bash Mambaforge-Linux-x86_64.sh -b && rm -f Mambaforge-Linux-x86_64.sh + + + ---> Using cache + + ---> e5d7f1c377ad + +Step 4/14 : copy environment.yaml /root/environment.yaml + + + ---> Using cache + + ---> f1895bb6bb01 + +Step 5/14 : run /root/mambaforge/bin/mamba env create --name snakemake-tutorial --file environment.yaml + + + ---> Using cache + + ---> 1c115b179fb8 + +Step 6/14 : env PATH /root/mambaforge/envs/snakemake-tutorial/bin:$PATH + + + ---> Using cache + + ---> 38bcbc3eaccf + +Step 7/14 : copy latch /root/latch + + + ---> Using cache + + ---> ba86df280c15 + +Step 8/14 : run cd /root/latch && python3 -m pip install -e . + + + ---> Using cache + + ---> e6903b7577c6 + +Step 9/14 : copy Snakefile config.yaml /root/ + + + ---> Using cache + + ---> 93c3fe88c890 + +Step 10/14 : copy scripts/plot-quals.py /root/scripts/plot-quals.py + + + ---> Using cache + + ---> b476a36f6f9c + +Step 11/14 : copy .latch/latch_entrypoint.py /root/latch_entrypoint.py + + + ---> Using cache + + ---> 75cead0538d5 + +Step 12/14 : arg tag + + + ---> Using cache + + ---> 9d8c1d4b5439 + +Step 13/14 : env FLYTE_INTERNAL_IMAGE $tag + + + ---> Running in e5785af71f54 + + ---> 7c55f16d4b30 + +Step 14/14 : workdir /root + + + ---> Running in c8f46c0343b8 + + ---> e2cedb2c4443 + +Successfully built e2cedb2c4443 + +Successfully tagged 812206152185.dkr.ecr.us-west-2.amazonaws.com/x1_test_latch_register:0.0.0-56df45 + diff --git a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-62524a/docker-build-logs.txt b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-62524a/docker-build-logs.txt new file mode 100644 index 00000000..e0305ce3 --- /dev/null +++ b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-62524a/docker-build-logs.txt @@ -0,0 +1,65 @@ +Step 1/15 : from 812206152185.dkr.ecr.us-west-2.amazonaws.com/latch-base:9c8f-main + + + ---> b253e8cdab51 + +Step 2/15 : run mkdir /opt/latch + + + ---> Using cache + + ---> 89e0ab657f0d + +Step 3/15 : RUN curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh && mkdir /root/.conda && bash Mambaforge-Linux-x86_64.sh -b && rm -f Mambaforge-Linux-x86_64.sh + + + ---> Using cache + + ---> 7741d9d31977 + +Step 4/15 : copy environment.yaml /root/environment.yaml + + + ---> Using cache + + ---> c2d3f498d2d5 + +Step 5/15 : run /root/mambaforge/bin/mamba env create --name snakemake-tutorial --file environment.yaml + + + ---> Using cache + + ---> 0370179f98b9 + +Step 6/15 : env PATH /root/mambaforge/envs/snakemake-tutorial/bin:$PATH + + + ---> Using cache + + ---> 558ea5988368 + +Step 7/15 : run python3 -m pip install latch + + + ---> Using cache + + ---> 73f3b443e340 + +Step 8/15 : copy Snakefile config.yaml /root/ + + + ---> Using cache + + ---> da1c8fa40657 + +Step 9/15 : copy scripts/plot-quals.py /root/scripts/plot-quals.py + + + ---> Using cache + + ---> 6e0a5622727c + +Step 10/15 : copy .latch/latch_entrypoint.py /root/latch_entrypoint.py + + +COPY failed: file not found in build context or excluded by .dockerignore: stat .latch/latch_entrypoint.py: file does not exist diff --git a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-6975e7/docker-build-logs.txt b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-6975e7/docker-build-logs.txt new file mode 100644 index 00000000..e2a4165f --- /dev/null +++ b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-6975e7/docker-build-logs.txt @@ -0,0 +1,100 @@ +Step 1/14 : from 812206152185.dkr.ecr.us-west-2.amazonaws.com/latch-base:b733-kenny--snakemake + + + ---> 77471241d7a3 + +Step 2/14 : run mkdir /opt/latch + + + ---> Using cache + + ---> 6d1d7399ec34 + +Step 3/14 : RUN curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh && mkdir /root/.conda && bash Mambaforge-Linux-x86_64.sh -b && rm -f Mambaforge-Linux-x86_64.sh + + + ---> Using cache + + ---> e5d7f1c377ad + +Step 4/14 : copy environment.yaml /root/environment.yaml + + + ---> Using cache + + ---> f1895bb6bb01 + +Step 5/14 : run /root/mambaforge/bin/mamba env create --name snakemake-tutorial --file environment.yaml + + + ---> Using cache + + ---> 1c115b179fb8 + +Step 6/14 : env PATH /root/mambaforge/envs/snakemake-tutorial/bin:$PATH + + + ---> Using cache + + ---> 38bcbc3eaccf + +Step 7/14 : copy latch /root/latch + + + ---> Using cache + + ---> 0a6841ad1519 + +Step 8/14 : run cd /root/latch && python3 -m pip install -e . + + + ---> Using cache + + ---> 987ca2488773 + +Step 9/14 : copy Snakefile config.yaml /root/ + + + ---> Using cache + + ---> ff2efbf9c325 + +Step 10/14 : copy scripts/plot-quals.py /root/scripts/plot-quals.py + + + ---> Using cache + + ---> efa63cf5aa2d + +Step 11/14 : copy .latch/latch_entrypoint.py /root/latch_entrypoint.py + + + ---> Using cache + + ---> 5222bb3def10 + +Step 12/14 : arg tag + + + ---> Using cache + + ---> 2b44d6814bf9 + +Step 13/14 : env FLYTE_INTERNAL_IMAGE $tag + + + ---> Running in badb0a9f44c5 + + ---> 87493969f9ba + +Step 14/14 : workdir /root + + + ---> Running in dc0733710fb0 + + ---> 1aeb3dc3c55a + +Successfully built 1aeb3dc3c55a + +Successfully tagged 812206152185.dkr.ecr.us-west-2.amazonaws.com/x1_test_latch_register:0.0.0-6975e7 + diff --git a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-87b6a8/docker-build-logs.txt b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-87b6a8/docker-build-logs.txt new file mode 100644 index 00000000..9ff7e2c9 --- /dev/null +++ b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-87b6a8/docker-build-logs.txt @@ -0,0 +1,100 @@ +Step 1/14 : from 812206152185.dkr.ecr.us-west-2.amazonaws.com/latch-base:b733-kenny--snakemake + + + ---> 77471241d7a3 + +Step 2/14 : run mkdir /opt/latch + + + ---> Using cache + + ---> 6d1d7399ec34 + +Step 3/14 : RUN curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh && mkdir /root/.conda && bash Mambaforge-Linux-x86_64.sh -b && rm -f Mambaforge-Linux-x86_64.sh + + + ---> Using cache + + ---> e5d7f1c377ad + +Step 4/14 : copy environment.yaml /root/environment.yaml + + + ---> Using cache + + ---> f1895bb6bb01 + +Step 5/14 : run /root/mambaforge/bin/mamba env create --name snakemake-tutorial --file environment.yaml + + + ---> Using cache + + ---> 1c115b179fb8 + +Step 6/14 : env PATH /root/mambaforge/envs/snakemake-tutorial/bin:$PATH + + + ---> Using cache + + ---> 38bcbc3eaccf + +Step 7/14 : copy latch /root/latch + + + ---> Using cache + + ---> 0a6841ad1519 + +Step 8/14 : run cd /root/latch && python3 -m pip install -e . + + + ---> Using cache + + ---> 987ca2488773 + +Step 9/14 : copy Snakefile config.yaml /root/ + + + ---> Using cache + + ---> ff2efbf9c325 + +Step 10/14 : copy scripts/plot-quals.py /root/scripts/plot-quals.py + + + ---> Using cache + + ---> efa63cf5aa2d + +Step 11/14 : copy .latch/latch_entrypoint.py /root/latch_entrypoint.py + + + ---> Using cache + + ---> 5222bb3def10 + +Step 12/14 : arg tag + + + ---> Using cache + + ---> 2b44d6814bf9 + +Step 13/14 : env FLYTE_INTERNAL_IMAGE $tag + + + ---> Running in 9d9fe52efd67 + + ---> 865ce9ad87f8 + +Step 14/14 : workdir /root + + + ---> Running in abd69922bebc + + ---> 40606bdcc357 + +Successfully built 40606bdcc357 + +Successfully tagged 812206152185.dkr.ecr.us-west-2.amazonaws.com/x1_test_latch_register:0.0.0-87b6a8 + diff --git a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-89875a/docker-build-logs.txt b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-89875a/docker-build-logs.txt new file mode 100644 index 00000000..bf752653 --- /dev/null +++ b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-89875a/docker-build-logs.txt @@ -0,0 +1,98 @@ +Step 1/14 : from 812206152185.dkr.ecr.us-west-2.amazonaws.com/latch-base:b733-kenny--snakemake + + + ---> 77471241d7a3 + +Step 2/14 : run mkdir /opt/latch + + + ---> Using cache + + ---> 6d1d7399ec34 + +Step 3/14 : RUN curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh && mkdir /root/.conda && bash Mambaforge-Linux-x86_64.sh -b && rm -f Mambaforge-Linux-x86_64.sh + + + ---> Using cache + + ---> e5d7f1c377ad + +Step 4/14 : copy environment.yaml /root/environment.yaml + + + ---> Using cache + + ---> f1895bb6bb01 + +Step 5/14 : run /root/mambaforge/bin/mamba env create --name snakemake-tutorial --file environment.yaml + + + ---> Using cache + + ---> 1c115b179fb8 + +Step 6/14 : env PATH /root/mambaforge/envs/snakemake-tutorial/bin:$PATH + + + ---> Using cache + + ---> 38bcbc3eaccf + +Step 7/14 : copy latch /root/latch + + + ---> Using cache + + ---> 0a6841ad1519 + +Step 8/14 : run cd /root/latch && python3 -m pip install -e . + + + ---> Using cache + + ---> 987ca2488773 + +Step 9/14 : copy Snakefile config.yaml /root/ + + + ---> Using cache + + ---> ff2efbf9c325 + +Step 10/14 : copy scripts/plot-quals.py /root/scripts/plot-quals.py + + + ---> Using cache + + ---> efa63cf5aa2d + +Step 11/14 : copy .latch/latch_entrypoint.py /root/latch_entrypoint.py + + + ---> 7ff56b528bef + +Step 12/14 : arg tag + + + ---> Running in a7aa5ba593e9 + + ---> 72806a2f7535 + +Step 13/14 : env FLYTE_INTERNAL_IMAGE $tag + + + ---> Running in 9c8313cc6ddd + + ---> 42412bb67f94 + +Step 14/14 : workdir /root + + + ---> Running in 0f6f141d57a8 + + ---> 346d6b9d4401 + +Successfully built 346d6b9d4401 + +Successfully tagged 812206152185.dkr.ecr.us-west-2.amazonaws.com/x1_test_latch_register:0.0.0-89875a + diff --git a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-a00131/docker-build-logs.txt b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-a00131/docker-build-logs.txt new file mode 100644 index 00000000..6c90709b --- /dev/null +++ b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-a00131/docker-build-logs.txt @@ -0,0 +1,2627 @@ +Step 1/15 : from 812206152185.dkr.ecr.us-west-2.amazonaws.com/latch-base:1393-kenny--snakemake + + + ---> cf4e007bf7d3 + +Step 2/15 : run mkdir /opt/latch + + + ---> Running in f3d6dc4c1146 + + ---> afed690b224b + +Step 3/15 : RUN curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh && mkdir /root/.conda && bash Mambaforge-Linux-x86_64.sh -b && rm -f Mambaforge-Linux-x86_64.sh + + + ---> Running in 742a170bb1bf + + % Total % Received % Xferd Average Speed  +Time Time Time Current + Dload Upload Total Spent Left Speed + 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 + 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 + 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 + + 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 + + 25 82.9M 25 20.8M 0 0 20.1M 0 0:00:04 0:00:01 0:00:03 20.1M + 100 82.9M 100 82.9M 0 0 43.0M 0 0:00:01 0:00:01 --:--:-- 69.7M + +PREFIX=/root/mambaforge + +Unpacking payload ... + +Extracting _libgcc_mutex-0.1-conda_forge.tar.bz2 + +Extracting ca-certificates-2022.12.7-ha878542_0.conda + +Extracting ld_impl_linux-64-2.40-h41732ed_0.conda + +Extracting libstdcxx-ng-12.2.0-h46fd767_19.tar.bz2 + +Extracting pybind11-abi-4-hd8ed1ab_3.tar.bz2 + +Extracting python_abi-3.10-3_cp310.conda + +Extracting tzdata-2023c-h71feb2d_0.conda + +Extracting libgomp-12.2.0-h65d4601_19.tar.bz2 + +Extracting _openmp_mutex-4.5-2_gnu.tar.bz2 + +Extracting libgcc-ng-12.2.0-h65d4601_19.tar.bz2 + +Extracting bzip2-1.0.8-h7f98852_4.tar.bz2 + +Extracting c-ares-1.18.1-h7f98852_0.tar.bz2 + +Extracting fmt-9.1.0-h924138e_0.tar.bz2 + +Extracting icu-72.1-hcb278e6_0.conda + +Extracting keyutils-1.6.1-h166bdaf_0.tar.bz2 + +Extracting libev-4.33-h516909a_1.tar.bz2 + +Extracting libffi-3.4.2-h7f98852_5.tar.bz2 + +Extracting libiconv-1.17-h166bdaf_0.tar.bz2 + +Extracting libnsl-2.0.0-h7f98852_0.tar.bz2 + +Extracting libuuid-2.38.1-h0b41bf4_0.conda + +Extracting libzlib-1.2.13-h166bdaf_4.tar.bz2 + +Extracting lz4-c-1.9.4-hcb278e6_0.conda + +Extracting lzo-2.10-h516909a_1000.tar.bz2 + +Extracting ncurses-6.3-h27087fc_1.tar.bz2 + +Extracting openssl-3.1.0-h0b41bf4_0.conda + +Extracting reproc-14.2.4-h0b41bf4_0.conda + +Extracting xz-5.2.6-h166bdaf_0.tar.bz2 + +Extracting yaml-cpp-0.7.0-h27087fc_2.tar.bz2 + +Extracting libedit-3.1.20191231-he28a2e2_2.tar.bz2 + +Extracting libnghttp2-1.52.0-h61bc06f_0.conda + +Extracting libsolv-0.7.23-h3eb15da_0.conda + +Extracting libsqlite-3.40.0-h753d276_0.tar.bz2 + +Extracting libssh2-1.10.0-hf14f497_3.tar.bz2 + +Extracting libxml2-2.10.3-hfdac1af_6.conda + +Extracting readline-8.2-h8228510_1.conda + +Extracting reproc-cpp-14.2.4-hcb278e6_0.conda + +Extracting tk-8.6.12-h27826a3_0.tar.bz2 + +Extracting zstd-1.5.2-h3eb15da_6.conda + +Extracting krb5-1.20.1-h81ceb04_0.conda + +Extracting libarchive-3.6.2-h3d51595_0.conda + +Extracting python-3.10.10-he550d4f_0_cpython.conda + +Extracting certifi-2022.12.7-pyhd8ed1ab_0.conda + +Extracting charset-normalizer-3.1.0-pyhd8ed1ab_0.conda + +Extracting colorama-0.4.6-pyhd8ed1ab_0.tar.bz2 + +Extracting idna-3.4-pyhd8ed1ab_0.tar.bz2 + +Extracting libcurl-7.88.1-hdc1c0ab_1.conda + +Extracting pluggy-1.0.0-pyhd8ed1ab_5.tar.bz2 + +Extracting pycosat-0.6.4-py310h5764c6d_1.tar.bz2 + +Extracting pycparser-2.21-pyhd8ed1ab_0.tar.bz2 + +Extracting pysocks-1.7.1-pyha2e5f31_6.tar.bz2 + +Extracting ruamel.yaml.clib-0.2.7-py310h1fa729e_1.conda + +Extracting setuptools-65.6.3-pyhd8ed1ab_0.conda + +Extracting toolz-0.12.0-pyhd8ed1ab_0.tar.bz2 + +Extracting wheel-0.40.0-pyhd8ed1ab_0.conda + +Extracting cffi-1.15.1-py310h255011f_3.conda + +Extracting libmamba-1.4.1-hcea66bb_0.conda + +Extracting pip-23.0.1-pyhd8ed1ab_0.conda + +Extracting ruamel.yaml-0.17.21-py310h1fa729e_3.conda + +Extracting tqdm-4.65.0-pyhd8ed1ab_1.conda + +Extracting brotlipy-0.7.0-py310h5764c6d_1005.tar.bz2 + +Extracting cryptography-40.0.1-py310h34c0648_0.conda + +Extracting libmambapy-1.4.1-py310h1428755_0.conda + +Extracting zstandard-0.19.0-py310hdeb6495_1.conda + +Extracting conda-package-streaming-0.7.0-pyhd8ed1ab_1.conda + +Extracting pyopenssl-23.1.1-pyhd8ed1ab_0.conda + +Extracting conda-package-handling-2.0.2-pyh38be061_0.conda + +Extracting urllib3-1.26.15-pyhd8ed1ab_0.conda + +Extracting requests-2.28.2-pyhd8ed1ab_1.conda + +Extracting conda-23.1.0-py310hff52083_0.conda + +Extracting mamba-1.4.1-py310h51d5547_0.conda + + +Installing base environment... + + + + __ + __ ______ ___ ____ _____ ___ / /_ ____ _ + / / / / __ `__ \/ __ `/ __ `__ \/ __ \/ __ `/ + / /_/ / / / / / / /_/ / / / / / / /_/ / /_/ / + / .___/_/ /_/ /_/\__,_/_/ /_/ /_/_.___/\__,_/ + /_/ + + +Transaction + + Prefix: /root/mambaforge + + Updating specs: + + - conda-forge/linux-64::_libgcc_mutex==0.1=conda_forge[md5=d7c89558ba9fa0495403155b64376d81] + - conda-forge/linux-64::ca-certificates==2022.12.7=ha878542_0[md5=ff9f73d45c4a07d6f424495288a26080] + - conda-forge/linux-64::ld_impl_linux-64==2.40=h41732ed_0[md5=7aca3059a1729aa76c597603f10b0dd3] + - conda-forge/linux-64::libstdcxx-ng==12.2.0=h46fd767_19[md5=1030b1f38c129f2634eae026f704fe60] + - conda-forge/noarch::pybind11-abi==4=hd8ed1ab_3[md5=878f923dd6acc8aeb47a75da6c4098be] + - conda-forge/linux-64::python_abi==3.10=3_cp310[md5=4eb33d14d794b0f4be116443ffed3853] + - conda-forge/noarch::tzdata==2023c=h71feb2d_0[md5=939e3e74d8be4dac89ce83b20de2492a] + - conda-forge/linux-64::libgomp==12.2.0=h65d4601_19[md5=cedcee7c064c01c403f962c9e8d3c373] + - conda-forge/linux-64::_openmp_mutex==4.5=2_gnu[md5=73aaf86a425cc6e73fcf236a5a46396d] + - conda-forge/linux-64::libgcc-ng==12.2.0=h65d4601_19[md5=e4c94f80aef025c17ab0828cd85ef535] + - conda-forge/linux-64::bzip2==1.0.8=h7f98852_4[md5=a1fd65c7ccbf10880423d82bca54eb54] + - conda-forge/linux-64::c-ares==1.18.1=h7f98852_0[md5=f26ef8098fab1f719c91eb760d63381a] + - conda-forge/linux-64::fmt==9.1.0=h924138e_0[md5=b57864c85261a0fbc7132d2cc17478c7] + - conda-forge/linux-64::icu==72.1=hcb278e6_0[md5=7c8d20d847bb45f56bd941578fcfa146] + - conda-forge/linux-64::keyutils==1.6.1=h166bdaf_0[md5=30186d27e2c9fa62b45fb1476b7200e3] + - conda-forge/linux-64::libev==4.33=h516909a_1[md5=6f8720dff19e17ce5d48cfe7f3d2f0a3] + - conda-forge/linux-64::libffi==3.4.2=h7f98852_5[md5=d645c6d2ac96843a2bfaccd2d62b3ac3] + - conda-forge/linux-64::libiconv==1.17=h166bdaf_0[md5=b62b52da46c39ee2bc3c162ac7f1804d] + - conda-forge/linux-64::libnsl==2.0.0=h7f98852_0[md5=39b1328babf85c7c3a61636d9cd50206] + + - conda-forge/linux-64::libuuid==2.38.1=h0b41bf4_0[md5=40b61aab5c7ba9ff276c41cfffe6b80b] + - conda-forge/linux-64::libzlib==1.2.13=h166bdaf_4[md5=f3f9de449d32ca9b9c66a22863c96f41] + - conda-forge/linux-64::lz4-c==1.9.4=hcb278e6_0[md5=318b08df404f9c9be5712aaa5a6f0bb0] + - conda-forge/linux-64::lzo==2.10=h516909a_1000[md5=bb14fcb13341b81d5eb386423b9d2bac] + - conda-forge/linux-64::ncurses==6.3=h27087fc_1[md5=4acfc691e64342b9dae57cf2adc63238] + - conda-forge/linux-64::openssl==3.1.0=h0b41bf4_0[md5=2d833be81a21128e317325a01326d36f] + - conda-forge/linux-64::reproc==14.2.4=h0b41bf4_0[md5=0f51393e019df1f0047ef864cd9ddeec] + - conda-forge/linux-64::xz==5.2.6=h166bdaf_0[md5=2161070d867d1b1204ea749c8eec4ef0] + - conda-forge/linux-64::yaml-cpp==0.7.0=h27087fc_2[md5=0449d47d8457feaa3720d4779616dde2] + - conda-forge/linux-64::libedit==3.1.20191231=he28a2e2_2[md5=4d331e44109e3f0e19b4cb8f9b82f3e1] + - conda-forge/linux-64::libnghttp2==1.52.0=h61bc06f_0[md5=613955a50485812985c059e7b269f42e] + - conda-forge/linux-64::libsolv==0.7.23=h3eb15da_0[md5=122332e6deb4aea9eaf22021d2ecd256] + - conda-forge/linux-64::libsqlite==3.40.0=h753d276_0[md5=2e5f9a37d487e1019fd4d8113adb2f9f] + - conda-forge/linux-64::libssh2==1.10.0=hf14f497_3[md5=d85acad4b47dff4e3def14a769a97906] + - conda-forge/linux-64::libxml2==2.10.3=hfdac1af_6[md5=7eecaadc2eaeef464c5fe17702f17c86] + - conda-forge/linux-64::readline==8.2=h8228510_1[md5=47d31b792659ce70f470b5c82fdfb7a4] + - conda-forge/linux-64::reproc-cpp==14.2.4=hcb278e6_0[md5=ede8e0f849f2fee2f78cb488b4ea3b33] + - conda-forge/linux-64::tk==8.6.12=h27826a3_0[md5=5b8c42eb62e9fc961af70bdd6a26e168] + - conda-forge/linux-64::zstd==1.5.2=h3eb15da_6[md5=6b63daed8feeca47be78f323e793d555] + - conda-forge/linux-64::krb5==1.20.1=h81ceb04_0[md5=89a41adce7106749573d883b2f657d78] + - conda-forge/linux-64::libarchive==3.6.2=h3d51595_0[md5=9f915b4adeb9dcfd450b9ad238e2db4c] + - conda-forge/linux-64::python==3.10.10=he550d4f_0_cpython[md5=de25afc7041c103c7f510c746bb63435] + - conda-forge/noarch::certifi==2022.12.7=pyhd8ed1ab_0[md5=fb9addc3db06e56abe03e0e9f21a63e6] + + - conda-forge/noarch::charset-normalizer==3.1.0=pyhd8ed1ab_0[md5=7fcff9f6f123696e940bda77bd4d6551] + - conda-forge/noarch::colorama==0.4.6=pyhd8ed1ab_0[md5=3faab06a954c2a04039983f2c4a50d99] + + - conda-forge/noarch::idna==3.4=pyhd8ed1ab_0[md5=34272b248891bddccc64479f9a7fffed] + - conda-forge/linux-64::libcurl==7.88.1=hdc1c0ab_1[md5=3d1189864d1c0ed2a5919cb067b5903d] + - conda-forge/noarch::pluggy==1.0.0=pyhd8ed1ab_5[md5=7d301a0d25f424d96175f810935f0da9] + - conda-forge/linux-64::pycosat==0.6.4=py310h5764c6d_1[md5=0e565d732f6660374b45d76761c09b06] + - conda-forge/noarch::pycparser==2.21=pyhd8ed1ab_0[md5=076becd9e05608f8dc72757d5f3a91ff] + - conda-forge/noarch::pysocks==1.7.1=pyha2e5f31_6[md5=2a7de29fb590ca14b5243c4c812c8025] + - conda-forge/linux-64::ruamel.yaml.clib==0.2.7=py310h1fa729e_1[md5=2f9b517412af46255cef5e53a22c264e] + - conda-forge/noarch::setuptools==65.6.3=pyhd8ed1ab_0[md5=9600fc9524d3f821e6a6d58c52f5bf5a] + - conda-forge/noarch::toolz==0.12.0=pyhd8ed1ab_0[md5=92facfec94bc02d6ccf42e7173831a36] + - conda-forge/noarch::wheel==0.40.0=pyhd8ed1ab_0[md5=49bb0d9e60ce1db25e151780331bb5f3] + - conda-forge/linux-64::cffi==1.15.1=py310h255011f_3[md5=800596144bb613cd7ac58b80900ce835] + - conda-forge/linux-64::libmamba==1.4.1=hcea66bb_0[md5=e512a4c95ff1eca1684642fa32bd2f55] + + - conda-forge/noarch::pip==23.0.1=pyhd8ed1ab_0[md5=8025ca83b8ba5430b640b83917c2a6f7] + - conda-forge/linux-64::ruamel.yaml==0.17.21=py310h1fa729e_3[md5=97204ae92b703d74a983db0e6d07d009] + - conda-forge/noarch::tqdm==4.65.0=pyhd8ed1ab_1[md5=ed792aff3acb977d09c7013358097f83] + - conda-forge/linux-64::brotlipy==0.7.0=py310h5764c6d_1005[md5=87669c3468dff637bbd0363bc0f895cf] + - conda-forge/linux-64::cryptography==40.0.1=py310h34c0648_0[md5=deafd9206c2e307874f3777a33cafb79] + - conda-forge/linux-64::libmambapy==1.4.1=py310h1428755_0[md5=323e09e9947b6a415f9d73562e4ca862] + - conda-forge/linux-64::zstandard==0.19.0=py310hdeb6495_1[md5=2cce1a48e6687f64d371d2e7fc9c7fbf] + - conda-forge/noarch::conda-package-streaming==0.7.0=pyhd8ed1ab_1[md5=1a2fa9e53cfbc2e4d9ab21990805a436] + - conda-forge/noarch::pyopenssl==23.1.1=pyhd8ed1ab_0[md5=0b34aa3ab7e7ccb1765a03dd9ed29938] + - conda-forge/noarch::conda-package-handling==2.0.2=pyh38be061_0[md5=44800e9bd13143292097c65e57323038] + - conda-forge/noarch::urllib3==1.26.15=pyhd8ed1ab_0[md5=27db656619a55d727eaf5a6ece3d2fd6] + - conda-forge/noarch::requests==2.28.2=pyhd8ed1ab_1[md5=3bfbd6ead1d7299ed46dab3a7bf0bc8c] + - conda-forge/linux-64::conda==23.1.0=py310hff52083_0[md5=c2f5cd14bf4a8cc673f66fd9839e6602] + - conda-forge/linux-64::mamba==1.4.1=py310h51d5547_0[md5=49170d6752d2326fe16dc2b6e74f9e54] + + + + Package Version Build Channel Size +─────────────────────────────────────────────────────────────────────────────────────── + Install: +─────────────────────────────────────────────────────────────────────────────────────── + + + _libgcc_mutex 0.1 conda_forge conda-forge Cached + + _openmp_mutex 4.5 2_gnu conda-forge Cached + + brotlipy 0.7.0 py310h5764c6d_1005 conda-forge Cached + + bzip2 1.0.8 h7f98852_4 conda-forge Cached + + c-ares 1.18.1 h7f98852_0 conda-forge Cached + + ca-certificates 2022.12.7 ha878542_0 conda-forge Cached + + certifi 2022.12.7 pyhd8ed1ab_0 conda-forge Cached + + cffi 1.15.1 py310h255011f_3 conda-forge Cached + + charset-normalizer 3.1.0 pyhd8ed1ab_0 conda-forge Cached + + colorama 0.4.6 pyhd8ed1ab_0 conda-forge Cached + + conda 23.1.0 py310hff52083_0 conda-forge Cached + + conda-package-handling 2.0.2 pyh38be061_0 conda-forge Cached + + conda-package-streaming 0.7.0 pyhd8ed1ab_1 conda-forge Cached + + cryptography 40.0.1 py310h34c0648_0 conda-forge Cached + + fmt 9.1.0 h924138e_0 conda-forge Cached + + icu 72.1 hcb278e6_0 conda-forge Cached + + idna 3.4 pyhd8ed1ab_0 conda-forge Cached + + keyutils 1.6.1 h166bdaf_0 conda-forge Cached + + krb5 1.20.1 h81ceb04_0 conda-forge Cached + + ld_impl_linux-64 2.40 h41732ed_0 conda-forge Cached + + libarchive 3.6.2 h3d51595_0 conda-forge Cached + + libcurl 7.88.1 hdc1c0ab_1 conda-forge Cached + + libedit 3.1.20191231 he28a2e2_2 conda-forge Cached + + libev 4.33 h516909a_1 conda-forge Cached + + libffi 3.4.2 h7f98852_5 conda-forge Cached + + libgcc-ng 12.2.0 h65d4601_19 conda-forge Cached + + libgomp 12.2.0 h65d4601_19 conda-forge Cached + + libiconv 1.17 h166bdaf_0 conda-forge Cached + + libmamba 1.4.1 hcea66bb_0 conda-forge Cached + + libmambapy 1.4.1 py310h1428755_0 conda-forge Cached + + libnghttp2 1.52.0 h61bc06f_0 conda-forge Cached + + libnsl 2.0.0 h7f98852_0 conda-forge Cached + + libsolv 0.7.23 h3eb15da_0 conda-forge Cached + + libsqlite 3.40.0 h753d276_0 conda-forge Cached + + libssh2 1.10.0 hf14f497_3 conda-forge Cached + + libstdcxx-ng 12.2.0 h46fd767_19 conda-forge Cached + + libuuid 2.38.1 h0b41bf4_0 conda-forge Cached + + libxml2 2.10.3 hfdac1af_6 conda-forge Cached + + libzlib 1.2.13 h166bdaf_4 conda-forge Cached + + lz4-c 1.9.4 hcb278e6_0 conda-forge Cached + + lzo 2.10 h516909a_1000 conda-forge Cached + + mamba 1.4.1 py310h51d5547_0 conda-forge Cached + + ncurses 6.3 h27087fc_1 conda-forge Cached + + openssl 3.1.0 h0b41bf4_0 conda-forge Cached + + pip 23.0.1 pyhd8ed1ab_0 conda-forge Cached + + pluggy 1.0.0 pyhd8ed1ab_5 conda-forge Cached + + pybind11-abi 4 hd8ed1ab_3 conda-forge Cached + + pycosat 0.6.4 py310h5764c6d_1 conda-forge Cached + + pycparser 2.21 pyhd8ed1ab_0 conda-forge Cached + + pyopenssl 23.1.1 pyhd8ed1ab_0 conda-forge Cached + + pysocks 1.7.1 pyha2e5f31_6 conda-forge Cached + + python 3.10.10 he550d4f_0_cpython conda-forge Cached + + python_abi 3.10 3_cp310 conda-forge Cached + + readline 8.2 h8228510_1 conda-forge Cached + + reproc 14.2.4 h0b41bf4_0 conda-forge Cached + + reproc-cpp 14.2.4 hcb278e6_0 conda-forge Cached + + requests 2.28.2 pyhd8ed1ab_1 conda-forge Cached + + ruamel.yaml 0.17.21 py310h1fa729e_3 conda-forge Cached + + ruamel.yaml.clib 0.2.7 py310h1fa729e_1 conda-forge Cached + + setuptools 65.6.3 pyhd8ed1ab_0 conda-forge Cached + + tk 8.6.12 h27826a3_0 conda-forge Cached + + toolz 0.12.0 pyhd8ed1ab_0 conda-forge Cached + + tqdm 4.65.0 pyhd8ed1ab_1 conda-forge Cached + + tzdata 2023c h71feb2d_0 conda-forge Cached + + urllib3 1.26.15 pyhd8ed1ab_0 conda-forge Cached + + wheel 0.40.0 pyhd8ed1ab_0 conda-forge Cached + + xz 5.2.6 h166bdaf_0 conda-forge Cached + + yaml-cpp 0.7.0 h27087fc_2 conda-forge Cached + + zstandard 0.19.0 py310hdeb6495_1 conda-forge Cached + + zstd 1.5.2 h3eb15da_6 conda-forge Cached + + Summary: + + Install: 70 packages + + Total download: 0 B + +─────────────────────────────────────────────────────────────────────────────────────── + + + + +Transaction starting + +Linking _libgcc_mutex-0.1-conda_forge + +Linking ca-certificates-2022.12.7-ha878542_0 + +Linking ld_impl_linux-64-2.40-h41732ed_0 + +Linking libstdcxx-ng-12.2.0-h46fd767_19 + +Linking pybind11-abi-4-hd8ed1ab_3 + +Linking python_abi-3.10-3_cp310 + +Linking tzdata-2023c-h71feb2d_0 + +Linking libgomp-12.2.0-h65d4601_19 + +Linking _openmp_mutex-4.5-2_gnu + +Linking libgcc-ng-12.2.0-h65d4601_19 + +Linking bzip2-1.0.8-h7f98852_4 + +Linking c-ares-1.18.1-h7f98852_0 + +Linking fmt-9.1.0-h924138e_0 + +Linking icu-72.1-hcb278e6_0 + +Linking keyutils-1.6.1-h166bdaf_0 + +Linking libev-4.33-h516909a_1 + +Linking libffi-3.4.2-h7f98852_5 + +Linking libiconv-1.17-h166bdaf_0 + +Linking libnsl-2.0.0-h7f98852_0 + +Linking libuuid-2.38.1-h0b41bf4_0 + +Linking libzlib-1.2.13-h166bdaf_4 + +Linking lz4-c-1.9.4-hcb278e6_0 + +Linking lzo-2.10-h516909a_1000 + +Linking ncurses-6.3-h27087fc_1 + +Linking openssl-3.1.0-h0b41bf4_0 + +Linking reproc-14.2.4-h0b41bf4_0 + +Linking xz-5.2.6-h166bdaf_0 + +Linking yaml-cpp-0.7.0-h27087fc_2 + +Linking libedit-3.1.20191231-he28a2e2_2 + +Linking libnghttp2-1.52.0-h61bc06f_0 + +Linking libsolv-0.7.23-h3eb15da_0 + +Linking libsqlite-3.40.0-h753d276_0 + +Linking libssh2-1.10.0-hf14f497_3 + +Linking libxml2-2.10.3-hfdac1af_6 + +Linking readline-8.2-h8228510_1 + +Linking reproc-cpp-14.2.4-hcb278e6_0 + +Linking tk-8.6.12-h27826a3_0 + +Linking zstd-1.5.2-h3eb15da_6 + +Linking krb5-1.20.1-h81ceb04_0 + +Linking libarchive-3.6.2-h3d51595_0 + +Linking python-3.10.10-he550d4f_0_cpython + +Linking certifi-2022.12.7-pyhd8ed1ab_0 + +Linking charset-normalizer-3.1.0-pyhd8ed1ab_0 + +Linking colorama-0.4.6-pyhd8ed1ab_0 + +Linking idna-3.4-pyhd8ed1ab_0 + +Linking libcurl-7.88.1-hdc1c0ab_1 + +Linking pluggy-1.0.0-pyhd8ed1ab_5 + +Linking pycosat-0.6.4-py310h5764c6d_1 + +Linking pycparser-2.21-pyhd8ed1ab_0 + +Linking pysocks-1.7.1-pyha2e5f31_6 + +Linking ruamel.yaml.clib-0.2.7-py310h1fa729e_1 + +Linking setuptools-65.6.3-pyhd8ed1ab_0 + +Linking toolz-0.12.0-pyhd8ed1ab_0 + +Linking wheel-0.40.0-pyhd8ed1ab_0 + +Linking cffi-1.15.1-py310h255011f_3 + +Linking libmamba-1.4.1-hcea66bb_0 + +Linking pip-23.0.1-pyhd8ed1ab_0 + +Linking ruamel.yaml-0.17.21-py310h1fa729e_3 + +Linking tqdm-4.65.0-pyhd8ed1ab_1 + +Linking brotlipy-0.7.0-py310h5764c6d_1005 + +Linking cryptography-40.0.1-py310h34c0648_0 + +Linking libmambapy-1.4.1-py310h1428755_0 + +Linking zstandard-0.19.0-py310hdeb6495_1 + +Linking conda-package-streaming-0.7.0-pyhd8ed1ab_1 + +Linking pyopenssl-23.1.1-pyhd8ed1ab_0 + +Linking conda-package-handling-2.0.2-pyh38be061_0 + +Linking urllib3-1.26.15-pyhd8ed1ab_0 + +Linking requests-2.28.2-pyhd8ed1ab_1 + +Linking conda-23.1.0-py310hff52083_0 + +Linking mamba-1.4.1-py310h51d5547_0 + +Transaction finished + +installation finished. + +WARNING: + You currently have a PYTHONPATH environment variable set. This may cause + + unexpected behavior when running the Python interpreter in Mambaforge. + For best results, please verify that your PYTHONPATH only points to + directories of packages that are compatible with the Python interpreter + in Mambaforge: /root/mambaforge + + ---> 6505a24fc87d + +Step 4/15 : copy environment.yaml /root/environment.yaml + + + ---> 2c2042a80716 + +Step 5/15 : run /root/mambaforge/bin/mamba env create --name snakemake-tutorial --file environment.yaml + + + ---> Running in 113cf9e4d1a5 + + + +Looking for: ["snakemake-minimal[version='>=7.3']", 'jinja2', 'matplotlib', 'graphviz', 'bcftools=1.15', 'samtools=1.15', 'bwa=0.7.17', 'pysam=0.19', 'pygments'] + + + +Transaction + + Prefix: /root/mambaforge/envs/snakemake-tutorial + + Updating specs: + + - snakemake-minimal[version='>=7.3'] + - jinja2 + - matplotlib + - graphviz + - bcftools=1.15 + - samtools=1.15 + - bwa=0.7.17 + - pysam=0.19 + - pygments + + + + Package Version Build Channel Size +─────────────────────────────────────────────────────────────────────────────────────────────────── + Install: +─────────────────────────────────────────────────────────────────────────────────────────────────── + + + _libgcc_mutex 0.1 conda_forge conda-forge/linux-64 Cached + + _openmp_mutex 4.5 2_gnu conda-forge/linux-64 Cached + + alsa-lib 1.2.8 h166bdaf_0 conda-forge/linux-64 592kB + + amply 0.1.5 pyhd8ed1ab_0 conda-forge/noarch 21kB + + appdirs 1.4.4 pyh9f0ad1d_0 conda-forge/noarch 13kB + + atk-1.0 2.38.0 hd4edc92_1 conda-forge/linux-64 552kB + + attr 2.5.1 h166bdaf_1 conda-forge/linux-64 71kB + + attrs 23.1.0 pyh71513ae_1 conda-forge/noarch 55kB + + bcftools 1.15.1 hfe4b78e_1 bioconda/linux-64 867kB + + brotli 1.0.9 h166bdaf_8 conda-forge/linux-64 19kB + + brotli-bin 1.0.9 h166bdaf_8 conda-forge/linux-64 20kB + + brotlipy 0.7.0 py310h5764c6d_1005 conda-forge/linux-64 Cached + + bwa 0.7.17 he4a0461_11 bioconda/linux-64 196kB + + bzip2 1.0.8 h7f98852_4 conda-forge/linux-64 Cached + + c-ares 1.19.0 hd590300_0 conda-forge/linux-64 114kB + + ca-certificates 2023.5.7 hbcca054_0 conda-forge/linux-64 148kB + + cairo 1.16.0 ha61ee94_1014 conda-forge/linux-64 2MB + + certifi 2023.5.7 pyhd8ed1ab_0 conda-forge/noarch 152kB + + cffi 1.15.1 py310h255011f_3 conda-forge/linux-64 Cached + + charset-normalizer 3.1.0 pyhd8ed1ab_0 conda-forge/noarch Cached + + coin-or-cbc 2.10.10 h9002f0b_0 conda-forge/linux-64 941kB + + coin-or-cgl 0.60.7 h516709c_0 conda-forge/linux-64 551kB + + coin-or-clp 1.17.8 h1ee7a9c_0 conda-forge/linux-64 1MB + + coin-or-osi 0.108.8 ha2443b9_0 conda-forge/linux-64 389kB + + coin-or-utils 2.11.9 hee58242_0 conda-forge/linux-64 687kB + + coincbc 2.10.10 0_metapackage conda-forge/noarch 12kB + + configargparse 1.5.3 pyhd8ed1ab_0 conda-forge/noarch 33kB + + connection_pool 0.0.3 pyhd3deb0d_0 conda-forge/noarch 8kB + + contourpy 1.0.7 py310hdf3cbec_0 conda-forge/linux-64 216kB + + cryptography 39.0.0 py310h65dfdc0_0 conda-forge/linux-64 1MB + + cycler 0.11.0 pyhd8ed1ab_0 conda-forge/noarch 10kB + + datrie 0.8.2 py310h5764c6d_6 conda-forge/linux-64 148kB + + dbus 1.13.6 h5008d03_3 conda-forge/linux-64 619kB + + docutils 0.20.1 py310hff52083_0 conda-forge/linux-64 721kB + + dpath 2.1.6 pyha770c72_0 conda-forge/noarch 21kB + + expat 2.5.0 hcb278e6_1 conda-forge/linux-64 137kB + + fftw 3.3.10 nompi_hc118613_107 conda-forge/linux-64 2MB + + filelock 3.12.0 pyhd8ed1ab_0 conda-forge/noarch 15kB + + font-ttf-dejavu-sans-mono 2.37 hab24e00_0 conda-forge/noarch 397kB + + font-ttf-inconsolata 3.000 h77eed37_0 conda-forge/noarch 97kB + + font-ttf-source-code-pro 2.038 h77eed37_0 conda-forge/noarch 701kB + + font-ttf-ubuntu 0.83 hab24e00_0 conda-forge/noarch 2MB + + fontconfig 2.14.2 h14ed4e7_0 conda-forge/linux-64 272kB + + fonts-conda-ecosystem 1 0 conda-forge/noarch 4kB + + fonts-conda-forge 1 0 conda-forge/noarch 4kB + + fonttools 4.39.4 py310h2372a71_0 conda-forge/linux-64 2MB + + freetype 2.12.1 hca18f0e_1 conda-forge/linux-64 626kB + + fribidi 1.0.10 h36c2ea0_0 conda-forge/linux-64 114kB + + gdk-pixbuf 2.42.8 hff1cb4f_1 conda-forge/linux-64 612kB + + gettext 0.21.1 h27087fc_0 conda-forge/linux-64 4MB + + giflib 5.2.1 h0b41bf4_3 conda-forge/linux-64 77kB + + gitdb 4.0.10 pyhd8ed1ab_0 conda-forge/noarch 52kB + + gitpython 3.1.31 pyhd8ed1ab_0 conda-forge/noarch 142kB + + glib 2.76.2 hfc55251_0 conda-forge/linux-64 484kB + + glib-tools 2.76.2 hfc55251_0 conda-forge/linux-64 112kB + + graphite2 1.3.13 h58526e2_1001 conda-forge/linux-64 105kB + + graphviz 7.0.5 h2e5815a_0 conda-forge/linux-64 2MB + + gsl 2.7 he838d99_0 conda-forge/linux-64 3MB + + gst-plugins-base 1.21.3 h4243ec0_1 conda-forge/linux-64 3MB + + gstreamer 1.21.3 h25f0c4b_1 conda-forge/linux-64 2MB + + gstreamer-orc 0.4.33 h166bdaf_0 conda-forge/linux-64 306kB + + gtk2 2.24.33 h90689f9_2 conda-forge/linux-64 8MB + + gts 0.7.6 h64030ff_2 conda-forge/linux-64 421kB + + harfbuzz 6.0.0 h8e241bc_0 conda-forge/linux-64 1MB + + htslib 1.16 h6bc39ce_0 bioconda/linux-64 2MB + + humanfriendly 10.0 py310hff52083_4 conda-forge/linux-64 123kB + + icu 70.1 h27087fc_0 conda-forge/linux-64 14MB + + idna 3.4 pyhd8ed1ab_0 conda-forge/noarch Cached + + importlib-metadata 6.6.0 pyha770c72_0 conda-forge/noarch 26kB + + importlib_resources 5.12.0 pyhd8ed1ab_0 conda-forge/noarch 31kB + + jack 1.9.22 h11f4161_0 conda-forge/linux-64 464kB + + jinja2 3.1.2 pyhd8ed1ab_1 conda-forge/noarch 101kB + + jpeg 9e h0b41bf4_3 conda-forge/linux-64 240kB + + jsonschema 4.17.3 pyhd8ed1ab_0 conda-forge/noarch 70kB + + jupyter_core 5.3.0 py310hff52083_0 conda-forge/linux-64 91kB + + keyutils 1.6.1 h166bdaf_0 conda-forge/linux-64 Cached + + kiwisolver 1.4.4 py310hbf28c38_1 conda-forge/linux-64 77kB + + krb5 1.20.1 hf9c8cef_0 conda-forge/linux-64 1MB + + lame 3.100 h166bdaf_1003 conda-forge/linux-64 508kB + + lcms2 2.14 h6ed2654_0 conda-forge/linux-64 262kB + + ld_impl_linux-64 2.40 h41732ed_0 conda-forge/linux-64 Cached + + lerc 4.0.0 h27087fc_0 conda-forge/linux-64 282kB + + libblas 3.9.0 16_linux64_openblas conda-forge/linux-64 13kB + + libbrotlicommon 1.0.9 h166bdaf_8 conda-forge/linux-64 67kB + + libbrotlidec 1.0.9 h166bdaf_8 conda-forge/linux-64 34kB + + libbrotlienc 1.0.9 h166bdaf_8 conda-forge/linux-64 295kB + + libcap 2.66 ha37c62d_0 conda-forge/linux-64 100kB + + libcblas 3.9.0 16_linux64_openblas conda-forge/linux-64 13kB + + libclang 15.0.7 default_h7634d5b_2 conda-forge/linux-64 133kB + + libclang13 15.0.7 default_h9986a30_2 conda-forge/linux-64 10MB + + libcups 2.3.3 h36d4200_3 conda-forge/linux-64 5MB + + libcurl 7.87.0 h6312ad2_0 conda-forge/linux-64 347kB + + libdb 6.2.32 h9c3ff4c_0 conda-forge/linux-64 24MB + + libdeflate 1.13 h166bdaf_0 conda-forge/linux-64 80kB + + libedit 3.1.20191231 he28a2e2_2 conda-forge/linux-64 Cached + + libev 4.33 h516909a_1 conda-forge/linux-64 Cached + + libevent 2.1.10 h9b69904_4 conda-forge/linux-64 1MB + + libexpat 2.5.0 hcb278e6_1 conda-forge/linux-64 78kB + + libffi 3.4.2 h7f98852_5 conda-forge/linux-64 Cached + + libflac 1.4.2 h27087fc_0 conda-forge/linux-64 421kB + + libgcc-ng 12.2.0 h65d4601_19 conda-forge/linux-64 Cached + + libgcrypt 1.10.1 h166bdaf_0 conda-forge/linux-64 720kB + + libgd 2.3.3 h18fbbfe_3 conda-forge/linux-64 272kB + + libgfortran-ng 12.2.0 h69a702a_19 conda-forge/linux-64 23kB + + libgfortran5 12.2.0 h337968e_19 conda-forge/linux-64 2MB + + libglib 2.76.2 hebfc3b9_0 conda-forge/linux-64 3MB + + libgomp 12.2.0 h65d4601_19 conda-forge/linux-64 Cached + + libgpg-error 1.46 h620e276_0 conda-forge/linux-64 258kB + + libiconv 1.17 h166bdaf_0 conda-forge/linux-64 Cached + + liblapack 3.9.0 16_linux64_openblas conda-forge/linux-64 13kB + + liblapacke 3.9.0 16_linux64_openblas conda-forge/linux-64 13kB + + libllvm15 15.0.7 hadd5161_1 conda-forge/linux-64 33MB + + libnghttp2 1.51.0 hdcd2b5c_0 conda-forge/linux-64 623kB + + libnsl 2.0.0 h7f98852_0 conda-forge/linux-64 Cached + + libogg 1.3.4 h7f98852_1 conda-forge/linux-64 211kB + + libopenblas 0.3.21 pthreads_h78a6416_3 conda-forge/linux-64 11MB + + libopus 1.3.1 h7f98852_1 conda-forge/linux-64 261kB + + libpng 1.6.39 h753d276_0 conda-forge/linux-64 283kB + + libpq 15.1 h2baec63_3 conda-forge/linux-64 2MB + + librsvg 2.54.4 h7abd40a_0 conda-forge/linux-64 7MB + + libsndfile 1.2.0 hb75c966_0 conda-forge/linux-64 350kB + + libsqlite 3.42.0 h2797004_0 conda-forge/linux-64 829kB + + libssh2 1.10.0 haa6b8db_3 conda-forge/linux-64 239kB + + libstdcxx-ng 12.2.0 h46fd767_19 conda-forge/linux-64 Cached + + libsystemd0 252 h2a991cd_0 conda-forge/linux-64 393kB + + libtiff 4.4.0 h0e0dad5_3 conda-forge/linux-64 658kB + + libtool 2.4.7 h27087fc_0 conda-forge/linux-64 412kB + + libudev1 253 h0b41bf4_0 conda-forge/linux-64 119kB + + libuuid 2.38.1 h0b41bf4_0 conda-forge/linux-64 Cached + + libvorbis 1.3.7 h9c3ff4c_0 conda-forge/linux-64 286kB + + libwebp 1.2.4 h522a892_0 conda-forge/linux-64 90kB + + libwebp-base 1.2.4 h166bdaf_0 conda-forge/linux-64 413kB + + libxcb 1.13 h7f98852_1004 conda-forge/linux-64 400kB + + libxkbcommon 1.5.0 h79f4944_1 conda-forge/linux-64 563kB + + libxml2 2.10.3 hca2bb57_4 conda-forge/linux-64 714kB + + libzlib 1.2.13 h166bdaf_4 conda-forge/linux-64 Cached + + lz4-c 1.9.4 hcb278e6_0 conda-forge/linux-64 Cached + + markupsafe 2.1.2 py310h1fa729e_0 conda-forge/linux-64 23kB + + matplotlib 3.7.1 py310hff52083_0 conda-forge/linux-64 8kB + + matplotlib-base 3.7.1 py310he60537e_0 conda-forge/linux-64 7MB + + mpg123 1.31.3 hcb278e6_0 conda-forge/linux-64 485kB + + munkres 1.0.7 py_1 bioconda/noarch 10kB + + mysql-common 8.0.32 h14678bc_0 conda-forge/linux-64 803kB + + mysql-libs 8.0.32 h54cf53e_0 conda-forge/linux-64 2MB + + nbformat 5.8.0 pyhd8ed1ab_0 conda-forge/noarch 101kB + + ncurses 6.3 h27087fc_1 conda-forge/linux-64 Cached + + nspr 4.35 h27087fc_0 conda-forge/linux-64 227kB + + nss 3.89 he45b914_0 conda-forge/linux-64 2MB + + numpy 1.24.3 py310ha4c1d20_0 conda-forge/linux-64 7MB + + openjpeg 2.5.0 h7d73246_1 conda-forge/linux-64 546kB + + openssl 1.1.1t h0b41bf4_0 conda-forge/linux-64 2MB + + packaging 23.1 pyhd8ed1ab_0 conda-forge/noarch 46kB + + pango 1.50.14 hd33c08f_0 conda-forge/linux-64 438kB + + pcre2 10.40 hc3806b6_0 conda-forge/linux-64 2MB + + perl 5.32.1 2_h7f98852_perl5 conda-forge/linux-64 15MB + + pillow 9.2.0 py310h454ad03_3 conda-forge/linux-64 47MB + + pip 23.1.2 pyhd8ed1ab_0 conda-forge/noarch 1MB + + pixman 0.40.0 h36c2ea0_0 conda-forge/linux-64 643kB + + pkgutil-resolve-name 1.3.10 pyhd8ed1ab_0 conda-forge/noarch 9kB + + plac 1.3.5 pyhd8ed1ab_0 conda-forge/noarch 23kB + + platformdirs 3.5.1 pyhd8ed1ab_0 conda-forge/noarch 19kB + + ply 3.11 py_1 conda-forge/noarch 45kB + + psutil 5.9.5 py310h1fa729e_0 conda-forge/linux-64 362kB + + pthread-stubs 0.4 h36c2ea0_1001 conda-forge/linux-64 6kB + + pulp 2.7.0 py310hff52083_0 conda-forge/linux-64 141kB + + pulseaudio 16.1 h4ab2085_1 conda-forge/linux-64 2MB + + pycparser 2.21 pyhd8ed1ab_0 conda-forge/noarch Cached + + pygments 2.15.1 pyhd8ed1ab_0 conda-forge/noarch 841kB + + pyopenssl 23.1.1 pyhd8ed1ab_0 conda-forge/noarch Cached + + pyparsing 3.0.9 pyhd8ed1ab_0 conda-forge/noarch 81kB + + pyqt 5.15.7 py310hab646b1_3 conda-forge/linux-64 5MB + + pyqt5-sip 12.11.0 py310heca2aa9_3 conda-forge/linux-64 85kB + + pyrsistent 0.19.3 py310h1fa729e_0 conda-forge/linux-64 100kB + + pysam 0.19.1 py310hff46b53_1 bioconda/linux-64 3MB + + pysocks 1.7.1 pyha2e5f31_6 conda-forge/noarch Cached + + python 3.10.8 h257c98d_0_cpython conda-forge/linux-64 23MB + + python-dateutil 2.8.2 pyhd8ed1ab_0 conda-forge/noarch 246kB + + python-fastjsonschema 2.16.3 pyhd8ed1ab_0 conda-forge/noarch 225kB + + python_abi 3.10 3_cp310 conda-forge/linux-64 Cached + + pyyaml 6.0 py310h5764c6d_5 conda-forge/linux-64 176kB + + qt-main 5.15.6 h18908ee_6 conda-forge/linux-64 55MB + + readline 8.2 h8228510_1 conda-forge/linux-64 Cached + + requests 2.29.0 pyhd8ed1ab_0 conda-forge/noarch 57kB + + reretry 0.11.8 pyhd8ed1ab_0 conda-forge/noarch 12kB + + samtools 1.15.1 h6899075_1 bioconda/linux-64 406kB + + setuptools 67.7.2 pyhd8ed1ab_0 conda-forge/noarch 583kB + + sip 6.7.9 py310hc6cd4ac_0 conda-forge/linux-64 493kB + + six 1.16.0 pyh6c4a22f_0 conda-forge/noarch 14kB + + smart_open 6.3.0 pyhd8ed1ab_1 conda-forge/noarch 47kB + + smmap 3.0.5 pyh44b312d_0 conda-forge/noarch 23kB + + snakemake-minimal 7.25.4 pyhdfd78af_0 bioconda/noarch 266kB + + stopit 1.1.2 py_0 conda-forge/noarch 16kB + + tabulate 0.9.0 pyhd8ed1ab_1 conda-forge/noarch 36kB + + throttler 1.2.1 pyhd8ed1ab_0 conda-forge/noarch 11kB + + tk 8.6.12 h27826a3_0 conda-forge/linux-64 Cached + + toml 0.10.2 pyhd8ed1ab_0 conda-forge/noarch 18kB + + tomli 2.0.1 pyhd8ed1ab_0 conda-forge/noarch 16kB + + toposort 1.10 pyhd8ed1ab_0 conda-forge/noarch 14kB + + tornado 6.3.2 py310h2372a71_0 conda-forge/linux-64 639kB + + traitlets 5.9.0 pyhd8ed1ab_0 conda-forge/noarch 98kB + + typing-extensions 4.5.0 hd8ed1ab_0 conda-forge/noarch 10kB + + typing_extensions 4.5.0 pyha770c72_0 conda-forge/noarch 31kB + + tzdata 2023c h71feb2d_0 conda-forge/noarch Cached + + unicodedata2 15.0.0 py310h5764c6d_0 conda-forge/linux-64 512kB + + urllib3 1.26.15 pyhd8ed1ab_0 conda-forge/noarch Cached + + wheel 0.40.0 pyhd8ed1ab_0 conda-forge/noarch Cached + + wrapt 1.15.0 py310h1fa729e_0 conda-forge/linux-64 54kB + + xcb-util 0.4.0 h516909a_0 conda-forge/linux-64 20kB + + xcb-util-image 0.4.0 h166bdaf_0 conda-forge/linux-64 24kB + + xcb-util-keysyms 0.4.0 h516909a_0 conda-forge/linux-64 12kB + + xcb-util-renderutil 0.3.9 h166bdaf_0 conda-forge/linux-64 16kB + + xcb-util-wm 0.4.1 h516909a_0 conda-forge/linux-64 56kB + + xkeyboard-config 2.38 h0b41bf4_0 conda-forge/linux-64 882kB + + xorg-kbproto 1.0.7 h7f98852_1002 conda-forge/linux-64 27kB + + xorg-libice 1.0.10 h7f98852_0 conda-forge/linux-64 59kB + + xorg-libsm 1.2.3 hd9c2040_1000 conda-forge/linux-64 26kB + + xorg-libx11 1.8.4 h0b41bf4_0 conda-forge/linux-64 830kB + + xorg-libxau 1.0.11 hd590300_0 conda-forge/linux-64 14kB + + xorg-libxdmcp 1.1.3 h7f98852_0 conda-forge/linux-64 19kB + + xorg-libxext 1.3.4 h0b41bf4_2 conda-forge/linux-64 50kB + + xorg-libxrender 0.9.10 h7f98852_1003 conda-forge/linux-64 33kB + + xorg-renderproto 0.11.1 h7f98852_1002 conda-forge/linux-64 10kB + + xorg-xextproto 7.3.0 h0b41bf4_1003 conda-forge/linux-64 30kB + + xorg-xproto 7.0.31 h7f98852_1007 conda-forge/linux-64 75kB + + xz 5.2.6 h166bdaf_0 conda-forge/linux-64 Cached + + yaml 0.2.5 h7f98852_2 conda-forge/linux-64 89kB + + yte 1.5.1 py310hff52083_1 conda-forge/linux-64 18kB + + zipp 3.15.0 pyhd8ed1ab_0 conda-forge/noarch 17kB + + zlib 1.2.13 h166bdaf_4 conda-forge/linux-64 94kB + + zstd 1.5.2 h3eb15da_6 conda-forge/linux-64 Cached + + Summary: + + Install: 230 packages + + Total download: 357MB + +─────────────────────────────────────────────────────────────────────────────────────────────────── + + + + +Downloading and Extracting Packages + +Preparing transaction: ...working... +done + +Verifying transaction: ...working... +done + +Executing transaction: ...working... + + +done + +# +# To activate this environment, use +# +# $ conda activate snakemake-tutorial +# +# To deactivate an active environment, use +# +# $ conda deactivate + + + ---> 3c11703ad114 + +Step 6/15 : env PATH /root/mambaforge/envs/snakemake-tutorial/bin:$PATH + + + ---> Running in 5758f3dd4146 + + ---> 48b5620a8619 + +Step 7/15 : run python3 -m pip install latch + + + ---> Running in 0e3eccd0beb3 + +Collecting latch + + Downloading latch-2.19.11-py3-none-any.whl (150 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 150.6/150.6 kB 4.8 MB/s eta 0:00:00 + + +Collecting awscli==1.25.22 (from latch) + + Downloading awscli-1.25.22-py3-none-any.whl (3.9 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.9/3.9 MB 58.3 MB/s eta 0:00:00 + + +Collecting asyncssh==2.12.0 (from latch) + + Downloading asyncssh-2.12.0-py3-none-any.whl (346 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 346.7/346.7 kB 41.3 MB/s eta 0:00:00 + + +Collecting aioconsole==0.5.1 (from latch) + + Downloading aioconsole-0.5.1-py3-none-any.whl (30 kB) + +Collecting kubernetes>=24.2.0 (from latch) + + Downloading kubernetes-26.1.0-py2.py3-none-any.whl (1.4 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.4/1.4 MB 71.6 MB/s eta 0:00:00 + + +Collecting pyjwt>=0.2.0 (from latch) + + Downloading PyJWT-2.7.0-py3-none-any.whl (22 kB) + +Requirement already satisfied: requests>=2.28.1 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from latch) (2.29.0) + +Collecting click>=8.0 (from latch) + + Downloading click-8.1.3-py3-none-any.whl (96 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 96.6/96.6 kB 14.8 MB/s eta 0:00:00 + + +Collecting docker>=5.0 (from latch) + + Downloading docker-6.1.2-py3-none-any.whl (148 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 148.1/148.1 kB 23.4 MB/s eta 0:00:00 + + +Collecting paramiko>=2.11.0 (from latch) + + Downloading paramiko-3.1.0-py3-none-any.whl (211 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 211.2/211.2 kB 28.6 MB/s eta 0:00:00 + + +Collecting scp>=0.14.0 (from latch) + + Downloading scp-0.14.5-py2.py3-none-any.whl (8.7 kB) + +Collecting boto3>=1.24.22 (from latch) + + Using cached boto3-1.26.137-py3-none-any.whl (135 kB) + +Collecting tqdm>=4.63.0 (from latch) + + Downloading tqdm-4.65.0-py3-none-any.whl (77 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 77.1/77.1 kB 11.9 MB/s eta 0:00:00 + + +Collecting lytekit==0.14.10 (from latch) + + Downloading lytekit-0.14.10-py3-none-any.whl (391 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 391.8/391.8 kB 43.4 MB/s eta 0:00:00 + + +Collecting lytekitplugins-pods==0.4.0 (from latch) + + Downloading lytekitplugins_pods-0.4.0-py3-none-any.whl (4.3 kB) + +Requirement already satisfied: typing-extensions==4.5.0 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from latch) (4.5.0) + +Collecting apscheduler==3.9.1 (from latch) + + Downloading APScheduler-3.9.1-py2.py3-none-any.whl (59 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 59.5/59.5 kB 10.5 MB/s eta 0:00:00 + + +Collecting uvloop==0.17.0 (from latch) + + Downloading uvloop-0.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.1 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.1/4.1 MB 83.0 MB/s eta 0:00:00 + + +Collecting websockets==10.3 (from latch) + + Downloading websockets-10.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (111 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 111.5/111.5 kB 16.7 MB/s eta 0:00:00 + + +Collecting prompt-toolkit==3.0.33 (from latch) + + Downloading prompt_toolkit-3.0.33-py3-none-any.whl (383 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 383.6/383.6 kB 39.0 MB/s eta 0:00:00 + + +Collecting watchfiles==0.18.1 (from latch) + + Downloading watchfiles-0.18.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.2 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.2/1.2 MB 70.7 MB/s eta 0:00:00 + + +Collecting gql==3.4.0 (from latch) + + Downloading gql-3.4.0-py2.py3-none-any.whl (65 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 65.2/65.2 kB 11.3 MB/s eta 0:00:00 + + +Collecting graphql-core==3.2.3 (from latch) + + Downloading graphql_core-3.2.3-py3-none-any.whl (202 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 202.9/202.9 kB 28.2 MB/s eta 0:00:00 + + +Collecting requests-toolbelt==0.10.1 (from latch) + + Downloading requests_toolbelt-0.10.1-py2.py3-none-any.whl (54 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 54.5/54.5 kB 8.7 MB/s eta 0:00:00 + + +Requirement already satisfied: setuptools>=0.7 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from apscheduler==3.9.1->latch) (67.7.2) + +Requirement already satisfied: six>=1.4.0 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from apscheduler==3.9.1->latch) (1.16.0) + +Collecting pytz (from apscheduler==3.9.1->latch) + + Downloading pytz-2023.3-py2.py3-none-any.whl (502 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 502.3/502.3 kB 49.0 MB/s eta 0:00:00 + + +Collecting tzlocal!=3.*,>=2.0 (from apscheduler==3.9.1->latch) + + Downloading tzlocal-5.0.1-py3-none-any.whl (20 kB) + +Requirement already satisfied: cryptography>=3.1 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from asyncssh==2.12.0->latch) (39.0.0) + +Collecting botocore==1.27.22 (from awscli==1.25.22->latch) + + Downloading botocore-1.27.22-py3-none-any.whl (8.9 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.9/8.9 MB 66.8 MB/s eta 0:00:00 + + +Collecting docutils<0.17,>=0.10 (from awscli==1.25.22->latch) + + Using cached docutils-0.16-py2.py3-none-any.whl (548 kB) + +Collecting s3transfer<0.7.0,>=0.6.0 (from awscli==1.25.22->latch) + + Using cached s3transfer-0.6.1-py3-none-any.whl (79 kB) + +Collecting PyYAML<5.5,>=3.10 (from awscli==1.25.22->latch) + + Downloading PyYAML-5.4.1.tar.gz (175 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 175.1/175.1 kB 27.0 MB/s eta 0:00:00 + + + Installing build dependencies: started + + Installing build dependencies: finished with status 'done' + + Getting requirements to build wheel: started + + Getting requirements to build wheel: finished with status 'done' + + Preparing metadata (pyproject.toml): started + + Preparing metadata (pyproject.toml): finished with status 'done' + +Collecting colorama<0.4.5,>=0.2.5 (from awscli==1.25.22->latch) + + Using cached colorama-0.4.4-py2.py3-none-any.whl (16 kB) + +Collecting rsa<4.8,>=3.1.2 (from awscli==1.25.22->latch) + + Using cached rsa-4.7.2-py3-none-any.whl (34 kB) + +Collecting yarl<2.0,>=1.6 (from gql==3.4.0->latch) + + Downloading yarl-1.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (268 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 268.8/268.8 kB 35.2 MB/s eta 0:00:00 + + +Collecting backoff<3.0,>=1.11.1 (from gql==3.4.0->latch) + + Downloading backoff-2.2.1-py3-none-any.whl (15 kB) + +Collecting lyteidl==0.2.0a0 (from lytekit==0.14.10->latch) + + Downloading lyteidl-0.2.0a0-py3-none-any.whl (162 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 162.2/162.2 kB 24.9 MB/s eta 0:00:00 + + +Requirement already satisfied: wheel<1.0.0,>=0.30.0 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch) (0.40.0) + +Collecting pandas<2.0.0,>=1.0.0 (from lytekit==0.14.10->latch) + + Downloading pandas-1.5.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (12.1 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 12.1/12.1 MB 81.4 MB/s eta 0:00:00 + + +Collecting pyarrow<7.0.0,>=4.0.0 (from lytekit==0.14.10->latch) + + Downloading pyarrow-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (25.6 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 25.6/25.6 MB 53.5 MB/s eta 0:00:00 + + +Collecting croniter<4.0.0,>=0.3.20 (from lytekit==0.14.10->latch) + + Downloading croniter-1.3.14-py2.py3-none-any.whl (18 kB) + +Collecting deprecated<2.0,>=1.0 (from lytekit==0.14.10->latch) + + Downloading Deprecated-1.2.13-py2.py3-none-any.whl (9.6 kB) + +Collecting docker>=5.0 (from latch) + + Downloading docker-5.0.3-py2.py3-none-any.whl (146 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 146.2/146.2 kB 21.7 MB/s eta 0:00:00 + + +Requirement already satisfied: python-dateutil>=2.1 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch) (2.8.2) + +Collecting grpcio!=1.45.0,<2.0,>=1.43.0 (from lytekit==0.14.10->latch) + + Downloading grpcio-1.54.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.1 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 5.1/5.1 MB 89.4 MB/s eta 0:00:00 + + +Collecting grpcio-status!=1.45.0,>=1.43 (from lytekit==0.14.10->latch) + + Downloading grpcio_status-1.54.2-py3-none-any.whl (5.1 kB) + +Collecting protobuf<4,>=3.6.1 (from lytekit==0.14.10->latch) + + Downloading protobuf-3.20.3-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (1.1 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.1/1.1 MB 66.5 MB/s eta 0:00:00 + + +Collecting python-json-logger>=2.0.0 (from lytekit==0.14.10->latch) + + Downloading python_json_logger-2.0.7-py3-none-any.whl (8.1 kB) + +Collecting pytimeparse<2.0.0,>=1.1.8 (from lytekit==0.14.10->latch) + + Downloading pytimeparse-1.1.8-py2.py3-none-any.whl (10.0 kB) + +Collecting keyring>=18.0.1 (from lytekit==0.14.10->latch) + + Downloading keyring-23.13.1-py3-none-any.whl (37 kB) + +Collecting responses>=0.10.7 (from lytekit==0.14.10->latch) + + Downloading responses-0.23.1-py3-none-any.whl (52 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 52.1/52.1 kB 8.7 MB/s eta 0:00:00 + + +Collecting sortedcontainers<3.0.0,>=1.5.9 (from lytekit==0.14.10->latch) + + Downloading sortedcontainers-2.4.0-py2.py3-none-any.whl (29 kB) + +Collecting statsd<4.0.0,>=3.0.0 (from lytekit==0.14.10->latch) + + Downloading statsd-3.3.0-py2.py3-none-any.whl (11 kB) + +Requirement already satisfied: urllib3<2.0.0,>=1.22 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch) (1.26.15) + +Requirement already satisfied: wrapt<2.0.0,>=1.0.0 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch) (1.15.0) + +Collecting retry==0.9.2 (from lytekit==0.14.10->latch) + + Downloading retry-0.9.2-py2.py3-none-any.whl (8.0 kB) + +Collecting dataclasses-json>=0.5.2 (from lytekit==0.14.10->latch) + + Downloading dataclasses_json-0.5.7-py3-none-any.whl (25 kB) + +Requirement already satisfied: jsonschema>=4.5.1 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch) (4.17.3) + +Collecting marshmallow-jsonschema>=0.12.0 (from lytekit==0.14.10->latch) + + Downloading marshmallow_jsonschema-0.13.0-py3-none-any.whl (11 kB) + +Collecting natsort>=7.0.1 (from lytekit==0.14.10->latch) + + Downloading natsort-8.3.1-py3-none-any.whl (38 kB) + +Collecting docker-image-py>=0.1.10 (from lytekit==0.14.10->latch) + + Downloading docker-image-py-0.1.12.tar.gz (8.2 kB) + + Preparing metadata (setup.py): started + + Preparing metadata (setup.py): finished with status 'done' + +Collecting docstring-parser>=0.9.0 (from lytekit==0.14.10->latch) + + Downloading docstring_parser-0.15-py3-none-any.whl (36 kB) + +Collecting diskcache>=5.2.1 (from lytekit==0.14.10->latch) + + Downloading diskcache-5.6.1-py3-none-any.whl (45 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 45.6/45.6 kB 7.5 MB/s eta 0:00:00 + + +Collecting cloudpickle>=2.0.0 (from lytekit==0.14.10->latch) + + Downloading cloudpickle-2.2.1-py3-none-any.whl (25 kB) + +Collecting cookiecutter>=1.7.3 (from lytekit==0.14.10->latch) + + Downloading cookiecutter-2.1.1-py2.py3-none-any.whl (36 kB) + +Collecting numpy<1.22.0 (from lytekit==0.14.10->latch) + + Downloading numpy-1.21.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (15.9 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 15.9/15.9 MB 75.7 MB/s eta 0:00:00 + + +Collecting wcwidth (from prompt-toolkit==3.0.33->latch) + + Downloading wcwidth-0.2.6-py2.py3-none-any.whl (29 kB) + +Collecting anyio>=3.0.0 (from watchfiles==0.18.1->latch) + + Downloading anyio-3.6.2-py3-none-any.whl (80 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 80.6/80.6 kB 12.7 MB/s eta 0:00:00 + + +Collecting jmespath<2.0.0,>=0.7.1 (from botocore==1.27.22->awscli==1.25.22->latch) + + Using cached jmespath-1.0.1-py3-none-any.whl (20 kB) + +Collecting googleapis-common-protos (from lyteidl==0.2.0a0->lytekit==0.14.10->latch) + + Downloading googleapis_common_protos-1.59.0-py2.py3-none-any.whl (223 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 223.6/223.6 kB 31.5 MB/s eta 0:00:00 + + +Collecting protoc-gen-swagger (from lyteidl==0.2.0a0->lytekit==0.14.10->latch) + + Downloading protoc_gen_swagger-0.1.0-py2.py3-none-any.whl (9.4 kB) + +Collecting decorator>=3.4.2 (from retry==0.9.2->lytekit==0.14.10->latch) + + Downloading decorator-5.1.1-py3-none-any.whl (9.1 kB) + +Collecting py<2.0.0,>=1.4.26 (from retry==0.9.2->lytekit==0.14.10->latch) + + Downloading py-1.11.0-py2.py3-none-any.whl (98 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 98.7/98.7 kB 15.6 MB/s eta 0:00:00 + + +INFO: pip is looking at multiple versions of boto3 to determine which version is compatible with other requirements. This could take a while. + +Collecting boto3>=1.24.22 (from latch) + + Downloading boto3-1.26.136-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 21.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.135-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.4 MB/s eta 0:00:00 + + + Downloading boto3-1.26.134-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.133-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.6 MB/s eta 0:00:00 + + + Downloading boto3-1.26.132-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.9 MB/s eta 0:00:00 + + + Downloading boto3-1.26.131-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.9 MB/s eta 0:00:00 + + + Downloading boto3-1.26.130-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.8 MB/s eta 0:00:00 + + +INFO: pip is looking at multiple versions of boto3 to determine which version is compatible with other requirements. This could take a while. + + Downloading boto3-1.26.129-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.6 MB/s eta 0:00:00 + + + Downloading boto3-1.26.128-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.9 MB/s eta 0:00:00 + + + Downloading boto3-1.26.127-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.6 MB/s eta 0:00:00 + + + Downloading boto3-1.26.126-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.125-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.7 MB/s eta 0:00:00 + + +INFO: This is taking longer than usual. You might need to provide the dependency resolver with stricter constraints to reduce runtime. See https://pip.pypa.io/warnings/backtracking for guidance. If you want to abort this run, press Ctrl + C. + + Downloading boto3-1.26.124-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.0 MB/s eta 0:00:00 + + + Downloading boto3-1.26.123-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.3 MB/s eta 0:00:00 + + + Downloading boto3-1.26.122-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 21.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.121-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.3 MB/s eta 0:00:00 + + + Downloading boto3-1.26.120-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.9 MB/s eta 0:00:00 + + + Downloading boto3-1.26.119-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.5 MB/s eta 0:00:00 + + + Downloading boto3-1.26.118-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.5 MB/s eta 0:00:00 + + + Downloading boto3-1.26.117-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.3 MB/s eta 0:00:00 + + + Downloading boto3-1.26.116-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.6 MB/s eta 0:00:00 + + + Downloading boto3-1.26.115-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.8 MB/s eta 0:00:00 + + + Downloading boto3-1.26.114-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.4 MB/s eta 0:00:00 + + + Downloading boto3-1.26.113-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.5 MB/s eta 0:00:00 + + + Downloading boto3-1.26.112-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.111-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.6 MB/s eta 0:00:00 + + + Downloading boto3-1.26.110-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 21.4 MB/s eta 0:00:00 + + + Downloading boto3-1.26.109-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.8 MB/s eta 0:00:00 + + + Downloading boto3-1.26.108-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.6 MB/s eta 0:00:00 + + + Downloading boto3-1.26.107-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 21.5 MB/s eta 0:00:00 + + + Downloading boto3-1.26.106-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 21.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.105-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.0 MB/s eta 0:00:00 + + + Downloading boto3-1.26.104-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.8 MB/s eta 0:00:00 + + + Downloading boto3-1.26.103-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.5 MB/s eta 0:00:00 + + + Downloading boto3-1.26.102-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.5 MB/s eta 0:00:00 + + + Downloading boto3-1.26.101-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.5/135.5 kB 21.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.100-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.5/135.5 kB 20.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.99-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.5/135.5 kB 21.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.98-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.5/135.5 kB 21.5 MB/s eta 0:00:00 + + + Downloading boto3-1.26.97-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.5/135.5 kB 19.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.96-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.5/135.5 kB 21.8 MB/s eta 0:00:00 + + + Downloading boto3-1.26.95-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.5/135.5 kB 19.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.94-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.1/135.1 kB 21.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.93-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.1/135.1 kB 21.8 MB/s eta 0:00:00 + + + Downloading boto3-1.26.92-py3-none-any.whl (134 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 21.3 MB/s eta 0:00:00 + + + Downloading boto3-1.26.91-py3-none-any.whl (134 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 20.6 MB/s eta 0:00:00 + + + Downloading boto3-1.26.90-py3-none-any.whl (134 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 19.0 MB/s eta 0:00:00 + + + Downloading boto3-1.26.89-py3-none-any.whl (134 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 20.3 MB/s eta 0:00:00 + + + Downloading boto3-1.26.88-py3-none-any.whl (134 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 19.6 MB/s eta 0:00:00 + + + Downloading boto3-1.26.87-py3-none-any.whl (134 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 19.9 MB/s eta 0:00:00 + + + Downloading boto3-1.26.86-py3-none-any.whl (134 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 19.8 MB/s eta 0:00:00 + + + Downloading boto3-1.26.85-py3-none-any.whl (134 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 6.0 MB/s eta 0:00:00 + + + Downloading boto3-1.26.84-py3-none-any.whl (134 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 19.8 MB/s eta 0:00:00 + + + Downloading boto3-1.26.83-py3-none-any.whl (134 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 18.8 MB/s eta 0:00:00 + + + Downloading boto3-1.26.82-py3-none-any.whl (134 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 20.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.81-py3-none-any.whl (134 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 20.8 MB/s eta 0:00:00 + + + Downloading boto3-1.26.80-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.9 MB/s eta 0:00:00 + + + Downloading boto3-1.26.79-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.5 MB/s eta 0:00:00 + + + Downloading boto3-1.26.78-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 21.0 MB/s eta 0:00:00 + + + Downloading boto3-1.26.77-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.76-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.0 MB/s eta 0:00:00 + + + Downloading boto3-1.26.75-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.6 MB/s eta 0:00:00 + + + Downloading boto3-1.26.74-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.5 MB/s eta 0:00:00 + + + Downloading boto3-1.26.73-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.72-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 21.5 MB/s eta 0:00:00 + + + Downloading boto3-1.26.71-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 21.0 MB/s eta 0:00:00 + + + Downloading boto3-1.26.70-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.0 MB/s eta 0:00:00 + + + Downloading boto3-1.26.69-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 21.0 MB/s eta 0:00:00 + + + Downloading boto3-1.26.68-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.67-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.8 MB/s eta 0:00:00 + + + Downloading boto3-1.26.66-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.8 MB/s eta 0:00:00 + + + Downloading boto3-1.26.65-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.4 MB/s eta 0:00:00 + + + Downloading boto3-1.26.64-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.63-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.4 MB/s eta 0:00:00 + + + Downloading boto3-1.26.62-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.6 MB/s eta 0:00:00 + + + Downloading boto3-1.26.61-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.3 MB/s eta 0:00:00 + + + Downloading boto3-1.26.60-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.9 MB/s eta 0:00:00 + + + Downloading boto3-1.26.59-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.4 MB/s eta 0:00:00 + + + Downloading boto3-1.26.58-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.8 MB/s eta 0:00:00 + + + Downloading boto3-1.26.57-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.8 MB/s eta 0:00:00 + + + Downloading boto3-1.26.56-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.6 MB/s eta 0:00:00 + + + Downloading boto3-1.26.55-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.9 MB/s eta 0:00:00 + + + Downloading boto3-1.26.54-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.53-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.8 MB/s eta 0:00:00 + + + Downloading boto3-1.26.52-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.1 MB/s eta 0:00:00 + + + Downloading boto3-1.26.51-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.1 MB/s eta 0:00:00 + + + Downloading boto3-1.26.50-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 17.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.49-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.1 MB/s eta 0:00:00 + + + Downloading boto3-1.26.48-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.3 MB/s eta 0:00:00 + + + Downloading boto3-1.26.47-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.6 MB/s eta 0:00:00 + + + Downloading boto3-1.26.46-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.45-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.3 MB/s eta 0:00:00 + + + Downloading boto3-1.26.44-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.43-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.9 MB/s eta 0:00:00 + + + Downloading boto3-1.26.42-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.41-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.40-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.6 MB/s eta 0:00:00 + + + Downloading boto3-1.26.39-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.6 MB/s eta 0:00:00 + + + Downloading boto3-1.26.38-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 21.5 MB/s eta 0:00:00 + + + Downloading boto3-1.26.37-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 21.6 MB/s eta 0:00:00 + + + Downloading boto3-1.26.36-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.5 MB/s eta 0:00:00 + + + Downloading boto3-1.26.35-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.4 MB/s eta 0:00:00 + + + Downloading boto3-1.26.34-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.1 MB/s eta 0:00:00 + + + Downloading boto3-1.26.33-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.1 MB/s eta 0:00:00 + + + Downloading boto3-1.26.32-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.5 MB/s eta 0:00:00 + + + Downloading boto3-1.26.31-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 19.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.30-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 18.9 MB/s eta 0:00:00 + + + Downloading boto3-1.26.29-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 19.0 MB/s eta 0:00:00 + + + Downloading boto3-1.26.28-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 19.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.27-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 18.6 MB/s eta 0:00:00 + + + Downloading boto3-1.26.26-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 19.6 MB/s eta 0:00:00 + + + Downloading boto3-1.26.25-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 19.0 MB/s eta 0:00:00 + + + Downloading boto3-1.26.24-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 20.3 MB/s eta 0:00:00 + + + Downloading boto3-1.26.23-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 21.6 MB/s eta 0:00:00 + + + Downloading boto3-1.26.22-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 20.3 MB/s eta 0:00:00 + + + Downloading boto3-1.26.21-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 19.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.20-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 18.9 MB/s eta 0:00:00 + + + Downloading boto3-1.26.19-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 19.1 MB/s eta 0:00:00 + + + Downloading boto3-1.26.18-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 20.1 MB/s eta 0:00:00 + + + Downloading boto3-1.26.17-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 21.1 MB/s eta 0:00:00 + + + Downloading boto3-1.26.16-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 21.5 MB/s eta 0:00:00 + + + Downloading boto3-1.26.15-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.1 MB/s eta 0:00:00 + + + Downloading boto3-1.26.14-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.4 MB/s eta 0:00:00 + + + Downloading boto3-1.26.13-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.4 MB/s eta 0:00:00 + + + Downloading boto3-1.26.12-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.0 MB/s eta 0:00:00 + + + Downloading boto3-1.26.11-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.4 MB/s eta 0:00:00 + + + Downloading boto3-1.26.10-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.9-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.3 MB/s eta 0:00:00 + + + Downloading boto3-1.26.8-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.6 MB/s eta 0:00:00 + + + Downloading boto3-1.26.7-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.3 MB/s eta 0:00:00 + + + Downloading boto3-1.26.6-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.1 MB/s eta 0:00:00 + + + Downloading boto3-1.26.5-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.6 MB/s eta 0:00:00 + + + Downloading boto3-1.26.4-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.8 MB/s eta 0:00:00 + + + Downloading boto3-1.26.3-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.3 MB/s eta 0:00:00 + + + Downloading boto3-1.26.2-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.3 MB/s eta 0:00:00 + + + Downloading boto3-1.26.1-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.0-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.9 MB/s eta 0:00:00 + + + Downloading boto3-1.25.5-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.3 MB/s eta 0:00:00 + + + Downloading boto3-1.25.4-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.3 MB/s eta 0:00:00 + + + Downloading boto3-1.25.3-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 11.4 MB/s eta 0:00:00 + + + Downloading boto3-1.25.2-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.7 MB/s eta 0:00:00 + + + Downloading boto3-1.25.1-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.9 MB/s eta 0:00:00 + + + Downloading boto3-1.25.0-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 21.3 MB/s eta 0:00:00 + + + Downloading boto3-1.24.96-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.2 MB/s eta 0:00:00 + + + Downloading boto3-1.24.95-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.3 MB/s eta 0:00:00 + + + Downloading boto3-1.24.94-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.3 MB/s eta 0:00:00 + + + Downloading boto3-1.24.93-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.6 MB/s eta 0:00:00 + + + Downloading boto3-1.24.92-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.7 MB/s eta 0:00:00 + + + Downloading boto3-1.24.91-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.9 MB/s eta 0:00:00 + + + Downloading boto3-1.24.90-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.5 MB/s eta 0:00:00 + + + Downloading boto3-1.24.89-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.1 MB/s eta 0:00:00 + + + Downloading boto3-1.24.88-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.0 MB/s eta 0:00:00 + + + Downloading boto3-1.24.87-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.0 MB/s eta 0:00:00 + + + Downloading boto3-1.24.86-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.3 MB/s eta 0:00:00 + + + Downloading boto3-1.24.85-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.4 MB/s eta 0:00:00 + + + Downloading boto3-1.24.84-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.6 MB/s eta 0:00:00 + + + Downloading boto3-1.24.83-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.6 MB/s eta 0:00:00 + + + Downloading boto3-1.24.82-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.6 MB/s eta 0:00:00 + + + Downloading boto3-1.24.81-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.1 MB/s eta 0:00:00 + + + Downloading boto3-1.24.80-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.6 MB/s eta 0:00:00 + + + Downloading boto3-1.24.79-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.3 MB/s eta 0:00:00 + + + Downloading boto3-1.24.78-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.0 MB/s eta 0:00:00 + + + Downloading boto3-1.24.77-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.1 MB/s eta 0:00:00 + + + Downloading boto3-1.24.76-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 13.1 MB/s eta 0:00:00 + + + Downloading boto3-1.24.75-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.9 MB/s eta 0:00:00 + + + Downloading boto3-1.24.74-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.2 MB/s eta 0:00:00 + + + Downloading boto3-1.24.73-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.6 MB/s eta 0:00:00 + + + Downloading boto3-1.24.72-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.2 MB/s eta 0:00:00 + + + Downloading boto3-1.24.71-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.6 MB/s eta 0:00:00 + + + Downloading boto3-1.24.70-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.4 MB/s eta 0:00:00 + + + Downloading boto3-1.24.69-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.4 MB/s eta 0:00:00 + + + Downloading boto3-1.24.68-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.3 MB/s eta 0:00:00 + + + Downloading boto3-1.24.67-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.1 MB/s eta 0:00:00 + + + Downloading boto3-1.24.66-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.5 MB/s eta 0:00:00 + + + Downloading boto3-1.24.65-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.7 MB/s eta 0:00:00 + + + Downloading boto3-1.24.64-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 21.3 MB/s eta 0:00:00 + + + Downloading boto3-1.24.63-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.9 MB/s eta 0:00:00 + + + Downloading boto3-1.24.62-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.6 MB/s eta 0:00:00 + + + Downloading boto3-1.24.61-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.7 MB/s eta 0:00:00 + + + Downloading boto3-1.24.60-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.3 MB/s eta 0:00:00 + + + Downloading boto3-1.24.59-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.1 MB/s eta 0:00:00 + + + Downloading boto3-1.24.58-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.4 MB/s eta 0:00:00 + + + Downloading boto3-1.24.57-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.1 MB/s eta 0:00:00 + + + Downloading boto3-1.24.56-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 21.0 MB/s eta 0:00:00 + + + Downloading boto3-1.24.55-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.3 MB/s eta 0:00:00 + + + Downloading boto3-1.24.54-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.3 MB/s eta 0:00:00 + + + Downloading boto3-1.24.53-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.0 MB/s eta 0:00:00 + + + Downloading boto3-1.24.52-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.4 MB/s eta 0:00:00 + + + Downloading boto3-1.24.51-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 21.5 MB/s eta 0:00:00 + + + Downloading boto3-1.24.50-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.7 MB/s eta 0:00:00 + + + Downloading boto3-1.24.49-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.2 MB/s eta 0:00:00 + + + Downloading boto3-1.24.48-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.8 MB/s eta 0:00:00 + + + Downloading boto3-1.24.47-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.7 MB/s eta 0:00:00 + + + Downloading boto3-1.24.46-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.7 MB/s eta 0:00:00 + + + Downloading boto3-1.24.45-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.3 MB/s eta 0:00:00 + + + Downloading boto3-1.24.44-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.1 MB/s eta 0:00:00 + + + Downloading boto3-1.24.43-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.0 MB/s eta 0:00:00 + + + Downloading boto3-1.24.42-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.8 MB/s eta 0:00:00 + + + Downloading boto3-1.24.41-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 9.5 MB/s eta 0:00:00 + + + Downloading boto3-1.24.40-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.3 MB/s eta 0:00:00 + + + Downloading boto3-1.24.39-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.0 MB/s eta 0:00:00 + + + Downloading boto3-1.24.38-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.0 MB/s eta 0:00:00 + + + Downloading boto3-1.24.37-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.0 MB/s eta 0:00:00 + + + Downloading boto3-1.24.36-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.6 MB/s eta 0:00:00 + + + Downloading boto3-1.24.35-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.2 MB/s eta 0:00:00 + + + Downloading boto3-1.24.34-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.4 MB/s eta 0:00:00 + + + Downloading boto3-1.24.33-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.5 MB/s eta 0:00:00 + + + Downloading boto3-1.24.32-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.6 MB/s eta 0:00:00 + + + Downloading boto3-1.24.31-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.4 MB/s eta 0:00:00 + + + Downloading boto3-1.24.30-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.8 MB/s eta 0:00:00 + + + Downloading boto3-1.24.29-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.6 MB/s eta 0:00:00 + + + Downloading boto3-1.24.28-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.8 MB/s eta 0:00:00 + + + Downloading boto3-1.24.27-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 21.3 MB/s eta 0:00:00 + + + Downloading boto3-1.24.26-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.7 MB/s eta 0:00:00 + + + Downloading boto3-1.24.25-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.3 MB/s eta 0:00:00 + + + Downloading boto3-1.24.24-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.9 MB/s eta 0:00:00 + + + Downloading boto3-1.24.23-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.4 MB/s eta 0:00:00 + + + Downloading boto3-1.24.22-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.3 MB/s eta 0:00:00 + + +Collecting websocket-client>=0.32.0 (from docker>=5.0->latch) + + Downloading websocket_client-1.5.2-py3-none-any.whl (56 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 56.6/56.6 kB 9.0 MB/s eta 0:00:00 + + +Requirement already satisfied: certifi>=14.05.14 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from kubernetes>=24.2.0->latch) (2023.5.7) + +Collecting google-auth>=1.0.1 (from kubernetes>=24.2.0->latch) + + Downloading google_auth-2.18.1-py2.py3-none-any.whl (178 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 178.9/178.9 kB 24.9 MB/s eta 0:00:00 + + +Collecting requests-oauthlib (from kubernetes>=24.2.0->latch) + + Downloading requests_oauthlib-1.3.1-py2.py3-none-any.whl (23 kB) + +Collecting bcrypt>=3.2 (from paramiko>=2.11.0->latch) + + Downloading bcrypt-4.0.1-cp36-abi3-manylinux_2_28_x86_64.whl (593 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 593.7/593.7 kB 54.4 MB/s eta 0:00:00 + + +Collecting pynacl>=1.5 (from paramiko>=2.11.0->latch) + + Downloading PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl (856 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 856.7/856.7 kB 67.4 MB/s eta 0:00:00 + + +Requirement already satisfied: charset-normalizer<4,>=2 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from requests>=2.28.1->latch) (3.1.0) + +Requirement already satisfied: idna<4,>=2.5 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from requests>=2.28.1->latch) (3.4) + +Collecting sniffio>=1.1 (from anyio>=3.0.0->watchfiles==0.18.1->latch) + + Downloading sniffio-1.3.0-py3-none-any.whl (10 kB) + +Collecting binaryornot>=0.4.4 (from cookiecutter>=1.7.3->lytekit==0.14.10->latch) + + Downloading binaryornot-0.4.4-py2.py3-none-any.whl (9.0 kB) + +Requirement already satisfied: Jinja2<4.0.0,>=2.7 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from cookiecutter>=1.7.3->lytekit==0.14.10->latch) (3.1.2) + +Collecting jinja2-time>=0.2.0 (from cookiecutter>=1.7.3->lytekit==0.14.10->latch) + + Downloading jinja2_time-0.2.0-py2.py3-none-any.whl (6.4 kB) + +Collecting python-slugify>=4.0.0 (from cookiecutter>=1.7.3->lytekit==0.14.10->latch) + + Downloading python_slugify-8.0.1-py2.py3-none-any.whl (9.7 kB) + +Requirement already satisfied: cffi>=1.12 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from cryptography>=3.1->asyncssh==2.12.0->latch) (1.15.1) + +Collecting marshmallow<4.0.0,>=3.3.0 (from dataclasses-json>=0.5.2->lytekit==0.14.10->latch) + + Downloading marshmallow-3.19.0-py3-none-any.whl (49 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 49.1/49.1 kB 7.9 MB/s eta 0:00:00 + + +Collecting marshmallow-enum<2.0.0,>=1.5.1 (from dataclasses-json>=0.5.2->lytekit==0.14.10->latch) + + Downloading marshmallow_enum-1.5.1-py2.py3-none-any.whl (4.2 kB) + +Collecting typing-inspect>=0.4.0 (from dataclasses-json>=0.5.2->lytekit==0.14.10->latch) + + Downloading typing_inspect-0.8.0-py3-none-any.whl (8.7 kB) + +Collecting regex>=2019.4.14 (from docker-image-py>=0.1.10->lytekit==0.14.10->latch) + + Downloading regex-2023.5.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (769 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 769.7/769.7 kB 62.7 MB/s eta 0:00:00 + + +Collecting cachetools<6.0,>=2.0.0 (from google-auth>=1.0.1->kubernetes>=24.2.0->latch) + + Downloading cachetools-5.3.0-py3-none-any.whl (9.3 kB) + +Collecting pyasn1-modules>=0.2.1 (from google-auth>=1.0.1->kubernetes>=24.2.0->latch) + + Downloading pyasn1_modules-0.3.0-py2.py3-none-any.whl (181 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 181.3/181.3 kB 26.0 MB/s eta 0:00:00 + + +INFO: pip is looking at multiple versions of grpcio-status to determine which version is compatible with other requirements. This could take a while. + +Collecting grpcio-status!=1.45.0,>=1.43 (from lytekit==0.14.10->latch) + + Downloading grpcio_status-1.54.0-py3-none-any.whl (5.1 kB) + + Downloading grpcio_status-1.53.1-py3-none-any.whl (5.1 kB) + + Downloading grpcio_status-1.53.0-py3-none-any.whl (5.1 kB) + + Downloading grpcio_status-1.51.3-py3-none-any.whl (5.1 kB) + + Downloading grpcio_status-1.51.1-py3-none-any.whl (5.1 kB) + + Downloading grpcio_status-1.50.0-py3-none-any.whl (14 kB) + + Downloading grpcio_status-1.49.1-py3-none-any.whl (14 kB) + +INFO: pip is looking at multiple versions of grpcio-status to determine which version is compatible with other requirements. This could take a while. + + Downloading grpcio_status-1.48.2-py3-none-any.whl (14 kB) + +Requirement already satisfied: attrs>=17.4.0 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from jsonschema>=4.5.1->lytekit==0.14.10->latch) (23.1.0) + +Requirement already satisfied: pyrsistent!=0.17.0,!=0.17.1,!=0.17.2,>=0.14.0 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from jsonschema>=4.5.1->lytekit==0.14.10->latch) (0.19.3) + +Collecting jaraco.classes (from keyring>=18.0.1->lytekit==0.14.10->latch) + + Downloading jaraco.classes-3.2.3-py3-none-any.whl (6.0 kB) + +Requirement already satisfied: importlib-metadata>=4.11.4 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from keyring>=18.0.1->lytekit==0.14.10->latch) (6.6.0) + +Collecting SecretStorage>=3.2 (from keyring>=18.0.1->lytekit==0.14.10->latch) + + Downloading SecretStorage-3.3.3-py3-none-any.whl (15 kB) + +Collecting jeepney>=0.4.2 (from keyring>=18.0.1->lytekit==0.14.10->latch) + + Downloading jeepney-0.8.0-py3-none-any.whl (48 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 48.4/48.4 kB 7.6 MB/s eta 0:00:00 + + +Collecting types-PyYAML (from responses>=0.10.7->lytekit==0.14.10->latch) + + Downloading types_PyYAML-6.0.12.9-py3-none-any.whl (14 kB) + +Collecting pyasn1>=0.1.3 (from rsa<4.8,>=3.1.2->awscli==1.25.22->latch) + + Using cached pyasn1-0.5.0-py2.py3-none-any.whl (83 kB) + +Collecting multidict>=4.0 (from yarl<2.0,>=1.6->gql==3.4.0->latch) + + Downloading multidict-6.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (114 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 114.5/114.5 kB 16.9 MB/s eta 0:00:00 + + +Collecting oauthlib>=3.0.0 (from requests-oauthlib->kubernetes>=24.2.0->latch) + + Downloading oauthlib-3.2.2-py3-none-any.whl (151 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 151.7/151.7 kB 22.3 MB/s eta 0:00:00 + + +Collecting chardet>=3.0.2 (from binaryornot>=0.4.4->cookiecutter>=1.7.3->lytekit==0.14.10->latch) + + Downloading chardet-5.1.0-py3-none-any.whl (199 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 199.1/199.1 kB 28.4 MB/s eta 0:00:00 + + +Requirement already satisfied: pycparser in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from cffi>=1.12->cryptography>=3.1->asyncssh==2.12.0->latch) (2.21) + +Requirement already satisfied: zipp>=0.5 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from importlib-metadata>=4.11.4->keyring>=18.0.1->lytekit==0.14.10->latch) (3.15.0) + +Requirement already satisfied: MarkupSafe>=2.0 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from Jinja2<4.0.0,>=2.7->cookiecutter>=1.7.3->lytekit==0.14.10->latch) (2.1.2) + +Collecting arrow (from jinja2-time>=0.2.0->cookiecutter>=1.7.3->lytekit==0.14.10->latch) + + Downloading arrow-1.2.3-py3-none-any.whl (66 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 66.4/66.4 kB 11.5 MB/s eta 0:00:00 + + +Requirement already satisfied: packaging>=17.0 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from marshmallow<4.0.0,>=3.3.0->dataclasses-json>=0.5.2->lytekit==0.14.10->latch) (23.1) + +Collecting text-unidecode>=1.3 (from python-slugify>=4.0.0->cookiecutter>=1.7.3->lytekit==0.14.10->latch) + + Downloading text_unidecode-1.3-py2.py3-none-any.whl (78 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 78.2/78.2 kB 13.0 MB/s eta 0:00:00 + + +Collecting mypy-extensions>=0.3.0 (from typing-inspect>=0.4.0->dataclasses-json>=0.5.2->lytekit==0.14.10->latch) + + Downloading mypy_extensions-1.0.0-py3-none-any.whl (4.7 kB) + +Collecting more-itertools (from jaraco.classes->keyring>=18.0.1->lytekit==0.14.10->latch) + + Downloading more_itertools-9.1.0-py3-none-any.whl (54 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 54.2/54.2 kB 9.2 MB/s eta 0:00:00 + + +WARNING: The candidate selected for download or install is a yanked version: 'apscheduler' candidate (version 3.9.1 at https://files.pythonhosted.org/packages/e4/9f/c3937d4babe62504b874d4bf2c0d85aa69c7f59fa84cf6050f3b9dc5d83e/APScheduler-3.9.1-py2.py3-none-any.whl (from https://pypi.org/simple/apscheduler/) (requires-python:>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4)) +Reason for being yanked: Not compatible with Python 2.7 + +Building wheels for collected packages: docker-image-py, PyYAML + + Building wheel for docker-image-py (setup.py): started + + Building wheel for docker-image-py (setup.py): finished with status 'done' + + Created wheel for docker-image-py: filename=docker_image_py-0.1.12-py3-none-any.whl size=8812 sha256=93f4864d5ecf3e832cba553638eb71bbc1a0f5f4f31a779334241dcdecafb163 + + Stored in directory: /root/.cache/pip/wheels/fb/45/02/503244da15fbcecde5c3edabb744ed0c4f9a7643126b2d222c + + Building wheel for PyYAML (pyproject.toml): started + + Building wheel for PyYAML (pyproject.toml): finished with status 'done' + + Created wheel for PyYAML: filename=PyYAML-5.4.1-cp310-cp310-linux_x86_64.whl size=141558 sha256=9ab4cce95121a88969a26fe93edc3bdaba68290248a821377df0b3f1da06d102 + + Stored in directory: /root/.cache/pip/wheels/c7/0d/22/696ee92245ad710f506eee79bb05c740d8abccd3ecdb778683 + +Successfully built docker-image-py PyYAML + +Installing collected packages: wcwidth, types-PyYAML, text-unidecode, statsd, sortedcontainers, pytz, pytimeparse, websockets, websocket-client, uvloop, tzlocal, tqdm, sniffio, regex, PyYAML, python-slugify, python-json-logger, pyjwt, pyasn1, py, protobuf, prompt-toolkit, oauthlib, numpy, natsort, mypy-extensions, multidict, more-itertools, marshmallow, jmespath, jeepney, grpcio, graphql-core, docutils, docstring-parser, diskcache, deprecated, decorator, colorama, cloudpickle, click, chardet, cachetools, bcrypt, backoff, aioconsole, yarl, typing-inspect, rsa, retry, responses, requests-toolbelt, requests-oauthlib, pynacl, pyasn1-modules, pyarrow, protoc-gen-swagger, pandas, marshmallow-jsonschema, marshmallow-enum, jaraco.classes, googleapis-common-protos, docker-image-py, docker, croniter, botocore, binaryornot, arrow, apscheduler, anyio, watchfiles, SecretStorage, s3transfer, paramiko, lyteidl, jinja2-time, grpcio-status, gql, google-auth, dataclasses-json, asyncssh, scp, kubernetes, keyring, cookiecutter, boto3, awscli, lytekit, lytekitplugins-pods, latch + + Attempting uninstall: PyYAML + + Found existing installation: PyYAML 6.0 + + Uninstalling PyYAML-6.0: + + Successfully uninstalled PyYAML-6.0 + + Attempting uninstall: numpy + + Found existing installation: numpy 1.24.3 + + Uninstalling numpy-1.24.3: + + Successfully uninstalled numpy-1.24.3 + + Attempting uninstall: docutils + + Found existing installation: docutils 0.20.1 + + Uninstalling docutils-0.20.1: + + Successfully uninstalled docutils-0.20.1 + +ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts. +yte 1.5.1 requires pyyaml<7.0,>=6.0, but you have pyyaml 5.4.1 which is incompatible. + +Successfully installed PyYAML-5.4.1 SecretStorage-3.3.3 aioconsole-0.5.1 anyio-3.6.2 apscheduler-3.9.1 arrow-1.2.3 asyncssh-2.12.0 awscli-1.25.22 backoff-2.2.1 bcrypt-4.0.1 binaryornot-0.4.4 boto3-1.24.22 botocore-1.27.22 cachetools-5.3.0 chardet-5.1.0 click-8.1.3 cloudpickle-2.2.1 colorama-0.4.4 cookiecutter-2.1.1 croniter-1.3.14 dataclasses-json-0.5.7 decorator-5.1.1 deprecated-1.2.13 diskcache-5.6.1 docker-5.0.3 docker-image-py-0.1.12 docstring-parser-0.15 docutils-0.16 google-auth-2.18.1 googleapis-common-protos-1.59.0 gql-3.4.0 graphql-core-3.2.3 grpcio-1.54.2 grpcio-status-1.48.2 jaraco.classes-3.2.3 jeepney-0.8.0 jinja2-time-0.2.0 jmespath-1.0.1 keyring-23.13.1 kubernetes-26.1.0 latch-2.19.11 lyteidl-0.2.0a0 lytekit-0.14.10 lytekitplugins-pods-0.4.0 marshmallow-3.19.0 marshmallow-enum-1.5.1 marshmallow-jsonschema-0.13.0 more-itertools-9.1.0 multidict-6.0.4 mypy-extensions-1.0.0 natsort-8.3.1 numpy-1.21.6 oauthlib-3.2.2 pandas-1.5.3 paramiko-3.1.0 prompt-toolkit-3.0.33 protobuf-3.20.3 protoc-gen-swagger-0.1.0 py-1.11.0 pyarrow-6.0.1 pyasn1-0.5.0 pyasn1-modules-0.3.0 pyjwt-2.7.0 pynacl-1.5.0 python-json-logger-2.0.7 python-slugify-8.0.1 pytimeparse-1.1.8 pytz-2023.3 regex-2023.5.5 requests-oauthlib-1.3.1 requests-toolbelt-0.10.1 responses-0.23.1 retry-0.9.2 rsa-4.7.2 s3transfer-0.6.1 scp-0.14.5 sniffio-1.3.0 sortedcontainers-2.4.0 statsd-3.3.0 text-unidecode-1.3 tqdm-4.65.0 types-PyYAML-6.0.12.9 typing-inspect-0.8.0 tzlocal-5.0.1 uvloop-0.17.0 watchfiles-0.18.1 wcwidth-0.2.6 websocket-client-1.5.2 websockets-10.3 yarl-1.9.2 + +WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv + + ---> ffa1fac95dd6 + +Step 8/15 : copy Snakefile config.yaml /root/ + + + ---> a58a3f610970 + +Step 9/15 : copy scripts/plot-quals.py /root/scripts/plot-quals.py + + + ---> 9fd8716c7a1e + +Step 10/15 : copy .latch/latch_entrypoint.py /root/latch_entrypoint.py + + + ---> b09ea9d0c599 + +Step 11/15 : arg tag + + + ---> Running in f3c75e94104c + + ---> 2755cc88c429 + +Step 12/15 : env FLYTE_INTERNAL_IMAGE $tag + + + ---> Running in d86eea5f113a + + ---> 686cc29564c2 + +Step 13/15 : env LATCH_SDK_DOMAIN "ligma.ai" + + + ---> Running in 8993581c5d61 + + ---> c6ba5312e42f + +Step 14/15 : env LATCH_AUTHENTICATION_ENDPOINT https://nucleus.ligma.ai + + + ---> Running in dd29a31f7c0c + + ---> 3475adc97799 + +Step 15/15 : workdir /root + + + ---> Running in 99d0cec86fe9 + + ---> ef73abcf99bc + +Successfully built ef73abcf99bc + +Successfully tagged 812206152185.dkr.ecr.us-west-2.amazonaws.com/x1_test_latch_register:0.0.0-a00131 + diff --git a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-a98450/docker-build-logs.txt b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-a98450/docker-build-logs.txt new file mode 100644 index 00000000..be6a3c99 --- /dev/null +++ b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-a98450/docker-build-logs.txt @@ -0,0 +1,100 @@ +Step 1/14 : from 812206152185.dkr.ecr.us-west-2.amazonaws.com/latch-base:b733-kenny--snakemake + + + ---> 77471241d7a3 + +Step 2/14 : run mkdir /opt/latch + + + ---> Using cache + + ---> 6d1d7399ec34 + +Step 3/14 : RUN curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh && mkdir /root/.conda && bash Mambaforge-Linux-x86_64.sh -b && rm -f Mambaforge-Linux-x86_64.sh + + + ---> Using cache + + ---> e5d7f1c377ad + +Step 4/14 : copy environment.yaml /root/environment.yaml + + + ---> Using cache + + ---> f1895bb6bb01 + +Step 5/14 : run /root/mambaforge/bin/mamba env create --name snakemake-tutorial --file environment.yaml + + + ---> Using cache + + ---> 1c115b179fb8 + +Step 6/14 : env PATH /root/mambaforge/envs/snakemake-tutorial/bin:$PATH + + + ---> Using cache + + ---> 38bcbc3eaccf + +Step 7/14 : copy latch /root/latch + + + ---> Using cache + + ---> ba86df280c15 + +Step 8/14 : run cd /root/latch && python3 -m pip install -e . + + + ---> Using cache + + ---> e6903b7577c6 + +Step 9/14 : copy Snakefile config.yaml /root/ + + + ---> Using cache + + ---> 93c3fe88c890 + +Step 10/14 : copy scripts/plot-quals.py /root/scripts/plot-quals.py + + + ---> Using cache + + ---> b476a36f6f9c + +Step 11/14 : copy .latch/latch_entrypoint.py /root/latch_entrypoint.py + + + ---> Using cache + + ---> 75cead0538d5 + +Step 12/14 : arg tag + + + ---> Using cache + + ---> 9d8c1d4b5439 + +Step 13/14 : env FLYTE_INTERNAL_IMAGE $tag + + + ---> Running in ec0261fc5544 + + ---> 10c776472c10 + +Step 14/14 : workdir /root + + + ---> Running in f4346ef370f3 + + ---> 068eab68ef5b + +Successfully built 068eab68ef5b + +Successfully tagged 812206152185.dkr.ecr.us-west-2.amazonaws.com/x1_test_latch_register:0.0.0-a98450 + diff --git a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-b1b9b5/docker-build-logs.txt b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-b1b9b5/docker-build-logs.txt new file mode 100644 index 00000000..d3f998d6 --- /dev/null +++ b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-b1b9b5/docker-build-logs.txt @@ -0,0 +1,105 @@ +Step 1/15 : from 812206152185.dkr.ecr.us-west-2.amazonaws.com/latch-base:9c8f-main + + + ---> b253e8cdab51 + +Step 2/15 : run mkdir /opt/latch + + + ---> Using cache + + ---> 89e0ab657f0d + +Step 3/15 : RUN curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh && mkdir /root/.conda && bash Mambaforge-Linux-x86_64.sh -b && rm -f Mambaforge-Linux-x86_64.sh + + + ---> Using cache + + ---> 7741d9d31977 + +Step 4/15 : copy environment.yaml /root/environment.yaml + + + ---> Using cache + + ---> c2d3f498d2d5 + +Step 5/15 : run /root/mambaforge/bin/mamba env create --name snakemake-tutorial --file environment.yaml + + + ---> Using cache + + ---> 0370179f98b9 + +Step 6/15 : env PATH /root/mambaforge/envs/snakemake-tutorial/bin:$PATH + + + ---> Using cache + + ---> 558ea5988368 + +Step 7/15 : run python3 -m pip install latch + + + ---> Using cache + + ---> 73f3b443e340 + +Step 8/15 : copy Snakefile config.yaml /root/ + + + ---> Using cache + + ---> da1c8fa40657 + +Step 9/15 : copy scripts/plot-quals.py /root/scripts/plot-quals.py + + + ---> Using cache + + ---> 6e0a5622727c + +Step 10/15 : copy .latch/latch_entrypoint.py /root/latch_entrypoint.py + + + ---> 2c641c26711a + +Step 11/15 : arg tag + + + ---> Running in 35395e4bff4b + + ---> 6c77e2242b73 + +Step 12/15 : env FLYTE_INTERNAL_IMAGE $tag + + + ---> Running in 75382a292780 + + ---> c2b2d52f48dd + +Step 13/15 : env LATCH_SDK_DOMAIN "ligma.ai" + + + ---> Running in 1eaeb43fcdb6 + + ---> b99ac2abf3bf + +Step 14/15 : env LATCH_AUTHENTICATION_ENDPOINT https://nucleus.ligma.ai + + + ---> Running in 8334c0825385 + + ---> d8f22dea8baa + +Step 15/15 : workdir /root + + + ---> Running in 74f859724d35 + + ---> 957f49e6cff2 + +Successfully built 957f49e6cff2 + +Successfully tagged 812206152185.dkr.ecr.us-west-2.amazonaws.com/x1_test_latch_register:0.0.0-b1b9b5 + diff --git a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-cdb14b/docker-build-logs.txt b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-cdb14b/docker-build-logs.txt new file mode 100644 index 00000000..aedd7386 --- /dev/null +++ b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-cdb14b/docker-build-logs.txt @@ -0,0 +1,2083 @@ +Step 1/14 : from 812206152185.dkr.ecr.us-west-2.amazonaws.com/latch-base:9c8f-main + + + ---> b253e8cdab51 + +Step 2/14 : run mkdir /opt/latch + + + ---> Using cache + + ---> 89e0ab657f0d + +Step 3/14 : RUN curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh && mkdir /root/.conda && bash Mambaforge-Linux-x86_64.sh -b && rm -f Mambaforge-Linux-x86_64.sh + + + ---> Using cache + + ---> 7741d9d31977 + +Step 4/14 : copy environment.yaml /root/environment.yaml + + + ---> c2d3f498d2d5 + +Step 5/14 : run /root/mambaforge/bin/mamba env create --name snakemake-tutorial --file environment.yaml + + + ---> Running in 3f2a1a3e5042 + + + +Looking for: ["snakemake-minimal[version='>=7.3']", 'jinja2', 'matplotlib', 'graphviz', 'bcftools=1.15', 'samtools=1.15', 'bwa=0.7.17', 'pysam=0.19', 'pygments'] + + + +Transaction + + Prefix: /root/mambaforge/envs/snakemake-tutorial + + Updating specs: + + - snakemake-minimal[version='>=7.3'] + - jinja2 + - matplotlib + - graphviz + - bcftools=1.15 + - samtools=1.15 + - bwa=0.7.17 + - pysam=0.19 + - pygments + + + + Package Version Build Channel Size +─────────────────────────────────────────────────────────────────────────────────────────────────── + Install: +─────────────────────────────────────────────────────────────────────────────────────────────────── + + + _libgcc_mutex 0.1 conda_forge conda-forge/linux-64 Cached + + _openmp_mutex 4.5 2_gnu conda-forge/linux-64 Cached + + alsa-lib 1.2.8 h166bdaf_0 conda-forge/linux-64 592kB + + amply 0.1.5 pyhd8ed1ab_0 conda-forge/noarch 21kB + + appdirs 1.4.4 pyh9f0ad1d_0 conda-forge/noarch 13kB + + atk-1.0 2.38.0 hd4edc92_1 conda-forge/linux-64 552kB + + attr 2.5.1 h166bdaf_1 conda-forge/linux-64 71kB + + attrs 23.1.0 pyh71513ae_1 conda-forge/noarch 55kB + + bcftools 1.15.1 hfe4b78e_1 bioconda/linux-64 867kB + + brotli 1.0.9 h166bdaf_8 conda-forge/linux-64 19kB + + brotli-bin 1.0.9 h166bdaf_8 conda-forge/linux-64 20kB + + brotlipy 0.7.0 py310h5764c6d_1005 conda-forge/linux-64 Cached + + bwa 0.7.17 he4a0461_11 bioconda/linux-64 196kB + + bzip2 1.0.8 h7f98852_4 conda-forge/linux-64 Cached + + c-ares 1.19.0 hd590300_0 conda-forge/linux-64 114kB + + ca-certificates 2023.5.7 hbcca054_0 conda-forge/linux-64 148kB + + cairo 1.16.0 ha61ee94_1014 conda-forge/linux-64 2MB + + certifi 2023.5.7 pyhd8ed1ab_0 conda-forge/noarch 152kB + + cffi 1.15.1 py310h255011f_3 conda-forge/linux-64 Cached + + charset-normalizer 3.1.0 pyhd8ed1ab_0 conda-forge/noarch Cached + + coin-or-cbc 2.10.10 h9002f0b_0 conda-forge/linux-64 941kB + + coin-or-cgl 0.60.7 h516709c_0 conda-forge/linux-64 551kB + + coin-or-clp 1.17.8 h1ee7a9c_0 conda-forge/linux-64 1MB + + coin-or-osi 0.108.8 ha2443b9_0 conda-forge/linux-64 389kB + + coin-or-utils 2.11.9 hee58242_0 conda-forge/linux-64 687kB + + coincbc 2.10.10 0_metapackage conda-forge/noarch 12kB + + configargparse 1.5.3 pyhd8ed1ab_0 conda-forge/noarch 33kB + + connection_pool 0.0.3 pyhd3deb0d_0 conda-forge/noarch 8kB + + contourpy 1.0.7 py310hdf3cbec_0 conda-forge/linux-64 216kB + + cryptography 39.0.0 py310h65dfdc0_0 conda-forge/linux-64 1MB + + cycler 0.11.0 pyhd8ed1ab_0 conda-forge/noarch 10kB + + datrie 0.8.2 py310h5764c6d_6 conda-forge/linux-64 148kB + + dbus 1.13.6 h5008d03_3 conda-forge/linux-64 619kB + + docutils 0.20.1 py310hff52083_0 conda-forge/linux-64 721kB + + dpath 2.1.5 pyha770c72_1 conda-forge/noarch 21kB + + expat 2.5.0 hcb278e6_1 conda-forge/linux-64 137kB + + fftw 3.3.10 nompi_hc118613_107 conda-forge/linux-64 2MB + + filelock 3.12.0 pyhd8ed1ab_0 conda-forge/noarch 15kB + + font-ttf-dejavu-sans-mono 2.37 hab24e00_0 conda-forge/noarch 397kB + + font-ttf-inconsolata 3.000 h77eed37_0 conda-forge/noarch 97kB + + font-ttf-source-code-pro 2.038 h77eed37_0 conda-forge/noarch 701kB + + font-ttf-ubuntu 0.83 hab24e00_0 conda-forge/noarch 2MB + + fontconfig 2.14.2 h14ed4e7_0 conda-forge/linux-64 272kB + + fonts-conda-ecosystem 1 0 conda-forge/noarch 4kB + + fonts-conda-forge 1 0 conda-forge/noarch 4kB + + fonttools 4.39.4 py310h2372a71_0 conda-forge/linux-64 2MB + + freetype 2.12.1 hca18f0e_1 conda-forge/linux-64 626kB + + fribidi 1.0.10 h36c2ea0_0 conda-forge/linux-64 114kB + + gdk-pixbuf 2.42.8 hff1cb4f_1 conda-forge/linux-64 612kB + + gettext 0.21.1 h27087fc_0 conda-forge/linux-64 4MB + + giflib 5.2.1 h0b41bf4_3 conda-forge/linux-64 77kB + + gitdb 4.0.10 pyhd8ed1ab_0 conda-forge/noarch 52kB + + gitpython 3.1.31 pyhd8ed1ab_0 conda-forge/noarch 142kB + + glib 2.76.2 hfc55251_0 conda-forge/linux-64 484kB + + glib-tools 2.76.2 hfc55251_0 conda-forge/linux-64 112kB + + graphite2 1.3.13 h58526e2_1001 conda-forge/linux-64 105kB + + graphviz 7.0.5 h2e5815a_0 conda-forge/linux-64 2MB + + gsl 2.7 he838d99_0 conda-forge/linux-64 3MB + + gst-plugins-base 1.21.3 h4243ec0_1 conda-forge/linux-64 3MB + + gstreamer 1.21.3 h25f0c4b_1 conda-forge/linux-64 2MB + + gstreamer-orc 0.4.33 h166bdaf_0 conda-forge/linux-64 306kB + + gtk2 2.24.33 h90689f9_2 conda-forge/linux-64 8MB + + gts 0.7.6 h64030ff_2 conda-forge/linux-64 421kB + + harfbuzz 6.0.0 h8e241bc_0 conda-forge/linux-64 1MB + + htslib 1.16 h6bc39ce_0 bioconda/linux-64 2MB + + humanfriendly 10.0 py310hff52083_4 conda-forge/linux-64 123kB + + icu 70.1 h27087fc_0 conda-forge/linux-64 14MB + + idna 3.4 pyhd8ed1ab_0 conda-forge/noarch Cached + + importlib-metadata 6.6.0 pyha770c72_0 conda-forge/noarch 26kB + + importlib_resources 5.12.0 pyhd8ed1ab_0 conda-forge/noarch 31kB + + jack 1.9.22 h11f4161_0 conda-forge/linux-64 464kB + + jinja2 3.1.2 pyhd8ed1ab_1 conda-forge/noarch 101kB + + jpeg 9e h0b41bf4_3 conda-forge/linux-64 240kB + + jsonschema 4.17.3 pyhd8ed1ab_0 conda-forge/noarch 70kB + + jupyter_core 5.3.0 py310hff52083_0 conda-forge/linux-64 91kB + + keyutils 1.6.1 h166bdaf_0 conda-forge/linux-64 Cached + + kiwisolver 1.4.4 py310hbf28c38_1 conda-forge/linux-64 77kB + + krb5 1.20.1 hf9c8cef_0 conda-forge/linux-64 1MB + + lame 3.100 h166bdaf_1003 conda-forge/linux-64 508kB + + lcms2 2.14 h6ed2654_0 conda-forge/linux-64 262kB + + ld_impl_linux-64 2.40 h41732ed_0 conda-forge/linux-64 Cached + + lerc 4.0.0 h27087fc_0 conda-forge/linux-64 282kB + + libblas 3.9.0 16_linux64_openblas conda-forge/linux-64 13kB + + libbrotlicommon 1.0.9 h166bdaf_8 conda-forge/linux-64 67kB + + libbrotlidec 1.0.9 h166bdaf_8 conda-forge/linux-64 34kB + + libbrotlienc 1.0.9 h166bdaf_8 conda-forge/linux-64 295kB + + libcap 2.66 ha37c62d_0 conda-forge/linux-64 100kB + + libcblas 3.9.0 16_linux64_openblas conda-forge/linux-64 13kB + + libclang 15.0.7 default_h7634d5b_2 conda-forge/linux-64 133kB + + libclang13 15.0.7 default_h9986a30_2 conda-forge/linux-64 10MB + + libcups 2.3.3 h36d4200_3 conda-forge/linux-64 5MB + + libcurl 7.87.0 h6312ad2_0 conda-forge/linux-64 347kB + + libdb 6.2.32 h9c3ff4c_0 conda-forge/linux-64 24MB + + libdeflate 1.13 h166bdaf_0 conda-forge/linux-64 80kB + + libedit 3.1.20191231 he28a2e2_2 conda-forge/linux-64 Cached + + libev 4.33 h516909a_1 conda-forge/linux-64 Cached + + libevent 2.1.10 h9b69904_4 conda-forge/linux-64 1MB + + libexpat 2.5.0 hcb278e6_1 conda-forge/linux-64 78kB + + libffi 3.4.2 h7f98852_5 conda-forge/linux-64 Cached + + libflac 1.4.2 h27087fc_0 conda-forge/linux-64 421kB + + libgcc-ng 12.2.0 h65d4601_19 conda-forge/linux-64 Cached + + libgcrypt 1.10.1 h166bdaf_0 conda-forge/linux-64 720kB + + libgd 2.3.3 h18fbbfe_3 conda-forge/linux-64 272kB + + libgfortran-ng 12.2.0 h69a702a_19 conda-forge/linux-64 23kB + + libgfortran5 12.2.0 h337968e_19 conda-forge/linux-64 2MB + + libglib 2.76.2 hebfc3b9_0 conda-forge/linux-64 3MB + + libgomp 12.2.0 h65d4601_19 conda-forge/linux-64 Cached + + libgpg-error 1.46 h620e276_0 conda-forge/linux-64 258kB + + libiconv 1.17 h166bdaf_0 conda-forge/linux-64 Cached + + liblapack 3.9.0 16_linux64_openblas conda-forge/linux-64 13kB + + liblapacke 3.9.0 16_linux64_openblas conda-forge/linux-64 13kB + + libllvm15 15.0.7 hadd5161_1 conda-forge/linux-64 33MB + + libnghttp2 1.51.0 hdcd2b5c_0 conda-forge/linux-64 623kB + + libnsl 2.0.0 h7f98852_0 conda-forge/linux-64 Cached + + libogg 1.3.4 h7f98852_1 conda-forge/linux-64 211kB + + libopenblas 0.3.21 pthreads_h78a6416_3 conda-forge/linux-64 11MB + + libopus 1.3.1 h7f98852_1 conda-forge/linux-64 261kB + + libpng 1.6.39 h753d276_0 conda-forge/linux-64 283kB + + libpq 15.1 h2baec63_3 conda-forge/linux-64 2MB + + librsvg 2.54.4 h7abd40a_0 conda-forge/linux-64 7MB + + libsndfile 1.2.0 hb75c966_0 conda-forge/linux-64 350kB + + libsqlite 3.42.0 h2797004_0 conda-forge/linux-64 829kB + + libssh2 1.10.0 haa6b8db_3 conda-forge/linux-64 239kB + + libstdcxx-ng 12.2.0 h46fd767_19 conda-forge/linux-64 Cached + + libsystemd0 252 h2a991cd_0 conda-forge/linux-64 393kB + + libtiff 4.4.0 h0e0dad5_3 conda-forge/linux-64 658kB + + libtool 2.4.7 h27087fc_0 conda-forge/linux-64 412kB + + libudev1 253 h0b41bf4_0 conda-forge/linux-64 119kB + + libuuid 2.38.1 h0b41bf4_0 conda-forge/linux-64 Cached + + libvorbis 1.3.7 h9c3ff4c_0 conda-forge/linux-64 286kB + + libwebp 1.2.4 h522a892_0 conda-forge/linux-64 90kB + + libwebp-base 1.2.4 h166bdaf_0 conda-forge/linux-64 413kB + + libxcb 1.13 h7f98852_1004 conda-forge/linux-64 400kB + + libxkbcommon 1.5.0 h79f4944_1 conda-forge/linux-64 563kB + + libxml2 2.10.3 hca2bb57_4 conda-forge/linux-64 714kB + + libzlib 1.2.13 h166bdaf_4 conda-forge/linux-64 Cached + + lz4-c 1.9.4 hcb278e6_0 conda-forge/linux-64 Cached + + markupsafe 2.1.2 py310h1fa729e_0 conda-forge/linux-64 23kB + + matplotlib 3.7.1 py310hff52083_0 conda-forge/linux-64 8kB + + matplotlib-base 3.7.1 py310he60537e_0 conda-forge/linux-64 7MB + + mpg123 1.31.3 hcb278e6_0 conda-forge/linux-64 485kB + + munkres 1.0.7 py_1 bioconda/noarch 10kB + + mysql-common 8.0.32 h14678bc_0 conda-forge/linux-64 803kB + + mysql-libs 8.0.32 h54cf53e_0 conda-forge/linux-64 2MB + + nbformat 5.8.0 pyhd8ed1ab_0 conda-forge/noarch 101kB + + ncurses 6.3 h27087fc_1 conda-forge/linux-64 Cached + + nspr 4.35 h27087fc_0 conda-forge/linux-64 227kB + + nss 3.89 he45b914_0 conda-forge/linux-64 2MB + + numpy 1.24.3 py310ha4c1d20_0 conda-forge/linux-64 7MB + + openjpeg 2.5.0 h7d73246_1 conda-forge/linux-64 546kB + + openssl 1.1.1t h0b41bf4_0 conda-forge/linux-64 2MB + + packaging 23.1 pyhd8ed1ab_0 conda-forge/noarch 46kB + + pango 1.50.14 hd33c08f_0 conda-forge/linux-64 438kB + + pcre2 10.40 hc3806b6_0 conda-forge/linux-64 2MB + + perl 5.32.1 2_h7f98852_perl5 conda-forge/linux-64 15MB + + pillow 9.2.0 py310h454ad03_3 conda-forge/linux-64 47MB + + pip 23.1.2 pyhd8ed1ab_0 conda-forge/noarch 1MB + + pixman 0.40.0 h36c2ea0_0 conda-forge/linux-64 643kB + + pkgutil-resolve-name 1.3.10 pyhd8ed1ab_0 conda-forge/noarch 9kB + + plac 1.3.5 pyhd8ed1ab_0 conda-forge/noarch 23kB + + platformdirs 3.5.1 pyhd8ed1ab_0 conda-forge/noarch 19kB + + ply 3.11 py_1 conda-forge/noarch 45kB + + psutil 5.9.5 py310h1fa729e_0 conda-forge/linux-64 362kB + + pthread-stubs 0.4 h36c2ea0_1001 conda-forge/linux-64 6kB + + pulp 2.7.0 py310hff52083_0 conda-forge/linux-64 141kB + + pulseaudio 16.1 h4ab2085_1 conda-forge/linux-64 2MB + + pycparser 2.21 pyhd8ed1ab_0 conda-forge/noarch Cached + + pygments 2.15.1 pyhd8ed1ab_0 conda-forge/noarch 841kB + + pyopenssl 23.1.1 pyhd8ed1ab_0 conda-forge/noarch Cached + + pyparsing 3.0.9 pyhd8ed1ab_0 conda-forge/noarch 81kB + + pyqt 5.15.7 py310hab646b1_3 conda-forge/linux-64 5MB + + pyqt5-sip 12.11.0 py310heca2aa9_3 conda-forge/linux-64 85kB + + pyrsistent 0.19.3 py310h1fa729e_0 conda-forge/linux-64 100kB + + pysam 0.19.1 py310hff46b53_1 bioconda/linux-64 3MB + + pysocks 1.7.1 pyha2e5f31_6 conda-forge/noarch Cached + + python 3.10.8 h257c98d_0_cpython conda-forge/linux-64 23MB + + python-dateutil 2.8.2 pyhd8ed1ab_0 conda-forge/noarch 246kB + + python-fastjsonschema 2.16.3 pyhd8ed1ab_0 conda-forge/noarch 225kB + + python_abi 3.10 3_cp310 conda-forge/linux-64 Cached + + pyyaml 6.0 py310h5764c6d_5 conda-forge/linux-64 176kB + + qt-main 5.15.6 h18908ee_6 conda-forge/linux-64 55MB + + readline 8.2 h8228510_1 conda-forge/linux-64 Cached + + requests 2.29.0 pyhd8ed1ab_0 conda-forge/noarch 57kB + + reretry 0.11.8 pyhd8ed1ab_0 conda-forge/noarch 12kB + + samtools 1.15.1 h6899075_1 bioconda/linux-64 406kB + + setuptools 67.7.2 pyhd8ed1ab_0 conda-forge/noarch 583kB + + sip 6.7.9 py310hc6cd4ac_0 conda-forge/linux-64 493kB + + six 1.16.0 pyh6c4a22f_0 conda-forge/noarch 14kB + + smart_open 6.3.0 pyhd8ed1ab_1 conda-forge/noarch 47kB + + smmap 3.0.5 pyh44b312d_0 conda-forge/noarch 23kB + + snakemake-minimal 7.25.4 pyhdfd78af_0 bioconda/noarch 266kB + + stopit 1.1.2 py_0 conda-forge/noarch 16kB + + tabulate 0.9.0 pyhd8ed1ab_1 conda-forge/noarch 36kB + + throttler 1.2.1 pyhd8ed1ab_0 conda-forge/noarch 11kB + + tk 8.6.12 h27826a3_0 conda-forge/linux-64 Cached + + toml 0.10.2 pyhd8ed1ab_0 conda-forge/noarch 18kB + + tomli 2.0.1 pyhd8ed1ab_0 conda-forge/noarch 16kB + + toposort 1.10 pyhd8ed1ab_0 conda-forge/noarch 14kB + + tornado 6.3.2 py310h2372a71_0 conda-forge/linux-64 639kB + + traitlets 5.9.0 pyhd8ed1ab_0 conda-forge/noarch 98kB + + typing-extensions 4.5.0 hd8ed1ab_0 conda-forge/noarch 10kB + + typing_extensions 4.5.0 pyha770c72_0 conda-forge/noarch 31kB + + tzdata 2023c h71feb2d_0 conda-forge/noarch Cached + + unicodedata2 15.0.0 py310h5764c6d_0 conda-forge/linux-64 512kB + + urllib3 1.26.15 pyhd8ed1ab_0 conda-forge/noarch Cached + + wheel 0.40.0 pyhd8ed1ab_0 conda-forge/noarch Cached + + wrapt 1.15.0 py310h1fa729e_0 conda-forge/linux-64 54kB + + xcb-util 0.4.0 h516909a_0 conda-forge/linux-64 20kB + + xcb-util-image 0.4.0 h166bdaf_0 conda-forge/linux-64 24kB + + xcb-util-keysyms 0.4.0 h516909a_0 conda-forge/linux-64 12kB + + xcb-util-renderutil 0.3.9 h166bdaf_0 conda-forge/linux-64 16kB + + xcb-util-wm 0.4.1 h516909a_0 conda-forge/linux-64 56kB + + xkeyboard-config 2.38 h0b41bf4_0 conda-forge/linux-64 882kB + + xorg-kbproto 1.0.7 h7f98852_1002 conda-forge/linux-64 27kB + + xorg-libice 1.0.10 h7f98852_0 conda-forge/linux-64 59kB + + xorg-libsm 1.2.3 hd9c2040_1000 conda-forge/linux-64 26kB + + xorg-libx11 1.8.4 h0b41bf4_0 conda-forge/linux-64 830kB + + xorg-libxau 1.0.9 h7f98852_0 conda-forge/linux-64 13kB + + xorg-libxdmcp 1.1.3 h7f98852_0 conda-forge/linux-64 19kB + + xorg-libxext 1.3.4 h0b41bf4_2 conda-forge/linux-64 50kB + + xorg-libxrender 0.9.10 h7f98852_1003 conda-forge/linux-64 33kB + + xorg-renderproto 0.11.1 h7f98852_1002 conda-forge/linux-64 10kB + + xorg-xextproto 7.3.0 h0b41bf4_1003 conda-forge/linux-64 30kB + + xorg-xproto 7.0.31 h7f98852_1007 conda-forge/linux-64 75kB + + xz 5.2.6 h166bdaf_0 conda-forge/linux-64 Cached + + yaml 0.2.5 h7f98852_2 conda-forge/linux-64 89kB + + yte 1.5.1 py310hff52083_1 conda-forge/linux-64 18kB + + zipp 3.15.0 pyhd8ed1ab_0 conda-forge/noarch 17kB + + zlib 1.2.13 h166bdaf_4 conda-forge/linux-64 94kB + + zstd 1.5.2 h3eb15da_6 conda-forge/linux-64 Cached + + Summary: + + Install: 230 packages + + Total download: 357MB + +─────────────────────────────────────────────────────────────────────────────────────────────────── + + + + +Downloading and Extracting Packages + +Preparing transaction: ...working... +done + +Verifying transaction: ...working... +done + +Executing transaction: ...working... + + +done + +# +# To activate this environment, use +# +# $ conda activate snakemake-tutorial +# +# To deactivate an active environment, use +# +# $ conda deactivate + + + ---> 0370179f98b9 + +Step 6/14 : env PATH /root/mambaforge/envs/snakemake-tutorial/bin:$PATH + + + ---> Running in 3e94901f04ce + + ---> 558ea5988368 + +Step 7/14 : run python3 -m pip install latch + + + ---> Running in f3dc76132437 + +Collecting latch + + Downloading latch-2.19.11-py3-none-any.whl (150 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 150.6/150.6 kB 7.0 MB/s eta 0:00:00 + + +Collecting awscli==1.25.22 (from latch) + + Downloading awscli-1.25.22-py3-none-any.whl (3.9 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.9/3.9 MB 59.9 MB/s eta 0:00:00 + + +Collecting asyncssh==2.12.0 (from latch) + + Downloading asyncssh-2.12.0-py3-none-any.whl (346 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 346.7/346.7 kB 35.0 MB/s eta 0:00:00 + + +Collecting aioconsole==0.5.1 (from latch) + + Downloading aioconsole-0.5.1-py3-none-any.whl (30 kB) + +Collecting kubernetes>=24.2.0 (from latch) + + Downloading kubernetes-26.1.0-py2.py3-none-any.whl (1.4 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.4/1.4 MB 64.9 MB/s eta 0:00:00 + + +Collecting pyjwt>=0.2.0 (from latch) + + Downloading PyJWT-2.7.0-py3-none-any.whl (22 kB) + +Requirement already satisfied: requests>=2.28.1 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from latch) (2.29.0) + +Collecting click>=8.0 (from latch) + + Downloading click-8.1.3-py3-none-any.whl (96 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 96.6/96.6 kB 14.5 MB/s eta 0:00:00 + + +Collecting docker>=5.0 (from latch) + + Downloading docker-6.1.2-py3-none-any.whl (148 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 148.1/148.1 kB 20.4 MB/s eta 0:00:00 + + +Collecting paramiko>=2.11.0 (from latch) + + Downloading paramiko-3.1.0-py3-none-any.whl (211 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 211.2/211.2 kB 26.5 MB/s eta 0:00:00 + + +Collecting scp>=0.14.0 (from latch) + + Downloading scp-0.14.5-py2.py3-none-any.whl (8.7 kB) + +Collecting boto3>=1.24.22 (from latch) + + Downloading boto3-1.26.136-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 16.9 MB/s eta 0:00:00 + + +Collecting tqdm>=4.63.0 (from latch) + + Downloading tqdm-4.65.0-py3-none-any.whl (77 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 77.1/77.1 kB 11.3 MB/s eta 0:00:00 + + +Collecting lytekit==0.14.10 (from latch) + + Downloading lytekit-0.14.10-py3-none-any.whl (391 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 391.8/391.8 kB 41.6 MB/s eta 0:00:00 + + +Collecting lytekitplugins-pods==0.4.0 (from latch) + + Downloading lytekitplugins_pods-0.4.0-py3-none-any.whl (4.3 kB) + +Requirement already satisfied: typing-extensions==4.5.0 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from latch) (4.5.0) + +Collecting apscheduler==3.9.1 (from latch) + + Downloading APScheduler-3.9.1-py2.py3-none-any.whl (59 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 59.5/59.5 kB 9.5 MB/s eta 0:00:00 + + +Collecting uvloop==0.17.0 (from latch) + + Downloading uvloop-0.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.1 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.1/4.1 MB 63.5 MB/s eta 0:00:00 + + +Collecting websockets==10.3 (from latch) + + Downloading websockets-10.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (111 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 111.5/111.5 kB 15.6 MB/s eta 0:00:00 + + +Collecting prompt-toolkit==3.0.33 (from latch) + + Downloading prompt_toolkit-3.0.33-py3-none-any.whl (383 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 383.6/383.6 kB 41.3 MB/s eta 0:00:00 + + +Collecting watchfiles==0.18.1 (from latch) + + Downloading watchfiles-0.18.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.2 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.2/1.2 MB 67.5 MB/s eta 0:00:00 + + +Collecting gql==3.4.0 (from latch) + + Downloading gql-3.4.0-py2.py3-none-any.whl (65 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 65.2/65.2 kB 9.6 MB/s eta 0:00:00 + + +Collecting graphql-core==3.2.3 (from latch) + + Downloading graphql_core-3.2.3-py3-none-any.whl (202 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 202.9/202.9 kB 26.3 MB/s eta 0:00:00 + + +Collecting requests-toolbelt==0.10.1 (from latch) + + Downloading requests_toolbelt-0.10.1-py2.py3-none-any.whl (54 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 54.5/54.5 kB 8.8 MB/s eta 0:00:00 + + +Requirement already satisfied: setuptools>=0.7 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from apscheduler==3.9.1->latch) (67.7.2) + +Requirement already satisfied: six>=1.4.0 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from apscheduler==3.9.1->latch) (1.16.0) + +Collecting pytz (from apscheduler==3.9.1->latch) + + Downloading pytz-2023.3-py2.py3-none-any.whl (502 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 502.3/502.3 kB 46.3 MB/s eta 0:00:00 + + +Collecting tzlocal!=3.*,>=2.0 (from apscheduler==3.9.1->latch) + + Downloading tzlocal-5.0.1-py3-none-any.whl (20 kB) + +Requirement already satisfied: cryptography>=3.1 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from asyncssh==2.12.0->latch) (39.0.0) + +Collecting botocore==1.27.22 (from awscli==1.25.22->latch) + + Downloading botocore-1.27.22-py3-none-any.whl (8.9 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.9/8.9 MB 85.4 MB/s eta 0:00:00 + + +Collecting docutils<0.17,>=0.10 (from awscli==1.25.22->latch) + + Using cached docutils-0.16-py2.py3-none-any.whl (548 kB) + +Collecting s3transfer<0.7.0,>=0.6.0 (from awscli==1.25.22->latch) + + Downloading s3transfer-0.6.1-py3-none-any.whl (79 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 79.8/79.8 kB 12.2 MB/s eta 0:00:00 + + +Collecting PyYAML<5.5,>=3.10 (from awscli==1.25.22->latch) + + Downloading PyYAML-5.4.1.tar.gz (175 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 175.1/175.1 kB 23.4 MB/s eta 0:00:00 + + + Installing build dependencies: started + + Installing build dependencies: finished with status 'done' + Getting requirements to build wheel: started + + Getting requirements to build wheel: finished with status 'done' + Preparing metadata (pyproject.toml): started + + Preparing metadata (pyproject.toml): finished with status 'done' + +Collecting colorama<0.4.5,>=0.2.5 (from awscli==1.25.22->latch) + + Using cached colorama-0.4.4-py2.py3-none-any.whl (16 kB) + +Collecting rsa<4.8,>=3.1.2 (from awscli==1.25.22->latch) + + Using cached rsa-4.7.2-py3-none-any.whl (34 kB) + +Collecting yarl<2.0,>=1.6 (from gql==3.4.0->latch) + + Downloading yarl-1.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (268 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 268.8/268.8 kB 32.0 MB/s eta 0:00:00 + + +Collecting backoff<3.0,>=1.11.1 (from gql==3.4.0->latch) + + Downloading backoff-2.2.1-py3-none-any.whl (15 kB) + +Collecting lyteidl==0.2.0a0 (from lytekit==0.14.10->latch) + + Downloading lyteidl-0.2.0a0-py3-none-any.whl (162 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 162.2/162.2 kB 22.7 MB/s eta 0:00:00 + + +Requirement already satisfied: wheel<1.0.0,>=0.30.0 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch) (0.40.0) + +Collecting pandas<2.0.0,>=1.0.0 (from lytekit==0.14.10->latch) + + Downloading pandas-1.5.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (12.1 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 12.1/12.1 MB 79.6 MB/s eta 0:00:00 + + +Collecting pyarrow<7.0.0,>=4.0.0 (from lytekit==0.14.10->latch) + + Downloading pyarrow-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (25.6 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 25.6/25.6 MB 37.9 MB/s eta 0:00:00 + + +Collecting croniter<4.0.0,>=0.3.20 (from lytekit==0.14.10->latch) + + Downloading croniter-1.3.14-py2.py3-none-any.whl (18 kB) + +Collecting deprecated<2.0,>=1.0 (from lytekit==0.14.10->latch) + + Downloading Deprecated-1.2.13-py2.py3-none-any.whl (9.6 kB) + +Collecting docker>=5.0 (from latch) + + Downloading docker-5.0.3-py2.py3-none-any.whl (146 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 146.2/146.2 kB 20.4 MB/s eta 0:00:00 + + +Requirement already satisfied: python-dateutil>=2.1 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch) (2.8.2) + +Collecting grpcio!=1.45.0,<2.0,>=1.43.0 (from lytekit==0.14.10->latch) + + Downloading grpcio-1.54.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.1 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 5.1/5.1 MB 60.8 MB/s eta 0:00:00 + + +Collecting grpcio-status!=1.45.0,>=1.43 (from lytekit==0.14.10->latch) + + Downloading grpcio_status-1.54.2-py3-none-any.whl (5.1 kB) + +Collecting protobuf<4,>=3.6.1 (from lytekit==0.14.10->latch) + + Downloading protobuf-3.20.3-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (1.1 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.1/1.1 MB 56.8 MB/s eta 0:00:00 + + +Collecting python-json-logger>=2.0.0 (from lytekit==0.14.10->latch) + + Downloading python_json_logger-2.0.7-py3-none-any.whl (8.1 kB) + +Collecting pytimeparse<2.0.0,>=1.1.8 (from lytekit==0.14.10->latch) + + Downloading pytimeparse-1.1.8-py2.py3-none-any.whl (10.0 kB) + +Collecting keyring>=18.0.1 (from lytekit==0.14.10->latch) + + Downloading keyring-23.13.1-py3-none-any.whl (37 kB) + +Collecting responses>=0.10.7 (from lytekit==0.14.10->latch) + + Downloading responses-0.23.1-py3-none-any.whl (52 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 52.1/52.1 kB 8.2 MB/s eta 0:00:00 + + +Collecting sortedcontainers<3.0.0,>=1.5.9 (from lytekit==0.14.10->latch) + + Downloading sortedcontainers-2.4.0-py2.py3-none-any.whl (29 kB) + +Collecting statsd<4.0.0,>=3.0.0 (from lytekit==0.14.10->latch) + + Downloading statsd-3.3.0-py2.py3-none-any.whl (11 kB) + +Requirement already satisfied: urllib3<2.0.0,>=1.22 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch) (1.26.15) + +Requirement already satisfied: wrapt<2.0.0,>=1.0.0 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch) (1.15.0) + +Collecting retry==0.9.2 (from lytekit==0.14.10->latch) + + Downloading retry-0.9.2-py2.py3-none-any.whl (8.0 kB) + +Collecting dataclasses-json>=0.5.2 (from lytekit==0.14.10->latch) + + Downloading dataclasses_json-0.5.7-py3-none-any.whl (25 kB) + +Requirement already satisfied: jsonschema>=4.5.1 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch) (4.17.3) + +Collecting marshmallow-jsonschema>=0.12.0 (from lytekit==0.14.10->latch) + + Downloading marshmallow_jsonschema-0.13.0-py3-none-any.whl (11 kB) + +Collecting natsort>=7.0.1 (from lytekit==0.14.10->latch) + + Downloading natsort-8.3.1-py3-none-any.whl (38 kB) + +Collecting docker-image-py>=0.1.10 (from lytekit==0.14.10->latch) + + Downloading docker-image-py-0.1.12.tar.gz (8.2 kB) + + Preparing metadata (setup.py): started + + Preparing metadata (setup.py): finished with status 'done' + +Collecting docstring-parser>=0.9.0 (from lytekit==0.14.10->latch) + + Downloading docstring_parser-0.15-py3-none-any.whl (36 kB) + +Collecting diskcache>=5.2.1 (from lytekit==0.14.10->latch) + + Downloading diskcache-5.6.1-py3-none-any.whl (45 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 45.6/45.6 kB 6.4 MB/s eta 0:00:00 + + +Collecting cloudpickle>=2.0.0 (from lytekit==0.14.10->latch) + + Downloading cloudpickle-2.2.1-py3-none-any.whl (25 kB) + +Collecting cookiecutter>=1.7.3 (from lytekit==0.14.10->latch) + + Downloading cookiecutter-2.1.1-py2.py3-none-any.whl (36 kB) + +Collecting numpy<1.22.0 (from lytekit==0.14.10->latch) + + Downloading numpy-1.21.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (15.9 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 15.9/15.9 MB 57.7 MB/s eta 0:00:00 + + +Collecting wcwidth (from prompt-toolkit==3.0.33->latch) + + Downloading wcwidth-0.2.6-py2.py3-none-any.whl (29 kB) + +Collecting anyio>=3.0.0 (from watchfiles==0.18.1->latch) + + Downloading anyio-3.6.2-py3-none-any.whl (80 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 80.6/80.6 kB 12.7 MB/s eta 0:00:00 + + +Collecting jmespath<2.0.0,>=0.7.1 (from botocore==1.27.22->awscli==1.25.22->latch) + + Using cached jmespath-1.0.1-py3-none-any.whl (20 kB) + +Collecting googleapis-common-protos (from lyteidl==0.2.0a0->lytekit==0.14.10->latch) + + Downloading googleapis_common_protos-1.59.0-py2.py3-none-any.whl (223 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 223.6/223.6 kB 29.0 MB/s eta 0:00:00 + + +Collecting protoc-gen-swagger (from lyteidl==0.2.0a0->lytekit==0.14.10->latch) + + Downloading protoc_gen_swagger-0.1.0-py2.py3-none-any.whl (9.4 kB) + +Collecting decorator>=3.4.2 (from retry==0.9.2->lytekit==0.14.10->latch) + + Downloading decorator-5.1.1-py3-none-any.whl (9.1 kB) + +Collecting py<2.0.0,>=1.4.26 (from retry==0.9.2->lytekit==0.14.10->latch) + + Downloading py-1.11.0-py2.py3-none-any.whl (98 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 98.7/98.7 kB 14.4 MB/s eta 0:00:00 + + +INFO: pip is looking at multiple versions of boto3 to determine which version is compatible with other requirements. This could take a while. + +Collecting boto3>=1.24.22 (from latch) + + Downloading boto3-1.26.135-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.3 MB/s eta 0:00:00 + + + Downloading boto3-1.26.134-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.8 MB/s eta 0:00:00 + + + Downloading boto3-1.26.133-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.132-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.9 MB/s eta 0:00:00 + + + Downloading boto3-1.26.131-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.1 MB/s eta 0:00:00 + + + Downloading boto3-1.26.130-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.0 MB/s eta 0:00:00 + + + Downloading boto3-1.26.129-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.2 MB/s eta 0:00:00 + + +INFO: pip is looking at multiple versions of boto3 to determine which version is compatible with other requirements. This could take a while. + + Downloading boto3-1.26.128-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.6 MB/s eta 0:00:00 + + + Downloading boto3-1.26.127-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.126-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.6 MB/s eta 0:00:00 + + + Downloading boto3-1.26.125-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.9 MB/s eta 0:00:00 + + + Downloading boto3-1.26.124-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.8 MB/s eta 0:00:00 + + +INFO: This is taking longer than usual. You might need to provide the dependency resolver with stricter constraints to reduce runtime. See https://pip.pypa.io/warnings/backtracking for guidance. If you want to abort this run, press Ctrl + C. + + Downloading boto3-1.26.123-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.3 MB/s eta 0:00:00 + + + Downloading boto3-1.26.122-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.6 MB/s eta 0:00:00 + + + Downloading boto3-1.26.121-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 17.6 MB/s eta 0:00:00 + + + Downloading boto3-1.26.120-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.119-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.118-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.9 MB/s eta 0:00:00 + + + Downloading boto3-1.26.117-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.4 MB/s eta 0:00:00 + + + Downloading boto3-1.26.116-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.115-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.114-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 17.4 MB/s eta 0:00:00 + + + Downloading boto3-1.26.113-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 17.9 MB/s eta 0:00:00 + + + Downloading boto3-1.26.112-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.9 MB/s eta 0:00:00 + + + Downloading boto3-1.26.111-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.110-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.109-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.108-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.107-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.4 MB/s eta 0:00:00 + + + Downloading boto3-1.26.106-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.9 MB/s eta 0:00:00 + + + Downloading boto3-1.26.105-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.6 MB/s eta 0:00:00 + + + Downloading boto3-1.26.104-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.0 MB/s eta 0:00:00 + + + Downloading boto3-1.26.103-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.3 MB/s eta 0:00:00 + + + Downloading boto3-1.26.102-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.1 MB/s eta 0:00:00 + + + Downloading boto3-1.26.101-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.5/135.5 kB 17.6 MB/s eta 0:00:00 + + + Downloading boto3-1.26.100-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.5/135.5 kB 16.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.99-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.5/135.5 kB 9.5 MB/s eta 0:00:00 + + + Downloading boto3-1.26.98-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.5/135.5 kB 18.4 MB/s eta 0:00:00 + + + Downloading boto3-1.26.97-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.5/135.5 kB 18.3 MB/s eta 0:00:00 + + + Downloading boto3-1.26.96-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.5/135.5 kB 18.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.95-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.5/135.5 kB 18.8 MB/s eta 0:00:00 + + + Downloading boto3-1.26.94-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.1/135.1 kB 17.9 MB/s eta 0:00:00 + + + Downloading boto3-1.26.93-py3-none-any.whl (135 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.1/135.1 kB 18.9 MB/s eta 0:00:00 + + + Downloading boto3-1.26.92-py3-none-any.whl (134 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 19.6 MB/s eta 0:00:00 + + + Downloading boto3-1.26.91-py3-none-any.whl (134 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 19.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.90-py3-none-any.whl (134 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 18.9 MB/s eta 0:00:00 + + + Downloading boto3-1.26.89-py3-none-any.whl (134 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 19.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.88-py3-none-any.whl (134 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 17.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.87-py3-none-any.whl (134 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 18.8 MB/s eta 0:00:00 + + + Downloading boto3-1.26.86-py3-none-any.whl (134 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 18.8 MB/s eta 0:00:00 + + + Downloading boto3-1.26.85-py3-none-any.whl (134 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 17.9 MB/s eta 0:00:00 + + + Downloading boto3-1.26.84-py3-none-any.whl (134 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 18.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.83-py3-none-any.whl (134 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 19.5 MB/s eta 0:00:00 + + + Downloading boto3-1.26.82-py3-none-any.whl (134 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 19.1 MB/s eta 0:00:00 + + + Downloading boto3-1.26.81-py3-none-any.whl (134 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 19.1 MB/s eta 0:00:00 + + + Downloading boto3-1.26.80-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.3 MB/s eta 0:00:00 + + + Downloading boto3-1.26.79-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.0 MB/s eta 0:00:00 + + + Downloading boto3-1.26.78-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.4 MB/s eta 0:00:00 + + + Downloading boto3-1.26.77-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.3 MB/s eta 0:00:00 + + + Downloading boto3-1.26.76-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.0 MB/s eta 0:00:00 + + + Downloading boto3-1.26.75-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.2 MB/s eta 0:00:00 + + + Using cached boto3-1.26.74-py3-none-any.whl (132 kB) + + Downloading boto3-1.26.73-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.1 MB/s eta 0:00:00 + + + Downloading boto3-1.26.72-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.0 MB/s eta 0:00:00 + + + Downloading boto3-1.26.71-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.8 MB/s eta 0:00:00 + + + Downloading boto3-1.26.70-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.69-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.68-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.67-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.66-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.8 MB/s eta 0:00:00 + + + Downloading boto3-1.26.65-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.64-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.1 MB/s eta 0:00:00 + + + Downloading boto3-1.26.63-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.62-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.3 MB/s eta 0:00:00 + + + Downloading boto3-1.26.61-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 17.8 MB/s eta 0:00:00 + + + Downloading boto3-1.26.60-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.0 MB/s eta 0:00:00 + + + Downloading boto3-1.26.59-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.58-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.1 MB/s eta 0:00:00 + + + Downloading boto3-1.26.57-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 17.3 MB/s eta 0:00:00 + + + Downloading boto3-1.26.56-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 17.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.55-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 17.5 MB/s eta 0:00:00 + + + Downloading boto3-1.26.54-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.9 MB/s eta 0:00:00 + + + Downloading boto3-1.26.53-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.1 MB/s eta 0:00:00 + + + Downloading boto3-1.26.52-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.8 MB/s eta 0:00:00 + + + Downloading boto3-1.26.51-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.5 MB/s eta 0:00:00 + + + Downloading boto3-1.26.50-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.49-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.48-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.4 MB/s eta 0:00:00 + + + Downloading boto3-1.26.47-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.9 MB/s eta 0:00:00 + + + Downloading boto3-1.26.46-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 17.1 MB/s eta 0:00:00 + + + Downloading boto3-1.26.45-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 17.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.44-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 17.3 MB/s eta 0:00:00 + + + Downloading boto3-1.26.43-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 17.3 MB/s eta 0:00:00 + + + Downloading boto3-1.26.42-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.41-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.6 MB/s eta 0:00:00 + + + Downloading boto3-1.26.40-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.39-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.8 MB/s eta 0:00:00 + + + Downloading boto3-1.26.38-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.4 MB/s eta 0:00:00 + + + Downloading boto3-1.26.37-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.5 MB/s eta 0:00:00 + + + Downloading boto3-1.26.36-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 17.9 MB/s eta 0:00:00 + + + Downloading boto3-1.26.35-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.34-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 17.5 MB/s eta 0:00:00 + + + Downloading boto3-1.26.33-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.8 MB/s eta 0:00:00 + + + Downloading boto3-1.26.32-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.5 MB/s eta 0:00:00 + + + Downloading boto3-1.26.31-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 18.0 MB/s eta 0:00:00 + + + Downloading boto3-1.26.30-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 18.5 MB/s eta 0:00:00 + + + Downloading boto3-1.26.29-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 17.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.28-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 18.5 MB/s eta 0:00:00 + + + Downloading boto3-1.26.27-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 16.5 MB/s eta 0:00:00 + + + Downloading boto3-1.26.26-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 18.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.25-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 17.1 MB/s eta 0:00:00 + + + Downloading boto3-1.26.24-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 18.5 MB/s eta 0:00:00 + + + Downloading boto3-1.26.23-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 19.1 MB/s eta 0:00:00 + + + Downloading boto3-1.26.22-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 19.6 MB/s eta 0:00:00 + + + Downloading boto3-1.26.21-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 18.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.20-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 18.6 MB/s eta 0:00:00 + + + Downloading boto3-1.26.19-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 18.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.18-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 18.1 MB/s eta 0:00:00 + + + Downloading boto3-1.26.17-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 17.5 MB/s eta 0:00:00 + + + Downloading boto3-1.26.16-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.15-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.0 MB/s eta 0:00:00 + + + Downloading boto3-1.26.14-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.13-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 16.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.12-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.3 MB/s eta 0:00:00 + + + Downloading boto3-1.26.11-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.5 MB/s eta 0:00:00 + + + Downloading boto3-1.26.10-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.4 MB/s eta 0:00:00 + + + Downloading boto3-1.26.9-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.8-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.2 MB/s eta 0:00:00 + + + Downloading boto3-1.26.7-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.5 MB/s eta 0:00:00 + + + Downloading boto3-1.26.6-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.4 MB/s eta 0:00:00 + + + Downloading boto3-1.26.5-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.6 MB/s eta 0:00:00 + + + Downloading boto3-1.26.4-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 11.5 MB/s eta 0:00:00 + + + Downloading boto3-1.26.3-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.3 MB/s eta 0:00:00 + + + Downloading boto3-1.26.2-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.0 MB/s eta 0:00:00 + + + Downloading boto3-1.26.1-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.7 MB/s eta 0:00:00 + + + Downloading boto3-1.26.0-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.4 MB/s eta 0:00:00 + + + Downloading boto3-1.25.5-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 16.3 MB/s eta 0:00:00 + + + Downloading boto3-1.25.4-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.9 MB/s eta 0:00:00 + + + Downloading boto3-1.25.3-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.2 MB/s eta 0:00:00 + + + Downloading boto3-1.25.2-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.7 MB/s eta 0:00:00 + + + Downloading boto3-1.25.1-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.4 MB/s eta 0:00:00 + + + Downloading boto3-1.25.0-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.9 MB/s eta 0:00:00 + + + Downloading boto3-1.24.96-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.1 MB/s eta 0:00:00 + + + Downloading boto3-1.24.95-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 16.6 MB/s eta 0:00:00 + + + Downloading boto3-1.24.94-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.7 MB/s eta 0:00:00 + + + Downloading boto3-1.24.93-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.2 MB/s eta 0:00:00 + + + Downloading boto3-1.24.92-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 15.9 MB/s eta 0:00:00 + + + Downloading boto3-1.24.91-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.7 MB/s eta 0:00:00 + + + Downloading boto3-1.24.90-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.2 MB/s eta 0:00:00 + + + Downloading boto3-1.24.89-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.1 MB/s eta 0:00:00 + + + Downloading boto3-1.24.88-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.0 MB/s eta 0:00:00 + + + Downloading boto3-1.24.87-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 16.7 MB/s eta 0:00:00 + + + Downloading boto3-1.24.86-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.5 MB/s eta 0:00:00 + + + Downloading boto3-1.24.85-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.5 MB/s eta 0:00:00 + + + Downloading boto3-1.24.84-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.5 MB/s eta 0:00:00 + + + Downloading boto3-1.24.83-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.6 MB/s eta 0:00:00 + + + Downloading boto3-1.24.82-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.9 MB/s eta 0:00:00 + + + Downloading boto3-1.24.81-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.0 MB/s eta 0:00:00 + + + Downloading boto3-1.24.80-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.5 MB/s eta 0:00:00 + + + Downloading boto3-1.24.79-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 16.9 MB/s eta 0:00:00 + + + Downloading boto3-1.24.78-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.0 MB/s eta 0:00:00 + + + Downloading boto3-1.24.77-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.1 MB/s eta 0:00:00 + + + Downloading boto3-1.24.76-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 16.1 MB/s eta 0:00:00 + + + Downloading boto3-1.24.75-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.1 MB/s eta 0:00:00 + + + Downloading boto3-1.24.74-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.0 MB/s eta 0:00:00 + + + Downloading boto3-1.24.73-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 16.9 MB/s eta 0:00:00 + + + Downloading boto3-1.24.72-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.0 MB/s eta 0:00:00 + + + Downloading boto3-1.24.71-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.8 MB/s eta 0:00:00 + + + Downloading boto3-1.24.70-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.0 MB/s eta 0:00:00 + + + Downloading boto3-1.24.69-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.8 MB/s eta 0:00:00 + + + Downloading boto3-1.24.68-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.6 MB/s eta 0:00:00 + + + Downloading boto3-1.24.67-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.7 MB/s eta 0:00:00 + + + Downloading boto3-1.24.66-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.9 MB/s eta 0:00:00 + + + Downloading boto3-1.24.65-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.4 MB/s eta 0:00:00 + + + Downloading boto3-1.24.64-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.1 MB/s eta 0:00:00 + + + Downloading boto3-1.24.63-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.5 MB/s eta 0:00:00 + + + Downloading boto3-1.24.62-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.1 MB/s eta 0:00:00 + + + Downloading boto3-1.24.61-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.9 MB/s eta 0:00:00 + + + Downloading boto3-1.24.60-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.0 MB/s eta 0:00:00 + + + Downloading boto3-1.24.59-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.8 MB/s eta 0:00:00 + + + Downloading boto3-1.24.58-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.9 MB/s eta 0:00:00 + + + Downloading boto3-1.24.57-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.7 MB/s eta 0:00:00 + + + Downloading boto3-1.24.56-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.0 MB/s eta 0:00:00 + + + Downloading boto3-1.24.55-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.8 MB/s eta 0:00:00 + + + Downloading boto3-1.24.54-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.4 MB/s eta 0:00:00 + + + Downloading boto3-1.24.53-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.8 MB/s eta 0:00:00 + + + Downloading boto3-1.24.52-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.4 MB/s eta 0:00:00 + + + Downloading boto3-1.24.51-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 13.7 MB/s eta 0:00:00 + + + Downloading boto3-1.24.50-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.4 MB/s eta 0:00:00 + + + Downloading boto3-1.24.49-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.4 MB/s eta 0:00:00 + + + Downloading boto3-1.24.48-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.5 MB/s eta 0:00:00 + + + Downloading boto3-1.24.47-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.0 MB/s eta 0:00:00 + + + Downloading boto3-1.24.46-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.3 MB/s eta 0:00:00 + + + Downloading boto3-1.24.45-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.3 MB/s eta 0:00:00 + + + Downloading boto3-1.24.44-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.2 MB/s eta 0:00:00 + + + Downloading boto3-1.24.43-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.5 MB/s eta 0:00:00 + + + Downloading boto3-1.24.42-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.2 MB/s eta 0:00:00 + + + Downloading boto3-1.24.41-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.7 MB/s eta 0:00:00 + + + Downloading boto3-1.24.40-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.6 MB/s eta 0:00:00 + + + Downloading boto3-1.24.39-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 16.8 MB/s eta 0:00:00 + + + Downloading boto3-1.24.38-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.2 MB/s eta 0:00:00 + + + Downloading boto3-1.24.37-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.0 MB/s eta 0:00:00 + + + Downloading boto3-1.24.36-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.0 MB/s eta 0:00:00 + + + Downloading boto3-1.24.35-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.6 MB/s eta 0:00:00 + + + Downloading boto3-1.24.34-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.7 MB/s eta 0:00:00 + + + Downloading boto3-1.24.33-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.3 MB/s eta 0:00:00 + + + Downloading boto3-1.24.32-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.4 MB/s eta 0:00:00 + + + Downloading boto3-1.24.31-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.8 MB/s eta 0:00:00 + + + Downloading boto3-1.24.30-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.5 MB/s eta 0:00:00 + + + Downloading boto3-1.24.29-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 16.4 MB/s eta 0:00:00 + + + Downloading boto3-1.24.28-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.5 MB/s eta 0:00:00 + + + Downloading boto3-1.24.27-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.8 MB/s eta 0:00:00 + + + Downloading boto3-1.24.26-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.9 MB/s eta 0:00:00 + + + Downloading boto3-1.24.25-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.7 MB/s eta 0:00:00 + + + Downloading boto3-1.24.24-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.7 MB/s eta 0:00:00 + + + Downloading boto3-1.24.23-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 14.9 MB/s eta 0:00:00 + + + Downloading boto3-1.24.22-py3-none-any.whl (132 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.6 MB/s eta 0:00:00 + + +Collecting websocket-client>=0.32.0 (from docker>=5.0->latch) + + Downloading websocket_client-1.5.1-py3-none-any.whl (55 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 55.9/55.9 kB 9.6 MB/s eta 0:00:00 + + +Requirement already satisfied: certifi>=14.05.14 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from kubernetes>=24.2.0->latch) (2023.5.7) + +Collecting google-auth>=1.0.1 (from kubernetes>=24.2.0->latch) + + Downloading google_auth-2.18.1-py2.py3-none-any.whl (178 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 178.9/178.9 kB 26.7 MB/s eta 0:00:00 + + +Collecting requests-oauthlib (from kubernetes>=24.2.0->latch) + + Downloading requests_oauthlib-1.3.1-py2.py3-none-any.whl (23 kB) + +Collecting bcrypt>=3.2 (from paramiko>=2.11.0->latch) + + Downloading bcrypt-4.0.1-cp36-abi3-manylinux_2_28_x86_64.whl (593 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 593.7/593.7 kB 46.7 MB/s eta 0:00:00 + + +Collecting pynacl>=1.5 (from paramiko>=2.11.0->latch) + + Downloading PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl (856 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 856.7/856.7 kB 57.8 MB/s eta 0:00:00 + + +Requirement already satisfied: charset-normalizer<4,>=2 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from requests>=2.28.1->latch) (3.1.0) + +Requirement already satisfied: idna<4,>=2.5 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from requests>=2.28.1->latch) (3.4) + +Collecting sniffio>=1.1 (from anyio>=3.0.0->watchfiles==0.18.1->latch) + + Downloading sniffio-1.3.0-py3-none-any.whl (10 kB) + +Collecting binaryornot>=0.4.4 (from cookiecutter>=1.7.3->lytekit==0.14.10->latch) + + Downloading binaryornot-0.4.4-py2.py3-none-any.whl (9.0 kB) + +Requirement already satisfied: Jinja2<4.0.0,>=2.7 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from cookiecutter>=1.7.3->lytekit==0.14.10->latch) (3.1.2) + +Collecting jinja2-time>=0.2.0 (from cookiecutter>=1.7.3->lytekit==0.14.10->latch) + + Downloading jinja2_time-0.2.0-py2.py3-none-any.whl (6.4 kB) + +Collecting python-slugify>=4.0.0 (from cookiecutter>=1.7.3->lytekit==0.14.10->latch) + + Downloading python_slugify-8.0.1-py2.py3-none-any.whl (9.7 kB) + +Requirement already satisfied: cffi>=1.12 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from cryptography>=3.1->asyncssh==2.12.0->latch) (1.15.1) + +Collecting marshmallow<4.0.0,>=3.3.0 (from dataclasses-json>=0.5.2->lytekit==0.14.10->latch) + + Downloading marshmallow-3.19.0-py3-none-any.whl (49 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 49.1/49.1 kB 7.0 MB/s eta 0:00:00 + + +Collecting marshmallow-enum<2.0.0,>=1.5.1 (from dataclasses-json>=0.5.2->lytekit==0.14.10->latch) + + Downloading marshmallow_enum-1.5.1-py2.py3-none-any.whl (4.2 kB) + +Collecting typing-inspect>=0.4.0 (from dataclasses-json>=0.5.2->lytekit==0.14.10->latch) + + Downloading typing_inspect-0.8.0-py3-none-any.whl (8.7 kB) + +Collecting regex>=2019.4.14 (from docker-image-py>=0.1.10->lytekit==0.14.10->latch) + + Downloading regex-2023.5.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (769 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 769.7/769.7 kB 53.6 MB/s eta 0:00:00 + + +Collecting cachetools<6.0,>=2.0.0 (from google-auth>=1.0.1->kubernetes>=24.2.0->latch) + + Downloading cachetools-5.3.0-py3-none-any.whl (9.3 kB) + +Collecting pyasn1-modules>=0.2.1 (from google-auth>=1.0.1->kubernetes>=24.2.0->latch) + + Downloading pyasn1_modules-0.3.0-py2.py3-none-any.whl (181 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 181.3/181.3 kB 22.4 MB/s eta 0:00:00 + + +INFO: pip is looking at multiple versions of grpcio-status to determine which version is compatible with other requirements. This could take a while. + +Collecting grpcio-status!=1.45.0,>=1.43 (from lytekit==0.14.10->latch) + + Downloading grpcio_status-1.54.0-py3-none-any.whl (5.1 kB) + + Downloading grpcio_status-1.53.1-py3-none-any.whl (5.1 kB) + + Downloading grpcio_status-1.53.0-py3-none-any.whl (5.1 kB) + + Downloading grpcio_status-1.51.3-py3-none-any.whl (5.1 kB) + + Downloading grpcio_status-1.51.1-py3-none-any.whl (5.1 kB) + + Downloading grpcio_status-1.50.0-py3-none-any.whl (14 kB) + + Downloading grpcio_status-1.49.1-py3-none-any.whl (14 kB) + +INFO: pip is looking at multiple versions of grpcio-status to determine which version is compatible with other requirements. This could take a while. + + Downloading grpcio_status-1.48.2-py3-none-any.whl (14 kB) + +Requirement already satisfied: attrs>=17.4.0 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from jsonschema>=4.5.1->lytekit==0.14.10->latch) (23.1.0) + +Requirement already satisfied: pyrsistent!=0.17.0,!=0.17.1,!=0.17.2,>=0.14.0 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from jsonschema>=4.5.1->lytekit==0.14.10->latch) (0.19.3) + +Collecting jaraco.classes (from keyring>=18.0.1->lytekit==0.14.10->latch) + + Downloading jaraco.classes-3.2.3-py3-none-any.whl (6.0 kB) + +Requirement already satisfied: importlib-metadata>=4.11.4 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from keyring>=18.0.1->lytekit==0.14.10->latch) (6.6.0) + +Collecting SecretStorage>=3.2 (from keyring>=18.0.1->lytekit==0.14.10->latch) + + Downloading SecretStorage-3.3.3-py3-none-any.whl (15 kB) + +Collecting jeepney>=0.4.2 (from keyring>=18.0.1->lytekit==0.14.10->latch) + + Downloading jeepney-0.8.0-py3-none-any.whl (48 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 48.4/48.4 kB 7.7 MB/s eta 0:00:00 + + +Collecting types-PyYAML (from responses>=0.10.7->lytekit==0.14.10->latch) + + Downloading types_PyYAML-6.0.12.9-py3-none-any.whl (14 kB) + +Collecting pyasn1>=0.1.3 (from rsa<4.8,>=3.1.2->awscli==1.25.22->latch) + + Downloading pyasn1-0.5.0-py2.py3-none-any.whl (83 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 83.9/83.9 kB 13.4 MB/s eta 0:00:00 + + +Collecting multidict>=4.0 (from yarl<2.0,>=1.6->gql==3.4.0->latch) + + Downloading multidict-6.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (114 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 114.5/114.5 kB 17.1 MB/s eta 0:00:00 + + +Collecting oauthlib>=3.0.0 (from requests-oauthlib->kubernetes>=24.2.0->latch) + + Downloading oauthlib-3.2.2-py3-none-any.whl (151 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 151.7/151.7 kB 5.8 MB/s eta 0:00:00 + + +Collecting chardet>=3.0.2 (from binaryornot>=0.4.4->cookiecutter>=1.7.3->lytekit==0.14.10->latch) + + Downloading chardet-5.1.0-py3-none-any.whl (199 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 199.1/199.1 kB 27.7 MB/s eta 0:00:00 + + +Requirement already satisfied: pycparser in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from cffi>=1.12->cryptography>=3.1->asyncssh==2.12.0->latch) (2.21) + +Requirement already satisfied: zipp>=0.5 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from importlib-metadata>=4.11.4->keyring>=18.0.1->lytekit==0.14.10->latch) (3.15.0) + +Requirement already satisfied: MarkupSafe>=2.0 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from Jinja2<4.0.0,>=2.7->cookiecutter>=1.7.3->lytekit==0.14.10->latch) (2.1.2) + +Collecting arrow (from jinja2-time>=0.2.0->cookiecutter>=1.7.3->lytekit==0.14.10->latch) + + Downloading arrow-1.2.3-py3-none-any.whl (66 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 66.4/66.4 kB 8.7 MB/s eta 0:00:00 + + +Requirement already satisfied: packaging>=17.0 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from marshmallow<4.0.0,>=3.3.0->dataclasses-json>=0.5.2->lytekit==0.14.10->latch) (23.1) + +Collecting text-unidecode>=1.3 (from python-slugify>=4.0.0->cookiecutter>=1.7.3->lytekit==0.14.10->latch) + + Downloading text_unidecode-1.3-py2.py3-none-any.whl (78 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 78.2/78.2 kB 10.4 MB/s eta 0:00:00 + + +Collecting mypy-extensions>=0.3.0 (from typing-inspect>=0.4.0->dataclasses-json>=0.5.2->lytekit==0.14.10->latch) + + Downloading mypy_extensions-1.0.0-py3-none-any.whl (4.7 kB) + +Collecting more-itertools (from jaraco.classes->keyring>=18.0.1->lytekit==0.14.10->latch) + + Downloading more_itertools-9.1.0-py3-none-any.whl (54 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 54.2/54.2 kB 8.6 MB/s eta 0:00:00 + + +WARNING: The candidate selected for download or install is a yanked version: 'apscheduler' candidate (version 3.9.1 at https://files.pythonhosted.org/packages/e4/9f/c3937d4babe62504b874d4bf2c0d85aa69c7f59fa84cf6050f3b9dc5d83e/APScheduler-3.9.1-py2.py3-none-any.whl (from https://pypi.org/simple/apscheduler/) (requires-python:>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4)) +Reason for being yanked: Not compatible with Python 2.7 + +Building wheels for collected packages: docker-image-py, PyYAML + + Building wheel for docker-image-py (setup.py): started + + Building wheel for docker-image-py (setup.py): finished with status 'done' + + Created wheel for docker-image-py: filename=docker_image_py-0.1.12-py3-none-any.whl size=8812 sha256=ea8e3c15a24840f8e9dd8f96be35bfe8807c4ac208bf6a7980dff5cab2708b31 + + Stored in directory: /root/.cache/pip/wheels/fb/45/02/503244da15fbcecde5c3edabb744ed0c4f9a7643126b2d222c + + Building wheel for PyYAML (pyproject.toml): started + + Building wheel for PyYAML (pyproject.toml): finished with status 'done' + + Created wheel for PyYAML: filename=PyYAML-5.4.1-cp310-cp310-linux_x86_64.whl size=141558 sha256=c9a8c01805f3c3f49d01b9022369a08c8f9bcbd8818988d9c967f0932b6bb652 + + Stored in directory: /root/.cache/pip/wheels/c7/0d/22/696ee92245ad710f506eee79bb05c740d8abccd3ecdb778683 + +Successfully built docker-image-py PyYAML + +Installing collected packages: wcwidth, types-PyYAML, text-unidecode, statsd, sortedcontainers, pytz, pytimeparse, websockets, websocket-client, uvloop, tzlocal, tqdm, sniffio, regex, PyYAML, python-slugify, python-json-logger, pyjwt, pyasn1, py, protobuf, prompt-toolkit, oauthlib, numpy, natsort, mypy-extensions, multidict, more-itertools, marshmallow, jmespath, jeepney, grpcio, graphql-core, docutils, docstring-parser, diskcache, deprecated, decorator, colorama, cloudpickle, click, chardet, cachetools, bcrypt, backoff, aioconsole, yarl, typing-inspect, rsa, retry, responses, requests-toolbelt, requests-oauthlib, pynacl, pyasn1-modules, pyarrow, protoc-gen-swagger, pandas, marshmallow-jsonschema, marshmallow-enum, jaraco.classes, googleapis-common-protos, docker-image-py, docker, croniter, botocore, binaryornot, arrow, apscheduler, anyio, watchfiles, SecretStorage, s3transfer, paramiko, lyteidl, jinja2-time, grpcio-status, gql, google-auth, dataclasses-json, asyncssh, scp, kubernetes, keyring, cookiecutter, boto3, awscli, lytekit, lytekitplugins-pods, latch + + Attempting uninstall: PyYAML + + Found existing installation: PyYAML 6.0 + + Uninstalling PyYAML-6.0: + + Successfully uninstalled PyYAML-6.0 + + Attempting uninstall: numpy + + Found existing installation: numpy 1.24.3 + + Uninstalling numpy-1.24.3: + + Successfully uninstalled numpy-1.24.3 + + Attempting uninstall: docutils + + Found existing installation: docutils 0.20.1 + + Uninstalling docutils-0.20.1: + + Successfully uninstalled docutils-0.20.1 + +ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts. +yte 1.5.1 requires pyyaml<7.0,>=6.0, but you have pyyaml 5.4.1 which is incompatible. + +Successfully installed PyYAML-5.4.1 SecretStorage-3.3.3 aioconsole-0.5.1 anyio-3.6.2 apscheduler-3.9.1 arrow-1.2.3 asyncssh-2.12.0 awscli-1.25.22 backoff-2.2.1 bcrypt-4.0.1 binaryornot-0.4.4 boto3-1.24.22 botocore-1.27.22 cachetools-5.3.0 chardet-5.1.0 click-8.1.3 cloudpickle-2.2.1 colorama-0.4.4 cookiecutter-2.1.1 croniter-1.3.14 dataclasses-json-0.5.7 decorator-5.1.1 deprecated-1.2.13 diskcache-5.6.1 docker-5.0.3 docker-image-py-0.1.12 docstring-parser-0.15 docutils-0.16 google-auth-2.18.1 googleapis-common-protos-1.59.0 gql-3.4.0 graphql-core-3.2.3 grpcio-1.54.2 grpcio-status-1.48.2 jaraco.classes-3.2.3 jeepney-0.8.0 jinja2-time-0.2.0 jmespath-1.0.1 keyring-23.13.1 kubernetes-26.1.0 latch-2.19.11 lyteidl-0.2.0a0 lytekit-0.14.10 lytekitplugins-pods-0.4.0 marshmallow-3.19.0 marshmallow-enum-1.5.1 marshmallow-jsonschema-0.13.0 more-itertools-9.1.0 multidict-6.0.4 mypy-extensions-1.0.0 natsort-8.3.1 numpy-1.21.6 oauthlib-3.2.2 pandas-1.5.3 paramiko-3.1.0 prompt-toolkit-3.0.33 protobuf-3.20.3 protoc-gen-swagger-0.1.0 py-1.11.0 pyarrow-6.0.1 pyasn1-0.5.0 pyasn1-modules-0.3.0 pyjwt-2.7.0 pynacl-1.5.0 python-json-logger-2.0.7 python-slugify-8.0.1 pytimeparse-1.1.8 pytz-2023.3 regex-2023.5.5 requests-oauthlib-1.3.1 requests-toolbelt-0.10.1 responses-0.23.1 retry-0.9.2 rsa-4.7.2 s3transfer-0.6.1 scp-0.14.5 sniffio-1.3.0 sortedcontainers-2.4.0 statsd-3.3.0 text-unidecode-1.3 tqdm-4.65.0 types-PyYAML-6.0.12.9 typing-inspect-0.8.0 tzlocal-5.0.1 uvloop-0.17.0 watchfiles-0.18.1 wcwidth-0.2.6 websocket-client-1.5.1 websockets-10.3 yarl-1.9.2 + +WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv + + ---> 73f3b443e340 + +Step 8/14 : copy Snakefile config.yaml latch_entrypoint.py /root/ + + +COPY failed: file not found in build context or excluded by .dockerignore: stat config.yaml: file does not exist diff --git a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-cddce8/docker-build-logs.txt b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-cddce8/docker-build-logs.txt new file mode 100644 index 00000000..9fde0450 --- /dev/null +++ b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-cddce8/docker-build-logs.txt @@ -0,0 +1,1541 @@ +Step 1/16 : from 812206152185.dkr.ecr.us-west-2.amazonaws.com/latch-base:b733-kenny--snakemake + + + ---> 77471241d7a3 + +Step 2/16 : run mkdir /opt/latch + + + ---> Running in cb2296ae24de + + ---> 6d1d7399ec34 + +Step 3/16 : RUN curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh && mkdir /root/.conda && bash Mambaforge-Linux-x86_64.sh -b && rm -f Mambaforge-Linux-x86_64.sh + + + ---> Running in 12dceda47752 + + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total  +Spent Left Speed + 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 + 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 + + 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 + + 19 82.9M 19 15.9M 0 0 20.1M 0 0:00:04 --:--:-- 0:00:04 20.1M + 100 82.9M 100 82.9M 0 0 47.2M 0 0:00:01 0:00:01 --:--:-- 69.8M + +PREFIX=/root/mambaforge + +Unpacking payload ... + +Extracting _libgcc_mutex-0.1-conda_forge.tar.bz2 + +Extracting ca-certificates-2022.12.7-ha878542_0.conda + +Extracting ld_impl_linux-64-2.40-h41732ed_0.conda + +Extracting libstdcxx-ng-12.2.0-h46fd767_19.tar.bz2 + +Extracting pybind11-abi-4-hd8ed1ab_3.tar.bz2 + +Extracting python_abi-3.10-3_cp310.conda + +Extracting tzdata-2023c-h71feb2d_0.conda + +Extracting libgomp-12.2.0-h65d4601_19.tar.bz2 + +Extracting _openmp_mutex-4.5-2_gnu.tar.bz2 + +Extracting libgcc-ng-12.2.0-h65d4601_19.tar.bz2 + +Extracting bzip2-1.0.8-h7f98852_4.tar.bz2 + +Extracting c-ares-1.18.1-h7f98852_0.tar.bz2 + +Extracting fmt-9.1.0-h924138e_0.tar.bz2 + +Extracting icu-72.1-hcb278e6_0.conda + +Extracting keyutils-1.6.1-h166bdaf_0.tar.bz2 + +Extracting libev-4.33-h516909a_1.tar.bz2 + +Extracting libffi-3.4.2-h7f98852_5.tar.bz2 + +Extracting libiconv-1.17-h166bdaf_0.tar.bz2 + +Extracting libnsl-2.0.0-h7f98852_0.tar.bz2 + +Extracting libuuid-2.38.1-h0b41bf4_0.conda + +Extracting libzlib-1.2.13-h166bdaf_4.tar.bz2 + +Extracting lz4-c-1.9.4-hcb278e6_0.conda + +Extracting lzo-2.10-h516909a_1000.tar.bz2 + +Extracting ncurses-6.3-h27087fc_1.tar.bz2 + +Extracting openssl-3.1.0-h0b41bf4_0.conda + +Extracting reproc-14.2.4-h0b41bf4_0.conda + +Extracting xz-5.2.6-h166bdaf_0.tar.bz2 + +Extracting yaml-cpp-0.7.0-h27087fc_2.tar.bz2 + +Extracting libedit-3.1.20191231-he28a2e2_2.tar.bz2 + +Extracting libnghttp2-1.52.0-h61bc06f_0.conda + +Extracting libsolv-0.7.23-h3eb15da_0.conda + +Extracting libsqlite-3.40.0-h753d276_0.tar.bz2 + +Extracting libssh2-1.10.0-hf14f497_3.tar.bz2 + +Extracting libxml2-2.10.3-hfdac1af_6.conda + +Extracting readline-8.2-h8228510_1.conda + +Extracting reproc-cpp-14.2.4-hcb278e6_0.conda + +Extracting tk-8.6.12-h27826a3_0.tar.bz2 + +Extracting zstd-1.5.2-h3eb15da_6.conda + +Extracting krb5-1.20.1-h81ceb04_0.conda + +Extracting libarchive-3.6.2-h3d51595_0.conda + +Extracting python-3.10.10-he550d4f_0_cpython.conda + +Extracting certifi-2022.12.7-pyhd8ed1ab_0.conda + +Extracting charset-normalizer-3.1.0-pyhd8ed1ab_0.conda + +Extracting colorama-0.4.6-pyhd8ed1ab_0.tar.bz2 + +Extracting idna-3.4-pyhd8ed1ab_0.tar.bz2 + +Extracting libcurl-7.88.1-hdc1c0ab_1.conda + +Extracting pluggy-1.0.0-pyhd8ed1ab_5.tar.bz2 + +Extracting pycosat-0.6.4-py310h5764c6d_1.tar.bz2 + +Extracting pycparser-2.21-pyhd8ed1ab_0.tar.bz2 + +Extracting pysocks-1.7.1-pyha2e5f31_6.tar.bz2 + +Extracting ruamel.yaml.clib-0.2.7-py310h1fa729e_1.conda + +Extracting setuptools-65.6.3-pyhd8ed1ab_0.conda + +Extracting toolz-0.12.0-pyhd8ed1ab_0.tar.bz2 + +Extracting wheel-0.40.0-pyhd8ed1ab_0.conda + +Extracting cffi-1.15.1-py310h255011f_3.conda + +Extracting libmamba-1.4.1-hcea66bb_0.conda + +Extracting pip-23.0.1-pyhd8ed1ab_0.conda + +Extracting ruamel.yaml-0.17.21-py310h1fa729e_3.conda + +Extracting tqdm-4.65.0-pyhd8ed1ab_1.conda + +Extracting brotlipy-0.7.0-py310h5764c6d_1005.tar.bz2 + +Extracting cryptography-40.0.1-py310h34c0648_0.conda + +Extracting libmambapy-1.4.1-py310h1428755_0.conda + +Extracting zstandard-0.19.0-py310hdeb6495_1.conda + +Extracting conda-package-streaming-0.7.0-pyhd8ed1ab_1.conda + +Extracting pyopenssl-23.1.1-pyhd8ed1ab_0.conda + +Extracting conda-package-handling-2.0.2-pyh38be061_0.conda + +Extracting urllib3-1.26.15-pyhd8ed1ab_0.conda + +Extracting requests-2.28.2-pyhd8ed1ab_1.conda + +Extracting conda-23.1.0-py310hff52083_0.conda + +Extracting mamba-1.4.1-py310h51d5547_0.conda + + +Installing base environment... + + + + __ + __ ______ ___ ____ _____ ___ / /_ ____ _ + / / / / __ `__ \/ __ `/ __ `__ \/ __ \/ __ `/ + / /_/ / / / / / / /_/ / / / / / / /_/ / /_/ / + / .___/_/ /_/ /_/\__,_/_/ /_/ /_/_.___/\__,_/ + /_/ + + +Transaction + + Prefix: /root/mambaforge + + Updating specs: + + - conda-forge/linux-64::_libgcc_mutex==0.1=conda_forge[md5=d7c89558ba9fa0495403155b64376d81] + - conda-forge/linux-64::ca-certificates==2022.12.7=ha878542_0[md5=ff9f73d45c4a07d6f424495288a26080] + - conda-forge/linux-64::ld_impl_linux-64==2.40=h41732ed_0[md5=7aca3059a1729aa76c597603f10b0dd3] + - conda-forge/linux-64::libstdcxx-ng==12.2.0=h46fd767_19[md5=1030b1f38c129f2634eae026f704fe60] + - conda-forge/noarch::pybind11-abi==4=hd8ed1ab_3[md5=878f923dd6acc8aeb47a75da6c4098be] + - conda-forge/linux-64::python_abi==3.10=3_cp310[md5=4eb33d14d794b0f4be116443ffed3853] + - conda-forge/noarch::tzdata==2023c=h71feb2d_0[md5=939e3e74d8be4dac89ce83b20de2492a] + - conda-forge/linux-64::libgomp==12.2.0=h65d4601_19[md5=cedcee7c064c01c403f962c9e8d3c373] + - conda-forge/linux-64::_openmp_mutex==4.5=2_gnu[md5=73aaf86a425cc6e73fcf236a5a46396d] + - conda-forge/linux-64::libgcc-ng==12.2.0=h65d4601_19[md5=e4c94f80aef025c17ab0828cd85ef535] + - conda-forge/linux-64::bzip2==1.0.8=h7f98852_4[md5=a1fd65c7ccbf10880423d82bca54eb54] + - conda-forge/linux-64::c-ares==1.18.1=h7f98852_0[md5=f26ef8098fab1f719c91eb760d63381a] + - conda-forge/linux-64::fmt==9.1.0=h924138e_0[md5=b57864c85261a0fbc7132d2cc17478c7] + - conda-forge/linux-64::icu==72.1=hcb278e6_0[md5=7c8d20d847bb45f56bd941578fcfa146] + - conda-forge/linux-64::keyutils==1.6.1=h166bdaf_0[md5=30186d27e2c9fa62b45fb1476b7200e3] + - conda-forge/linux-64::libev==4.33=h516909a_1[md5=6f8720dff19e17ce5d48cfe7f3d2f0a3] + - conda-forge/linux-64::libffi==3.4.2=h7f98852_5[md5=d645c6d2ac96843a2bfaccd2d62b3ac3] + - conda-forge/linux-64::libiconv==1.17=h166bdaf_0[md5=b62b52da46c39ee2bc3c162ac7f1804d] + - conda-forge/linux-64::libnsl==2.0.0=h7f98852_0[md5=39b1328babf85c7c3a61636d9cd50206] + - conda-forge/linux-64::libuuid==2.38.1=h0b41bf4_0[md5=40b61aab5c7ba9ff276c41cfffe6b80b] + - conda-forge/linux-64::libzlib==1.2.13=h166bdaf_4[md5=f3f9de449d32ca9b9c66a22863c96f41] + - conda-forge/linux-64::lz4-c==1.9.4=hcb278e6_0[md5=318b08df404f9c9be5712aaa5a6f0bb0] + - conda-forge/linux-64::lzo==2.10=h516909a_1000[md5=bb14fcb13341b81d5eb386423b9d2bac] + - conda-forge/linux-64::ncurses==6.3=h27087fc_1[md5=4acfc691e64342b9dae57cf2adc63238] + - conda-forge/linux-64::openssl==3.1.0=h0b41bf4_0[md5=2d833be81a21128e317325a01326d36f] + - conda-forge/linux-64::reproc==14.2.4=h0b41bf4_0[md5=0f51393e019df1f0047ef864cd9ddeec] + - conda-forge/linux-64::xz==5.2.6=h166bdaf_0[md5=2161070d867d1b1204ea749c8eec4ef0] + + - conda-forge/linux-64::yaml-cpp==0.7.0=h27087fc_2[md5=0449d47d8457feaa3720d4779616dde2] + - conda-forge/linux-64::libedit==3.1.20191231=he28a2e2_2[md5=4d331e44109e3f0e19b4cb8f9b82f3e1] + - conda-forge/linux-64::libnghttp2==1.52.0=h61bc06f_0[md5=613955a50485812985c059e7b269f42e] + - conda-forge/linux-64::libsolv==0.7.23=h3eb15da_0[md5=122332e6deb4aea9eaf22021d2ecd256] + - conda-forge/linux-64::libsqlite==3.40.0=h753d276_0[md5=2e5f9a37d487e1019fd4d8113adb2f9f] + - conda-forge/linux-64::libssh2==1.10.0=hf14f497_3[md5=d85acad4b47dff4e3def14a769a97906] + - conda-forge/linux-64::libxml2==2.10.3=hfdac1af_6[md5=7eecaadc2eaeef464c5fe17702f17c86] + - conda-forge/linux-64::readline==8.2=h8228510_1[md5=47d31b792659ce70f470b5c82fdfb7a4] + - conda-forge/linux-64::reproc-cpp==14.2.4=hcb278e6_0[md5=ede8e0f849f2fee2f78cb488b4ea3b33] + + - conda-forge/linux-64::tk==8.6.12=h27826a3_0[md5=5b8c42eb62e9fc961af70bdd6a26e168] + - conda-forge/linux-64::zstd==1.5.2=h3eb15da_6[md5=6b63daed8feeca47be78f323e793d555] + - conda-forge/linux-64::krb5==1.20.1=h81ceb04_0[md5=89a41adce7106749573d883b2f657d78] + + - conda-forge/linux-64::libarchive==3.6.2=h3d51595_0[md5=9f915b4adeb9dcfd450b9ad238e2db4c] + - conda-forge/linux-64::python==3.10.10=he550d4f_0_cpython[md5=de25afc7041c103c7f510c746bb63435] + - conda-forge/noarch::certifi==2022.12.7=pyhd8ed1ab_0[md5=fb9addc3db06e56abe03e0e9f21a63e6] + - conda-forge/noarch::charset-normalizer==3.1.0=pyhd8ed1ab_0[md5=7fcff9f6f123696e940bda77bd4d6551] + - conda-forge/noarch::colorama==0.4.6=pyhd8ed1ab_0[md5=3faab06a954c2a04039983f2c4a50d99] + - conda-forge/noarch::idna==3.4=pyhd8ed1ab_0[md5=34272b248891bddccc64479f9a7fffed] + - conda-forge/linux-64::libcurl==7.88.1=hdc1c0ab_1[md5=3d1189864d1c0ed2a5919cb067b5903d] + - conda-forge/noarch::pluggy==1.0.0=pyhd8ed1ab_5[md5=7d301a0d25f424d96175f810935f0da9] + - conda-forge/linux-64::pycosat==0.6.4=py310h5764c6d_1[md5=0e565d732f6660374b45d76761c09b06] + - conda-forge/noarch::pycparser==2.21=pyhd8ed1ab_0[md5=076becd9e05608f8dc72757d5f3a91ff] + - conda-forge/noarch::pysocks==1.7.1=pyha2e5f31_6[md5=2a7de29fb590ca14b5243c4c812c8025] + - conda-forge/linux-64::ruamel.yaml.clib==0.2.7=py310h1fa729e_1[md5=2f9b517412af46255cef5e53a22c264e] + - conda-forge/noarch::setuptools==65.6.3=pyhd8ed1ab_0[md5=9600fc9524d3f821e6a6d58c52f5bf5a] + - conda-forge/noarch::toolz==0.12.0=pyhd8ed1ab_0[md5=92facfec94bc02d6ccf42e7173831a36] + - conda-forge/noarch::wheel==0.40.0=pyhd8ed1ab_0[md5=49bb0d9e60ce1db25e151780331bb5f3] + - conda-forge/linux-64::cffi==1.15.1=py310h255011f_3[md5=800596144bb613cd7ac58b80900ce835] + - conda-forge/linux-64::libmamba==1.4.1=hcea66bb_0[md5=e512a4c95ff1eca1684642fa32bd2f55] + - conda-forge/noarch::pip==23.0.1=pyhd8ed1ab_0[md5=8025ca83b8ba5430b640b83917c2a6f7] + - conda-forge/linux-64::ruamel.yaml==0.17.21=py310h1fa729e_3[md5=97204ae92b703d74a983db0e6d07d009] + - conda-forge/noarch::tqdm==4.65.0=pyhd8ed1ab_1[md5=ed792aff3acb977d09c7013358097f83] + - conda-forge/linux-64::brotlipy==0.7.0=py310h5764c6d_1005[md5=87669c3468dff637bbd0363bc0f895cf] + - conda-forge/linux-64::cryptography==40.0.1=py310h34c0648_0[md5=deafd9206c2e307874f3777a33cafb79] + - conda-forge/linux-64::libmambapy==1.4.1=py310h1428755_0[md5=323e09e9947b6a415f9d73562e4ca862] + - conda-forge/linux-64::zstandard==0.19.0=py310hdeb6495_1[md5=2cce1a48e6687f64d371d2e7fc9c7fbf] + - conda-forge/noarch::conda-package-streaming==0.7.0=pyhd8ed1ab_1[md5=1a2fa9e53cfbc2e4d9ab21990805a436] + - conda-forge/noarch::pyopenssl==23.1.1=pyhd8ed1ab_0[md5=0b34aa3ab7e7ccb1765a03dd9ed29938] + - conda-forge/noarch::conda-package-handling==2.0.2=pyh38be061_0[md5=44800e9bd13143292097c65e57323038] + - conda-forge/noarch::urllib3==1.26.15=pyhd8ed1ab_0[md5=27db656619a55d727eaf5a6ece3d2fd6] + + - conda-forge/noarch::requests==2.28.2=pyhd8ed1ab_1[md5=3bfbd6ead1d7299ed46dab3a7bf0bc8c] + - conda-forge/linux-64::conda==23.1.0=py310hff52083_0[md5=c2f5cd14bf4a8cc673f66fd9839e6602] + - conda-forge/linux-64::mamba==1.4.1=py310h51d5547_0[md5=49170d6752d2326fe16dc2b6e74f9e54] + + + + Package Version Build Channel Size +─────────────────────────────────────────────────────────────────────────────────────── + Install: +─────────────────────────────────────────────────────────────────────────────────────── + + + _libgcc_mutex 0.1 conda_forge conda-forge Cached + + _openmp_mutex 4.5 2_gnu conda-forge Cached + + brotlipy 0.7.0 py310h5764c6d_1005 conda-forge Cached + + bzip2 1.0.8 h7f98852_4 conda-forge Cached + + c-ares 1.18.1 h7f98852_0 conda-forge Cached + + ca-certificates 2022.12.7 ha878542_0 conda-forge Cached + + certifi 2022.12.7 pyhd8ed1ab_0 conda-forge Cached + + cffi 1.15.1 py310h255011f_3 conda-forge Cached + + charset-normalizer 3.1.0 pyhd8ed1ab_0 conda-forge Cached + + colorama 0.4.6 pyhd8ed1ab_0 conda-forge Cached + + conda 23.1.0 py310hff52083_0 conda-forge Cached + + conda-package-handling 2.0.2 pyh38be061_0 conda-forge Cached + + conda-package-streaming 0.7.0 pyhd8ed1ab_1 conda-forge Cached + + cryptography 40.0.1 py310h34c0648_0 conda-forge Cached + + fmt 9.1.0 h924138e_0 conda-forge Cached + + icu 72.1 hcb278e6_0 conda-forge Cached + + idna 3.4 pyhd8ed1ab_0 conda-forge Cached + + keyutils 1.6.1 h166bdaf_0 conda-forge Cached + + krb5 1.20.1 h81ceb04_0 conda-forge Cached + + ld_impl_linux-64 2.40 h41732ed_0 conda-forge Cached + + libarchive 3.6.2 h3d51595_0 conda-forge Cached + + libcurl 7.88.1 hdc1c0ab_1 conda-forge Cached + + libedit 3.1.20191231 he28a2e2_2 conda-forge Cached + + libev 4.33 h516909a_1 conda-forge Cached + + libffi 3.4.2 h7f98852_5 conda-forge Cached + + libgcc-ng 12.2.0 h65d4601_19 conda-forge Cached + + libgomp 12.2.0 h65d4601_19 conda-forge Cached + + libiconv 1.17 h166bdaf_0 conda-forge Cached + + libmamba 1.4.1 hcea66bb_0 conda-forge Cached + + libmambapy 1.4.1 py310h1428755_0 conda-forge Cached + + libnghttp2 1.52.0 h61bc06f_0 conda-forge Cached + + libnsl 2.0.0 h7f98852_0 conda-forge Cached + + libsolv 0.7.23 h3eb15da_0 conda-forge Cached + + libsqlite 3.40.0 h753d276_0 conda-forge Cached + + libssh2 1.10.0 hf14f497_3 conda-forge Cached + + libstdcxx-ng 12.2.0 h46fd767_19 conda-forge Cached + + libuuid 2.38.1 h0b41bf4_0 conda-forge Cached + + libxml2 2.10.3 hfdac1af_6 conda-forge Cached + + libzlib 1.2.13 h166bdaf_4 conda-forge Cached + + lz4-c 1.9.4 hcb278e6_0 conda-forge Cached + + lzo 2.10 h516909a_1000 conda-forge Cached + + mamba 1.4.1 py310h51d5547_0 conda-forge Cached + + ncurses 6.3 h27087fc_1 conda-forge Cached + + openssl 3.1.0 h0b41bf4_0 conda-forge Cached + + pip 23.0.1 pyhd8ed1ab_0 conda-forge Cached + + pluggy 1.0.0 pyhd8ed1ab_5 conda-forge Cached + + pybind11-abi 4 hd8ed1ab_3 conda-forge Cached + + pycosat 0.6.4 py310h5764c6d_1 conda-forge Cached + + pycparser 2.21 pyhd8ed1ab_0 conda-forge Cached + + pyopenssl 23.1.1 pyhd8ed1ab_0 conda-forge Cached + + pysocks 1.7.1 pyha2e5f31_6 conda-forge Cached + + python 3.10.10 he550d4f_0_cpython conda-forge Cached + + python_abi 3.10 3_cp310 conda-forge Cached + + readline 8.2 h8228510_1 conda-forge Cached + + reproc 14.2.4 h0b41bf4_0 conda-forge Cached + + reproc-cpp 14.2.4 hcb278e6_0 conda-forge Cached + + requests 2.28.2 pyhd8ed1ab_1 conda-forge Cached + + ruamel.yaml 0.17.21 py310h1fa729e_3 conda-forge Cached + + ruamel.yaml.clib 0.2.7 py310h1fa729e_1 conda-forge Cached + + setuptools 65.6.3 pyhd8ed1ab_0 conda-forge Cached + + tk 8.6.12 h27826a3_0 conda-forge Cached + + toolz 0.12.0 pyhd8ed1ab_0 conda-forge Cached + + tqdm 4.65.0 pyhd8ed1ab_1 conda-forge Cached + + tzdata 2023c h71feb2d_0 conda-forge Cached + + urllib3 1.26.15 pyhd8ed1ab_0 conda-forge Cached + + wheel 0.40.0 pyhd8ed1ab_0 conda-forge Cached + + xz 5.2.6 h166bdaf_0 conda-forge Cached + + yaml-cpp 0.7.0 h27087fc_2 conda-forge Cached + + zstandard 0.19.0 py310hdeb6495_1 conda-forge Cached + + zstd 1.5.2 h3eb15da_6 conda-forge Cached + + Summary: + + Install: 70 packages + + Total download: 0 B + +─────────────────────────────────────────────────────────────────────────────────────── + + + + +Transaction starting + +Linking _libgcc_mutex-0.1-conda_forge + +Linking ca-certificates-2022.12.7-ha878542_0 + +Linking ld_impl_linux-64-2.40-h41732ed_0 + +Linking libstdcxx-ng-12.2.0-h46fd767_19 + +Linking pybind11-abi-4-hd8ed1ab_3 + +Linking python_abi-3.10-3_cp310 + +Linking tzdata-2023c-h71feb2d_0 + +Linking libgomp-12.2.0-h65d4601_19 + +Linking _openmp_mutex-4.5-2_gnu + +Linking libgcc-ng-12.2.0-h65d4601_19 + +Linking bzip2-1.0.8-h7f98852_4 + +Linking c-ares-1.18.1-h7f98852_0 + +Linking fmt-9.1.0-h924138e_0 + +Linking icu-72.1-hcb278e6_0 + +Linking keyutils-1.6.1-h166bdaf_0 + +Linking libev-4.33-h516909a_1 + +Linking libffi-3.4.2-h7f98852_5 + +Linking libiconv-1.17-h166bdaf_0 + +Linking libnsl-2.0.0-h7f98852_0 + +Linking libuuid-2.38.1-h0b41bf4_0 + +Linking libzlib-1.2.13-h166bdaf_4 + +Linking lz4-c-1.9.4-hcb278e6_0 + +Linking lzo-2.10-h516909a_1000 + +Linking ncurses-6.3-h27087fc_1 + +Linking openssl-3.1.0-h0b41bf4_0 + +Linking reproc-14.2.4-h0b41bf4_0 + +Linking xz-5.2.6-h166bdaf_0 + +Linking yaml-cpp-0.7.0-h27087fc_2 + +Linking libedit-3.1.20191231-he28a2e2_2 + +Linking libnghttp2-1.52.0-h61bc06f_0 + +Linking libsolv-0.7.23-h3eb15da_0 + +Linking libsqlite-3.40.0-h753d276_0 + +Linking libssh2-1.10.0-hf14f497_3 + +Linking libxml2-2.10.3-hfdac1af_6 + +Linking readline-8.2-h8228510_1 + +Linking reproc-cpp-14.2.4-hcb278e6_0 + +Linking tk-8.6.12-h27826a3_0 + +Linking zstd-1.5.2-h3eb15da_6 + +Linking krb5-1.20.1-h81ceb04_0 + +Linking libarchive-3.6.2-h3d51595_0 + +Linking python-3.10.10-he550d4f_0_cpython + +Linking certifi-2022.12.7-pyhd8ed1ab_0 + +Linking charset-normalizer-3.1.0-pyhd8ed1ab_0 + +Linking colorama-0.4.6-pyhd8ed1ab_0 + +Linking idna-3.4-pyhd8ed1ab_0 + +Linking libcurl-7.88.1-hdc1c0ab_1 + +Linking pluggy-1.0.0-pyhd8ed1ab_5 + +Linking pycosat-0.6.4-py310h5764c6d_1 + +Linking pycparser-2.21-pyhd8ed1ab_0 + +Linking pysocks-1.7.1-pyha2e5f31_6 + +Linking ruamel.yaml.clib-0.2.7-py310h1fa729e_1 + +Linking setuptools-65.6.3-pyhd8ed1ab_0 + +Linking toolz-0.12.0-pyhd8ed1ab_0 + +Linking wheel-0.40.0-pyhd8ed1ab_0 + +Linking cffi-1.15.1-py310h255011f_3 + +Linking libmamba-1.4.1-hcea66bb_0 + +Linking pip-23.0.1-pyhd8ed1ab_0 + +Linking ruamel.yaml-0.17.21-py310h1fa729e_3 + +Linking tqdm-4.65.0-pyhd8ed1ab_1 + +Linking brotlipy-0.7.0-py310h5764c6d_1005 + +Linking cryptography-40.0.1-py310h34c0648_0 + +Linking libmambapy-1.4.1-py310h1428755_0 + +Linking zstandard-0.19.0-py310hdeb6495_1 + +Linking conda-package-streaming-0.7.0-pyhd8ed1ab_1 + +Linking pyopenssl-23.1.1-pyhd8ed1ab_0 + +Linking conda-package-handling-2.0.2-pyh38be061_0 + +Linking urllib3-1.26.15-pyhd8ed1ab_0 + +Linking requests-2.28.2-pyhd8ed1ab_1 + +Linking conda-23.1.0-py310hff52083_0 + +Linking mamba-1.4.1-py310h51d5547_0 + +Transaction finished + +installation finished. + +WARNING: + You currently have a PYTHONPATH environment variable set. This may cause + unexpected behavior when running the Python interpreter in Mambaforge. + For best results, please verify that your PYTHONPATH only points to + directories of packages that are compatible with the Python interpreter + in Mambaforge: /root/mambaforge + + ---> e5d7f1c377ad + +Step 4/16 : copy environment.yaml /root/environment.yaml + + + ---> f1895bb6bb01 + +Step 5/16 : run /root/mambaforge/bin/mamba env create --name snakemake-tutorial --file environment.yaml + + + ---> Running in f846c7f12119 + + + +Looking for: ["snakemake-minimal[version='>=7.3']", 'jinja2', 'matplotlib', 'graphviz', 'bcftools=1.15', 'samtools=1.15', 'bwa=0.7.17', 'pysam=0.19', 'pygments'] + + + +Transaction + + Prefix: /root/mambaforge/envs/snakemake-tutorial + + Updating specs: + + - snakemake-minimal[version='>=7.3'] + - jinja2 + - matplotlib + - graphviz + - bcftools=1.15 + - samtools=1.15 + - bwa=0.7.17 + - pysam=0.19 + - pygments + + + + Package Version Build Channel Size +─────────────────────────────────────────────────────────────────────────────────────────────────── + Install: +─────────────────────────────────────────────────────────────────────────────────────────────────── + + + _libgcc_mutex 0.1 conda_forge conda-forge/linux-64 Cached + + _openmp_mutex 4.5 2_gnu conda-forge/linux-64 Cached + + alsa-lib 1.2.8 h166bdaf_0 conda-forge/linux-64 592kB + + amply 0.1.5 pyhd8ed1ab_0 conda-forge/noarch 21kB + + appdirs 1.4.4 pyh9f0ad1d_0 conda-forge/noarch 13kB + + atk-1.0 2.38.0 hd4edc92_1 conda-forge/linux-64 552kB + + attr 2.5.1 h166bdaf_1 conda-forge/linux-64 71kB + + attrs 23.1.0 pyh71513ae_1 conda-forge/noarch 55kB + + bcftools 1.15.1 hfe4b78e_1 bioconda/linux-64 867kB + + brotli 1.0.9 h166bdaf_8 conda-forge/linux-64 19kB + + brotli-bin 1.0.9 h166bdaf_8 conda-forge/linux-64 20kB + + brotlipy 0.7.0 py310h5764c6d_1005 conda-forge/linux-64 Cached + + bwa 0.7.17 he4a0461_11 bioconda/linux-64 196kB + + bzip2 1.0.8 h7f98852_4 conda-forge/linux-64 Cached + + c-ares 1.19.0 hd590300_0 conda-forge/linux-64 114kB + + ca-certificates 2023.5.7 hbcca054_0 conda-forge/linux-64 148kB + + cairo 1.16.0 ha61ee94_1014 conda-forge/linux-64 2MB + + certifi 2023.5.7 pyhd8ed1ab_0 conda-forge/noarch 152kB + + cffi 1.15.1 py310h255011f_3 conda-forge/linux-64 Cached + + charset-normalizer 3.1.0 pyhd8ed1ab_0 conda-forge/noarch Cached + + coin-or-cbc 2.10.10 h9002f0b_0 conda-forge/linux-64 941kB + + coin-or-cgl 0.60.7 h516709c_0 conda-forge/linux-64 551kB + + coin-or-clp 1.17.8 h1ee7a9c_0 conda-forge/linux-64 1MB + + coin-or-osi 0.108.8 ha2443b9_0 conda-forge/linux-64 389kB + + coin-or-utils 2.11.9 hee58242_0 conda-forge/linux-64 687kB + + coincbc 2.10.10 0_metapackage conda-forge/noarch 12kB + + configargparse 1.5.3 pyhd8ed1ab_0 conda-forge/noarch 33kB + + connection_pool 0.0.3 pyhd3deb0d_0 conda-forge/noarch 8kB + + contourpy 1.0.7 py310hdf3cbec_0 conda-forge/linux-64 216kB + + cryptography 39.0.0 py310h65dfdc0_0 conda-forge/linux-64 1MB + + cycler 0.11.0 pyhd8ed1ab_0 conda-forge/noarch 10kB + + datrie 0.8.2 py310h5764c6d_6 conda-forge/linux-64 148kB + + dbus 1.13.6 h5008d03_3 conda-forge/linux-64 619kB + + docutils 0.20.1 py310hff52083_0 conda-forge/linux-64 721kB + + dpath 2.1.6 pyha770c72_0 conda-forge/noarch 21kB + + expat 2.5.0 hcb278e6_1 conda-forge/linux-64 137kB + + fftw 3.3.10 nompi_hc118613_107 conda-forge/linux-64 2MB + + filelock 3.12.0 pyhd8ed1ab_0 conda-forge/noarch 15kB + + font-ttf-dejavu-sans-mono 2.37 hab24e00_0 conda-forge/noarch 397kB + + font-ttf-inconsolata 3.000 h77eed37_0 conda-forge/noarch 97kB + + font-ttf-source-code-pro 2.038 h77eed37_0 conda-forge/noarch 701kB + + font-ttf-ubuntu 0.83 hab24e00_0 conda-forge/noarch 2MB + + fontconfig 2.14.2 h14ed4e7_0 conda-forge/linux-64 272kB + + fonts-conda-ecosystem 1 0 conda-forge/noarch 4kB + + fonts-conda-forge 1 0 conda-forge/noarch 4kB + + fonttools 4.39.4 py310h2372a71_0 conda-forge/linux-64 2MB + + freetype 2.12.1 hca18f0e_1 conda-forge/linux-64 626kB + + fribidi 1.0.10 h36c2ea0_0 conda-forge/linux-64 114kB + + gdk-pixbuf 2.42.8 hff1cb4f_1 conda-forge/linux-64 612kB + + gettext 0.21.1 h27087fc_0 conda-forge/linux-64 4MB + + giflib 5.2.1 h0b41bf4_3 conda-forge/linux-64 77kB + + gitdb 4.0.10 pyhd8ed1ab_0 conda-forge/noarch 52kB + + gitpython 3.1.31 pyhd8ed1ab_0 conda-forge/noarch 142kB + + glib 2.76.2 hfc55251_0 conda-forge/linux-64 484kB + + glib-tools 2.76.2 hfc55251_0 conda-forge/linux-64 112kB + + graphite2 1.3.13 h58526e2_1001 conda-forge/linux-64 105kB + + graphviz 7.0.5 h2e5815a_0 conda-forge/linux-64 2MB + + gsl 2.7 he838d99_0 conda-forge/linux-64 3MB + + gst-plugins-base 1.21.3 h4243ec0_1 conda-forge/linux-64 3MB + + gstreamer 1.21.3 h25f0c4b_1 conda-forge/linux-64 2MB + + gstreamer-orc 0.4.33 h166bdaf_0 conda-forge/linux-64 306kB + + gtk2 2.24.33 h90689f9_2 conda-forge/linux-64 8MB + + gts 0.7.6 h64030ff_2 conda-forge/linux-64 421kB + + harfbuzz 6.0.0 h8e241bc_0 conda-forge/linux-64 1MB + + htslib 1.16 h6bc39ce_0 bioconda/linux-64 2MB + + humanfriendly 10.0 py310hff52083_4 conda-forge/linux-64 123kB + + icu 70.1 h27087fc_0 conda-forge/linux-64 14MB + + idna 3.4 pyhd8ed1ab_0 conda-forge/noarch Cached + + importlib-metadata 6.6.0 pyha770c72_0 conda-forge/noarch 26kB + + importlib_resources 5.12.0 pyhd8ed1ab_0 conda-forge/noarch 31kB + + jack 1.9.22 h11f4161_0 conda-forge/linux-64 464kB + + jinja2 3.1.2 pyhd8ed1ab_1 conda-forge/noarch 101kB + + jpeg 9e h0b41bf4_3 conda-forge/linux-64 240kB + + jsonschema 4.17.3 pyhd8ed1ab_0 conda-forge/noarch 70kB + + jupyter_core 5.3.0 py310hff52083_0 conda-forge/linux-64 91kB + + keyutils 1.6.1 h166bdaf_0 conda-forge/linux-64 Cached + + kiwisolver 1.4.4 py310hbf28c38_1 conda-forge/linux-64 77kB + + krb5 1.20.1 hf9c8cef_0 conda-forge/linux-64 1MB + + lame 3.100 h166bdaf_1003 conda-forge/linux-64 508kB + + lcms2 2.14 h6ed2654_0 conda-forge/linux-64 262kB + + ld_impl_linux-64 2.40 h41732ed_0 conda-forge/linux-64 Cached + + lerc 4.0.0 h27087fc_0 conda-forge/linux-64 282kB + + libblas 3.9.0 16_linux64_openblas conda-forge/linux-64 13kB + + libbrotlicommon 1.0.9 h166bdaf_8 conda-forge/linux-64 67kB + + libbrotlidec 1.0.9 h166bdaf_8 conda-forge/linux-64 34kB + + libbrotlienc 1.0.9 h166bdaf_8 conda-forge/linux-64 295kB + + libcap 2.66 ha37c62d_0 conda-forge/linux-64 100kB + + libcblas 3.9.0 16_linux64_openblas conda-forge/linux-64 13kB + + libclang 15.0.7 default_h7634d5b_2 conda-forge/linux-64 133kB + + libclang13 15.0.7 default_h9986a30_2 conda-forge/linux-64 10MB + + libcups 2.3.3 h36d4200_3 conda-forge/linux-64 5MB + + libcurl 7.87.0 h6312ad2_0 conda-forge/linux-64 347kB + + libdb 6.2.32 h9c3ff4c_0 conda-forge/linux-64 24MB + + libdeflate 1.13 h166bdaf_0 conda-forge/linux-64 80kB + + libedit 3.1.20191231 he28a2e2_2 conda-forge/linux-64 Cached + + libev 4.33 h516909a_1 conda-forge/linux-64 Cached + + libevent 2.1.10 h9b69904_4 conda-forge/linux-64 1MB + + libexpat 2.5.0 hcb278e6_1 conda-forge/linux-64 78kB + + libffi 3.4.2 h7f98852_5 conda-forge/linux-64 Cached + + libflac 1.4.2 h27087fc_0 conda-forge/linux-64 421kB + + libgcc-ng 12.2.0 h65d4601_19 conda-forge/linux-64 Cached + + libgcrypt 1.10.1 h166bdaf_0 conda-forge/linux-64 720kB + + libgd 2.3.3 h18fbbfe_3 conda-forge/linux-64 272kB + + libgfortran-ng 12.2.0 h69a702a_19 conda-forge/linux-64 23kB + + libgfortran5 12.2.0 h337968e_19 conda-forge/linux-64 2MB + + libglib 2.76.2 hebfc3b9_0 conda-forge/linux-64 3MB + + libgomp 12.2.0 h65d4601_19 conda-forge/linux-64 Cached + + libgpg-error 1.46 h620e276_0 conda-forge/linux-64 258kB + + libiconv 1.17 h166bdaf_0 conda-forge/linux-64 Cached + + liblapack 3.9.0 16_linux64_openblas conda-forge/linux-64 13kB + + liblapacke 3.9.0 16_linux64_openblas conda-forge/linux-64 13kB + + libllvm15 15.0.7 hadd5161_1 conda-forge/linux-64 33MB + + libnghttp2 1.51.0 hdcd2b5c_0 conda-forge/linux-64 623kB + + libnsl 2.0.0 h7f98852_0 conda-forge/linux-64 Cached + + libogg 1.3.4 h7f98852_1 conda-forge/linux-64 211kB + + libopenblas 0.3.21 pthreads_h78a6416_3 conda-forge/linux-64 11MB + + libopus 1.3.1 h7f98852_1 conda-forge/linux-64 261kB + + libpng 1.6.39 h753d276_0 conda-forge/linux-64 283kB + + libpq 15.1 h2baec63_3 conda-forge/linux-64 2MB + + librsvg 2.54.4 h7abd40a_0 conda-forge/linux-64 7MB + + libsndfile 1.2.0 hb75c966_0 conda-forge/linux-64 350kB + + libsqlite 3.42.0 h2797004_0 conda-forge/linux-64 829kB + + libssh2 1.10.0 haa6b8db_3 conda-forge/linux-64 239kB + + libstdcxx-ng 12.2.0 h46fd767_19 conda-forge/linux-64 Cached + + libsystemd0 252 h2a991cd_0 conda-forge/linux-64 393kB + + libtiff 4.4.0 h0e0dad5_3 conda-forge/linux-64 658kB + + libtool 2.4.7 h27087fc_0 conda-forge/linux-64 412kB + + libudev1 253 h0b41bf4_0 conda-forge/linux-64 119kB + + libuuid 2.38.1 h0b41bf4_0 conda-forge/linux-64 Cached + + libvorbis 1.3.7 h9c3ff4c_0 conda-forge/linux-64 286kB + + libwebp 1.2.4 h522a892_0 conda-forge/linux-64 90kB + + libwebp-base 1.2.4 h166bdaf_0 conda-forge/linux-64 413kB + + libxcb 1.13 h7f98852_1004 conda-forge/linux-64 400kB + + libxkbcommon 1.5.0 h79f4944_1 conda-forge/linux-64 563kB + + libxml2 2.10.3 hca2bb57_4 conda-forge/linux-64 714kB + + libzlib 1.2.13 h166bdaf_4 conda-forge/linux-64 Cached + + lz4-c 1.9.4 hcb278e6_0 conda-forge/linux-64 Cached + + markupsafe 2.1.2 py310h1fa729e_0 conda-forge/linux-64 23kB + + matplotlib 3.7.1 py310hff52083_0 conda-forge/linux-64 8kB + + matplotlib-base 3.7.1 py310he60537e_0 conda-forge/linux-64 7MB + + mpg123 1.31.3 hcb278e6_0 conda-forge/linux-64 485kB + + munkres 1.0.7 py_1 bioconda/noarch 10kB + + mysql-common 8.0.32 h14678bc_0 conda-forge/linux-64 803kB + + mysql-libs 8.0.32 h54cf53e_0 conda-forge/linux-64 2MB + + nbformat 5.8.0 pyhd8ed1ab_0 conda-forge/noarch 101kB + + ncurses 6.3 h27087fc_1 conda-forge/linux-64 Cached + + nspr 4.35 h27087fc_0 conda-forge/linux-64 227kB + + nss 3.89 he45b914_0 conda-forge/linux-64 2MB + + numpy 1.24.3 py310ha4c1d20_0 conda-forge/linux-64 7MB + + openjpeg 2.5.0 h7d73246_1 conda-forge/linux-64 546kB + + openssl 1.1.1t h0b41bf4_0 conda-forge/linux-64 2MB + + packaging 23.1 pyhd8ed1ab_0 conda-forge/noarch 46kB + + pango 1.50.14 hd33c08f_0 conda-forge/linux-64 438kB + + pcre2 10.40 hc3806b6_0 conda-forge/linux-64 2MB + + perl 5.32.1 2_h7f98852_perl5 conda-forge/linux-64 15MB + + pillow 9.2.0 py310h454ad03_3 conda-forge/linux-64 47MB + + pip 23.1.2 pyhd8ed1ab_0 conda-forge/noarch 1MB + + pixman 0.40.0 h36c2ea0_0 conda-forge/linux-64 643kB + + pkgutil-resolve-name 1.3.10 pyhd8ed1ab_0 conda-forge/noarch 9kB + + plac 1.3.5 pyhd8ed1ab_0 conda-forge/noarch 23kB + + platformdirs 3.5.1 pyhd8ed1ab_0 conda-forge/noarch 19kB + + ply 3.11 py_1 conda-forge/noarch 45kB + + psutil 5.9.5 py310h1fa729e_0 conda-forge/linux-64 362kB + + pthread-stubs 0.4 h36c2ea0_1001 conda-forge/linux-64 6kB + + pulp 2.7.0 py310hff52083_0 conda-forge/linux-64 141kB + + pulseaudio 16.1 h4ab2085_1 conda-forge/linux-64 2MB + + pycparser 2.21 pyhd8ed1ab_0 conda-forge/noarch Cached + + pygments 2.15.1 pyhd8ed1ab_0 conda-forge/noarch 841kB + + pyopenssl 23.1.1 pyhd8ed1ab_0 conda-forge/noarch Cached + + pyparsing 3.0.9 pyhd8ed1ab_0 conda-forge/noarch 81kB + + pyqt 5.15.7 py310hab646b1_3 conda-forge/linux-64 5MB + + pyqt5-sip 12.11.0 py310heca2aa9_3 conda-forge/linux-64 85kB + + pyrsistent 0.19.3 py310h1fa729e_0 conda-forge/linux-64 100kB + + pysam 0.19.1 py310hff46b53_1 bioconda/linux-64 3MB + + pysocks 1.7.1 pyha2e5f31_6 conda-forge/noarch Cached + + python 3.10.8 h257c98d_0_cpython conda-forge/linux-64 23MB + + python-dateutil 2.8.2 pyhd8ed1ab_0 conda-forge/noarch 246kB + + python-fastjsonschema 2.16.3 pyhd8ed1ab_0 conda-forge/noarch 225kB + + python_abi 3.10 3_cp310 conda-forge/linux-64 Cached + + pyyaml 6.0 py310h5764c6d_5 conda-forge/linux-64 176kB + + qt-main 5.15.6 h18908ee_6 conda-forge/linux-64 55MB + + readline 8.2 h8228510_1 conda-forge/linux-64 Cached + + requests 2.29.0 pyhd8ed1ab_0 conda-forge/noarch 57kB + + reretry 0.11.8 pyhd8ed1ab_0 conda-forge/noarch 12kB + + samtools 1.15.1 h6899075_1 bioconda/linux-64 406kB + + setuptools 67.7.2 pyhd8ed1ab_0 conda-forge/noarch 583kB + + sip 6.7.9 py310hc6cd4ac_0 conda-forge/linux-64 493kB + + six 1.16.0 pyh6c4a22f_0 conda-forge/noarch 14kB + + smart_open 6.3.0 pyhd8ed1ab_1 conda-forge/noarch 47kB + + smmap 3.0.5 pyh44b312d_0 conda-forge/noarch 23kB + + snakemake-minimal 7.25.4 pyhdfd78af_0 bioconda/noarch 266kB + + stopit 1.1.2 py_0 conda-forge/noarch 16kB + + tabulate 0.9.0 pyhd8ed1ab_1 conda-forge/noarch 36kB + + throttler 1.2.1 pyhd8ed1ab_0 conda-forge/noarch 11kB + + tk 8.6.12 h27826a3_0 conda-forge/linux-64 Cached + + toml 0.10.2 pyhd8ed1ab_0 conda-forge/noarch 18kB + + tomli 2.0.1 pyhd8ed1ab_0 conda-forge/noarch 16kB + + toposort 1.10 pyhd8ed1ab_0 conda-forge/noarch 14kB + + tornado 6.3.2 py310h2372a71_0 conda-forge/linux-64 639kB + + traitlets 5.9.0 pyhd8ed1ab_0 conda-forge/noarch 98kB + + typing-extensions 4.5.0 hd8ed1ab_0 conda-forge/noarch 10kB + + typing_extensions 4.5.0 pyha770c72_0 conda-forge/noarch 31kB + + tzdata 2023c h71feb2d_0 conda-forge/noarch Cached + + unicodedata2 15.0.0 py310h5764c6d_0 conda-forge/linux-64 512kB + + urllib3 1.26.15 pyhd8ed1ab_0 conda-forge/noarch Cached + + wheel 0.40.0 pyhd8ed1ab_0 conda-forge/noarch Cached + + wrapt 1.15.0 py310h1fa729e_0 conda-forge/linux-64 54kB + + xcb-util 0.4.0 h516909a_0 conda-forge/linux-64 20kB + + xcb-util-image 0.4.0 h166bdaf_0 conda-forge/linux-64 24kB + + xcb-util-keysyms 0.4.0 h516909a_0 conda-forge/linux-64 12kB + + xcb-util-renderutil 0.3.9 h166bdaf_0 conda-forge/linux-64 16kB + + xcb-util-wm 0.4.1 h516909a_0 conda-forge/linux-64 56kB + + xkeyboard-config 2.38 h0b41bf4_0 conda-forge/linux-64 882kB + + xorg-kbproto 1.0.7 h7f98852_1002 conda-forge/linux-64 27kB + + xorg-libice 1.0.10 h7f98852_0 conda-forge/linux-64 59kB + + xorg-libsm 1.2.3 hd9c2040_1000 conda-forge/linux-64 26kB + + xorg-libx11 1.8.4 h0b41bf4_0 conda-forge/linux-64 830kB + + xorg-libxau 1.0.11 hd590300_0 conda-forge/linux-64 14kB + + xorg-libxdmcp 1.1.3 h7f98852_0 conda-forge/linux-64 19kB + + xorg-libxext 1.3.4 h0b41bf4_2 conda-forge/linux-64 50kB + + xorg-libxrender 0.9.10 h7f98852_1003 conda-forge/linux-64 33kB + + xorg-renderproto 0.11.1 h7f98852_1002 conda-forge/linux-64 10kB + + xorg-xextproto 7.3.0 h0b41bf4_1003 conda-forge/linux-64 30kB + + xorg-xproto 7.0.31 h7f98852_1007 conda-forge/linux-64 75kB + + xz 5.2.6 h166bdaf_0 conda-forge/linux-64 Cached + + yaml 0.2.5 h7f98852_2 conda-forge/linux-64 89kB + + yte 1.5.1 py310hff52083_1 conda-forge/linux-64 18kB + + zipp 3.15.0 pyhd8ed1ab_0 conda-forge/noarch 17kB + + zlib 1.2.13 h166bdaf_4 conda-forge/linux-64 94kB + + zstd 1.5.2 h3eb15da_6 conda-forge/linux-64 Cached + + Summary: + + Install: 230 packages + + Total download: 357MB + +─────────────────────────────────────────────────────────────────────────────────────────────────── + + + + +Downloading and Extracting Packages + +Preparing transaction: ...working... +done + +Verifying transaction: ...working... +done + +Executing transaction: ...working... + + +done + +# +# To activate this environment, use +# +# $ conda activate snakemake-tutorial +# +# To deactivate an active environment, use +# +# $ conda deactivate + + + ---> 1c115b179fb8 + +Step 6/16 : env PATH /root/mambaforge/envs/snakemake-tutorial/bin:$PATH + + + ---> Running in 95f9cd4a0f89 + + ---> 38bcbc3eaccf + +Step 7/16 : copy latch /root/latch + + + ---> ba86df280c15 + +Step 8/16 : run cd /root/latch && python3 -m pip install -e . + + + ---> Running in 1ec44e1a4125 + +Obtaining file:///root/latch + + Installing build dependencies: started + + Installing build dependencies: finished with status 'done' + + Checking if build backend supports build_editable: started + + Checking if build backend supports build_editable: finished with status 'done' + + Getting requirements to build editable: started + + Getting requirements to build editable: finished with status 'done' + + Preparing editable metadata (pyproject.toml): started + + Preparing editable metadata (pyproject.toml): finished with status 'done' + +Collecting asyncssh==2.12.0 (from latch==2.19.11) + + Downloading asyncssh-2.12.0-py3-none-any.whl (346 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 346.7/346.7 kB 10.5 MB/s eta 0:00:00 + + +Collecting aioconsole==0.5.1 (from latch==2.19.11) + + Downloading aioconsole-0.5.1-py3-none-any.whl (30 kB) + +Collecting kubernetes>=24.2.0 (from latch==2.19.11) + + Downloading kubernetes-26.1.0-py2.py3-none-any.whl (1.4 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.4/1.4 MB 52.6 MB/s eta 0:00:00 + + +Collecting pyjwt>=0.2.0 (from latch==2.19.11) + + Downloading PyJWT-2.7.0-py3-none-any.whl (22 kB) + +Requirement already satisfied: requests>=2.28.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from latch==2.19.11) (2.29.0) + +Collecting click>=8.0 (from latch==2.19.11) + + Downloading click-8.1.3-py3-none-any.whl (96 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 96.6/96.6 kB 13.3 MB/s eta 0:00:00 + + +Collecting docker>=5.0 (from latch==2.19.11) + + Downloading docker-6.1.2-py3-none-any.whl (148 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 148.1/148.1 kB 20.4 MB/s eta 0:00:00 + + +Collecting paramiko>=2.11.0 (from latch==2.19.11) + + Downloading paramiko-3.1.0-py3-none-any.whl (211 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 211.2/211.2 kB 22.3 MB/s eta 0:00:00 + + +Collecting scp>=0.14.0 (from latch==2.19.11) + + Downloading scp-0.14.5-py2.py3-none-any.whl (8.7 kB) + +Collecting boto3>=1.24.22 (from latch==2.19.11) + + Using cached boto3-1.26.137-py3-none-any.whl (135 kB) + +Collecting tqdm>=4.63.0 (from latch==2.19.11) + + Downloading tqdm-4.65.0-py3-none-any.whl (77 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 77.1/77.1 kB 10.7 MB/s eta 0:00:00 + + +Collecting lytekit==0.14.10 (from latch==2.19.11) + + Downloading lytekit-0.14.10-py3-none-any.whl (391 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 391.8/391.8 kB 34.1 MB/s eta 0:00:00 + + +Collecting lytekitplugins-pods==0.4.0 (from latch==2.19.11) + + Downloading lytekitplugins_pods-0.4.0-py3-none-any.whl (4.3 kB) + +Requirement already satisfied: typing-extensions==4.5.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from latch==2.19.11) (4.5.0) + +Collecting apscheduler==3.9.1 (from latch==2.19.11) + + Downloading APScheduler-3.9.1-py2.py3-none-any.whl (59 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 59.5/59.5 kB 8.6 MB/s eta 0:00:00 + + +Collecting uvloop==0.17.0 (from latch==2.19.11) + + Downloading uvloop-0.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.1 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.1/4.1 MB 70.6 MB/s eta 0:00:00 + + +Collecting websockets==10.3 (from latch==2.19.11) + + Downloading websockets-10.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (111 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 111.5/111.5 kB 12.4 MB/s eta 0:00:00 + + +Collecting prompt-toolkit==3.0.33 (from latch==2.19.11) + + Downloading prompt_toolkit-3.0.33-py3-none-any.whl (383 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 383.6/383.6 kB 39.0 MB/s eta 0:00:00 + + +Collecting watchfiles==0.18.1 (from latch==2.19.11) + + Downloading watchfiles-0.18.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.2 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.2/1.2 MB 63.9 MB/s eta 0:00:00 + + +Collecting gql==3.4.0 (from latch==2.19.11) + + Downloading gql-3.4.0-py2.py3-none-any.whl (65 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 65.2/65.2 kB 10.1 MB/s eta 0:00:00 + + +Collecting graphql-core==3.2.3 (from latch==2.19.11) + + Downloading graphql_core-3.2.3-py3-none-any.whl (202 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 202.9/202.9 kB 25.7 MB/s eta 0:00:00 + + +Collecting requests-toolbelt==0.10.1 (from latch==2.19.11) + + Downloading requests_toolbelt-0.10.1-py2.py3-none-any.whl (54 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 54.5/54.5 kB 8.1 MB/s eta 0:00:00 + + +Requirement already satisfied: snakemake>=7.25.4 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from latch==2.19.11) (7.25.4) + +Requirement already satisfied: setuptools>=0.7 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from apscheduler==3.9.1->latch==2.19.11) (67.7.2) + +Requirement already satisfied: six>=1.4.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from apscheduler==3.9.1->latch==2.19.11) (1.16.0) + +Collecting pytz (from apscheduler==3.9.1->latch==2.19.11) + + Downloading pytz-2023.3-py2.py3-none-any.whl (502 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 502.3/502.3 kB 44.6 MB/s eta 0:00:00 + + +Collecting tzlocal!=3.*,>=2.0 (from apscheduler==3.9.1->latch==2.19.11) + + Downloading tzlocal-5.0.1-py3-none-any.whl (20 kB) + +Requirement already satisfied: cryptography>=3.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from asyncssh==2.12.0->latch==2.19.11) (39.0.0) + +Collecting yarl<2.0,>=1.6 (from gql==3.4.0->latch==2.19.11) + + Downloading yarl-1.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (268 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 268.8/268.8 kB 30.1 MB/s eta 0:00:00 + + +Collecting backoff<3.0,>=1.11.1 (from gql==3.4.0->latch==2.19.11) + + Downloading backoff-2.2.1-py3-none-any.whl (15 kB) + +Collecting lyteidl==0.2.0a0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading lyteidl-0.2.0a0-py3-none-any.whl (162 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 162.2/162.2 kB 21.3 MB/s eta 0:00:00 + + +Requirement already satisfied: wheel<1.0.0,>=0.30.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (0.40.0) + +Collecting pandas<2.0.0,>=1.0.0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading pandas-1.5.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (12.1 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 12.1/12.1 MB 68.4 MB/s eta 0:00:00 + + +Collecting pyarrow<7.0.0,>=4.0.0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading pyarrow-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (25.6 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 25.6/25.6 MB 46.2 MB/s eta 0:00:00 + + +Collecting croniter<4.0.0,>=0.3.20 (from lytekit==0.14.10->latch==2.19.11) + + Downloading croniter-1.3.14-py2.py3-none-any.whl (18 kB) + +Collecting deprecated<2.0,>=1.0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading Deprecated-1.2.13-py2.py3-none-any.whl (9.6 kB) + +Collecting docker>=5.0 (from latch==2.19.11) + + Downloading docker-5.0.3-py2.py3-none-any.whl (146 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 146.2/146.2 kB 19.9 MB/s eta 0:00:00 + + +Requirement already satisfied: python-dateutil>=2.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (2.8.2) + +Collecting grpcio!=1.45.0,<2.0,>=1.43.0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading grpcio-1.54.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.1 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 5.1/5.1 MB 69.4 MB/s eta 0:00:00 + + +Collecting grpcio-status!=1.45.0,>=1.43 (from lytekit==0.14.10->latch==2.19.11) + + Downloading grpcio_status-1.54.2-py3-none-any.whl (5.1 kB) + +Collecting protobuf<4,>=3.6.1 (from lytekit==0.14.10->latch==2.19.11) + + Downloading protobuf-3.20.3-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (1.1 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.1/1.1 MB 63.6 MB/s eta 0:00:00 + + +Collecting python-json-logger>=2.0.0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading python_json_logger-2.0.7-py3-none-any.whl (8.1 kB) + +Collecting pytimeparse<2.0.0,>=1.1.8 (from lytekit==0.14.10->latch==2.19.11) + + Downloading pytimeparse-1.1.8-py2.py3-none-any.whl (10.0 kB) + +Requirement already satisfied: pyyaml in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (6.0) + +Collecting keyring>=18.0.1 (from lytekit==0.14.10->latch==2.19.11) + + Downloading keyring-23.13.1-py3-none-any.whl (37 kB) + +Collecting responses>=0.10.7 (from lytekit==0.14.10->latch==2.19.11) + + Downloading responses-0.23.1-py3-none-any.whl (52 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 52.1/52.1 kB 6.9 MB/s eta 0:00:00 + + +Collecting sortedcontainers<3.0.0,>=1.5.9 (from lytekit==0.14.10->latch==2.19.11) + + Downloading sortedcontainers-2.4.0-py2.py3-none-any.whl (29 kB) + +Collecting statsd<4.0.0,>=3.0.0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading statsd-3.3.0-py2.py3-none-any.whl (11 kB) + +Requirement already satisfied: urllib3<2.0.0,>=1.22 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (1.26.15) + +Requirement already satisfied: wrapt<2.0.0,>=1.0.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (1.15.0) + +Collecting retry==0.9.2 (from lytekit==0.14.10->latch==2.19.11) + + Downloading retry-0.9.2-py2.py3-none-any.whl (8.0 kB) + +Collecting dataclasses-json>=0.5.2 (from lytekit==0.14.10->latch==2.19.11) + + Downloading dataclasses_json-0.5.7-py3-none-any.whl (25 kB) + +Requirement already satisfied: jsonschema>=4.5.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (4.17.3) + +Collecting marshmallow-jsonschema>=0.12.0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading marshmallow_jsonschema-0.13.0-py3-none-any.whl (11 kB) + +Collecting natsort>=7.0.1 (from lytekit==0.14.10->latch==2.19.11) + + Downloading natsort-8.3.1-py3-none-any.whl (38 kB) + +Collecting docker-image-py>=0.1.10 (from lytekit==0.14.10->latch==2.19.11) + + Downloading docker-image-py-0.1.12.tar.gz (8.2 kB) + + Preparing metadata (setup.py): started + + Preparing metadata (setup.py): finished with status 'done' + +Collecting docstring-parser>=0.9.0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading docstring_parser-0.15-py3-none-any.whl (36 kB) + +Collecting diskcache>=5.2.1 (from lytekit==0.14.10->latch==2.19.11) + + Downloading diskcache-5.6.1-py3-none-any.whl (45 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 45.6/45.6 kB 6.9 MB/s eta 0:00:00 + + +Collecting cloudpickle>=2.0.0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading cloudpickle-2.2.1-py3-none-any.whl (25 kB) + +Collecting cookiecutter>=1.7.3 (from lytekit==0.14.10->latch==2.19.11) + + Downloading cookiecutter-2.1.1-py2.py3-none-any.whl (36 kB) + +Collecting numpy<1.22.0 (from lytekit==0.14.10->latch==2.19.11) + + Downloading numpy-1.21.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (15.9 MB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 15.9/15.9 MB 59.3 MB/s eta 0:00:00 + + +Collecting wcwidth (from prompt-toolkit==3.0.33->latch==2.19.11) + + Downloading wcwidth-0.2.6-py2.py3-none-any.whl (29 kB) + +Collecting anyio>=3.0.0 (from watchfiles==0.18.1->latch==2.19.11) + + Downloading anyio-3.6.2-py3-none-any.whl (80 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 80.6/80.6 kB 12.1 MB/s eta 0:00:00 + + +Collecting googleapis-common-protos (from lyteidl==0.2.0a0->lytekit==0.14.10->latch==2.19.11) + + Downloading googleapis_common_protos-1.59.0-py2.py3-none-any.whl (223 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 223.6/223.6 kB 27.8 MB/s eta 0:00:00 + + +Collecting protoc-gen-swagger (from lyteidl==0.2.0a0->lytekit==0.14.10->latch==2.19.11) + + Downloading protoc_gen_swagger-0.1.0-py2.py3-none-any.whl (9.4 kB) + +Collecting decorator>=3.4.2 (from retry==0.9.2->lytekit==0.14.10->latch==2.19.11) + + Downloading decorator-5.1.1-py3-none-any.whl (9.1 kB) + +Collecting py<2.0.0,>=1.4.26 (from retry==0.9.2->lytekit==0.14.10->latch==2.19.11) + + Downloading py-1.11.0-py2.py3-none-any.whl (98 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 98.7/98.7 kB 15.4 MB/s eta 0:00:00 + + +Collecting botocore<1.30.0,>=1.29.137 (from boto3>=1.24.22->latch==2.19.11) + + Using cached botocore-1.29.137-py3-none-any.whl (10.8 MB) + +Collecting jmespath<2.0.0,>=0.7.1 (from boto3>=1.24.22->latch==2.19.11) + + Using cached jmespath-1.0.1-py3-none-any.whl (20 kB) + +Collecting s3transfer<0.7.0,>=0.6.0 (from boto3>=1.24.22->latch==2.19.11) + + Using cached s3transfer-0.6.1-py3-none-any.whl (79 kB) + +Collecting websocket-client>=0.32.0 (from docker>=5.0->latch==2.19.11) + + Downloading websocket_client-1.5.2-py3-none-any.whl (56 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 56.6/56.6 kB 9.2 MB/s eta 0:00:00 + + +Requirement already satisfied: certifi>=14.05.14 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from kubernetes>=24.2.0->latch==2.19.11) (2023.5.7) + +Collecting google-auth>=1.0.1 (from kubernetes>=24.2.0->latch==2.19.11) + + Downloading google_auth-2.18.1-py2.py3-none-any.whl (178 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 178.9/178.9 kB 20.4 MB/s eta 0:00:00 + + +Collecting requests-oauthlib (from kubernetes>=24.2.0->latch==2.19.11) + + Downloading requests_oauthlib-1.3.1-py2.py3-none-any.whl (23 kB) + +Collecting bcrypt>=3.2 (from paramiko>=2.11.0->latch==2.19.11) + + Downloading bcrypt-4.0.1-cp36-abi3-manylinux_2_28_x86_64.whl (593 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 593.7/593.7 kB 46.7 MB/s eta 0:00:00 + + +Collecting pynacl>=1.5 (from paramiko>=2.11.0->latch==2.19.11) + + Downloading PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl (856 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 856.7/856.7 kB 53.9 MB/s eta 0:00:00 + + +Requirement already satisfied: charset-normalizer<4,>=2 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from requests>=2.28.1->latch==2.19.11) (3.1.0) + +Requirement already satisfied: idna<4,>=2.5 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from requests>=2.28.1->latch==2.19.11) (3.4) + +Requirement already satisfied: appdirs in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.4.4) + +Requirement already satisfied: configargparse in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.5.3) + +Requirement already satisfied: connection-pool>=0.0.3 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (0.0.3) + +Requirement already satisfied: datrie in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (0.8.2) + +Requirement already satisfied: docutils in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (0.20.1) + +Requirement already satisfied: gitpython in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (3.1.31) + +Requirement already satisfied: humanfriendly in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (10.0) + +Requirement already satisfied: jinja2<4.0,>=3.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (3.1.2) + +Requirement already satisfied: nbformat in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (5.8.0) + +Requirement already satisfied: psutil in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (5.9.5) + +Requirement already satisfied: pulp>=2.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (2.7.0) + +Requirement already satisfied: reretry in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (0.11.8) + +Requirement already satisfied: smart-open>=3.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (6.3.0) + +Requirement already satisfied: stopit in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.1.2) + +Requirement already satisfied: tabulate in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (0.9.0) + +Requirement already satisfied: throttler in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.2.1) + +Requirement already satisfied: toposort>=1.10 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.10) + +Requirement already satisfied: yte<2.0,>=1.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.5.1) + +Collecting sniffio>=1.1 (from anyio>=3.0.0->watchfiles==0.18.1->latch==2.19.11) + + Downloading sniffio-1.3.0-py3-none-any.whl (10 kB) + +Collecting binaryornot>=0.4.4 (from cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) + + Downloading binaryornot-0.4.4-py2.py3-none-any.whl (9.0 kB) + +Collecting jinja2-time>=0.2.0 (from cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) + + Downloading jinja2_time-0.2.0-py2.py3-none-any.whl (6.4 kB) + +Collecting python-slugify>=4.0.0 (from cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) + + Downloading python_slugify-8.0.1-py2.py3-none-any.whl (9.7 kB) + +Requirement already satisfied: cffi>=1.12 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from cryptography>=3.1->asyncssh==2.12.0->latch==2.19.11) (1.15.1) + +Collecting marshmallow<4.0.0,>=3.3.0 (from dataclasses-json>=0.5.2->lytekit==0.14.10->latch==2.19.11) + + Downloading marshmallow-3.19.0-py3-none-any.whl (49 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 49.1/49.1 kB 7.3 MB/s eta 0:00:00 + + +Collecting marshmallow-enum<2.0.0,>=1.5.1 (from dataclasses-json>=0.5.2->lytekit==0.14.10->latch==2.19.11) + + Downloading marshmallow_enum-1.5.1-py2.py3-none-any.whl (4.2 kB) + +Collecting typing-inspect>=0.4.0 (from dataclasses-json>=0.5.2->lytekit==0.14.10->latch==2.19.11) + + Downloading typing_inspect-0.8.0-py3-none-any.whl (8.7 kB) + +Collecting regex>=2019.4.14 (from docker-image-py>=0.1.10->lytekit==0.14.10->latch==2.19.11) + + Downloading regex-2023.5.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (769 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 769.7/769.7 kB 59.9 MB/s eta 0:00:00 + + +Collecting cachetools<6.0,>=2.0.0 (from google-auth>=1.0.1->kubernetes>=24.2.0->latch==2.19.11) + + Downloading cachetools-5.3.0-py3-none-any.whl (9.3 kB) + +Collecting pyasn1-modules>=0.2.1 (from google-auth>=1.0.1->kubernetes>=24.2.0->latch==2.19.11) + + Downloading pyasn1_modules-0.3.0-py2.py3-none-any.whl (181 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 181.3/181.3 kB 20.5 MB/s eta 0:00:00 + + +Collecting rsa<5,>=3.1.4 (from google-auth>=1.0.1->kubernetes>=24.2.0->latch==2.19.11) + + Downloading rsa-4.9-py3-none-any.whl (34 kB) + +INFO: pip is looking at multiple versions of grpcio-status to determine which version is compatible with other requirements. This could take a while. + +Collecting grpcio-status!=1.45.0,>=1.43 (from lytekit==0.14.10->latch==2.19.11) + + Downloading grpcio_status-1.54.0-py3-none-any.whl (5.1 kB) + + Downloading grpcio_status-1.53.1-py3-none-any.whl (5.1 kB) + + Downloading grpcio_status-1.53.0-py3-none-any.whl (5.1 kB) + + Downloading grpcio_status-1.51.3-py3-none-any.whl (5.1 kB) + + Downloading grpcio_status-1.51.1-py3-none-any.whl (5.1 kB) + + Downloading grpcio_status-1.50.0-py3-none-any.whl (14 kB) + + Downloading grpcio_status-1.49.1-py3-none-any.whl (14 kB) + +INFO: pip is looking at multiple versions of grpcio-status to determine which version is compatible with other requirements. This could take a while. + + Downloading grpcio_status-1.48.2-py3-none-any.whl (14 kB) + +Requirement already satisfied: MarkupSafe>=2.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from jinja2<4.0,>=3.0->snakemake>=7.25.4->latch==2.19.11) (2.1.2) + +Requirement already satisfied: attrs>=17.4.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from jsonschema>=4.5.1->lytekit==0.14.10->latch==2.19.11) (23.1.0) + +Requirement already satisfied: pyrsistent!=0.17.0,!=0.17.1,!=0.17.2,>=0.14.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from jsonschema>=4.5.1->lytekit==0.14.10->latch==2.19.11) (0.19.3) + +Collecting jaraco.classes (from keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) + + Downloading jaraco.classes-3.2.3-py3-none-any.whl (6.0 kB) + +Requirement already satisfied: importlib-metadata>=4.11.4 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) (6.6.0) + +Collecting SecretStorage>=3.2 (from keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) + + Downloading SecretStorage-3.3.3-py3-none-any.whl (15 kB) + +Collecting jeepney>=0.4.2 (from keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) + + Downloading jeepney-0.8.0-py3-none-any.whl (48 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 48.4/48.4 kB 7.3 MB/s eta 0:00:00 + + +Collecting types-PyYAML (from responses>=0.10.7->lytekit==0.14.10->latch==2.19.11) + + Downloading types_PyYAML-6.0.12.9-py3-none-any.whl (14 kB) + +Collecting multidict>=4.0 (from yarl<2.0,>=1.6->gql==3.4.0->latch==2.19.11) + + Downloading multidict-6.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (114 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 114.5/114.5 kB 14.5 MB/s eta 0:00:00 + + +Requirement already satisfied: dpath<3.0,>=2.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from yte<2.0,>=1.0->snakemake>=7.25.4->latch==2.19.11) (2.1.6) + +Requirement already satisfied: plac<2.0.0,>=1.3.4 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from yte<2.0,>=1.0->snakemake>=7.25.4->latch==2.19.11) (1.3.5) + +Requirement already satisfied: gitdb<5,>=4.0.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from gitpython->snakemake>=7.25.4->latch==2.19.11) (4.0.10) + +Requirement already satisfied: fastjsonschema in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from nbformat->snakemake>=7.25.4->latch==2.19.11) (2.16.3) + +Requirement already satisfied: jupyter-core in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from nbformat->snakemake>=7.25.4->latch==2.19.11) (5.3.0) + +Requirement already satisfied: traitlets>=5.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from nbformat->snakemake>=7.25.4->latch==2.19.11) (5.9.0) + +Collecting oauthlib>=3.0.0 (from requests-oauthlib->kubernetes>=24.2.0->latch==2.19.11) + + Downloading oauthlib-3.2.2-py3-none-any.whl (151 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 151.7/151.7 kB 17.6 MB/s eta 0:00:00 + + +Collecting chardet>=3.0.2 (from binaryornot>=0.4.4->cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) + + Downloading chardet-5.1.0-py3-none-any.whl (199 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 199.1/199.1 kB 24.8 MB/s eta 0:00:00 + + +Requirement already satisfied: pycparser in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from cffi>=1.12->cryptography>=3.1->asyncssh==2.12.0->latch==2.19.11) (2.21) + +Requirement already satisfied: smmap<6,>=3.0.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from gitdb<5,>=4.0.1->gitpython->snakemake>=7.25.4->latch==2.19.11) (3.0.5) + +Requirement already satisfied: zipp>=0.5 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from importlib-metadata>=4.11.4->keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) (3.15.0) + +Collecting arrow (from jinja2-time>=0.2.0->cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) + + Downloading arrow-1.2.3-py3-none-any.whl (66 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 66.4/66.4 kB 8.5 MB/s eta 0:00:00 + + +Requirement already satisfied: packaging>=17.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from marshmallow<4.0.0,>=3.3.0->dataclasses-json>=0.5.2->lytekit==0.14.10->latch==2.19.11) (23.1) + +Collecting pyasn1<0.6.0,>=0.4.6 (from pyasn1-modules>=0.2.1->google-auth>=1.0.1->kubernetes>=24.2.0->latch==2.19.11) + + Using cached pyasn1-0.5.0-py2.py3-none-any.whl (83 kB) + +Collecting text-unidecode>=1.3 (from python-slugify>=4.0.0->cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) + + Downloading text_unidecode-1.3-py2.py3-none-any.whl (78 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 78.2/78.2 kB 11.3 MB/s eta 0:00:00 + + +Collecting mypy-extensions>=0.3.0 (from typing-inspect>=0.4.0->dataclasses-json>=0.5.2->lytekit==0.14.10->latch==2.19.11) + + Downloading mypy_extensions-1.0.0-py3-none-any.whl (4.7 kB) + +Collecting more-itertools (from jaraco.classes->keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) + + Downloading more_itertools-9.1.0-py3-none-any.whl (54 kB) + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 54.2/54.2 kB 7.8 MB/s eta 0:00:00 + + +Requirement already satisfied: platformdirs>=2.5 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from jupyter-core->nbformat->snakemake>=7.25.4->latch==2.19.11) (3.5.1) + +WARNING: The candidate selected for download or install is a yanked version: 'apscheduler' candidate (version 3.9.1 at https://files.pythonhosted.org/packages/e4/9f/c3937d4babe62504b874d4bf2c0d85aa69c7f59fa84cf6050f3b9dc5d83e/APScheduler-3.9.1-py2.py3-none-any.whl (from https://pypi.org/simple/apscheduler/) (requires-python:>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4)) +Reason for being yanked: Not compatible with Python 2.7 + +Building wheels for collected packages: latch, docker-image-py + + Building editable for latch (pyproject.toml): started + + Building editable for latch (pyproject.toml): finished with status 'done' + + Created wheel for latch: filename=latch-2.19.11-0.editable-py3-none-any.whl size=3728 sha256=99f87f896350c5424c539c4f3a3aae13c22ac4c8712d098aad89f087721ddffd + + Stored in directory: /tmp/pip-ephem-wheel-cache-26oiq4k4/wheels/66/25/3a/f25ede02a4206d090762dd0ca4dbdc81da4d61e154ed692990 + + Building wheel for docker-image-py (setup.py): started + + Building wheel for docker-image-py (setup.py): finished with status 'done' + + Created wheel for docker-image-py: filename=docker_image_py-0.1.12-py3-none-any.whl size=8812 sha256=433616dac59187300c1a2a34fb46d818e7098983f2031e72ee00be9a7c146420 + + Stored in directory: /root/.cache/pip/wheels/fb/45/02/503244da15fbcecde5c3edabb744ed0c4f9a7643126b2d222c + +Successfully built latch docker-image-py + +Installing collected packages: wcwidth, types-PyYAML, text-unidecode, statsd, sortedcontainers, pytz, pytimeparse, websockets, websocket-client, uvloop, tzlocal, tqdm, sniffio, regex, python-slugify, python-json-logger, pyjwt, pyasn1, py, protobuf, prompt-toolkit, oauthlib, numpy, natsort, mypy-extensions, multidict, more-itertools, marshmallow, jmespath, jeepney, grpcio, graphql-core, docstring-parser, diskcache, deprecated, decorator, cloudpickle, click, chardet, cachetools, bcrypt, backoff, aioconsole, yarl, typing-inspect, rsa, retry, responses, requests-toolbelt, requests-oauthlib, pynacl, pyasn1-modules, pyarrow, protoc-gen-swagger, pandas, marshmallow-jsonschema, marshmallow-enum, jaraco.classes, googleapis-common-protos, docker-image-py, docker, croniter, botocore, binaryornot, arrow, apscheduler, anyio, watchfiles, SecretStorage, s3transfer, paramiko, lyteidl, jinja2-time, grpcio-status, gql, google-auth, dataclasses-json, asyncssh, scp, kubernetes, keyring, cookiecutter, boto3, lytekit, lytekitplugins-pods, latch + + Attempting uninstall: numpy + + Found existing installation: numpy 1.24.3 + + Uninstalling numpy-1.24.3: + + Successfully uninstalled numpy-1.24.3 + +Successfully installed SecretStorage-3.3.3 aioconsole-0.5.1 anyio-3.6.2 apscheduler-3.9.1 arrow-1.2.3 asyncssh-2.12.0 backoff-2.2.1 bcrypt-4.0.1 binaryornot-0.4.4 boto3-1.26.137 botocore-1.29.137 cachetools-5.3.0 chardet-5.1.0 click-8.1.3 cloudpickle-2.2.1 cookiecutter-2.1.1 croniter-1.3.14 dataclasses-json-0.5.7 decorator-5.1.1 deprecated-1.2.13 diskcache-5.6.1 docker-5.0.3 docker-image-py-0.1.12 docstring-parser-0.15 google-auth-2.18.1 googleapis-common-protos-1.59.0 gql-3.4.0 graphql-core-3.2.3 grpcio-1.54.2 grpcio-status-1.48.2 jaraco.classes-3.2.3 jeepney-0.8.0 jinja2-time-0.2.0 jmespath-1.0.1 keyring-23.13.1 kubernetes-26.1.0 latch-2.19.11 lyteidl-0.2.0a0 lytekit-0.14.10 lytekitplugins-pods-0.4.0 marshmallow-3.19.0 marshmallow-enum-1.5.1 marshmallow-jsonschema-0.13.0 more-itertools-9.1.0 multidict-6.0.4 mypy-extensions-1.0.0 natsort-8.3.1 numpy-1.21.6 oauthlib-3.2.2 pandas-1.5.3 paramiko-3.1.0 prompt-toolkit-3.0.33 protobuf-3.20.3 protoc-gen-swagger-0.1.0 py-1.11.0 pyarrow-6.0.1 pyasn1-0.5.0 pyasn1-modules-0.3.0 pyjwt-2.7.0 pynacl-1.5.0 python-json-logger-2.0.7 python-slugify-8.0.1 pytimeparse-1.1.8 pytz-2023.3 regex-2023.5.5 requests-oauthlib-1.3.1 requests-toolbelt-0.10.1 responses-0.23.1 retry-0.9.2 rsa-4.9 s3transfer-0.6.1 scp-0.14.5 sniffio-1.3.0 sortedcontainers-2.4.0 statsd-3.3.0 text-unidecode-1.3 tqdm-4.65.0 types-PyYAML-6.0.12.9 typing-inspect-0.8.0 tzlocal-5.0.1 uvloop-0.17.0 watchfiles-0.18.1 wcwidth-0.2.6 websocket-client-1.5.2 websockets-10.3 yarl-1.9.2 + +WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv + + ---> e6903b7577c6 + +Step 9/16 : copy Snakefile config.yaml /root/ + + + ---> 93c3fe88c890 + +Step 10/16 : copy scripts/plot-quals.py /root/scripts/plot-quals.py + + + ---> b476a36f6f9c + +Step 11/16 : copy .latch/latch_entrypoint.py /root/latch_entrypoint.py + + + ---> 75cead0538d5 + +Step 12/16 : arg tag + + + ---> Running in 7008c22c3f2f + + ---> 9d8c1d4b5439 + +Step 13/16 : env FLYTE_INTERNAL_IMAGE $tag + + + ---> Running in a2dae98974d2 + + ---> 937b6876b211 + +Step 14/16 : env LATCH_SDK_DOMAIN "ligma.ai" + + + ---> Running in 55f4bfc3f1d1 + + ---> 166b7adade89 + +Step 15/16 : env LATCH_AUTHENTICATION_ENDPOINT https://nucleus.ligma.ai + + + ---> Running in 813f919f4581 + + ---> a58bd3d35779 + +Step 16/16 : workdir /root + + + ---> Running in 7a31c27da0c0 + + ---> 6157f3b85044 + +Successfully built 6157f3b85044 + +Successfully tagged 812206152185.dkr.ecr.us-west-2.amazonaws.com/x1_test_latch_register:0.0.0-cddce8 + diff --git a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-dc4ace/docker-build-logs.txt b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-dc4ace/docker-build-logs.txt new file mode 100644 index 00000000..3e113e62 --- /dev/null +++ b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-dc4ace/docker-build-logs.txt @@ -0,0 +1,61 @@ +Step 1/15 : from 812206152185.dkr.ecr.us-west-2.amazonaws.com/latch-base:9c8f-main + + + ---> b253e8cdab51 + +Step 2/15 : run mkdir /opt/latch + + + ---> Using cache + + ---> 89e0ab657f0d + +Step 3/15 : RUN curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh && mkdir /root/.conda && bash Mambaforge-Linux-x86_64.sh -b && rm -f Mambaforge-Linux-x86_64.sh + + + ---> Using cache + + ---> 7741d9d31977 + +Step 4/15 : copy environment.yaml /root/environment.yaml + + + ---> Using cache + + ---> c2d3f498d2d5 + +Step 5/15 : run /root/mambaforge/bin/mamba env create --name snakemake-tutorial --file environment.yaml + + + ---> Using cache + + ---> 0370179f98b9 + +Step 6/15 : env PATH /root/mambaforge/envs/snakemake-tutorial/bin:$PATH + + + ---> Using cache + + ---> 558ea5988368 + +Step 7/15 : run python3 -m pip install latch + + + ---> Using cache + + ---> 73f3b443e340 + +Step 8/15 : copy Snakefile config.yaml /root/ + + + ---> da1c8fa40657 + +Step 9/15 : copy scripts/plot-quals.py /root/scripts/plot-quals.py + + + ---> 6e0a5622727c + +Step 10/15 : copy .latch/latch_entrypoint.py /root/latch_entrypoint.py + + +COPY failed: file not found in build context or excluded by .dockerignore: stat .latch/latch_entrypoint.py: file does not exist diff --git a/latch_cli/services/init/new_example_snakemake/Dockerfile b/latch_cli/services/init/new_example_snakemake/Dockerfile new file mode 100644 index 00000000..e7ac1c14 --- /dev/null +++ b/latch_cli/services/init/new_example_snakemake/Dockerfile @@ -0,0 +1,25 @@ +from 812206152185.dkr.ecr.us-west-2.amazonaws.com/latch-base:fe0b-main + +RUN curl -L -O \ + https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh \ + && mkdir /root/.conda \ + && bash Mambaforge-Linux-x86_64.sh -b \ + && rm -f Mambaforge-Linux-x86_64.sh + +copy environment.yaml /root/environment.yaml + +run /root/mambaforge/bin/mamba env create --name snakemake-tutorial --file environment.yaml +env PATH /root/mambaforge/envs/snakemake-tutorial/bin:$PATH + +# Latch SDK +# DO NOT REMOVE +run pip install latch==2.32.6 +run mkdir /opt/latch + +copy . /root/ + +copy .latch/jit_entrypoint.py /root/jit_entrypoint.py + +arg tag +env FLYTE_INTERNAL_IMAGE $tag +workdir /root diff --git a/latch_cli/services/init/new_example_snakemake/Snakefile b/latch_cli/services/init/new_example_snakemake/Snakefile new file mode 100644 index 00000000..03a9e038 --- /dev/null +++ b/latch_cli/services/init/new_example_snakemake/Snakefile @@ -0,0 +1,88 @@ +from latch.types.metadata import SnakemakeMetadata, SnakemakeFileParameter +from latch.types.directory import LatchDir +from latch.types.metadata import LatchAuthor, LatchMetadata, LatchParameter + +SnakemakeMetadata( + output_dir = LatchDir("latch:///sample_output"), + display_name="snakemake_tutorial_workflow", + author=LatchAuthor( + name="Kenneth", + ), + parameters={ + "samples" : SnakemakeFileParameter( + display_name="Sample Input Directory", + description="A directory full of FastQ files", + type=LatchDir, + path=Path("data/samples"), + ), + "ref_genome" : SnakemakeFileParameter( + display_name="Indexed Reference Genome", + description="A directory with a reference Fasta file and the 6 index files produced from `bwa index`", + type=LatchDir, + path=Path("genome"), + ), + }, +) + +SAMPLES = ["A", "B"] + + +rule all: + input: + "plots/quals.svg" + + +rule bwa_map: + input: + "genome/genome.fa", + "data/samples/{sample}.fastq", + "genome/genome.fa.amb", + "genome/genome.fa.ann", + "genome/genome.fa.bwt", + "genome/genome.fa.fai", + "genome/genome.fa.pac", + "genome/genome.fa.sa" + output: + "mapped_reads/{sample}.bam" + shell: + "bwa mem genome/genome.fa data/samples/{wildcards.sample}.fastq | samtools view -Sb - > {output}" + + +rule samtools_sort: + input: + "mapped_reads/{sample}.bam" + output: + "sorted_reads/{sample}.bam" + shell: + "samtools sort -T sorted_reads/{wildcards.sample} " + "-O bam {input} > {output}" + + +rule samtools_index: + input: + "sorted_reads/{sample}.bam" + output: + "sorted_reads/{sample}.bam.bai" + shell: + "samtools index {input}" + + +rule bcftools_call: + input: + fa="genome/genome.fa", + bam=expand("sorted_reads/{sample}.bam", sample=SAMPLES), + bai=expand("sorted_reads/{sample}.bam.bai", sample=SAMPLES) + output: + "calls/all.vcf" + shell: + "bcftools mpileup -f {input.fa} {input.bam} | " + "bcftools call -mv - > {output}" + + +rule plot_quals: + input: + "calls/all.vcf" + output: + "plots/quals.svg" + script: + "scripts/plot-quals.py" diff --git a/latch_cli/services/init/new_example_snakemake/config.yaml b/latch_cli/services/init/new_example_snakemake/config.yaml new file mode 100644 index 00000000..0de1d041 --- /dev/null +++ b/latch_cli/services/init/new_example_snakemake/config.yaml @@ -0,0 +1,5 @@ +samples: + A: data/samples/A.fastq + B: data/samples/B.fastq + +prior_mutation_rate: 0.001 diff --git a/latch_cli/services/init/new_example_snakemake/data/genome.fa b/latch_cli/services/init/new_example_snakemake/data/genome.fa new file mode 100644 index 00000000..63982cc2 --- /dev/null +++ b/latch_cli/services/init/new_example_snakemake/data/genome.fa @@ -0,0 +1,3838 @@ +>I dna_rm:chromosome chromosome:R64-1-1:I:1:230218:1 REF +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNTCCTAACACTACCCTAACACAGCCCTAATCTAACCCTGGCCAACCTGTCTCTCAACTT +ACCCTCCATTACCCTGCCTCCACTCGTTACCCTGTCCCATTCAACCATACCACTCCGAAC +CACCATCCATCCCTCTACTTACTACCACTCACCCACCGTTACCCTCCAATTACCCATATC +CAACCCACTGCCACTTACCCTACCATTACCCTACCATCCACCATGACCTACTCACCATAC +TGTTCTTCTACCCACCATATTGAAACGCTAACAAATGATCGTAAATAACACACACGTGCT +TACCCTACCACTTTATACCACCACCACATGCCATACTCACCCTCACTTGTATACTGATTT +TACGTACGCACACGGATGCTACAGTATATACCATCTCAAACTTACCCTACTCTCAGATTC +CACTTCACTCCATGGCCCATCTCTCACTGAATCAGTACCAAATGCACTCACATCATTATG +CACGGCACTTGCCTCAGCGGTCTATACCCTGTGCCATTTACCCATAACGCCCATCATTAT +CCACATTTTGATATCTATATCTCATTCGGCGGTCCCAAATATTGTATAACTGCCCTTAAT +ACATACGTTATACCACTTTTGCACCATATACTTACCACTCCATTTATATACACTTATGTC +AATATTACAGAAAAATCCCCACAAAAATCACCTAAACATAAAAATATTCTACTTTTCAAC +AATAATACATAAACATATTGGCTTGTGGTAGCAACACTATCATGGTATCACTAACGTAAA +AGTTCCTCAATATTGCAATTTGCTTGAACGGATGCTATTTCAGAATATTTCGTACTTACA +CAGGCCATACATTAGAATAATATGTCACATCACTGTCGTAACACTCTTTATTCACCGAGC +AATAATACGGTAGTGGCTCAAACTCATGCGGGTGCTATGATACAATTATATCTTATTTCC +ATTCCCATATGCTAACCGCAATATCCTAAAAGCATAACTGATGCATCTTTAATCTTGTAT +GTGACACTACTCATACGAAGGGACTATATCTAGTCAAGACGATACTGTGATAGGTACGTT +ATTTAATAGGATCTATAACGAAATGTCAAATAATTTTACGGTAATATAACTTATCAGCGG +CGTATACTAAAACGGACGTTACGATATTGTCTCACTTCATCTTACCACCCTCTATCTTAT +TGCTGATAGAACACTAACCCCTCAGCTTTATTTCTAGTTACAGTTACACAAAAAACTATG +CCAACCCAGAAATCTTGATATTTTACGTGTCAAAAAATGAGGGTCTCTAAATGAGAGTTT +GGTACCATGACTTGTAACTCGCACTGCCCTGATCTGCAATCTTGTTCTTAGAAGTGACGC +ATATTCTATACGGCCCGACGCGACGCGCCAAAAAATGAAAAACGAAGCAGCGACTCATTT +TTATTTAAGGACAAAGGTTGCGAAGCCGCACATTTCCAATTTCATTGTTGTTTATTGGAC +ATACACTGTTAGCTTTATTACCGTCCACGTTTTTTCTACAATAGTGTAGAAGTTTCTTTC +TTATGTTCATCGTATTCATAAAATGCTTCACGAACACCGTCATTGATCAAATAGGTCTAT +AATATTAATATACATTTATATAATCTACGGTATTTATATCATCNNNNNNNNGTAGNNNNN +NNNNNNNNNNNNGTTCGTTAATTTTCAATTTCTATGGAAACCCGTTCGTAAAATTGGCGT +TTGTCTCTAGTTTGCGATAGTGTAGATACCGTCCTTGGATAGAGCACTGGAGATGGCTGG +CTTTAATCTGCTGGAGTACCATGGAACACCGGTGATCATTCTGGTCACTTGGTCTGGAGC +AATACCGGTCAACATGGTGGTGAAGTCACCGTAGTTGAAAACGGCTTCAGCAACTTCGAC +TGGGTAGGTTTCAGTTGGGTGGGCGGCTTGGAACATGTAGTATTGGGCTAAGTGAGCTCT +GATATCAGAGACGTAGACACCCAATTCCACCAAGTTGACTCTTTCGTCAGATTGAGCTAG +AGTGGTGGTTGCAGAAGCAGTAGCAGCGATGGCAGCGACACCAGCGGCGATTGAAGTTAA +TTTGACCATTGTATTTGTTTTGTTTGTTAGTGCTGATATAAGCTTAACAGGAAAGGAAAG +AATAAAGACATATTCTCAAAGGCATATAGTTGAAGCAGCTCTATTTATACCCATTCCCTC +ATGGGTTGTTGCTATTTAAACGATCGCTGACTGGCACCAGTTCCTCATCAAATATTCTCT +ATATCTCATCTTTCACACAATCTCATTATCTCTATGGAGATGCTCTTGTTTCTGAACGAA +TCATAAATCTTTCATAGGTTTCGTATGTGGAGTACTGTTTTATGGCGCTTATGTGTATTC +GTATGCGCAGAATGTGGGAATGCCAATTATAGGGGTGCCGAGGTGCCTTATAAAACCCTT +TTCTGTGCCTGTGACATTTCCTTTTTCGGTCAAAAAGAATATCCGAATTTTAGATTTGGA +CCCTCGTACAGAAGCTTATTGTCTAAGCCTGAATTCAGTCTGCTTTAAACGGCTTCCGCG +GAGGAAATATTTCCATCTCTTGAATTCGTACAACATTAAACGTGTGTTGGGAGTCGTATA +CTGTTAGGGTCTGTAAACTTGTGAACTCTCGGCAAATGCCTTGGTGCAATTACGTAATTT +TAGCCGCTGAGAAGCGGATGGTAATGAGACAAGTTGATATCAAACAGATACATATTTAAA +AGAGGGTACCGCTAATTTAGCAGGGCAGTATTATTGTAGTTTGATATGTACGGCTAACTG +AACCTAAGTAGGGATATGAGAGTAAGAACGTTCGGCTACTCTTCTTTCTAAGTGGGATTT +TTCTTAATCCTTGGATTCTTAAAAGGTTATTAAAGTTCCGCACAAAGAACGCTTGGAAAT +CGCATTCATCAAAGAACAACTCTTCGTTTTCCAAACAATCTTCCCGAAAAAGTAGCCGTT +CATTTCCCTTCCGATTTCATTCCTAGACTGCCAAATTTTTCTTGCTCATTTATAATGATT +GATAAGAATTGTATTTGTGTCCCATTCTCGTAGATAAAATTCTTGGATGTTAAAAAATTA +TTATTTTCTTCATAAAGAAGCTTTCAAGATATAAGATACGAAATAGGGGTTGATAATTGC +ATGACAGTAGCTTTAGATCAAAAAGGAAAGCATGGAGGGAAACAGTAAACAGTGAAAATT +CTCTTGAGAACCAAAGTAAACCTTCATTGAAGAGCTTCCTTAAAAAATTTAGAATCTCCC +ATGTCAACGGGTTTCCATACCTCCCCAGCATCATACATCTTTTTTCAAAGAAACTTCAAA +TGCCTCTTTTATGCAAGGGGCAAAATCCTGAAATGACTTAAACTTAGCAGTTTCGTCTTT +TTTCAAAGAGAATGGTTGAAGAAGAATTGTTTTGGACGCTTATTGACAATCTGTTGCATT +GATAAAGTACCTACTATCCCAGACTATATTTGTATACAAGTACAAAATTAGGTTTGTTGA +AACAACTTTCCGATCATTGGTGCCCGTATCTGATGTTTTTTTAGTAATTTCTTTGTAAAT +ACAGGGAGTTGTTTCGAAAGCTTATGAGAAAAATACATGAATGACAGGTAAAAATATTGG +CTCGAAAAAGAGGACAAAAAGAGAAATCATAAATGAGTAAACCCACTTGCTGGACATTAT +CCAGTAAAGGCTTGGTAGTAACCATAATATTACCCAGGTACGAAACGCTAAGAACTTGAA +AGACTCATAAAACTTCCAGGTTAAGCTATTTTTGAAAATATTCTGAGGTAAAAGCCATTA +AGGTCCAGATAACCAAGGGACAATAAACCTATGCTTTTCTTGTCTTCAATTTCAGTATCT +TTCCATTTTGATAATGAGCTAGTGATCCGGAAAGCTACTTTATGATGTTTCAAGGCCTGA +AGTTTGAATATTTATGTAGTTCAACATCAAATGTGTCTATTTTGTGATGAGGCAACCGTC +GACAACCTTATTATCGAAAAAGAACAACAAGTTCACATGCTTGTTACTCTCTATAACTAG +AGAGTACTTTTTTTGGAAGCAAGTAAGAATAAGTCAATTTCTACTTACCTCATTAGGGAA +AAATTTAATAGCAGTTGTTATAACGACAAATACAGGCCCTAAAAAATTCACTGTATTCAA +TGGTCTACGAATCGTCAATCGCTTGCGGTTATGGCACGAAGAACAATGCAATAGCTCTTA +CAAGCCACTACATGACAAGCAACTCATAATTTAAGTGGATAGCTTGTGATAAATTGAATT +TTCTCTGTTTAGTACTTGCCGAATAGTTACTTGTTAGTTGCAGATGCTTTTTGATGACAA +AGTTATCAATCTCAATATTAAACTTTTTAGGCTTTCAGGTTTAATCTTTCTTTGAGGGTG +TATTAATTTTCATACAAATATTTGATTCATTATTCGTTTTACTGTTACATTAGACCTGCT +CATTACATGGAGTAACTTAAGTTTTCTCAAACGCTTGATAGCATGATTTGATGTAGTNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNTTGTTAATCGACAAAGTTAATATTATGGTGGTAG +TATCTCAAATATCTGGATAACCAGATCGTACATCTCTGATAAACAATCTTTGCCACTGCT +TTATCCTTTTAAATTGTATTGAGTGCTTCAGTCATTGCAAAATTTTACGAGATTTAAAAT +TTGTGAACCCGACCTTACCGAGAAATGATGAGCTAATTTTTATAGGTCGACCCTTCTGTC +GCTTACTGGGTTGATTATCTTGTGCTTTCTTAGTATCTATCACAAAGGAGACAAAATCGT +TGATAAAAAGTGCATCAACATTCCCAGCCAGAAAATGCACATCATAAAGACATGTTATTC +AAGAGCCACGACCGTCTTCAATTTATCTTTTATAAAAAACCCTTGTTCTACTGACAGGAT +GGAATAGATATTAAATATACATTTTGCANNNNNNNNNNNNNCTGTATTGAAGATTTGTAT +ATGAAAGATGTTTATACATCAAATGCTTTGAATAAAGCCATCTTAATTTCAATTTCATGC +CCTCCTTCACCGTTTTCTGTTGGTCTAGAGGTAGCTTGTTGTGGTCACTAATGAGAACTT +AAATAGTTTTCAACTGCTGGTGATAAATCAATAATTTATGTTCTTAACCTAACATTTGAT +GACCTTTGATGCGTTGGTTATGTTGAAGACAAATTGCCTCTAATCAGTTCCATTAAGAAA +TCTTCTTAACTCCTCCAAATATTCTGCCCATACGATACCTATTTGTTTACTTTGTCATTT +TGCCATAAGATTGGTATCCACTTCTTGTCTGTAAAATAATTAGAAAGTAGCACAATTTTT +ACAGTAATGTAGCACGCGTAACTCCTAAACTTTGTCATAATGGTTGAAATGAATGTATGA +TATAAAAACTCGGACCCTGTTTTACTTCTTTTATAGAACCTTATTTTTGACGCAGGGAGG +CGACATTTATCCAAATTAAGTTTTGACATGGCGCATCAGGGAATNNNNNNNNCTTTATTA +TGTGGCCGAATCAACATTAATCAAATGCACTAATATTGTAACGTTCTTACAAAGGGCAGA +CAACTTGAGAACTTTCATGCGTGCAACAGTATTAATATTTTACTGTCTTGATATCGTTAT +CCTCATCGTAACGTGAATTTTTTTGTCTCATACGTTAAGGTAAATTTTGATGACCCCCGT +TGTCCTTGTTTGCCTTACTGTATAAAGCACCCTTTTATTGTTTAGAATACTAGAATGATA +ACTGCATTCGGACTATGAAAGAAAAAATGGTAGTAGCAAAGGATAGGCATCGCCGTATTT +ACTACTTTGTAAACCAGTGGATTTTTGCTCAACATATAAAAAACTAAAGACCTTTTTTTC +ATCAATATACTTCTGAGACGTGCAGATGTGATATTCGGGTTTGAGCTTGTAGTCAACGAA +GCGGGTTCATGGGCAAANNNNNNNNNNNNNNNNNNNNNNNNNGTCTAGATTATTTCGAAT +ATGAGTTAATCATACGTTGATTAGTACTGTTGGTCTCTCATTGAAATTTTACGTGACACC +ATCATTTTACTTCCACATAAGTTCTAATGTTACGTAGTTCAATTTTAGTCGACCTAGCTT +CATATTTATTTTAGAAGCAATTCGTAATTATCATTTTGCTTTCGAAGAAAATTAAGACTT +CATTTACTATTCTCGTGATATTTTAGTAGGCGCTTCTTTTGTATCGAACCATTTTATTGC +AATGGCCCTTAAGTTACCGTTATTCATACCAATTTGACGTTAATTTTAAATGCGTTCTGA +AGTTTCTTAAATAACCCGGATTGGTTAGGTTCAGCCATGCCTGGCGCGTACATTGAGGCA +TTAGAAGATCCGCAGATAAATAATAAGCTTAGTAAATCCTAAAGATAACAACTAAAATTA +TATTTCCATCAGCTCAATACCGCAGTACTTTGAAACCTGATTTATATATTGCAGAACTTA +ATTAAAAGTACATTGTAGTTCAAAAAATAAATATCAAACTTTTGGACCCTCTCTTATTGC +CTCCCAATTAATTAAAACATCTTTTCTTCCAATCTACAGGTTTGAAAAGGTAATAAGTAA +TATAAACTTGAGAACCNNNNNNNNNNNNNNNNNNNTACTGATCCTTACAGGTTTTAAGGT +TGCAAAGGGAACATTTATTGAAAGGAGCTAACAATAGTGGGTATGAGTAAAGATATATAG +ATCGATATTTTGAATTCTAAATGATGAACTAGGGAAGTAATTTAGGTGAAACATTGCAAC +CAATCATTTTACACTTTTGGTTGCACGTAATGTACCTTTTTATGATANNNNNNNNNNATA +GTAGTAGTGTGAAAATTTCTTCAGGACTTGCAAAAAGAATCTAACTGATCTTCGGATGAG +CCTTTATCGATTATTTTTTTCCTAAATATAATACTTTACAAGCGAATGTTTTGTTAGGAG +AAAGATATAAAAATTATGCGGCATAGGCATATTATCCAATAAAAAGGAAATTTATATATA +AACTTCATTTACGTCATAAGAAAATGTTAAGTTCTCTTAACGAAAACTGTGCGAATTTTG +TGTTAAAGCTGGATGATGAGAAATTATTCTCGTATTATTTTTCATCAGATACTGATAAGG +TTTCAACGTCTTTTGACGTTGGCTTTTCCACACCATGTTTAGAGTTATAAAGCACAATAC +CGTTCTTCTTGGCATTGTTCCTTTCATCACGTTTATAGAAGTAGAGTACAACAAAAGTCC +AAATGGAGAGACAAAAAGCAGAACATGCAGTGAAAGTAAACCCCTTTAAATACCTGGGAG +CTTCTTCTGTTTTCCAAACCAAAACACTTATCCATGCGGTAGATGATTGAGCCATAATAT +TCATTGTAACTAAAGTAATAGCTCTAGTTTGAGCATCTCGGCGACAAATATCGTTTTGCC +AAGAGTATAAAACAGGAGCCATAGCCCAACCAAAACATTGCAGCATAAATGCAAACCATT +TGGCTCCTTCTGCGACGTCCCAAGCGGCTAATATGGAGTTACCAATGATATTGAAAACCT +GAGTAAAAATAATCGCAAACCAACGAGAGTGTAATTTATCTGCAATAATACCAGTAAGCA +TCAAATAAACCATACCTAAACCCGGAGTAATCATGGATAACTGATTGAGCTTAGGAATAG +AGTATCTTTTCAAAGATTTCAACCATAGTAGGTATGCCCCAGATGAAACATTACTGTCAT +TCCAACAGAAAATATTCCATAAAGTTAAAATGTATATTTTCCAATCACTGAAAATTGTTT +TCCACAGTTTAATATCGAATACTTTTGTTTCAAAATCACTTTTACCTGTTTGGTTTTCTT +TTAATCTTTTCCTCGCCAACCTAATTTCATCATCAGTTAAGAAAATAGAATAACAGTTGT +ATGGGTCACCTGGCAGGGAGTAAAATCCAATAAGGCCCACTACGACAGACACAATAGCGT +CAATAATAAAGTTCCATCTCCATCCCTCTAAACCATTTACACCATTTAACGATGAATATA +CGGCTGACTGGATCCCACCAGCGGATAGAATACCGATATACTGGCCCAAATAGTAAAAAG +CAGAACGACGCACCATTTCATCATGTTTGTAAAAGGAACCAAACAAATATTGGTATGCCA +AATAACTTGGCGCTTCAAAAGCCCCAATGAAAAACCTAATTGCTTTCAAGTGTGGTACAG +AATTGACATATGCAGCACCAACGGTTAAAAGCGACCAACATAAGTCGAGGCTTGGTAAAA +CATAGTTTAATGGGAGCTTGTTCAGGTAAATCAAAAATGGCAATTGAAATATAATATTAC +CAACTGTGTACATTACTTGAGTATGCACCAAATCATTACCTTGAAAGCCTAAATCTTCCT +TCATTCCCGAAACGTAAGCGTTGTTTATATTAACCGTATCCAGATATTTCACCCAATAAG +CAATACAAGAATAAAAGGCTAAAAGGACATCCAATTTAATTAATAANNNNNNNNCTTTGA +AAGAGGTACCCTGTTTGAACCAACTATACCATTTATTGTGAGATCTTTCCTTTTCATTGA +TCCGATACTCTTGTTCATCGAAAAATCTCCACCATGGCCTATCGGCTTCATCTCTATATT +CATAACTTCTAGTAACGTTCACATTGTCTTTATGTTCACTATAGCTACTAGTCTCAAAAT +GTAGTTGATCTTTTTCACTTGTAGTCGTGATGAAATTTTCAGCTGTTTCATGACTCTGGA +TACTGTTGGAGATAGTGACAATTTCTGTTGAATTTAAGTCATCTGGCAGGTCTTCCACCT +GCCGCTTTACTGGAATAAAACCCCATTTTAGTCTTTTGTAAGGATCTACAATAATCTCTT +TAACAATTGAATACATGTATGTTATTTATATATGCAGTAGTTCTCTTTGTAANNNNNNNN +AACAAATAGAGAGTAAGATATGTAGCGAATGTCCATTCATCATAACAGGTAAACTAGATG +CTCTTTTATATAGTCTGGTTGTATAAATAATTTATATCCTCATCTAAACGCATGTCTCCG +CTTGGTTTCTTATCTATTTGTGGAGGCACCCGTAGTACTGTGCNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNCCAGTGACACAATCTTTACCATTACACAGTTTTT +ACTATTTCTAATGATTACATTGGACCATCGGAAAACTGCGCTAACTTTGGATAACGCCAC +AGAACGTGATCTGACTATTGTAAAGGTGTCATTCGGTAAGGTAAACCTTCAAGGCGTCCA +CACCTTTAACCATATAACAGCGTAAACTCTTGTTAAAATACAGGGGTAAGACATTGGTGG +ATATTCAACAAGATCCGATACCTCCAATTCCGATTTCTACAAATTGTGCTCTACATATTA +CTGCGATGCAATTATCCACACATAAAATCGATGCCTTTAGAAAAAGACATAAAGCAGACG +GCATTGTAGATATTTGACCAATTAGAATTGAATGAGATGAATATCTCACCAAGCTATTCG +ATATTATAGATAAAGTTTGTATCTTAGTTATGCATTGTGAGTTGGTTGCTCTACTCGCGG +TTACCAGTCTCTTCTAAAAAATCTAAGGCCAATGGTATCCATGACATTTCTGCACTTTTT +GTAATTGGTTTAGTTATGAAAGGAACGTCAAACCAAATGGTTTTTCAGATAAGAAATTGA +CAGTATCTGAGAATTTGCTATCAAAGCTCAGAGGATTTACATATTTTAACGTAATTAAAA +CATTTTTATGTTCGATATATTAGCAAATAGCGTATTAATATACAGCTGTTGCGCTCATGG +TAAAATTTAGCGATATACTTTGCATCTTGGCTGCAAAGAAGAATGAATCGGATATACTAT +TTTTGATCATAATGACGGACATCATGATATAATAACGTTATACGGATAACTTTATTTCAA +AAGCACCATCATGTTATCTCTTGTAAAAAGAAGTATTCTTCATTCAATACCAATTACTCG +TCACATTCTTCCAATCCAATTAATATTGGTTAAAATGAACCATGTGCAAATCAGAAACAT +AAAATTATATCACTTTATTTCATATGGTTTCATGCTTACAAAGCTTACTGTCTTTCTCTT +TAACTTATTTTTCTACAGGCTACGAATTCTTTGCAGGCTTACTTTACTCATATTATCATT +ACCTGTACAAATATATATTAAAGAAATCCAAACAAAAATGCTTGAAAAGCATACAGCTTC +CGATACATCATGTATATAGAAAATCACAGTACAAAAATTTTGAATTTATGTATAACCGTT +TCGCCTGATATATGTAAGAGCTCTTGATTGTCGGAATAGTTCGGGAATTCTGGGTGGAAC +TAGTAGCTGGAGATGCGTTCTAAAGGATCTAAAATCAGACTCACCCCAAAAACCAAAATT +TTGATATTCAACTTTAGTATTAGCCAGTCTTAAAATGATTTTTTGCCAAGAAAGCCGAAG +TTTAACGAGCGTTTTAAAATATGCACAAGTCCATTAATTAAATTTGATCACAGTGATTAC +CAATTTTGTTGAAAGCAGTAATTTGTGACGTCCGTTTTTGGCACAAGTAAAAAATATTTG +TTTTGAAGTCTAGTTACAAGAAGCTACTGAAAACACAGGGCTGGATATAGATGTTTATAA +GCTCCTCCCATGGTCTAAGAGTTTCTCCAAACGCCTAATGTATGCAATTTGTTAAATAAA +AATGAAGAATAGATGCATAAACAAGCGTCATTAAAGTTCTTATCATTATTCCATGTAGAA +ATGACCTGCAAGTACGAGCTGGTTATGCGAAACTGAGCTTAACAACATAGTTTTCTTTTC +CATTGGCTTGGATATAAATTTTTCGCTGAGAAACTTCTCTGCATTTTTTAAGCATTAAGC +GTACATAACATAAAGTCACTGAGATATTAGAGGTTATAAAAAAAGACTACGTGGGTGTTT +ACCTAAGATTTTCACAACTTGTTTATTAATTGGATAAATAGTATTTTTCTTGGCATTTAC +AAACTTTATGTTTTTAGGTGTATTTGCAGTTCCATTAAGGGAAATAAGTCATAAGCTTTT +TTGGAAAACAGATTTTTTGCCCCGCTTAACCTGAAATTGATATTAAAAGAATGTGTGAAT +GGCCATTAACTAACAAGAGAATTAATAATGTTAAAACACAGATACCTCGAAACAAACTCT +ATGTAAACACTTATTTTATTGTGGTAATATTTTTTGATAACAACACATCTGAAACAAAAT +AATGCAAAGCCGAATAGTTAGGCTAAAAATGTACTCTTAGACATTTAAAAAGGTTTATGA +ATCCTATGGTATTTAATATATTAAAGAACGAAGTAAATGGGAAAAAATGTGTAAACACTA +TAAGCGTGATGATAGAATTATTAATATAAGATGATGCCGTGCGTTTACCATACGATTGCC +AGCAATACGGTGGAAATAAAAACACTTATGCCATTATTGGTCAACAGACCATTGGCAATA +CCAACGTAGGTTGAGATTTCTAAAGAGGCAGTACTAGATCCTATTATGCTACTTGCTGGT +GTGCTACGAGGCTGTTGCGACATAGTACTTAACCCGGAAGTTATTAGACTCTTGGTGTTG +CCAGTTTCGGATACAGAAACAACACTACTGCTGTGACCAATCACATCGGTCGCGGAAGCC +GTCTGTGTTTCAGCATGATTGAATCTTGAAATTGAAGAGGTGACTACTGTTTTCNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTGGTA +GCACTGTTCATTTTAGAGCTGACAGACTCTTCATTCGTAGTCTGTGGCCTCCATGTTGGA +TAGACCGTAACAACATCATTCACAGTAGCCGTGGCCGTCGAAACAATGGCAGGTGAAGCA +GTTTCGGAACACACACCAGATTCGCAGGAAGTAACAGTAACTAGCGTAGTTTGTTGCCTC +GATTCTGTGGTGGAAATAGGACACCATGTCGTGTATTCTGTGGTAACGCCGTTAATAGTA +GCAGTGCTTATAGATACAATGGCTGGAGAAGCAGTCTTAGAGCATACGTCAGATTCACAA +GAAGAAATTGTAACTACTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNAGAAATAGGGCACCATGTGGTATACTCTGTTGTG +GCACCGCTAACAGTAACGGTGGCCGTGGAAACAATTGCAGAGGAGATGGATTCAGTGCAC +ACATGAGATTCGCAGGATGTCACGGTAACCAAAGTGGTTTGTTCGCTCNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNAC +GAATATGTAGACTTTGGTGATTCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTAGCT +GAACTAGTTTCGCTCTCAGAAGAACCAGAGGTGGAACTACTGGTTGGAATGACGGATGAT +TTAAATGATTCAGAGAATATAGAAGTGGAGGTTGTTGTNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTTCCA +TTGCTAGGATAGAATGGGGTAATAATTGGATGCTAAGACGTGATAGAGCTGGTTATTTGT +TCTGAAGAAGATGATGACAAACTGGATGAGGTGGCAGTGGTTGGACTTTTAGCAACAATA +ACGGTTTCGTCAGTTGGTTGACCATTAGTGCCAGTGACAGTAGTCATCTCAGTAGAAGTC +GAAGTGGTAGTTGCGATGGTGCTAGTAGTATGTTTTGAAGGATCAGGGATAGTACAATTG +GGCTGTTAGGTCATCGTCAAAAGAGTAAACGTGCCCTGCAAAATCATCGCTAACAGTAGT +AACATCAGGCAATTCCACGCTAACTGGCAGTGTATGCCAAGAAACAGCGTTTGAGTAGAC +AATCTTCATTGGACAGTAGAATCCAGCATACATATACACAGTCCCTGCAATGTTATCGGG +CAATCTTCCTTGCCATGGCTTGATACCATTAATCGTAAAGTTTGTGGATGTAATTGGAGG +TTGCTCTTGTGCACAGCATCCGAATGCAACGTCGCCACCGACTGATAGAATTGCAGAGTC +ATCGACCTTAGCAAACCTGAACGTGTAAGAACTTGTTTGTGGTGGTAAAAAGTAACCTGT +CATTTCTAGAGTAGCGTTTTTTGGGATAGTATAGAAACCAAGTAAATCAGTACTCCAATA +GGTCTTTCCTGGCTATTTTGAACATTCACTATGACCTCTGCATCCCCAGTTTCCATAAGC +ATCTGATTGAGCACATTTAAAAGTTCCTGAAGAGATAACACAAGAAAGATCGTAGTCAAT +TGAGAAATCCGTCTGTCCGCCAACGGAACCTAATTCCAATTCGAGGCATATCCAGAAGTC +ATATATTGCGGGTAGGAATACGTTGTTGAATTCAGTAATGAGTACAAAAGTTGACATTCA +TCCCATTTTTCCTCGGGTCCGTTGGCAAGCATGCTTGTGTACTTCCTGAAACAACATTGG +ACGTGGCCAGGTAGGTGAAGAGTGCCAAAAATAAATAGTGATGAGGCATTTCTTGGTTCG +TCAATCAGGTATGGGTATATTAAACAATAACTTTAAGCCATGCTGTTAATGATGAAAATT +CTGATGCTGGTCTCTTCATATGTCATTGTTTTGGGAACTGTCTTTTTTCGATCAGATGTA +TGCGCAACGATTTGTTTAGCGTAGTGATGTTCCCGCGTAGTACTTAGGAAATTTTGGTAT +CGAAACGTCCCTACAACACTTTTTGTCGCTGATATCTGCACATGTGAGTAACGCAGATTC +CATTGCATTATTACCTTCCCCTTCCCAGAAACGATTTATTACGACTCAACAAGTTCAAGN +NNNNNNNNNNNNNGGTTACAACCGCATTTTGCGTTTAGGTGCAGCGAGACTTACCTTGAT +GCAGTCCTAAAGGGTCCTGCAGCGGTTGTAACGAATCCTATTTGCTTTTGTGCATTCCTA +AACGGGCTGAAGTAAAAGTCTTGAGGAACTCCAGGAGAAGATACGATAAGCTCCGAAGTG +CCAAATTTTATTATCNNNNNNNNNTATTTGTACGAGCGGAAAAGGATTATACTCTTCCTC +TTTTGCTTCATCACAAGAGGATTATTTTGACGTCGTCTGTTGTACTACTTCTTTATCGGT +GTGCGCAGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NTCTCGTGAGACCTCCGGAATTTTGACGCTGCAAGTCAATCTACGGGAAAGAAGAAATTT +TTTAAACCTAATGCAAAATAAGCTTTTCTTGGAAAATAAGATTTTCGGCAATAAAAGGTA +AATGCAGCCAAAAATCAAAATACTTCAGAAGAAGTCGTAGCGAGGACTGCTAAGGGGAAG +CGGATTTGAAGATCCTTTCCAGAACAAGAAGGAGCCGAAAGCTGTCAGGAACTGTTCCTG +ATTTTTTAGGAAAACAATTAATAGGTATCTCGTCTAGAGTAGTATCTCGAGCTTCCAGAA +GTTGCAGATAATCAAAATCATTGTTTTATCCCTTTTTTTAGATTACAGCTTAGAAGAGTA +GAGAGCAAGTTTACTGAAACGGTTCCTTGTTTACAATAATATTCCTAACAAACTTTACGA +ATTAGGATGCAGCATGATTTTTTATATTGCTTCACTTCCTAAAGTATGAATTTTTATCCG +TAGTCGCAAACAAAACAGCTACTGGAAATCTGCAGCTTGTTAAAAACCGGTAGTTTCCGA +ATACTCCTCGTCCTTGAGTTGTATACCGTTAAACTTCCTAGGGTGTCATGTGTCTGGCCC +AATTGGCCCACAAAATCTGGTCCTATTGACGGTTTTCTTTTGATTTTCAGCATCTTCCTC +TAAGAAGGACAGAAAATTATGTAATATATGGGAGAAACGGCCTCCCAACTGCTAAGTGTC +CCCGGCAGCACGAGTAAGCAAAATTCAGGCAAACTATTGCATTAAGAAGCCGTACATAAT +TCAGCGTGATATGATGAAATTTTGTTAATTGCAAATTTTAGTACGATTTGGTTGTTAGTG +TGTGTTTATGCAAGTAATTATTGAACCCTAAGTAGTTACTGTCTTCTTTTGCTGTAATTC +GTGGATTCACGGCCCTCCAGCAACATGGATTGAAAGGTTCTTTAAAGTTTTCAATCCGTA +AAGTTCTGAAATGTATTTTAATCATGTCAATAATTTTACTGGTGAGTAGCATTTATGACC +AAAAGCGTACTTAAATTAGCAGCAAAAAAATTTTTAATAACGAAACTATAAGGAAAATAC +GAGGTACTGATTATGAGAGTCCCCGTTTCTCATTTTTGAGACATGATCTGAACAAGGCTG +AAAACAGCAATCTTTTTCGATAACTTTTGCAAAAATTTCAAACATTGTTGTTTGAATGCA +GCCAATTTTTATAGGGTACAGAGCTTAATGCTTTACATGTGCTTTATTTTCGGTACTTTC +CTTAAAGTGTCTACATTATCTCTCAGGACTTGAATGTCTTCGGCTGAATTACTATAAAAT +CTTGAGTTTTCTCTGAAGTTTAATCCTAAGACAATAGTGGTGAGTGATGTAGTTCACGTG +TGTGCCACTGGTAATAATAGAGATAACTATCTCAGTTAAGTTTGAAAAGGTAAAAAATAG +TTTAAGTAGTCATTTTTTGCGACGGTCATTCTTCTCTGATGCACGTTCTTTAGACTACCT +ATAAACACCATTCTTACGGAATTATAATGGAAATAAAACATCAGTACGTGTTGCTGTCGG +TGATAGAGGGGTAACAGAACCTTAATTGAAAAATTAGCACAGTGCATAATTTATTAACAT +GATTGTTTTCTGTGGAAAATAAGAAATTCAGCACCAGTAAAAGACGAGAAATATAGGCAC +ATAAATGCGCTCTTACTCGTATGTTCCAGGATGAAAATGTTTAGGGCATCAAGTATTGCC +GAAAGGGCAATATGCTTTAACACCAGAAAATCCACTGTATACTCGTTACGGGTAAACAAA +GCAAAACGCAGTGCGTGATAATGTTTCTAAAATCTCTGCACACTGTTGAAATGCGGCTCT +GATACTTTAGCCCTTAGTACCTGACGGTGCCTAAAATGAGGATAAGTATATGAGTTTACA +ACGAATATAATGCTTTTTACCTCATCATATAAAGAATAATATTAATTTAAAAGTAAAAAT +TAGACCTAGGTGGTAATGAGGAATGTGTCCTAATGAATTTATGTAGTTGATGCTTTTGCA +GCGNNNNNNNNNNNNNGTATTAATCAAAGTGCACTACGTGNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTAACATGGTATTCTTAATCGTATATCGTA +ATGGATTGTCAAAAATAAAGAGAATATAGTCGGTTCAAACCACTTTGTACGTCTACAGAG +TATAGTGTAGAAATTATAGTTAGGATTGTGACATCCCTTTTTCTTTAACATAATAAGTTT +GCTTCAAATTAATTGATCAATTAGGATAATAACTCTCAACACCTTTATTATTTATGTTTA +GAGAGTTTATGGTCAGATGGTGATTGGTATTGATACTTATACTTTTTTTCTCATTAGTAT +AATACGCTATATTCCATGTTTGAATAGATCTTATTTTTTGGCTGTCTAGATAATAAACAT +ACCGTTTTTAACACACACACACCAATGAGTAGACGTTATTGCGACTGTATGCCCTTTAAG +ATATTCTGTTCAAAGAGATAAGGTATTTATTCGTTTTCTTGCAATTTCTTCTCATCTATC +ATTATCATACCAGATTGAATCTTATTTTTTAATTTTTAGTCTATTTGATGACGGCTACTG +AATCTTTACATTACTTGAGCTGAGAAGTAAAATTGCATTATTCATATTAAACAAAAAAAT +CAATTTCCCATAAAGACAATAGCTCAACTTCATCACGTCCTTGGTTTTTACCGAGTACAT +ATATTTGATGAATTCTGATTTGAAAATATCAATTTGTTCCTCTAGAATATTTCCACTCGC +ACATTCAAAAGCAGGTATTGGAACGCACAAGAAGCGATCGTCACCTTCCATTGGGGTTAG +TAGCAGGATATATATTTCCATTCTATATTCCAGGTTCTCTTTCACAATTTTATTGAATGA +AATACCTGAGCTACCAAATCAGTCTTAATAACACCATCTTTTACACCGGTACTACAACAA +ACCATACTGAGTCTGAAATTGGACTTCTGCAATGAAAAATTTAAGCCCTGATCTACGCAT +AATGCCCGCTATAAACCTTATTTTTTATATGGGGGTCTGGCGCTTCGGGAAAAGAGAGGA +AAACTTGTAACTCAATATATCTCGATACAACATTACGTTTTGTAAATTTATCACAAAAGC +CAAATGATGATATCTCTCTTGCAAGTTATCGAACATTGATTGGTAATTTGTTTGAAAATT +GTTAATTTATTGAATATTTCTTTTGCAAAAGAAATAGTCTCAGCGAAAGCTGGTTACAAA +ATTTACATCATGAGTTTACGGGATTTGTAAATACGCTTTTTGCATAAAAATACTTTGCCG +TTTCCCACCCTTGCATATTCACTTACTCCCCCCTTCATATACTCTATGTAATGATGATTA +AGCTTTGGCCGCTAAGTCTCTCAATTAGTGTTGATTTTGGTTTTATTCATATGATTCTTC +TTTAGTGAAGTATTGATCAATTACGTGAGTCAGCTTTTTGAAAACCCCATTTGGAAGGAA +TTAGGAAATTATTTTGCTTACTACGACCACTAATTTACCGCCATTTCTGGGCCTTTTTAT +TGACTATTTTGACCATGTGCTCGACTAGAAGAACGGCATCATAATCTGCTGGTAGAGTTA +GTCTATAATGATTGTTGAAAATAAAGGCATAAGAGATATTCCACCTAAAATTCAAGTTAT +TGACTTTATTATCAGGATCTTAGTATCCTTTTTTGGTAAGTCATATTCAATGAACTAGGT +CTCGCAAACTTTTTGTTCGAAAAGCGGTAGTGCATAGTTATGCTAACTCTGGATATATGG +CATAAACCGTACAACACTAGCCCATTTTTTTGGAAGTAGTGAGGGCAGCTAGACTGTATG +ATGAATATTCGCCTGCATACTGAGNNNNNNNNNNNNNNNNNNNATGTGGCTGGCCTTACG +ATATGATGCACAATTCATAATTTGGAAGAAGGGCAGAACAATTGCATCTGTGCTTGGCTC +TCAAGAACGGTGTTTGGTGCATCAAAAGTTTTCGACTGCTTATTTGGTCGGAAATATAAA +AACTCGATCCTCTTATCTAAGCAGTATACATTCTTCTTTTTGAAATGAATGTACTCCGTA +ATATCTTCTTATTTGGCATTTTCATCCTTAACTTTTGCATGGCTCTGAACTAGTCAGATA +GTTGCCCTTTTCAGCAAACCTCTTATTATTGAAAGCATGGTGTACATCCGTTATACTATT +ATATTATAAGAAATTGGGATGCCAANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NCGCAAAAGTAATTGCAGATTTAATAGCAGGATATTATACCGTTGGTAAAACTTAAGGAT +TTTATGAACAATAGCTTCAAGTACAGCATTCATAGAACCAACTACTAAGGATGAAACTAG +TATGTTTTTGTCAAAATATTTTCTTGACCTTGCTGTAACATCAAGATCTGTTTCTCTAAG +ATATTAAAGTTGAGTAAAAACAAAGCTGATATGAGAAAAATACGTAATTGCTCCACATAA +TACGTGGGTCAGACATAAAGGTAGAATACTTGATACAGAAGAGATTATTCGGTACTCTTG +ATGGCGTGCTTGAACTGGTGCCTCTTAACAACCGGTAATATAGTCAGATGAGTCACTACG +AGTGTGTGTAGTAGCAAGTGTTTTACCTACGTGGCAGTAAGAGTAGCTCTATGGTTGTGT +AATAGTGGTGCTTATTCCTAATGCTCTGAAGTCTGAAGCGGTACAGTTGGTCTGGTCTAT +ATCATGGTCAAAGGAGCAAACATATCTTCTGAAGTGACCGCAAATAGTACTATGATGTGG +TTGGCAATATAACTTAAAAGGAAATAACCACAAGGAATTGCACCCATGTACACAGTTTTT +CCCGGAAATTGGGAAACCAGTACGAACATATATCAATTACTTTTACATTATCTTGATTGG +AAAACTGGCACAATTGACTGTGACGTTAGTAGTATGTTGTTCTTCTCTACATCAGTTAAA +TATACGTGTCAACATCAACTAATCAACTTTCCCCCGTTTACCACATTGAAGCTGGGTGTG +GAAGATTTATTTGAAGAAACTAAAACGTACCCTGTCATTTCCTGAGTCCCCTTTCAACTT +AGTGTGAAAGCCGAACAATTATAATCCTCGGTAGACAACAGATTTATTGTACTAAAGTTA +CTCTTCCTGTTATCTTCCTTGATTTTACTGTTATAGCAATGACCCACCGCAATCAGGAGA +GCCGCCGTATGGAATAGCATACCAAGTCATAAAATCGTCAACCTATTAACGGGGTTCAGG +TTCTTTTTCAGCGTAGTAGCCCTTTAACAAGCGCTGACAAAGTTGACACTCAGAGAAAAT +TCAGGATTTATTGTAATCCAGCTACTCATCCTTAGATCCGCTTGCAGGCATGGTTTTTTT +CACCTTGAGAGGCTATTTTGGGTAAGCCAGGAAGGCTGAAAAATCCCAAAAGGACACAGT +AATAAGAAATTGTTGTTGTTGTATGATGCATTTAGAACTCAAAAGACGAGTTTCTGAAAA +TGCTTACAATACTCCATAGGTAACATGATTTTTTTATTAAAAAAGTATACTGTTCCTTTG +GGTAAAAATTATGCAACCCTTGAGTGTCCGATGAAGATAAGACTACGAAACAATTTGCGG +TAAATTTTTTCTGCTATTGACATTTACACATGCTCCAATCCATTACCCTTTCCATTCTCG +TAATAAAACCTCGAACTGTTATTTCATATTTACATCTAGACGGGTATCGGCCTCAACAAC +TCCAAACAAAAGTAAATAGAAAAGAGCCAGACCTATCGCACCGGGTAGAGCCAGAAAATA +TTTTAAACTATAGTTGACGTATTCTACGGCTGTTGTTTAGGACAATACTTTTTCCTTCAC +AGGCTTCGAATTACGCACATGCAGAACTCCTGTAGAAACCACGAAGAAAAGTTTAATTAA +CTTTCAAATGCCAGAACTAAAGATTGATGAAACAGTTATACGAATTTAAGGGGAACTTGC +TTTTTCCTTTTGCTTCATCATAAGCGCAATATTCGCAGCGGTGGCGTCGCGTCTTACCAT +TTATCGGCACATTTTTCCGAAAAGGAAGGAAAATGGCGGTGTCAAACGGTCTGGTGTGAC +ATCTAGAAGTTCGGCATTGCAAGTTAATCTACGGGAAAAAGAAAATTTTCTTATAACCCT +AATGTATAATAAGGTTTTCGGAGAAAGCAACTCACGGGGAACAATTGGTTAGAAGAGACC +GTAGAAGCGCCCCACTAACCTGGAGTTGATTATCGAGGATCTTTCTCAGAAAAGCAGCTA +ATAAATGAGCACAGTACTCAAAAATTACTCATAGTATTATAATTACTTACTTAGTCAATA +TGGCTGCGCTTTTAAAATGAGTATCTTTTATTTTTTGACAAGGAAGAAAAAGATGCAAGC +AAAGAGAAATTTACTAAGTACAAGCTCATTTCCAAAAATTCAGTTTGCCTGTAACAATGG +GTAGCGATCTTCAACATATGGGATTATGCCTTGAATGAGATTTTTGAACGTAGAGGAAAA +AATCGCAGACAGGCTTTATTGTGCTGTTTGACATAGTATACTCAGCCGTTGTGGTGTTAA +TGAATACTATCGATGTGTATACAAACGTACTTCAAATAAGCAATGCGAATATACTGCAAC +TTTTCGGCCTTTGCAACGATTTGTAATGAATCCTTTTGCATCGCTAGAAGGACAAGATAA +TATTTCTTCTGNNNNNNNNNNACATATGCAACAATTTGAAAGTCAGGTCAAAGACAGATT +CCGGTTCCCCATATTCAGATTGGAGAGAAAAACTTTTGGCAACTCATGTTACCAAGTCGA +GACGCTTAAAGTTAAGTGTCGGCCAAGACACGCAAAATCTTGTAATCTTTTAACGCTGCT +CTTCAAATCACGGACGCAATCAGTACTTGTACCTAATTTTGGTTTTCTAATATTGAATAG +CGAACCATAGGTCGAAAATTTAAGGCCACATAAATCCAGAGCCCGCAACTTGGATAGGTA +TTTACTTGATTTTTAGTTTGCTTTCAATAGTGTCGTGAAATTATAAAGTACGCCGCATAT +ATATCTTGATTAGTTAAAAATAGCAGTGTTCAATGATGATTTGATAGGGTTCATAACTGG +TACCAGCGTAGTACAATTACGATTATCCATGAACATAAAAGTGGTTTAAGTACTATATAT +CAGTGAAGCTTCAAAGTAAGCAAACGAGATACCAAGATCTTGTAGGACCACGATATATAA +GAAGCCTAGTTCCGTTGTAGCATCACATAGAAGAGAGCGACAATGCCTCAGAAATTCTAC +AGCAACAGAAAGCACAGTGAGTCATTAACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNAAAGCATTCGCCAAATTTTTA +TTAATAAAACAAATGTCAGAAATATGGCCGGAATCTAATCTGAAAGTTAAAATAATTCTT +ACGATATTCTTATCATAAAACCAATGATTAATGTTTATGATGAGCAAAACTGTGCGAGGG +CACATACATACAGTGGGACCTCATGAGATCCAGAAAAAAAGCAAAGGAAAGTTCGATCGA +AACATTAGCTCTTAGATATTACAGACGTGAGGTATCTCTTCCTTGAAGAGAATCTGGCCC +TGATCAAAAACTTTATTTTGATACTGTTCGAAAAGAGAAATAAGGACAACGTTCTAATTT +ATACAAATATAACCAGTAGGCTTTATCGTAAAATCCTCGAACTTGCTTCTCATCACAGAA +GTATAAAAAGTAAAGAGGTCAAGCAAGAAACGAATAACCACCAAATTTTTTTCAATTGAA +AAGCGAAACGTAATGGAAATTCACCTGCTTTGAATCGTTGTTGAATTCTTATCATCAGTC +ATTATTTTCCTCTTTTAAAGCTTAAGTCAACCGCATCTAAGTTTAACACTTCGTTCCCGT +TTTGAAGTTTATCAAAATTCCAAAATACAGTAGTTAGGTGCTCGTGACAAACCTTTTTCC +AAAGTGTCATTAGACTTCATGGAACTACTACACTTCTGGGGAACGAAAAGCTACCATTTG +CTCATCATTGGATAATTTCNNNNNNNNNNNNNGATGCATCCAAACTTGGACCCCTTTTGA +ATGTCGAGTATGAAGTATCAATTTTAGGGCAAGTAGTTTTACAATAATTTTGGTGCACTT +TTACGTCTCTGCTGATATTTTTAATACTAGTGCAAAAGAATTCGAAATAAATATAAAAGA +ACAAGGAGGATTAACATACTTTAAATAACTAATTATCACCATTATTTCAAGTTTCAAGTA +CTGCGTATGGCATGCACAGCAGATTTCTACTCAAAAACATCCTAAGCGAACCACACTAGA +TCTTACGTTAGTACTGCTGAAAATGGCAATAATTGTTAAAGCAAAAATTGGCGATGGTTC +ATTAATTGCTAAACAAAATAGGGCATTTTTCCTCGTTAATGATAAGTACTCATACTTCTG +TTTCTATAAGTGTTAGTTGTAACTTATGAAATATCGATTTAAATTCGAAGTGTTGTTTGC +AGGATNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +CAATGATATCGATAACGGTGAAATTCTTTTCATGGATTTTTGTTGCCCAAGAAAATAACA +ATAACGTTTTCTTTATGATACATATATCTACTTTTTCAAAAAAGGAAGCGCAAGAATTAT +CATTTAGTTCAATTTGAATATTTGAAAGTTTGGAGGAGAAACAGTTAAAAAATAATTCAT +GTCAGCGTATATTTAGCAAAGAAAAGATACACAGATACGTAAAAAGAACGCGAATTTTAT +TAAATAATTGCCAGCAATAAGGACGCAATGAAGACACTTAAACCACTACCGGCCAGTAAG +CTGTTGGCACTGCCAGCATACGTTGAAATTTCTAAAGAAGCTGTACTAGATCCTACCATG +CTACTTGCTGGTGTGCTACGAGGCTGTTGCGACATAGTACTCAACCCGGAACTTGTTAGA +CTCTTGGTGTTGCCAGTTTCGGATACAGAAACAACACTACTGCTGTGACCAATCACATCG +GTCGCGGAAGCCGTCTGTGTTTCAGCATGATTGAATCTTGAAATTGAAGAGGTGACTACT +GTTTTCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNCTGGTAGCACTGTTCATTTTAGAGCTGACAGACTGTTCATTCGTAGTCTGTGGC +CTCCATGTAGAATAGACCGTAACAACATCATTCACAGTAGCCGTGGCCGTCGAAACAATG +GCAGGTGAAGTAGTTTCGGAACACACACCAGATCCGCAGGAAGTAACAGTAACTAGCGTA +GTTTGTTGCTTCGATTCTGTGGTGGAAATAGGACACCATGTTGTGTATTCTGTGGTAACG +CCATTAATAGTAGCAGTGCTTGTAGATACAATGGCTGGAGAAGCAGTCTTAGAGCATACG +TCAGATTCACAAGAAGAAATTGTAACTANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNA +GAAATAGGGCACCATGTGGTATACTCTGTTGTGGCACCGCTAACAGTAACGGTGGCCGTG +GAAACAATCGCAGAGGAGATAGATTCAGTGCACACATGAGATTCGCAGGATGTCACGGTA +ACCAAAGTGGTTTGTTCGCTCGTTTTTGTAGTGGTAACAGGTGGTAATGAAGAAGTAATT +TCCTGACTTGTTGTTGCACTGGTAACAGGTGGTAATGATGAAGACGAATATGTAGACTTT +GGTGATTCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTAGCTGAACCCGTTTCGCTC +TCAGAAGAACCAGAGGTGGAACTACTGGTTGGAATGACGGATGATTTAGATGATTCAGAG +AGTATAGAAGCGGAGGTTGTTGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTTCCATTGCTAGGATAGAAT +GGGGTAATAATTGGACGCGCAGACGTGATAAAGCTGGTGATTTGTCCTGAAGAAGATGAC +AAACTGGATGAGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNCTGACAGTATAATTTGAAGGGTCTGGAATGGTA +CAGTTTGGCTGGCTTAGATTGTTGTCAAAAGTATATACGTACCCTTCAAAGTCATCACTA +ACGGTAGTGCCATCTGGTAGTGTCACACTAATTGGAAGTGTACCCCAGGCAACGGCATTT +GAGTAAACAATCTTCATTGGATAATAGAAACCAGCATACATGTAGACAGTCCCTGTAATA +TTATCAGGGGGACTTCCATTCCATGGCTTGATACCATTGATGGTGAAGTTAGTCGACGTG +ATGGGAGGTTGTTCTTGTGCACAACATTCGAACGCAATGCTACCACCGACTGATAGAATT +GCAGAGTCGTCAACTGTAGCAAACTTGAATGTGTAAGAACCCGTCTGTGGTGGTAAAAAA +TAACCTGTCATTTCTAGGGTTACGTTTGTTGGGGTAGTATAGAAACCAAATAAATCAGTA +CTCCAGTATGCAATTATTGGATTATTAGAACAAGCACCAATTCCTTTGCATCCCCAATTA +CCATATAAATCTTCTTGAGGACAAGGAAATGTGCCTGATGAACTAACACAAGGAATATTA +TAATCAATCGAGATATCAGTTTGTCCTCCGACAGAACCCAGTTTAGTTTTTGAGGCATAT +CCATAAGCCATATATGCTGCATTCGAATATGTGGAGGAATCTCTCAATGAATACTGGTAA +AAGTTTACATTCATACCATTCTTCCTTGAGTTTGCTGGCAGGCATGCCGCTGTAGTCGCA +GAGACAACATTAGTTAATCCCAGCAATGTGACGATGGCTAGTAGTAAACAATAATGTGCC +AGAGACATTTTTGGGGCTTTTATTGTACAATTGTTCTTTTTAAATTGCAATTTAAAGAGC +GTACCTGTAAATAAGAAGGAAGAACGTTATGTTATTAATGGACTTTTAGTGTCATCGAAT +TTTATGTAATATATAAGAAGGTAGAATAATTTGGCAGGATAATGTGTTAGCAAAGGAGGA +AATCGAATACCTTTAAAAGAGAAAAAATTTTTTAGCTGCTTAAATTTCTGTGTTATACCA +CCCGATAGATTTTGAGTTATGCTTTCTAATTGATCTGACTGCGAACGTTTTCTTTATGCC +ATCTGAATTGTCAGGAACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCTGTGGTCGTGT +GTGATGTACCTTTCCTTTACATGCATTAATGCGCTCTGAAATGTGGTACGATATCCTTAC +AGAGAATATATTTTCTGTATATCGTGCAATGTTGAATAACCTATGAAGGAAAGTACCCAT +CGCTCAAGGTAAGCATTCCAGGAGGGTCGCCAGAAACTTAAACTAGTTTTAGCGACAGAT +CCGAAAATTGATAGAGACATTGAAAAAATCACTACTCCGTCCTTTTTAGTGCTTTCTCAA +TGCATAATTTTGGTGCACGACTAAAAAATTCTAGAACACTATAGTTGCATTTTTTGGGCC +GGAAGAAGAAAAACGCATGTAACTTTAATGTCAAATAAAGTTTTCACCTAGTAAGCGCGA +TACNNNNNNNNCACAGAAATAGCCATAGGAAAGTGAATTTTGTCAGCCGACTAAAATTAA +GGTTAGCTTACAAAGCAGCAAAAAATTTGACATCGCACGGTATTCCCTGAAAAAGGAGCA +GGCAGGTGCTGTATATTTTTTTCGGTTCCTGCCTCTTACATGGCGTCGGTGTATCTTAAA +TACTAAAGTGAGCTGACTACCCTTTTGAGTGCCCTATGTGACCTCTGATCTCGAAAGTAA +ACAAGAGATACCTAATTTCACAGCCACTTTTTGTTGCGGACACTGACGGGATGTGTTGTG +AATATTTTAAACCTTAAAAGTATTTATTGGTTAGTTATACTTAATTCTTATACGTCCTTT +AAAACCAGTGTGCAGTAAGTCTGTCACACAAAAATATGATTGATGCATTTTCAAAAAATA +ATGGCTTTGAGGTAATTCGTTCCACTTTTGAGACTTATTCACATGTCCCAGCTGGGTGCA +ATCAAAATATACCGGCATTTCAGCAAGGTAACTATATACGCTTTTTTTCTCATGGTTTTT +GAAATCATACCTGCCAAGCTTGCTGCACTTGGAAGGCAACTCCGTTTTTCAGAGATTAGA +TCCNNNNNNNNNNGAAGAAAAGGCAGCCAAGTTACGTCATAGAGAAAACTCCCTAGAGCG +CTGCAAACACTTGTTAGTTTGCAGCTTACTTCACGTGTGGCTGGAAAATTGAAAAGTTAC +AATACGGTAAAAATACTTTGAAGACACTACACTATAACTGCTTGACCAAATTTTTACTCG +TGAAAAATTTGTTCCAGCCGGTCTGTTACTGATATTAAGTTAAGGAATAGTAAACCGTAT +ATTTTTCATCCACGTTTTTGTAGTTTATTTTCGGTTTACTAGCTATGCATTGATTGTCTA +TCAGAGCATATCAAGGTGGTTATGGAGGTGCTGATATTTAATCAATAAAATTATAGAAAT +TTTGAGAAAACAATAATGATTGTTTCTACAATGAAAATCAGTTCATGGAATAGTTGCCTT +CGCACTACTTTTTCACCAGATTAATGGTGCATCAGAGNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNCGATTGGTTTATCACGTAAGTTTCTTATGACATAAGAAGAGGCAAGAAA +CGAAAAGGGAAATATTGCCTACTTTTTTCTTTTCGAACGTAAATAATGACGGGATTTTGG +TGTCANNNNNNNNCGTCTGGATTTTCTCAGAGAAGTACGTTTCGTCGCACAAGCTAAAAT +CATTGACAGGGCATGAGTTACGTCAATCTCTGGTCAATCCATGTCCAAAAAAATTTCTTG +ATTTGTTCAAAGTTTTTGCATAGGCACATTAATTGGTTTAGCGAAGTATACATTCTGAAG +AACATTTTTGGGTGTATTTTCCACATAGAAAATTCGANNNNNNNNNNNCAATGCACCACT +TGTCGAGTATACGTTAACTTTAATGTATTGAAGATGCAAAAATGAAAAGCCTACTTGGCA +TATGGAATTACAATAAATGGTCAATTCCTGTTTAAGCTAGCAGCGGCACTGTCGGTGTAA +ATTTGGGTTTAAACTATTGTTTACTTACTTTGAGAAATTTATGTATCGCCTATATTTTTC +AATAAGTGCGATATCTTTAGCTTTCCACAGAACCCCCCCTCAGGCTATGGACGTGCGGTT +ATATGATCTTCTAATAAAAATCTCTTAGACTACGGTTCATGGAATACTTCTTGACTTCTT +GGCGAAGGAAAGGCGCATAAATGTTGTGATCGAATGACCAGTAATACGTCGTTTGTTCTC +TTGCTGAACAGCGAGGAAGAGATATTCATCCAAATGCATGAACGCAGAATCCTGTAAAAG +TCGTAAAAATGTTAATCGCAATGTTGTAAAAACCGTCAAGGCATTTATCGTTCAAAATGG +CGATCATTGTTACTACTAAACACTTACTGTTAAATTAAAAAGCTGATGTTGCGTAATCCA +TTGACCAATTCATAGGCAATGTATTTCAATGACGCACAAGATTCATAACAAATTTTTTAT +TTACGATGTACCTGTACATTGTGCAGAAGGTCTTCAGAGTGAGTTTAAGCTAGGCTGTAA +ATATTTTAATGTTAAGATGAAATTTAAGTGAGCTGGTAATATCAAGTGAGGCATAATTTG +TTATATGTAGCTGAACTTCAACTTTAAATAGAAAAATTACAACTAACAAGCACCGGATTG +TTTCAGAATTCAAAGTGTAGAAGCTATTATTCTTGCAAAATAAAACGCTTTCAAAGTTTT +CTTCTATAAACATACTTGTGGCAGCTTGNNNNNNNNNNNNNNNNNNNNNNNNNNGTTGGG +TCTCTGAGAACTTTCNNNNNNNNNNNNNGTAAAGTATGATAAAACGGAGCACTTGCCAAA +GTAATTAACGCCCATTAAAAAGAAGGCATAGGAGGCNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNGGCTGCTGACAGATATTCTGCACTTAAAAACTAAAAATATTATACCAACTTTTC +TTTTTCTTCCCGTTCAGTTTGCTTGATTGGCCCAGCTCTTTGAAGAAAGGAAAAAATGCG +GAGAGGGAGCCAATGAGATTTTAAAGGGTATATTACTTATCTTATCGATAAGCAGTATTG +ATATTAAAGGGACAGTTTTATCGTTGGTTAATATGGAAAAAGTGATGACCATGATGCCTT +TCTTAAAAAGAGTATTTCTTTTTATTTCACTTTCACATAAACAGTTAATGACTTCTGACT +TTGAGCCGTTCGAACTCAGTTATATAAAGGTACATACATAGGCNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNGGGAAGTAGCAACAGTCACCGNNNNNNNNNNNNNNNNNN +NNNNNNNTGACAAGCGAACCAGAGTTTCAGCAGGCTTACGATGAGATCGTTTCTTCTGTG +GAGGATTCCAAAATTTTTGAAAAATTCCCACAGTATAAAAAAGTGTTACCTATTGTTTCT +GTCCCGGAGAGGATCATTCAATTCAGGGTCACGTGGGAAAATGATAATGGCGAGCAAGAA +GTGGCTCAAGGATACAGGGTGCAGTTCAATTCAGCCAAGGGCCCTTACAAGGGTGGCCTA +CGCTTCCACCCATCAGTGAACCTGTCTATCCTAAAATTTTTGGGTTTTGAACAGATCTTC +AAGAATGCGCTCACTGGGCTAGATATGGGCGGTGGTAAGGGTGGCCTGTGTGTGGACTTG +AAAGGCAAGTCTGACAACGAGATCAGAAGGATTTGTTATGCGTTCATGAGAGAACTGAGC +AGGCATATTGGTAAGGACACAGACGTGCCCGCAGGAGATATTGGTGTCGGTGGCCGTGAA +ATTGGCTACCTATTCGGCGCTTACAGATCATACAAGAACTCCTGGGAAGGTGTGTTGACT +GGTAAGGGTTTAAACTGGGGTGGCTCACTTATCAGGCCGGAGGCCACCGGGTTCGGCTTA +GTTTACTATACGCAAGCAATGATCGATTATGCAACAAACGGCAAGGAGTCGTTTGAGGGC +AAACGTGTGACAATCTCCGGAAGTGGCAATGTTGCGCAATATGCAGCTTTGAAAGTGATC +GAGCTGGGTGGTATTGTGGTGTCTTTATCCGATTCGAAGGGGTGCATCATCTCTGAGACG +GGCATTACTTCTGAGCAAATTCACGATATCGCTTCCGCCAAGATCCGTTTCAAGTCGTTA +GAGGAAATCGTTGATGAATACTCTACTTTCAGCGAAAGTAAGATGAAGTACGTTGCAGGA +GCACGCCCATGGACGCATGTGAGCAACGTCGACATTGCCTTGCCCTGTGCCACCCAAAAC +GAGGTCAGTGGTGACGAAGCCAAGGCCCTAGTGGCATCTGGCGTTAAGTTCGTTGCCGAA +GGTGCTAACATGGGTTCTACACCCGAGGCTATTTCTGTTTTCGAAACAGCGCGTAGCACT +GCAACCAATGCAAAGGATGCAGTTTGGTTTGGGCCACCAAAGGCAGCTAACCTGGGCGGC +GTGGCAGTATCCGGTCTGGAAATGGCTCAGAATTCTCAAAAAGTAACTTGGACTGCCGAG +CGGGTCGATCAAGAACTAAAGAAGATAATGATCAACTGCTTCAACGACTGCATACAGGCC +GCACAAGAGTACTCTACGGAAAAAAATACAAACACCTTGCCATCATTGGTCAAGGGGGCC +AACATTGCCAGCTTCGTCATGGTGGCTGACGCAATGCTTGACCAGGGAGACGTTTTTTAG +CCGTAAGCGCTATTTTCTTTTTGTTCGTAACTATCTGTGTATGTAGTAGTGTAATCTACT +TTTAATTTACTATGCAAATAGGGTTCAGCATTACGGAAGAAACTGAAATCCCTTCCGCGG +AAGTTTCTTAGTAGTGGCCGTGCGGGGTGAGGAGATTACATGTCGGTAATTAGATGATTA +ACCTAGGCAATTTGAAGGGGGATAGTGGCATTGGTTAGCTCAGATATGATAAGGAGAACT +AAGCAAGGGGGTTAACCACCACGGCTGTAGCACAAGACCGGCAGATGCGATTATTAGCAA +CACATTAGTTAATGCTTTTGATAAAATGTATATAAAGGCTGTCGTAATGTGCAGTAGTAA +GGACCTGACTGTGTTTGTGGTTCTCTTCATTCTTGAACCTTGTCATTGGTAAAAGACCAT +CGTCAAGATATTTGAAAGTTAATAGACAGTTAACAATAATAACAACAGCAATAAGAATAA +CAATAAATTCATTGAACATATTTCAGAATGAGAGCCTTAGCGTATTTCGGTAAAGGTAAC +ATCAGATTCACCAACCATTTAAAGGAGCCACATATTGTGGCGCCCGATGAGCTTGTGATT +GATATCGAATGGTGTGGTATTTGCGGTACGGACCTGCATGAGTACACAGATGGTCCTATC +TTTTTCCCAGAAGATGGACACACACATGAGATTAGTCATAACCCATTGCCACAGGCGATG +GGCCACGAAATGGCTGGTACCGTTTTGGAGGTGGGCCCTGGTGTGAAAAACTTGAAAGTG +GGAGACAAGGTAGTTGTCGAGCCCACAGGTACATGCAGAGACCGGTATCGTTGGCCCCTG +TCGCCAAACGTTGACAAGGAATGGTGCGCTGCTTGCAAAAAGGGCTACTATAACATTTGT +TCATATTTGGGGCTTTGTGGTGCGGGTGTGCAGAGCGGTGGATTTGCAGAACGTGTTGTG +ATGAACGAATCTCACTGCTACAAAGTACCGGACTTCGTGCCCTTAGACGTTGCAGCTTTG +ATTCAACCGTTGGCTGTGTGCTGGCATGCAATTAGAGTCTGCGAGTTCAAAGCAGGCTCT +ACGGCTTTGATCATTGGTGCTGGCCCCATCGGACTGGGCACGATACTGGCGTTGAACGCT +GCAGGTTGCAAGGACATCGTCGTTTCAGAGCCTGCCAAGGTAAGAAGAGAACTGGCTGAA +AAAATGGGTGCCAGGGTTTACGACCCAACTGCGCACGCTGCCAAGGAGAGCATTGATTAT +CTGAGGTCGATTGCTGATGGTGGAGACGGCTTCGATTACACATTTGATTGCTCCGGGTTG +GAAGTCACATTGAATGCTGCTATTCAGTGTCTCACTTTCAGAGGCACCGCAGTGAACTTG +GCCATGTGGGGCCATCACAAGATACAGTTTTCTCCGATGGACATCACATTGCATGAAAGA +AAGTACACAGGGTCCATGTGCTACACACACCACGATTTTGAGGCAGTAATAGAAGCTTTG +GAAGAAGGCAGGATTGACATTGATAGAGCAAGACATATGATAACGGGCAGAGTCAACATT +GAGGACGGCCTTGATGGCGCCATCATGAAGCTGATAAACGAGAAGGAGTCTACAATCAAG +ATTATTCTGACTCCAAACAATCACGGAGAGTTGAACAGGGAAGCCGATAATGAGAAGAAA +GAAATTTCCGAGCTGAGCAGTCGGAAAGATCAAGAAAGACTACGAGAATCAATAAACGAG +GCTAAACTGCGTCACACATGATTGTGATTGAGTACTCACGTTCTCGTGTTAATCCCGCGG +TCTTCTTGTTTTACTAACTTTTCTTTCTCTCATAGCATTCTCTTGACAGTGTTTTATATA +CATCATATGTACATTTATCGAGCCAATCGAGGGCAGCAGTTTAACATCAAGCCGGATTTG +CTCACGCTACTTTGACCCCTTTTCGTTTCGACGGAGAGAAGAAACCGGTGTTTTCCTATC +CTTGCCTATTCTTTCCTCCTTACGGGGTCCTAGCCTGTTTCTCTTGATATGATAATAGGT +GGAAACGTAGNNNNNNNNNTCGACATATAAAAGTGGGGCAGATACTTCGTGTGACAATGG +CCAATTCAAGCCCTTTGGGCAGATGTTGCCCTTCTTCTTTCTTAAAAAGTCTTAGTACGA +TTGACCAAGTCAGNNNNNNNNNNNNNNNNNNNNNNNNNNNNGTTTTAATTAATTATGAGA +GCTTTGGCATATTTCAAGAAGGGTGATATTCACTTCACTAATGATATCCCTAGGCCAGAA +ATCCAAACCGACGATGAGGTTATTATCGACGTCTCTTGGTGTGGGATTTGTGGCTCGGAT +CTTCACGAGTACTTGGATGGTCCAATCTTCATGCCTAAAGATGGAGAGTGCCATAAATTA +TCCAACGCTGCTTTACCTCTGGCAATGGGCCATGAGATGTCAGGAATTGTTTCCAAGGTT +GGTCCTAAAGTGACAAAGGTGAAGGTTGGCGACCACGTGGTCGTTGATGCTGCCAGCAGT +TGTGCGGACCTGCATTGCTGGCCACACTCCAAATTTTACAATTCCAAACCATGTGATGCT +TGTCAGAGGGGCAGTGAAAATCTATGTACCCACGCCGGTTTTGTAGGACTAGGTGTGATC +AGTGGTGGCTTTGCTGAACAAGTCGTAGTCTCTCAACATCACATTATCCCGGTTCCAAAG +GAAATTCCTCTAGATGTGGCTGCTTTAGTTGAGCCTCTTTCTGTCACCTGGCATGCTGTT +AAGATTTCTGGTTTCAAAAAAGGCAGTTCAGCCTTGGTTCTTGGTGCAGGTCCCATTGGG +TTGTGTACCATTTTGGTACTTAAGGGAATGGGGGCTAGTAAAATTGTAGTGTCTGAAATT +GCAGAGAGAAGAATAGAAATGGCCAAGAAACTGGGCGTTGAGGTGTTCAATCCCTCCAAG +CACGGTCATAAATCTATAGAGATACTACGTGGTTTGACCAAGAGCCATGATGGGTTTGAT +TACAGTTATGATTGTTCTGGTATTCAAGTTACTTTCGAAACCTCTTTGAAGGCATTAACA +TTCAAGGGGACAGCCACCAACATTGCAGTTTGGGGTCCAAAACCTGTCCCATTCCAACCA +ATGGATGTGACTCTCCAAGAGAAAGTTATGACTGGTTCGATCGGCTATGTTGTCGAAGAC +TTCGAAGAAGTTGTTCGTGCCATCCACAACGGAGACATCGCCATGGAAGATTGTAAGCAA +CTAATCACTGGTAAGCAAAGGATTGAGGACGGTTGGGAAAAGGGATTCCAAGAGTTGATG +GATCACAAGGAATCCAACGTTAAGATTCTATTGACGCCTAACAATCACGGTGAAATGAAG +TAATGACAAAATAATATTTGGGGCCCCTCGCGGCTCATTTGTAGTATCTAAGATTATGTA +TTTTCTTTTATAATATTTGTTGTTATGAAACAGACAGAAGTAAGTTTCTGCGACTATATT +ANNNNNNNNNNNNNNNNNNNNNNNNCCTTTATTCAACTTGGCGATGAGCTGAAAATTTTT +TTGGTTAAGGACCCTTTAGAAGTATTGAATGTGGGAACAAAGACGACAAAAGGTAGTTTT +TTCCTTGACTATACTGGTAAGATATCGTCTAAAACAAAGCATGGCCAAGAAAATATCAAA +GAATTCAAGAGCTGCTAGACAATCGGATGCTCTTGAACCAGAGGTAAAGGATTTAAGTGA +ACTACCTAGAGCTGAAAAAACCGATTTGACTAATATTTTGATTAGAACAGCAGCCAAGAA +TGAGGCATTGCTGGAAGCAAAGATATCTAAGAAAGCCAATAAAAGTAAGAGGGGCAAGAA +GTTAAATAAAAAGGCTCTGGAAGACAAACTGGCCAACTCTATTTCATCCATGGACAGGGA +TCGTTTAGTGAAGGCCTTGAATTTTACCAATCGTCTGGACGGTAAAATTGCCAAGTCCAT +TTCTCGTGCCAAGTACATTCAAAATACAAGAAAGGCTGGCTGGGATAGCACCAATGAGAC +TATAAAAAAAGAGCTGGCTTTTTTGAACGGAGGGTTGTCTGTGCAGGCAAAAAGTGCTAG +TGAAGGTAATGCTGAAAAGGAAGATGAGGAGATCCCAGAAGTTTTTGACTCTTTAGCAGA +GGATAACACAGTGCAGAAGACTCCTACAAATAGATTCGGTGTCCTGCCAGACGATGTTGA +AGAATAGAAAATTTTCATATGAAAGGTCCTAGGAATACACGATTCTTGTACGCATTCTTC +TTTTTTCTATCTTCTTTCATTCTTTGTACATTAGATAACATGNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNTATATCTGGATGTATACTATTATTGAAAAACTTCATTAATAGTTACAAC +TTTTTCAATATCAAGTTGATTAAGAAAAAGAAAATTATTATGGGTTAGCTGAAAACCGTG +TGATGCATGTCGTTTAAGGATTGTGTAAAAAAGTGAACGGCAACGCATTTCTAATATAGA +TAACGGCCACACAAAGTAGTACTATGAAATTTTCTGCGTATTTATGGTGGCTGTTTTTGA +ATCTAGCGTTGGTGAAAGGCACTTCATTGCTATCCAACGTTACATTAGCGGAAGATTCTT +TCTGGGAGCATTTTCAGGCTTACACTAATACAAAGCATTTAAACCAAGAGTGGATCACAA +GTGAAGCCGTCAACAATGAAGGCTCTAAAATATATGGTGCACAATGGCGACTATCACAGG +GTCGATTGCAAGGATCCGCATGGGATAAAGGAATCGCAGTTCGAACAGGCAATGCCGCAG +CTATGATAGGACATCTCTTGGAGACACCTATTAATGTTTCAGAAACGGATACCTTGGTTG +TCCAGTACGAAATTAAGTTGGACAATTCTTTGACGTGCGGCGGTGCGTTTATTAAGTTAA +TGTCTGGTTTCATGAATGTTGAAGCATTAAAACACTATGCACCCGATACAGAGGGTGTCG +AGTTAGTTTTTGGTCCGGATTATTGTGCTCCTGAAATAAATGGCGTGCAATTTGCCATCA +ATAAGGTTGACAAGATCACACATGAATCTAAACTAAGATATTTGCAAGAGATGCCCCTGT +CAAAATTAACTGATACCTCGCAATCTCATCTGTATACGCTCATAATAGATGAATCAGCGC +AGTCTTTTCAAATTCTTATAGACGGTAAGACGGTTATGGTAAGAGAACATATCGAAGACA +AGAAAAAGGTCAATTTTGAGCCACCCATTACACCGCCTTTAATGATTCCTGATGTTTCAG +TAGCGAAACCGCATGATTGGGATGATCGCATCCGAATCCCAGATCCTGAGGCGGTGAAGC +TCAGTGATCGGGATGAACGAGACCCATTGATGATTCCACATCCAGATGGCACTGAACCAC +CAGAATGGAACAGCTCCATCCCCGAATACATTCTTGACCCAAATGCTCAAAAGCCCTCGT +GGTGGAAGGAACTTGAGCACGGGGAATGGATACCGCCCATGATTAAAAATCCTCTTTGCA +CTGCAGAACGTGGTTGTGGCCAGCAGATACCAGGGCTGATAAATAATGCCAAGTACAAAG +GTCCAGGCGAACTCAATGAAATCATAAATCCCAATTACATGGGGGAATGGCATCCACCGG +AAATTGAAAACCCGCTATACTACGAAGAGCAGCACCCATTGCGCATCGAAAACGTTATCA +GTGGTGTGATCCTCGAGTTTTGGAGTGGATCTCCAAACATGTTGATAAGCAACATTTATG +TTGGTAAAAATGTAACAGAGGCGCAAATTATTGGGAATAAGACTTGGCTGATGAGAGACC +GCGCGTTTAGAGGCTCCGATGGCCCCACAGAACGCAAATTCATGAATAGCAGACTAGGAA +ATCTACAAACAACTTTCCATAACGAAAGAGAATCCCCTAATCCATTTGACCGCATTATAG +ATCGCATATTAGAGCAACCTCTGAAATTTGTGCTTACTGCGGCCGTCGTGCTCTTGACGA +CGTCGGTTCTTTGTTGTGTAGTATTTACATAGTGGACAAGTGTTAGTTTATAACATGGTC +TCAATAATTGCACCACAACGGCTTCTCTTTTATAGATGGTTAACATTATAGTATCAATAT +TATCATCATGATTAAATGATGATGTATAATACTTACCCGATGTTAAATCTTATTTTTTCA +TGCAGTAAGTAATCATGCAACAAGAAAAACCCGTAATTAAGCGAACATAGAACAACTAGC +ATCCCCGATAAGACGGAATAGAATAGTAAAGATTGTGATTCATTGGCAGGTCCATTGTCG +CATTACTAAATCATAGGCATGGAAATTTCCAGTTCACCATGGAACGACGGTGGATACAGC +CCCTATGAGAGAAACAGAGTCGCTGTATCACCATTTTCATCAGCGTTGGAAGGCGAAGAA +CGAATAGAAACCTCTCGATCTTTGGGTGATCATTGCTTTGAACCTTTGCCATACGTGACG +AATTATCTTTCTATTTTCGCGCTTTTTGGTAAAGAGATATTTGGTGACAAGGGAAATGTG +AGCTCAAGAAATGAATATTTGCTAAAAAAATACTACTCTTTGAAAAAGCCATTTGTATTG +CGACATAATGGGCATGCGTTGAAGAATCCCGACATGCCACTCCAGAGGAATGACATATTG +CAAACCAATTTCATGGTTGACAAATTTCTGAATCGTACTGTGCGGTCAGTGAATTTTAAT +AATTTCAAGATAATATCAGATATGCAAAGTAAAAGCGGTCGAGGAACAAAGTCAGGCACA +AATCAGAATCAAAGTGCCGACGCTATTCAAAATATTTGTCTACCATCTATACCGTCGGCG +TTGCCTTATTTCCAGTATTATAGGAAGCTATTGACAGTTAATACCAAAGAATGGGATATT +TTAAAACTGCACAGTTTATGGGTACCAAAGCTAAGGAAGGATTTTAAAGATTTTTCGTTG +TATGGTGATAAAAACTCTTTAAAGCCGATCGATAGTCACTATGATGAGGATAATACCATG +AAGAAAAATTTATTTTTTGAAAGATCTCCAAGTCGACAGACTCTAGATGGTAAAGGGTGT +GCCTCTAAGGGGTATGACATTTCTTCCGGTAATATGATTATCCCATCCCTATTTTCTGAA +GATAAGCTGCCGGCTTTAACTTATCATTGTTCCGTAGAATTAAATGGAAACATTTACATA +TTTGGGGGATTGATGCCATGCTACAGCTATGAGGAGGATGCGCCGATGCTGAACGATTTT +TTTGTAGACGGAATAAAGAACTTACCTCCGCCTTTACTACCTCAAGTGATTAATAATCCA +TCAATGGTCAATAATCCTCATCTTTATGTCGCTTCTATACCATCATGCCGGTTTAGCAAA +CCTAAAATGGGGGGTTATATACCGCCTCCATTGCTATGTGTTCAAGGATCCAAATTAACG +GACCGACATATTTTCTTTTATGGCGGATTTGAAATCAGGACAGAAACCCGTGGTGATGAA +AATGGGAAGTATCATCTCAAGAAAAGATTATATGTGAATAACACTGGTTACATACTCGAT +ATTATGTCGTTCAAGTTCACTAAAATAGATATCATAGTACAACCTTCCAAATATAATGCA +TATCCGACAATGTCATCGAGGTTTGGTCACTTACAAATTTCTATTGATAATCCAAATAGG +AGAGCTAGCGTTCATTCTTCAAGCATGAACGAAATTCATAAAATGGGGAGTGCTTCCATG +AAACAAGGTAGCAGCATCACTTCCGGGCGGCTTGAAAAAGCAGCAGTACTTTCATCATTA +CCTCATAATACTGTGCACACGGTTATAATATTTGGTGGTTACAGACAAACCGGTGATGAT +CGTTACGAAGCAATGAATGATTTGTGGAAGATAGAGATACCCGTGATACGTCGCGGTAAA +AAAGGTTATTGTAAGTTTTCAGAGACAGCTAACGCGATACTACTGACGCCAAGCGAAAAG +GACAAATCGGATTGGCCCGAAGAAAGAGCCTTTTCTGCCTTTTCTGTTCATGGGACTTCG +TTAATGGATAGGAGTTCTCTTGACATGAGACTATTGAACAACTTAAAAAACCATTTTGTT +TTAAAACCGTCATATATATCACAGGATCGCGTTGTTAGTCCTAAACCGGTTTTCCCCATG +ATGGTTCATGGCACGCATCAAGATCTTTTCAATAGTGGCTCTGCGGCACAAGAATCGCCC +AAAGCTGGTGCCTCGGCCAGCAGCGCAAGTGCTGCGAGCTTTGATCCCGATATGGACGAT +AATTTGGAAAATTATATAGTCAATCCAGGGAGAAAATCGTCATCTATTCCAATGACTGCG +ATAGGGAGACAGAGATTAATTTTAAGCCAAGAGAAGCCAGTAGGTAAAACTGTTGTATTG +CATGGTGGGTCTAACGGTCTCAACGTTCTTGATGATATGTGGTTGATGGACTTAGAGTGT +GAGACATGGACTCCAATAGAGACATTTGCAAAGGCAGATTCGAGCGAAGACGGTGATGAA +AAATTGGATAGTGTGAACGTAGGTCTCGTTGGCCACAGAATGGAAAGTATTGGACGAATA +TGTGTATGTATAGGTGGTATGGTACAAGAGGATGTTGACCAATTTTACTCGGAGAATGAT +GATGAGCCTCCTCGAAAACGCAAGGTCGATACATTACCGTTGGGTGGTAATTTTTTGAAC +ACAATTGATTTAAGCACGCAGTGTTGGGAAGAACATAAAATTACTCTGTCCAAGAAGGAA +GACGATGAGGACAGACAAGATAGCGAAAATGAAGATACAAATTCAAATATAGTAGTTGGT +GTCGGTGGCACTTCTTTGCAATGTGACAAAAGTATTATTTTGATTGGCGGATTGATATCT +AGACGGAGCAATGTAAAAGAAATATATTTACATGGTACCATAACGAAAAGTATTTTTCCT +AGCGTAAATCCTAGTGCATAAAAAGGCAGTTTTCAATGCTTTCACTTTGTAAACTTTGTT +TAGTAGTAGAATATAATATATTCAGTTTTGTTTTATAGTCACATAACACTTTGTCTTTCA +AAGAATAATCTCCTTCGCAATACCAGCGAAATATTTTGGCAAAAAATTAACAATTAGGTT +CATAGTCCCCTAATTCAATTAATCGNNNNNNNNNNNNNNNNNTATAAGGGAAGATTGTGC +TGATGAAATAGACAATGAAACAATAATGAAGAATAAAGAAGAAGAAGATATAAAACATGC +CACCACCATCAAGAAGTAGAATAAACAAAACAAGAACATTAGGAATAGTGGGTACAGCTA +TAGCAGTGTTGGTCACGTCCTACTATATATATCAAAAGGTGACAAGTGCAAAGGAAGATA +ATGGGGCACGACCTCCAGAGGGTGATTCAGTAAAAGAGAACAAAAAGGCAAGGAAGAGCA +AATGTATTATAATGAGCAAGTCGATACAAGGACTGCCCATAAAGTGGGAGGAGTACGCCG +CTGATGAAGTGGTTTTGCTGGTACCTACGAGCCACACTGATGGATCAATGAAACAAGCCA +TTGGGGATGCCTTTCGCAAGACGAAAAACGAACACAAAATCATATATTGCGATAGCATGG +ATGGATTATGGTCATGTGTAAGACGGCTAGGTAAATTTCAGTGCATATTGAACTCCAGGG +ACTTCACAAGTAGTGGTGGTAGCGATGCAGCAGTCGTTCCTGAAGATATAGGCAGGTTTG +TCAAATTTGTTGTTGATAGCGATGTAGAGGATGTGCTGATTGACACTTTATGCAATTAAT +GTAGAAAAGAGTTTCTTGTAACANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNCAGCTCGGTTATAAGAGAACAAAAACACACGNN +NNNNNNNNNGTCGTCAATATAAAAAGGAAAGAAATCATCATTACAACTTGACCGAATCAA +TTAGATGTCTAACAATGCCAGGGTTTGACAATGTAGAAACGTCGCCTAGTTGGTCACTTT +CTCCTGCTAGGATTTTTCTTAAAATACGTCTCATAATTTTGCCGGATCTTGTCTTGGGCA +AGTCATCCACTAAAATGATCAATTTTGGTGCGGCAAATGGCCCGATGTCTTTTCTAACAG +TAAAGACCAAATGCTTCTTGATATCTTGTAATTCATCATCTGTTGCGGTGGACCAACTAG +ATTTGTTTTTCAACACCACAAATGCAGCAACTGCTTGACCAGTCAAGTCATCGTTGAATC +CGACAACAGCACACTCGGCCACAATTGGATCTTCGATAATAGCAGCCTCAATTTCAGCGG +TAGACAGACGGTGACCAGAGACGTTCACCACATCGTCTACACGACCCAAAATCCAGATAT +AACCATCCTTATCCTTTGCAGCACCATCACCAGTGAAATAGTAGCCAGGGTAAGGGTTCA +AATAAGTGTCTAGATACCTATCATGATTTTTCCAAATAGTTCTTGCAAATGATGGCCATG +CAGCTTTGACGGCAAGGACACCCTCTGCGTGGCTGGTGTTAAGTTCTTCACCAGTGTTAG +GGTCAAGAACAACTGCATCAATACCGAAGAAGGGGAATGAGGCAGAACCCGGTTTCATTG +GTGTAACACCACCAGCCAGCGGGGTGACCAGATGCGAACCAGATTCTGTTTGCCAGTAGG +TGTCTACAATGGGGATTTCATTTTTACCTATTTTTTCAGAGTACCACTCCCAAACTTCAG +CAGCAATTGGCTCACCGACCGAACCCAAGCAACGCAAAGATTTTAAGGAATGATTTTCGA +TGTAGGAATCACCAGCTCTTTTCAACAAACGCAAAGCAGTTGGCGCAACATAAAATTGGG +TGACTTTGTGTTCATCAATAATATCCCAATAACGGGAGTAATTTGGGTACGCAGGAGTCC +CTTCAAAGACCAAAGTGGCACAACCATATAGTAAGGGACCATAAACCACATAAGTGTGGC +CTGTAATCCAGCCAATGTCTCCAGCTGTGAAGAAAACGTCTTCTTGGTGAGTGTCAAAAG +TGTAGCGCATGGTCAACAAAGCTCCCAGCAAGTAACCTGCGGTAGAATGTTGAACACCCT +TGGGGGCACCAGTAGAACCAGACGTATACAACAAGAATAATGGATCCTCAGAATCAACGG +GTGTGCATGGATAGTAGGTCTTGTATTTCTTCTTTTCTGTTGCCCAATCCAAATCTCTGG +GGGCATGGAAAGCAACAGATGGATTGTTGGTCTTTCTATAAACCAAGACGTGTCTCACGC +CTGGGGTCTCTCTTAGCGCGTCATCAACAATTCTTTTAGTCTCAATGACTTTACCACCTC +TGTTGGATTCATCTGTAGTGATGACAACTTTAGAGTCCCCATCGTTGATACGATCTCTCA +AGGAGTTGGAAGAAAACCCGGCAAAGACTACGGAGTGAATGGCACCGATACGGGAAATGG +CCAACAAGGTTATGATTGCTTCTGGGACCATAGGCATGTACACGGCAACAGTATCGCCCT +TGCGAACGCCCATAGAGTAAGTCAGCACTTGTGCCACTTGACAAACTTCTTCAAGTAGTT +CCTTGTAGGTAATGGAATAGCCTTGGCCAGGCTCGTCACCTTCGAAAATAATGGCTTTCT +TGTTAGGAGTCTTCAAGGCATGTCTGTCAACACAGTTGTAACAGGCGTTTAATTGGCCGT +TGAGGAACCATGCATTGTTCTGGAAGGAGGGCCTGCCCGTTTTAGGGTCTGGGATGAACA +CCTTATCGAATGGCTTAGACCAGTTTAAAAATTGGGTAGCTTTAGAACCGAAGAACTTAG +CAGGGTCTTCAATAGACTCCTTGTGCAAGCGCTGATAGTCCTGCAACCCGTCCAAGTGTG +GAGAATAGTGGGTAGCAATTGCGGGCTGCAGTCTATCTGAGATGGGCCGTTGTGGCACGA +TCTTGACCGAAGTCAAATGTTCATACTCATGTTCCTTCTTCTGCTGCGCAGTGGCGGCAG +ACTGGGACATTTTTGCTTTCAACTTGTCAATTTCACTTGACTGTTCTTCTAGTTTTGATG +ATTGTACGGCAGAGGGCGACATAGCACAGTGGGCAATGTCTTTCTAGTAGTTTTGATATG +TTTGGTTTTGCTTATAGATAGAAAATATAAGAACAAGATATAACGTACTACCAGATAACC +TAAGGGAGAAATATGCTTAGAATAGCCGCCCAGTTTATATACAAAATGAAGGGAGAACTA +TTTGCCACCGAGGAACTGTACCCCAACTGCAATACCCATTGAATAATGGCATCGGAGGCT +CGGCGGCAATTCGTACCCCAACCNNNNNNNNNNACTTTTCTTTGGATCTTAGAGATAACA +GAAAAAAAGGATGACCCCAATCATTTGCCACGGCATGTCAACAGGTGAGTGCCTTTTGAN +NNNNNNNNNTCATCTCGACATCCGGCGAAATGGAGCAGTCACACGTGAACATTTTTAGGG +GATGGAGAGTGCTACGCCGTTCGTCCGAGATGATTATCATATTTACACAGCCGTACATAC +ACGTGCCATTTATCTTGATATCATTCTGGACGTATGTGCACATGTGATTTGCTTTTGTTT +TTTTAAGAATGTCGGGTAATAAACAGATTGTTTTTCTGGGAGGATAATCTTTTCTTTTTT +CCTGTTGGTATTCTAAAATTAACCTTGCTGTTTCNNNNNNNNNNNNNNNNCGCGCGACTA +CTCAGCCATCTTGCATTTTTAAAGAAAAAGATAATCATTAATGCCTTCACGGGAATACGT +ATAGAACATTATTAAAAGTATATGAATGGCATATATATATAGAACACCACCCTTGGAAAA +CATTTATACCCCTTAAACTAAAACAATTTGCTGCGCTATACCGTGTTTCAGTGTATTATA +ATACATTCATTTCTGTTTCATTACGATTATATTGACGTGATAAAAAGATTATATAGCCAT +GATCTTCCTAAACACCTTCGCAAGGTGCCTTTTAACGTGTTTCGTACTGTGCAGCGGTAC +AGCACGTTCCTCTGACACAAACGACACTACTCCGGCGTCTGCAAAGCATTTGCAGACCAC +TTCTTTATTGACGTGTATGGACAATTCGCAATTAACGGCATCATTCTTTGATGTGAAATT +TTACCCCGATAATAATACTGTTATCTTTGATATTGACGCTACGACGACGCTTAATGGGAA +CGTCACTGTGAAGGCTGAGCTGCTTACTTACGGACTGAAAGTCCTGGATAAGACTTTTGA +TTTATGTTCCTTGGGCCAAGTATCGCTTTGCCCCCTAAGTGCTGGGCGTATTGATGTCAT +GTCCACACAGGTGATCGAATCATCCATTACCAAGCAATTTCCCGGCATTGCTTACACCAT +TCCAGATTTGGACGCACAAGTACGTGTGGTGGCATACGCTCAGAATGACACGGAATTCGA +AACTCCGCTGGCTTGTGTCCAGGCTATCTTGAGTAACGGGAAGACAGTGCAAACAAAGTA +TGCGGCCTGGCCCATTGCCGCTATCTCAGGTGTCGGTGTACTTACCTCAGGGTTTGTGTC +TGTGATCGGTTACTCAGCCACTGCTGCTCACATTGCGTCCAACTCCATCTCATTGTTCAT +ATACTTCCAAAATCTAGCTATCACTGCAATGATGGGTGTCTCAAGGGTTCCACCCATTGC +TGCCGCGTGGACGCAGAATTTCCAATGGTCCATGGGTATCATCAATACAAACTTCATGCA +AAAGATTTTTGATTGGTACGTACAGGCCACTAATGGTGTCTCAAATGTTGTGGTAGCTAA +CAAGGACGTCTTGTCCATTAGTGTGCAAAAACGTGCTATCTCTATGGCATCGTCTAGTGA +TTACAATTTTGACACCATTTTAGACGATTCGAATCTGTACACCACTTCTGAGAAGGATCC +AAGCAATTACTCAGCCAAGATTCTCGTGTTAAGAGGTATAGAAAGAGTTGCTTATTTGGC +TAATATTGAGCTATCTAATTTCTTTTTGACCGGTATTGTGTTTTTTCTATTCTTCCTATT +TGTAGTTGTCGTCTCTTTGATTTTCTTTAAGGCGCTATTGGAAGTTCTTACAAGAGCAAG +AATATTGAAAGAGACTTCCAATTTCTTCCAATATAGGAAGAACTGGGGGAGTATTATCAA +AGGCACCCTTTTCAGATTATCTATCATCGCCTTCCCTCAAGTTTCTCTTCTGGCGATTTG +GGAATTTACTCAGGTCAACTCTCCAGCGATTGTTGTTGATGCGGTAGTAATATTACTGAT +CATCACGGGACTTCTGGTTTATGGAACTATAAGGGTTTTCATCAAGGGAAGAGAGTCTCT +CAGATTATACAAGAATCCTGCGTACCTACTTTACAGTGATACCTACTTCTTGAACAAGTT +TGGGTTCTTATACGTTCAATTCAAAGCAGATAAGTTTTGGTGGCTTTTACCCTTATTAAG +TTATGCGTTCTTAAGATCCCTGTTTGTTGCCGTTTTACAAAACCAAGGTAAGGCTCAAGC +AATGATCATCTTTGTCATTGAACTAGCTTACTTCGTTTGTCTCTGTTGGATAAGACCATA +TTTGGACAAGAGAACTAATGTTTTCAATATTGCTATTCATTTGGTGAATTTGATCAATGC +ANNNNNNNNNNNNNNNNNCAGTAATTTGTTCAAGCAACCAGCAGTGGTTTCGTCAGTGAT +GGCGGTTATTCTGTTCGTTTTGAACGCGGTGTTTGCTCTATTCCTATTATTGTTCACTAT +TGTCACCTGTACACTGGCATTACTACACAGAAACCCAGATGTCCGTTACCAACCAATGAA +AGATGACCGTGTGTCATTCATTCCTAAGATTCAAAATGATTTCGATGGCAAAAACAAAAA +TGATTCTGAACTGTTTGAATTGAGAAAAGCTGTTATGGACACCAATGAAAATGAGGAAGA +AAAAATGTTCCGTGACGACACTTTCGGCAAGAACCTGAATGCAAACACAAATACAGCAAG +ACTCTTTGATGATGAGACTAGTTCATCCTCTTTTAAGCAAAATTCCTCTCCCTTCGATGC +CTCGGAAGTAACGGAGCAACCTGTGCAACCAACCTCCGCTGTCATGGGTACGGGTGGCAG +CTTCTTGTCTCCACAGTACCAACGTGCGTCATCTGCTTCTCGTACTAATCTAGCGCCGAA +TAATACAAGCACCTCCAGTTTAATGAAGCCTGAATCAAGTCTCTACCTGGGGAATTCCAA +TAAATCATATTCGCATTTTAACAACAACGGCAGCAACGAAAACGCCCGCAACAACAACCC +ATATTTGTAATCCAATATATACTCACATGTAACAACTTATTATATAAATATTTAAGGGCA +AGGATATCCTACATTATATTTCATAGAAAACCGCTCAAAAAGGTGTATTATCTCCATTAC +ATCCCAACACCACACATATTTCAGCGATAAAAACCTTAAATGTGAAATTCGCTTTGGCTC +TGCTTCCTTAAATGTACGCAATTGCCGCTTTTTTCTGACATCTTTTTTGACGTGTAGAGA +AGGAAACAGATCCTCCAGAAGGGATTTACTGTTGGCTATTTTGTGTTAGAAGCAGGTTAA +TAATAGATTAGGTTGCGTAAGTCATGGTCGAAAATAGTACGCAGAAGGCCCCACATGCCG +GAAATGATGATAATAGCTCTACCAAGCCATATTCGGAGGCGTTTTTCTTAGGGTTCAATA +ACCCAACGCCTGGATTAGAAGCTGAGCACTCAAGCACATCGCCTGCCCCCGAGAACTCCG +AAACACATAATAGGAAAAGAAATAGAATATTGTTTGTCTGCCAGGCTTGTAGGAAGTCAA +AAACAAAGTGTGATAGAGAAAAACCTGAATGTGGTCGATGCGTCAAGCATGGGTTAAAAT +GTGTTTATGACGTATCAAAACAGCCAGCACCACGAATTCCGAGTAAAGACGCCATTATAT +CAAGGTTGGAAAAAGATATGTTTTATTGGAAAGATAAAGCTATGAAGCTACTAACAGAGA +GAGAGGTGAATGAATCAGGCAAGAGATCAGCAAGTCCGATCAATACAAACAATGCTAGCG +GGGACAGTCCTGATACCAAGAAGCAGCATAAAATGGAACCTATATATGAACAAAGTGGTA +ACGGGGATATAAACAATGGTACCAGAAATGATATTGAAATCAACTTGTATAGAAGTCATC +CAACCATGATCATGAGTAAAGTCATGAAAAGAGAAGTTAAGCCGTTATCTGAAAATTATA +TTATAATTCAGGACTGTTTTCTAAAAATCCTGGTCACTTCAGTGTTCCTTGACACTTCAA +AGAACACGATGATACCGGCATTGACGGCAAACGCGAATATTACAAGAGCCCAGCCTAGCG +TAGCAAATAACCTTTTGAAATTGAAGGAAATGCTAATCAGACAGTGTCAAACCGAAGATG +AAAAAAATCGTGTAAACGAATTCACTGATAGAATACTACAAAATACAAATTCAAATAGAA +ACTTGAAAATCGGTATGCTATTATCAATGCTTTACAATTCTGTCGGTTACCAATATCTGG +AGGATCATTGCCCTCAAGGTGGCGAATATTCGGATTTATTGAGAAATTTGATCAATGAAT +GTGAAGCTATTTTGCCATCTTACGAAATTATTGAACGCTACAAGAACCACTTTTATGAGT +ACGTTTATCCAAGTCTACCTTTCATCGAATTAGAAATTTTTGAAGAATCATTAAGTCAAA +CAATTTTTCCGGACCCAAACAACCCCTCCAAGGTGCAAATACGTATGGGTAGCACACATT +TGAGAGCTAAGGTGGAAAACTTGAGTCTTCTATTGGTTATCTTGAAACTCTCATACATGT +CAATAAGGTTTTTAGATCATAGTACAGCAGACTCGAGTTTTTATCTTTCAAAGGAAATAA +TTGATAAATACCCAATACCGAACGATTTTATTTTATTGAGTCAAAGATGTCTAGCATCGG +AAAATTGGTGTGCATGCGCTAATGAAAACATCATATCATGTTTACTATATATCTGGTCNN +NNNNNNNNNNNNCTCCTGAAGAGGGTGATTTCTTTCTCGAGCACCCCACCGATGTTATCA +GTAGTTTGATAATGATGCTTTCCACCTCGATTGGTCTCCACAGAGATCCTTCAGATTTCC +CTCAATTGATTTCCCCGTCCACCTCAGATAAAAGAACCTTGAATCACAGAAGAATACTCT +GGTTGAGTATCGTTACCGTTTGTTCGTTTGAAGCAAGTCTCAAAGGTAGACATTCTGTCT +CACCGATATCTTTAATGGCCTTATTCCTAAATATTAAGGATCCTGATTCTCTGACGGTAT +ATATGAACCGAGTTAGGGGCGATCTAAGCGATATCAATAATCACAAACTTTTGAGAATTC +ATAAATTTACATTCAAGAGAGCCCAGCTTGCGTTACTCCTGTCGGACTTAGATAACTTGA +CGATGACATACTATGGTAGTTTCCATTTGCATTCAATTGAATTCATAAGAGAAAAGATTG +AGATTTTTGTGGAGGAAAACTTTCCCATAGTACCATTAAAAAGTGTCGCACAGGATAAGT +CAGACCTTGATGACATGAATGTGATTTCAGAAATGAATATATTATCTTCAGAAAATTCTT +CTTCATTTCACAATCGAATAATGAATAAACTATTGATGTTGAGAACTTCAATGGCCGTAT +TCTTGCATTTTGAAACACTTATCACTAAGGATAAAAGTATCTTCCCATTCTACAAGAAAT +ACTTTATGGTTAGCTGTATGGATGCGTTGTCACTAATAAATTATTTCAATAAGTTTTTCA +ACGGAGAATATCGACACGCAATATCTTCTTTAACCAGTTTTAATGTTACAAAATTTATTC +AGTTAGCACTATCCAGCACAATCTTCAGCCTATTAGGGATTATACTAAGAATAGGTTTAG +CCATCCATATGTTATCTTCTGAAGTACAAAAGTTATCGGGAACGACAGATCCAAGAATAA +AGGAGTTAAATACCAAAGTCGAAAAATTTAGTACCCTGCAAAGAGATCTCGAGTCTGCTT +TAGAAGGTATATATTGCTCTGCTTCGGAACATTTAAGATTCACATACTTCCCCGTTTTTA +AGATGTTGGCTTTATTCGATGTCATTGTACAAAGGATGAGAAAGGGTGAATTATGGCACG +GCATATTTACGATGATTCAAATGGAACAAATGCATTCTAGGATAATCAAGACATTAAGCA +TTACCTTAGGAGTCAAACTGGACAAAAAGGATAGGCTATTAGAGGAATTGATGGCATGCA +ATCACGTTGCGAATTTTAGCGTTGAAGATATAGATGAGCTGAACCGTAATATCAAAAAAG +AGATTCAAATTTCTTCAGGATTGAAGCCGCCTGTAAACACAATTGACTTAACCAACGGCG +AACCATTCGGAAATGCTGTTCCTACCTTCACAAAGACATGGAGTTCATCCTTAGATAATT +TAGAAAAACTATCATCGGCCGCTGCAGTTGGTCAGAGCTTGGACTACAACAGTGGTTTAC +GTCAGGGTCCTTTGGCGGGTGGTGGTTCAAAAGAGCAAACGCCAATAGCCGGGATGAATA +ACTTGAACAATTCAATCAATGCTACACCAATTGTCGATAACTCATCTGGATCACAACTTC +CTAATGGTTTCGATAGAGGCCAAGCGAATAATACTCCTTTTCCAGGTTATTTTGGAGGTT +TGGATTTATTTGATTATGACTTTTTGTTTGGCAATGACTTTGCTTAAAAATTTTCTTTCC +AAACTCCTACCTATTCATTTCATCAATTAATTAATATTATATAGCCACGAATTTATGAAA +CTGACCGATAATATAAAGTGCTCANNNNNNNNNNNNNNNNNNNNNACGGTTAACGTAAGA +AGAGCTCTTCCCTCTTAAACATTCGAAAAATGATTGAACCAGTATATTTGGTCGAGCAAG +ACTTTCTCCTTCGCATATTTTACGGCAGGTATGGATATATCGCCTCTTGCTGCAAACCCG +TGAGCCACACCACTGAAGAGGTCTAACTGGTAAGTAGCGTGATTATCCTTTAATTTTTCC +TCCGTTAAGTGTCTTAAGTTTGCCGGAAAGATGTGATCCTCTTCCGCTGCTGAAATCAAT +ATTGGTTTCTTGCTATCAATTGCTTCAATTTCCTCGATGCTGACGAAAGATGGATGTGCA +ATGGCTGCAGCATTGGCAAGACCCCCGTCGCCACTAATGTGTTGGACGGCAAACTTTGCA +CCAAAACAGTAACCCACAACGCCAATAAACTTTGGGTCATATTCAAGTTTTAACAACTTC +ATGAATCCATCAACAATTTTCTTGGTGACTTCAGGAGAATGTCTTTGAAACCAGGCATCA +CGATCAATTGGTTTGTCCGATGAGATAGCATCGCCGAATAAAATATCGGGAACAAAGACC +ATGTACCCAGCACTAGCAAATTTGTCGGCCGTTAATAAAACATTGTTGAATTTATTGCCA +TACACATCTGTCAAGATAACTATAACTTTTTCCTTGGGAGATGTAGAGCCTGCTGCATAA +GTATCTAAACCGAAGATTTCTTCACGACGACCCTTGGGTGTTCCATCGTGACAAACTCCT +TCAAAGCAACACTTGCCAGGTTGATTAGATGCCATTTGATTGAAATAATTTTGTTCTGCT +GTAGTTAGACGTAGTGGAAAACTTTAAGTCTACTGAGTCTTGAGACCTTATCACCCTTTG +AAGGTTTCTTGCAAATGAGCGTGGTTTGGCATTTTTTATCGGAAAGAAAAAAAGGGCTCC +GCCTTAGGCCAGATATCATAGAAATGCAACACTTCCCTAATATAGAAATTTGGGCATTAA +TTATTTTGAGAATTTTGATGATTTGAATAATTTCATTAACGTAAAGGAACATAGTGCTAC +GAATCCAACAGTGGACCCAAAAATGAGAGCCGTTTGTCTGTAGTCGACATCTTTTGCTGC +TGTTTCTTCTGGCAATCCCGGAGTGTTTTTGCCAGGATCAAGAGCAGCTTCTGTGATTTT +AATAAACAATTCATTAAGGGAACTTAGCCATCTGGATGATATGTGCAGTGGGTGGTTCAC +AAATAGCTCGTCTGCCAGTTCATCTGGTTGGATTTGACACCTTTGTTGCTGCTTATCCAA +ATCTGCCTTAGAAGCTACAAATACCAACGGTAGATCTTGTAAATGTGTGAATTTGTCTAG +AAGCGAAACTAAGTAGGAGAATGATTCTGGGTCGCTGGAATCGTATGTTAGACAGATTAC +GTCACATTCTTTTAACTTATCCTTATTCTCTAGTATGGCGTATTCCTGTTCTCCAAGTTC +TTGCAAAATCAAATAGTACTGTTTCCCACCTTTGAGTTCTAAACTATTGACTGCAATTCT +TGGTTTGATTGTCGGAGAATACTCCTCCGAGAAAGATCTGCCCAAGAAGGCCTCTAGCAA +AGAGCTTTTGCCGCAACATGGCTTTCCAATGACAAAGCAATTGAACACTTTTCTGTCATT +GATATTGGATCTGTAAAGTTTCCCGGAACGGCGTCTCATTTTCCTTGGCTTGGTTACTTG +TAGGGCTAGTCTTGCATCTTCCTGAAAGCCAAAATACACCAAGTAAGCGGTAGTTGTGCT +ATAGTTCAAGAAAGTCGTCATACTCCATTGTGCTAGCCAGCCTTGTAAGGTGATGCAACC +CTTGTTGTTTACGACAGTGGAGAAGGGGAAATTCGTTGAGGTCCATAGTTTAGGCAGCCC +TGGTGTGCACTTAAATAGACGATGTAATTCTTGATTATTCAAACCACCATCATTGTCGAT +ATCAAACTTCAAAAAAATATCTACAAGAAATCTGTAGCCCTTGGGGCTCAATTCCACACT +GGAAGTGTCAGGGACAACCAACCTCGGATGGAGAATTTTGTCATTAATACACAAGGAATC +TGTGTAATGGAAAGTTCTTAGGATAGCCCATGTAGTTTCGTGTCTCCCCCTTTCAGCGTA +TATTTTGTTCAGTACAAGGAAACCATCTTTGGTGATGCCTTTTCCCGGTACGTATAGCTT +GCGGTTAATGTACTCTTGATCGTGCTTGGAAATATCCAAAAGCAAATCTTTAATAAAATT +CAGTTCGTTTACATCGATACTCTTATTGAAGCACTTTTTTTGTAAGCCCAAGATTTCGTT +GTCATCTAAATATGAGTCCTGGTTTAAATCGCTTAAAAGAAAAATTCTTTTTAAAGCCAT +GACAGCCAATGGCTTTAGTTCACCTACCATGGCATCAAATAAAGGTGATATTGGGTGTGT +TATAGCCCTTTGGCAAAGATAAAACGCTTGGTTAAGATCAAACTGTGTCTTGGCACTTGT +CTTAATGCAAGTGTCGATTTCTTTAAACTCCATTAATATTGGGATAAATTCTTCATCCTC +CACTTTGGTATCGATATCATCATCACTGTTCTCTGACACGACCATTGCATTGGCATTAAC +ATTCGATATGGAATCACATTTATTTTTGCAGAGAATGACAGGAATATTCAACCCCAGGGA +TCTGAAATGAGGCAACCAAAAGAGAGAAACATGGTCATACGATTCGTGATCGCAATACAC +AAGCCAAATTACGTCGGCGGACTTCAACTCATGGTCTAAAGCTATGAGGTCCGAATCTGA +AGTGTCTATAAGTACTGTATTCTTAGGAGAATATGTAGGTGATGATGAGAAATCTCTTGG +GATACTGATGGGTGGCAGCACGTCCTGTATGGTCGGTATGAATTCAGCTTTTGTTAATGA +TACAATCAGACTGGATTTACCAACCCCTTCATCACCGCAAATAACTACCCGAATCGTTTC +TTTAGTCATTGTGTTGTTCAACACATTAGTATTTAGAAGTCCGCTATTTTTGTTTTCAAT +TTTTATTTGTTTAATATACAAATTTCATTCTTGTTTTGAGGGTAAACCACTATACCAAAT +GTTGAAGATCTAAAGGTATCGATCAAATATGTTGCTAGAGAGTGACTGAGTGTTACATTA +AATATATTTATATATAAACGTATGATATTTAGGGATTGTTGATTGATAGGTTGAAAAGTT +TCGATCTCAATGACTCATTTTCCTGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNCGTCTTTCTCTTTCGGATATCCATCTTCTTTGTAACTCCTCTATTCGTA +AGGTCAGTTCTTTATTTGGAGTTGCCGTTAATTCATTGCCCTGTTGATGTGGCTGCTCTG +GGGTTTCCATGGAAATCAGTGAAGAGATATATGAGTTTATTATGGACTCTAATGCAGTCT +CTATAAAAGTGTAGAGCGATTCTAGTTTGGGCTGAATCAAATTCAAGTTTTTCAACGCAT +TTGGTACAGATTTTATGGATTTCATTTTCCTGTCAAATTGGGCAATAGAACTTTCTTGTA +AGATTTTCTGCAGAATATTGAAAATACTGTCAAGGTGTAGTAAAAGGTTCTGATTAAATT +TGATAAAATTGCTTTCATATTGGGATAGTATTAACTTTTGGTTGTCCAAAGTATTTAACT +GATTTTTTAATTGGTAATTCTCCAAGTCTAATTTGTCTAACTGATTTTGTATTACGTGGA +ATTCCTCTGATTTATCGATTTGAAGGTCATTGATTTGTTTTTCCAAGTCATTGATGTAGC +TGTCCCAATTATTTTCCTTTAGTTTATTGATTTTGGTCTGAGTTTCCAGTTCTTTGGTTA +AAACTTTTTCATTTTGTTTCATTTTAATGATGTCTTCCTTCAATTTTTCCAAATTGTTTA +TCAAGACAGATTGCGATTCGATCTTTTCCTTCAGTTGGGAAATCAAATGATCTTGTTTTT +CTATAACGGAACTAGAATTTTCTTCCAATTCTAAGGAATCTAGTAGATGAGACTGCTCAT +TTAGTTTGGACGCTATTATTTTTTCTAATTTTTGCGATTTCTCGAATTTCAATCTAATGG +AATTTATAAATTGATCATATTCTTTGTGCAAATTTTCTATGACAATCTCTAATTGAGTGT +CTAAGGTTTTCTCAAAACGAGACTCGACGGCTGAAATTGGTAAGGAAGTACTGTTTGCCA +TTACATTTTCTGTATCAATGTGGTTGTTACTGTCATGAATTTCGTCATTCTGGTATCCAC +CATCAGTATTCTCCTCTTTACTTGATGGTGAGTCCCTACTTTCTAACTGTGATCCTGCTG +GTGAGGACTGGGCCAGTGAAAGAAATTCTTCCTTATCCTGCTTTGATTCCGCTCGACTTT +TGGAATGCAAAAAGTCCTGCAAGAATTGGATGATGAACTTGGACAAAGTATCCATTTTTT +CAAGAACATAATCCGAGCTCAGCTCTAAAGTTTCCTCCAGGGTCTCCCTCTCTTCTTTAT +CAAGAAGATGGGCATTTTCATCTTGCTCATTAAAATGCGTCAATATAAAGGACAATAGGT +GATTGATCGTATTCACGATACTTTCCGAATTTTCTAAATTCTCTTGAACGAATTGTAGCG +TATCTTGGTACTCGACTTCCTTCGCCTTTAAATCCTGTTTCAATTTGTTTATTTCAAGAT +TTAGACCCTCGATAATCGAATTTCTAAAATCAGTGTCATTGCCCAGCGATGGTGCATTGC +CGTCTTTATTAGGGATTCTGCGAATGTATTCATAGAGTACTTGAATCTTGATTTTGGCAT +TAGTCAACTCCTTCTCCAAATTTTTGACTTTGTTGGAATCGTTCATCAGAGCAGGCTTGA +TGGGATCGTTATGAGATGACCTCGTGGTCATGGAGTCCCTGAGTGATGGTATGGACATCC +CAGAATCCATCGAGTTTGTGAACTCGCTGTCGTCATCATCACCAGTGTTGTCATTATTGC +GAAGATGCCTGCCACTAGGAATCCATCGACGTACCATGGCTATAACTTTCCTTATGTTGT +TTGCTTAGTTTTTTGATATTAGTGTTGCTTATGTGAAATTTCGCGATTTCAATTAAAATA +ATAAATACATATATAAAGAATATACACAGAGGGAAGCAAAAGTAAACTAAAAGTGATACT +TACACGAGCTTTTTTGGTTCCAAACTGTTCATGATGATGCCGGACCCTTCCCAGTTGACT +TCTTAGTGGTCAATTGTAGGCCATGCCATCTGGAAATATCGTCCCTCAAAATTCTGTTCA +CCAGCTGGTGCTGCTTGATGAGACTCAGTCCGTTGAACTTCTTGCTTGTTATGTTGATAG +CAAACATGGATCCGCAGCCACCGGAAACGTCTTGCACTTTACACACTTCAGGTTCCAGTT +CCTGTTGTAGTTTATCGGTGATCATCTTCTCCTCCGGAGTCATTGCCATCTGCGTTGAGT +ACCAAAGCTTTGAGCCCGTCAGAATCCTTGGCCACCGGACATGCTTCACAGATATAGAAC +GTAGCATGGTCTGTGGGAGCTTCATTTCTATGTTTTACCTTCTCTTTTCGCTTTTATGGT +TCTCAGTGACCAAATAAAGAAACTTATATATGTTCCGGAATGACGAATCAAAAAGAGAAT +AGCATCGTTAGCAGCAAACGAAAGTGGAAAGAGAATAATGTTCAAGAGAGCAATGAGCAC +AGATGGTCCCGTGGCACGTACCATCCTGAAGAGACTGGAATGCGGCTTTCCAGATTACAA +GAACTTTGCGTTTGGCCTCTACAACGATTCTCACAAGCATAAGGGCCATGCTGGTGTACA +GGGAAATGTCTCTGCTGAGACACATTTCCGGATTGAGATGGTCAGTAAAAAGTTCGAAGG +CCTGAAACTTCCACAACGCCATCGTATGGTTTATTCCCTCTTGCAAGACGAGATGGCTCA +GGCGAACGGTATCCATGCTTTACAATTGTCACTAAAGACCCCACAGGAGTATGAATCCAA +AGCGAAATAGAATGCATAAGCATAAGTGTACACGTTGAGTTTATTGTTTTATTTCCCCTA +CNNNNNNNNNNNNNNNNNNGAAATTACTTTACGTACGTATAAGCTTTGTTCAGTCATCAT +GAACCAGTGTCTTTTCGTACTGTTCTAAGGACATTAGACCCTCGACCTGTTCCACATTAA +CGCCCTCACCAAGCTTCATTTTGACTAGCCAGCCGTCACCCATAGGATCTTCGTTCACCA +CACCTGGATTTTCCTCAAGATTAGTGTTAATTTCCTCTACGGTACCATCGGCAGGCTGGT +AGATCTCGGAGGCTGACTTGACGGACTCAATGGACCCTAGCGACTCACCTTGGGCAATCT +CAGTGCCCACTTCTGGCAACTCAACATAGGTAGCGTCCCCTAAGGCATCAGTGGCGTATT +TTGTAATTCCGACAAAGGCAGTCTTGTCCTGATGCACAGCTATCCACTCATGTTGGGAAG +TGTACCTCACGGCTTGAGGTCCTTGGGATGAGTACAAAAATGGTAGTTTATTCTTGTTTA +GGGCATTGCCGGAGCTGTTTCTCAAAAACAATTTGCTCACAGTGGGCATGCGGGTGGTCC +ATAGTCTAGTAGTGCGTAACATTGTCGATGTGGTATGCTTCATGTGGAGATTCCCTTTCC +CATTAGATACTTGTTTGTTGGTCTGTATATATAGAAGAAAGAGTTAGCGAAAGTGACTCC +GCCGCTGAATGACTCCTTACGGAAGTGTCAAAATTGCGAGGTCCCTATAGCACAGAATGA +TAGATAAAACATTGATTTGCAAGTTGAAGGAAGACCCTACACATGCGTATATATGATGTA +TGTAATGGTTGTGATCATTTTAGCCTGTCAAGCAGTGAATCGCACTGCTTGTGTAAGCCT +TCATCTTCTTGCTTTAGCTGATGCAGCAGGTCGCGAACAGTGTCCTGCACTGGGGGTCTA +AACATAATGAGAAACTTTAGCGTTTGGAAACCAAGGGAACTTCTTGCCGGATCCAGGCAG +ATAGGCTTCAGTGCCTCAAGATGATCGCTTTGAAGACTGGGCAGTTCGCTCATAAGTCTG +ATGAAGAATCGTCTGTGTTTGTTTTCAAGGAATGGACCCAGAGACTCGAGAACTCTTAAG +GACCATTTTTTGTAGTTAGAGGGATCTTGATGCAGCGAGGTTTGGAAGAACCATTCTTCA +TTGAGCCATTCAATGATCAGACTGACACGTTGCTCGAAATCCTGGATGAAGAAGCCAAGC +AGTTCTTCACGAATCAGGTCACTGGCCTCTTGTGCTTCGATTCCTCTCGTAACCAATCTG +ATTAAGACGTGTAACCATGACGAGGAGTCGTCATCGTCCAGTAATATGGAGGAGGAAGAC +GAAGATTTGGCCCGGGTAGTATCCTGGCGACCGGATAATTCAAACAGTTTCTTGGTCAGC +TTTGAGAGGTACTTTAGTTTTTCATCCTGCGTCAATGAGTCAGGTTCAAAGGGGGGTGCG +ATCTCCTTAATGGCAGAAGTTGATTTGTTGGCATCTCCTGAGATTTCTTGGGCGCTTTCC +TCTTCTTGAAGCATCTTCTGCATTCGGTCATCGTCTTCGGGCTCCTCTGGTTCCTCCGCT +AGTGGTTCTGTTTCCATTTTGATTTTCTTGCTATTAGCCGTTGGGCCATCGTTTCCAACT +TCTTCATTGTCGTTGCCGTCGTCATCATCGTCGGATTTCCTCTTTGATGATGACGAGGAC +GGTACAGAATTGATGTACGTATTCATTAAATCCGTGTACCTCGAAGCAACGATAGACAAT +CCGGTGATCAGTTTCGTGCTGTCCATTTGCAAGATGGCCTCTGTGGACAGCTTGATAAGT +ATGTCATTGGGTAGCTGGGTCACATCCTGGTTGGAGTTCGAACTGTTCATCAATGAGTAC +ACAGATGAGTAGGTGTTGCTGATTGGTTTGGGTGAGTTGTTGAAAAAAGTATTGCCCTGG +TGTGAAGCCTTGTTGAGGGTGTATTTTTGCAATATCTTCAGTTGATCAAGCATGTTTTCG +GTTGAAGAGCCCGTTGCAGGTGCGGACACAGGCGTGGGGGTCTTTGTGGACACCCCTAGA +GTAGACAATAACGCGGATAATTGCCTTTTCCATAGTGAGATGTATTTTAGTTTGTCCTGC +CTGGACAACGTTTTCTTGCTATTGCCCTTGGAAGGGTCGAAGTTCAAAATTCCCTTGCTC +TTGGTCTCTTCGCCAATAACGTGTAAAGTTTGAGAAATCTTGGTCAGCTTGGAGTAGATC +GATGACCCTGATCCGGATGAGAGGGATTTTGTAATGATTTGATTTTTTAGCCCAAATTGC +ACAAAGTTCTTGTACGCCCTTTCAACAAATCTCTTGGATAGTTTGTAGTTCAAGTCAGAC +TTGCCCTCTAGGGGAAACTTGGCGTCGACGTTGAAACGCAACAGCCCGGAAAGAATTCTT +ATTGTTGTCTGCGGCCTTCTTTTGATGACGAAGGATAAAGAATTGATGATACCAATGAAA +ACGGACGAGACCATGTACTGTTCCTCAATTAGGTAGTTTAGCAACATATCAAGAAGCCTC +TTAGCCTCGCTCTCCAAAGCCGGTTTGTTCAACACAGGGTGGTTATCCGGGATGGTAGAT +GAATTAATCTCGTTGCCGCTGGGTGATTTAGTTTGCGACAGCACGACCTCAGATATGAAC +TTGATGGTCGCTAATTTCACGCCGATATTTTGGTCAATCTGCGCCAGCCATTGTTCGACA +TCCGTTTCATCGTCAACGGTGGCACGCAAAGGATATGCAGTTCTCCAGTGCGAGAGCACG +AACTTCTTCAGCATACACAACTGATCAAACATTTCCTGGTTTGATGTCTTAGCAACCAGA +TCCAACACCAGCGGGTATGAAGCGCACATAATAAGCACGATATTCTTGTACACTAGTACG +TCCGCGGTGGATTGCGCCATAGCAAGAAGTAGTGGCAGATATTGAGCAGCAATAAACGGT +CTCTCAGTATTCGCAATTGGAGAGTCCATCGACACCACGTCTAGAACTAACTGTGTAAAA +AACTTGGCCAAAGGCAACTTCAGCTTGCTGAGATTACCGTTGTGGTACATGGATGCCGTA +GTTTCGAGCACCTTGGGCAGCATCTCCGTTGGATTGTTGTGCATGGCCAGTGTCTTGGCC +TGTAACAATTGTTCCATCTCTGCAGATGACATTGCGCTGCTTAGTGGTAGTTATATGCTT +CTTGCCACGATTTAACCATTTGTTCAGTCAAGTACTAACGGTTAAAAGGTATCGAAATAT +GGCAACTTTTCACTTTTAGATCAAGTCACTATATACGACTTGAACATCAGAACGGCGATT +TTCCATCAAGATGGAGTGGAAACCACGCCATTATAAAGGAAAGCTAGTTTTATGTCTCGT +ATACATGCGGAGTAGGACAGTGATATAACACACATAGCTAGACACAATAGACATCATGAA +AAGGTCCACGTTGCTGTCGCTGGACGCATTCGCTAAGACCGAAGAGGACGTACGAGTCCG +CACCAGGGCCGGCGGGCTGATCACTTTATCGTGCATCTTGACCACGTTATTTCTGCTGGT +GAACGAGTGGGGACAGTTCAATTCTGTGGTAACAAGGCCACAATTGGTGGTGGACCGTGA +CCGACACGCAAAGCTGGAGCTTAATATGGATGTGACATTTCCATCGATGCCATGTGACCT +GGTGAATCTCGATATTATGGACGACTCTGGAGAGATGCAACTAGACATTCTTGACGCAGG +GTTCACGATGTCTAGGTTGAATAGCGAGGGTCGCCCCGTGGGAGATGCTACTGAGTTGCA +TGTGGGTGGGAACGGCGACGGAACCGCGCCGGTTAATAACGATCCTAACTATTGTGGGCC +ATGTTACGGTGCCAAAGATCAGTCGCAGAATGAGAATCTAGCACAGGAAGAGAAGGTTTG +CTGCCAAGACTGTGATGCAGTGAGATCAGCATACTTGGAGGCAGGCTGGGCTTTTTTCGA +CGGGAAGAATATCGAGCAGTGTGAAAGAGAGGGCTATGTCAGCAAGATTAACGAGCACTT +GAATGAAGGCTGCAGGATCAAAGGTTCTGCACAAATTAACAGAATTCAGGGGAATCTTCA +CTTTGCCCCTGGAAAACCCTACCAGAATGCATATGGACATTTTCATGATACTTCTTTGTA +CGACAAGACTTCGAATTTGAACTTCAACCACATCATCAATCATTTGAGCTTTGGGAAGCC +GATCCAGTCCCACAGTAAGTTGTTAGGAAACGATAAGCGCCACGGCGGCGCCGTAGTTGC +CACTTCTCCCTTGGACGGACGCCAGGTGTTCCCGGACAGGAACACACACTTTCACCAGTT +CTCGTATTTTGCCAAGATTGTCCCCACCAGATATGAGTACTTGGATAATGTTGTCATTGA +GACCGCGCAGTTCAGCGCCACTTTTCATTCCCGACCTCTTGCCGGTGGAAGGGACAAGGA +TCATCCAAACACACTTCACGTTAGGGGTGGTATCCCTGGTATGTTCGTCTTTTTCGAAAT +GTCTCCATTGAAAGTCATCAATAAGGAACAGCACGGGCAGACTTGGTCGGGCTTCATCTT +GAATTGTATCACCAGCATTGGTGGTGTCCTAGCTGTGGGCACTGTCATGGACAAGCTATT +CTACAAAGCACAGAGATCGATCTGGGGCAAGAAGAGCCAGTAGAGGAAGAGACTGTCATA +GGGAAGAGCCCTTTCTACATACTACTACNNNNNNNNNNNNNNNNNNNNNGAAATTGGTAT +ATCACTACTTGTACAAATATCATATTGTACGATAATCGCGAAGAACGACGCACTGGTGGG +AAGAAGTGGAAAACAGAAGCTTTAAGGTAGAAACAGAACAAGAATGTGGCTATGGTAGGA +TAGCAGAAGAGTACCATTGCTGTTATCATTTGTTGCCTAGCCCTATCAAGACCTGTCTGC +TAATCCAACCCGAGAGATCATGGCGATCCAAACCCGTTTTGCCTCGGGCACATCTTTATC +CGATTTGAAACCAAAACCAAGTGCAACTTCCATCTCCATACCCATGCAAAATGTCATGAA +CAAGCCTGTCACGGAACAGGACTCACTGTTCCATATATGCGCAAACATCCGGAAAAGACT +GGAGGTGTTACCTCAACTCAAACCTTTTTTACAATTGGCCTACCAATCGAGCGAGGTTTT +GAGTGAAAGGCAATCTCTTTTGCTATCCCAAAAGCAGCATCAGGAACTGCTCAAGTCCAA +TGGCGCTAACCGGGACAGTAGCGACTTGGCACCAACTTTAAGGTCTAGCTCTATCTCCAC +AGCTACCAGTCTCATGTCGATGGAAGGTATATCATACACGAATTCGAATCCCTCGGCCAC +CCCAAATATGGAGGACACTTTACTGACTTTTAGTATGGGTATTTTGCCCATTACCATGGA +TTGCGACCCTGTGACACAACTATCACAGCTGTTTCAACAAGGTGCGCCCCTCTGTATACT +TTTCAACTCTGTGAAGCCGCAATTTAAATTACCGGTAATAGCATCTGACGATTTGAAAGT +CTGTAAAAAATCCATTTATGACTTTATATTGGGCTGCAAGAAACACTTTGCATTTAACGA +TGAGGAGCTTTTCACTATATCCGACGTTTTTGCCAACTCTACTTCCCAGCTGGTCAAAGT +GCTAGAAGTAGTAGAAACGCTAATGAATTCCAGCCCTACTATTTTCCCCTCTAAGAGTAA +GACACAGCAAATCATGAACGCAGAAAACCAACACCGACATCAGCCTCAGCAGTCTTCGAA +GAAGCATAACGAGTATGTTAAAATTATCAAGGAATTCGTTGCAACGGAAAGAAAATATGT +TCACGATTTGGAAATTTTGGATAAATATAGACAGCAGTTATTAGACAGCAATCTAATAAC +GTCTGAAGAGTTGTACATGTTGTTCCCTAATTTGGGTGATGCTATAGATTTTCAAAGAAG +ATTTCTAATATCCTTGGAAATAAATGCTTTAGTAGAACCTTCCAAGCAAAGAATCGGGGC +TCTTTTCATGCATTCCAAACATTTTTTTAAGTTGTATGAGCCTTGGTCTATTGGCCAAAA +TGCAGCCATCGAATTTCTCTCTTCAACTTTGCACAAGATGAGGGTTGATGAATCGCAGCG +GTTCATAATTAACAATAAACTGGAATTGCAATCCTTCCTTTATAAACCCGTGCAAAGGCT +TTGTAGATATCCCCTGTTGGTCAAAGAATTGCTTGCTGAATCGAGTGACGATAATAATAC +GAAAGAACTTGAAGCTGCTTTAGATATTTCTAAAAATATTGCGAGAAGTATCAACGAAAA +TCAAAGAAGAACAGAAAATCATCAAGTGGTGAAGAAACTTTATGGTAGAGTGGTCAACTG +GAAGGGTTATAGAATTTCCAAGTTCGGTGAGTTATTATATTTCGATAAAGTGTTCATTTC +AACAACAAATAGCTCCTCGGAACCTGAAAGAGAATTTGAGGTTTATCTTTTTGAAAAAAT +CATCATCCTTTTTTCAGAGGTAGTGACTAAGAAATCTGCATCATCACTAATCCTTAAGAA +GAAATCCTCAACCTCAGCATCAATCTCCGCCTCGAACATAACGGACAACAATGGCAGCCC +TCACCACAGTTACCATAAGAGGCATAGCAATAGTAGTAGCAGTAATAATATCCATTTATC +TTCGTCTTCAGCAGCGGCGATAATACATTCCAGTACCAATAGTAGTGACAACAATTCCAA +CAATTCATCATCATCCTCATTATTCAAGCTGTCCGCTAACGAACCTAAGCTGGATCTAAG +AGGTCGAATTATGATAATGAATCTGAATCAAATCATACCGCAAAACAACCGGTCATTAAA +TATAACATGGGAATCCATAAAAGAGCAAGGTAATTTCCTTTTGAAATTCAAAAATGAGGA +AACAAGAGATAATTGGTCATCGTGTTTACAACAGTTGATTCATGATCTGAAAAATGAGCA +GTTTAAGGCAAGACATCACTCTTCAACATCGACGACTTCATCGACAGCCAAATCATCTTC +AATGATGTCACCCACCACAACTATGAATACACCGAATCATCACAACAGCCGCCAGACACA +CGATAGTATGGCTTCTTTCTCAAGTTCTCATATGAAAAGGGTTTCGGATGTCCTGCCTAA +ACGGAGGACCACTTCATCAAGTTTCGAAAGTGAAATTAAATCCATTTCAGAAAATTTCAA +GAACTCTATTCCAGAATCTTCCATACTCTTCAGGATATCATATAATAACAACTCTAATAA +TACCTCTAGTAGCGAGATCTTCACACTTTTGGTAGAAAAAGTTTGGAATTTTGACGACTT +GATAATGGCGATCAATTCTAAAATTTCGAATACACATAATAACAACATTTCACCAATCAC +CAAGATCAAATATCAGGACGAAGATGGGGATTTTGTTGTGTTAGGTAGCGATGAAGATTG +GAATGTTGCTAAAGAAATGTTGGCGGAAAACAATGAGAAATTCTTGAACATTCGTCTGTA +TTGATAAATAAAACTAGTATACAGCAAATACTAAATAATTCAAGAAAAAAACATTAGATA +GAGAGGGGCAGATGTTCAAGCTATACCCATTATATTGATCCACACTTAGTATTAAGATAC +GTCTGTGAAGGATGNNNNNNNNTGTATAATGTGACTAGAGGAAGTAAGGAGAAAAAACGA +TAGTAATCGTATTTTAGGTTGTGCGTTTTTATAANNNNNNNNNNNNNGTAATTCTATGCA +AATGTAATATAAGTATATTTAAAGAAATAATGAGTCCTGTGNNNNNNNNNNNNNNNNNNG +ATCATTAATGTATGTTAACGTATTTGCTTTGCAAATTTTAATTTATTTGTTGTTAAATGC +ANNNNNNNNNNGTCGTTTCAGCGAGTTTTCTTGAGGTTGCTACTATCATTAAAATCACAA +TCCACAGAGGAAGTTGATCTCTTTTTCAGTTGGGTGGGGGCAGAGCATGGGTGAGCAGTG +GCCATGGGTCTAACAGGAAATAATCTTTTTGAACGCACAGATAAATTTTGTAATAATTTT +CTATTTGACATTAGAGATGGGGTGGTGGGAGTTAGTGGGCTTGGCCAAAAGATGCTTGAA +TTTTGTGGGATGCTCAGTGACCTTTTAAAAGAATTTTGGGTAGAAGAGAACGAACCTGAA +TGTGAATGGTGTGATGCAGAGTCTGGGGTCGTCATTGAACTTGAAGTCTTGTAAGGGGAA +TTGAATGGAGATGGAGAGGATGAAGATGAGGTTGGAGTGAAGGCAAATGGTGGAGAAATG +CTATCTTTGGTCAACCTTCTTAAATGAGTGTGATCCGAGAAATAGTCTGTGGCCGCAGAT +GAAACCGTAGCGCTCTTTGGAGTAGTAGCATTTGAGTAAACACAAGTCAATGAATCGCTG +TCAAAGGACTGAGCAAAGATAGTATTGTACATGGTTTCCAATTCTTGTGAACGGTAGAAT +TCTTCCAGTTTCAATTGAATACAATAGTTTTGTAATGCGTCTAAGAGAGATTTTGCTAAA +GATGTCTTATTGCTATTCAAATATTTTGATTTGAAACTGGAGGGGAAAGAATTTTGGTCC +ATTGCTATATCCAATAAAGTATTAGAGATTTCTGACAATTTAATATCTAGGTCTTGGCAG +TTTTCCTCCAAAGCCAGATTGATATTTTCCCAAAGGTTTGAATTATAGTAGTTCAAAGAT +AATTTGATGAGGTTAATTGCACCCAGCGCAATTAGTGAACGATCATATTTAAATGATAAT +TCGAGATTGAAGGAAGCTAACTCGCACAACATAATGGCACCCAATTTGATCTCGTTGATG +TTCAAAGAGGGGCCTTGAGAAGAGGACGATTTATTAATAGCAGTACCAGCAGCGTTATTT +AATAAGGCCAGTTTCTGTTGAATGAAAGCTTCCAAAGGGGCAGAAAGGACAACGCCAGGC +GATAACGGGGACGTAGATTGGAACAAGAAGATGTCGATGTAGGAGTCGAATGTTGCCGAC +TGACAGATGGACCAATCGAGTGATTTGAAAAGATGCATTTCCATAGTCGTGAATTGCTTT +ATAGAATATTGATTGCAACACAAGTTTTGCAAGACTTTCAAAGTGGCCATTCTATTCTTG +GAGTCCCAAAATTTGGACGAAATCCAAAGCGCGGTCAAGGACAAGAGCTGGTAGTTGTAA +CTCTTGATAATGAACCGCGAGGAATACTTGTCCAAGATAGTGAAAGTAAGGAACAAAGTC +GAGGTCGATAGATTGAGTCTTGTGTGACAGTACATGATGAAGTCAAAGATCAAGAAACGC +ATCTTCGGATTAACTTGTGGCTGAGAGTTGAAGTTAGTCAGGTTGTACAGCGGCCTTTCT +GTGTGGGAAAGACGGAAATAGTGGTCCAATTGATCATTATTGTATTCGCTGATCGCTGAG +TGATGTGCTTGCAATTCTCTTTTAACGAGATTAGGGTTTTTAGACTTTGCACTAGCAATG +GCCCGCCTCTTTTGCAAGAGCAAGGGCAAATTAGGACATGAGGCAGCGCTGACAGAGGCG +GCAGTGGCGGTGGAAGTGCCACTAGCGGTAGCATACCTTGCATTAGCGTATCTAATTATG +GTATCCTTCAATATGGCCATCGTACAGAAAGCGTATCAAATCAGTGTCTTGAACGAGAGT +AAAAGGGAGATGCAATGGAATGTAAGAAATGCTATGGGTCAGAAAAGAAATGCAGAGGAG +TTAAACCGAATGAGGAAATGCAATGGATACGTTAAATTGGAGATGTGAGATTGCGACTGG +GACTCGGATGGATGCTTGCTTTTGGATGCTAGTACNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNGTTGGTTTAAGTCGGCAGAGGAGACTACTCGGGCAATTCGTTTC +CTAATGGGTATAGTCCTCTTTCCTCAGAAATCCATTTGACTGGCAGACTCAGTAGTAGAA +GAAAAAATCAAGAAAGAAATTGTGTGAAAGTATACTACACAAGAAAATGTTTAAGAAGAA +GATTAAAAGCTCGAGGAAAGTACAGATATACAAATTATAAATAGGTAGGAGGAAGNNNNN +NNNNNGATGAGGGCAAAAACCCAAGGCCAAATATGGAAATGTGGCAGAGGGACACACTAA +TCCGATAGTAAATTTATGTAACTTGATCATTACAGTGAGAGCAGGCTTGGTAATTTCTTT +TTCTTGCCTGATAANNNNNNNNNNNNNNNNNNNNNNNNNCTTGAAAGTTCACAATTTAGG +GTTTGAGCACAGCGTTTGGTTGCGACACTTCCCCAGAAGGAAAACCGGCCTCTTTGGCTG +GGGAGGGAAGAAGGGGGAGGAGAGCTCAGAAAGCCCTATCGCGATATGAGGGACCGATCT +GTATCAGCATACTTTCGGTATCATCACGGTCGCAGGATAGAGATAGTGAATGAGTTAGCT +GTTTTACAGGCCAAGCGTTCAAACGAGACGAATGGCGACATTTGCCCGTCAAGAAAACCC +GCCGAGTTTTTTCCTAAACGGGTAAAACAGCCATGCACCGCAGCACGTCGACGAGGTGAT +ATTTCCAATTTGGGAAATTTCCCAAATCAGTAATGTAGCCTCTACGGGTGTCTCTGTCAG +CCCCGTGGTCGCCAGCACAGAATGTATCGTACCCCTGAAGGTAGTTTTTTACCGCCGTGG +CACACGATAAAGGTGCACCTTGTGATAATAAGGTGGAAAAATATATATGAAAAAGTGAAA +TTGATTGTGGCTGCACTAGGACATCATTATTTCTTACTTGGCTATTTACACGTACTTACG +CTGGCTGTATATCATTTAAGGGGCGGAGGACGAAGAGGACGGACCCGAGATCATCCGGTC +CAAGAAACGGGTCATCCGGTCCTTAGCATTGTCTAGACTATCTAGGGCAGGACGGACATC +CACGTGGAAAGTAGGCATTCCGTTTTCGTCGTCGGGCCCTCCGTAGAAATCCAAGACGTA +TCTAACTTCCTTGAAGGTTGGAGGTTGTTGTTCCGCTTTGCGCTCGCCTCGGAGTACAAT +CCAGTCGTGCCTGTCGAATGGTAGTTCTTGGCTAAAATGGGACGGAAACAGTAGGCCGCA +CAGGTGCATCCAGCGAGCACGAGGGCTCAATACGCCCGGTTTCCCCATGAATTTCAGCAA +CTTAGGCTGCACGTGGCTTTCATCTGTGTGCGGTTTTTCCCATTCGAGCACTTCCTGCCA +GCACCCTTCATTTAGAAAGTTGTGGACCTGCACCATGGACTCCACTGCATCTTCGGCGAC +TTCGCCGCTACCGCCAATCTTGCCCTTTCTAACCATAGCATTGTACATCTGTTGTGGAGA +AGGATACTCCCAGAACTCGTTACTGTCTGGACTCTTGGGGATGCTGGAGATGGTCCGATC +AACGGGCAAGTCCATCTTTTGGCCAGGCTGTTTGGATGCTGCCAACTCCGGCATATTGTT +CAGCGGGTTTATTCTATCGTTATCTCCCTGCATAACGGGGCACTCAGAGGATGGTGGCGA +CGACGACGACGACTCGTGCATGACTGGGCACCCTGACATGGATGATACTGCTGCCCCACC +AATATCTTTGCCCGTAGTTTTTTGATCTGCCCAAAACCAACCCATTTTTTGTAGTTTCTG +TTGTATTTGCTCTGCTTTATTCGTGCTACTCGTATGTGTATGCTATCTTATTAGCTGCCT +ATTTCATTTCTCTTAGTATTCGCATTTAAAGCTGAGAAATTTTTTGATAATCATTTCCCG +ATNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNTTTGGGTNNNNNNNNCGGAAGATCCCACGCCGCGCAAGAGATATTTCAATATT +ACTACTACATAGTATATGCGGCGCTACCATACGTACAACNNNNNNNNNNNNNNNNNNNNN +NNNGCCTTCTAAATTTGTAATTCGGTCACACTTTTGTCGCAGTGTTGCAAACGTCTTGAA +AGAATTGTAGGTGTTGTAAACCACAACTTGCTCCCTTGAAAGCGTTGCTGATTATTTCCT +TTGAACCNNNNNNNNNNNNNNNNNNNNNNNNNNCTGCTGATGTTTTAGGCACTTAGTATT +AGATATTCCTAAGCCTCCCTCACCATAAATTACCTTTATTACTTGCATGACTATTATTAG +CAGAGCATGTAGTATGGGACTCAAGACCGATATGATACACACCAAAGACGTAGGCACCGG +CGATTAAATCAAAGGCTCCGATAGCCGAAAAGTGAGAAGNNNNNNNNNNNNNNNNNNNNN +NTTGTCCTAATGAGCGGTGTGGCCGACTTGCCATAATATCAGTTAGGGCTACTATCAATG +TTTTATCTACGTTGGAGTAAGATCGTTTATCACTTCCATATTTGGACCAAATGAAAAGTT +CAATCGGCCAAGTATTTCATGGATGGAATGACGTTTGGTAAGGAAGTGCTTTTTCTTTTT +CCACATATTTTCCCTTTCTCTCGGGGAAATTTTGTTTCTAAACATAAAAAATAAAGCAAC +AGCAAAAAAGAGGGTCTGTCCAGCGAATAAGAAGAAAACCTCCTTTTCGGCTTTTGAAGA +TAGGTTGCAGTTGTCTGCGGGCACAAAATGGGCANNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNCGCCAATTATATCGCATGAAGAATAACCAGAGTTTTTCTCCGAACG +TTAAGGGAGTTGAAGTAAAAATAAAGAAAGGACCAAATGAGAATGGGTATGCTTGGTCTT +AGTCTTCGAATCAAATTCTGCTTCCCTGTTCATGGCAACGTCACCTCAATTATTTGGAAA +GGGGGGGTTTTCCGACTTTATTTGAGATGACTTGAGATGTGTGTCAATGCTAGTATTTTG +GAGATTAATCTCAGTACAAAACAATATTAAAAAGAGGTGAATTATTTTTCCCCCCTTANN +NNNNNNNNGTTAGAATTGATCCAAATGTAAATAAACAATCACAAGGNNNNNNNNNNNNNN +NNNNNNNNTAGCCGCCATGACCCCGGATCGTCGGTTGTGATACGGTCAGGGTAGCGCCCT +GGTCAAACTTCAGAACTAAAAAAATAATAAGGAAGAAAAAAATAGCTAATTTTTCCGGCA +GAAAGATTTTCGCTACCCGAAAGTTTTTCCGGCAAGCTAAATGGAAAAAGGAAAGATTAT +TGAAAGAGAAAGAAAGNNNNNNNNNNNNTGTACACCCAGACATCGGGCTTCCACAATTTC +GGCTCTATTGTTTTCCATCTCTCGCAACGGCGGGATTCCTCTATGGCGTGTGATGTCTGT +ATCTGTTACTTAATCCAGAAACTGGCACTTGACCCAACTCTGCCACGTGGGTCGTTTTGC +CATCGACAGATTGGGAGATTTTCATAGTAGAATTCAGCATGATAGCTACGTAAATGTGTT +CCGCACCGTCACAAAGTGTTTTCTACTGTTCTTTCTTCTTTCGTTCATTCAGTTGAGTTG +AGTGAGTGCTTTGTTCAATGGATCTTAGCTAAAATGCATATTTTTTCTCTTGGTAAATGA +ATGCTTGTGATGTCTTCCAAGTGATTTCCTTTCCTTCCCATATGATGCTAGGTACCTTTA +GTGTCTTCCTNNNNNNNNNNNNNGGCTCGCCATCAAAACGATATTCGTTGGCNNNNNNNN +CTGAATTATAAATACTCTTTGGTAACTTTTCATTTCCAAGAACCTCTTTTTTCCAGTTAT +ATCATGGTCCCCTTTCAAAGTTATTCTCTACTCTTTTTCATATTCATTCTTTTTCATCCT +TTGGTTTTTTATTCTTAACTTGTTTATTATTCTCTCTTGTTTCTATTTACAAGACACCAA +TCAAAACAAATAAAACATCATCACAATGTCTAGATTAGAAAGATTGACCTCATTAAACGT +TGTTGCTGGTTCTGACTTGAGAAGAACCTCCATCATTGGTACCATCGGTCCAAAGACCAA +CAACCCAGAAACCTTGGTTGCTTTGAGAAAGGCTGGTTTGAACATTGTCCGTATGAACTT +CTCTCACGGTTCTTACGAATACCACAAGTCTGTCATTGACAACGCCAGAAAGTCCGAAGA +ATTGTACCCAGGTAGACCATTGGCCATTGCTTTGGACACCAAGGGTCCAGAAATCAGAAC +TGGTACCACCACCAACGATGTTGACTACCCAATCCCACCAAACCACGAAATGATCTTCAC +CACCGATGACAAGTACGCTAAGGCTTGTGACGACAAGATCATGTACGTTGACTACAAGAA +CATCACCAAGGTCATCTCCGCTGGTAGAATCATCTACGTTGATGATGGTGTTTTGTCTTT +CCAAGTTTTGGAAGTCGTTGACGACAAGACTTTGAAGGTCAAGGCTTTGAACGCCGGTAA +GATCTGTTCCCACAAGGGTGTCAACTTACCAGGTACCGATGTCGATTTGCCAGCTTTGTC +TGAAAAGGACAAGGAAGATTTGAGATTCGGTGTCAAGAACGGTGTCCACATGGTCTTCGC +TTCTTTCATCAGAACCGCCAACGATGTTTTGACCATCAGAGAAGTCTTGGGTGAACAAGG +TAAGGACGTCAAGATCATTGTCAAGATTGAAAACCAACAAGGTGTTAACAACTTCGACGA +AATCTTGAAGGTCACTGACGGTGTTATGGTTGCCAGAGGTGACTTGGGTATTGAAATCCC +AGCCCCAGAAGTCTTGGCTGTCCAAAAGAAATTGATTGCTAAGTCTAACTTGGCTGGTAA +GCCAGTTATCTGTGCTACCCAAATGTTGGAATCCATGACTTACAACCCAAGACCAACCAG +AGCTGAAGTTTCCGATGTCGGTAACGCTATCTTGGATGGTGCTGACTGTGTTATGTTGTC +TGGTGAAACCGCCAAGGGTAACTACCCAATCAACGCCGTTACCACTATGGCTGAAACCGC +TGTCATTGCTGAACAAGCTATCGCTTACTTGCCAAACTACGATGACATGAGAAACTGTAC +TCCAAAGCCAACCTCCACCACCGAAACCGTCGCTGCCTCCGCTGTCGCTGCTGTTTTCGA +ACAAAAGGCCAAGGCTATCATTGTCTTGTCCACTTCCGGTACCACCCCAAGATTGGTTTC +CAAGTACAGACCAAACTGTCCAATCATCTTGGTTACCAGATGCCCAAGAGCTGCTAGATT +CTCTCACTTGTACAGAGGTGTCTTCCCATTCGTTTTCGAAAAGGAACCTGTCTCTGACTG +GACTGATGATGTTGAAGCCCGTATCAACTTCGGTATTGAAAAGGCTAAGGAATTCGGTAT +CTTGAAGAAGGGTGACACTTACGTTTCCATCCAAGGTTTCAAGGCCGGTGCTGGTCACTC +CAACACTTTGCAAGTCTCTACCGTTTAAAAAAAGAATCATGATTGAATGAAGNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTTCAACTCAAAT +AAAGATTTATAAGTTACTTAAATAACATACATTTTATAAGGTATTCTATAAAAAGAGTAT +TATGTTATTGTTAACCTTTTTGTCTCCAATTGTCGTCATAACGATGAGGTGTTGCATTTT +TGGAAACGAGATTGACATAGAGTCAAAATTTGCTAAATTTGATCCCTCCCATCGCAAGAT +AATCTTCCCTCAAGGTTATCATGATTATCAGGATGGCGAAAGGATACGCTAAAAATTCAA +TAAAAAATTCAATATAATTTTCGTTTCCCAAGAACTAACTTGGAAGGTTATACATGGGTA +CATAAATGCAGATGCCAGTGAACTATGTTCAGCTTCTGGCCTTCGTTTGGTGGTTTAATC +TATTTTTTATAAAAAATGACGCGGGCAGATTCAATTAGTGTCCTAAATTTATTCGCGTTT +CAAGATTTCAAAGGATTGATCCTCTTATCAGAAACGATAAGTGCTACTCCGTCCTATTCT +TCTAGCCATCTAGTACGTATTCTTTTCATAACATAATCCCTTATTTACAGAATGTGTTTC +GAAGAAAAATTAATTAGATGGGAAGAAAACTGAAGTGGCTTATATAATCAGTGACATAGT +GCCAATAATTACGCAAAAAGCAAAGGAAATAACACTGCTATGGATATGGAAATCGAAGAT +TCAAGCCCCATAGATGACCTGAAGTTACAAAAACTGGATACCAATGTTTATTTTGGACCC +TGTGAGATATTGACACAACCTATTCTTTTGCAATATGAAAATATTAAGTTCATCATTGGT +GTCAATCTAAGTACTGAAAAGATAGCGTCGTTTTATACCCAGTATTTCAGGAACTCTAAT +TCGGTAGTCGTGAATCTTTGCTCACCAACTACAGCAGCAGTAGCAACAAAGAAGGCCGCA +ATTGATTTGTATATACGAAACAATACAATACTACTACAGAAATTCGTTGGACAGTACTTG +CAGATGGGCAAAAAGATAAAAACATCTTTAACACAGGCACAAACCGATACAATCCAATCA +CTGCCCCAGTTTTGTAATTCGAATGTCCTCAGTGGTGAGCCCTTGGTACAGTACCAGGCA +TTCAACGATCTGTTGGCACTCTTTAAGTCATTTAGTCATTTTGGAAATATCTTGGTTATA +TCATCACATTCCTATGATTGCGCACTTCTCAAATTTCTTATTTCCAGGGTGATGACCTAC +TATCCACTAGTGACCATCCAGGATTCTTTGCAATATATGAAAGCAACCCTGAACATATCC +ATCAGTACATCCGATGAGTTCGATATTCTGAATGATAAAGAACTGTGGGAGTTTGGCCAA +ACCCAGGAAATTCTAAAACGTAGGCAGACGAGCTCAGTCAAGAGGAGATGTGTCAATTTA +CCAGAAAACTCTACGATCGATAACAGAATGCTTATGGGTACCACAAAGCGAGGTCGCTTT +TGAAGAGCCCTCGGTAGCATAACATTTTTAATTATTACGACTGNNNNNNNNATTCATTAT +GTAGAGATAATTAAATGTTATAGATGCTCTATACTCAAACGGTGGAAGNNNNNNNNNNNN +NNNNNNTAACCGATACCCCCTTTTCGAATACAAATGCTTGTATATTCAATTATGAATTAN +NNNNNNNNNNNNNCATTTCTTATATTATTTTTTGTTCGAGAATCACTTTTTCAAGATGGT +AACAACATCTTCGTCTTCCAAAATGTGACTCAACCCCACGTATTGAGGTTGATGTTTGAC +ACTGCTACCGTAAACCAGAGCATTTCTAAAGTCGTCCACTAAAGATTTATGAATTTGGTT +ACAAAAATCCTTGACACTGCAACGGTCTGATCTTAGCACCACAGGGTCGGTAAAATCTGG +TATTTGGCCCTTTGGTTTAGTGTAAATACGGACTAGATTTAGTCTATCCCACATGACTTG +CAACAGCTCGTCCAAGTTCCAATCTTGACCAGACGAAATAGGCACGGCATTAGGAATTCG +GTAAAGTAATTCCAATTCCTCTATTGACAGAGAATCAATCTTGTTTAACACATAGATGGC +AGGCATGTATCTTCTTGACGAAGCTTCCAAAACATCAATCAAATCATCCACAGTGGCATC +ACACCTGAAGGCAATCTCAGCGCTATTTATTCTGTACTCGCTCATAACGGCTCTGATTTC +GTCATTCCCCAGATGGGTCAATGGGACTGTGTTTGTGATGGAAATACCACCTTTCTCNNN +NNNNNNGATCAAGATATCTGGCGGAGTTTTATTCAGACGAATCCCCACACCTTCCAGTTC +CTTCTCAATGATTTGCTTATGATGCAAGGGTTTGTTCACATCTAGGATGATAAATAACAG +GTTACAGGTTCTTGCCACGGCAATAACTTGCTTACCTCTACCTCTACCATCCTTAGCACC +ATCGATAATACCAGGTAAATCCAACATTTGGATCTTGGCACCTTTATAACGAATGACACC +GGGGACGGTAACCAGGGTGGTAAACTCGTACTCAGCTGCTTCAGACTCAGTACCAGTCAA +CTTGGACAGTAATGTAGATTTCCCCACCGACGGGAACCCGACAAACCCCACACTGGCCAC +ACCAGTTCTAGCCACATCAAAACCAATACCAGCACCACCACCGCTGCCGGATGAAGCACT +GGTCAACAATTCTCTTCTCAGTTTGGCCAGCTTGGCCTTCAGTTGACCCAAATGGAAAGA +TGTGGCCTTGTTCTTTTGGGTACGGGCCATTTCATCTTCGATAGCTTTGATTTTTTCAAC +TGTAGTAGACATTTTGCTCAATCAACAACTCTACGCTTGCACCTACTGCATCTAGCTTCA +AACACTTCCTATCATTGCGCCCTCATCACACCGTAATATCCCATCTTAAAAGTGGAAAAC +TCTTATAGCTCATCGATGAAAAAAACGGGCCCTCGTCGCTTGTGATGTGAAAAAATTTTT +CAAGCTTTAAGCCCATTGAAAGCAAGAGATCTTGCACTAGAATAAGTGGCAAAGGTGAAC +TTTGAGGGGATAAGAAGGGCAATCAGGAACATCAGATAAGTGAAAGATGGCGAAAAAGAG +TAAAAAGAACCAACAGAACTACTGGGATGAGGAATTCGAAGAAGACGCCGCCCAGAACGA +AGAAATCAGTGCCACGCCAACTCCAAATCCAGAAAGCAGCGCAGGTGCAGATGACACTTC +CAGAGAAGCAAGTGCAAGTGCTGAAGGTGCTGAGGCCATTGAAGGCGACTTCATGTCTAC +TTTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGATGGTAA +GCCTATACTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNGCCCAACAGCAAGCTCAAAAGGAGAAGAACAA +GGAGTTGAACAAGCAAAATGTTGAAAAAGCTGCTGCTGAGAAGGCTGCTGCTGAGAAATC +CCAAAAATCTAAAGGTGAAAGTGATAAACCAAGTGCTAGTGCTAAGAAGCCAGCCAAGAA +AGTACCTGCCGGTTTGGCTGCTTTGAGACGTCAATTAGAATTGAAGAAACAACTTNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNGAAGAAGCTAAAGCAGCTAAAAAGGAAAAGGAGAAGGC +AAAGCGTGAAAAACGAAAGGCTGAAGGTAAGCTATTGACCAGAAAGCAAAAAGAAGAAAA +GAAATTATTGGAAAGAAGACGTGCCGCTTTATTGTCTTCCGGTAACGTCAAAGTTGCCGG +TCTGGCCAAGAAGGATGGAGAAGAAAACAAACCAAAGAAGGTTGTTTACAGCAAGAAGAA +GAAGAGAACAACCCAGGAAAACGCCTCCGAAGCCATTAAATCTGACTCTAAGAAAGACTC +GGAAGTTGTACCTGATGACGAACTCAAAGAATCCGAAGATGTTTTGATTGATGATTGGGA +AAATTTGGCTCTTGGTGATGATGACGAGGAGGGAACCAACGAAGAAACGCAAGAATCCAC +CGCAAGCCATGAAAATGAAGACCAAAATCAAGGCNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNGCACATGTGCATGAAGTTGCCAAAAGCNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNACTCCATCCAGCGCTTCTCCAAACAAAAAAGATCTTCGTTC +CCCAATTTGTTGTATTTTGGGTCATGTCGATACCGGTAAGACTAAATTGTTAGACAAAAT +CAGACAAACCAACGTTCAAGGTGGTGAAGCTGGTGGCATCACCCAACAGATTGGTGCCAC +TTATTTCCCCATCGACGCTATTAAGGCAAAAACTAAAGTTATGGCTGAATATGAAAAACA +AACTTTTGATGTCCCAGGTCTTTTGGTTATTGATACCCCAGGTCACGAATCCTTCTCTAA +CTTACGTTCAAGAGGTTCTTCATTGTGTAACATCGCAATTTTGGTTATTGACATTATGCA +TGGTTTGGAACAACAGACTATTGAATCTATCAAACTGTTAAGAGATAGAAAGGCTCCATT +TGTCGTTGCCCTAAACAAAATTGATAGATTATATGACTGGAAAGCCATTCCAAACAATTC +ATTCAGAGACTCCTTTGCAAAGCAATCAAGAGCTGTTCAAGAGGAATTTCAATCTAGGTA +TTCTAAGATTCAATTGGAATTAGCTGAACAAGGTTTGAATTCGGAATTGTATTTCCAAAA +CAAAAATATGTCTAAGTATGTCTCCATTGTCCCAACATCTGCCGTCACCGGTGAGGGTGT +TCCAGATTTATTGTGGTTGCTATTAGAATTGACCCAAAAGAGGATGTCCAAACAATTGAT +GTACTTGTCTCACGTGGAAGCAACCATTTTGGAAGTGAAAGTCGTAGAAGGTTTTGGTAC +CACAATTGATGTTATCTTGTCCAACGGTTACTTGAGAGAAGGTGACCGTATTGTACTGTG +TGGTATGAATGGTCCAATTGTAACGAATATCAGAGCATTACTAACACCACAACCATTACG +TGAACTACGTTTGAAATCTGAATATGTCCACCACAAAGAAGTCAAGGCTGCTTTAGGTGT +CAAGATTGCCGCTAATGATTTAGAAAAAGCCGTTTCTGGTTCTAGGCTGCTAGTTGTCGG +TCCTGAAGATGACGAAGATGAATTGATGGACGACGTTATGGATGATTTGACTGGTTTGTT +GGACTCCGTTGACACAACTGGTAAAGGTGTTGTGGTCCAAGCATCCACCTTGGGTTCTTT +GGAAGCTTTGTTGGATTTCTTGAAAGACATGAAAATCCCTGTGATGTCTATCGGGTTAGG +TCCAGTGTACAAGCGTGATGTTATGAAAGCCTCCACTATGTTGGAAAAGGCTCCAGAGTA +TGCCGTGATGTTATGTTTTGATGTTAAAGTGGATAAGGAAGCTGAACAATACGCTGAACA +AGAAGGAATTAAGATCTTTAATGCAGACGTCATCTATCATTTATTTGATTCATTTACAGC +ATACCAAGAAAAGTTATTGGAAGAACGTCGTAAAGATTTCCTAGATTACGCTATTTTCCC +ATGTGTCTTACAAACCTTACAAATTATTAACAAACGTGGTCCAATGATTATTGGTGTAGA +CGTTCTGGAAGGTACTCTACGTGTGGGAACTCCTATTTGCGCTGTGAAAACCGACCCTAC +TACAAAGGAAAGACAAACTTTGATATTAGGTAAAGTCATCTCTTTAGAAATCAACCATCA +ACCTGTCCAAGAAGTAAAGAAGGGCCAAACCGCTGCTGGTGTTGCCGTCCGTCTAGAAGA +TCCCTCCGGTCAACAACCTATCTGGGGTCGTCATGTTGACGAGAATGATACATTATACTC +CTTGGTTTCAAGAAGATCTATTGACACTTTGAAGGATAAAGCTTTTAGGGACCAAGTTGC +TAGATCCGATTGGCTGCTATTGAAGAAGCTGAAGGTCGTTTTCGGCATCGAATGAGCATG +GCATACGCTGACTTGTCAACCCAATCACATTCTACAAAATTTAATGAATTAAATAGGTAA +TTGTATATAAAAATGTGAACCTTTGTGTATTAGTTTCAATTCTATCTTACTTTTCATTGC +CATTTTACTTCTTTCACCTTGCTGTCTTTCAACCTTGGAAATTTTTATAGTACGCGTAAA +CAAAAAAGGTAAATAAGAGGCATTGAATATAAGTTGGCATTTATTAGGAAGTTGAGTAAT +AACACGTTGAAACTGGGTTAAGACGATCAAAACAACCATGTCTGCTCCCACTATGAGATC +CACCTCAATATTGACAGAGCATTTGGGATATCCGCCCATCTCGCTTGTTGATGATATCAT +TAATGCTGTAAATGAAATTATGTACAAGTGCACTGCTGCCATGGAAAAATATCTGCTATC +CAAGAGCAAAATCGGCGAGGAAGATTATGGAGAAGAGATCAAAAGTGGAGTTGCTAAGTT +GGAATCACTTTTGGAAAACTCCGTGGATAAGAATTTTGACAAACTAGAACTATATGTTTT +GAGGAACGTCCTTCGAATCCCTGAAGAGTATTTGGACGCCAATGTTTTTAGATTGGAGAA +CCAAAAGGATCTGGTCATTGTAGATGAGAATGAGTTGAAGAAAAGTGAGGAGAAACTTCG +AGAGAAAGTGAACGACGTGGAGTTAGCGTTCAAAAAGAATGAAATGCTATTGAAAAGAGT +TACAAAAGTGAAAAGACTGTTGTTTACGATAAGAGGATTCAAACAAAAGCTAAACGAGTT +ACTGAAATGCAAAGACGATGTACAATTGCAGAAAATTTTGGAGTCGTTAAAACCTATAGA +TGACACAATGACTCTACTGACTGATTCATTACGTAAACTATATGTTGATAGTGAAAGTAC +CAGTTCAACAGAGGAGGTAGAGGCACTACTGCAGAGATTGAAGACCAACGGGAAGCAAAA +TAATAAGGATTTCAGAACACGATATATCGATATAAGGACGAATAATGTCCTACGAAAATT +GGGGCTACTAGGTGATAAAGAGGACGAAAAACAGTCTGCCAAGCCGGATGCGAGGACGCA +AGCAGGGGATATAGTTAGTATAGATATTGAAGAGCCTCAATTGGATTTACTTGATGATGT +GTTATAATATAAAGTGGGAAAAAGTATGTGCTATGATATGATGTATGTATTCACGAATGT +ATTATGTAGAAAAATGCTAAAAAATTGGATAAAAGAAAACCATGTTTAAAATGCATACCA +CCATGTGTATTATAAGTACTTCGTAAAATTCGAATCCTGTAGCCAGCCAACCTTCTCGAA +AGCTTGGAATAGTCTTGATGCTTTATTAACGTCGATCCTACAGGCTTTTTGGGCGTCGGT +CCTTCTAAACGGCAACCCTTTCTTTAGTCTATAAACTTTTTCCAAAAATAACCTTCTCTT +AGAATCCAGATACAAATCACAAGGTAACCTTAGAGTTTGAGCGAGAACTAGTTCAGCAGG +GTGTAGCTCGTTCCTCAGCGGGTCTGTGGACAGGTCCATTGGAGACCCCTTCCACTCGAT +CTTGAGTGACTTGTTACTGTCTGTAGGAAGCGTAGATAAGGGCGGAGAGTAATCTGGTAA +TTTTTTCCATGAGACGTTTGGTATATATTGAGGAGCATCATGAATCGCCTCAATGGATGC +AATGTTAGTGTGAGGAGTGGATGCAGAGGGTGAGAACTTCTTGGCGCGATGTGGACTGGT +AGTCATCGTTCTTCTTTGTGGTGAGTATACCTTGCGTTTCCGTGGTATCCATTCAGTGTC +GGATTCAAACTTTCCTAGATTGTTATTGTAGAGAGCCTGTTTCCTCATATTATATCTTGC +TTGTCTATTCAAATTCGGAGATGCTAACGGGGAAGGTAATCTAGAAGAAGAGGAAGGCAG +AGGAGGAGGAGTCATATCATCATTGTATTTGGAATATTTATGTCTAGCATTATAGGCCAG +ATTGTTGTACCGGTTGATAATGTTCTTAGAATATGGTTGGGCCAAATTGCTGAAAATTTT +GTATTGAGACAGAAACCCGTAGGTGGCGTAGCGGTACCTTTTTCTTGATAACCCATTGGG +CCATACAGGCTTCACGAACAGCACATTCTCTACAGCGCCTTTAGGCGTAGATCCCACTAG +CACTGAAGAGGCCATGCGGGGTGAGCCATTGTGGCTAATTTTCGACTCCAGCTTGGGCGA +CAAAGGTGGCGATGGTATTATATGTTCATCAACCAAGGAGTCAATGCTGCCAGAAAAGCA +TCCATTGCCATTATTTTGTGAGTTCTGGTTAATTCTTACGTCGTACGAGCGCCCATAGGG +TGAATTATTGCTATAATCACTCATGTTTAAACCGTTTTTATTACTATCGTTATTGTTGTT +ACTTGCTTTCAAATTCTGATTCAGACGTCTGAAAATGGACTGCGAATCATCCTTACCAAT +GTAATTCATATTTAATTGAGACTTTTCAGATTCAGGAGAATATAATCCCATGTTTCCCCT +ATAAATGTTACGATGCGCGAATATCCTGTTTATCGATGCCCAGTGTATGAGCCATAACGG +GGATGTTATGAACCATGTGGCTACTTTTATAAGCGGTTCTCTTAGGAAGAAGGGGGTTCT +TGATAGACCCCTGCACCTCATCTAGCGGAGGTGCACGGATGTACCAACAGTTTTAGTGAA +CATTATTCACTAAAGAAGCATTGGGCATACTCAGAGCCAATGGCAAGCTCGTTTACCAGT +TCAAATATGTCGTTTCATTATCTGTATGACTGTCGTAACTTTGAATCGATCTAATGTGTT +GACCCTGTCTCAGGCTCACCCATGGCGGCGCCTGCACCTGTGGGTGAAGGAAGAAAGACG +ATGTTTGTGAGGGAACTGAATTGGGTTGAAGTTCATATCCTAAACAAACACTTCACCAGC +CATGGATGCATGCCTTGTCTTTTCGCAGTTGGTGGCATGAAAATATATATCACCCACCAA +ACCCTCTTACTCTTTTCTTACCAAGTAACTCCAGTAAGTGCTCGTTTTTTTCTTCTTCCA +TTCAAACCTGCTTAAAAACCTCGACAAACGAGCCCCCAACGTACTACCACAGCAACCACT +CTGGTTTTTCTATCTTGTTGTCTTTAATTGCCTCCTGACTTTGTTTTGTTTTGTTCTTGC +TTAGCGCTCTTGAAAAATATTTTACTTTTCACTATCAGATTAATGTGATAGCAATAGTTA +GTGCAACAAAGAAACAAGTCGATAAATGGTACGTTTAAAAAGTAGATATATCCTTTTTGA +AATTATATTCCCACCTACAGACACCAACGTTGAGGAATCTGTGTCGAAAGCAGACATCTT +GCTTTCGCATCACAGAGCATCGCCTGCGGATGTGTCCATAAAGTCGATACTCCAAGAGAT +ACGACGCTCGCTGTCGTTGAATCTGGGCGACTATGGGTCTGCAAAATGTAACTCTCTCTT +GCAGTTGAAATACTTTTCAAATAAGACGTCTACGGGGATAATCCGATGCCATCGAGAGGA +TTGCGACCTTGTTATCATGGCATTGATGTTGATGTCGAAAATTGGCGACGTCGATGGACT +GATCGTGAACCCCGTCAAGGTAAGTGGGACCATCAAGAAAATAGAGCAGTTTGCTATGAG +AAGGAATTCTAAAATTCTGAACATAATCAAGTGTAGTCAATCATCACACCTCAGCGATAA +TGACTTTATTATCAATGATTTCAAGAAAATTGGAAGGNNNNNNNNNNNNNNNNNNNNGGA +CGATTAGAATATATTAATATATAGATGTACACGTATATGCAGTAGTTTTATTTTTTTATC +TATAATACAACTCAAGCACAAGAATGCTTTGTTTTCCTAGTGCTCATCCTGGGCCTAGGC +GCCATAGTTATCCGATTTATCATCGGATTCAGCTTTAGTAAACTGAATGGGGCCGTGAGA +ACCACTGGCACCTTCACTCTTAACATTGACCGCTTCGTCCAGCTTTTCGTAGTTGGTCTT +GTATATGCTTTCAATATCTTGTTGGACGAACAGTGGGTTGTCATAAACCTGGTCTTCATG +CCTTTTGGCGGAGGCATTTGCCCCTCTTGTGAAAAATCTTGAATCGTACTGCAGATCCGG +TTGTTCTGAACGCTTTGCTGCGCCCAGAATTATCTTTTCGGATACGTCTCTTCCTTGAGA +GTACGCCAGCTCTTTTAGTCTGGCCACTGTGCTCGTTTGCTTTTTGGGCTTAACTATTGC +TCCCGTCTGCGGAGTCCCGTTGTGGTATCTGGCTCGTTGGCTCAATTCTTTCAATTTAGA +TTCTTTAGCAAGCATTTCCTGTTCCATAGCAAGCCGCTTCAATTCCATTTTGGACCTGAT +CTCTTGTCTTGCCTTCTTGTCAGCGTTTTCTAACGCTTCGGAGAGCTTCATAAACCCATC +GTTGATGGTATTATTTTCGTTGTCAAGAGCTTTACCTACACGTCTTTCCAAGGCCACGGT +ATAACCATTTGGATTTTTCCAGTTTGACACAGCTGCAGGTATCTTCCACTCATTTGGATC +AGCTTCTCCCCTATCATTGCTGCCATCCATATGGAGAACAGGCACGACTTCGTCGTTTTC +TGTGGGTGCTACAACCTTTCTCGCCTTCTTCCCAACGAACCTTGGCAACAATGGATCCAT +TTGCTTGGACACTACCTCAATATGGTGGCTGTTGTTCAATAATAGATTCGCGGGTGCCTG +ATGTGTTTCGGTGACGTACCTTGATGATGCCCTGTTATTTGAGTTGGCTAGTTTCGCATT +CACAAGCCGCTGAATGTATGACTTGGTTCTTGCTGTACATTCTTGGATTTCTGCTTTCGT +TGGCAAAGGAACCGATAGTTCGAAATTAGACTGTCTCTTTGGAATAAAATCATCGAGCTT +AACGTTTTTAGCGATTTGGTCAGTCAATATTGCCGGCTCAACGCGATCTGAGCTCAAAGC +CGTCGAAACTCGTCCTTGAGAATGTTTTGGAGGTGGTAGTCTGTTACTAAACATATTTGG +TTGAGGTTGCTGATACGTCCTCTCGGCTCAGAGCTGCCATGTGTCAATAACCCCATAATT +TGAACTTCTTTCATCAACTTTTTAGCTGGGGAAAAATCAAATTCGTGAAGAATTACAATA +ATACGTTAAGGTAAAAGATTAAATATTAAAAAATAGTATGAGTACTTTTGAATCATCAGA +CAAGAACAATGAAGGATATGAATAGTATTAGATATGTATTCNNNNNNNNNNCCAGGGACA +TAAAGAGTTGTTTTTATAAGGTGCGGAGTTATCTCAATTTGCTTCTGATTTTAGAAGCTA +TTCTATGCCCGGTCGACTCTTTGATTTCGATCCCAAACGGCATCATGGTAGTTTCGGAGC +CAGATTCGCCATTTTCCCACTCTAATCCATCTCGAAGACTTTTTCGAAAGGTAAACCCTT +CTTCTTGTCTCAGCGTGTTATATTTGGACTTATGCTGTAGCGGCTTGATCATTGCCGAAG +CAGGTATTGGCGGATAATGTAGCACAGCCGGCTTCTTGTACCAACCCACCTTTGTTGGTT +TAGGATTTTCTGCCTCTGTCATTGGCGGTACACCAGCAAATCTCACCCTTTTGATGGACA +ATTCACTGGAGTTTGACTCCGGATCTAGAGTTAATGTCTCTATAGCCAAAGTATCACTAC +TATTGGCAATCAGGGTACTTGATGATTTTCCTGAGGAGGTGTTGTTTATACTGGATACTT +TTGGTGAAGGCGCTAACGATGAAGATGCAGAAGGATTGGGTGTAGATGCACTTTTGTTCA +TCAAATGCCGCACTGTATCTTGGACGATTTTTTGATTTAACGTCATGGTTGAGGACTGCA +AAGAATTGGACCTTTGATTGTTGAGCTTTGAAGGTGGAGCTATTGACGGATGTCTTGTAG +AATTCAAATATGAGGTTTGTTGTTTGTTTGTATAGGATTGCAAAGATGAGGATCTAGGCC +TTCTGCCGTTGATCAGTTTTCTTTTCTCCGGAGACACCACGCTTTTCTTCGTTTCTGCGT +TTTTATTGTTGAAAGTGGTCCTTACAGGCGATACTGAGGGAGACCTAGAAGAATTTGAGG +CTAAATGCGCCCTTGCCCTTGTTCTTATGCTCTCTAAAGAGGCCTGTCTTGATGGGCTTG +CTGAAGATGTGGGTGAGGGGGATGGAGAAGAAGAGGCTGGCAGCTTTGTTATTGACGGCT +TCTTCTTTAGCTTACTTTTCGCGTTTTTAACCTCTAAATACAGAGCCTTATCTCTTTCTA +GCTTTTCTTTCAAATTCTCCCGCAAGTCATTGGTTTCATCGAAGGTTTTATAATTTTTCT +CAATATATTTCCAGCAATCCATCCAATTGGATAATAATCCCATAATGGACCTCAATTTCG +GTATAATCTTGCAGATATGATTATTAAACAATTCCACAACTAAACCAGGTTGAAGGTGGA +AAATGGGAGTTCTTGAGGAATTGTTATCGGTACGCGCCGTTTGAGTCCAAAATTTTAAAT +TCTCCTGCAGTTCGAATAAAGCTGTGACATCATCACATTCTGGAGAGAGCAAAGCCATCA +GCTCACAAATTATCAAATCGTAATGGTACACGTTTTCGCTGGATAATCTTGTCTTGATGT +CCAAGAAATGTTGTTTATTCGGTAGGAAAATTTGCCTAGAGAAACTGATAATAACACACA +AGACAGAAAAAACCCGCAAGTGGAAAGTGTATATCCTGTGTAGAGTCCATTCCCAATGTG +GTAGATCCTTCTGTAAATTTGACAGTGAAGTAGGTCTTGTTTCCGAAAATTTCTGCAATT +GGTTGTAATATGTCCTTAGAATGGGGAAGATTTTCGAATGAACACAGGAGTTCAGTTTCT +CCATCACTTGCCATTGCAATTTGTAAAAGGAATGGGTGGACTTATCCCTTACTGGATCAT +TAATCAAAACGGCTAAATCTAGAATCAATGTCATTTCAACTGGATTTAACAAGTCTTCAA +TTATTGAAGTGTCAAATGGAAGTGACCGAGCTTTGTACGCATCCCTTTCCAATAAAATCT +GTCTCAACTTGGCATTATAAATTTTTATAGCATTTTGAGCAATGCAAGACAGCGAATTTA +AAATCTTCCATTGTAGAGAATTATTGTATATGCACGATTTATAGTGATCTAGGGGTACCT +CCTCGGGAAACATCCAGCCCTCTACATCAATAAAATTAGTTGATAATCTCTGCTGCACTT +CGCTTAGCTTTATCAGCTGGAATCGACAGAGCAAATGGTACCTCTTAGCCAATACGGGGC +TTACATTAAATATAGGACCCTCACAAAGTGATAAGATGAAATTAACGAGGGGAATAATTT +TGTAGGACTCGTCATTGTCTCTTTTCTTCTTCAAATGCGGTACCAGAACGTTTAGTAGCC +TATTCAGTTCATTCAGCTTGTAAAGAGCGTTCTTATATTGAATGATTTTTATATCATACG +AGTCCAACGGAACAGAACCTTTGATTGCCGGAATAGAAGCGCTGGCAGCAGCTTTGGCTA +GCAACTTTTTTCTCTTTTGCACATCTACCATGTTGTAATATAAAACTAGTCTAAATCCTC +AACCTTCAGCTTCCAATCACTCCTTTTATCATTGTTCATTCGCTAACAAACTTCAAACAT +ATGCCTTTATTATGCGTCTTCCTGCTGTTTCAACCATTGATTGCAGGGTAACAGACATTT +TTAAGGGTCTTTCCCACAGCATCTATAAGAAAGATCGTCAAAAGTATTAGTTAAACATTG +AAAATTTGCGCCAAAGACATAGCAAGCGCAACGTATTCATTGTCCATGTCGTCATCTACT +CCCTTTGACCCTTATGCTCTATCCGAGCACGATGAAGAACGACCCCAGAATGTACAGTCT +AAGTCAAGGACTGCGGAACTACAAGCTGTAAGTACAGAAAGCCACAGAGTACCATCTAGG +AAATTAACATTATACTAACTTTCTACATCGTTGATACTTATGCGTATACATTCATATACG +TTCTTCGTGTTTATTTTTAGGAAATTGATGATACCGTGGGAATAATGAGAGATAACATAA +ATAAAGTAGCAGAAAGAGGTGAAAGATTAACGTCCATTGAAGATAAAGCCGATAACCTAG +CGGTCTCAGCCCAAGGCTTTAAGAGGGGTGCCAATAGGGTCAGAAAAGCCATGTGGTACA +AGGATCTAAAAATGAAGATGTGTCTGGCTTTAGTAATCATCATATTGCTTGTTGTAATCA +TCGTCCCCATTGCTGTTCACTTTAGTCGATAGAAGTTCACTCGCAATGCNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNTTACTTTGTTCTTATTTTCTGTCTAATTTTATAATTTTACTGACAGTAGCTAAGCCC +TCTGTATTGCTGTTCTGTGTTATTGCACTAGTGTCATAACGCAGATGGTTTTTAGCAGAG +TCAAATTGGGCAGAAAGCATAATTTCCATCTTCCCTGGCAAAGACAGATTTTCTCTTTTG +ATCACGTTAGCTAAATAATTCAAGATTTCGTTCGGTACTCCAGCTTCGCCCTTGTTAGCA +GGCTTGTATTTCAACAGAATTGCTTGTATTTGGGCTGGATTCAAGGCATACCAGAAATCG +AATAGTAACTTGAACTCGTTCAAGTTGCTTATCTTCAACTGTAATATCTTGACAGCCTGA +ATTATTTGAATCAAATTGGGACGAACGTCTTCAATTCTTGGTTCAAACCAGCTCACCAAC +CGCTCGATATTTCTATCCACTTCGTACCCATACTTCCAATTTAACGCGGGACATTTGGTT +ATTAGGTCATTAAATAGCATTACGTTCAGATACTTCAGGGTGTCGTTAAAAATTTTTGTA +TGCATTGAGTCAACAACTTGAAATTTACACAAGACAGCATCAAATTCATTTAAGAATGTG +AATAATTTAGCGAACTTCTCATCACCAGAATTTTTAAATAGCTTCTCGTTTAAAACCATA +TCGAAGATCTCGATGTGGGCTGAAGCATGCTTCATGAATTTCACTAACCAAGTGGAATAA +ATCTTGTCGAATACTTTTAAAGTTTCATTCTCCAAATCATTCAAATATATCAGTGTTAAC +TTATCTTTTTCATCACCACCATTCGCTTCATATAATGTTTTTTGATTTGCAGCAAATGCG +GGAAGTCTGGAAAGATTACTTAACCAAAAGATACCACCAAGCATTGTTTCGTCCTTTGGT +AGACTCATAACAATGCTTTCTACAGTCAATAGGACTTTCGAGATGAATTTGCTACTTTGA +ATCAATAACCCATTTCTCACTAAGCTACTTACCACTGTAGTAATGACGTGTATAGGACCC +AGAACATTGTCTCCATTCACCTCAGTAACATTTACTTTTTTCAAGTAACCTTCTGTGACT +TCTAATGTGTAACAATTCAGGTCCATTAGTAATTCTAGAAGATCAGGATTTCCTGATTCT +CTACGAATTACATTGACTAGCTTCGGTTTTACTTGTTGTCCTGCGATTCCCAAACCTTTC +ACTTTATCATTCTTATTAGCAGAATATGTGGTGGTGAAATCTTGTGCTATTACGTTTTCA +ATAAACGCTAGTTCTTGCTTCATTGATTTGACTTCATCACTTAATCTTGAAGGTTTGTTA +CCTTTTATAGCAGCCAAACTTTGCATATGTGACTGTATTAAAGAAGATTGCTTCTTTTTT +CTCTCCTTCAAGGCATTCTTCTTGTTTAAAGTATTCATGATTTCAACTTGTAACGTCTTC +AGCTTGGAAATCTTATCATTATAACCATTTACTATCGTTTCGTACTCTTGCCTTTGCTTA +GATGGAATATTTGACAAATCTCCCTGCAACAACTGTGTTAATCTTGTATATGAGTCATTT +AACATCTCTAGATTCAAAATGAAAGAGTTCTTAAATTCGATAGCTTCCTCCAGTAATCCA +ATCCCGTAACTAGCCCTAATATTCCGTTCTTCAACTTCTTTTTGCAGAACTATATACCTT +CGTCTAGCTAACTGCATTCTCATGGCGCTTTGTACAAGAATGGAGCTCCTTTTCAATGTT +CTGTAATCTGTTTTGTGACCATATGATCTGATGTAGCTTTGGATAATTACTGCCGCCATG +AGCATGAATTTCCTGTTAACACTATCTAAAATCAATTTTCTTTTACAGGTACATTGTAGT +TTTATTATTTGCCCAATGGCAGCTCTATAGTATTCCCGTTTCCATAATGCTCTAATGTTC +GTTTGTAGTAATATGGCAGCTCTTGTCTTGAGCTCATGATCGACCCTTGTACGAACCAAC +AAACTTCTAATTTGGCTTTGGCACTTCTTTATTGATTCCATGGTCTGCAAATACTGAAGC +CTATAGTATCTTGCCCTTATCTTTTTCTGTATTATGATGCATATTTCATTCATTTTATTA +GTCCTTAGCTTTTCCAAAAATGCAAGCATTCCTGCTTTAAAGAAAATTTTGGTATTACCA +ATTTGGTATTTTGCTGAATCAGAGATAGTAGCATCTAGAATAGATTGACAGAAGTTGACG +ATTGCCTCTTTTGGGAGGTCTGGATTATAAAGAATTCCACTCCATAAGCTGTAGTCCGTC +AGGAGGAAATATCTTTGAACGAATTCGTCAAAAGTCCATCTTGATGGAAAGCCTGCACAT +GAAATCCTGATTGTTTCCAGCACACCACAAGCTCTTAATTGCGATAAGACCATCAAATTA +TCGAACTCCCATGGCTTTTTTTCAGAATTTGGTTTTATGCAACGAATATAATGAACATTA +GTAGAATTTATGATGGCCATCAATTCCCCGAGCGATTTTTTGAACATAGATCCCAGGGTT +GGTTTCTTTTGACTTAATCTTGCTGGGATCATTATCTTTTTTTCAGTATTTTGCTCTTCA +GGAGCATCGTCACTCCTAAGTTCTCTGTTGTCTAAAATTTGTTTGAAAATTGGATTTGTC +GTTGCTTTGAAAACATCCAGATGACCTAGGGAAACGCTGTCTCTATTCTTTTCAATAAAC +CCTTCAACTTCATATTCTACATCAACAGCATAATGGCTTACTATAAACTTCGTTTGTCCG +AATCTTGGCTTCGAAAAAACTTCATTTGAGGGCGGTTTATTAAAGGCAGAATATAGTTTT +GAGGCCCATGATTCATCTGAGCCTGATGGTAATCTACTTTCTTCATCTAATAGAGAAAGT +ATTCCAAGTTTATTCTCAATCAAGTCTATGCAAGGTTGGTTGTCGCTGAACTCAATGAAA +GACCACTCAATTTCCTCCTTTACATATTCTTCTTGCTCCAATTTGAAAACGTGCTGGTTG +AACTCTTGTTGTAATTTTTCATTCGCATAGTTTATACAGAATTGTTCGAATGAGTTTTTC +TCAAAATGCTCAAACCCGTAGATATCTAAAATACCAATAAAGGAAAAGACATGATCTTGT +TGATCCAGCTCAGGATCGTATAATGTCTTGTTAATGTTGTCTACTAGCCAATCAAAAAGC +GTGGAATAAATAAATTTCGCCACAGAGTCCCTAGCAATTAGCGCTTGATTGTAATTCAAA +TTAGTGACAATTTTTTCAGACCTTGTGACGATTTGTTTCTTGACAATCCATTTTGCAAAA +TTGAAGGGATCAATACCCAATAATTCACATGCGATTTGCAGGTTTTGCTCTTCCGATGAT +AGTGATGCGTCGTTTCTAGTCATTTTCATCTCGATATTACCTATATGTAGCAAGCCTGCA +AGAATTTTGAAAATTCCAAGCTGAGTCTCGTGGTTTATACCTACTAATGACAGGGCATCA +GTGGTTATCTTGTATTCTCGAGCTTCATCTATACCAGCTATGTTCGGCTGTCCACCTTGG +TTAGTATAATGGTAGTCCTTGGGAGATGACAAATGCAGTTCTTGTTTTACCGGTTCTGGC +AATCCTTCCAAAATTTGGTAAAAAATATGGTAATTTCTTTCTGTCTCTGGCTGATAAACT +AACCTGGATTTTTCCAAGAGATAGGTTCTAATTTTGGACCCCCTGATGGTAGTATTCTCA +TCAAATAAAATTTGCAGATATTTGCCGAAACGAGAGGAATTATCATTTCTGGTAGTTTTG +GCGTTACCAAAGGCTTCCATGATCGGGTTAGTAGCTAAAATTTGGCTCTCGATTTGAGAC +ATTTCCACTTCCCCTTCACGATTGTTGCTTTCTTGGACTGAGGCAAAGTATCTCATAATG +TATTTAGCAGAGACGGTCTTACCAGCACCGGATTCACCACTGACTACAACAGTCTGGTTA +GCCTTTTCATGGACCATGAACCTGTACGCCTCCTCTGCTATGGCAAAAAGGTGCGGCTCC +AGCTCATCTTTACGCTTACTAGAATAATTCTGTATCATCTCGCGAGAGTACAAATGGTCG +ACTTTATCAAAGGGATTAGCGGCAATAAGGACAATACCAGAGTAAGTATATATCTGTCCA +TTCATGTATCNNNNNNNNATGGCATGCAGCACTGCCGGTTCGTTCAGATATGATAGGGTG +GTTAAGTCATCAGTAGACTCTAAAATAGGTGGGTTTCGTAGTACAGGTAGCGTGGGATGA +TCATCATCATTTTCGAAGCTATTTGTTTCAATGGATACAGTTTCTCCATCCTCCAATTTC +AACTCTAAGTGGAACGTTCCTTCAAAGAAGTCATTCTTGGTGACTTCGCCGCCTATCCAG +CCTTGTTCTTTGTGAGGGTACCAACACTTAGTTCCTACTTCAAATGACATGCGGGAGAAC +TGGTTATAGGANNNNNNNNNNNNNNNNNNNNNNNAGAATTAGATTGAATTATAAAAAGAA +GAACAAAAGGGTATCGTATTGAAAATAAATTGTCTCGCCAAACTGGTAACAATGTTTTCA +GCTAGAACAATAAGAAAAGAAGAGAAGGTNNNNNNNNNGGTGATAACTCCGTAGGAATTG +AGGAATTGAGTATGCAGAATCAGAATAAAGGCTGACTTTCAAAAAAAGGTTGTATTACAA +TTGCAGGTTTTCGATAAAAGAGACCCTATTCTCATCTACTACTGCTAAACTTCGAGATNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCATTAGTTCAGAACCCTAAAGAAT +GGTAAACATTCTATGGATAACCCGGAGAGTGAGTTTCTTAAAGACCTAGTTTTATTTTAA +GGGTTTTAACTCAATCTTGATGTTTTCATTGTGTACCCTAAAGAAAGTTTAAGAATAGCC +CTAACTGTTACCTTTTGAAATAAAATAAGGGGAAGGTCAAAAAGCTATTGTTCTATTGTT +ATGAAACATTGTCTCAAAGAGTAAGAATAACACAAATTGATGGCAGTTTTTTACGTAGTC +CAGTAGTTGTCCAGGTACAATGCAAAATGCTCAAATAAAGAGCTCTTCTAAAGGCAGCGG +AATAGATGGTACAGATCGCAATAGCAAAGATGGTGTAGAAAAGAGACCCCTGGAAGATGT +AAAGCAAATGATTGACGCTGGAACACCAGATGTTGGCCACAAATCTACTGTTGAAACTAA +GCCAAACGTTGGATGGCAAGCCTCTCACAGTAATTTGGCTGCATTACACGAAAAAGAGCA +GAAATATGAAATGGAGCACCATCATGCTCGTCATAAACTGCATCGTCAAGTTATTCCGGA +TTACACGTCTGCCTCGACCGCAATGTTCAGCGATTGTATGTTCAACGCAGCACCAGATAA +AGTACGAAGTCTCAGTACGATGAAGTCTTCTGGACTCTCGCCAAAACACCCATTTAACGT +AGTCGCCACCTTTAAAGGACCATTCCCGCAGCATAGTGTAGAATCAAAGCCTCTCGATGG +TGGATACTCTGCCAAAGACCATTTTCCCTCATTTAAGATGTTGCAAGCCCAGCAGCACCC +AGCCCATCGCCATTACAAAGACAACGACAAGTACGGTCTTAAATCACCTTCCCGGTCCTT +CGTGAAGGACAAGAAAAGGTTGGTTCACCGGTTTTTGAAATCCATGGAGCCTTCTTCGTC +TGGGCAATCTAAGGATTCGTCTGCACTGGCGCCGGCTTTCGATCCAATATTGCCCAATGT +TATATCTAAGCCTTCCAAGCGACCCACACATCATTCGCATTCATCAGACGGGAGTTCTAG +CACGCAGACAGATATATCGTTACAGAGCTTGCTTTACCATGATCTTGAAAGCTCACCAAA +GAAACATGTTTCGCCCTCAAGACCGCCCTCTGTAGCTTCCGAATCCTCTCCTGCCGTTGC +TAATCCCATTGGGCTTTCGCCAAAAGACGCCTGCAATGCATCGTTTTCGCANNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNATTCTCACAGTCAGTGGC +TGTTGATCCTCTTGAACCTCCTGGAAATATCACATATAGTAGTTCGAATCTTTCGCTAAA +TTCAGATGAATTAGACTACTATCAGCGTCATATCGGATTGCAGTTACAGCAGACAGAAGC +TTTACTAAAGCACAGTTTGAAAGATGAGGTTCTGAAAGATGAAAATGACCTTGTTAAAAA +CATTGCAAATTTTGACAAGATCGTTAAAGAGCTAAGGGACTTAAGATCCAGGACCATTGG +ATGGAAAGAGCTTGTTGAAGAGGATTATTTAATGAATTTGAAACAGGATTTTGACAAGGA +AAACCCCGAATCATTTGAGGCACGTTTGAGTGATACAATAAATACAAACGTGGCAAAATT +ACAAGATTTAGAGAAAAGAATGGCTTCTTGCAAAGACAGGTTGGCCTCTAGGAAGGAAGT +AATGAGGAAAATGGAAAGTTTATTGTCTTTGGAGAATTCCTTAATGATATCCNNNNNNNN +TGTAACATTCGCATCTAAATACCGCAACGAGGCCCTTGATATTGTCTTTTTAATTATCAT +CATCGTCATATGCTATACCTTCAAGCATCTAGTATCGCATAAATAAAAAATAGTATTTGT +ATATCAAAAAATGATCCTGTGATTTTTTCATATGTAACGTATAAATGTAAAAATGTGCTT +CTTCTGGTATTTTTAATCAAGTGGAAAGATGAGTGGAAAAAAGGGCAATGAAATAGAAAA +GGACAGGCCTGAAAGGGAAGAATACAAGAAGATTGAGTATATTGGACTTCACAGTAACCG +TGAAAAATGGCACCAAGTATAGCAACGGTAAAGATAGCCAGGGACATGGTTTTGCCATTA +CGTATATTTGTCAATAGAAAGCAGATCCTTCAAACCAATGATAAGACTAGCAATAAGTCG +AATGCCACTATATTTGAAGCACCATTATTATCAAATAACTCCATAATCTGCTTAAAATCA +CCAAATACAAGAATATATTTATCGCAACAAGATAAGAAGAATCTTTGTGACGAGATCAAG +GAGGACCTGTTATTGATTGTTTACGAACTAGCGTCCCCGGAAATCATCAGTTCCGTACTC +AGCAAAATAAGAGTTGGTCATTCTACTGATTTCCAAATCAACGTTCTGCCCAAACTTTTT +GCAGGTGCCGATACGGATAATGCGGTAACTTCTCACATCCAGTCTGTGACAAGGCTGGCT +AAATTCAAATACAAGTTGCACTACAAACATAAGTGGGAGCTCGACATATTCATCAACAGC +ATTAAGAAGATCGCCAATTTAAGGCACTATTTGATGTTTCAAACATTAACATTAAACGGT +TTCTCATTAAATGCAGGACCCAAAACGTTATTAGCTAGGAAAATAGAAAAACAGCCCCAG +GTACCTAATTTGTTAATAGAAAATGGGGACGCTGATGCCCTGGATACACCGGTGGAAGAG +GATATAAAACCTGTAATAGAATTTATGTACAAGCCTGTTATTAATTTAGGTGAAATTATT +GATGTACATGTGTTGCATAGGCCTAGAAGACATAAGGTACGTACCCAGTCGAAGCAACCC +CAGGAGGAATGAAAAACCGATAACAAAGTGATGGCTTAATATTATAACTTCTATATAACG +GATATATTTTATGGTAAATGTACATATTTCAGTAATGGTAATAATGACNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNGTCTTCTGCTCTTTGTTTCTGTGCCTCATATATCAA +ATGAAATATCATCTCTCGAAGAACTGAATCTATTTGAATTTTGATTACCATCAGCAAATG +GATTTTCAATGAACGGTTCTGCACTTTCAAAGTCGTTACTTCCCAGTCCATTATTGTCAT +TAAAGGGGTTCGCCGAAGCATCTTGTAATTCACCGTACTTACCTCTCTTTTGAGTAGTAT +CATACATTCTGACAATTTTTTCTTGCCCACCCTCTTCAGCCTGTGAAAAGGCAAATCCTC +TTTGTTTTTTCATTCTTTGCACTTGCCTCACCTTCCTGATGGCATTTTGAAATTGCTGAA +CGTGCGGCCTAGAGTCGCTGATATTGTATTTCTGCATTTCTTGAATAACATGATACGTTT +CTGGTTCATACATTCTTTTATAGTACTTCCATAGAAAATCTCTTACCAGTGCAAAAATTG +GTAAAACGATCAAAGTTAACCAAAATACACCGGATCCATACGTGTGTTTAACCACACCAT +AATACTCTCTTGAGATGTTAGCATGAGGAAATATAGAAGCATAAATTGGGAAGAATATTA +ACCAAAATAAGAGGGAACCAGGAATGGCAATTAAGGTGAATTTCGTCCATTGATTAGTTA +CCAAAGCAGCCTTTCCCAAAACAATAATGACACTTGTAGTGTAGACAGTTACACCCCAAG +ACCAATGATCAGCTAGTTCGCCGTGCATATTTAAGGCAAACCCATATCTGTAAATCAATA +TGGTGCCAATAAATACTATTGCAGAATGGAAAAAGCCATTAATAATCCATCCCCAGAAGA +TGTAAACAGAGAAAAATTGACCCTTCTGTCCTAATTTGTACAATTGTGGGTACCGCTCAA +GTAATCTACTACTAACAAATTGATCAAATACACCAATGACAAAAGGGGGCCAAACAGTGA +AGAATAAGTTGTAGAAACTCATTGTCCATGATTCCATAATGGATTGACCTGAAAAGGCAT +TGGCAAAAACGTACCAAAACTGCGTCATGTATAATGCTGTATTCTTGTAAAAAGAGTACA +AAATTGCGACAGAAATTCTTTGATAAGACCAGGAGCCATGGACAAGTAATAGTTTTTTTA +AAAATTTAAATTGGCCAACAGCTATATCAGCTGAACGAGCCGCTTGCATACCTTCCATAC +CACTAATACCGACACCAACATGAGCTGCCTGTATCATACTAACATCGTTGGCACCATCGC +CAATGGCTAGCAGTAGTGAAGACGACTTTCTTTTTACCATTTTAACAACCAAGGCTTTCT +GTAGTGGAGATACACGGCAACATATAACCGCTTTACAAAGCTTCGCCACAGTTAGCAAAT +AATCTTCTAATTCTGGTTCCAAGGCAAAGCCTAATGACTTCCCATCAATGACGAGCGCTA +AGGTATTCATATCATGTGTTGACAATTGATGCTCGTTTAGAGCGTTAATCTTCTCTAACA +AATTTCTCTCAGTATCATCTCTGGTTTCCTCGTTGATGATCAACAAATTCATGTCTTCAC +TCAATAAACGGCAACTCATACCAATGTTAATAGCAGTTTCCTGTCTGTCACCAGTTAAAA +CCCAAATTTTAATACCCGCTTCTTGTAATGTGTGGATAGTTTCTGGAACACCGTCCTGTA +ACTTATCTTCAATAGCAGTTGCACCAATTAATATTAGATTTTTCTCGATTAGATTTGCGG +CTTCGTCTAGCTTCTCGGCTCTGTTATCTAATGTTGTGGCAGCCTCATTATAAATGCTAT +TCCATTCTTCATATTCTCCTTCAGAGATATCTCTCATCGCCAAACACAACGTCCGCAAAC +CCTCAGATGCATAATCTTCTAAATGTCTCATTGTAGCTTCTACATATTGATTAGCTTCAT +CATCCAATCTTTCCAGAATGACAGTATCAGCACCTTTACAGAATAACTTTATCGAACCAT +CCGGAAATCTAAATATAGCGCTCATTCTCTTCCTGGTGGAATTAAATTCACAAATGTTAA +GTAGTTGATACTCTTTTTCCTCGCCAGTTTCCTCCAATAAAACAGTTACAGAGTTTGGTT +TACGGATGATAAACTTATACCCTAAATCTGCACCACCTTGAACGAGGGCACCTTCATCTG +GAGAGGCTGCTTGATATTTAATAGATCCATCGCTTTGAAATTCTGGAATGACAGTATGAC +AGGTAGCCAGTAATGTTAAGAAGTCATTGATAATAGGTGAATCCTCATCAGAGGGATCAT +TTAACTTTTTCTTCAAATCGTCAAATTTTCTATAACCAACTTCAATCCCATCTTCAACAG +TGGCCGTTTTATCTTCAGGTATTTTATCAATATAGCAATGGCCTGCAATAGAGCAGGATT +TAAATTCCATAATATTTCTTGTTAAAGTTCCTGTCTTGTCACTGAATATATATTCTATTT +GACCAAGTTCTTCAACCAAAGAGGATGTACGAACCACAGTTGGGGTATCAGTTTTTTCGT +AGTACAAATCTAGATCTGAACCTATCATAAAAGCCTGATAATATTTGATTAATTCAACGG +TGACAAATAGAGAAATAGGAACTAGATTCGAAAATAGAATCCAAAATGTTAAAAAGTCTT +TGAAGAATAAGCCAGCCTTGTTGGTACCCTCCAGGTAAAGGTACGATAAATGTTTGGCAT +CTGCAGTAGACATAATAACATTACCAATTGAAGAAATTAAAATTAGCACGATTAAAACTG +TGAACAATGCAATAATCTGTCTGTTGATAATTTTCTCAACCGCGGTTCTTTTAATTGGGG +TTGCAGTAGCATTACGCAATAACTTAGTTTCATGACCAGTGAAGATAACTAAACCAAATA +TCCATGCAGTATTTCTTAAAGTTGCACCTCTTAAAATCATTTGGTCAGGAGATAACGGTA +TTTGACGATCATTTAAAGTCATTGTACCTTCATAAGTATACAAGCTAGAGTTCGGCTGTT +CGGAAACAACTTTTCCGTTCATGTTCTTCAAAGTTTTAACGTCTATAAATTTGGCAGTTT +CTACTCTCGACTGTTTGATTTTCAAATTTGTTTCACCATCCAAGTTGGCAGTTTCAATGT +AGCAAAGACCCTCCGGTTCCGAAGATGACAAAATTATGGTATCAGCAGGAATAGGTTCCT +CTGATTTTACTCTAATTATGTCACCTACACGAATATCAATCCATCGTTTCTCAACAAAGT +CATCATGTGCTTCTGAAAATATTTCTGCTGTCGAATTATTTAATTCTTTATCAGAATTAG +CTCTCTTGATATCTTCGATACATTCCTTCATGGCAGAAACAATCAAAACCACTAATAAAG +TACCAATTGTGGTGTATCTATTAGTTGGCGAGACGTGAGGCACCTGTTGAATGGCAGATG +TACATNNNNNNNNCAGATTAGCGTATTTGGAAAATTCTTGGAACAAAAATTTAGGCAGAA +AGGTCGCAAAATTATACTTGGTGGTAGATATATGGTTGTCACTATAACCGAAGGAGGAAT +TAGCGAGAGAATCGTTGATGTGGATGACTCTTGGTTCACCATTGCCCTCTGCGTCGCCAA +CGTTCTTTCTTAAAATGTACCGGTTGAAAAGAATTTTAATGTTGAACTTATTCCTCGAGT +CTAGATAATTATCGTCTAATTCGTTATTAGTCACCGCATTGTAATGATTCATTTCGAAAC +TTTCGGGCCCTTTCTTCCGTTTGAACGTAAAGGCATTTTTGAGACCATTACCAAACCTAG +CAAATAAACCGGGAGGCTTGACTGCTCGTAGGGATTGTGGTTGATATGCATCTGAGTCGA +ATCTATTGGCATTCCAAGACGTTTGGTCGTCATGGTTATTGCTCATAAATAGATTTTCAT +GGACATCATTTTCAATGTTATCATCATCAGCGTCTAAGTCGATAGTCTCTTCGGGAAGTA +CATGACTTGGTGGTATATAATTCGCGTTCGCATGTGAGTTGGTGACCTTTGAACGGGATC +CAGAATGAGAAGTCGTGTCGTCTAAGAAGTCAATATCGAAAAGCGTGTCGTCCTCCCCAG +GTTTCCTCTTTGGGGGGGTTTCTCTGTCGTCATTCATGGTAAAATCAGGGAATGAAAGAA +CCTACCAGTAAATTATTGCTTGGCGCTAACCTCTATTTGGCGTTACTGGCTTCTTGTTGC +ACTATTCCCCTTAGAATTGCCAACAATTGTTGATTATATGTTTCTTCAACTTAGTGGCAT +TAAACAGATTTGGGTTTTCTGGCAAAAAAAGCCAATCACGTGATCAGGAAGATTTCAGTG +ATTTACGCTTCAAATAACCTTTACCTCAATAATCCCGNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNTTGCAATGTTATTAGCCCAACAGCTACTAAAGGTATTANNNNNNNNNNNNN +NGATAAGAAATTTAAGTGTTACAGAATGGGCCATCTTACAAAAATAATAGTCTTTATGTA +TTTTTATATATGTAAAAGAATTGAAATATTTTATAACTGGTTGTTATTATGGTACAGTGC +GCTGCCCAATCCACGTGGAAAAATCCTGTTCATTCAATAATAGAAACTGAAATCATGTAA +TGTTGCGTAGTATAGTGCGTGAGCTTATTGTGCCACTTCTTGCTCAGCATTTTGAACTTC +GTGTTCCTCCTCGTATTCGATTTCGACTTTAGGACGTTTAGTTTTGGCACTAGTTCCCTT +CTTACGTCTCTTGGCTGAATTCTTATTTTCTTCATCACTATCGNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNGGAAGCTTCTCTGTCAGAGTCAGCTAACCACTT +TTCTAAGTCATCCACGTCAACGTATTCACCTTCGCCATCATCTGCAACGTATTCAACTTC +CCCATCATCACTTTCCTCTTCTTCATCCCAGTCTTCTTCCTCGTCCTGAGAATTCTCCTC +TTCCATTTGACCCATTATCTTCTTCCAGACCTTTTCGTCAACATTTAATGGTTTATCACC +GTAAGCACCACTCTTTAATCTGTCCATCAATTCTTTTTCGATGGCTTTTTCAATCTTGGC +AGCTACCAATGCCTTTCTCTCCCTGTTTTGTTCTCTTCTTTTGACCTTTGGTGCTACACC +AACGTAGTGTCTCTCCTCCTCCCTTAATGCTAAACGTCTCTCTGTTATCATGACCTGCGT +CAATTTTGTAAATCTCTGTTTACACTTATGACGGAAAAACTTGCTCCAATGTAGTAGGTG +TTCGTCGATCTGTTGTAAAGCCTTCGTGTAATTTTTGGATAGTTTGATTCTTTCCCATAA +CTTGGCAGGAGTGTGCGCTCTTTCAGGCGTCTTCATATACAAGTACAGTTTCCCATTGTC +ACACTTCACTGTTGCATACTTGGAGTTGGCAAGTGGGCATGATTGCCTTGTACACAACCC +AGTGACGTTATACTCATTTCTGCAAAAATTTTGACCATTAGGTGCCTTAATTCTATGAGA +GCAGAAACTTTGATTAATCACTTGCCAAACAATTTCGTCGGACATATCCTCGTTGTATTC +TAACCGTTGTAGTTATGTACTGAAGAGAACACTGTCAAAAGAAAGAACTAAGCAATGCAA +TATCTGCCTCTATACCAATCACNNNNNNNNNNNNNNNCAAAAGCTCATCGGAAAATTTTT +CNNNNNNNNNNNNNNNNNNNNNNNNGGTTTATTACCCTACTGCATTTTGATAATCTGAAC +ATAATGAGCTAATGAAAGCAATTCTCATTTAAAAACAAGTATTCTCTCTTATTGAAGTAT +GCATTATCTATCATTATAAATTCTTTTATTCTGTTCGAGTCCATGTTTTTNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTTTATATGCAAAGTTT +TTTACAAGAGGAATTTGGGAACTGGAGGAAAGTGGCACAATACCTCATGTGGATAGTTCA +TTAATCTCTTCTTGTGTTAATGTGCTAATATAAACACACTTACTCAGCAATTCGTGGTTA +ACTTTGAAAGTGTAAAACTTGGACCATTGAACCCTTTGAATGAAATTCTTGACTATTTGA +ACGTTCGTATCGAATTTATTGTAATTCACTACTTTATCTTCTAAGATCCAGTCTTTCTTC +TCTGCGTTTGCTGATAGGTCCGAAAGATATACGACGATGAAAGGGACGCAACCCACCAGT +GGATTCACAGAGTTAAGTAGATTTCTTATTGTAGAATAATTCCTGTCTAGCGAGGGAATC +TTCTTTAGCTCTTCCCAAGTCAGTAAGTCGCCTGGTTCAATCAGACGCCATGCATCAGTG +AATTTTTGAACAACTGAAGAACTTAAGGCTAGAATGATTTCCATCAATGTGTTAAAGTTC +TGAAATGTCCTGCAGTGGTCTGCAACGTGTATAAACCTTTGAATGACATTTCTTTTCATT +TTGCTGCTCTTGGTAAGAAGTATTTCTGATATAATCCAATCCACAGTTAAGTTAAATCTG +GATATAGCTAAATCAATGCCAGATAAGGTCTCGTTCCTTACTAGTAGTTGCAACCAACTT +ATAACTTGTGGGCCTTCATGCTTCATCTTTAAATCTAATAAATCTTTCCAGTCTATTTCT +CCTAAAATTTCCTTCTCTATCAAGGTCATTTGTTGCGCTACAGACAGGGAATCGTACATT +AGTATAAATGGAACGTGACTTTCATTATTAGAAATCATTAATCTCGAATCGTGAATCCTG +TATTGACCGATTAATTCCTGGATTTGCGCCGCTTGCACAGCAACATCAACATTAGCTGAC +ACGTCTATTTTTTCAGGAGAGGAGGAAGTAAAGCCTTCCTTCTCGGATTGATCTGGAGTA +AAGGGGATATTCATTATAGTTTGTCTCCTTCTTTCTATTAATAACGATTTTCTTTTTTCT +GCGGGGCTATTTTGGAATGACGGCAAGTTGTTAAGGTTTAGCATTTCCACTTCATCTGCT +AACTTGCTCGTTTTAATTCCAATAGCGTCACTACTCTTGGTGTTCTCTGGTTTTTCGGGA +ATTTTCTCGTATGTACCTTCCAGTTTCATTAATGCCACGGTTATTGGATCGTCATTAATT +GAATCATCGAGCATATTAGCAATTTCATTTAAATTTTTCTTATTCAAGGAGCCTGTAAAA +GCCGACTCAGAGTTTGCTCTCCGTGTGTTCCGGGCACTAGATGTGTCATTAATGTCGATA +TCGTCCATTGTCAATACACTTCCTGATATGTTACTATTAGTTTCACTCTCGTTCTTCAGA +AATTTACTTTTCAGCTCTTCAACGTTTTTCATTGGAGAAGCAACGTCAATGCTACCGTCA +TCTGGTGNNNNNNNNTACTTGTTGTTTTTCGCATGGGTACTTGGACTTTCTAGGTCATTA +TTGGAATCGCTTAAATCAATTGTTTTTAACTCATGCAATGAAGAAGTATTTGAGATTATA +TCTTGATTACCCCTTTGATATTCTTCTCTCAAATTTATTATCCTTTGGTGTGGCACTGGT +AAATCTCTGGACGTTTCGAAAGTTTCAACTGTGCTACCAGTGGTAATCGAATTCAAATCA +CTTACAACAGATTCTATTGTGGGTGCTATGGATAATCTGATTCTATTGGTTTCACTCACG +CTGGTCCCGTTGGGAAATTCTCTCTGTGGATTTTGAGTTTGTTTTAGAGGACTATTCTGA +GCAGATTCAAAAAGCTTGCTCGTTGAGATACTGATAACGGTGGACGATGTATCAGAGTAC +AACGCGCTTTTTTTATTATATTCCAGGTTGAGAGGTTCTATTTCACTTATTTCCTCTATA +ACTGAGTTTGACTTGTTTTGCTCAGGATCTACTATGGATAACTCTTTGGTTGGTGTTATG +GCAATGCTTTGAACTCTTGAAATGCTGATCCTTCCACTAGCCGGTCTTACAACTGCTTGT +TTGATCTTGTGATTGCAAGATGAATGTTTTTTTCTTGTAGTTATATCATAATTATTGGCT +TCTGATGATGCATCGAGTGAGTTGTCCAGCTTTTTTGTGCTCTCATATTCTGATTCCTGA +TTTTCTTTGTTATCATAATTCTTTTCAAGGCCATCTATAGTACTCTTTTTCTCATCTAAA +GACTTGGTATCTTCAAATGTAAACTCTCTTAGATTTAAAAATCCAGTTTTTGTTTTTAGA +GTTGGACTATCTGTATTATTCACGATGTTTCTGACTTTTCTTGACTTTTTCGTTACAGTA +TCTCTGGGTGGAGAGCTGGATGACAACTCGGAATCGTATGAGTATGTTATTGATTCTGTG +TCTTCCCTACTATCGTTTAAGGGAGACGATTCTTTAAGATCAGGTAGAACATTTTTCAGA +GGCGAAGAAGTCATGCTTTTTTGGGATTGGGAATGATTTTTCCTCCTTGGTGTCATATTT +GTAATCGCTTCTGAGTTGGTTTTATCAGTTTCATGGAATAACAATCTTTGAGGTCCATTC +TCGTCTGTACGTGAAGAACTATTATCTTTATCAAAGAGCCTCATACTTTCTGCTGAGTAG +CTACCGTGCATTTTATTGTAATATGCTGTCGTGAGACTTTTTACTTTCCTTCGTTGCAGT +GCATCATACGAGGGTGATGGCTGCATATTCGATTCATTGTTCTGCAGTTGCTTGTTTAAA +GTATTAGTTAAAGAGATGACTGACTGAGCAATTGAACTTACGGTTTGATACAGATCCAAA +TTGTCCATAGCGCTAAAATTATCATTACTCGGTTTAAAGCTATTTTGTTGTAAAATCTTT +ATATCATGTATGTGTTCCCGACGTTCACAATCAACATTAACTGTAGGACCTCGGTTGTTA +TTCGAATGTGTTTGAACTTTTTCTATCAGCTGGTTTTGTAAATGCAGTAGGGACTCCACT +TCATCTATGGTTCTTGCACTTAGGATGTCAAATTTAGAAGAATCAGAGTTAAGAAACTCT +TCCTCTTCTTCCTTGGAAGATTTTCTATTGAGAGATGATATTGATACAACGTATTTGACA +AACGCATCCATTTCAGGTTTCTGGTTTGCTGGTTTAATAGCACTCATAAATTTTTTATCA +TTACTGCTATCATGGCGATTATGGTTTTTCATCCACTTAGCTAAAAGACCAATAGCGCTG +CGATGTAACACAGACATTGAAGATGTATTAGATCTACTATTACTGTTGCTATTGTTATCT +AGAGATGATGTCGTCGATGTACCTTGAAGCGTTCCGCTTTGTTCATTTAAATCTTCAGGA +ATATATAAGGAATTCAGAATAAATTCAACTTTTTTAGCCGGTGTTGGAGGCATTATTTTA +TCGACTGCATATGATGACGGGTAGTCTACGCCTTTCATTAGTGTGGATACTAGAGTGACT +TTTGACAAGTGGCTGATCTTTTGTTTACTATCTGACATGTCCTCGCTTTCATTATCAACT +GAAGGTTCTTTCGCTATTCGGTGCTTCGAGTAAACATTTGATGTATTATCGGGAAATAAA +AGCATAGAAGGGCTTCTCTGGTTTTTGGAAGAATTTGAAGACTGTAGCTTCTCCGGCAGT +CTAAATACATCAGAAGTTTTATATAATGATAAAACGCTTTGGTTACGAAAATCAGGACTG +GCAAAACTTTGCCTGGCGTAAATGCTCAGTCGGCTTCCTCTTTTGTGTAGGCTTTCTAGT +TGCGTGAAATCCTTTAACGAATAATGCAGCCATGCATCAAAGTCTAATTTATCAGGTTCA +TTTAGTTCAATATTCTCCCAAACCAACTTAGAACAATGCACCCAGNNNNNNNNCAGATTG +ATTATACAGCTGGAAATTATTTTTGGGTACTGTTCAATGTGTTTGTCGTTTAGAAACTCG +ATCAACCGAAGTCTTAATGTTATGTTCGGTAAAAAATCTTGCACAAAATAATTCAGTATG +GAATGCCTCAACAACACAAACGTCCTCACGAGGGCAACTTCACCAATTCGCCTTCTCTTA +GCTTTTGCAGCATTTGTTGTGATCTCCCTAATACACCATCGAAATCTATAGATGAGTAAG +TCGTGTAAGTCTTGAGGCGTTATAAAATTCCTATAAATAAGGAAAAAATCTGCAGATGCG +TTGTAGTCTACACCTTCCAAAGGGGAAGAAAGGTGTACAATTAACGCGGGCAGGTCTGCA +CTATTCACTGGTTTGGATACACAATCGCTTTCATAGCTAATAACATTTGAGGATGGAGTC +GGGTAGTAATCTTTCTGGCTAAATATTTCCATGGTTCAGGGTAGCGAATCTTTGAATGGC +TAGAGGCTATGTAAAGCAAACAAAAAGGTTCGCGTAAATCAACGAGCGAATAACACGAGT +ACGGTTGGGGTGGGCTAAAGGGTTCAAGAAATTATCAGTTTCTGTTTACAGNNNNNNNNN +CATTGTTGATAAAAAGATCAAGAATTTCATTATTCGCGAAAATCAAAATGCAGAAAGGAA +AAAATAGAAGGGTAATAAAACAGCATCGGATCGCAAAGATGAGTAAGGAGAACAGCCTGG +TTAACAATTAAAGAGTGTTTATCGAAATTCATTATATAGTGGTTTATATAGACCACTTCT +TCTGCTGGTTGATATAGAAATTTTATTTAATTCTTGTTTTTTACTTATGTACTTACTACG +ATGATCTTAATTCATGCTTCTTGCTTGTCGGCAATGTCCCAAGTGGAAAACCAGTTTAAG +TAGCGGAAGTTACTACTTGGTCCCTCCATACCAAATGATATTGGGGAGAAGTACCAGAAG +CAACCAATTACAAGTGCCATGAATCCGGCGTATAGGACGAACCGCATGATACGGCCGCAC +TTAGATCTGGACCATTTTTGCAAACCGGCGTCGAAACAGTACGCCAAAATGATCAGTGCA +AAATACAAGGCAGGCAAGTAATGATGAACGTAGGTGACTCTAGACATGATAACGAATGGC +ATGTAGTGTAGGCCCCAAGCTAGTAGTGGGTAGAACCCGCCCATTAAGAAAACGTTCCAG +TTAGATGGATTTCTTAGGTCCACATATTGTCTTTGCCATCTGATCAGTAAGATAACGACC +GTGGCCATGAATGCGAGGACGGCAACACTAGAAGCCCACGTGGAAGCTGGGGTACCCAAT +AGGAAGTATTTTGGATTATCATCACCCCAGCCACATAGTCTCAAACCCACATTCAAAGTT +GGCCATTGCCATGCTGAGGAAGCTAAGTAATCAAATTTGTCTGGATCTGGCACCAAAGCG +TTATTAGTGGCCATCATGGCTAGATTTAAATGAATGAAGTCTTTTAAGAAGTTGGTCTTT +GGGTATTGAAAATCTTCGGGTCTTGGTGGCAACCTTTCATTTTCGTGGGTCTCGATGTTC +CACCAGGTCCTCTTGTCCCTCTTGAATGGGTTTTTCATGCAGACAACCTCTTGTTGTCTG +AAACCCCATTCGGGCAAACTGTTACCGGTTTGAGCCAAGTAACAGCCCATCTCCAAGTTC +TTGATACGGAAAGAGGTGGTCAATGTGTGCAACTTCTCAGGGTCTTCATCTCCTCTTTGG +TCCATGATCTCAATAACCCAATTGTCTTTGTTGTCACCAACAACATTGTCACCGTAACCA +GAAACCTCCCATTGTGTCTTTGACACTGGTGCAGCAACTGGGTGGGTGTGCAAGTTTCTG +CCCGTGCTTTTGTGTACCAATCTATAGGAGGTACCTGGCTTCAAATACTCGATGTCAGTT +TCGTTTTCTGACCATGATGGTAAGCCTCTTTCTCTGTTGAAAAACCATTCGTTGTTAGCA +TCTTTGTAACCATAACAGGTTACTTGTTGTTGGTTGGACCCATCTGGATAAGTTTGTATA +TGTGAGTGCAATAGAGATCCTCCAAGAGCTTGGTTTTTGATGGAAACAACGGAGGAACCT +AGAGCAATGTCACGGGGGCCTTGTCCGACGTCAGAACCCACTAATCTTGCTTGGAAAAGA +GATGGCATGTTAGCATCACCTGTACCAGAATGCGATAATAGGTCAAAATGTATTTTGAAG +CACAATAGGAAAATGCAGAAGGGGACGATAATAAGACCAAATATTCTTGCCAACCAGTGG +TTAATATAGGTTTTCCATGACATGGATTTATCTGCCAAAAAGGTCCATAAGTCAATCACA +GTATAGATACCGACCATAGTGATGATAAATAGACCCACCATTTTGACGGAAATAGTGCAA +CCCAAAGAAATACCAGTGATCAACAGCCATTTCCACCACTTTCTAGAGAACGGCTTGGAC +CTCTGGTTGTGGAACATAACAAAACTAAAGAACGATGCGACAGTGAAGAAAAGTAGCATG +GAGTCCAAAAGAATGAACCTGCCCAAAGTACTATACGAGTTTTCAAACAAAACCAACACG +GTCATCAGCCAAACTGTTGGTAAAGAAAATCCAATAGCTTTGGCAGTGAAGTAGGCCAAT +GGCACACAGAGCGCGGAAAATGACGCGTTGAACAGTCTCATTTTAACATAATCCAAATAG +TCTGGGTAAATTTCCCCAGAAGGGAAGTCCCAAGAACCGTTGTAGCCTGCCAAATAACCA +GACAACCCGACCAGCATTTTTCCTAGGGGAGGATGGACATCGTGGTAAAATTCGTGTCTC +AAGTAATAAGAACCAAATTTACCAAAGTGCGCCTCATCCCAAACAACATGGTTGTTGATG +CCGATTTTGTACATCCTGGTAAACAACGCCAATGCAGTAAAGATCACCGGCATTACAACG +GATTCCAGGCGTAACAGTGAGCTTTGTGCAGCGGGCTTTTCCTTCGAGAAATCTTCCGCG +TCTCTCTCATCAGCGCTCGAAAGTTCCTCACTGACGCTGATGGAAGACGATTCTCTTTGT +CTCAGTGTATTCTCTTGCTTAATGTGGGCGGCATTGTTTTTGCTGTACCCGGTAGACGAA +GACGAGGACATGATTGCTGGACCACGGTTCGAAACAGAATGACAGTAGCGATGTGGACTA +AGCCGGTTCTCCTTGGTAATGTTGTTAGTCTCGAGAAATGACCNNNNNNNNACCCTCAAA +AAGAATGCAACACTATTAATAAACAGTACACGAAACGGNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAGGGCGACGTGTCCAATAATA +TGTATGTTTGTCGCTATGTACGAGATATTATTGCTAAGTGACAGTAAATCGTATCACGAC +TGTAAATGATGGCGTTTCGGTATGTACAGTATCTATCTACCTGATAATAAAGTCAATTAT +GAAGACGAATACGTAGCTTATGATGCTGCCCAGAGCTAGTCCTGTAGAAACGAAAATATT +AGTGAATCCACCGGCCGCTTCCTTCTCGTCGTCGTTGTCCAGTTGCTCTGGCACCTTCAT +GAAACTCATAGAGATGACGTGCCCGTTGGTTACGCCGAAAAGGAACTGCAGTAGCATGTA +ACACAAGTCAACGATTACGGAGCCATTGTGCTCTTCATCGCCGCTTGAAGAGGAGGTGAT +GGCTGTGAACATCAAGAACAGTGGTATTGCGGCCACCCGCAACAATGAGTAGATGAAGGT +TTTGCGTGGCGTAAATTTCTGGTCACGGAACATGGGCCAGTCGGCAATGACTCTTCCGTA +AAGGTCGCCTAGGTTCCACAGCGTGAATATGAGAGGTATGTACTGTGCGTTGCTTAAAGG +AAGCCCTGTCACGTAGGTGGCAGACGCAAATACAGGAAAAACAAGAGTTACGACAAACGT +GGTGAATATGGAAAGAACCAGGTACTTTAGTTTGGCAAATAAGACCTCGAAAGGCACTTT +TAGTTGGAGTTCCTCACCTTCGTCGTTGTCGTCGCGAGTGCCGTTGGTGCGGCGGTGGTC +TTCATCCTCCATTTGGTCAATGCGGCCAACAATACGGATTTCCTCCTCATTGGAGCGCAG +AGACCCTAACAACACATCAGTGATATGTCCGTCTTCCACATTCCAATTCTCGTTCACTTT +CCGACTGATTTTGCTCACGCTGAACATGACCACACAAATGGTGACCACGAGTGTTGTGGT +AAAAAAGTATAGAAGAATCCCGCCCGTAGTAGACACAGAAGAGTTCTCGATGAAAGCTAG +GGCAAAAAGCACTAGGGAGGGCAGGACACCAGCAACGGCTTGCCCCACCATGACACCTTG +ACTGTACTCGGAACCGAAGACGTTGGCTATGGCCATGATACCATTCTGTGTCATGGCTGT +CCCCATGGAACTGATCACTACAAGCATCATTATAAACATGAAATTGAACCATTTAGGTAA +AAGGAAATGCAAAATTGTAAAGAAGCACATGACAGTAAAGACAATAATCTCCCACACAAG +CCCGTTTATGACCCTTCTCGAGTATTTGTACTGTCTTTTGGCCAAGTAGATGTTGAACAG +CATTGACGATATGGTAGAAAAGGACATCATAGAGCTTGTGAAGATCTTTGCCCAAATGGA +GGTGTCTTTGAAAATATCGTGCTTAAAATATTGCGAGGCACTGAGGATACAGTTCCACGG +CCATAAAAGACCTATTCCTATGGCGAAAAATGTAATATATGAAAGATTTTTCAACTTTTT +TCTTAACGGCAATGTATCCAGTGGTTCGGTTGACACAGATTGCTCTCTTTCAGAATAATT +ATCGCCTTCTTCATCTGAGTGCTCGTTGTTCTCTGATTCATGTTCTTCTCCAGAGCGTGA +TATCTCCTCTGAATGCGTATCGGCCAGTGCAGGCTCTGGCACCGCAAGGATTGGCTTCTT +GATGGTATCAGTGTCCGCACTAGTACTCATTTTTGCAATCTGGTATGCTTTCTTGCGTTT +GATGATAAGCTGTCGCCGTAACGTAAATCATTCATCCTTTCCTATGANNNNNNNNNNNNN +NNNNNNNNNNNNNNNCGGGAAATTAATTCTGTTTTTGGCATTAATAACAACAAGAAGAAT +TAAGGATTCGTTATAGAATACAAGATTCTTGGTTTGGTTAAATAATTTTGGCTCTCTTAA +ATATTATAAAAAGATACTTAAGTAAGAAAGAAACAGGACGAAAAAGATACGCAAANNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGTATAACGTGAAGGCTTTATGGG +AAGTGCGGTGAGATTGGGATCGTTTCAATTTTATAATGAGGTAGTGTACAGAGAGGAGGG +AGGGAGTGGGATGAAAGTGTGCGGTTTATACTTTCTTACTGCCTGTGTTTGTCTTCATAA +ATTCAAATCTTGCTAACAATGGTATATGGTCACTGGGGAATTTGTCGTTGGGGAACCCGA +TAAACTTACTCACGTATTCAGGGTCCACTTCACCCAATAGCCCACGCACCCTTAGAGCAT +GTGTAGAAAACCATATATAGTCGATAACATCTGTGAATGACGGTGTGAAATTGGTGAATG +GTAGTTCTCCGATACAATTATAACTTGATTTGAGAGCCAAGTTATGTGAGAAATTTTTCT +CCGACATGTAACCGAAATCTCTACCATTTCCCTCTTGATGTATTTGGACACGGCCTGTAT +TTATCAATTCGTATACGGCGGAGTTGATGTATGAATTGAAGTCACCACAAATGAGCACAG +GAAATTTCTTAATGTCCTGTCTAAAATTGTGCGATGTCTCCTCCTTTAGCAGCGTTTCCA +GATGATCTAACAGGACACCTACTTGGAATGTCTTGACATCATTAAATTTTGGATCCCAGT +GCAAATGCGTGGTGACCGCCCATATGGTGTCGCCACTAGGAATGTGTTGTAGCTTTAAGA +ACAGTGCAACGTTGTCTTTGTTCATTGCACGGTTTAAATAATCTTCAGTTCTTTGGAACT +TCTTGTGTTTCATCCAAGCACCGCTGAAATCCATGGCGTCTTTGGTGATCAACTTGAATT +GGTCCCTTTTGAAAAAAATGCAACACCCGTCCACTTTCTTGGAGTCCTTGGAATGCATGG +TCTTGGCTCTTGCCTTTGCATGGAAGATGCCTGTATAACCGTGCTTGTCCAATAGGGGCA +CCCAATACTCTTCAAAAGTCTTAGACTCCACTTCTTGTAAACACAACAGATCACTGTCGT +ACGAGAGAATCTGCTCCTTTAATTTATTGCGCCTGTAATCCCAACTTAACGCCCACGACG +GTGTGTAACGGTACATTTTTGGGGTGGCATAGTGTTGACATAAGGTGTTGTAGGATAAGA +CGGTGAACGTCCTCTTGGCTAAATCGGTGGCCAGATGCTCAGTGGATTGCTGCAAAGAAT +CGTACTCCCTCTGTGGTTCCCCATCGGTATTGATTTCGATGAACCTACGTTCATGCGGTA +AGGGAATCTCTGGTCTGTTGTCCCTTAGGTAGAAAATCAATCCCGTGACAGATTTTTCTG +TAAGGATCTTTAAAAACTGTTTTTCTAAGGGGTTTCCTTCTACACCAAGAAACTGAAGGT +TACACAGGTTCCCAAACTCCCATGGTAATGTGGTGACCATGTTATCAAAAAAGTAGAAGT +ATTTCAATTGGAAACATGAGCCTAGTTCCGCTGGTAGAGATGTTAACCTATTATGCGACA +GGTCCAAAACGCGTAGGTTGCTTAGGTTCTTGATCTCCGCTGGCAGTTCCGTGAGGCTAT +TGCCATTCAAATATAGTCTCGTTAGAAAATCGTACTTGAAGATGTTGGCGCTGATATTGA +AGATTTGCAAGTTGGACAAATCTAGCGCGTGCCATAATTGGTCGTCGTATTTCGAGTCCT +TGGGCATGACCATTCTGTTTTCAATGTCGTCATCTTCGTCGATGCTGTACTGAGACAGTT +TCTTGTGTTGTAAGAGCGCCTGGTTGGCTTCGTCCTTGCCATTAGCAAACAGCTCTATCT +TGGGAGTCAATGGTGTAGAAACTGCACTGTTAGTTGCCGTGCCTGAGGGAGTGCTATCTC +CCGTAGGTTGTTGTTTCTTTGCTGTCTTGCTGTCGGTGAGAGTGTCGGCCATTTCCATCA +AGGCTTGCTTTGTGCAGTCTACCAGTGATTTGGAGGCTTCTGCAATGTGAGATTGCTGGA +AATCGGTGGGCTGCAAAGCTGGTGGTGCAGCCTGAGGTCCGGGGCCAAATGGGCCCGGGA +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTGTAGCCA +AATACTTCTTCATAGCGTTTTGTCTAGCATAAATGTTGGGTTGCCCCAGAGATTGTGCGG +ACACTGCAGCCAGATGCAATTGAAGCTTCCAGATCGGATTGTTTAGTAAAGAAGGGTCAT +CCAAGTGCGGGTGTAATAAAGGGTTACTGGCGTTCACATTGATGTTCACAGGCGTACCAA +CGGTAGGAACCATCCCTATAGAATTTACTGCGGCTGTGGAGGCATTCATCATCACCCCGC +TTCCACCGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNCATATTGAGCATGTTCGCGTTCCCATTAGCCAATTGGTCGAGCAACTGGCGCGAGT +TGTTGTTGCTGGAAGTGTGTACATCGCTGTTGTTCATGAGTCCCGGTGGAGGTATCCCGG +TGAGCTGGTTCATGTGTAGCTGCTGCTGTAGAGCGTTTGGTGTACCCTTTCCTAGTAGCC +CGGCANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGGGCCCACATTAGGGTAGCCTA +GTAAAGAAGGGTCGTTCATTAGCGGTAGTTTGCAGGGATAACGTCAGTCGGAGTTCCCTT +GCTGGTGTCCCTTATGCTGTGCCCTTGTGCTTGAGAACCTTCTCTAAGGTGGAAACTTTT +TCAAATTTTTTCGTTGTTGGCCCGTTTTTCGCAAGTACGGGCGATAACAAAAGGCCTAAA +CGGCTACTTTACCTTTGAGATCTACCACGATGAGAATTAATGCTGAATGGACATCTATGT +ATATGATAGTGGGTATATAGTTACTTATCAGTGCTAGAGCACGATCCACGTGGTGGCACA +TCCGCCAAACACGCGAGGTTTTCCAGAGTATTGGCCCACGAGCTGCAGTCCAGGCTGGGA +GCCCTTTTGCGGGCCGCAGTTGCCATGCTCTCCCCAGCCCCAGCAGTATACATTGTAACA +GTGAGACTTGCCTTCTTGATTAGCAGTAGTTAGAATACCGTGCTCACTCCCGGTTGCAAC +ACCGACAATAGGGAAGTCTAGGCGCTCTTGCGGGAAGAGTTGGGAATGTGTGCCCCTACC +AAACGACTCTACCGTATTGAGGCGCGCATTCCACAGGTGGATCGAGGTCCACATGCACAG +TACCACTAGATTGTGTCTTTTTTGCTGTTGTTTGAGCTCGAACCCAGTGGGCAGGCGACC +GGATGCGTGCACTATGCGGCCGCCCTCGTCCACTATGACCATGAAGTCCTTGCCCATGGC +CACGTAGTCTACGGCCACAGACCCGGTATCGTACACCAATACGGGCTCTTTCAGTGATCG +GGATTTGGGCTCTTGCAATTGACACTTTGTGTTGCTGCCCCAGCCGTATACTCGGGTGCC +TTGCACCACCACAAAGTTCTGGAAACATCCGTATACTGCGATGCGCTCATCGTTGGAATT +CAATGGCACATGTTGCTGAGTGAACTCGTAGCAACCGCCTCCTCTCTGCCATACACGGCC +ATCAGCATCCACAATAACTGTCGTGTCCCAGCCGCACGCCACATCCACCACGGGTGCCGG +TACTTCCACGGGCCTCCAGTCATGCACCTGCCGCAGTGCTTGCGCACTATCCAGTTCTCC +CCGTCTGTTATCTCCACATCCTACCAGATTCCCGTCATTTGTCAGCATCACGCTGTGGTT +CCCACCGCACGCTATCTTCCTGACTATTGCTCCATCATCTCCTGGCACAGACCTCTGTGG +GGTATCCATATCCTCATCGTGCCCCAGTCCCAGTTGCCTTTGCCCATTAGACCCAAACGC +ATACACACAACTCATCGATACAAGCCTGTTATAGCCTTTAATGATCACATTCCATCACTT +GCGCTTTGGATCTGCCTGCATTATCAAGGCTCAAACGGCTGCGTTACCCCCGTCGCCGCG +AAATTTTTCATAATTTTTCACTTTGTAGGATTAAAAGAGATCATGAGCCCATCTCGCAAT +GCAACACGTAACTTAAATCAGTACTGGCGTGTGCTATAGTGCTCTATATTCGAGTTTGTT +GCTACTGGTGGACACCCGACTATCTACAGTAAGGAACGTAAACAAGAAAAAGAGAGAAAA +TACGCTATAGTTGAAAACATGAGTGGTTCGCATTCAAATGATGAGGATGACGTAGTGCAA +GTGCCCGAGACGTCCTCTCCCACCAAGGTAGCATCGTCGTCTCCCTTAAAGCCTACTTCG +CCAACAGTTCCGGATGCAAGTGTGGCGTCTTTGAGAAGCAGGTTTACTTTCAAGCCTTCA +GATCCCAGCGAAGGAGCTCATACTTCGAAGCCGCTCCCATCTGGGAGTCCTGAGGTAGCA +CTGGTTAACCTTGCGAGAGAGTTCCCCGATTTCTCTCAAACTCTGGTGCAGGCTGTTTTC +AAATCTAACTCTTTTAACTTACAGTCTGCCAGGGAACGTCTTACAAGATTGAGGCAGCAA +AGACAAAATTGGACATGGAACAAGAACGCATCTCCCAAGAAGTCAGAAACCCCGCCACCT +GTCAAGAAGTCATTACCACTGGCAAACACAGGCCGTTTATCATCTATCCATGGCAATATC +AACAACAAATCCTCCAAGATTACCGTGGCCAAACAGAAAACGTCCATTTTTGACCGTTAC +TCAAACGTCATCAACCAGAAACAATACACTTTTGAGCTGCCAACTAACTTGAATATAGAC +TCGGAGGCACTGAGCAAGTTGCCCGTGAACTACAACAAAAAGAGAAGGCTGGTAAGGGCA +GATCAGCATCCAATTGGCAAGTCTTATGAGTCATCCGCTACACAATTAGGTTCTGCAAGA +GAGAAACTACTGGCGAACCGCAAATACGGTCGTCATGCAAACGACAACGATGAAGAGGAG +GAAGAGAGTATGATGACGGACGATGACGATGCAAGTGGCGACGACTACACAGAATCCACG +CCGCAGATAAATCTGGATGAACAAGTTTTACAGTTTATTAATGACTCTGATATTGTCGAT +CTCTCGGACCTCTCAGATACCACGATGCATAAGGCTCAACTCATAGCCTCACATAGGCCA +TATTCTTCTTTAAATGCCTTTGTAAACACAAATTTCAATGATAAGGACACTGAGGAGAAC +GCATCGAACAAGAGAAAAAGACGTGCGGCTGCATCCGCCAATGAGAGTGAGAGGCTGCTC +GATAAAATCACCCAAAGTATAAGAGGTTACAATGCAATTGAGTCTGTGATCAAGAAATGT +TCTTCCTACGGTGATTTGGTCACTTCGCAAATGAAGAAATGGGGTGTGCAAGTGGAAGGC +GATAACTCTGAGTTGGACCTGATGAACCTTGGGGAAGACGATGACGNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCCGCTGGCGCAGACGCCACTAGC +AAGGAAAAAGAAGATACAAAGGCCGTAGTGGAAGGTTTTGATGAAACTAGCGCAGAACCT +ACTNNNNNNNNNNNNNNNNNNNNNNTGGAAAGAGAAACAAAACGAATTAGAAACACAACT +AAGCCAAAAGTGGTCGAAGATGAAGATGACGATGTAGATTTGGAGGCAATCGATGACGAA +TTGCCGCAGTCTGAGCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNATTT +GTCGCTACCAGAAAAAACACACACGTGATCTCCACCACGAGCAGAAATGGCCGTAAACCT +ATTGTCAAGTTCTTCAAGGGCAAACCCAGACTGTTAAGCCCGGAAATTTCACTAAAAGAC +TACCAACAAACGGGTATAAACTGGTTGAATCTGCTATACCAAAACAAGATGTCATGTATC +CTTGCAGACGACATGGGTCTAGGTAAAACATGTCAAGTCATTTCATTTTTCGCATATTTG +AAACAAATAAACGAACCGGGTCCTCACTTGGTTGTTGTGCCATCATCGACGCTAGAAAAT +TGGTTAAGGGAGTTCCAGAAATTCGCACCTGCTTTGAAGATTGAACCCTACTATGGCTCT +TTACAAGAAAGGGAAGAATTGCGTGATATCCTGGAAAGGAACGCTGGGAAATATGATGTT +ATCGTGACCACGTATAACTTGGCTGCAGGTAATAAATACGACGTTTCGTTTTTGAAAAAT +AGAAACTTCAATGTTGTGGTTTATGATGAAGGTCATATGTTGAAAAATTCCACTTCAGAG +AGATTTGCCAAACTGATGAAAATTCGTGCCAATTTCCGCCTTTTATTAACTGGTACGCCA +TTACAAAATAACTTGAAGGAACTAATGTCGCTGTTGGAATTTATCATGCCAAATCTTTTC +ATTTCCAAAAAGGAATCATTTGACGCAATCTTCAAACAACGTGCCAAGACCACAGACGAT +AACAAAAATCACAACCCGCTATTAGCGCAAGAAGCCATTACAAGAGCTAAAACGATGATG +AAGCCATTTATTTTGAGAAGACGTAAGGATCAAGTGTTGAAACATTTGCCACCAAAGCAC +ACGCATATTCAGTATTGTGAATTGAACGCAATACNNNNNNNNNTATATGATAAGGAAATA +CAAATCGTGTTAGAACATAAGAGAATGATTAAAGATGGCGAATTGCCAAAAGATGCAAAA +GAAAAGTCTAAATTACAATCTTCAAGTTCCAAAAATTTAATAATGGCATTGCGAAAGGCC +TCTCTGCATCCACTTTTGTTCAGAAATATCTATAATGATAAAATCATCACTAAAATGAGT +GATGCCATATTGGATGAACCTGCTTATGCTGAAAACGGTAACAAAGAGTATATTAAGGAA +GATATGAGCTATATGACGGATTTTGAGTTGCACAAACTATGCTGCAATTTCCCGAACACG +TTATCCAAATACCAACTTCATAATGACGAGTGGATGCAATCTGGGAAGATAGACGCTTTG +AAAAAATTGCTGAAAACAATCATTGTTGACAAACAGGAAAAGGTGCTGATATTTTCCTTA +TTCACTCAAGTCCTGGATATTCTAGAGATGGTTTTGTCCACCTTAGATTATAAATTTTTA +AGATTAGATGGTTCCACGCAAGTGAATGATAGACAACTACTAATAGATAAGTTTTATGAA +GATAAGGATATTCCCATTTTCATCTTATCAACAAAGGCAGGTGGATTCGGTATTAATTTG +GTGTGCGCAAATAATGTTATTATATTCGATCAAAGTTTTAACCCACATGATGACAGACAA +GCTGCTGATAGGGCACATCGTGTGGGACAAACAAAGGAAGTTAATATAACCACTTTAATT +ACTAAGGATTCCATAGAGGAAAAGATTCATCAACTGGCCAAAAATAAACTAGCTTTAGAT +TCGTATATCAGTGAAGATAAAAAATCTCAAGATGTGTTGGAAAGTAAAGTTAGTGATATG +TTGGAGGATATAATTTATGATGAAAACTCGAAACCGAAGGGAACNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTAACATATTT +ATTTTCTTCTGCGTGAACGCACCATGTGGAAAAAGAGAGTTGATAGAACAAAGGACAAAG +AAATTTAGAACGGTAAAAATATTTTCTANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNGCTAGGTAATTTTAATCTGGGGAGAGAAATGGTGAACTTTTTTC +AATTTATTGATTCGGTTGTTGATTGATATCTTGTGGTGCTGCTTCAATTTCAGCTTGAGT +TTCTACTAAATTTTCAGGGACCATTGGATGATCAAGGTTAAATAAAACGCTACCAATAGT +ATTTGTAGAAATGGCAAAGCCCGCTAAAATGGGCACGGACTCAATCAAACCGGCCAAGAA +ACCAAATGAGGCATATTGGCCAGCGTGGAGATAAATATTTTCACGTCTTTGTATGTTGTC +GAAATTTTGTAAACGTAAAACTTTCGTGAAGTAAATTTGAGTGATGAAAGGAGAAATTAA +AATATGAAAAAGGATTGGTCCAATAAGTGGGAAAAAAGATATAACCAACAGCACAAAAAG +AACCGACAGGCCTAACATGTACTTGACCAACTTGAATGGGAAATAGTAAGCCCAGAAATA +TATCGAGTTAATAGGTGCATAGTACTTGATTGGTTTGACTTCACTCAAATTCTCCTCTAA +ACCATTCTTCTCTAAGCACACCTCCACTAAATGATTATTAAAATGACTGAGTCTCATAAA +CAATAAAGTGAAAACATTTGCTTGCAAAAAGGAATGAAAAATGGCAATGAAAAGCCCAAT +AGGGCCCAGCACAATCAAAAAAGCTGTGTACATTGGCGTAATTGTAGCCCAATACACAAA +GCTTACCAGGGCAAACATTATCAAGTAACTCGATAATATACCTAACATAGTCGTTGAGTA +ACTGCTCTTATTGGTGTTGAACTCTAAAAACCCTTTGAACGGGTACATGAATGCACCTCC +TGTGAATGCATCTTTGAAAAAGTTCATTAGCACGTATCTGGTACGGCTCATAACTTTGCT +GAAGTGCTTCTTGTAAACTTTATCCAAGTACTGATTGAAGGGGATGTTGACATATGGCAG +TTTTTCATACGATTGGCCTCCGCCAAACTTGTACACCAAACCACCAATACCTGCCAGCGC +TAATGAACCTGTAAAACTCATTTCCTGTTGTTGTTATTGTTTGTATAATGTACCTTTGTT +CCCTACACTATAACAACACTTATTCGTGGCAAGAACGAAAATAAAAAATGATTTGAAACT +TCCTTTTCCACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNTCCATGTGTCACAAAACCAGAAAGATCCCGTCGTATTATTGAGTCACGTGCTTTAT +TCCATGGCGGGTAATAAATATTAAAACAAGGGTTTTTTAAGTAAATGATTACATGCTAAG +GAAGTGGTGAATAAGATTTGGCAAGGGGCAGGTCGCTAACCACAACATAGCATTCGTTGA +AAAGGAAATCAACGTTACAAAGTGCAGTTTTTTGTATTATTTTCCTATTATCCTCTTCTT +TTCCTTTGTTTCAGGCGTCGTTGCACCTTTTTGCTATACAAAAGCTCATAAAAGATTAGA +AACCCCGGATATCGTCACAACAGCGGTATATTATAGTTATTTTGCATCTTTTTGGTAAGT +CAGAAATTAGAAACAGTAGCTTACCAATTGAGTGAAAGTTTCCGTTCGTCATCTCCCTCN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNCTCTCCCTAATTTGCATATAGGTAAACATCAAAGAAGTAATGCCCTACATCGGTG +CTTCCAACCTCTCAGAACATTCATTTGTTAATTTGAAGGAAAAACATGCGATTACACATA +AAGGTACGAGCAGTTCTGTAGCATCTTTGCAGACACCACCGAGCCCCGATCAAGAGAACC +ATATTGACAATGAATTAGAAAATTACGATACGTCTTTAAGTGACGTTTCAACCCCGAATA +AAAAGGAAGGTGATGAGTTCGAGCAAAGTTTAAGAGATACATTTGCGAGCTTTCGGAAGA +CTAAACCCCCACCTCCTTTAGATTTTGAACAACCAAGACTTCCTTCGACAGCTTCTTCAT +CCGTTGATTCAACCGTATCATCGCCCTTAACGGATGAAGACATAAAGGAGTTAGAGTTTC +TTCCGAATGAATCAACTCATTCTTATTCGTACAATCCACTTTCGCCAAATTCCCTGGCAG +TCAGATTGAGGATTTTGAAGAGATCATTGGAAATCATAATACAAAACCCAAGTATGCTAC +TGGAGCCTACTCCAGATGATTTGCCTCCTTTGAAAGAGTTTGCGGGCCGTAGGAGCAGTT +TACCAAGGACATCGGCTTCTGCAAACCATTTAATGAACAGAAATAAGAGCCAGATTTGGA +ACACTACTTCCGCTACTTTAAATGCATTTGTAAATAATACCTCTTCCTCCTCAGCAGCAT +CTTCTGCTTTATCTAACAAAAAACCGGGCACCCCAGTTTTCCCTAATTTGGATCCAACAC +ATTCTCAAACATTCCATAGAGCCAACTCGTTGGCTTATTTACCTTCCATCTTACCTGAGC +AAGATCCGCTGCTCAAACATAATAATTCTTTATTTCGTGGCGACTATGGAAACAACATAA +GTCCTGAAAGGCCAAGTTTTAGACAACCCTTCAAGGATCAAACTAGCAATCTCCGCAATA +GCAGTTTACTCAATGAGAGGGCATATCAGGAAGATGAAACTTTTTTACCGCACCATGGAC +CCTCTATGGATCTATTGAATGAACAAAGAGCGAACTTGAAAAGTCTTCTGAATTTATTAA +ACGAAACACTGGAGAAAAATACTTCCGAGAGAGCTTCGGATCTTCATATGATATCGTTGT +TCAATTTGAATAAACTAATGCTTGGAGATCCCAAGAAAAATAATTCAGAACGCGATAAAA +GAACTGAAAAGCTTAAAAAGATTTTGCTGGATAGTCTTGCAGAACCATTCTTTGAGCACT +ATAATTTTATTGGAGATAATCCGATCGCAGATACAGATGAACTAAAGGAGGAAATTGATG +AATTTACAGGTTCTGGAGATACGACAGCGATAACAGATATACGGCCCCAACAGGACTATG +GCCGCATATTGAGGACATTCACTTCTACCAAAAATTCCGCCCCACAGGCAATTTTTACAT +GTAGTCAGGAAGACCCTTGGCAATTCAGAGCTGCGAATGATCTAGCGTGCTTAGTATTCG +GTATCTCACAGAATGCCATTCGCGCTTTAACCTTGATGGATTTAATTCACACCGATAGCA +GAAATTTTGTTTTACACAAATTACTTTCTACGGAGGGTCAAGAAATGGTTTTCACAGGCG +AAATCATTGGTATAGTTCAACCAGAAACACTCAGCTCATCCAAAGTAGTATGGGCATCGT +TTTGGGCAAAAAGGAAAAACGGCTTATTAGTTTGTGTTTTCGAAAAGGTTCCTTGCGATT +ATGTTGATGTACTTTTGAACCTGGATGATTTTGGGGCCGAGAATATTGTAGACAAATGTG +AGTTATTATCAGATGGACCCACATTGTCTTCCTCTTCTACATTATCGCTACCTAAGATGG +CTTCTTCACCAACTGGTAGTAAATTAGAGTATTCGTTGGAGAGGAAAATCCTGGAAAAGA +GTTATACTAAGCCTACTTCAACAGAGAATCGCAACGGCGATGAAAACCAACTTGATGGAG +ATAGTCATTCTGAACCATCGCTGTCATCATCGCCAGTAAGGTCGAAGAAAAGTGTAAAGT +TCGCAAATGATATTAAAGACGTCAAGAGTATAAGCCAATCGTTAGCCAAATTAATGGATG +ATGTGAGGAATGGGGTTGTATTTGATCCCGATGACGACCTTTTGCCTATGCCCATCAAAG +TTTGCAACCACATTAATGAAACAAGATATTTTACTCTAAATCATCTATCTTATAATATCC +CATGCGCGGTTTCCTCCACTGTGTTGGAGGATGAGCTGAAATTAAAGATTCACAGTTTAC +CTTACCAGGCGGGTTTGTTTATTGTGGATTCGCATACTTTAGATATTGTAAGTTCCAATA +AATCTATTTTAAAAAACATGTTTGGTTATCATTTTGCTGAGCTGGTGGGAAAATCCATTA +CTGAAATAATTCCTTCTTTCCCAAAATTCCTCCAATTTATAAATGACAAATATCCTGCGT +TGGATATCACACTCCATAAAAATAAAGGTTTGGTATTAACAGAACATTTTTTTAGGAAAA +TTCAGGCAGAGATTATGGGTGATCGTAAAAGCTTTTATACGTCGGTGGGTATTGATGGCC +TTCATAGGGATGGCTGTGAAATCAAAATTGATTTCCAGCTGCGTGTCATGAATTCTAAAG +TGATTTTGCTTTGGGTTACACATTCGAGAGACGTGGTATTTGAAGAATATAATACAAATC +CATCTCAATTGAAGATGCTGAAGGAGAGTGAATTAAGTTTAATGAGCAGTGCAAGTAGTT +CTGCCAGCTCTTCCAAAAAATCTTCGTCTAGGATATCCACCGGGACATTAAAGGACATGA +GTAATCTGTCAACATATGAGGATTTGGCCCACCGAACGAATAAGCTTAAGTATGAAATCG +GAGATGATTCTAGAGCACATTCTCAATCTACTTTGTCCGAGCAGGAACAAGTTCCCCTGG +AAAACGATAAGGACAGTGGCGAGATGATGCTTGCAGACCCCGAAATGAAGCACAAGTTAG +AATTGGCCAGAATTTACTCAAGAGATAAATCTCAATTTGTGAAAGAAGGAAATTTTAAAG +TTGACGAAAATTTGATTATTAGCAAAATTTCACTTTCCCCAAGCACTGAATCCTTAGCAG +ATTCTAAAAGTTCTGGGAAAGGGCTTTCTCCACTTGAAGAGGAAAAGCTAATTGACGAAA +ACGCTACAGAAAACGGATTAGCGGGATCACCTAAAGACGAAGACGGAATCATAATGACTA +ACAAGCGAGGAAACCAACCTGTTAGTACTTTCCTACGCACCCCCGAAAAGAACATCGGTG +CTCAAAAGCATGTTAAGAAGTTTTCGGACTTCGTAAGTCTGCAAAAAATGGGTGAAGGTG +CATATGGTAAGGTCAACCTATGTATTCATAAGAAGAATAGGTATATTGTGGTGATTAAGA +TGATTTTTAAAGAAAGAATCCTTGTAGATACATGGGTTAGAGATAGGAAATTAGGCACTA +TACCTTCTGAGATCCAAATTATGGCCACGTTGAACAAAAAACCACATGAGAATATTTTAC +GGTTACTGGATTTTTTTGAAGACGACGATTACTATTATATCGAAACTCCCGTACATGGTG +AAACAGGATGTATAGATCTTTTCGATCTAATTGAATTTAAAACCAACATGACCGAATTTG +AAGCAAAATTGATATTCAAGCAGGTTGTAGCGGGAATAAAACATCTACACGACCAGGGTA +TTGTTCACAGAGATATCAAGGATGAGAATGTTATCGTAGATTCTAAAGGCTTTGTTAAGA +TTATTGATTTTGGATCTGCTGCGTATGTCAAAAGCGGACCATTTGATGTTTTTGTTGGGA +CAATAGATTATGCTGCCCCTGAAGTCTTAGGAGGAAACCCTTATGAGGGCCAACCACAGG +ATATTTGGGCTATTGGTATTCTATTGTATACGGTGGTCTTCAAAGAAAACCCCTTCTACA +ATATAGATGAAATATTAGAAGGCGACCTGAAATTCAATAATGCAGAGGAAGTTAGTGAAG +ATTGCATTGAGTTAATCAAGAGTATTTTGAACCGTTGCGTACCGAAGAGACCCACCATTG +ACGACATAAATAACGACAAATGGTTGGTTATTTGAAGGATTAATGATCATTCTAGGACAT +TAGTAATTGGAAAAGAAAATGCAAAAAAATATCCAGTAGAAACAATGCTTGGTATGTCGT +TCTTCTTACTTTCTTCAGTAATGAGTTGGTAGTTTTCTCTATTTAAATATGAATAAATCA +ATATGTACTTTCTTTCTTTAATCAAAATGTTAATATGATAAAAATACAGCATCCAAAGCA +GTTAATCAAGACTTAAATATAAAAAATTTACATATTTAGAAAACAAAGATAGGGTAAATA +TTGAAATTACATAGTAAACCATACCTTAAAAGCAGAAATACTGATACCACATGAACTATT +GATCAATACTACTGCTATTCTCTTCCTAATGCAAAGAGCTTATTACCATTATTAAATCAC +TACAGACGATAATACCCGGAATGCCCTTTTTGCAGGGAAAGCGAAAAAGGTGAAAGAGTT +AACAGGAGAAAGTGTTAGGGAACTAAGTTACGAAGGAAGGCAGATAGCAACAATACTAAC +GTGGAACTTATTTCGACGACTATAACAACTGGTATCTGATTATCGAAGAATAATTGAGTG +GTCAGAAAGGAGCGAAATATGTCTGGAGCAAGATCAACAACGGCAGGTGCCGTGCCCTCG +GCAGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNACTCTAAGGACTCAGACTCTAACGAG +TCATTATATCCCTTGGCTCTGCTTATGGATGAGTTAAAACATGATGATATTGCTAATAGG +GTAGAAGCCATGAAAAAACTAGATACCATCGCGTTGGCACTCGGTCCCGAAAGAACAAGA +AACGAGTTGATTCCCTTTTTAACGGAAGTTGCACAAGATGATGAAGATGAGGTGTTTGCC +GTTTTAGCCGAACAGTTAGGAAAATTTGTCCCCTACATTGGCGGTCCTCAATACGCCACA +ATCCTATTACCAGTTTTGGAAATTTTGGCATCTGCAGAAGAAACTTTGGTTAGAGAAAAG +GCCGTAGATTCTCTGAATAACGTGGCCCAAGAACTTTCTCAAGAACAATTATTTAGTGAC +TTCGTCCCTTTAATTGAACATTTAGCTACTGCAGATTGGTTTTCTTCAAAAGTTTCTGCT +TGTGGTCTTTTCAAGTCTGTTATTGTTAGAATCAAAGATGATTCATTGAGAAAGAATATC +CTGGCTTTATACTTACAACTCGCTCAAGATGATACTCCAATGGTGAAAAGGGCCGTCGGT +AAAAACCTGCCCATCTTGATCGATCTGTTGACTCAAAATTTGGGATTATCTACAGACGAA +GATTGGGATTACATTTCTAACATTTTCCAGAAAATCATTAACGATAATCAAGATTCTGTC +AAGTTTCTGGCAGTTGATTGTTTAATTTCCATCTTGAAATTTTTTAACGCTAAAGGTGAT +GAGTCTCACACTCAAGATTTATTGAACTCTGCTGTCAAATTAATTGGTGACGAAGCGTGG +AGGGTACGTTACATGGCTGCCGATAGATTTTCAGATTTAGCCTCGCAATTCAGTTCCAAC +CAAGCATATATCGATGAATTAGTACAACCATTTTTGAACCTTTGTGAGGACAACGAGGGA +GATGTTAGGGAAGCTGTGGCTAAACAAGTTTCTGGGTTTGCCAAGTTCCTAAATGATCCT +TCAATTATATTGAATAAGATCTTACCTGCTGTGCAGAATTTGAGTATGGACGAAAGTGAA +ACAGTGAGATCTGCTTTGGCTTCTAAGATTACAAATATTGTATTACTGTTGAATAAAGAT +CAAGTCATTAACAATTTTCTTCCGATTTTACTGAATATGCTAAGAGATGAGTTCCCTGAC +GTTCGTTTAAATATCATTGCCAGCTTGAAGGTTGTCAATGACGTAATAGGAATTGAGCTG +CTATCAGACTCTTTGTTACCTGCCATAACAGAATTAGCCAAGGACGTGAATTGGAGAGTT +AGAATGGCTATAATTGAGTACATACCTATCTTGGCAGAACAATTAGGTATGCAATTTTTT +GACCAACAGTTAAGCGATTTATGTCTTTCATGGTTGTGGGATACTGTTTATTCTATCAGA +GAAGCCGCAGTGAATAATTTAAAAAGGTTAACGGAAATATTTGGCTCTGATTGGTGTCGT +GATGAAATTATTTCAAGACTGCTCAAATTTGATCTACAATTACTGGAAAATTTTGTCTCG +AGGTTCACAATACTCTCTGCTCTAACCACTTTGGTGCCCGTGGTATCGTTAGATGTCGTT +ACTGAGCAACTATTACCATTCATTTCTCACTTGGCTGATGACGGTGTTCCAAATATTAGG +TTTAATGTGGCCAAATCCTACGCTGTGATAGTGAAGGTTTTAATTAAGGACGAGGCCAAA +TATGATGCATTAATTAAGAACACAATTTTACCCTCATTGCAAACGCTGTGTCAAGACGAA +GATGTTGATGTAAAATACTTCGCTAAGAAAAGTTTGGCAGAATGTCAAGAACTTTTAAAA +AATTGATACTAGTTCAAATATATACATACATACACATATGTACACTTGAATGAATAAAAA +GTATACATATTAACAACTAGGCCTGCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNACCAC +ACTTAGTCCTCTACTTTAACAGAAATATCATTTTCCAGTTTGACCATAGTTTCTTCAACT +GTTTTCTCCTCGTGTTTAACATTGATTTCCGCCTCCACGTTCAGTTCACGTTTTCCTTCC +AGGTATTTCACCCACTTTGGATAACTCATGATATTTTGCTGGATTTCCTTGTACAATTGA +GACTGCAAATCCCAATCTAAGGAGCTTCTGGGATCATCCGGTGGCAAGAATTGTAACATG +TCACCAAGGTTCCTCGATTTAGTGATTATTTGTCCAAATCCAACCAGCAACCCATTTATT +TCTGTCCAAAGCCCCTTAGGCAGCCAATTTTGTAATTGAGTTCTTGTCTGATCTGGAGTC +TTGCATTTCTGCGCATCTACCCATTTCCAAAGCTTGGTCAATCTATCCACGTGAACGTCA +ACGCAGATACCTTCAATCTTGCCCCATGCCTTTTGTAATGTTAGATAAGCCATTTTGGGC +CCTACACCGGGCAGGCCCAATAGCTCATTAATCGTAGCTGGAACATCACTCGAAAACTGA +TCTTGAAGGATTTTGCAGGTTGACAAAATATACTTGGCCTTCCTTGTGTGGAACCCAACT +GAATGAATCAATTCGTCTAATTTGGTCTCATTGATTTGTAAAACGGCCTCTAATGTCATA +CCTTCTTCGCTGTGCAGTTCGTCTATACAATACCGCATTATGTTAAGCATTGCCATTGCG +GTAACTTCATCTTTTGTTTGCGATGATAGCATCACCCCAAGAAGGACCTGTAATCTGTAG +TCCCTCGGTGATATCTGCTCTTTCGAGATACCACACTTAGAGGCAACCGTTACAGGAATG +GATGATCCACCAATTATATCGACGGGGGCTAGAATCTTAGATCTCAGTACTCGCATTCTA +GCGTATGTTTCTTGAAACTTGTAAGGGACTTTCGTCGAGGCCGGAGTGACAAGGATCGAG +GGGTCCAATGGTGTGGCCCACCTGTTGGGCACATTGCCGTTTCTAACCACAATCCATTCG +AAGTACTGCTTATTTGGCAGCGATTTAACCCAGTCGATATCCACGGGTTGAGGGACAACC +TCTTCTTGTTTGATTTTGGTCCTTTTCTCCGGTAGGAGTTCTGATTCTGGCCCAGTTTCA +GTCTTTACCAGCGGTCTTTTCCTCAGAATTGCCATAGATGAGTATTTACTGATCTTTTGC +ATANNNNNNNNNNNNNNGGGCTATAAAGTATATATAGATACAAATATATGATGAATCATT +AAAGAGGAGGTTATTACTAAGTGAAAGNNNNNNNNNNNNNNNNNGATCAAAACCAAACTT +CGTATTCGAGCCTAAAAAACAGAATATAATGTTATAATACTAATAGAAGCAACAGGAGCA +CCACTATCAGCACAAGAATAATCACGCAGTTGCCGTTATCCTTGAACCTAGAATTGTTAA +AGCCATGCATGGACCGAGAGGCCCTGTTCAAATTCCTACCATTATTATCAATCAGGTTTT +CTAAATCAACCAGCAGCGAGTCGTTCTGAGAAACGATCTCATTATTAAGGTCCAGCGAAA +TGTCATGAGTCCTCCCAATAGACTGAGACAGTGCGCCCAAGTGGGAATCTTGCTCTAACA +ACTGCTGTTGCTGGTTAATAAATAGTTCTTGGTTGGAAACCATGGGTTGTGNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNCGATTGCAATGGTTCATCCTTGTATGGAGTATGCGTCG +AAGGCAGCGGCGACTCCTCGTCTTGTTCATCGTCATCCTTATACATGACCGTAAGCTCGT +CATCATTCTTGAACCGCACTTTTTTCAAAGACTCTTTGGACACCTCATCAGTATTTCTTG +CCACCTGCTGTTGGAACCTATACAACTCCTTGTCAACCGCCGTATCAGGAATTTTGTCCA +GTATGGTATTGTATCGGGATATTAGTTCATCATTGGGCGCACACTTCTGCAATAACTCCA +ATATTGAGCCCAATTGCCGTTTCAAAGTAACGTTATCGTTTGAGGTCGGGGCGAGCTTCA +ACACCGACACTAGCCTTGTTCTTTCTTCGACCAGATCAGAGAGCTGGTCCAGTTCATAAC +CCAGCTTCAACACATCCATACCGTGTGTGCTTACGCATCTATTTGCTGTCGTGAGATCTG +TCTCTATGCTTTATTCGTTTTCCATTGTAAAGTCTCAGCATTTATTTCTTGTTCTTTACT +TGTTTTTGCCCTTTCGGGTGATCAAAGTCGTGCTGGGAAATTTTATTCTTATAAAATGAT +TTTTAGAAATAATAAACTCATAACAGTGCAACGGCAAAGTACAAGGGAAGGAAGCACAGA +AGCAAGAGGAGGCGCATCGATCGTGGCAGATGAGTCAGCAAACACCACAGGAAAGTGAAC +AGACCACAGCGAAAGAACAGGACCTTGATCAAGAGAGCGTGTTGAGCAACATTGACTTCA +ATACGGATTTGAATCACAATTTGAATTTATCGGAATACTGTATATCCAGTGACGCAGGAA +CAGAGAAGATGGATAGCGACGAGGAGAAGTCGTTGGCCAATCTGCCGGAGTTGAAATACG +CTCCCAAGCTATCCAGCCTGGTGAAGCAAGAGACGCTCACCGAGAGCTTGAAAAGACCAC +ACGAAGATGAGAAAGAGGCGATAGATGAGGCCAAGAAGATGAAAGTGCCGGGAGAGAACG +AGGACGAAAGCAAGGAAGAGGAAAAGAGTCAAGAACTGGAAGAGGCAATTGACAGCAAGG +AGAAGAGCACCGACGCCAGGGACGAGCAAGGGGACGAAGGTGATAATGAGGAGGAAAACA +ACGAGGAGGATAATGAAAACGAAAACGAGCATACAGCACCGCCTGCGCTGGTGATGCCCT +CCCCCATCGAAATGGAGGAACAGAGGATGACTGCGCTGAAGGAAATCACCGACATCGAGT +ACAAGTTCGCGCAATTGCGCCAAAAACTATATGACAATCAATTGGTGCGGTTGCAAACGG +AGCTGCAGATGTGTCTGGAAGGGTCACACCCGGAATTGCAGGTCTACTACTCGAAGATTG +CCGCGATCCGTGACTACAAGCTACACCGAGCGTACCAGCGACAGAAGTACGAGCTTTCAT +GCATCAACACAGAAACAATCGCTACCAGGACATTCATTCACCAGGACTTCCACAAGAAGG +TCACCGACCTGCGAGCCAGGCTGCTGAACAGAACCACGCAGACCTGGTACGATATCAACA +AGGAGCGCCGCGATATGGATATAGTCATCCCAGATGTCAATTACCACGTCCCCATCAAAC +TTGATAACAAGACGCTGAGCTGTATCACGGGCTACGCCAGCGCAGCACAGCTGTGCTATC +CCGGCGAGCCCGTGGCAGAGGACCTCGCTTGCGAAAGCATCGAGTACCGCTACAGAGCCA +ACCCGGTGGACAAACTCGAAGTCATTGTGGACCGAATGAGGCTCAATAACGAGATTAGCG +ACCTCGAAGGCCTGCGCAAATATTTCCACTCCTTCCCGGGTGCTCCTGAGTTGAACCCGC +TTAGAGACTCCGAAATCAACGACGACTTCCACCAGTGGGCCCAGTGACCGCCACACTGGA +CCCCATACCACTTCTTTTTGTTATTCTTAAATATGTTGTAACGCTATGTAATTCCACCCT +TCATTACTAATAATTAGCCATTCACGTGATCTCAGCCAGTTGTGGCGCCACACNNNNNNN +NCCATAAAAATCCTCGAGNNNNNNNNNNNNNNNNNNTATTTCAGTTATTTAAAGCATAAG +ATGCCAGGTAGATGGAACTTGTGCCGTGCCAGATTGAATTTTGAAAGTACAATTGAGGCC +TATACACATAGACATTTGCACCTTATACATATACACACAAGACNNNNNNNNNNNNNNTAT +GACTCTACAAGAATCTGATAAATTTGCTACCAAGGCCATTCATGCCGGTGAACATGTGGA +CGTTCACGGTTCCGTGATCGAACCCATTTCTTTGTCCACCACTTTCAAACAATCTTCTCC +AGCTAACCCTATCGGTACTTACGAATACTCCAGATCTCAAAATCCTAACAGAGAGAACTT +GGAAAGAGCAGTTGCCGCTTTAGAGAACGCTCAATACGGGTTGGCTTTCTCCTCTGGTTC +TGCCACCACCGCCACAATCTTGCAATCGCTTCCTCAGGGCTCCCATGCGGTCTCTATCGG +TGATGTGTACGGTGGTACCCACAGATACTTCACCAAAGTCGCCAACGCTCACGGTGTGGA +AACCTCCTTCACTAACGATTTGTTGAACGATCTACCTCAATTGATAAAGGAAAACACCAA +ATTGGTCTGGATCGAAACCCCAACCAACCCAACTTTGAAGGTCACCGACATCCAAAAGGT +GGCAGACCTTATCAAGAAGCACGCTGCCGGCCAAGACGTGATCTTGGTTGTCGACAACAC +CTTCTTGTCCCCATATATCTCCAATCCATTGAACTTCGGTGCAGACATCGTTGTCCACTC +CGCTACAAAGTACATCAACGGTCACTCAGACGTTGTGCTCGGTGTCCTGGCCACTAATAA +CAAGCCATTGTACGAGCGTCTGCAGTTCTTACAAAACGCCATTGGTGCTATCCCATCTCC +TTTCGATGCTTGGTTGACCCACAGAGGTTTGAAGACTTTGCATCTACGTGTCAGACAAGC +TGCCCTCAGCGCCAACAAAATCGCTGAATTCTTGGCAGCAGACAAGGAAAACGTTGTCGC +AGTCAACTACCCAGGTTTGAAGACACACCCTAACTACGACGTAGTGTTAAAGCAACACCG +TGATGCCCTTGGTGGTGGTATGATCTCCTTCAGAATCAAGGGTGGTGCTGAAGCTGCTTC +CAAGTTCGCCTCCTCCACAAGACTGTTCACATTGGCCGAATCCCTTGGTGGTATCGAATC +TCTATTGGAAGTGCCCGCTGTGATGACCCACGGTGGTATCCCAAAGGAGGCCAGAGAGGC +CTCTGGTGTTTTTGACGACTTGGTTAGAATCTCTGTCGGTATTGAAGACACTGACGATCT +TTTGGAAGACATCAAGCAAGCCTTGAAACAAGCCACCAACTAATCGCCAGTGCCACGTCT +CTGCCTTCGACCGGACCTTTTTAAGTACGATAAATATCCTTTTATAAATATATAGTCTAA +AATATCCATTAATACTGTGCTCAATCAATCGTGTTAGATGATTTAGTTTTTTCCAAATCG +TTATTATAGTGCAGAAGTAGTATACATAAAGGCATATGCATGCGATTTGGAAGTAACGCT +CGCCGTAGACAAGTAAGAATGCCTGCTGTCTTGAGAACCAGGTCCAAAGAATCCTCTATA +GAGCAGAAGCCTGCTTCCAGAACTAGAACGAGATCAAGAAGGGGCAAGCGTGGTCGTGAC +GATGATGATGATGACGACGATGAGGAAAGCGATGATGCATACGATGAAGTAGGTAATGAC +TATGACGAGTATGCTTCAAGAGCGAAGCTGGCCACCAATAGGCCCTTCGAAATAGTCGCG +GGACTGCCTGCTAGTGTGGAGCTGCCCAACTATAACTCTTCGCTTACTCATCCGCAATCA +ATTAAAAATTCTGGGGTGCTTTACGACTCTCTGGTCAGTTCCAGAAGAACCTGGGTTCAG +GGTGAGATGTTTGAACTGTATTGGCGAAGACCTAAGAAAATTGTTAGTGAATCTACCCCA +GCAGCGACGGAGAGTCCAACATCTGGAACGATTCCTTTGATTCGAGATAAGATGCAGAAA +ATGTGCGATTGTGTAATGAGTGGAGGTCCTCACACGTTCAAAGTTAGACTTTTCATACTG +AAGAATGACAAAATCGAACAGAAATGGCAAGATGAGCAAGAGTTGAAGAAAAAGGAAAAG +GAACTGAAACGAAAGAACGATGCAGAGGCCAAAAGATTGAGGATGGAGGAAAGGAAAAGG +CAGCAGATGCAAAAGAAAATAGCCAAGGAACAAAAACTTCAATTGCAGAAGGAAAATAAA +GCCAAGCAGAAGTTGGAACAGGAGGCGCTGAAGNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNCAGGGTTCACCTTCTTCCTCCATGCATGACCCAAGA +ATGATAATGAATTTGAATTTGATGGCACAAGAAGATCCAAAACTAAACACTTTAATGGAA +ACCGTCGCAAAGGGTCTTGCCAATAATAGTCAACTGGAGGAATTTAAAAAGTTCATTGAA +ATTGCCAAAAAAAGGTCACTAGAGGAGAACCCAGTTAATAAGCGTCCATCTGTCACAACA +ACGCGACCTGCACCTCCCTCTAAAGCTAAAGACGTAGCCGAAGATCACCGGTTAAACTCG +ATAACCTTGGTGAAAAGTTCCAAAACCGCTGCCACGGAACCTGAACCAAAAAAAGCTGAT +GACGAGAATGCAGAGAAGCAACAGTCCAAAGAGGCAAAGACAACTGCCGAATCGACTCAA +GTAGATGTCAAGAAAGAAGAAGAAGATGTGAAGGAAAAGGGTGTGAAATCAGAGGATACA +CAAAAGAAAGAAGATAATCAAGTGGTACCGAAAAGGAAAAGAAGAAAGAACGCAATAAAG +GAAGATAAAGATATGCAATTGACCGCGTTCCAACAGAAATACGTTCAAGGTGCGGAGATC +ATCCTGGAGTATTTAGAATTCACCCATTCGAGGTATTACCTGCCTAAGAAATCAGTAGTA +GAATTTTTGGAGGATACGGATGAGATTATAATATCTTGGATTGTTATACACAATTCTAAA +GAAATTGAGAAGTTCAAAACCAAGAAAATAAAAGCTAAACTGAAAGCCGACCAAAAACTA +AACAAGGAGGATGCCAAGCCAGGCTCTGATGTGGAGAAGGAAGTCAGCTTTAATCCTCTT +TTTGAAGCCGATTGCCCTACCCCTCTCTACACCCCAATGACAATGAAGTTATCGGGGATT +CACAAAAGATTTAACCAAATCATCCGAAATAGCGTTTCTCCAATGGAAGAAGTTGTTAAA +GAAATGGAAAAAATTCTGCAAATTGGTACTAGATTGTCTGGCTATAATCTGTGGTACCAA +TTGGATGGATACGATGATGAAGCTTTGAGCGAAAGTTTGCGGTTCGAACTAAATGAGTGG +GAGCACGCCATGAGAAGCAGAAGACACAAAAGATAAGGTGTTCGGTTACTTTATTCTGCT +TTAACGCCATTATGATTATACACATTGTATTACTTATTTTTTAACCTGTATATTAAAACC +TTTATTTTATTTCACATTACTCATCATGTGGAGTACTGGAATTGTATGCCAAACTTTGCC +GGGAAAACTGGTATATTGCCGTTTTCTGTATCAGTTGCTGATATAGATATTGCATTATCA +TTCTTTTCATCATCGGATAAACTTTCTTGAAAGCCTCTAGTGAATACCAGCTCTGTCCCG +GCAGATATTAAAAATCCCCTCCATTTGCCTTCCCATAATAGTTTTAAAGTCTTGTCACGT +AATGACGTGCTTAATTTCCAAACACTGGTAAAAATGGAACTATTTATTTTGTTATCAAAT +TTTTCGATGGTAGATCTTTCTTCATCGATTTTTCTTAATGACGACGAGAATGCATAAGTT +AAATCATTTAATAGCTTTTGTTTGTGAACAGGTATATCTAGTGTAGAAGGAATATCGTTA +ACAGCTGAATTCAGATCCGGTACATTTTCGTGCAGTAGTTTAGTCGCTCTGCTGTTTGGA +TTTATATCAACCAATTCGTCGGAGATTGGTTCTAATTTATCATTATTGTTTTTATTGGTT +TCAAGCAAATGATGCTTTTTTTGCCAAAATTCGCACCCAAATGAAAGATTTGATTCAATC +GAATAAAGATTAAAATCATACTTCGCGCAAAAAGTAGAATTTGTCCCTGTCTTGGCCGAA +TATGTGGAGGATATATGGCCGAATAATGGATTCCAAGATAATGTCAAAGTTAGTGGTCGT +CCTGTGTTTGTAGAATGTGTGTAATATCTTAAAGTTGTCGAACAACCGGGGCTTAAACTT +ACTAACCCTAACCAAAATTCAGCACCAAGCGACAACGAAGAATTATTGTACAGTGAGGTG +TTAAACTTGGAAGGCGTGGTAAGGAAATTGTGTAATACTCTATAACCACATAATAGATCA +CTGGTGGAAAATATCCACTCCTGTAAATTGCGGTGAGAATCTCTTTGAAAATAGCACGTT +AAAACGTTTAAGCTTTCTTTGAAACTACTGACACCCTTAAGCATAAATTGGGTTTGTGGA +CTTAGTCGTTTTATTATCATTGCTTCTAAATCAGAGCTGGGGTAGTACATTCTACCATAA +TAAAGGGATTTTTTAACAAATTTCGAGTCATGTAGTAATTTCTTGTCATTGTCGACTGTG +GTGTTGTCACTACTCAACGTATTCGCACTACTAACACTGAAATTGAGGTTTGGTTGCAAT +TGTCTGTATGTTTCGGTGGCATCTTGTAATGGGATATCAGTAGAGTTGCGCATGAATTTC +TCCAATTGCTGTGCATCGGAGTATAAATAACTCAGAGAACCATTTATCCTGGACCTCGTA +GAAAAATCTAAAGAATTGAATGTATTGGGAGTAGATTTGTTGGAAATTTGCAGGTGTATT +GCTGAGGGAATTCGGAAATCTAATAATGTTCTCGATGTGGCCGTTATATCCTCGTAGCTA +TTTTGCGTACTCCAATGGGTGCTCTGATAAAATGCCCTTAGTACTTGGTCCATATAGGGT +AGCATCAAGATCGGTCTTCTCTGTTCGTGTCTTTTTCCTAACGTATATTTGCTTTGTTTC +TTCACTCAACAATAAAGTCAAAGTAAAATTAAATACTAATTATTCTTAAAAGGGAAGATG +CGAAATTTAGCGAAAATCTATTGATTATACACACAAAGGAAGAAAGGTAGTGGAAAGCTA +AATAAAGGAGGTCATGGAGCCAGAGAGCATAGGCGATGTGGGGAACCATGCCCAGGATGA +TAGTGCCAGTATAGTGTCCGGGCCTCGCAGGCGTTCTACTAGCAAGACATCCAGTGCGAA +GAATATACGGAACTCCAGTAATATCTCTCCAGCATCGATGATTTTCAGGAATTTGTTGAT +ACTGGAGGATGATTTAAGACGCCAAGCTCACGAACAAAAGATACTGAAGTGGCAATTCAC +TTTGTTCTTAGCGTCTATGGCCGGTGTAGGCGCATTTACCTTCTACGAACTTTATTTCAC +TTCAGATTATGTCAAGGGCCTCCATAGGGTTATTTTGCAATTCACTCTTTCTTTCATTTC +CATTACTGTAGTTCTTTTTCATATCAGTGGACAATATAGAAGAACTATCGTCATTCCAAG +AAGATTTTTTACCTCTACTAATAAAGGGATTAGGCAGTTTAATGTGAAGCTAGTTAAAGT +ACAGTCTACGTGGGACGAGAAATACACAGATTCAGTAAGATTTGTGAGTCGAACAATTGC +TTATTGTAATATTTATTGTTTGAAAAAATTTCTGTGGCTTAAAGACGATAATGCCATTGT +GAAATTTTGGAAAAGTGTCACGATACAATCCCAACCGAGGATCGGAGCTGTGGATGTGAA +ATTAGTCCTCAACCCCAGAGCATTTAGTGCAGAGATTAGAGAAGGATGGGAGATTTATAG +AGACGAGTTTTGGGCCAGGGAAGGTGCTAGAAGACGCAAACAAGCGCACGAACTCCGACC +TAAATCAGAATGAAAGAGTTGGAGGGCTTCTTCCTTCGAATAAGAGGTCATATTTACCTA +TGTAAAATTGTAACCATCTATGTTCACACATAAATTATATTTTATACATTATTAGAAGTG +AAGCTGTTGTGTCGTGAAAATTTTACAAATCCGTCATTTCATATTTAAGTTTTCCAACAA +GTGCTAGAAAACCTAGGGGTTGTTGAAATTGGTTAAACAAGGCATCTTATTATACATACA +ACAGCATAACGCTAGAGGGGCAAGAAGGAAGAACTTAAAATAATAGGTGTAAAATGACTT +TGGCTTTTAATATGCAACGGTTGGTGTTTCGTAATTTGAATGTTGGGAAGCGCATGTTCA +AGAACGTCCCCTTATGGAGGTTTAATGTCGCCAATAAATTAGGAAAGCCCTTAACTCGCT +CTGTAGGGTTAGGCGGTGCTGGCATAGTTGCTGGTGGCTTTTACTTGATGAATCGCCAGC +CTTCTAAGTTGATATTCAATGATTCTTTAGGGGCAGCTGTCAAACAACAGGGTCCCTTGG +AACCAACTGTGGGCAACAGTACGGCAATTACCGAGGAAAGGAGGAACAAAATAAGTAGTC +ACAAGCAGATGTTTTTGGGATCATTATTCGGTGTTGTTTTAGGAGTTACGGTGGCTAAGA +TATCAATTTTGTTTATGTATGTCGGTATTACAAGCATGCTTCTTTGTGAATGGTTACGGT +ACAAGGGATGGATTCGCATTAATTTGAAAAATATCAAATCTGTAATTGTTTTGAAAGATG +TAGACTTGAAGAAACTGCTTATTGATGGGTTATTGGGTACAGAATACATGGGTTTTAAAG +TATTCTTTACATTGAGTTTCGTATTAGCAAGTTTAAATGCTAACAAATGAGCAAGACAAA +TGACCAGATATAAACGAGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNCCTATACAGTAAATATACATAGGGCTAAGGAAGNNNNNNNNNTCACGTCGAAT +ATAAACCTAATTGTGTTCTATATTGCGGACATATATTTTTCGTAGATTGAAAAGTTCTTA +AACGTAATTTTTTTGACGACCAGTGAAGAGGAATTGAATAAGTAGAACTTGGGCAATACT +TATAACGGCAATGATAATGATAATCAATATAGATAACCAAGTCAACCTTGATTCGGTGGA +ATTGACGGTAGACATGTTTCTCCATTCTCTGGCTCTCAAATAGTTCAAAGTCTTCGTGAT +TTTGTTCAAGTTTCTATCTATTTCCTCCACGGCGTTATTGGCAATAATGTCATCGTTATT +GACATCAGCTTCATGCTCGTCAGTCAAAGTTTTTTCCTTTTCTAGTGTAATTTCTACCTT +TTTCAACGCTGTACCATAGTTATTGGAAAAACAAAAGGTATACTTCCCCACTCCAAACGA +TTTTAATAAAAAGTCTGAGTACTTCTTTTGTTTCTCACTAGTAATCACAGATCCATCAGG +AGCAGTAATATCAAAATCAATCTCAAAATTACCACCGGTTAGAACTTGGTAACCCACAGC +CAGGGAATCATCCTCAGTAACCATATCGTAGTACAGGCATTCTTTGCTGAATGCTGGTAA +ACTGATAGCAACTGGTGCATAACTGGAAGATGCAGCCACTGAATTGACCAACGCCAAAAT +TAAAACAATGAAGAAAGAGGGTAGAGCAATTGTAGATTTGATCATGGTTTTCCTTTACAA +TGAGTGTACTCCACTGTTTATCTTATTCTAGTTTGGGTCACCTGATGCAGAATTGGCGGT +GTCGATCCCTAAGGTTAATGAATCGAAATCACTGGAGATTTTGTTAGTTTTTCATTTTAA +CTAGTTCAAGTTTTGGCAGAATGTACTTTTTCGTGTTTCGGGACACGTCGCTGAAAAGGA +TTGAAATATAACCAAACGCCATCATGTAAGGTGCAGTGAACATTAGCGCTAAGAGGATTG +AGGATTGCTTTATGAAAGTTTATGAACATTTTCTTGAATTAAATAAATAAGTCTGAAAAC +ACTTGAATTCGAGATGCTGTAGCAATTTGTAATATTATTTAAAGTTCACAGAGTGGCTTC +CTTGGCGGATCTGAAAAATAGGTAGTGATTTNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNTGAAATAGAATCTTTAATGATCACAGTGGATC +TTTTAAAAACTTGGTGAGATAGTGCTAGTGATCCGTAGTCTAAATGAGTTACGTACGAAA +GGGAGCCAAAAGCAATCTGACCAATTTGTATATATATACATCTATCCGAAAAGGAAGACA +TCAATTAGTACGGGCGTGTGGTCTAGTGGTATGATTCTCGCTTTGGGCGACTTCCTGATT +AAACAGGAAGACAAAGCATGCGAGAGGCCCTGGGTTCAATTCCCAGCTCGCCCCGAATAA +NNNNNNNNNGCCTATCTATAAAATTAAAGTAGCAGTACTTCAACCATTAGTGTTAGCGAT +AATCAAGAAGTGAAACTCTTTCTCTANNNNNNNNNNAATTGAAAAATTTCCTTTCTCTAT +AGCGTATAGAATATATGTTACATGNNNNNNNNNNNNNNAAGTAAAAACGTTCGGAAAATT +CCTCATTATACCCAGATCATTAAAAGACATTTTCGTTATTATCAATTGCCGCACCAATTG +GCTTAATCAACTTCTTCAACGGTTGGACCTTCAGCCTCTGGAGCTGGANNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNAGCTTGGTACAAC +TTAGACATGATTGGGTTGGCAATGTCTTGCAACTCCTTCAACTTGTCATCGAATTCTTCC +TTGCTGGCAGTGGTGTTGCTGTCTAACCAAGAAATAGTCTCTTCAGCCTTCTTGGTGACG +GTGTCCTTGTCAGCTTGTTCCAATTTGTCACCAGCTTCAGAAATGGTGTTCTTCAAAGAG +TAAGCAATGGATTCCAATTGGTTCTTGGAAGCAATTCTTTGAGATTCCTTTTCATCTTCT +TCCTTGAATTTTTCGGCTTCAGCAACCATCTTTTCGATATCTTCCTTGGACAATCTACCC +TTGTCGTTGGTAATAGTGATCTTGTTAGACTTACCAGTACCCTTTTCGACGGCGGAAACA +TTCAAAATACCGTTAGAGTCGACATCGAAAGTGACTTCAATTTGTGGGACACCTCTTGGA +GCTGGTGGAATACCACTCAATTCGAACTTACCCAACAAGTTGTTGTCCTTAGTCTTGGCT +CTTTCACCTTCAAAGACTTGAATCAAGACACCTGGTTGGTTATCAGCATAAGTGGAAAAG +ATCTCGGACTTCTTTGTTGGAATGGTAGAGTTTCTTGGAATCAACTTGGTCATGACACCA +CCAGCAGTTTCAATACCCAAGGATAATGGAGCGACATCCAACAACAATAGATCTTGAGTC +TTGGAAGATTCGTCACCAGTCAAAATAGCAGCTTGAACAGCAGCACCGTAAGCAACAGCT +TCATCTGGGTTGATAGATCTGTTTGGTTCCTTACCGTTGAAGTAGTCAGTGACCAATTTT +TGGACCTTTGGAATTCTGGTAGAACCACCGACCAAGACAATTTCATCGACTTGAGATTTG +TCCAATTTAGCATCTCTCAAGACCTTTTCAACTGGGTCCAAAGTAGATCTGAACAAGTCA +GCACACAATTCTTCGAATCTGGCTCTGGTGATGGAAGTGTAGAAATCGATACCTTCGAAC +AAAGAGTCAATTTCAACGGAAGTTTGAGCGGAGGAAGACAAAGTTCTCTTGGCTCTTTCA +CAAGCGGTTCTTAATCTTCTCAAAGCTCTTTGGTTGGTAGACAAGTCCTTCTTGTTCTTT +CTCTTGAATTCTTGGATGAAGTGGTTGACCAATCTGTTGTCAAAATCTTCACCACCCAAA +TGGGTGTCACCAGCGGTGGCCTTAACTTCAAAGATACCGTCTTCAATGGACAACAAAGAG +ACATCGAAAGTACCACCACCCAAGTCGAAAATCAAGACGTGTTCTTCCTTACCCTTCTTG +TCCAAACCGTAAGCAATGGCAGCGGCGGTAGGTTCGTTAATAATACGCAAGACATTCAAA +CCAGCAATGGTACCAGCATCCTTGGTAGCTTGTCTTTGAGAATCGTTGAAGTAAGCTGGG +ACAGTGACGACAGCGTCATTGACCTTGGCTCCCAAGTAAGATTCGGCAGTTTCCTTCATC +TTACCCAAGACCATGGAGGAGATTTGTTCTGGGGTAAAGTTCTTGGTTTCACCCTTAAAT +TCAACTTGAATTTGAGGCTTACCGTCAACATCGATCAACTTGAATGGGAAGTGCTTCATG +TCAGCCTGCACTTCTGGGTCGTTGAAGTTTCTACCGATCAAACGCTTAGCGTCGAAAACG +GTATTCGAAGGATTCATAGCAGCTTGATTCTTAGCAGCATCACCAATCAATCTTTCAGTG +TCAGTGAAAGCGACAAAAGATGGAGTGGTTCTGTTACCTTGATCGTTGGCAATAATGTCC +ACACGATCATTAGCAAAGTGAGCAACACACGAGTATGTTGTACCTAAATCAATACCGACA +GCTTTTGACATATTATCTGTTATTTACTTGAATTTTTGTTTCTTGTAATACTTGATTACT +TTTCTTTTGATGTGCTTATCTTACAAATAGAGAAAATAAAACAACTTAAGTAAGAATTGG +GAAACGAAACTACAACTCAATCCCTTCTCGAAGATACATCAATCCACCCCTTATATAACC +TTGAAGTCCTCGAAACGATCAGCTAATCTAAATGGCCCCCCTTCTTTTTGGGTTCTTTCT +CTCCCTTTTGCCGCCGATGGAACGTTCTGGAAAAAGAAGAATAATTTAATTACTTTCTCA +ACTAAAATCTGGAGAAAAAACGCAAATGACAGCTTCTAAACGTTCCGTGTGCTTTCTTTC +TAGAATGTTCTGGAAAGTTTACAACAATCCACAAGAACGAAAATGCCGTTGACAATGATG +AAACCATCATCCACACACCGCGCACACGTGCTTTATTTCTTTTTCTGAANNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTAGGGCTCAGAACCTGCAGGTGAAGAAGC +GCTTTAGAAATCAAAGCACAACGTAACAATTTGTCGACAACCGAGCCTTTGAAGAAAAAA +TTTTTCACATTGTCGCCTCTAAATAAATAGTTTAAGGTTATCTACCCACTATATTTAGTT +GGTTCNNNNNNNNNNCCTTCTACTCTTTATCTTTTTACCTCATGCTTTCTACCTTTCAGC +ACTGAAGAGTCCAACCGAATATATACACACATAATGGCATCCACCGATTTCTCCAAGATT +GAAACTTTGAAACAATTAAACGCTTCTTTGGCTGACAAGTCATACATTGAAGGGTATGTT +CCGATTTAGTTTACTTTATAGATCGTTGNNNNNNNNNNNNNNNNNNNNNNCCTATGGTTA +CATGTAAAGGGAAGTTAACTAATAATGATTACTTTTTTTCGCTTATGTGAATGATGAATT +TAATTCTTTGGTCCGTGTTTATGATGGGAAGTAAGACCCCCGATATGAGTGACAAAAGAG +ATGTGGTTGACTATCACAGTATCTGACGATAGCACAGAGCAGAGTATCATTATTAGTTAT +CTGTTANNNNNNNNNNNNNNNNNGTTCAAAAAAAGAAAGACAGAGTCTAAAGATTGCATT +ACAAGAAAAAAGTTCTCATTACTAACAAGCAAAATGTTTTGTTTCTCCTTTTAAAATAGT +ACTGCTGTTTCTCAAGCTGACGTCACTGTCTTCAAGGCTTTCCAATCTGCTTACCCAGAA +TTCTCCAGATGGTTCAACCACATCGCTTCCAAGGCCGATGAATTCGACTCTTTCCCAGCT +GCCTCTGCTGCCGCTGCCGAAGAAGAAGAAGATGACGATGTCGATTTATTCGGTTCCGAC +GATGAAGAAGCTGACGCTGAAGCTGAAAAGTTGAAGGCTGAAAGAATTGCCGCATACAAC +GCTAAGAAGGCTNNNNNNNNNNNNNNNNNNNNNGCTAAGTCCATTGTCACTCTAGATGTC +AAGCCATGGGATGATGAAACCAATTTGGAAGAAATGGTTGCTAACGTCAAGGCCATCGAA +ATGGAAGGTTTGACCTGGGGTGCTCACCAATTTATCCCAATTGGTTTCGGTATCAAGAAG +TTGCAAATTAACTGTGTTGTCGAAGATGACAAGGTTTCCTTGGATGACTTGCAACAAAGC +ATTGAAGAAGACGAAGACCACGTCCAATCTACCGATATTGCTGCTATGCAAAAATTATAA +AAGGCTTTTTTATAAACTTTTTATAATTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAGAAGG +AATTTTGAACGATAAACTTTTCGACTGCACACGAAACATTATTACTAATTTGTGTAACCA +CTATATAAGGAATCGTGTTTATTAATTGAATTTATTCCGGGAATATTCAAGTTATGTATA +TCTCTTTTCATATTCTTAAATACACATACTCATAATATCTTGTCGAAAATACGCGGTGTA +GGGAGTTATGGTGGATAACTTTTTCACGATTAGAAGAAAAGGAAAATTTCATTATTCGTA +GCTTAACATGGCAAAAACGAGAAAGACATATAATCAAAACGTGAGTTTCCTGTGGNNNNN +NNNNNNNGGGAACCTCTGGTTACGATGATATACCTGCGTGAAAAAGGACAGTTATTACCA +ATACATACAAAGGCTTAATAAGTGTAAAATATATATCTGCCGAGACCATTACTCATTACA +CCTAGAATGGAGCAAAATGGCCTTGACCACGACAGCAGATCTAGCATCGATACGACTATT +AATGACACTCAAAAGACTTTCCTAGAATTTAGATCGTATACCCAATTAAGTGAAAAACTG +GCATCTAGTTCTTCATATACGGCACCTCCCCTGAACGAAGATGGTCCTAAAGGGGTAGCT +TCTGCAGTGTCACAAGGCTCCGAATCCGTAGTCTCATGGACAACTTTAACACACGTATAT +TCCATCCTGGGTGCTTATGGAGGGCCCACGTGCTTGTATCCGACAGCCACGTATTTTTTG +ATGGGCACTTCTAAAGGATGCGTACTCATTTTTAATTATAATGAACATTTGCAGACAATC +CTAGTGCCGACCTTATCTGAGGACCCTTCTATTCACTCAATAAGAAGTCCAGTGAAATCA +ATTGTCATATGTTCCGATGGTACTCATGTAGCTGCCTCATACGAGACCGGAAATATATGC +ATTTGGAACTTGAACGTAGGGTATAGAGTGAAACCCACTTCTGAACCAACAAATGGTATG +ACCCCAACGCCTGCCTTACCGGCAGTCTTACACATCGATGACCATGTGAACAAGGAAATC +ACAGGGTTAGACTTTTTTGGTGCTCGGCATACAGCCCTGATTGTTAGTGATAGGACAGGT +AAAGTATCACTCTATAACGGTTACAGAAGAGGCTTTTGGCAGTTGGTGTATAATTCNNNN +NNNNTTTTAGATGTGAACTCTTCCAAGGAGAAATTAATAAGGTCAAAGTTGTCTCCACTA +ATATCACGGGAGAAAATTTCCACTAATTTGTTGAGTGTACTCACAACTACACATTTTGCC +CTTATTTTATTATCGCCACACGTTTCTTTGATGTTTCAAGAAACTGTTGAACCCTCAGTA +CAAAATTCTCTAGTCGTGAATAGCTCTATTTCATGGACTCAAAACTGTTCCAGGGTTGCT +TATTCCGTAAATAATAAAATTTCTGTTATTTCCATATCTTCATCAGACTTCAATGTTCAG +TCCGCTAGCCATTCTCCTGAATTTGCAGAATCTATATTATCCATTCAATGGATTGACCAG +CTCCTACTTGGTGTTTTAACCATATCGCACCAATTTTTGGTATTGCACCCCCAACATGAC +TTCAAGATCCTGTTAAGATTGGATTTTCTGATTCACGATTTGATGATCCCACCTAATAAA +TATTTTGTAATAAGTAGAAGAAGTTTCTACCTGTTAACAAACTACTCATTTAAAATTGGC +AAATTTGTGTCTTGGTCAGATATTACTTTAAGACATATTTTGAAAGGCGACTACTTGGGT +GCATTGGAGTTCATAGAATCACTTTTGCAACCTTACTGTCCACTGGCAAACTTGTTGAAG +CTAGATAATAATACGGAAGAGAGGACTAAGCAACTTATGGAACCATTTTACAATCTGTCC +TTGGCTGCCCTAAGGTTTCTTATAAAAAAAGATAATGCCGACTACAATAGGGTTTACCAA +TTATTAATGGTAGTTGTTCGTGTTTTGCAGCAATCTTCCAAAAAACTAGACTCAATTCCT +TCTCTAGACGTCTTTTTGGAACAGGGTCTGGAGTTCTTTGAATTGAAGGACAACGCGGTA +TATTTTGAAGTTGTAGCAAATATTGTTGCCCAAGGATCAGTTACGTCAATTTCCCCAGTT +CTTTTCAGGTCCATAATTGATTACTATGCTAAGGAGGAGAATTTAAAAGTAATTGAAGAC +TTAATCATCATGTTAAATCCTACTACGCTTGATGTTGATCTTGCCGTCAAACTATGCCAA +AAGTATAATTTGTTCGATTTATTAATATATATTTGGAACAAGATCTTTGATGATTATCAA +ACCCCAGTGGTGGACTTGATATACAGGATTTCTAACCAAAGTGAAAAATGTGTGATCTTC +AATGGTCCTCAAGTACCTCCTGAAACGACTATATTTGATTACGTAACGTATATCCTTACT +GGCAGGCAATATCCACAAAACTTGTCTATATCACCAAGTGATAAATGCTCCAAAATACAA +AGGGAACTTTCAGCATTTATTTTTAGTGGCTTCTCCATAAAATGGCCGTCGAACAGCAAT +CATAAACTTTACATATGCGAAAATCCAGAAGAAGAGCCAGCATTTCCTTACTTTCACCTT +TTATTGAAATCGAATCCGAGTAGGTTCTTAGCAATGCTCAATGAAGTGTTTGAAGCGTCC +TTGTTTAACGATGACAATGACATGGTTGCATCAGTTGGAGAAGCAGAATTGGTAAGTAGG +CAATATGTTATTGATCTACTATTGGATGCTATGAAAGATACGGGAAATTCAGACAACATC +AGGGTACTTGTTGCAATTTTCATTGCAACTAGTATATCAAAATATCCTCAATTTATTAAA +GTGTCTAACCAAGCCCTCGACTGCGTTGTTAATACCATATGCTCCTCTAGGGTTCAAGGT +ATATATGAAATTTCTCAAATAGCTCTGGAGTCGCTTTTACCCTATTATCATTCAAGAACA +ACAGAAAATTTTATACTGGAACTAAAAGAAAAAAATTTCAATAAAGTTCTTTTCCATATC +TATAAAAGTGAAAATAAGTACGCCAGTGCGCTTTCACTTATTTTAGAAACTAAGGACATC +GAAAAAGAATATAACACGGACATTGTATCCATAACCGACTACATACTCAAAAAATGCCCA +CCTGGAAGTTTAGAATGTGGCAAAGTTACTGAAGTTATCGAGACGAACTTTGATCTTCTT +CTCTCAAGGATCGGTATCGAAAAATGCGTCACAATTTTTTCTGACTTTGACTATAATCTT +CATCAAGAAATCCTGGAAGTAAAGAATGAGGAGACTCAGCAAAAGTATTTGGATAAGCTT +TTTTCTACGCCAAATATCAACAATAAGGTCGATAAGCGTTTAAGAAATTTACACATCGAA +TTGAACTGTAAATACAAGAGCAAAAGGGAAATGATTCTTTGGCTTAATGGTACAGTTCTC +AGCAACGCTGAGAGCTTACAAATTCTGGACTTATTGAATCAAGACTCTAATTTTGAAGCT +GCAGCTATAATTCACGAACGCTTGGAAAGTTTTAACCTAGCAGTCAGGGATTTATTAAGT +TTTATTGAACAATGTCTAAATGAAGGGAAAACAAATATATCTACTTTATTGGAATCTTTG +AGGAGGGCCTTTGATGATTGTAATTCTGCTGGTACCGAGAAAAAATCGTGTTGGATATTA +TTGATTACATTCCTGATCACTCTATATGGGAAATATCCTTCACACGATGAAAGGAAAGAT +TTATGTAATAAACTACTTCAAGAAGCATTTTTGGGATTGGTTAGGTCCAAGAGTTCCTCT +CAGAAGGATTCAGGTGGGGAATTCTGGGAAATAATGTCTTCTGTTCTTGAGCACCAAGAC +GTTATTTTAATGAAAGTTCAGGATTTAAAGCAACTGCTACTGAATGTTTTTAATACTTAT +AAATTGGAAAGATCTCTTTCTGAGTTGATTCAAAAGATTATAGAGGATTCTTCGCAAGAT +CTTGTTCAACAGTATAGAAAATTTCTGAGTGAAGGGTGGTCTATACACACCGACGACTGC +GAAATCTGCGGGAAAAAAATATGGGGAGCTGGTCTGGACCCATTACTTTTTCTAGCTTGG +GAAAATGTACAGCGCCACCAAGATATGATTAGTGTAGATCTCAAAACTCCCCTTGTCATA +TTCAAATGTCACCATGGCTTTCACCAGACTTGCCTCGAAAACTTGGCCCAGAAACCCGAT +GAATATTCTTGTTTAATTTGCCAGACGGAATCTAACCCAAAAATAGTATAACATTTCTAA +ATATTTAATACAACTTTGGTTACATAAAAGTAAAATTTATACACCTCATTTCATTATGTA +GATTCATATATAGAATACCAATTATGATTGACCCAATAGCCATCAAAATCAGTAGTTATT +AATACTTGTCTTTCTAGGAGCCATTTGCATATTTCTGATATTTCATGAAGCGAAAGTACT +TCACGACACCTAGATTGCAATCTACTCAATGTTATCCCTGGATGAAATATTATTTCGTTA +ACGACCATAGTAACTACCTGCTTCCATATGTTTGGCCTAATGGAACCAGATCCATTCACC +CATAAACGAGAAAATGGTTTGCCCAGTGGAACTTTGACAGCAGACTTCCTTGCTGTATTC +AATTTTGTCTGAGAATTGGCATATATAATCAGAGGGGGAGTTAATGTTCGTATTTCAAAT +CTCCTTGAAGTATACGTTAAAGGTCGAACATTTCTCACCATTGGAATTACATCCATATTC +AATAGCTCTCCCGAAATCAAATCAATTAAAACCCAAGAGGATATATCGGACGGCTCTTGA +TTGATAACAATAGCGTTTCCGGCCTCCAATAATTCATTAACCTTACATCTATACTGAAAA +GCTACACCAAAATCTTTATAATTTCCTCTATTTTCCAAAATGTCTGGTAAAGTATCAGTA +CATTCAAGTTTTGAGCCATGGAGATAAATTTGCTTTTCCTTAGCCATATCCATGATGACG +TTATCTATTGATTCGTTTCCAACGTTCTTCAACGCCTCTATTTCATTTCTAGTGGTCGAA +GGACTTTCTATTAATATGGACCGGATCACTGTGCGAATATAATCGTCGCTTTGACTCTTC +GATAAGTCCTTAGTAGAAGCGGAAATCTTTCTAGTGTAAGNNNNNNNNAAAGAAGAGATC +TCTCTTTGAATCATAGAAGACATGGCCAGATCGTTGCCAGAATGTGTAAGTGTGTCATCA +CGTACCAGAGTAAATTTTTTTCTATTCTCTTCGTAGTTCTTATAAAGAAAGAGCGGCCTT +TTTATTTCCTTTTCATCAAAAGAGGTCCAAATATCAAGCAATTTGATAAGATCTAGTTCT +TCAACATCCCTCAGTGAAATCTTTTCACTTTTAATGGCTAGAACGAGCATTTTTTTCCAC +TTATCGACATATGCCCTCCAACCACTATGACCCATTCTTACTCGCCGTGCCGTCCATTTC +TTTTTTAGGTTATCTAAAGAATTATTAGGAAATAATTTTGTTATTTTGTCCCACATTATT +TCATTTTTAATACTTTTAGTAACTACAACAGCTCTGATTAAAGCCTGAACACCATCTTTA +GTGCCTGCATGATAGACAGTTTTGTCTTCTTTAGTATTTTCCACGACCACCGTTGTCCTA +CCAGCAGACACTTTTTTGTCTCTCCTTTTGATCTTTCCATCTGATACGTTGACCGACGTA +CTCTTCTTAGAGATAGCGTCATCTGAAGCTTTGATCTTAGCATTCTTTTGGCGGTTCTGA +AACTTACGAATTCTTTCAACTGATTTCTTTCCTCTGTGAAACCTATTTTTTTCCGTTTGG +TCAAAGAAGTATATTTCCGTATCATGTATAACATCAGTAAAGGTTGCTTTTTTACTATCT +TTTTCTTTCAGGATGTACCTTTGGATAGCGTCCTCTCCAACAGTGGGCAAAAAAATAATT +TTTCTTCCTGATACAGGCTCTGTTCTGGCTCCTAATTTTTCGCTTTCTACCATCAAATCA +ACATCACCACGGACAGTCTTTTTATCTAATGTCGTTGTGGAGCCCATATATTTAGAAACG +CTTTCGTAAAATTGTTCTCTCAGGTATGCTACCCCACCAATCGTATTCATAACTTTCAAA +ATGGCTCTCTGTCTCTGTAGTGAACGCAAAGAGCGGGCAGAAAAGCCGCCGAAGTTAACC +ACCTTGCCTTTGACAACAGTGCCTCCGTTTGAACTTGGACTATCTTCAGCAGATTTCGGC +TCCTGTGCAGTGCTGACATGCTGCTCTAGCTTAATCCTTTTGGGATTCGAAATGTTTCCT +GCAACAGAAGCATTAGTACTGTTTTTAACCTGCCTCTTCNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNAATTCACCGTGCCAGAAGAATATATCCTGTCCATCG +CTGTCCGTTGTAAATCTAACAGTGTTGTTGAGTGCGACGAAATTATCCTCGTTGAGAGTT +TTCAAATCGGTACGAGATTTGCCTAGCTCATCAAACCCTTTTGGAACGGATATTTCGTCT +TCCGCATTTGTTAACTTTTGAAAGTTCTGAGCTGTGAACAGCCTAAAAAACTTCTTCTTT +CCCTCAAAATCGTATATGCGAAAAAGCCTATACCCCCCTGTATTTTCTTTTTGCTTATCC +ACACTTTCTAAATAATATTCGCTTGATTTGGTAAAAGCTCGCTGAAATTCTTTTCCGGTA +ATTCGATTTACAACATCCATAGTTGAAATTCCTTTAAGGCCAGACTTATCTGCAATGTCA +TAAGTCTGATTTTGAAGTGGATAAAATCGATTAAGAAGAACTTCATTCTTTACAGCATCC +TCTTTCTCTTCCATAACAAGGCCTTGATTTTGTAATAAATCAGTCGCATTGAAATTATCT +AAACCTTCGACTAAGTCTTCATCTTCGAAAGCTGCCTTGCTATCTGATACAGAATCTTCA +TCCGCGCTATTGCTATCATACTCAAATGAAGGCGAGCCTTTAGAGTCTGGAATATCTTTC +ACGTATTTTACACATCTGATTTTAATGGCAGGATTCTTGGGTGATACTACAAGCACTTTC +TTTAAGTACTCCTTTTCATCTAACCATGCAATAGCTGCAATAAAAGCTTTAGAAAGTCTT +TTCTCTTTGTCAAATTTCAATTCACGCTTTAAATCAATTATCTGGCGAATACCATTTTTT +GATCGTTTTACCACCTCAACTATTGTTGCTAAATGATCCCTAATATTAATATAGGGATTA +CTATCCACCCCGTCATGGCTGAATTTTTTTAGCTTCAATTGCTTCACGACGTGTCCCTTA +TAAATCAGTTGTGAACTTGTTAACAGGTGGTTTATTTTCTTGATACGTCCAGTCACACTT +CTAGGATCTTGCCCAGTTACCTGCGCCAAATCCATAGTATTGATCCCTTTTTCTCCTGAT +TTGGCAACTTCGAGAAGTAGTTCAAATGCAGAATTTCCAATAGTTGACTCCTTTTTTGTG +TATCCCGTTAATAATGTCCATAGGCTGTCCTCAGTAATCCCAACCGAGTATGAATGATTA +GCGTCGCCTATAATATCAGTCACATTTTTAGTTGTTATAGCACCATCACAATACACCTCA +ATGTCCTTTTTCAATATCACGCATGAAAGCACGAACTGTTTAACTTTTTTATCAGACAAA +TCAAAATATTTACCAGATATATCCCACAGCTGATTCAAAGTGATTTCTTCAATGTGTCGT +TAGTAAATAATCTTTCACAATATAGTACGTTTATCACCTAAACGGAGCCGAAAAGGAGAA +TGAGACATGAACATACTTCCCTTATTTGAAGCAATTTTATCAGACACTATTTGTACGAGT +TCGTCAGGATAAATCGTCAGTACCATTTTTCTTGTGGCTAGTTGGCTTCAACCAAACGTC +CTCTTCTCTCTTATGGCAAGAAGAAAGTTATATGTGTGACTGGTTGTTTATTTCACTTTC +GCGACTGAAAGCGCCGCCCTTTATGATGCAAAAAACCAAGCGGTATTTGAAAATGCAGAT +TTGCANNNNNNNNNNNNNNNNNNNNNNNNNNCTTATAATTTTACCAGCTTCAATAACTCG +ATTTGCATAAGTGTGCCTTAGTATGCTTATTATATTGACTTTGACATTGAACTTCAAAAC +CTTTTATGTAATGATTTAAGTCTTGTCACATGANNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNCCGAAGCAGTCAAAGTATTTTAATTTTCGGAGCTTTCATTTCAAGCGCCNN +NNNNNNACACATAATACGATCAAGATAAATTATTATAGTGGTACAGAACTCTTAAGCACT +AGGCGGTGGACCTTATTAGCTCAATCTTGAGTCAGTCCATGTATCGTTTTATAATACTTT +TTTAAGCACTTTCTTTAATAAATATTCCATTGAAGTACTGTTACTGAAATGAGATGAACT +GTTCAGAATGTAGAAATGGCGCCAGAAATCAATCATTGTTTAGCAAAAACACCTTTCGTC +TGCTGCCTCGGGTGTTTTTTCAAATTATTTCAGCAGGTAAATTAAGATAGTTATTCGAGT +GATTGCCAAATATCATGTTCTACTTCGAAGACTTATAGCTAATTAATTTTTTCATAATGA +AGGTGTCGTTAATTGTTCTGATTAGTAACATGNNNNNNNNNNNNNNNNNNNNNNNNNNNN +GCTAAATGTATACTTTTTTGTCTACATTAGTTACCTTTTATTACATGAGAAAGTTANNNN +NNNNNNNNNNNNNNNNNNNNNNNNGAAACTTTTTCCTCTCGGAAAATAAAAGATATATTT +ACAAGTGAAAGCTTATTGTAATGTGTACTTTTAAACATCAAATAACAGACCTTTACATCA +AATAAGCACCGCAAGATATCCTAAAATCGACATCCAATGCATCGTAAATCATTGAGGAGG +GCTAGCGCTACTGTGCCTTCCGCTCCCTATCGAAAGCAGATTATTAGCAATGCACACAAT +AAACCAAGCCTTTTCTCTAAAATTAAAACTTTCTTTACCCAAAAAGATTCAGCCAGAGTG +AGTCCAAGGAATAATGTTGCTAATAAACAACCACGCAATGAGTCTTTTAACAGAAGAATC +TCAAGTATGCCTGGAGGTTATTTCCATTCTGAGATATCCCCAGATTCTACTGTAAACCGT +TCCGTAGTTGTTTCTGCAGTGGGTGAAGCCAGAAACGACATTGAGAATAAAGAAGAGGAG +TATGATGAAACACATGAAACTAACATCTCCAATGCAAAGCTTGCAAACTTTTTTAGTAAA +AAAGGTAATGAGCCTTTATCAGAAATTGAAATAGAGGGTGTGATGTCATTGTTACAAAAA +TCAAGCAAATCCATGATAACTTCGGAAGGAGAACAAAAATCAGCCGAAGGTAATAATATC +GACCAGTCGCTTATCTTGAAGGAGTCAGGAAGTACACCAATCAGCATATCTAATGCGCCG +ACCTTCAACCCAAAATATGATACTTCAAATGCGTCAATGAATACGACTTTGGGAAGCATT +GGTTCAAGAAAATACAGTTTCAATTATTCTAGCCTGCCCTCACCATACAAAACAACCGTT +TATAGATATAGTGCAGCGAAAAAGATCCCCGATACATACACAGCCAACACATCTGCTCAA +AGTATAGCATCTGCTAAATCGGTAAGAAGTGGTGTTTCAAAGTCAGCTCCTAGTAAGAAA +ATAAGTAATACAGCTGCGGCATTGGTCTCACTATTAGATGAAAATGACAGTAAGAAGAAT +AATGCAGCTTCAGAACTTGCTAATCCATACTCCTCATATGTAAGCCAAATACGCAAACAT +AAGAGAGTTTCTCCAAATGCTGCACCAAGGCAAGAGATCAGTGAAGAAGAAACTACTGTT +AAGCCATTATTTCAAAACGTTCCTGAACAAGGCGAAGAACCAATGAAACAACTGAACGCC +ACCAAAATTTCACCATCTGCGCCAAGCAAAGATTCTTTTACTAAATACAAACCTGCAAGG +TCCTCATCCTTACGCTCAAATGTCGTCGTAGCTGAAACCTCACCTGAAAAGAAGGATGGT +GGAGATAAACCTCCATCCTCTGCTTTTAACTTCTCGTTTAATACTTCAAGAAACGTTGAA +CCTACTGAGAATGCTTATAAGAGCGAGAACGCACCATCTGCATCATCAAAGGAATTCAAT +TTTACCAACCTACAGGCGAAGCCGTTAGTTGGAAAGCCAAAAACCGAACTTACAAAGGGC +GATTCTACTCCCGTCCAACCAGATCTTTCGGTTACTCCTCAAAAAAGTTCATCGAAAGGC +TTTGTTTTTAATAGTGTTCAAAAGAAATCACGGTCCAATCTTTCACAAGAAAACGATAAT +GAAGGTAAACATATCAGCGCCTCAATTGATAACGACTTTTCAGAGGAAAAGGCGGAAGAG +TTTGATTTCAATGTTCCCGTGGTGTCTAAGCAGCTAGGAAATGGCTTGGTTGATGAAAAT +AAAGTTGAGGCTTTCAAGTCCCTATATACCTTTTGATAATGAAAATTTTAGCCGTGACAT +AATTACCGTATAGCCCAACTCAATACGTAAGTTTGTGTAAAATACCATTCCAAGATGATA +TTATTTAGTCANNNNNNNNCCACTTTCTCAAAAAGAAGGAATACCTTTAGCGGCTCTTAT +AAACTATAAATTTCTAGAAGATACATAAAAGGTTTTTAGTCTGATCATAAAATTTTTTGC +TTAACAAAAAATTTGCCCAGGTGTTTCATTTGCCAGCCACAAGTAACAGCGAGAACAATT +AATTGAATGACAATCCACCACATAGCACGAGAATTAACAGCTTCAGAGGCGTCTCTAAAG +GTAGCTTCACGATCTCTCATCAATTTTTGCTCTCTTCTAATTTCGCCGATCTTGGAGTTT +AGGACGTTAACCTTGGCATGTAGAATGTCAATAGTGGCTTTACCCTTAGAATCTAACTTT +TCATCAGAGCCCACTTGGAATTCAACGTCAATCTTCGTTTTAGCCTTAATCAACCAGCCA +CCAGCTTCGGGCTGAATACAGATTTTATGTTCACCCGAATCAGACGCAAGGAAAGTTAAA +TCACCACTTGCTGAACCTTTCTGATGAACAACCAGGTGGTTATCATCAAAAGTTTCCTCA +ATATCAATCAAGACACCAAAATCTTGCGCACCAGCGTCTCTGTAATTTTGTAATTGGTCA +TCGTAAATTTGTGCCTTGTAAGTTGCTTGGAACAAAGTACCTTTAGACAATTCCTTGTGG +AAGCACTTACGTTCAGCACCAGAAGTATAATAATAGAACGCAGTAACTTGAGCTGGTAAA +ACTAGACAGCAGGCAAAAACCTGTAAAAGAGAGGTTAAAAGCATGATTAGTAGAGAGATT +GGTTACCTTTAAATACTTTTCCAAACTACAGAGGGAAGATAGAGTAAGTTTTGTATGTAC +ACATTTCTGCTGATGTGNNNNNNNNNNNCAACTTATTACGCGATTCGNNNNNNNNNNACG +GTAACAGAATACAGAATAAATTCACGTACAAAAATAGAGAATATATAAAATAATAGGTTG +ACGATTATATTGGATCTTCCCCTGGGGTTCAAGAGTCGAGACCGAGTCCTTTTAGTTTGT +GTATATCAGCTGGTTCTTTTCGTTATGAACATCCTTTTACAGGATCCATTCGCTGTTCTT +AAGGAACATCCTGAGAAGCTCACACATACGATTGAGAACCCTTTACGCACTGAATGTCTC +CAGTTCAGTCCTTGCGGTGATTACCTGGCTCTTGGGTGTGCCAATGGAGCACTTGTTATT +TACGATATGGATACGTTCAGGCCTATTTGTGTCCCAGGAAATATGTTGGGAGCACATGTT +CGACCCATTACATCTATCGCATGGTCTCCAGATGGTAGATTGTTGCTTACAAGCTCTAGA +GACTGGTCAATAAAACTGTGGGATCTTTCAAAGCCAAGTAAGCCTTTGAAAGAAATACGA +TTCGATTCTCCAATTTGGGGTTGCCAATGGCTGGATGCTAAAAGGCGGCTTTGTGTAGCT +ACGATATTTGAGGAAAGTGACGCATATGTTATTGACTTCAGCAATGATCCGGTCGCAAGC +CTTCTCAGTAAATCAGACGAAAAACAATTGAGTTCGACACCTGATCATGGATATGTTCTT +GTTTGTACAGTACATACCAAACATCCAAATATTATTATTGTTGGAACTTCAAAAGGTTGG +CTAGACTTCTATAAATTCCATTCTCTATATCAAACAGAATGTATTCATTCCCTTAAAATC +ACGAGTTCTAATATCAAACATTTAATTGTCTCGCAAAATGGTGAAAGATTAGCTATTAAC +TGCTCCGATAGAACAATAAGACAATACGAAATAAGTATTGATGATGAAAACTCTGCGGTT +GAGTTGACCTTAGAGCATAAGTACCAGGATGTGATTAATAAATTACAGTGGAACTGTATC +CTCTTTAGTAATAATACTGCCGAATACTTAGTCGCTTCTACACATGGTTCTTCTGCACAT +GAACTATACATCTGGGAAACGACTAGTGGAACGTTGGTGAGAGTCCTGGAAGGGGCTGAA +GAGGAGTTGATAGATATAAATTGGGACTTCTATAGTATGAGTATAGTGAGTAATGGTTTT +GAATCTGGGAACGTGTATGTGTGGTCTGTTGTTATTCCGCCAAAGTGGAGTGCTTTGGCG +CCAGATTTTGAAGAAGTAGAAGAGAATGTCGACTATTTGGAGAAGGAAGATGAATTTGAT +GAGGTCGATGAGGCAGAACAGCAGCAAGGACTAGAACAAGAGGAAGAAATAGCTATCGAT +CTTCGGACGAGAGAGCAATATGATGTTAGAGGTAATAACTTGCTTGTAGAACGGTTCACA +ATCCCTACAGATTATACGAGGATAATTAAGATGCAGTCATCATAGGTTTCTCTTCAAAAG +GAGAAAGTTTAAATAGGCAACTGACACTGAAGAGGTATAGTCATGCCTACCGCGATTTCT +TTGACACAGAATTGAAAAATTTTGCATTTTTTGGTAATTTCCTAATAATACGAAGTGCAA +TAATCTCACTTTGATAGGAGCACGTCATGATGGTAATTTCATACTACTGAACGTAAATGT +TGAAGGTGAATTTGTAAAGCTTTGTTATTTGAAGCTGTACACCTAAAGGGCGGTAAATTG +TTGGGTGTTAGTACCATGCCATTAATTAGAATTTGTTAGCATTTTTATTCATTTGTGCAT +TATGGGTTCAAATTCATATGACTGAACGTGTAGTTTCATATCCAGTCATCAAGAGATGCT +GAACCGCCCTTCAAAAACTTGACGAAATAGAAGNNNNNNNNNNACATTTCTCATATGTTA +CATAGATTAAATAGTACTTGATTATTTGATACATTAAGCTAACAAAGCCTTGGATAACTC +ATCGGCAAGATAGTCGGCTTCAGCCCTGTAATTCAAGCTGTGTAGGTTAGCAACGGTATA +TCTAATTCTGCTTTGATCATTGTATGTATCCTCACGCGCTCTAATCCTAAAGTCATATTC +GTTCATTTGGATACTTTGAGTAATTTTTGTGAATTCGTTGGGGTCTTCTTCCTTCAAAGA +CATTAATGTATTAGCATCAACACCCAATAATTGTTTAGCTTGGTCGTCAAATAAAGTGAG +CCATAGTTGATTGGTTTCGTCAATAATTGATATTGTCAAGATGTATCTCCAATTTGGCCT +TGCATTATTGGTGTCGCACTTCTCACATCTCCAAGTACCATCAGGCTGTTCCAGAACTTT +CTTATTACAATTCTCATTAGAACAGGCAGGATATGCAAAATTATCAACTTTTAAGAAACT +TATAGCAGCTTTAACACTAAAAAAGTCACCTTTCTCGCTTCTTCCTAGATTTTCAGCTTG +AGCTCTAGCAATAGTAATACGCTGAGCAATGAATTTTGTTAAGCTAGCAGCCGATTGACC +ACCCATACCGGGTTCTTGCTTTAAAGTGATGAAGTTTGCGTTGCGGCCCTTGGAATCATA +CCAACCCTTTAAGGCATATGCCTCAGGAATTTCTGGATTCGGAATCAGGGTACTAGAAAA +TCCCATAGACAAAGATTTGCCACCAAAATCCGTCACACGAACACCTTTAATGGCAGCAAC +AGAACCTTCAGGAAGGTTGAAATCAAGGGCTTGCTGATTCCATAGGCCAACAGAGATAGA +AAACCCAGAGTCGTCAACAATTGTGATGTCACGACGATCGAATTTCTTCCCAGCCCTTGA +AGTTAGCTCAAAATGTGGGTTTATAGTTTGGATAATACCGAGGACGTCTACGTTGGAATT +TACTTCCTGGTTCTGAATAGCATCTAGTTTGATGAAATTGAAATGGGTTTTCGGAACATT +ACTTTCATCGAAACATTCTTCTATAACAGTGTCTCTATCCAAATTCAGTTCATAAGGGTG +TGTTAGATTAGTAAATTGGGGCTTAGCTGGTTGGAGTTTTGCCTTTGATACATAGTATAC +TTTGCCTTCTTGTAAAATTTCGTTAAATTTTGTAGCAAAATCATTAAACGCCGTGGCTCG +GATTTCTCCAGAGGTATCCAAGAAGTTGACATTGAATAGTTTACCATCACCTCTTTGATT +GTGCCACGTTTTAATTTCTCCCTTGTAGGAAACTCTTGCTTTGATAGTCCAAACGTTTTG +GTATGGAGACAGTTGTTCGATGGCAAAAATTGGTCTGGTTTTTTGCGAATTAGGGTTTTC +ATTGGCGAATTTTCTCTCATTTGCATTCAAGTTTGAGTTTGAATGCAGCATATCAGGGAC +ACCAGCATTGCTGGCGTTTGTTTGATTGGCAACATTACCACTGTCAGTTATATCTTCGTC +TTTTAAGGTTTCATTTGGATGCTCTGAGAAATAGTTATCCAAAAAAGTACTAGTTTGGTT +GACCATATCAGCACGCGACTGGACCAACTCAAAGTCATCTACTAAAAGAACGTATTTCTT +TCTTTCCCTGACAATAGCAGGTTCTGCAATTATCACGCGAATGATATCACCCCTTTGTAG +TTCCATTGACTGGAACTTGGATGCAGCTTGGTTTCTCAACAGAGCCTTCATATGGTAAAT +ACCATCGGAAATCATGATCAAATTCTTTCTGTTGCTGTTAGCCCCATCAGATTTCCTGGT +GTTATAAACTTGATAAACGCCACCGGTGGGATTATCGTACCTTTGCTTATTGGTGAAGAT +GCTATGAAAATCGCCCCTCGAAAGTTGAACACTGCTCATCTCTTGTAAGTATAATCTGGT +CTTCTTGCTGGTTTCGCCTTTACCGTAATAAGAAGAGTGAATAGTTTTTGTTTTACGTGT +AGAACTTAAAGTGATAACATTTGTTCAAGTAAACCTTTATGTTAGTTCACGCGTCTTTTG +TCGCCTCGTCTAATTTTTACGCGTGACATTTTTCCAAGCAGAGATATTTTATTGAGCAGC +GAAGAAGAGTTAGAGAATAAGAAAGTGATGCGATAAGAAATCCACCCAATTAGCATAGAT +CCTTTCGTATATGGCTGAAGAAGGTGGTACGCGCATAGCTATTAACATATATGCAAAAAG +AACGGCAAAAGGCGAGGAGGTTTTTATGCCACCGCTAGTATTTGACATAGATCACATCAA +ACTTCTAAGGAAATGGGGTATTTGTGGTGTGTTATCTGGAACTTTGCCTACTGCAGCACA +GCAAAATGTATTTTTGTCGGTACCTTTGAGGCTTATGTTAGAAGATGTGCTGTGGCTGCA +TTTGAACAATCTTGCCGATGTGAAATTAATAAGACAAGAGGGAGATGAGATTATGGAGGG +AATAACATTAGAGCGGGGCGCCAAACTATCTAAAATTGTCAACGATCGTTTGAACAAGTC +ATTTGAATATCAGAGAAAGTTCAAAAAGGATGAACACATTGCAAAATTAAAGAAAATCGG +TAGAATCAATGATAAAACCACAGCTGAAGAATTGCAACGGCTTGATAAATCTAGCAATAA +TGACCAGCTAATTGAATCTTCTTTGTTCATTGACATTGCTAATACCTCTATGATTTTAAG +AGACATACGGAGTGATTCAGACAGCTTATCCCGCGATGATATCAGTGATTTGTTATTTAA +GCAGTACAGACAGGCAGGAAAAATGCAGACCTATTTCTTATACAAGGCATTGAGAGATCA +AGGGTACGTTTTGTCCCCAGGTGGACGTTTTGGTGGGAAGTTTATAGCATACCCTGGTGA +TCCTCTTCGTTTCCATTCACATCTGACGATACAAGATGCGATTGATTATCATAATGAGCC +GATTGACCTAATATCCATGATAAGTGGTGCAAGACTAGGAACGACTGTGAAAAAACTTTG +GGTCATAGGCGGTGTTGCGGAAGAGACAAAGGAAACTCATTTCTTCTCAATAGAATGGGC +TGGATTTGGTTAAGCTGGGAATCAGTCATGTATAATTATTTTCTCAGAATTTATGTATTT +ATAAGGTTTTTCAGAAGCATACATATGTGTAATACAATTTTTAAATTTGCATTGATATTT +TGATGCATTCAGCGGGAAAGTAGTTGTTTATCACTAGACATATAATTATGTTTATTTATA +TTTAGTGGGAGCAAAACAGTTTATTGAATGTTTACCAGAACCGNNNNNNNNGCTCTTCTA +AACTGTTGACATCCAGTTCATTTACTTCCACGTGTAGATGTGAAGGAACAAATATTTTAG +CATCGTTCATACAAGTAATTATGCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNGGTTCTTATTTTCAACAATGTAATTGATGGCCTTAAAT +CTCTACTACATCATAAAGCTTCTAAGCACTTACCATTCCTTCATAAGTCTAGTATTGTAA +TGAGTTGGGCACATGGCGCAGTTGGTAGCGCGCTTCCCTTGCAAGGAAGAGGTCATCGGT +TCGATTCCGGTTGCGTCCAAATTTTTTTGTTAATCCAACACAATTGAATTCGTGAATAGC +TGACTGTCATCAGTAATGTTCGTGGAAAGTACCTATCCATACTGTTGTATCACGACTAAG +TAGTTGTCGACTACTACCTCCTCAACCCCAGTTATATCCCTATGACACATTGGAGGATGC +TGAATAATGACAGAATTTTATTCCTCCTTTTCATTATCATAATCTGAAGCAAAGTTAAAA +AATAGAAGAAGTAAGATAAACTTTGTAGATACGATATATAGTTGTTTGTTTTAGCTATCA +TATATGCTGAACTGTTACTACCTTATTTTTTCCGAAATGTTTCTAAAACAAATAAATATT +CATGAATATGATGCAAGTTCGTTGGATGAGAAAAAGACCAGGCTTTATTGTAAGGACAAT +ATCATTTACGAATAATTTCATCCAATTGTTTCATCAACACATCCATTCTGTCAAAAACTG +GAGCATAGAGATGTTGAACCAAAGAATTGGGCTTCGAAGCCGGATCGGACATATTGGTAT +TAGACAATGCCCTTGATCCGGAAAGTGAACTATTTATGCTTGCTGATGATACCGCCCTTT +GTTCATCCATATAAAAATCTTCTTCAGATGATGAGTGTAACGATAAGGTTGATTGCTTTT +CTTCTTCGGGGGTACTGTGATGTTTTTCTAGCTCCTCTTTAGGTTGTTCTGCGTCAGTTT +GATTTGCCATTCCTCCACTAGACCCCAAGCTGGCTTGAATTTGCCCCTCTGTGTTTTCCA +CGTTTGTTGTCTCTTCAATTTTCGATTTTGCATGAATATATTGTGAAATGTCCTTTATTG +CTCTAGATGATGGAATACTGCTGCTTTCTTCAACTATTGGAGTGGATGGTGATTCGTTTG +TCCATTCTGACGACGACGGTGAAAACTCGCCAATTGTTGAAAGGGAATTTTGAGAGTCTG +ATTTTGCCATACCATTCGCAAATGGCATACGAGGCGCTTCAAATACTTTTTTCAGATCGG +TATCGTAATCACTGTCAACCGGTTCAGACTTTTCTTGCCCCACATACCGATTTGCATTAT +AATCATCTTCTCTGTCTTTACTCGATGATGTCTTAGGCTCACTTTCGTTTTTGTTGTCTT +GTCTCCGAACTTTTTTCACATTTAGTGGTGTATTCAAAGATGTACTAAAGGAGACGTCGC +TCACTACATCGCTCGTATCATCATCCTGGAATTTGCCAAAATTTAACTTCGCTTCAGTGT +ATTCGTCCCGGTGCGTTACTTTTGTTTCCTTGTCGTTATCAACATCATCGTCGTACGACT +GTCCATTGCCTTCACCGCCATCATCGTTACTATCTAACGAGGTATCTTCAATTGCATCAT +CTATAAACCTGTCTGCATAACCGACAACATCATTGAAACTAACAGATTTGTTCCCCTTAC +CATATCCATTCAGTGCAGGTGTCGGAATTATACTCTCTGCATCACTTTGATTCTTGTTAC +CAGAGCTGATGGAATCATCTTTCGAATCGGAGGAAGCAACCGATTGAGAAGACATGTTTT +CATTTTTCCAGCAATTCAATCGAGCTAGTCTTTCTGGAAAGGTTTCTAGAATTTCCGCTG +GCGCAAACCCGATTTTACCATCAGTGATCCTCTTAACCAGCCACCAATAGGCATCCTGGT +CATTCAAAAGTATACAAGGTTCGTCTTGCCCTAATTGACAATGTGAAGAATCATGGCCAT +TGAACGCATATAAAGCATATAGTTTATCAGGGTCCAGTTCTCTTGGCGGCGATAAGGGTT +GGTAATCGTCGTTTTCCTCCTCCAAATCGTCTTTCTCCCCTTGAAACCCTGAATCTTGAA +ATTTTCTGTCAAAGTCATCGTCATCAGAGTAGTTTTCCTCTTCATCCTCGTCCTCCGAGA +TGGCGTATTTCAAGCCATCACTAAAATCGTCAACGTCAGGGTTCATTGTATTATTCACTG +AAAAATGCACCTCATCCTTATCGGCGCTATCCACGGAATCAGTTTCGATCTCTTGTAGCC +TTCTTTCCAAATTGTCCTCAAATTCAGAATCCGAATAATCATATGAGTCGGGCAATTCCG +AAGAATTTTCTTTGTAATGTCGCTGATCCCTTTTACTGTTGCTATGCATATGTTTTTCCA +CGTTCTCCTCCTCTAACTCTTTGTCATCATCTCTATTTCGCAGAACATCATGGCCCTTTT +CTGCCGCATTACTCAGTATATTAAGTTTCGAATTGAAGGGCGAACTCTTATTCGAAGTCG +GAGTCACCACAACACTTCCGCCCATACTCTCCGAATCCTCGTTTCCTAAAGTAAGTTTAC +TTCCACTTGTAGGCCTATTATTAATGATATCTGAATAATCCTCTATTAGGGTTGGATCAT +TCAGTAGCGCGTGCGATTGAAAGGAGTCCATGCCCGACGTCGACGTGATTAGCGAAGGCG +CGTAACCATTGTCATGTCTAGCAGCTATAGAACTAACCTCCTTGACACCACTTGCGGAAG +TCTCATCAACATGCTCTTCCTTATTACTCATTCTCTTACCAAGCAGAGAATGTTATCTAA +AAACTACGTGTATTTCACCTCTTTCTCGACTTGAACACGTCCAACTCCTTAAGTACTACC +ACAGCCAGGAAAGAATGGATCCAGTTCTACACGATAGCAAAGCAGAAAACACAACCAGCG +TACCCCTGTAGAAGCTTCTTTGTTTACAGCACTTGATCCATGTAGCCATACTCGAAATTT +CAACTCATCTGAAACTTTTCCTGAAGGTTGAAAAAGAATGCCATAAGGGTCACCCGAAGC +TTATTCACGAGTCAGTCTGACTCTTGCGAGAGATGAGGATGTAATAATACTAATCTCGAA +GATGCCATCTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCTTAC +CCAGATTCTTTGAGGTAAGACGGTTGGGTTTTATCTTTTGCAGTTGGTACTATTAAGAAC +AATCGAATCATAAGCATTGCTTACAAAGAATACACATACGAAATATTAACGATAATGTCA +ATTACGAAGACTGAACTGGACGGTATATTGCCATTGGTGGCCAGAGGTAAAGTTAGAGAC +ATATATGAGGTAGACGCTGGTACGTTGCTGTTTGTTGCTACGGATCGTATCTCTGCATAT +GACGTTATTATGGAAAACAGCATTCCTGAAAAGGGGATCCTATTGACCAAACTGTCAGAG +TTCTGGTTCAAGTTCCTGTCCAACGATGTTCGTAATCATTTGGTCGACATCGCCCCAGGT +AAGACTATTTTCGATTATCTACCTGCAAAATTGAGCGAACCAAAGTACAAAACGCAACTA +GAAGACCGCTCTCTATTGGTTCACAAACATAAACTAATTCCATTGGAAGTAATTGTCAGA +GGCTACATCACCGGATCTGCTTGGAAAGAGTACGTAAAAACAGGTACTGTGCATGGTTTG +AAACAACCTCAAGGACTTAAAGAATCTCAAGAGTTCCCAGAACCAATCTTCACCCCATCG +ACCAAGGCTGAACAAGGTGAACATGACGAAAACATCTCTCCTGCCCAGGCCGCTGAGCTG +GTGGGTGAAGATTTGTCACGTAGAGTGGCAGAACTGGCTGTAAAACTGTACTCCAAGTGC +AAAGATTATGCTAAGGAGAAGGGCATCATCATCGCAGACACTAAATTCGAATTCGGTATT +GACGAAAAGACCAATGAAATTATTCTAGTGGACGAGGTGCTAACGCCAGACTCCTCTAGA +TTCTGGAACGGTGCCTCTTATAAGGTAGGAGAATCCCAAGATTCTTACGATAAGCAATTT +TTAAGAGACTGGCTTACTGCTAATAAGTTGAACGGTGTTAACGGCGTCAAAATGCCCCAA +GACATTGTCGACAGGACAAGGGCCAAATATATAGAGGCTTATGAAACATTGACAGGGTCT +AAATGGTCTCACTAACGTGATTTACATATACTACAAGTCGCCAGTGTAACTCCTCACTGA +ATATGATTCATACATACCCGTATGTATTAATGTATAAATGTTCTCAGAGCAAATTTTATC +GATATCTTGTTTGCCAGTGGTATGCAGGTTTGGCAAATTTTTTACCATAATATCCGTTTA +TAGATTCTGGAACCTTACCAACTTTCTTACCGCTAATTACTTCCCTGGCTCGCTCCTCCA +CTGCCTGGGTAAATTGTTCCTTCAACTGACTCAGTTCTCTTTCGTATTCAATAGCTTGCT +TCTCGAGGATTTTTTCAATGTTTGTCAGCTCATTTTCATAGTCCAGTAACTTCCTTTCAA +ATCTCTCTAATTGCAACGACTTTCTTGCAGTTCGTATCTGAATATCTTGCAGTAATTCAA +AAGTGGAAGGCCTGGTTCTTAAGTTCACATCTATCATTGAATGTATTATGGCATTAAGCC +CTCTAGAGTAATACTCAGGGACGGTGTCACATTTCCCGTTTTTAATCTTAGTTTGTAGCT +CGAGATAATTTTTTGCCTGAAATGGGGGGTGCAACGAACACATCTCAAAAATAACACAAC +CTAGTGACCAGATGTCGGATAGTGGGGAGTATGGTTGGTCCATCAACACTTCAGGCGACA +TGTAATATGGTGTACCGACGTATGTTGTGGCAAATTGAATACTAGTTTCCAGAGATTTGG +CTAACCCAAAATCACCTAACTTTACCACAACTTGACTATAGTCCATAGGGCTCCCCCTTT +TCCCTGAATTCACTCTATGGTCTCTGTAATAATTACTATTCACTTCCTCGTGACCGTCTA +CTTGTTCATTAATATTGTAATCGCTATCATCATAGCTTAAGAATATATTTCCTGGTTTCA +GATCACGATGGATAACGATGTTTTTGCCTTTTACCGGTGGTTTCATCCGGTCATATATTG +TGGTCAAAGTTGGCAATTCAACACCATAATGACATTTATAGAGCGCAGTCAATAATTGGG +CCAGGATACCCCACACAATTTTTTCTGGTATATATTTATGCTCCTGTTTGTAGTGCTTAA +TCATCTGGGATAAATCACCCCTGGAACAATATTCCATATAAAGGTATAACACTTCTTTTT +GTTCATCGAAGTCCCAGTTATAAAATTCTACAATATTTTCATGCTTCAACTGCGATAGAA +TGCTACATTCAGCGATCAGCTGTTGTCTCTCTTTGCTATTCATATGGCCATATTTGATAT +CCTTTCTAACCAAAAGTTTCTTGGTAGGTATATGGATGACTTTTCGTACAGACCCAAATG +AACCTCTCCCAATTTCTTCGAGAACTTGGTATTCTGACCTTGGTGGGTGTCCCTGCTGCT +GCTGAGGACTACGGTATTCTTGGAAAAACTGTCGTCTATGCATACTCACACAGAGAATTG +ATTCAATTATCAAATAGCACTCTCATTGAAATTAGTATTGTGAATCTTGCTCTTTTCATG +TTATATGATTTGATATTCTTTTGAAAAGTCGCTTTTATTTACGTTTAACCTAATTAGGAA +ACGTAATGAAAAAATTCAGAAACCTTNNNNNNNNNNCTTGGCTGTAACCTATCGGAAGAC +TGTGCCACTGCAATCATGTCAGATATCGTATTTCAGATTTATTGATCTATAGCTAGAAAC +ATTTAACAAAATGCACTTTGAGTCGTTCATACATTTAATCCCCAATTGNNNNNNNNNNNN +NNNNNNNNNNNGCATATATATGTATATGCTTTTTTATCATTACTGGCCTCTTTAAATTCA +AAAACTTTTCTGATCTCTTTTCCAAACAGATGCGTTTTCAGTATTGGAAGGTTCACAATT +CTATATATAGTGTTAATGTAATGCTGTATTATTTCTCTATATATGTATGTATGCACATGC +AATTCCTACATTATGTTTGAAATGTTGTAATGGGGACGGAAAAGCCGTCACTTTTATCTT +TGGAGGATCGCAAATTACTACGCTCATCTTTTGTTGGAGAACTACCAATTGCTGCAGTGA +CGCTTGAAACTTTTTGCAGGCTTCCTTTTTTTGATAATGAACGGATATCCTCACATAGCT +GACAGATCAAAACTGAGTCCCCCCCAACTTGATTTGAATTCCTTTTTGGGACATCCTTGT +TCCAGTTGTTGTTTAAAAACTCCGTTATTTGTACTAAAATGGCACGAAGTTTGAAAACAG +TGGCCTTATTACGACGATTTGGTTCGGTTTGCTTTATAGGATCCGGCTGTCCTGTGTAGT +CATATAGCTTCAATAACGATTTTGAGAATATTAGCTTTATGAATTTCAATAGATCGATTT +GAATAAGTAAACTGTTGAAATAGGTATCAAAGAAAGAAACAATCTTTTCATAAAAGTTCG +GGTGAAATATGATATTAATTGTAAGGTTTTCAAAACCGGGCAATGAGCATATCTTCGTGA +AAATGCTAATTAGTTTACTGAGGTTAACGTCATCGTCATTCAATGCATAAAACAGGTCAA +CTAATTGATCAATCGGTAATTCAATAGCAGCGTCATTGTTGACCTTTATGAGGAAAACAC +TATGAGACTCTGATGAGCCCACTGTAGGAGCCACATCATCATTTACATTGCGTAACGTAA +AATGCAAGCAGTTCAGTATGATCTCCAGTCCACTTATGGAGGTGTTATTCTTTTTTCTGA +TGAAATTCATAGCTGTAGAAAATAAAGAAGCACTCATTTGGTCCATATCCAAACTCATTT +CAACGCATATAGCAGTGATTTGTTTCCAAATGAAAGCTGCTGTCTTTGCGTCGTCGATAA +AGGGAATGATGGTATCAATATTCCGGATAAAAGCAAAAAAAGCATCGTTGTCAAGCAGAT +CATTTAAAAAAGTGCTGTTTATATGTACTGTAAGGTAACAAAGCTTGGTGAAGTACTTTA +AAACAGATAAATCTTTGATTTGGGCCATGTCAACAAAAAAAGATGTTAGCCAGGTAAAGA +AACCCTCCGGTAATTCAATTAGTAGTCTTGATTTTGAAGATATGGTCAGATGGGGAAAGT +TTGAAATGCTCTTGTGTCGCATTGGAGAAGAGGGACGCGTTGCCATCAAAGAATGAACAG +GGGACCTTGATGGAGACTGTACCGAATTCACTGGTGAGTTCCTCGTGGGTGAGGAGGATA +ACGGTAGAGAGGAAGAAGAAGGAATAGCGGACTTGTGTATTTTATCGTCATTCGTGGTTA +TCATATAGTTTATTGATTTGAAGACTACGTAAGTAATTTGAGGACTGATTAAAATTTTCT +TTTTTAGCTTAGAGTCAATTAAAGAGGGCAAAATTTTCTCAAAAGACCATGGTGCATATG +ACGATAGCTTTAGTAGTATGGATTGGGCTCTTCTTTCATGGATGTTATTCAGAAGGAGTG +ATATATCGAGGTGTTTGAAACACCAGCGACACCAGAAGGCTGTGGATGTTAAATCGTAGA +ACCTATAGACGAGTTCTAAAATATACTTTGGGGTTTTCAGCGATGCAAAATTCGGAGGAT +ACATTATTCCACATTCAATTAAAGTCTGAGGGTAGTCGATGACGAACTCTTTGGCTAAAT +GTTCGAATTTAATGATCAGTGGAATTCCTCCCATAGCGATGAATTTCAGTCGCAACCTAG +AGTGGTTATGCTGGGTATCGTAAACAAAAATGGAGCCAAATGCAGTTATTAATCGTTTAT +CAACAGTTGTGCGCGACAGACACTCGATAATTGTATCAGCGATGTTCTCGAGGGAGCAAA +CACTGAAAAGCACATGCAAGTCCGTCAAAGGCTTAGATGAACTCTTCAATTGGCTCAGCA +ATTGACTTTCAGTGGGGGGCATTAAATCTAGTTCTTGATTGTTTTCTGCCCAGGCAGCGG +GAGCCGCTGCAAGACTGAATTTAGAGGGTGATATATTTAGTTTCTCTTCTTGAAAATCGG +CATCCCAATGATAATCAGCGTCGGTAAAGTCCTCCTTGAACTTGTTGAGCTTGTCGACCT +TCACATTTTCGGTAGAGTTGATCCACACATGCTTGAGTAACTGGTCGGCTGTCGGCCTCT +TGTACATGTTTTTCACAAAGCATTTAGATAAGAAATCCTTTAGTGGCTCAGAGAAAGAGC +TAGGTGGGTAGTAGGTATCATTTTCAACAGCGTAGTAGATATTGGCGTCTGTCAAATTGT +GGTAGGGTGGATTCTTTGTGAGCATTTCAACTACAGTGGCACCTAGAGACCAAATGTCGC +TGAGCGTAGAAGCTCCCCTGTTGCCCAGGATCTCTGGAGCCATCCAATTGAGTGTGCCCG +CTAGCGTTAAGGCGCTGGAGTTCACAATAGTGGAAACGCCAAAATCAGCAAGTTTGACAG +TGTTATCAGCACTCAGCAGGATGTTAGCCGCCTTGATGTCCCTGTGGATGACTCCTTCAC +CGTGTAAATATTTCAGCCCCAATAGTGTCTGTGTCACATAGGTTTTCGATTCATTTTCAC +TTAATCCGGTAGAGCTCCTTGAAATGAGCCTCCTCAAAGAACCATTAGCGCAGTATTCGA +GGAGGATATACAATTCATAGCTTTTTCGTATGAAGCCGTGGTATTTAACAATATTGTTAT +GGTTTAAATTTTTTAACAAGCTAATTTCTGCCATAATGTCATTAAGTTCCTCATCATTTT +CGTACACGACCTCCTTTATTGCCACGACTTGGTCAGTATGTTTATTAATGGCTTTGTAAA +CTACCCCGTAAGAACCCCTCCCAATGACCTGCTTCAAGTGGTATTGCACGGATTTCTCAG +ATGCCCTCTGGATGGGAGTCAAGTTGACTCTATCGGTATCGGCCATACTGTTCATGGTAT +AGTCTTACCAGGAAAATGGGTAGTGCTTATGTGTGTTTTGTCCTTCCTCGAGCCTCCAAG +TAGAAGATATACCTTTTGTGAGGCAGATCTCCCGTATACAAAAATAACAGCAAGAAAAGC +GGAAAGACCATCGCAAGGTGGAAAGGATTATAATGGCACAGCAAAGTCCGCACAGAGCAC +TACAGTATAGCATAGAGTGCTAATGAGTTGATAGGCCCAATTTTGATTATGCCTCTTTTC +CATACACGACGCCAGAGGACATTATTACATTACAGTAGTTCGCCGCTAGATGACAAACGA +CATCCTTACCGATATGAGATGTGCAAAGCTACATAATGGCAACAAGCGTTATGAACAGCC +TTGTCTTTACGACCACAGAAAAGCCGTATTAGAGCTCTTCAGCTGCAAAATTTTCTTCTA +ATATGATGCAAAGCCATCAAAAATCATGCATAGTTATGAAATACCTGATGAAACGCTTCG +AGTTCGTGCTCAAGAAATTACTGAAAGGTTACCGAGAAGAAAAATATCTATGAGACACGA +TAAGGCCCCTTCTGAATCCATTGTCCTGGGCTTGTTCATTCTATTTACCACTTAAAATTG +ATCCTTTCAAAGGAATTTTTTTCTATTTCCAATAGTATATTTGTACAAAAACTACAAAAA +TGGATAAAAAATAACAGTAATTTGTGACTACTGTAAATATCACTGATTTGGATTTTGTAA +TGAGTACTGCTCATGCCCATGCCGATGCAAGTGGATCATAAATTTTACTAAACGATATTC +GATAATGCGCCAAGCCTTTATAAGGAACTCAAAATAACCCATATGGACAGTTTCAGAAGG +CCAAATAACGATCAAGGACATTCACTCATGTTTTTCAAAGGCGAAGAGTGTAAAATTTTC +TTCTATATAGTTCGAATATTTTATCTTATAAATTTCAGTCGTCATTTTCCACATTCGAAC +TCAAATAATGATAAAGAACGCTGCAGTAATGGCTTAAAAAAACATACTTTATAACCCATT +ATCTCTTACGTGTAATTTAAAATTGTTTATAGTACTATTTGGTTATGCTTGTATGCCTCT +ATTATTTACTTGATCTTTTTATGTTTTCTTATGATTGAATTATTTATATTCTAAATTCCT +CACGAATTTATACTGAAGATTTCCTTCCAGGCGAGAATAATAAACACATATTTATGATGA +TAACAAGACGAACGTGTATTAAGCTCCCAGTACGAGGGAAGCAGTAAAAATTATCCCAAG +ATCCATTTAAAATGGATAACTCCACGAGCTACAACAAAATACTAAGGGAATAGGCCGTTA +TTTCCGTAAAGGATGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNACATGCGCCTAACTATTCATACTATTAATTTCATATTATTAAGC +NNNNNNNNNNNNNNNNNNNNNNNNNNNNCGTAACCTCTCATACCTGTACAGGTTTCATTC +GTAAAGCAGGGACTCTAGTTTGCGATAGTGTAGATACCGTCTACGGATAGAGCACTAGAG +ATAGCTGGCTTTAATCTGCTGGAGTACCATGGAACACCAGTGATAACTCTGGTAACTTGG +TCGGCGGGAATACCAGTCAACATGGTGGTGAAATCACCGTAGTTGAAAACAGCTTCTGCA +ATTTCAACTGGATAAGTTTCAGTTGGGTGAGCAGCTTAGAAAGAGTAGTATTCAGCCAAA +TGAGCTCTGATATCGGAAACATAAACACCTAATTCAACCAAATTAACTCTTTCGTCAGAT +TGAGATAATGTAGTGGTTGCTGCGGCGGAGGCACCAGCAGCAATGGCGGCGACACCGGCA +GCGATTGAAGTTAATTTGACCATTGTATTTGTTGTTTTTTGGGTTATTGCTTAGTGATGA +TATAGGCTTAACTGGAAGGAAAAGAACAGAGAAATGTCTCAAACAAAGCTGATCAAGCCG +CTGTATTTATATGAAACTTTGAACAACTACATCTGCACACATGGGCTCTTACTGGTCGCC +CATCTCACACTCATGCCTTCCACATTCCACTTAGCGACTAAGTCATTATTACTATGGGGA +CGGGTTGTTCTTGAACGATGCTATACTTCGTATAGGAAGCCGTTTTTTTATGCCCCATCC +TTTCATATGTTCCATAGCACAAGAATGTTCTCTACAGGAAAAGTGCCTATAGGGCTGCAG +CTGCAGTTTTGGCCAAGAAATAGAACCAAAGCCAAATTTATTTTGGGCCCTCGTTCAAGG +GCCATCTCACCCTTGGCACTAAACGGTTAGTAGGAGGGAAATCGGACTTTTCCCAAATTA +GAAACAATGAAAAATTAAGTGTGAGCTCTTAGAGTCGCATCTGCAGGAATATGCACACAA +AAAGGGGAGCTGTACGTAAATAATCAGACCACACAAACTATTGCCAACCATTTGATACTC +ACGCTAGATATGATGGGGGTTCTTGTTTGGACAACACAAGTCTCAGAGCCAGCGTAGATA +TGCTTGTACATAAATGACGACTGGGGCATCAATTGAATCGGGTTACATTGTGCGAGCTAT +TACATGAAGAGAATATGCCTTTAGGGTAATTTCCAAATGTAGGAAGTCTCGCTAAGTAGG +GCGCCCAAATCTGTATAGCGATGTTGTTGAGGCCATATAGTAAAATGACGTGCCAATTAC +CGAGCTTTTGATGGAGGTAAAATCTAAGATTAATCTTGCGCCTTGAAACCACTAGAAATG +AAAGGAATTGGTGAAAAAATAATCGCGCAATAGATGACATGGAACGACAGAAGTCTTGTA +TTGTGCACGAATCCGCAATATTCAAAGCCGAAGTTCATATACGAATGCGAACTATTTCTT +AGGGTAGCTCTCTGTATGGGCCGCCATAAATTAGTACCAAAAGATAGGTTTTTGAAAAGG +CTACAATGTGCTTTTTTCCTTCTTGCTTTCGAGTCCGGTGAACAGAATATTACGACGTCC +TTGTATTAAGAGCCAGACCTCCTGTTAGCGTCACTATAAGAGTAAGTCTGAAATACGCAA +CAACTACAGTGCAATGAAAAAGTGCTCAACTCAATGACAATAAACAATTTAACCATGGCA +GGTTAAAATATTACTGCGATCAGTAAAAATGGGGATATCACCTTTTGACACATAACATAG +CAATAAAGTAACAGATCATTAGTGATCGGACAACCTGAACCAACGATATAATGTCGAAGC +CACCACTACCTTTAAGATTAGTAGCGCTGCAGGGGGAGACAATGAGAGAAATTTCCCGCC +ACATGAACTGAGTCAGGAGNNNNNNNNNNCTTGCTGGAGAATCATTTAATTTCATGGTTA +AACTCCTCTATAAGCATCCCATTCTCCCATGCCTGAAAACACTTTTGTCCATTCGATCCT +CATGCAGCCCTCGTTAATATGCTAAAATGGCTCATTAAATTGTAGATTGTATCGTTCGAG +AAACGTCAGGCATGATAGATGTTGCAATCACAGGACATTGATTATTTAATCCTGCTCTCA +ACATGTTCAATAAGTTGAAGAGTTGCTGATCTCCCCGTATATCTTATGAACCAAAGCATG +GTGGGTGAATGTTATGGTTATCCTTGTTGAAAAATGATTGATAGACTGGATTGAGCGGAA +AAACATGGGTCAATATGCTGATCTTGACATTTTTCAAAATCCACGGGGGATCAAATCAAC +TTCTTATAGCGTATGACCTCTTTTACATTGTTTAATGATGTTAAGATTGCGATATTATAG +TCAGTTAAGTTACTCAAACGCACAGATTTAATAGAAAACTGCGTCTTCGTTGCCTAGTCG +ATCATAATAAATTCGCAGATTATTTCGAATTTGATCTCCTTCGAAATCAAGTTTATTCTC +TTCACAACAAAAAATGCTTTTAACTTGAACAAAACTCGTAAACTATTTCCCCACTGTTGC +TTCGGGACGACCCAGTTATTCAATATCTTGCAATGCTAANNNNNNNNGGGAGAGCAGTTG +CAAATATTGCAAACACATCTAAAGCGTACCCACAATTTATGACTTCCTGGAGCCCAGAAC +AGCCCNNNNNNNNNNNGATGCGTTCTTTTTATACCAATATATTAGATACGTAAACTCTAC +TCATATTGCAGGTATGCCCACATCTGGATATTGACTTTGCCAATATTCCCGCACAGCATG +GGCTTGAATTTCGGCTGCTTTAAAGAGGCACCACTTTACGGTTGGTTCAACATCAGAATT +TTGAGTTGCAGCCTGATTTTCTGGAACACTGATGAACGGCTGTGTATTCGCTGTATCCCA +CTGTACATCAGGATATTTTCCCTTTATGAGATCCTTGAAAAATTCATAGCACTGGTGTTC +ACAAAAAAAGTGGTATGGTGTTTTCCATAAGCCAGCCTTGAACAAATATTGATTCATGTT +ATACGTTATGGTTTTCCATTCTTTCCCAGCTATCGATGGTCTATGAGTTATTACCTCTAG +TAGAAGTTTTGTACGGAATGTTTCATTACTTATTGGTCTACTGAATGACCATATCTGAAG +GACTACCATAGAGCCACCTAAACATATCCGGATCACCATGGCAGGGGAGAGAACACCAGA +AAACCAAATGTTTGTTAAAGTCGCCAAAATCGTCAAGACAAAAAGGAGGAAATTGATCAT +TATATACTTGGCGCGTACAATTTCGTAAAGCAAATAACTCTGGTATGATGCAAACTCATC +CTCTGGAAGGACGATATCAGCTGAGATTAAAGGACTTTCAGGGTTGTCAGGAGATCCTTC +CCTCAATGGGATTGCTTTAGGATCGTCCGTGACATGAGTGNNNNNNNNAAATAAGATTGC +ATGTTTAACAAACGATTTAACTTGCTTTTGCTTACAAGTCAAGTAAACCTTATCCTGATA +GCTTAGGAAAAATAGACTTGAATGTGTCGAACATTTCAAACCTCAATTGGTATTTTCCTT +TTTTTCAACTGTACGTACATAGCTTTTCGCTTTCTTTAGCGCCCCCAGATGAAAGTATAT +ATCGTAACAAGGATGGGAACATGAAAGGTACTGAAAAAACATCTGTATTTATTAAAAGTA +AATCAAAAGCAGACTGGGAAGTTCTGTCGTAGGGANNNNNNNNNNAATGTTATGTGTGTA +GGATTATTCTATTTCCTTGAATTTCTCGATCGAGATTTTTCGTACCTGTGTATTTTTGGA +TATAAGAGTGTTTCTGATCTATTGAGTGAGCAGGTCTCCAGCGGAATATAGAGTAGATTG +AATATGGAAGAGGACTACATTAAGGCTTATTGTTAGTTAGTTACTGTTAGGACGCTTCGG +CGAGCTGATGTCTGACTTCTCGTTGTATCAAAGAGCTCCCAATACGCCAGCGCATTTAAA +CTATGATCACGGAATGCTGGATTAGTAGTATAGCAAAAGTAACACTTGTCCACCGCAGAC +TCCATCACTTAGTCAACACCTTGGGTGTTTTACCGCTGATAATGGCCGTAAAATCGCCAG +ATATATATCATCATTGTTCTTCGCGAATAATACGTAACACAGTCTCTTTTCGAAATTTAG +ATGAGGACCATAGGCATGACTTATTTACTGAGATGTCCCTGCGTTAAAACTTTTACTGGC +CGATTGCTAACTTTATATTTGTTAATAAAACTATTCACGCCTGTGTCCTAATTGTTGGAT +AATACCTAAACAATAACGATGTTGTATAGCTAAGAGGACGACCAGACAAAAAGTTATAAA +CTTTACCCTCGTTGAAAATGGGGCAGCCACCTATGAATCACTTCCCATTACAATGCCGAA +TAGCAAAATATGTAGTAGAACACGTACACGCATGATAATTACTTCCATGCTGTACTTATT +TTTTGGGTGTCTCTTCAGAAAGAATGCTTTATATAACCATGTGTTTGAATTAGCGATCAG +CTAATAACAAGTCAGTGTCCAAATAGTTAAAACATTGTGACCCAAATATCACAAATAAGT +GGTTGTTTGGCCGAGCGGTCTAAGGCGCCTGATTCAAGAAATATCTTGACCGCAGTGAAC +TGTGGGAATACTCAGGTATCGTAAGATGCAAGAGTTCGAATCTCTTAGCAACCATTATTT +TTTCTTTTTCCTCCTATACTTCATAATCTACGTAGGAATGAAAGTACCAACATTATACCA +ATGAGGGTGTGTTTCGTGGATGCATATACTCTGAAGATAAAAACAAACTCAAGTCCGCTT +CCTACGGTTTGAGTATTTCTTACCACTACATAATAAAGAATATTACGTTAACTGTAAAAT +CAAGTAGACTTGGAAAATACAACGAGAACACTTTCCTGATTCTGCATCAGCGTTTTCTTA +TCACCAGCTGTACTTCTACATTAGCTAACTCTCCTTTCTATAAAGGGCGTCTTTCACTTC +ACTTGTGCCATGTTACAAAGCTCCAAACGCACTTCTAACTGAGTACAATGCACGATCCCA +CTGACAGACAAAACAGCTTCACAGAATTTGATCATGCCATCGTAAAAACCACGTAGTAAG +GAATAAAAAATCCCGAAGTCGATCATACTATGTAGAGATGTACATGAATAGTCTAGGAAT +CTGGTCTTCCAGCATGTTGCTTTGGTCTGCTTCAAGCGCTATGGAAGCGCTCGCCATGAG +ATATGCTGTTTCAAGGCAAAATAGCAAAGCTCTTTGTAAAGAAATACAATTCAGAGAAGA +AGCTACAGCATTTTGTTTCTGGATGATCCCTGCAGGTTCATACTACTAAGTAAATCTTGA +ACAGTTCAAATTTCAACAATTCAGAAACCGCTCTTTTTATATATACTCTACCAAACGAGA +TGAAACAGCATTTTTTTACTCTTATAAGGTACCAATATTTTGACGTATGCTTTCTTTAAC +GTTCACGATCGGGCTGGGCCATTAAACTTACCTTAGATATTATTTGGAACAGCACCGCAA +GTGCTGATGTCCCAGAAATGGGCGCCGGTTCAATTAGGTCGTGAAGTCAGACATATGGAG +ACTCTCGGACTGAAAGCACTAAGGGATGATAGCTGGCATGCCAATTCCATTTTAAATTTA +CACATCAAGTTACAGGGTTTGGGAAAATCACGTTCAAAGCCTGAAAATTTGAGGTTGTTC +ACGGAAATCATTTGGTTATGTCTGTCGGCCTGCTATTTAGAGACATTTTTTATTGCAACA +ACCTACTCTATGCACTTACACGGAATCGCAGAATAACGCGCGCACAACACAATTGGGAAA +CGATAGGATTTTGAATAGTGTATTGCTTTGTACCGATTTAAATAATTCTTTCTCGTGTTG +AATCCGAGTTGAAGATGAGTATGCTTTGAAGAGGTGAAATATCATCAGTNNNNNNNNNTA +ACGACAACTGCAGGACTCGAACCTGCGCGGGCAAAGCCCAAAAGATTTCTAATCTTTCGC +CTTAACCACTCGGCCAAGTTGCCAAAATTGTATGTTATTNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNTTATTTTCAGTGATAAAATATGTAAACCAATTATAAGAAAA +AGGATTGCGTTGCATCACAACTGTAAACCATTAATTAAAAAGAGCAATTGCTATTTAGAT +TTGTTGCTGAGAATTGGCTAAAAAATCTGATAATTGTAGGACTTCTATTATTGCTAGGGG +CAATGTGTTGGAATGCAATTCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAATTCTCAACATCC +GACTGCCATGCAATGTGCTTTTCTGGATCTCACTCATGATCATAATGGCCCTGTAAAAGG +CTCGCACTATTATTATTATATCTTCACTATATATTATTTCGGAGGCTGTACCTATCAGTG +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGAATATGAAAGGGGTTCTGAATTGCTAAA +ATATTTCGTCAAAGCTCAATTAGTATCATGATCAAGTCGTAATTCGAATCAGCATAACAA +CCTCCAAAACCATATAATAACCTTACACAAGACAAGATATCAATTCAACATGCAAACCCC +TTCAGAAAATACCGACGTCAAGTTGGATACTCTCGACGAACCCAGTGCACATTTAATCGA +GGAAAATGTGGCTCTTCCAGAGGATACATTCAATTCGTACTGGAGTTATATACTTAATGA +AATCGCTCGTTGTAAACCGCTAATGATTATGTTCCTAATACCTGTGTGTTTGGTTTTATT +GATTACGTTTTTTCATGATATCAAAGGTATCCTTGTGTTTTTAGTGATTTCTCTTATCCT +CTCTATTATCATTTTATTGATCGGTATAACTGCCTTCGTGTCTGAGACCTTGAATAAGGG +TTTCATAATTAAGCTTTTAGTAGAAGTCATTACACGTAAACCAGCAGTAGGGGGGAAGGA +ATGGAGAATAATCGCATATAATATGAACCAGTATCTGTTTGACCATGGGATATGGCATAC +TCCGTATTACTTTTTTTGTGAACATAGGTGCCATAAATTTTTCAAAAGCCTTATCAAACA +GACAAGGTCGAATGCACATTTGAGTTCACCAACGAACGGTGCAGAGAATACGCAGTCAAA +CACACCAGCAAAAGAGGTTTCAAATGAGATGGTAAAACCTTATATCTTTAGTTCTGATCC +AGTTTTAGAAGCTTACCTTATTAAAGCTGCGGAAATTCACAAAGAAGCTGAATTTGAGTA +TTGGAGAAAGCAATACCCAGAGGTTGATTTGCCTTAGGGCCGAATTTTTGGTATTTATCT +AGTATATTCTAATATAAAATGTACGAGCATCATTAACTTCAAGAACATTACGAAGCCCGC +AATTAAGTGTCAGTCCATCTGGGTGTAAAAGTTATGTACGCTCGAAACAAATTTTATGTA +GTTTACTTTAGATGCAAATGCTATTATATATTTTGCTTTATGATCCTCGGCTTGATGCTC +GCCAACGTGAGATAGCTGGTCATCACAATAGATCAGCCGGGACGCTTTTCGATCACATCG +AATCCCTTCGGGACGTTGCAACAATACGTGAAAAATGCCTCAAAAATAATAAATACAATG +GTGAACAACGTTAAAAAAGCATAAAACAGCTGGCTATTTTGATCAGGATAACATCTATAA +GTGCCATATTAAGGCAAGATATCAATTGACCATGCAAACACCTTCAGAAAATACCGACGT +AAAGATGGATACTCTCGACGAACCCAGTGCACATTTAATCGAAGAGAATGTAGCTCTTCC +CGAAGACACATTCAGTTCACATCTGAGTTATGTACTTTATGAAATTGCTCATTGTAAACC +GATCATGTTTATGATCATCATAATCGTGAGTTTGATCTCATTGATTGTGCTTTTTCATGA +TAACGACGGGTGCACTGTGATCTTAGTGATGTCCCTTATAGTAGCCTCCATGGCTTTAAT +GGTGGTTGCAGCATTCACATTCGGGAAAGCGATCACTGAACAGGAGTTCATGATAAAGCT +TTTAGTGGAGGTGATCGCACGCAAGCCTGCGGGGAAGGAATGGGGTACTGTCGCATATAA +TATGAACCAATATCTATTCATGAAGAGACTATGGTATACCCCGTACTATTTCTATAGCGG +CAAGAAGTGCCATGAGTTCTTCACCACTCTTATCAAGGAAGTGAATTCTGGTTCGCACTC +GGATTCCTCATCGAATAGTGCCGAGGATACACAATCACCTGTCTCAGCAGGGAAGACTTC +AAATGGTCTAAACAACTTTTATAGTATTAGATCAGACCCTATTTTGATGGCATATGTTTT +GAAGGCAACACAAATAGAAAAGGAGGCTCAAAGTGAATACTGGAGAAAGCAATATCCTGA +CGCTGATTTACCTTGAAGCGGAAGCATTTTATTCACCAAGTATACTTACTTTTCTTTAAA +ACGAGAACAAGAATCGAATTCAAGAACATCTCGAAGCCAGAATTGAGCATCATATATTCG +AGCTGTACAAACATCATGGCCTACAACTATCGTATTTGTAAGTTTTTTTAGAGGTTTTCA +TATTTGTTTAATAAGGGTTCTGTCAGTTTTTGTCACATTCTATTGTTGCGCTTCGCATAA +TGCAGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGGATCTCAAAAAGGGTTTGGT +GTTGTAGTTATAAGAATAACTAGTGAATAAAAAAGCTGTTGTTTGGTCCGTATTACATTC +GTCAAAAATTTAGTACTCAAATCGTGTATGCAATCGCAACCACAAAATAAAAATATTAGA +CTGGATGTGTTGAGTGGAGATGGTGCCAATTTAGTTGAGGGAAATGTGGTCCTTCCCAAA +GACATGTTCAATTCGTACTTAAGTTATTCACTTTACGTGTTACGAGGGGGCTCATTGTAA +GCCGATAATGATTATGTTCCTGGCATCTGTAATTTTGATTTCACTGACTAATTTCCGAGT +ATACCATCTCATGTCCCTTCTATCCTCTTTTTTCATCTCCGGGACAGACCGACAATAAAG +CATCTAATATTAGGCTTTCGTTAGAGGTAAGCACACGCCAGCGTTCGGTGAAAGGGGAAT +GAAACATTATCACGTACAAGATGAATAAATATCTATTTGACCATAAAATATGGAGTACTC +CTTACTACTTTTATTGCGAAGAAGATTGCCACCGTCTTTTTCTAAGTTTTATTGAGGGAA +GAACTTTCGAGAAGCCAACAAGCAACGCTGAGGAAAATGTACAGGAGACTGAAGCTGGCG +AATCTTTCACATTAAATCCCGGAGAAGATTTTCAAAATTGCTTTCCAAGACAGCGGATAT +TGTAGAACAATCTCAAGTGAAGTATTGGCAAGATATTGGTGCAATTATTTGAAAGGAAGG +AGAAATATTCTGACAGTACCTTGCTAGCAAAGGGATTTACCAATCCACTGACGCTAAAAT +GGGGTAGTAAATTAGATAAATTGCATTCTAACGTGACTTTATATAGTGGGAAACAGATAT +GTAGCACACAAAACGGCATGATTATGCTTAATTGATTCCTATTTTTTAACGTAAATACTC +TCCCAGAACGATCAGAAAACTTAACCCGCAACCATCTTTGCTGTGCTAACAACTTATGTC +GCCTCAATACCATTTTTATTTTGTATCATTCCGGAACTTAGTATTGAATGAAAAATGCCT +CCGAAGTAAAAAGCAGGTGATGAAAAGTTTCAATTGGTATAAGACAGATCGCTATTTTGA +TCCGCATAACATCCTTCAACACCATAGCAGAGCTATAGAGAAGACAAGATATAAACTGGG +CATGCAAACATCTTCAGAAAGTACCGACGCCAAGTCGGATTTTCTCGACGAACCCAGTGC +ATATTTAATTGAGAAAAATGTGGCTCTTCCCAAGGACATATTCGGTTCGTACTTAAGTTA +TTGGATATATGAAGTTACTCGTCATAAAGCGGCAGTAATTTTGCTCGTACTTATTGTGAC +TTCAATTTTATTATTAGTGTTTTTTTATAATACGGAATTTTGCGTTGCCTTTGAGATACT +ATTGTTTTCCTTTTGCTTTCCAGGAACATGCATGGTTGTAATTGCATTTAGTGAACCGAT +CGGTGATCGGGAATTTAAAGTTAAGCTTCTGATGGAAATTATCACACGTAAACCGGCGGT +AAAGGGGAAAGAATGGAGGACAATTACATACAAGATGAACCAGTATTTATTTGATCATGG +GCTATGGGATACTCCCTACTACTTTTACCGTGATGAAGATTGCCACCGTTATTTTCTAAG +TCTTATTAAGGGAAGAACTTTCAAGAAGCAAAAGGAATCGTCAGCCAGCAATGTTAAAGA +CGCACAATCAAATGACGAAACCGCTGGCACACCAAACGAAGCCGCTGAGTCTTCTAGTTT +TAGTGCCGGACCGAACTTTATAAAGCTCCTCACCAAGGCAGCCGAAATCGAACAACAATT +TCAAAAGGAATATTGGCGACAAGAGTATCCTGGTGTCGATGAGTTTTTTTAGACAGAAGA +CGGGAGACACTAGCACACAACTTTACCAGGCAAGGTATTTGACGCTAGCATGTGTCCAAT +TCAGTGTCATTTATGATTTTTTGTAGTAGGATATAAATATATACAGCGCTCCAAATAGTG +CGGTTGCCCCAAAAACACCACGGAACCTCATCTGTTCTCGTACTTTGTTGTGACAAAGTA +GCTCACTGCCTTATTATCACATTTTCATTATGCAACGCTTCGGAAAATACGATGTTGAAA +ATGCCTCTAGAGATGAAAAACAATCGTAAAAGGGTCCTGCGTAATTGAAACATTTGATCA +GTATGCAGTGGCACAGAAACAACCAGGAATACTATAGTCATAGGCAATACAAGGTATATA +TTGGCTATGCAGACCCCTCCAGAAAGTACCGACGTCAAGTTAGATACACTTAACGAACCT +AGTGCACATTTAATTGAGAAAAATGTGGCTCTTCCTAAGGACATATTCCGTTCGTACTTG +AGTTATTGGATCTATGAAATCGCTCGCTATACACCAGTCATGATTTTGTCCCTGGTAATA +GGGGTTTTGGTTTTATTAATTATATTTTTTAATGACAACGAAGCTTGTGTTTTCAATTCT +GCAATATTTGCTTTTACTTCTCTTGTAGGTTTGTTAATAATATTAAGTGATGGTAATCCA +AAGCTAGTCAGTCGTCGAAATTTTAGGACCGAGCTTTTAGTGGATGTCATCACACGTAAA +CCGGCGGTAGAAGGGAAAGAATGGAGGATCATCACATACAACATGAACCAATATTTGTTT +AATCATGGGCAATGGCATACTCCGTATTACTTTTACAGCGATGAGGATTGCTACCGTTAT +TTTCTACGCCTTGTTGAGGGAGTAACCCCCAAGAAGCAAACAGCCACGTCAATTGGCAAT +TCTCCGGTCACCGCTAAGCCTGAAGATGCCATCGAGTCAGCTTCTCCTAGTTCCAGACTG +AATTATCAAAACTTTTTGCTCAAGGCAGCGGAGATCGAACGACAAGCTCAGGAAAATTAC +TGGCGAAGGCGGCATCCCAATATCGATGCGCTTCTTAAAAAGACGGAATAGCTTAGAGAC +ACTACCATACGTAAAGCGAACATAAACTAGAGTATGATATATAATCAGCACTAACTGGCC +GGAAAACGGCCGAAGGAAGCCTCGAAAAGTCGATTCGTGTTGGACCCATTTGCTGAACAA +AGTGGTTCATTGCCTACCTATTATGGTAGTAGTCGTGATAATCGTGTGGTTGGTTTTGTC +AACGGTGCATTTGCATTTTCATGACAATAAACCTTGCGTTTTCGTTCTCGGGATATTACT +TTCCCTCCACTTCTTTCGCCTCAATAGCTCCTATAAGCATTCTCAGGGCGTATGTCGGTG +ATCGAGATTTCCAAGCAAGCTTTTAGTGGAAATCATCGCGCGCAAGCCAGCGGTAAAGGG +AAAAGAACGGAGGACGATTACATACAAGATGAACGNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNAGTACAGTAGCATTAAATATTATTAAGTTTAATGATTAAAAATTGGTTAATTG +TCAAGAAAATCTAAGGTATTAATAAATAAATAATACTATGACAACTTGCAGCGAAAGCAT +CAGCCCCAATGAAAATTAATCAGAATTGAATCTGAGCGTATTTATTTGATAACGGTTTAC +GTAACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGTAACACCCCACCCCGTATT +ACTTTTACCGTGATGAAGATTGGCATCGTTACTTTCTAAACGTAGGACGTGCGGAATGAC +AAAACCATCAGCAGTGTCACGATCTCTCCAGTCACAATGGCAATCATGAGTGCATAGTCC +AAAGTAAAGGGGCAAGGAAAAGCATGATTGAAAGGACTCCCCATCTGGACTCTATATGTC +ATCAGCGGCTNNNNNNNNGCATATAGCACAANNNNNNNNNNNNNNNNNNNNCTAGAGTCA +TCGGCCCGGCGGTCCGCGGTCATCCCCGCGGACTTTCCGTCCGCCCGGCGGGCTGTATCA +GCGTCAACTGGAACGCGCATATATATACAAGACACACATAACATAGAAGCACACCNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNCCGCCCACCCCTCCTTTCCGTATACAATGCCAAA +CTTAAAGAGACTACCCATCCCGCCACTGCAGGACACGCTCAACCGCTACCTGGCACGCGT +GGAACCCCTGCAGGACGAGCGCCAAAACCGCCGTACGCGCCGCACTGTGCTCTCCGCAGA +AAACCTGGACGCATTGAACACGCTGCACGAGCGGCTGCTAGAATACGACGCACGGCTCGC +GGAAAGCAACCCAGAGTCCTCATACATCGAGCAGTTCTGGTATGACGCGTACTTGCTATA +TGATGCAACTGTCGTTCTCAACGTCAACCCGTACTTCCAACTGCAGGACGACCCAACCAT +CAAAGACACACCAGAGACGGCGGCACAGGGCCCCTATGGCGCACACACGGTGCAGGTTCG +TCGTGCCGCACGACTCACCACCTCTATTCTCAAGTTCATCCGCCAGATTCGCCACGGCAC +ACTCCGCACAGACACTGTGCGCGGCAAAACGCCGCTGTCGATGGACCAGTATGAGCGGCT +ATTCGGCTCCAGTAGAATCCCTCCGGGTCCCGGCGAGCCCTCTTGCCACTTGCAAACAGA +CGCCACGTCGCATCACGTGGTGGCGATGTATCGTGGCCAGTTCTACTGGTTCGACGTGCT +GGACACACGCAACGAGCCCATCTTCGCCACCCCAGAACAACTGGAGTGGAACCTCTACTC +GATCATCATGGACGCGGAATCCGCCGGAAGCGGATCCGCGCCCTTTGGCGTGTTCACCAC +AGAGTCGCGCCGGGTGTGGTCCAACATCAGGGACTATCTGTTCCATGCGGACGACTGCAC +CAACTGGCGCAATCTCAAGCTGATCGACTCCGCGCTGTTCGTGGTCTGTCTCGACGACGT +GGCGTTTGCCGCCGATCAGCAGGACGAGCTCACGCGTTCGATGCTGTGCGGGACTTCTAC +CATCAATCTCGACCCGCACCAACACCAGCCGCCATTGAACGTGCAGACAGGCACCTGTCT +CAACCGCTGGTACGACAAGTTACAACTGATCGTGACCAAGAACGGTAAGGCGGGCATCAA +CTTCGAACACACCGGTGTGGACGGCCACACTGTGCTGCGGCTCGCCACAGACATCTACAC +AGACTCGATCCTGAGCTTCGCACGCGGTGTCACCAAGAACGTCGTCGACATCTTTAGCGA +CGACGATGGAAAACCATCGTCGTCGTCGTTGGCCTCGGCGGCTCACTCCGCCAACTTGAT +CACCATCCCTCGTAAACTGGAATGGCGCACTGACAATTTCCTGCAATCGTCGCTGCACTT +TGCCGAGACGCGCATCTCGGACTTGATCTCGCAATACGAGTTTGTTAATCTTGACTTCTC +CAACTACGGCGCGTCCCATATCAAGACAGTGTTCAAGTGCTCGCCAGACGCCTTCGTGCA +GCAGGTGTTCCAGGTCGCATACTTCGCGTTGTACGGTCGCTTCGAGACCGTGTACGAGCC +TGCCATGACCAAGGCGTTCCAAAACGGCCGCACAGAGGCCATCCGCTCCGTCACGGGCCA +ATCGAAGCTCTTTGTCAAGTCACTACTGGACCAGGATGCCTCGGACGCCACCAAAATTCA +GCTCTTGCACGACGCCTGTACGGCGCACTCGCAAATCACAAGGGAATGCTCCCAGGGGCT +CGGCCAGGACCGTCACTTGTATGCGCTCTACTGCCTCTGGAACCAATGGTACAAGGACAA +GTTGGAGCTCCCACCCATCTTCCGCGACAAGTCCTGGACTACCATGCAGAACAACGTCTT +GAGCACCTCCAACTGCGGTAACCCCTGCCTCAAGAGCTTCGGGTTCGGGCCTGTCACCGC +CAACGGCTTCGGCATCGGCTACATCATCAGAGACCACTCCGTCTCTGTGGTGGTGTCCTC +AAGGCATCGCCAGACTGCTCGGTTTGCGTCGCTCATGGAAAAGTCGCTGCTGGAGATCGA +CCGCATCTTCAAACGGCAGCAAGCTCGCGCAGCAAAACCCGCTGCCAGGACCACTGCTAG +CGCCAACACCAAATCAGAAGACATGAAATACCTGTTGTCCGGCTACGATTACTTCGACGT +GAGCGTGTCCGGTTGAGTTTATGCTGAGTTTTTGCGCATCAATATTATTTTNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNAGAGGAAAACGCTTTGG +AAGTGACTGGCGCCGCCGCTGGCTACTATAATAGCAGCGACTGTAATTTAATCTCATCCC +GTCGTTTGGATTACCTCTTTTACTCGCCGAGCGAACGTGCACCNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTGGATAAATAGAAGCACTCAAACTAA +ATTAAACTGCCNNNNNNNNNNNNNNNNNNNNGGGAAAAGTTTAAACATCAAAGTACACCT +TTCACCCCTCCACACACCATGGAACAACCTGATCTATCGTCTGTGGCCATCAGTAAGCCG +CTGCTGAAGTTGAAACTTCTCGACGCCCTTCGCCAGGGAAGTTTCCCCAACCTACAAGAT +CTCCTAAAGAAACAATTCCAGCCGCTAGACGACCCAAACGTCCAACAAGTGCTCCATCTC +ATGCTCCACTATGCCGTGCAAGTCGCCCCCATGGCTGTCATAAAGGAAATCGTCCATCAT +TGGGTCTCAACTACAAACACCACTTTTCTAAACATCCATCTTGATCTAAACGAACGGGAC +TCCAACGGCAACACCCCATTGCACATCGCCGCCTACCAGTCCCGCGGTGATATCGTAGCC +TTCCTCCTGGACCAACCAACCATCAACGACTGCGTGCTCAACAACTCCCACTTGCAGGCC +ATCGAAATGTGCAAGAACCTAAACATCGCGCAGATGATGCAGGTGAAACGCTCCACATAC +GTTGCAGAGACCGCCCAGGAATTCAGAACAGCTTTTAACAACAGGGACTTCGGCCACCTA +GAATCTATCCTCTCCAGCCCTCGAAACGCAGAACTGCTCGACATCAACGGTATGGACCCG +GAGACTGGCGATACCGTTCTGCACGAATTCGTCAAGAAAAGAGACGTCATCATGTGCCGT +TGGTTGCTTGAACACGGTGCTGACCCCTTCAAGAGAGACCGCAAGGGCAAACTGCCCATC +GAGCTCGTTAGGAAAGTCAATGAAAACGACACCGCCACCAACACCAAGATCGCCATCGAC +ATCGAACTGAAAAAACTATTGGAAAGGGCCACCAGGGAGCAAAGTGTCATCGACGTCACA +AACAACAACTTGCACGAGGCCCCCACTTACAAAGGCTACCTGAAAAAATGGACCAACTTC +GCTCAAGGCTACAAATTGCGTTGGTTCATCCTTAGTAGCGATGGGAAACTATCCTACTAC +ATCGATCAGGCCGACACTAAGAATGCCTGCAGGGGCTCCCTAAACATGTCTTCGTGCTCT +CTGCATTTGGATTCGTCTGAAAAGTTGAAATTCGAAATTATCGGCGGTAACAACGGTGTT +ATCAGGTGGCATTTAAAGGGGAACCACCCCATCGAGACAAATAGATGGGTTTGGGCCATC +CAGGGCGCCATAAGATACGCAAAGGACAGAGAAATTTTGCTGCACAATGGCCCCTATTCG +CCTTCTCTGGCCTTAAGCCATGGCTTGTCATCCAAAGTGTCCAATAAAGAAAACTTGCAT +GCAACTTCAAAACGGTTGACCAAGAGCCCGCATCTGTCCAAATCCACACTGACACAAAAC +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNAAGT +AGACCCCTCATAGAACCATTACCGTTGATTTCATCCAGAAGCCAAAGCTTAAGCGAAATC +ACTCCCGGTCCACATTCTAGGAAGTCTACAGTCTCGTCTACAAGGGCAGCCGATATACCA +TCAGATGATGAGGGTTACTCTGAGGACGATTCTGATGACGACGGTAACTCCTCTTACACA +ATGGAAAACGGCGGTGAAAACGATGGCGACGAAGATCTAAATGCCATTTATGGTCCCTAT +ATTCAAAAACTACACATGCTACAAAGATCCATTTCCATCGAGTTGGCATCTTTGAACGAA +TTGCTGCAAGATAAACAACAACACGATGAGTACTGGAACACCGTCAACACTTCTATTGAA +ACCGTCAGCGAATTTTTCGACAAATTAAATCGGTTGACCTCTCAAAGGGAAAAAAGAATG +ATTGCCCAAATGACCAAGCAACGGGATGTTAACAATGTTTGGATTCAATCGGTAAAAGAT +CTGGAAATGGAACTGGTTGATAAAGACGAAAAATTGGTTGCCTTGGATAAAGAACGNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNTTGAACAATCAACCACAGGTTGAAACTGAGGCT +AATGAAGAATCCGATGATGCAAATTCAATGATAAAAGGATCCCAAGAATCAACAAATACC +CTTGAGGAAATCGTAAAATTTATCGAAGCAACAAAGGAAAGTGATGAGGATTCTGACGCC +GACGAATTTTTCGACGCAGAAGAAGCTGCTTCCGACAAAAAAGCCAATGATTCGGAAGAC +TTAACCACAAACAAGGAGACTCCAGCTAATGCGAAACCACAAGAAGAAGCTCCTGAAGAC +GAGAGCCTTATTGTGATCAGTTCTCCACAGGTGGAAAAGAAGAACCAACTATTAAAAGAG +GGATCATTCGTCGGATATGAAGACCCAGTGAGAACCAAACTGGCTTTAGACGAAGATAAT +CGTCCCAAGATTGGTCTCTGGTCTGTTTTAAAGTCTATGGTCGGTCAAGACTTAACCAAA +CTAACTCTACCGGTATCGTTCAATGAGCCAACATCCTTACTACAGAGAGTATCTGAAGAT +ATTGAGTATTCTCATATTCTTGACCAAGCTGCCACTTTTGAAGACTCCTCTTTAAGAATG +CTATATGTAGCTGCCTTTACTGCATCAATGTACGCATCTACCACTAACAGAGTGTCTAAA +CCATTCAACCCCTTACTCGGTGAAACTTTTGAATATGCCAGAACTGATGGTCAGTACCGA +TTCTTCACCGAACAAGTCTCTCACCACCCACCTATCTCTGCTACTTGGACAGAATCGCCC +AAATGGGATTTTTACGGTGAATGTAATGTTGATTCGTCATTCAATGGGCGCACGTTCGCC +GTGCAACATTTAGGATTATGGTACATTACTATCCGGCCTGATCATAATATTAGTGTTCCC +GAGGAAACTTATTCCTGGAAAAAACCAAATAACACTGTTATCGGTATTTTAATGGGGAAA +CCACAAGTAGACAACAGTGGGGACGTCAAAGTCACAAACCATACCACAGGCGACTATTGT +ATGCTGCATTACAAAGCCCATGGCTGGACCTCAGCCGGTGCATATGAAGTCAGAGGTGAA +GTATTCAACAAGGACGATAAAAAATTATGGGTTCTTGGTGGGCATTGGAATGATTCCATT +TACGGGAAAAAAGTAACTGCTAGAGGCGGAGAACTGACATTAGACAGAATAAAAACGGCA +AATTCTGCCACGGGAGGACCAAAACTAGATGGGTCTAAGTTTCTGATATGGAAAGCAAAT +GAAAGGCCTTCAGTGCCATTTAATTTAACGTCGTTTGCATTGACTTTGAATGCTTTGCCA +CCCCACTTGATACCATATTTAGCACCCACAGATAGTCGTTTAAGGCCCGATCAAAGGGCT +ATGGAAAATGGTGAATACGATAAAGCTGCCGCGGAAAAGCATCGTGTTNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTACAGACCTAAGTGGTTTGTC +CAGGAGGAGCACCCCGTTACCAAAAGTCTATACTGGAAATTTAATGGAGAGTATTGGAAC +AAAAGAAAAAATCATGACTTTAAAGATTGTGCTGATATTTTCTAAGCTGTGCAATGTAGT +CACAATAACACTCGTTCATTTGTATCCATTGCGAATGCCGGTACATCGGAAAACAGGATA +GGACCTATTTAATTATATAGTATGAAGTATTCATAACTTCTTGAGGCATCAATACATCAT +ATTCCATGAGCTGCGTGGCATTCATACTCATTGATTTAAAGGTTTTTTATTTTCATGGAA +AAGATTAACCGGGCTGAACGAAATATATTAAAGATGCTAAAACTTATGCTTTCATTGACT +TTCAATAGTGTCCACTAACCNNNNNNNNNNNCTACTCTAACAAGGGATCCCCATGGATTC +AAAGCCGATACCAAACAGATATTACTCTGCATAGAATTCAAAATATTATCCATATAAAGA +TGGGAAAGAATTCCAAAAGGAAAATTCTGCTCTAGAAGGTCACAAAACTAGTAAGAAGTT +GACCCCCCTGCCATTAAAAAACGTTTTTAACAGCTCTAGCAATATTCTAATTTCGAAAGT +GCTCTCAAAAGAATTTATTCATTTGCGAAAAAAAGAATATCTCAAAATTTTCTCGATCAC +GTACAACATCGTAGTATTTAAAGGATTATTAAGTCAACGAATAATTTCCACAAGAAAGGT +ACCTCTAGTTTTGGTGATGAAGCAAGACAATAACTGGCAAGGGCTCTCACTAAATATCAA +CCCCTTTCAAATAAAAAAAGGATCATGGCTGGCAGCGCCCACAACAATTAAACTCTGTTA +CTATCAAAAAACATTGAGCCCAAGAATGGAATAAAATTTTCACTACACCTCGGACATGGA +TTTGTACATGTCCTATTATCCTGTAATTTTGACATATACTGATATGGACCTCTTGTTTCG +TATAAATCGCTATTTATTTCCCCAGATAACTAAAGAAAATCCTTCAACCCAGCGTTCTAT +ATTACTATATTCTCAACCCGCCGTTTTCCTGCTGTGCGATAATTCTCATTCAATACTACC +ATTTCAAACCTAGAAAAGGGTGTCTTTATTAAAACTGTAAGAAAATTTTATCATGAACTC +TGATGAAAAGTCTTCGGAAGATCAACTTTTTGATTTTTCAAAAATGAAAGAAACTGTTGT +CTCCATTTATGGCCTCATATCTGAAGGAAATTCGTCTGCTATTAGTCATACCACTATCTT +CTTCTTGAAGCTGCATTTCAAGGTTGATTAGGAAGCATCTAACAATCATTCGATAGGGAA +AACAGAAAGGCCGTTACAGTTTTTTAAAAATATCAATATCAAGAGAAAGAACTAGGGATA +TTGCAAAATCAAAACTTCTGATATTTGGTTTTACGTGAAAATTACCAACACTTAAACGTT +AAAATTTCAAACTATCTACTGAAATATAAATTTTCAGTCAAAGAGATGAAACGATTATTT +TCTTGAGTAATTCGTTGTCACAATTTAACAGAAAATTACTGTTTTTTTCAAGTAGTTCAC +AAAGATACTCAAACTAAGATCATGGAGACGTCGGCAAGCAATTGATTGTTAGTGATTATC +AAAACTCATTAGCTTCGGTAAAACTACATAGATTGAAAATCAGTAGTAACATACAACATG +GTTTCCATGAGATTACAAACCGGCCAACCTAATGCTTTCAAAAATTCTTTGCTTACTGAT +TCACGGTGGCCAAGAAGCATATAAATCTGTACTTTGCAGTAAAAAACAGATGGTATTGCT +CATTCCCAGCGATTGCCAAATACGATTCATAACAGATTGACTTATCTTTTTCGAAAGCTC +TATCATATGGCTTTGAGTAATAAGGTGAGATTTTTTTGGTGATGAAAATAAATACGGTGC +CTTGATGCAAAATTTTTAGCCACAAACCTCTCTTCAGTCCCACATGATTCACCTGATTAC +GACTCACTATTTCATCTGTTCCATAAATCTCGGCTTTTTATATACAGAACATTAGACGAC +GGGAAGAGAAAAACGTCAGTATAACCCACTTTTGTTCGTAAAAAAAGGTTATTCACTTCT +ACTCCGTACTAATCAATGACTTTAATGGTGAAACCATGATGAGGAGAGTAACACGATGTA +ATTGTCATAAACTAATATTATCCCATATTAGTTTACTGACGGCTACAAGTGAGAATATAT +ACTTTAAGAGTGTAACCATACCAGTAATTGGGTTCCAAACAAGTTTGTGAGGCGCGTGTG +CTGAAAGTNNNNNNNNCTTACCTTAATAACGCAATTTCTGGCGAGGTTAAAATATTAAAT +ATAAAAAGCCTTCCAAGTAATTTTGCCCACTAAAATGTAACACAAAGCTCCACTGGTTCT +CGGCTTCTTGTTCTTTCAAAAGGATCTTCAAATCCGCTTCCACTTAAGCAGCCTTCTGCT +ACGACTTCTTCTGAGACACTCGGTTTCGCGCGGGCACTTCTGCCCACCAAAAAAGTTTAT +TTTCCGGAAAGCTTATTTCTAAATAAACTTCTGAGGAANNNNNNNNCCGCAAATTTCCAT +GCAACGTCGAACTCTCAAATTCTCACGAGATTATTTGACTTGCTTTCCTTTCCCCCTTTT +TCCACGCACTACGTCAATGCAAGTGATCCGCTTTTGAAGAAGCAAAAAATACTTCTTTCA +GCTCGTACCGGCATTTTTATTATTTGTCAAAACTGGCGTTTGGAAACCAGCTCTTCACTT +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNAGAGTTTTGTTTAAGCCCCTTTTATGGATG +CATGAGNNNNNNNNNNNGGTTTGCTACAACCATCTCAGGTCTCTTGAAGGATAGTTCGAA +GCTCGCCTGACCGTCTTTGGGTGACCAGGCTTGGTTTTCAGNNNNNNNNAGCTCATTGAG +ATATGTGATCCCGTTCCTAGATATTATGAGGGAATTTTATATATCAAATTGATTTTCACC +GCGAATTCCAGAAGGATGGGCAAAAGAGGGCTTGTTGGCGTGGGAGGATGGTCGCGGCTG +AAAATTTTCACCACGAGCAGTTTCTTGTGAGACATCCTAATACTTTTGCATTTTTACCAA +GCAGTCGTCCGTAGCAAAGCATAGGTTAGTAATAACAATGTGCAAATAAAAAACTATCTT +ACAGGCAATTATTTTGTGGCAAAGCAAGGTCCATGTTTTCTTGAAAGGTAAGAAGTGGCT +TTGGGACAGCTCATATAGACAGATTTAAGTTTTTGATCTGAGAAGCGAATGAAATGTCTT +CAGTATCATTCAATTTAGCATCCTTTTCATTGACTTTGAATGTTTTACCGCCCCAATCAA +TGCCATAATTAGCACCCCATGGATGGTCGTTTAAGGCCTGAAGAGTTATGGAGCATTGTG +AATAAAATAAAAAATTACTTAGGAAAAGCATCGTGTTGAAGTAAAGCAAAGAGCAGCAAA +AAATAAATGGAGTAAATATGAGAGAAATACAGATCAGAATGGTTCGTTCAAGAGTCCATA +CTATAAACCCGATGGTGACTTTTGCACAAAAAAACAATGGTTTCGAAGATTGTGCTCATA +TTTTCTGAGCTCAACATATGCTCGCAAAAACACCTACTAATTGATGTTTACCAAGAACGC +GAGTACAGTCATATATAGATGTAGTAGAGTTGAGATATTCTGAATCGGAAGTACGATATT +TCAATTCCTATATTGCAAAAATTTATATATTTGGAGCTTCTTGAAAGAAAAAGTGTCCAA +CATCCTGCATGAAGTTTGATCACTTTAGCTGGTCCCATTCGAAGAACCNNNNNNNNNNNN +NNNNNNNNNGAGATTCTTCATATTCTGTTATTAAATTTTTAGACTTTAATTTTTACTTTC +TATGTAACGTTCACTCTTACCCTAAATATTAAACTATTTGATAAAATATTACACTGAAAG +GTGTTACAACTTTTCCTAGACCAACCTTAATATAAACGTTACGATATAAAATAAACAGTA +ATTTTAAGATTCCATTGTTGAATGTGACACGTAACTCTAGGCCATACCTGGTTTAGTATT +TTTTAAAAGAACTCTTGCTACAGCATATTTTACGTTTGCATAAAAATAAAAGAAAAGCTT +CCTTATGAAACACTGGTTAAGAAAAGAAAATGGAGTGGTTACATACTCCAAAATAAATTA +CTCTTAATATCTGTTTATCCAATGAGGAGCAGATCTCAAAGATAATCAGACTTGTTATTG +AAGCAATTGAAGTAAGTCTTCCATTGAAATCACGCTAATTATTAAGCAATATGGTGGATT +AAACAACTCTGACGGGACCGTACTACTTGATGAAAAGTTATATACAATATTGAATAACAG +CATAATGCTGTATGATGTTGAGCGGAAGATTGTATAAAAATGTCCTTTTCTAAAATCATG +AAAAACGAACCCTTTAAAGTAATTTTGTAGCGAAATTTAACCTCACGAGTTCATGATCAT +AACTCGTTATCATTTTTGTAATATTGAATCGGTCTCTATAGAGCCTCATGAGAAGATAGA +GGACCCGAAATAATTCTCCCTTCAAACATTATGGCCAATAAGTGTCAGGAAGTGAAGCAT +TGACATGACAGCAGCACATTAAAACTCTATTGAATATAAATACGATCCACGACATGTCGT +TTACAAAGCGCTAAAAACTCATGAGCCAACTATTCCCTAAATTTCCAAGATCTATCATAT +ATTTTTCCCTAATTTTCCAAGAGGAACCTCCATAAAATAATGCAGAAAAACATTTGTTTG +ATCTATTTTAAAAGGCATATCGCATGTTATAGTGAATCTGAAGATTGCTTCTCTCGTCAG +TATTAATGCACTATATTACGTTTCAAATAATTCGTAGATTGTCTCAAGTTTTCAGTATAT +TTGCCTTCATGACCCACCGGTCCTCTTCCCTCAAGTGCTCAACGATGGGAGCTTCAGAAA +AATCCAGCAGCATAGTTGAGTTCTGATTCTCTCCTTGGTAGTTTTTTCCTTTGGTGATTT +CGGATTCATAATGAAAATGTTTCGTATATTCTATGACTAAAGTTGTTATTGTTGTAAGTA +TTTCTGCTTCCTCTTGCAACAATTCCGCTCCCACTTATAATGCACCGAGGTGAATTGGTC +ATCCTTACGAAAATACCCAGATAGAAATGGAGTAGTTGCGTGATCGTTTACTGCATCTTT +TGCGCCTTTTAATCAATCTTGACGTGGATATCTTGTTTTGCTTGAACCACCACCTGTATT +GCTGGTATAAATCACCATATTAACCATCGTTTTCAATCAACGCAACTTTTAGTGTATTGT +CTGCAACATCTGATTTCCCTCTGGTAAGTCACCTAATCTAAAATCTCTATTTTGAATCCA +CGGAGACATACGTTTGAAAGATATAAAAGAGTTCATTGAAAAGTCTAGCGTCACAACTGA +CATTAAAATACTTAAATATGAACCAAAATTTTTTGGCTTTTATTTTCAATGCAATCATTA +TCTGCCTATACAGGAAACGCTTTATTTGGCTCAATAATATGATCATGTTTGTCTGAAGTT +GGCAATAAAAGAAACTAAGAAGAGCCACTAAACTTATTTTATGATATGGGAAACACAGAA +AACACTCCAAAAATTTTGGTACAAGAACCTGAAAATAGAACAAAGAAAGAGGCGAGGTTT +GGTACATCTAATTTACGTGACCTAGACGTTGCTCACCTTATGTTAATAGCTTATCAGAAT +TACAAGTAATTACTTGTAGGAACATCCTCTACTAGTGAATATGAAAGAGCAGAGGTTAGC +TCCGTCTCAACCAATTTTGTACAAGTCGTTGAAAAGGACGGCTCTACTGTAGACAGGTCG +ATTCAAAGTCTGGTCTCAAAATAGAAGGTAAAATATTATTGAACAAAAGACCACTAAAAG +GCTATGGTATGTCCAATAAGATGCAAAATAGACATTTCACTCGCTAATCGTTAGTGGGAT +TATATCTTACTATACTCCTTATCTCATTGAATGGCACTAGTCGATCGAGGAACAAAAAAG +GATCGAACCGATTAGCACGGATTTCCTTAAGTAATTTAAATTACCAAAGAAGATCCACAT +CAGCAGTCGAATGTTCAAGATGCCGTAAGTTTAAAATCTTTCGTATCTTTCCCCGATCCT +GTCTTTCATCAATGAACTTGAATATCAAGAGTGAAAAAAACTCATATGGCTTCTCTTGAA +GAGTTAGAAAGATAGGCACATGCCAATTGTGTGCATAGCACTTACTACTCAACGATTTCA +CAACCTAGCATAATACGCGNNNNNNNNNGTGCATTTATTTAGGTAAGTCTCATTACCTAA +ACGCCAGTTTGTTTCACGTAATTGGTAACGATGAGGGAACCGCAGTAGAAAAAACTTTCA +TTCACAAACGATTAAAGTGTTATGCTAGCCAGTTTCAGGCTTTTTGTTTTATGCAAGAGA +ACATTCGACTAGATGTCCAGTTAAGTGTGCGTCACTTTTCCTACGGTGCCTCGCACATGA +ATGTTATCCGGCGCACGATACTTATCACCGAAAAACCTTATTCTACGGAAAACCTTATTT +ACATTAAAGTTGGAAAAATTTCCTCTTTTTCCTAATAAGGTGGAGCTTTTGGCTTCCAGT +ATGCTTTCACGGAATTATTTCTCATGTACATTTAGCTCCATTTCCAGTGCCTCCGATAGG +GAGGCATCATGGTACTACCGTGACGGAGAATACGTAGGCTGACTTTTTCGTCAGTTTGTT +GTCCGTTTACAAAATTGGTGAATGAATTCTAGCCTTCCTCTGCTCATTAATTGCCCTCAC +AAGAATTTGGAAGTGCGTAGAACAGGTAAAAGATTGTACTACAGAGGTATTGTGGAACCT +TCTACAGTACTTCGGAATACACCTAAAAGGTTGTTGGATGCTAAATTTAGCAAAAGTCTT +TTTTAGCTCACTATTAGGCTTGTTAAAGTCTGAAATTGTTGAAAGGCACTCAAAAAGATA +AATCAACAATCAGCATTAACGGCACAGTTGAAAGAGTCACCCACTTGAAATTAGCTCGGT +TATCAAATATAATTATCTCTGGTAAAGAGCTCTGCAGCAGGGTTAATCTATTCGCATACT +TACGCTGTAGGAACATTTTATTATTAGGATCCGACTACTGCCTACATATTTATTCGGAAG +GCATGATGTCGAAAATTTTTGAGCTTATAAAAGGAACATATTTCACTCTTGCTCGTTTGA +TGTAAGCTCTCTTCCGGGTTCTTATTTTTAATTCTTGTCACCAGTAAACAGAACATCCAA +AAATGACAATGCCTCATCGCTATATGTTTTTGGCAGTCTTTACACTTCTGGCACTAACTA +GTGTGGCCTCAGGAGCCACAGAGGCGTGCTTACCAGCAGGCCAGAGGAAAAGTGGGATGA +ATATAAATTTTTACCAGTATTCATTGAAAGATTCCTCCACATATTCGAATGCAGCATATA +TGGCTTATGGATATGCCTCAAAAACCAAACTAGGTTCTGTCGGAGGACAAACTGATATCT +CGATTGATTATAATATTCCCTGTGTTAGTTCATCAGGCACATTTCCTTGTCCTCAAGAAG +ATTCCTATGGAAACTGGGGATGCAAAGGAATGGGTGCTTGTTCTAATAGTCAAGGAATTG +CATACTGGAGTACTGATTTATTTGGTTTCTATACTACCCCAACAAACGTAACCCTAGAAA +TGACAGGTTATTTTTTACCACCACAGACGGGTTCTTACACATTCAAGTTTGCTACAGTTG +ACGACTCTGCAATTCTATCAGTAGGTGGTGCAACCGCGTTCAACTGTTGTGCTCAACAGC +AACCGCCGATCACATCAACGAACTTTACCATTGACGGTATCAAGCCATGGGGTGGAAGTT +TGCCACCTAATATCGAAGGAACCGTCTATATGTACGCTGGCTACTATTATCCAATGAAGG +TTGTTTACTCGAACGCTGTTTCTTGGGGTACACTTCCAATTAGTGTGACACTTCCAGATG +GTACCACTGTAAGTGATGACTTCGAAGGGTACGTCTATTCCTTTGACGATGACCTAAGTC +AATCTAACTGTACTGTCCCTGACCCTTCAAATTATGCTGTCAGTACCACTACNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNTCTCATCCAGTTTGTCATCATCATCTTCAGGACAAATCACCAGCTCTA +TCACGTCTTCGCGTCCAATTATTACCCCATTCTATCCTAGCAATGGAACTTCTGTGNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNTTCTACAACAACCTCCACTTCTATATTTTCTGAATCATCTA +AATCATCCGTCATTCCAACCAGTAGTTCCACCTCTGGTTCTTCTGAGAGCGAAACGAGTT +CAGCTGGTTCTGTCTCTTCTTCCTCTTTTATCTCTTCTGAATCATCAAAATCTCCTACAT +ATTCTTCTTCATCATTACCACTTGTTACCAGTGCGACAACAAGCCAGGAAACTGCTTCTT +CATTACCACCTGCTACCACTACAAAAACGAGCGAACAAACCACTTTGGTTACCGTGACAT +CCTGCGAGTCTCATGTGTGCACTGAATCCATCTCCCCTGCGATTGTTTCCACAGCTACTG +TTACTGTTAGCGGCGTCACAACAGAGTATACCACATGGTGCCCTATTTCTACTNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGG +TAGTTACAATTTCTTCTTGTGAATCTGACGTATGCTCTAAGACTGCTTCTCCAGCCATTG +TATCTACAAGCACTGCTACTATTAACGGCGTTACTACAGAATACACAACATGGTGTCCTA +TTTCCACCACAGAATCGAGGCAACAAACAACGCTAGTTACTGTTACTTCCTGCGAATCTG +GTGTGTGTTCCGAAACTGCTTCACCTGCCATTGTTTCGACGGCCACGGCTACTGTGAATG +ATGTTGTTACGGTCTATCCTACATGGAGGCCACAGACTGCGAATGAAGAGTCTGTCAGCT +CTAAAATGAACAGTGCTACCGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNAAACAGTAG +TCACCTCTTCGCTTTCAAGATCTAATCACGCTGAAACACAGACGGCTTCCGCGACCGATG +TGATTGGTCACAGCAGTAGTGTTGTTTCTGTATCCGAAACTGGCAACACCAAGAGTCTAA +CAAGTTCCGGGTTGAGTACTATGTCGCAACAGCCTCGTAGCACACCAGCAAGCAGCATGG +TAGGATATAGTACAGCTTCTTTAGAAATTTCAACGTATGCTGGCAGTGCCAACAGCTTAC +TGGCCGGTAGTGGTTTAAGTGTCTTCATTGCGTCCTTATTGCTGGCAATTATTTAATAAA +ATTCGCGTTCTTTTTACGTATCTGTGTATCTTTTCTTTGCTAATTATACGCTGACATGAA +TTATTTTTTAACTGTTTCTCCTCCATACTTTCAAATATTCAAATTGACTAAATGATAATT +CTTGCGCTTCTTATTTTGAAAAAGTAGATATGTGTATCATAAAGAAAACGTTATTATTAT +TGTCTTAGGCAACAAAAATCCATGAAAAGAATTTTACCGTTATCGATATCATTGTATTTA +TTTTATTTATTTATTCAANNNNNNNNNNNNNGGTTTATATCCTGCAAACAACACTTCGAA +TTCAATTCGATATTTCATAAGTTACAACTAACACTTATAGAAACCGATGTATGAGTACTT +ATTATTAACGAGGAAAAATGCCCTATTTTCTTTAGCAATTAATGAACCATCGCCAACTTT +TGCTTTAACAATTATTGCCATTTTCAGCAGTACTAACGTAAGATCTAGTGTGGTTCGCTT +AGGATGTTTTCGAGTAGAAATCTGCTGCACATGCCACACGCAGTACTTGAAACTTGAAAT +AATGGTGATAATTAGTTATTTAAAGTATGTTAATCTTCCTTGTTCTTTTATATTTATTTC +GAATTCTTTTGCACTAGTATTTAAAATATCAGCAGAGGTGTAAAAGTGCACCAAAATTAT +TGTAAAACTACTTGCCCTAAAATTGATACTTCATACTTGACATATTCAAAAGGGGTCCAA +GTATAGATGCATCNNNNNNNNNNNTTATCCGATGATGAGCAAATGGTAGCTTTTCGTTCC +CAGGAAGTGTAGTAGTTCCATGAAGTCTAATGAGACTTTGGAAAAAGGTTTGTCACGAGC +ACCTAACTATTGTATTTTGGAATTTTGATAAACTTCAAAACGGGAACGAAGTGTTAAACT +TAGATGCGGTTGATTTAAGCTTTAAAAGAGGAAAATAATGACTGATGATAAGAAGTCAAC +AACGATTCAAAGCAGGTGAATTTCCATTACGTTTCGCTTTTCAATTGAAAAAAATTTGGT +GGTTATTCATTTCTTGCTTGACCTCTTTACTTTTTATACTTCTGTGATGAGAAGCAAGTT +CGAGGATTTTACGATAAAGCCTACTGGTTATATTTGTATAAATTAGAACGTTGTCCTTAT +TTCTCTTTTCGAACAGTATCAAAATAAAGTTTTTGATTAGGGCCAGATTCTCTTCAAGGA +AGAGATACCTCACGTCTGTAATATCTAAGAGCTAATGTTTCGATCGAACTTTCCTTTGCT +TTTTTTCTGGATCTCATAATGTCCCACTGTATGTATGTGCCCTCGCACAGCTTTGCTCAT +CATAGACATTAATCATTGGTTGTACGATAAAAATATCGCAAAAATTATTCTAACGTTCAG +ATTAGATTCCGGCCATATTTCTGACATTTGTTTTATTAATAAAAATTTGGCGAATGTTTT +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNGTTAATGATTCACTGTGCTTTCTGTTGCTGTAGAATTTCTGA +GGCATTGTCGCTCTCTTCTATGTGATGCTACAACGGAACTAGGCTTCTTATATATCGTGG +TCCTACAAGATCTTGGTATCTCGTTTGCTTACTTTGAAGCTTCACTGATATATAGTATTT +AAGCCACTTTCATGTTCATGGATAATCGTAATTGTACTACGCTGGTACCAGTTATGAACC +CTATCAAATCATCATTGAACACTGCTATTTTTAACTAATCAAGATGTGTATGCGGCGTAC +TTTATAATTTCACGACACTATTGAAAGCAAACTAAAAATCAAGTAAATACCTATCCAAGT +TGCGGGCTCTGGATTTATGTGGCCTTAAATTTTCGACCTATGGTTCGCTATTCAATATGA +GAAAACCAAAATTAGGTACAAGTACTGATTACGTCCGTGATTCGAAAAGCAGCGTTGAAA +GATTACAAGATTTTGCGTGTCCAGGCCGACACTTAACTTTAAGGTCTCGACTTAGTAACA +TGAGTTGCCAAAAGTTTTTTTCTCCTATCTGAATATGGGGAACCGGAATTTGTCTTTGAC +CTGACTTTCAAATTGTTGCATATGTNNNNNNNNNCAGAAGAAATATGATCTTCTTCTTCT +AGCGATGCAAAAGGATTCATTACAAATCGTCGCAAAGGCCGACAAGTTGCAGTATATTCA +CATTGCTTATTTGAAGTATGTTTGTATACACATCGATAGTATTCATTAACACCACAACTG +CTGTGTATACTATGTCAAACAGCATAATAAAGCCCGTCATTTTTGTACCCGCTCATTTCC +AATAGGCATCTAAACTTACAAATGTGGTACACTACTTCGAATTCATTAATCGATATTGAA +TGCTAAAAGTCTGCGATTTCTTCCTCAACGTTCAAAAATCTCATCCAAGGCATAATCCCA +CATATTGAAGATCGCTACCAATTGTTACGGGCGAACTGAGGTTTTGGAAATGAGCTTGTA +CTTAGTAAATTTCTCTTTGCTTGCATCTTTTTCTTCCATGCCAAAAAATAAAAGATACTC +ATTTTAAAAGCGCAGCCATATTGACTAAGTAAGTAATCATAATACTATGAGTAATTTTTG +AGTACTGTGCTCATTTACTAGCTGCTTTTCTGAGAAAGATCCTCGATAATCAATTCCAGG +TTAGTGGGGCCCTTCTACGGCTTCTTCTAACCAATTGTTCCCCGTGAGTTGCTTTCTCTG +AAAACCTTATTATACATTAGAGTTATAAGAAAATTTTCTTTTTCCCGTAGATTAACCTGC +AGTGCCGAACTTCTAGATGTCACACCAGACCGTTTGACACCGCCATTTTCCTTCCTTTTC +GGAAAAATGTGCCGATAAATGGTAAGACGCGACGCCACTGCTACGAATATTACGCTTATG +ATGAAGCAAAAGGAAAAAGCAAGTTCCCCTTAAATTCGTATAACTGTTTCATCAATCTTT +AGTTCTGGCATTTGAAAGTTAATTAAACTTTTCTTCGTGGTTTCTACAGGAGTTCTGCAT +GTGCGTAATTCAAAGCCTGTGAAGGAAAAAGTATTGTCCTAAACAACGGTCGTAGAATAC +GTCAACTGTAGTTTAAAATATTTTCTGGCTCTACTCGGTGCGATAGGTCTGGCTCTTTTC +TATTTACTTTTGTTTGGAGTTGTTGAGGCCGATACCCGTCTAGATGTAAATATGAAATAA +CAGTTCGAGGTTTTATTACGAGAATGAAAAGGGTAATGGATTGGAGCATGTGTAAATGTC +AATAGCAGAAAAAATTTACCGCAAATTGTTTCGTAGTCTTATCTTCATCGGACACTCAAG +GGTTGCATAATTTTTACCCAAAGGAACAGTATACTTTTTTGATAAAAAAATCTTGTTACC +TATACAGTATTGCAAGCATTTTCAGAAACTCGTCTTTTGAGTTCTAAATGCATCATACAA +CAACAACAACAATTTCTTATTACTGTGTCCTTTTGGGATTTTTCAGCCTTCCTAGCTTAC +CCAAAATAGCCTCTCAAGGTGAAAAAACCATGCCTGCAAGCGGATCTAAGGATGAGTAGC +TAGATTACAATAAATCCTGAATTTTCTCTGAGTGTCAACTTTGTCATCGCTTGTTAAAGG +GCTACTACGCTGAAAAAGAACCTGAACTCTGTTAATAGGTTGAAGATTTTATGACTTGGT +ATACTATTCCATACGGCTGCTCTCCTGATTGCGGTGGGTCATTGCTATAACAGTAAAATC +AAGGAAGATAACAGGAAGAGTAACTTTAGTACAATAAATCTGTTGTCTTCCCGAGGATTA +TAATTGTTCGGCTTTCACACTAAGTTGAAAAGGGGGACTCAGGAAATGACAGGGTACGTT +TTAGTTTCTCCAAATAAATCTTCCACACCCAGCTTCAATGTGGTAAACGGGGGAAAGTTG +ATTAATTGATGTTGGCACTTATATTTAACTGATGTAGAGAAGAACAACATACTACTAACG +TCACAGTCAATTGTGCCAGTTTTCCAATCAAGTATTTCGAGATAATGTAAAAGTAATTGA +TATATGTTCGTACTGGTTTCCCAATTTCCGGGAAAAACTATGTACATGGGTGCAATTCCT +TGTGGTTATTTCCTTTTAGGTTATATTGCCAACCACATCATAGTACTATTTGCGGTCACT +TCAGAAGATATGTTTGCTCCTTTGATCATGATATAGACCAGGCCAACTGTACCGCTTCAG +GCTTCAAAGCATTAGGAATAAGCACCACTATTACACAACCATAGAGCTACTCTTACTGTC +ACGTAGGTAAAACACTTGCTACTACACACACTCGTAGTGACTCATCTGACTATATTGCCG +GTTGTTAAGAGGCACCAGTTAAGCACGCCATCAAGGGTACCGAATAATCTCTTCTGTATC +AAGTATTCTACCTTTATGTCTGACCCACGTATTATGTGGAGCAATTACGTATTTTTCTCA +TATCAGCTTTGTTTTTACTCAACTTTGATATCTTAGAGAAACAGATCTTGATGTTACAGC +AAGGTCAGGAAAATATTTTGACAAAAACATACTAGTTTCATCCTTAGTAGTTGATTCTAT +GAATGCTGTACTTGAAAATATTGTTCATAAAATCCATAAGTTTTACCAACGGTATAATAT +CCTGCTATTAAATCTGCAATTGCTTTTGCGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNTTGGCACCCCAATTTCTTATAATATAATAATATAACGGAAGTACACCATGCT +TTCAATAATAAGATGTTTCCTGAAAAGGGCAACTATCTGACTAGTTCAGAGCCATGCAAA +AGTTAAGGATGAAAATGCCAAATAAGAAGATATTACGGAGTACATTCATTTCAAAAAGAA +GAATGTATACTGCTTAGATAAGAAGATCAAGTTTTTATATTTCCGACCAAATAAGCCATC +GAAAACTTTTGATGCACCAAACACCGTTCTTGAGAGCCAAGCACAGATGCAATTGTTCTG +CCCTTCTTCCAAATTATGAATTGTGCATCATATCGTAAGGCCAGCCACATNNNNNNNNNN +NNNNNNNNNCTCAGTATACAGGCGAATATCCATCATACAGTCTAGCTGCCCTCACTACTT +CCAAAAAAATGGGCTAGTGTTGTACGGTTTATGCCATATATCTAGAGTTAGCATAACTAT +GCACTACCGCTTTTCGAACAAAAAGTTTGCGAAACCTAGTTCATTGAATATGACTTACCC +AAAATGGATACCAAGATCCTAATAATAAAGTCAATAACTTGAATTTTAGGTGCCATTATT +TCCAACAATCATTATAGGCTAACTCTACCAGCAGACAAGAATACCGTTCTTCTAGTTGAG +CACATGGTCAAAATAGTCAATAAAAAACGCCCAGAAATGGCTGTAAATTAGTGTTTGTAG +TACACAAAATAATTTCCTAATTCCTTCCAAATGGGGTTTTCAAAAAGCTGACTCACGTAA +TTGATCAATACTTCACTAAAGAAGAATCATATGAATAAAACTAAAATCAACACTAACTGA +GAGACTTAGCGGCCAAAGCTTAATCATCATTACATAGAGTATATGAAGGGAGTAAGTGAA +TATGCAAGGGTGGGAAACGGCAAAGCATTTTTATGCAAAAAGCGTATTTACAAATCCCGT +AAACTCATGATGTGAATTTTGTAACCAGCTTTAGCTGAGATTATTTCTTTTGCAAAAGAA +ATATTCAATAAATTAACAATTTTCAAATAAATTACCCATCCATGGTCGATAACTTGCAAG +AGAGATATCATCATTTGGCTTTTGTGATAAATTTACAAAACGTAATGTTGTATCGAGATA +TATTGAGTTACAAGTTTTCGTCTCTTTTTCCGAAGCGCCAGACTCCCGTATAAAAAATAA +GGTTTATAGCGGGCATTATGCGTAGATCAGGACTTAAATTTTTCATTGCAGAAGTCCAAT +TTCAGACTCAGTATGGTTTGTTGTAGTGCTGGTGTAAAAGATGGTGTTATTACTTAAGAC +TGATTTGGTTGCTCAGGTATTTCATTCAATAAAATTGTGAAAGAGAACCTGGAATATAGA +ATGGAAATATATATCCTGCTACTAACCCCAATGGAAGGTGACGATCACTTCTTGTGCGTT +CCAATCCCAGTTTTTGAATGTGCGAGTGGAAAAATTCTAGAGGAACAAATTGATATTTTC +AAATCAGAATTCATCAAATATATGTACTCTGTAAAAACCAAGGATGTGATGAAGTTGAGA +TATTGTCTTTATGGGAAATTGACTTCTTTGTTTAATATGAATAATGCAATTTTACTCCTC +AGCTCAAGTAGTGTAAAGATTCAGTAGCCGTCATCAAATAGACTAAAAATTAAAAAATAA +GATTCAATGTGGTATGATAATGATAGATGAGAAGAAATTGCAAGAAAACGAATAAATACC +TTGTCTCTTTGCACTGAATATCTTAAAGGACATACAGTCGCAATAACGTCTACTCATTGG +TGTGTGTCAAAAACAGTACGTTTATTATCTGGACAGCCAAAAAATAAGATCTATTCAAAC +ATGGAATATAGCGTATTTTTATTTAATCACGGTACAATGGAGATATTTGCATGCCTATAG +AAACAAGTAATAGTTATCATATTATTTTCTAGATTTTGTCACTGAACTTTTCCACTAATG +AATCCTATCAAAATTATATATCCAATATGGCTGCATTCCCAACTAAATATTAAAATGCCG +CTAAGTATAAAATGTCTCCGCATCGGTAAAAAGCATTACAAATGCGTATTATACTAGCGA +GAAAAAAGTATAAGTATCAATGCCAATCACCCTCTGACCATAAACTTTCTAAACATGAAT +AATAAAGGTGTTGAGAGTTATTATCCTAATTGATCAATTAATTTGAAGCAAAGTTATTAT +GTTAAAGAAAAAGGGATGTCACAATCCTAACTATAATTTTTGCACTATACTCTGTAGGCG +TACAAAATGGTTTGTACCGACTATATTCTCTTTATTTTTGACAATCCTTTACGATATATG +ATTAAGAATACCATGTTATTTTTATGAAAATCTGTGNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNGTCACGTAGTGCACTTTGATTAATACNNNNNNNNNTGCTGCAAAAGCATCGAC +TACATAAATTCATTAGGACGCATTCCTCATTACCACCTGGGTCTAATTTTTATTTTGAAA +TTGATATTATTCTTTATATGATGAGGTAAAAAGCATTATATTCGTTGTAAACTCATATAC +TTATCCTCATTTTAGGCACCATCAGGGACTAAGGGCTAAAGTATCAGAGCCGCATTTCAA +CAGTGTACAGAGATTTTAGAAACATTATCACGCACTGCCTTTTGCTTTGTTTACCCGTAA +TGAGTATACAGTGGATTTTCTGGTGCTAAAGCATATTGCCCTTTCGGCAATACTTGATGC +CCTAAACATTTTCATCCTGGAACATACGAGTAAGAGCACATTTATGTGCCTATATTCCTC +GTTTTTTACTGGTGCTGAATTTCTTATTTTCCACAGATAACAATCATGTTAATAAATTAT +GCACTGTGCTAATTTTTCAATTAAGGTTCTATTACCCCTCTATCACCGACAGAAACACGT +AATGATGTGTTATTTCCATTATAATTCCGTAAGAATGGTGTTTATAGGTAGTCTAAAGAA +CGTGCATCAGAGAAGAATAACTGTCGCAAAAAATGACTATTCTTTACCTTTTCAAACTTA +ACTGAGATAGTTATCTCTATTATTACCAGTGGCACACACGCGAACTACATCACTCACCAC +TATCGTCTTAGGAACTCAAGATTTTATAGTAATGCAGCCGAAGACATTCAAGTCCTGAGA +GAAAATGTAGACATTTTAAGAAAAGTACCGGAAATAAAGCACATGTAAAGCATTGAGCTC +TGTACTCTATAAAAATTAGCTGCATTCAAACAACAATGTTTGAAATTTTTGCAAAAGTTA +TTGAAAAAGATTGCTGTTTTCAGCCTTGTTCAGATCATGTCTCAAAAATGAGAAACTGGA +ACTCTCATAATCAGTACCTCGTANNNNNNNNNCCTTATAGTTTCGTTATTAAAAATTTTT +TTGCTGCTAATTTAAGTACGCTTTTGGTCATAAATGCTACCCACCAGTTGAATTATTGAC +ATGATTAAAATACATTTCAGAACTTTACGGATTAAAAACTTTAAAGAACCTTTCAATCCA +TGTTGCTGGAGGGCCATGAATCCACGAATTACAGCAAAAGAAGACAGTAACTACTTAGGG +TTCAATAATTACTTGCATAAACACACACTAACAACCAAATCGTACTAAAATTTGCAATTA +ACAAAACTCCATCATATCACGCTGAATTATGTAGGGCTTCTTAATGCAATAGGTTGCCTG +AATTTTGCTTACTCGTGCTGCCGGGAACACTTAGCAGTTGGGAGGCCGTTTCTCCCATAT +ATTTCATAATTTTCTGTCCTTCTTAGAGTAGGATGCTGAAAATCAAAAGAAGACCGTCAA +TAGGACCAGATTTTGTGGGTCAATTTTGGGCCAGACACATGATACCCTAGGAAGTTTAAC +GGTATACAACTCAAGGACGAGGAGTATTCGGAAACTACCGGTTTTTAACAAGCTGCAAAT +TTCCAGTAGCTGTTTTGGTTGCGACTACGGATAAAAATTCATACTTTAGGAAGTGAAGCA +AGATAAAAAATCATGCTGCATCCTAATTCGTGAAGTTTGTTAGGAATATTATTGTAAACA +AGGAACCGTTTCAGTAAACTTGCTCTCTACTCTTCTAAGCTGTAATTTAAAAAAAGCGAT +AAAACAATGATTTTGATTATCTGCAACTTCTGGAAACTCGAGATACTACGCTAGACGAGA +TACCTATTAATTGTTTTCCTAAAAAATCAGGAACAGTTCCTGGCAGCTTTCGGCTCCTTC +TTGTTCTGGAAAGGATCTTCAAATCCGCTTCCACGTAGCAGTCCTCGCTACGACTTCTTC +TGAAGTATTTTGATTTTTGGCTGCATTTACCTTTTATTGCCGAAAATCTTATTTTCCAAG +AAAAAAGCTTATTTTGCATTAAGTTTAAAAAATTTCTTCTTTCCCGTAGATTGACTTGCA +GCGTCAAAATTCCGGAGGCCTCACGAGATTTTTTGACATCGNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNCTGCGCACGCCGATAAAGAAGTAGTACAACAGACAACGT +CAAAATGATCCTCTTGTGATGAAGCAAAAGAGGAAGAGTATACTCCTTTTCCGCTTGTAC +AAATANNNNNNNNGATAATAAAATTTGGCACTTCAGAGCTTATCGTATCTTCTCCCGGAG +TTCCTCAAGACTTATACTTCAGCCCGTTTAGGAATGCATAAAAGCAAATAGGATTCGTTA +CAACTGCTGCAGGACTCTTTAGGACTGCATCAAGGTAAGCCTCGCTGCACCTAAACGCAA +AATGTGGTTGTAACCNNNNNNNNNNNNNNCTTGAACTTGTTGAGTCGTAATAAATCGTTT +CTGGGAAGTGGAAGGTAATAATGTAATGGAATCGGCGTTACTCGCATGTGCAGATATCAG +CGACAAAAAGTGTTGTAGGGACGTTTCGATACCAAAATTTCCTAAATACAGCGCAGGAAC +ATCACTACGCTAAACAAATCGTAGCGCATACATCTGATCGAAAAAAGACAGTTCCCAAAA +CAATGACATATGAAGAGACCAGCATCAAAATTTTCATCATTAACAGCATGGCTAAAAGTT +ATTGTTTAATATACCCATACCTGATTGACGAACCAAGAAATGCCTTATCACTATTTATTT +TTGGCACTCTTCACCTACCTGGCCACGTCCAATGTTGTTTCAGGAAGTACACAAGCATGC +CTGCCAGTGGGCCCGAGGAAAAATGGGATGAATGTCAACTTTTATAAATACTCATTACTG +GATTCAACAACGTATTCCTACCCGCAATATATGACTTCTGGATATGCCTCGAATTGGAAT +TAGGTTCCGTTGGCGGACAGACGGATTTCTCAATTGACTACGATCTTTCTTGTGTTATCT +CTTCAGGAACTTTTAAATGTGCTCAATCAGATGCTTATGGAAACTGGGGATGCAGAGGTC +ATAGTGAATGTTCAAAATAGCCAAGAAAGACCTATTGGAGTACTGATTTACTTGGTTTCT +TACTATCCCAAAAAACGCTACTCTAGAAATGACAGGTTACTTTTTACCACCACAAACAAG +TTCTTACACGTTCAGGTTTGCTAAGGTCGATGACTCTGCAATTCTATCAGTCGGTGGTAA +CGTTGCGTTCGAATGTTGTGCACAAGAACAACCTCCAATTACATCGACGGATTTTACAAT +CAATGGTATTAAGCCATGGCAAGGAAGTTTGCCTGATAACATCGGAGGGACTGTCTACAT +GTATGCAGGCTACTATTATCCGCTGAAGGTTGTTTACTCCAATGCCGTTTCCTGGGGCAC +GCTTCCAATTAGCGTGGAATTGCCTGATGGTACTACTGTTAGTGATGACTTTGAAGGGTA +CGTTTACTCTTTTGACGATGATTTAAGTCAGTCAAATTGTACTATCCCTGATCCTTCAAA +ACATACTACTAGCATCGTCACAACTACTACCGAACTGTGGACTGGTACTTTTACTTCTAC +ATCTACTGAAATGACCACCGTCACCGGTACTAATGGTCAACCAACTGACGAAACCGTTAT +TGTTGCCAAAGCTCCAACCACTGCCACCTCATCCAGTTTGTCATCATCTTCTTCAGAACA +AATCACCAGCTCTATCACGTCTTAGCATCCAATTATTACTCCATTCTATCGCAGCAATGG +AACTTCTGTAGTTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTTCTGCAACGAC +CTCCACTTCTATATTCTCTGAATCATCTAAATCATCCGTCATTCAAACCAGTAGTTCCAC +CTCTGGTTCTTCTGAGAGCGAAACAATCTTAGTGATTGCTGGCATGTCATTAGCGACAAG +ACGCTTATTACCGTAGTAGCCCCCCAAGGCAAACATCTCTTTATCAGTAATATCCAAAGC +TGTTCAACTTCTCGAATTGGCCCAGGAAAAGAGCATTGGGGCGGCAACTAACTCTGGCAT +ACTTACAGTTTCTGCTCTTGACAGCGCTAAAAAAGGGCTTGTTTTGTAATGCCCGGTTCG +CAATTCTACAAGTACCACGCACTAGCTGCTAAAAGTGTCTAACCTTGCGAACAAATCTGG +ACTTTCTTATGAGAATCCCATCGTCAAGAAACAAAATTATACAGACAGGCGTAAATGTAG +CTCGTAAGCGCCTGATCAAGTAAGCCAAATGCGCTAACTTGAGGAAATATAGCCATCTAA +ATCTCTGCAACATGCCAATTCGCACGTGACTTGAAACTATGGAAAGTGTCTAGAAGATTA +CCAAGAACCACGTTATTTGAGAGAGGATGGCAAGGTGACGACAATCACACCAAGACCACA +TTTTGGGTGCGCCTGGAAGCAAGACCTGAGAAACTGGGCCAAAATATTCAAACCAAGCAT +AAGATAGTTGGAGGTAGGAATACACTATCTAATCTGTGCTGATGAAATGCTGGCGAAAAC +GGGCGATGTAGTGGTACAGAAGGTGCCGGTTATCCGTTTGTCCGNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNGCACCGCTTATATATGGGTATGAAACAAGTTCAAGA +ATTTATAATGGAACCCAAAGGTTCAGTCTTTGTAGTTCGAGCGACATTGCGCGTTTCCTT +AGAAAACGCTGGAAAGATATTCTTTAACGAGACGGAGTAATTCTCGTCAGGAATAGGATG +TTGATTGATTTTTGCTGTAGTTATATAGCAGGGACCCACGGAAGAGAGCGAGCGCCTTCT +TTCACAGGGACTTTTGTCAGCCACGTCTCCGGGGAAAACAATTGCCGTCCGCGTCGCAGT +GAGATTACGCAGCCGTGCGCTTCAGGGACAGAAAAGAAGCATTTCGCGGCTACGGAGAAA +CCGTGCACTAACTCTCTCGAGGGTAGCCGCAAAGATTTCTTGTCTCTTCCATTAGGACAT +AGCTATCTTTTTCTTTTCTGTTTTTGGCGTATGATCTGTTCTGAGCCAAAGTTATAGATC +ATTGCTTGAATAAGCACCTCACAGAGTAGGGATTGTATAGAAAGTAGCTGAGCGTCTGCC +CACGTAACAAACAATCTTGCCCCTTCCCCGCTCTTGTTTTCGCGTGCCTCTTCTACAATA +ATCTGGCCAGGCTGAATCGCGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNGTCTGCAAATTAGCACCTCGTTCCCTGTTGGCAA +ACGCGCGCGTACAAGCCTTACAGGGCTTGAGAATGTTCTTCGTAGAAATGCATGCACAAA +AATTCTGATCTAGCACACCATCGGTCTCTGTAGCTTCGGGCTCTATAGCTATGGGTTAGG +AGTCCGTGAGTAGTAACAAGAAGAAGTATATAAAAAGCAGGTAAATCGTACTTCAATATG +CTTCATTGTCACTGGATCGTCATATTCACTCTTGTTCTCATAATAGCAGTCCAAGTTTTC +ATCTTTGCAAGCTTTACTATTTCTTTCTTTTTATTGGTAAACTCTCGCCCATTACNNNNN +NNNNNGAGATGTTCAATCGTTTTAACAAATTCCAAGCTGCTGTCGCTTTGGCCCTACTCT +CTCGCGGCGCTCTCGGTGACTCTTACACCAATAGCACCTCCTCCGCAGACTTGAGTTCTA +TCACTTCCGTCTCGTCAGCTAGTGCAAGTGCCACCGCTTCCGACTCACTTTCTTCCAGTG +ACGGTACCGTTTATTTGCCATCCACAACAATTAGCGGTGATCTCACAGTTACTGGTAAAG +TAATTGCAACCGAGGCCGTGGAAGTCGCTGCCGGTGGTAAGTTGACTTTACTTGACGGTG +AAAAATACGTCTTCTCATCTGATCTAAAAGTTCACGGTGATTTGGTTGTCGAAAAGTCTG +AAGCAAGCTACGAAGGTACCGCGTTCGACGTTTCTGGTGAGACTTTTGAAGTTTCCGGTA +ACTTCAGTGCTGAAGAAACTGGCGCTGTCTCCGCATCTATCTATTCATTCACACCTAGCT +CGTTCAAGAGCAGCGGTGACATTTCTTTGAGTTTGTCAAAGGCCAAGAAGGGTGAAGTCA +CCTTTTCTCCATACTCTAACGCTGGTACCTTTTCTTTGTCAAATGCTATTCTCAACGGTG +GTTCTGTTTCCGGTTTGTAACGTAGAGACGACGATGAAGGCTCTGTAAATAACGGTGAAA +TCAACCTAGACAATGGAAGTACCTATGTTATCGTTGAACCAGTTTCTGGAAACGGTACAA +TCAACATCGTCTCTGGTAACCTATACTTGCACTACCCTGACACCTTTACTGGCCAAACTG +TTGTATTCAAGGGTGAAGGTGTTCTTGCCGTTGACCCAACCGAAACCAACGCCACTCCTA +TTCCTGTTGTTGGCTACACCGGTAAGAACCAAATTGCCATTACCGCCGACATCACTGCTC +TTTCTTACGACGGTACTACTGGTGTCTTAACTGCAACCCAAGGTAACAGACAATTCTCTT +TTGAAATTGGTACTGGATTCTCTAGTTCTGGCTTCAGTGTCTCCGAAGGAATCTTCGCAG +GCGCCTACTCATATTACCTAAACTATGACGGTGTCATCGCTACAAGCGCCGCATCCACAT +CCGCATCCACTACCTCTGGTGTTGTCTCTACTGCCACTGGTTCAGTCACTTTATCCTCTA +ACGCTTCTACCACCGTCTCTTCTACGATCTCTTCTAGCGCCCCAGACTCAATAATTCCTT +CATCTAGCGCCTCTATCTCTGGTGTCTCAAACTCCACTACAGCATCTGGTTCAATCNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGCCACCAGCTTCA +CCTCAGGTTCCGCTTCTGTCTACACTACTACATTAACTTACTTGAATGCCACAAGTACAG +TCGTGGTTTCCTGTTCAGAAACAACCGACGCTAGCGGTAACATTTACACCATTACCACAA +CTGTCCCATGCTCATCTACCACTGCCACCATCACATCTTGTGACGAAAACGGATGCCATG +TTCCAGCACCAACTGCTACCGACGCAACTGCAACCGTTTCCTCCAAGTCATACACCACTG +TTACTGTTACTCACTGTGACAACAATGGCTGTAACACCAAGACTGTCACTTCTGAATGTT +CTAAAGAAACTGCAGCAACCACCATTTCTCCAAAATCATACACTACTGTTACCGTTACTC +ACTGTGACGACAACGGCTGTAACACCAAGACTGTCACTTCCGAGGCTTCCAAACAAACAT +CATTGGCCACTAGCACAGTCACCAAGTCTGCTGCTCCAACTTCTCATACTGCTGCTTCCA +GCACCTTCACTGGTATTGTCGTTCAATCCGAAGGTATGGCTGCTGGTTTGAGAACCAATG +CTTTAAGTACTTTGGCAGGTATTTTCATCCTTGCNNNNNNNNAAAATGAGTGCGTAACCG +TACTTTCCTAAAAATAACTAAGTAGAAAGTATTTTAATATATAAACGTCAGTGTAAACAT +TCAAGTGATTTTAACTTTACGCGGTTGAAGAATGCTGTGTTCGAACTATAAAGCGTCAGA +AAAGATGGTTTAGCGAAGGCACCATTATGAAGATAGACACATTCTTCNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNCATTTACTTTTATTTCGCGCGGTCGGTAAATTTTTCG +TGGGTTTCTTTGAATCTATTAGCCGACATAAGAATAATGCATAAATAATATTTTTAATGT +CTTCCTATGCCCAAAAGAAGAAGTCTTGAAGTTGCCGCACATGGAAATCACATGACCATG +GCTTGGCCCTTCGTTTTAAATGCAACATGCAATATGGAATGTGTCATGAATACTATCAGC +AGGAACAGAAAGCGTCGTTTTGTTTCTGCAAATGCTGTAGTTTTGGGCCGAAAATAGATG +TAGTAGAATATATAGTGAAACGTGATGTACNNNNNNNNNNNNNNNNNNNNNNNNNNTTAG +ATAACTTGGATTTTTACCCTGAATATTGCATGTGATTCGTAAAGAACTGAGTTACCTCAA +ACGGACCTCCCTTTTCATTTCGTATTCCGCGAATCATGAAGTCATGCAATTACCTCTGAA +GAGCTGACTGTCCCAAAAGAAGCTATCGAATCTGTCCTTGATTTATTTAAGCCTTGCGTT +TCGAGAAAGTGAAAACCAATTGAATACNNNNNNNNNNNNNNGAAGAAAGAAATAGCAGGT +CTAAGATATATAAGAAAGTTAATATCATTTTTGAACATTTTATTTTAGACGCCTTCAGCC +GCGCGACGCCCGGAGTAATCATATGCCCATGACTTTACCAAAAGGCAACAGGGAGGAACA +TGCATTAATGTGAAGCATCACTGCTGCAATTCTCGGTGTTGCTAATAATTCATGGATCGA +GAAAGAGACATAACATTTAGGCCAATTTTTTGAATAAATATGAACTCAGCTAAGACTCGA +CAATACAATTTTCTTATACTAAACGTAGATTTATAAAATAAACACAACTGTAAGGGCAAT +GCAACCGTAGATGCATATATCATTTATAGAAATTATATCCAACAGAAAGCTCAGACTTAT +ATCCGGTTTAAGAGAGAAATTCTTGCTCATATTACCCCAAGACCAGGTGGCGTGTTGAAG +TTTATAACATATAAGAACTACTACCTCATGAATTCTAGTGGATGAAAGAAGCAGCACGAA +CACCATTTCTACAGACAACGACACATGGAAAGGTTCACCATTCCCAAAGAAAACAACGAT +GGCCACAAGGGTGTGGTCCTCCATTCTCCTACTGTTGGAAGGAGATATTATCCGACCGAC +TGTTTTGTGATATGGCAAACTATTTTTTTAAATGAGCAAAATTACTTCTTTTGGCTGGAA +ATGTCATTAGAAAGTGCCCAAGTGACATTTAGCTAAACTCGGGTATTGTCTACAAGACCG +GTGCTGTGACCGTTTCCAATACGGAAAGAAACGGTACTGGGAGCAGGAGTTGCTTTTACA +GATATGAACAATGCCAATAGAGCCGCACATGTAATTACTGGTTCACACTCGTGGGGCCCA +CACGATTCCTGTGCAAAGTTTGACAAGAGGATGGAGTTTCACGTAAATGCTGCCAAAGGT +GATGCGGTTTTGTTTTTGGGCAGCCTCTACCATGTTGCAAGTGCGAACCATACTGTGGCC +ACATAGATTACAAAAAAAGTCCAGGATATCTTGCAAACCTAGCTTGTTTTGTAAACGACA +TTGAAAAAAGCGTATTAAGGTGAAACAATCAAGATTATCTATGCCGATGAAAAATGAAAG +GTATGATTTCTGCCACAAATATATAGTAGTTATTTTATACATCAAGATGAGAAAATAAAG +GGATTTTTTCGTTCTTTTATCATTTTCTCTTTCTCACTTCCGACTACTTCTTATATCTAC +TTTCATCGTTTCATTCATCGTGGGTGTCTAATAAAGTTTTAATGACAGAGATAACCTTGA +TAAGCTTTTTCTTATACGCTGTGTCACGTATTTATTAAATTACCACGTTTTCGCATAACA +TTCTGTAGTTCATGTGTACTNNNNNNNNNNNNNNNNNNGAAATAGGAAGGAAAGAGTAAA +AAGTTAATAGAAAACAGAACACATCCCTAAACGAAGCCGCACAATCTTGGCGTTCACACG +TGGGTTTAAAAAGGCAAATTACACAGAATTTCAGACCCTGTTTACCGGAGAGATTCCATA +TTCCGCACGTCACATTGCCAAATTGGTCATCTCACCAGATATGTTATACCCGTTTTGGAA +TGAGCATAAACAGCGTCGAATTGCCAAGTAAAACGTATATAAGCTCTTACATTTCGATAG +ATTCAAGCTCAGTTTCGCCTTGGTTGTAAAGTAGNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNATCATCAGAAATACCAATGTTGAAGTCAGCCGTTTAT +TCAATTTTAGCCGCTTCTTTGGTTAATGCAGGTACCATACCCCTCGGAAAGTTATCTGAC +ATTGACAAAATCGGAACTCAAACGGAAATTTTCCCATTTTTGGGTGGTTCTGGGCCATAC +TACTCTTTCCCTGGTGATTATGGTATTTCTCGTGATTTGCCGGAAAGTTGTGAAATGAAG +CAAGTGCAAATGGTTGGTAGACACGGTGAAAGATACCCCACTGTCAGCAAAGCCAAAAGT +ATCATGACAACATGGTACAAATTGAGTAACTATACCGGTCAATTCAGCGGAGCATTGTCT +TTCTTGAACGATGACTACGAATTTTTCATTCGTGACACCAAAAACCTAGAAATGGAAACC +ACACTTGCCAATTCGGTCAATGTTTTGAACCCATATACCGGTGAGATGAATGCTAAGAGA +CACGCTCGTGATTTCTTGGCGCAATATGGCTACATGGTCGAAAACCAAACCAGTTTTGCC +GTTTTTACGTCTAACTCGAACAGATGTCATGATACTGCCCAGTATTTCATTGACGGTTTG +GGTGATAAATTCAACATATCCTTGCAAACCATCAGTGAAGCCGAGTCTGCTGGTGCCAAT +ACTCTGAGTGCCCACCATTCGTGTCCTGCTTGGGACGATGATGTCAACGATGACATTTTG +AAAAAATATGATACCAAATATTTGAGTGGTATTGCCAAGAGATTAAACAAGGAAAACAAG +GGTTTGAATCTGACTTCAAGTGATGCAAACACTTTTTTTGCATGGTGTGCATATGAAATA +AACGCTAGAGGTTACAGTGACATCTGTAACATCTTCACCAAAGATGAATTGGTCCGTTTC +TCCTACGGCCAAGACTTGGAAACTTATTATCAAACGGGACCAGGCTATGACGTCGTCAGA +TCCGTCGGTGCCAACTTGTTCAACGCTTCAGTGAAACTACTAAAGGAAAGTGAGGTCCAG +GACCAAAAGGTTTGGTTGAGTTTCACCCACGATACCGATATTCTGAACTATTTGACCACT +ATCGGCATAATCGATGACAAAAATAACTTGACCGCCGAACATGTTCCATTCATGGAAAAC +ACTTTCCACAGATCCTGGTACGTTCCACAAGGTGCTCGTGTTTACACTGAAAAGTTCCAG +TGTTCCAATGACACCTATGTTAGATACGTCATCAACGATGCTGTCGTTCCAATTGAAACC +TGTTCTACTGGTCCAGGGTTCTCCTGTGAAATAAATGACTTCTACGACTATGCTGAAAAG +AGAGTAGCCGGTACTGACTTCCTAAAGGTCTGTAACGTCAGCAGCGTCAGTAACTCTACT +GAATTGACCTTTTTCTGGGACTGGAATACCAAGCACTACAACGACACTTTATTAAAACAG +TAAATAGATAATATGATTATGTAATTTTAGAAACTAATTATGAATACCGATTTANNNNNN +NNNNNNNNNNNCACTTTTGCTGGCAAGAAATACGAAATTGCAATGACGATCACAGTCCAA +AGAGGTAAGCACAAAGGCGCAGTATGTGATTACTCTATCATTCTTTAGCAAAACCAGGAT +AGGAGTATATGTATAAGAAATATGCAACGCCATCATTTAATGCAATAGACACGACATGCC +CTTTACATGAGGTGGTACAATGTTTTAATATTGTGTCAGGGCAAGTACATGATAATATCG +TTTAAAGATGATGCTAGAGTAAAAGTATGAAGTGAAAGAAAAGGGCAATTGATTGACTAA +GCGGATGTTGTAGGATGATATAGTGGCTCATGATCTGTAAATGATCGGTTGACCGCAGTA +TTATATAATAACATCCGTATAAGTACATATACTACCATGTCTGTTCTCTACATTGCTTTT +TATTCAAGATTATTGGTTTTCCTAACCGCCGCGCCGCGCAGGTACCCCGCGCATCTCTTC +TTCTCGAAGAAAGCGGNNNNNNNNNNNNNNNNNGTATAAATAGTGGAGTCTTTTCCCATT +TAACATTTAGAAAAAAATTCGAATGGAAATTTCTTGCCGAACATTTAACCGGAGACCCTT +GGCGGCTTTTTCTCAGTTTCGTGGGCTAGTACATTTTACCTAGTATGCTGGGAACTTTTT +TTCCGTATTCTATTCTATTCCTTGCCTTACTTTTCTTATCATTTTTTATATAACCAATTT +CAAAAATACTTTTTAACTGTCATAGACGCATTTTGTTTATTACAAATTAAAAGAATCAAA +TATAATATGTGCAATTAATAACTCCACAAGTAGCGAAAGCAATGGCCGCCATTAGAGACT +ACAAGACCGCACTAGATCTTACCAAGAGCCTACCAAGACCGGATGGTTTGTCAGTGCAGG +AACTGATGGACTCCAAGATCAGAGGTGGGTTGGCTTATAACGATTTTTTAATCTTACCAG +GTTTAGTCGATTTTGCGTCCTCTGAAGTTAGCCTACAGACCAAGCTAACCAGGAATATTA +CTTTAAACATTCCATTAGTATCCTCTCCAATGGACACTGTGACGGAATCTGAAATGGCCA +CTTTTATGGCTCTGTTGGATGGTATCGGTTTCATTCACCATAACTGTACTCCAGAGGACC +AAGCTGACATGGTCAGAAGAGTCAAGAACTATGAAAATGGGTTTATTAACAACCCTATAG +TGATTTCTCCAACTACGACCGTTGGTGAAGCTAAGAGCATGAAGGAAAAGTATGGATTTG +CAGGCTTCCCTGTCACGGCAGATGGAAAGAGAAATGCAAAGTTGGTGGGTGCCATCACCT +CTCGTGATATACAATTCGTTGAGGACAACTCTTTACTCGTTCAGGATGTCATGACCAAAA +ACCCTGTTACCGGCGCACAAGGTATCACATTATCAGAAGGTAACGAAATTCTAAAGAAAA +TCAAAAAGGGTAGGCTACTGGTTGTTGATGAAAAGGGTAACTTAGTTTCTATGCTTTCCC +GAACTGATTTAATGAAAAATCAGAAGTACCCATTAGCGTCCAAATCTGCCAACACCAAGC +AACTGTTATGGGGTGCTTCTATTGGGACTATGGACGCTGATAAAGAAAGACTAAGATTAT +TGGTAAAAGCTGGCTTGGATGTCGTCATATTGGATTCCTCTCAAGGTAACTCTATTTTCC +AATTGAACATGATCAAATGGATTAAAGAAACTTTCCCAGATTTGGAAATCATTGCTGGTA +ACGTTGTCACCAAGGAACAAGCTGCCAATTTGATTGCTGCCGGTGCGGACGGTTTGAGAA +TTGGTATGGGAACTGGCTCTATTTGTATTACCCAAAAAGTTATGGCTTGTGGTAGGCCAC +AAGGTACAGCCGTCTACAACGTGTGTGAATTTGCTAACCAATTCGGTGTTCCATGTATGG +CTGATGGTGGTGTTCAAAAACATTGGTCATATTATTACCAAAGCTTTGGCTCTTGGTTCT +TCTACTGTTATGATGGGTGGTATGTTGGCCGGTACTACCGAATCACCAGGTGAATATCTC +TATCAAGATGGTAAAAGATTGAAGGCGTATCGTGGTATGGGCTCCATTGACGCCATGCAA +AAGACTGGTACCAAAGGTAATGCATCTACCTCCCGTTACTTTTCCGAATCAGACAGTGTT +TTGGTCGCACAAGGTGTCTCTGGCGCTGTCGTTGACAAAGGATCCATTAAGAAATTTATT +CCGTACTTGTACAATGGATTACAACATTCTTGTCAAGACATCGGCTGTAGGTCGTTAACT +TTACTAAAGGAAAATGTCCAAAGCGGTAAAGTTAGATTTGAATTCAGAACCGCTTCTGCT +CAACTAGAAGGTGGTGTTAATAACTTACATTCCTACGAAAAACGTTTACATAACTGAATG +TTAAATGGGATCATTAATACAATAGTACTGTACGTATGGCACCTGTACATACTGCGTTAT +AAATGTACTAATGGAATGATATATTAATATATAGTGTGTTTATACCTTATTATTGATGAT +TAGTATATATTTTTATATTTAGGTGATTTTAGTGGAGATTATTTGGTGGTAATTACACTA +GTATACATAAAATGGGTAGTGGATATTTGTATAGAAAGGGCATTACGCATGGAGTTAAGA +GTATTTACATGATAATTGGGGTTCCGTGATTCATTATAGATAATAAAACGTGGATAATAT +TGGGTGTTATAGGTAAATGGGACAGGGTATAGACCGCTGAGGCAAGTGCCGTGTATGGTG +ATGTGGTATGGTATCGAGTACCGATGGAGTGAGAGATGGCCTTGGTGTAGAGTATTATGG +CGGGTAAGTTAGATGATGTANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNTCAATATATCAATGGAGGGTATGTAGCATTATGGTAAGTAGCAC +GTGGTAGATGGGGATTGTAGGTGGATGGTAGGATGAGTGGTAGTGAGAGTTGGATAAGAT +ATATTGGGCAGGGGATAGATGGTTGTTGGGGTGTGNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNGGATGGTGGAGTGGGGGAATGAGACAGGGCATGGGGTGGTGAGGTAAGTGCCGT +GGATTGTGATGATGGAGAGGGAGGGTAGTTGACATGGAGTTAGAATTGGGTCNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGG diff --git a/latch_cli/services/init/new_example_snakemake/data/genome.fa.amb b/latch_cli/services/init/new_example_snakemake/data/genome.fa.amb new file mode 100644 index 00000000..ec9ab33f --- /dev/null +++ b/latch_cli/services/init/new_example_snakemake/data/genome.fa.amb @@ -0,0 +1,228 @@ +230218 1 227 +0 62 N +1723 8 N +1735 17 N +4617 29 N +5068 13 N +5624 8 N +6077 25 N +6736 19 N +6947 10 N +8626 8 N +9052 8 N +9223 43 N +11874 60 N +12258 68 N +12468 370 N +12863 31 N +12998 137 N +14459 14 N +14655 9 N +14768 53 N +16863 13 N +16900 51 N +18744 19 N +19105 36 N +21611 10 N +22229 310 N +23239 13 N +23705 55 N +24306 60 N +24688 91 N +25028 31 N +25163 137 N +25393 1754 N +28278 29 N +28683 8 N +29283 10 N +29737 34 N +29885 8 N +30097 11 N +30988 26 N +31035 13 N +31116 30 N +31483 38 N +31542 25 N +34990 9 N +35113 28 N +36421 24 N +37242 29 N +42085 17 N +42743 64 N +42838 11 N +45263 10 N +45359 10 N +45634 16 N +47581 17 N +49978 14 N +51804 21 N +55045 46 N +57901 18 N +62608 21 N +65534 8 N +65614 13 N +65681 18 N +65761 10 N +67715 41 N +67975 10 N +68114 25 N +69662 65 N +69734 8 N +69819 24 N +69967 26 N +70179 22 N +70534 40 N +70858 10 N +70906 22 N +71116 12 N +71530 13 N +71572 8 N +73312 53 N +74863 8 N +74928 18 N +74999 14 N +75597 9 N +76623 49 N +76689 79 N +76975 87 N +77494 48 N +77569 30 N +83197 20 N +84701 10 N +87769 74 N +91990 8 N +92291 23 N +92429 9 N +92578 36 N +93831 51 N +94372 8 N +95568 36 N +99005 8 N +99937 32 N +100007 14 N +100363 44 N +101242 15 N +101281 24 N +101450 54 N +102967 8 N +105405 8 N +106011 9 N +108643 8 N +108698 60 N +110507 28 N +110695 42 N +112740 52 N +113050 54 N +113285 33 N +116146 51 N +116283 22 N +116416 100 N +117394 9 N +118304 66 N +118468 48 N +119651 53 N +120119 66 N +124924 30 N +126866 29 N +128103 14 N +128187 17 N +128571 31 N +130613 8 N +130638 18 N +130783 14 N +132933 51 N +137539 48 N +137620 9 N +138751 237 N +139260 9 N +139346 10 N +139404 14 N +139548 59 N +141889 40 N +142085 10 N +142288 22 N +142506 17 N +142872 21 N +143188 85 N +143575 12 N +144416 8 N +148420 8 N +149619 45 N +151325 26 N +151473 96 N +151618 8 N +152012 28 N +152096 28 N +153971 8 N +154817 11 N +154847 10 N +156693 10 N +160003 8 N +160104 132 N +160237 5925 N +169210 44 N +171866 10 N +172008 23 N +176476 60 N +176580 28 N +178459 10 N +179139 8 N +179225 11 N +179980 8 N +180275 10 N +182509 9 N +182619 340 N +183141 324 N +183600 31 N +185825 34 N +189215 32 N +189425 335 N +189970 8 N +189991 20 N +190135 31 N +192291 52 N +192463 49 N +192551 20 N +193920 116 N +194576 31 N +196008 51 N +196460 11 N +198368 8 N +198638 8 N +198840 30 N +198906 11 N +199001 8 N +199908 21 N +202399 9 N +204232 2420 N +206756 83 N +207233 65 N +207622 89 N +208278 13 N +208753 11 N +209460 318 N +210385 9 N +212970 38 N +213350 19 N +215376 31 N +215433 9 N +216383 9 N +217481 40 N +217625 8 N +217815 14 N +219193 35 N +220004 40 N +220642 64 N +221035 10 N +222296 51 N +222934 8 N +223127 36 N +223470 26 N +223707 14 N +225080 18 N +225394 49 N +226914 17 N +227416 17 N +229760 56 N +229955 31 N +230092 124 N diff --git a/latch_cli/services/init/new_example_snakemake/data/genome.fa.ann b/latch_cli/services/init/new_example_snakemake/data/genome.fa.ann new file mode 100644 index 00000000..ef6c0b1a --- /dev/null +++ b/latch_cli/services/init/new_example_snakemake/data/genome.fa.ann @@ -0,0 +1,3 @@ +230218 1 11 +0 I dna_rm:chromosome chromosome:R64-1-1:I:1:230218:1 REF +0 230218 227 diff --git a/latch_cli/services/init/new_example_snakemake/data/genome.fa.bwt b/latch_cli/services/init/new_example_snakemake/data/genome.fa.bwt new file mode 100644 index 0000000000000000000000000000000000000000..9c42a579cb7eb2df36c3de6674c8300be20a41af GIT binary patch literal 230320 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 z -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

  • Rdy?r-DxfUko0tN%CwY zP$NS&9^ZOlj_XH4RikKr_xqY$7o2ir?ZTV^e;s@-_|8A^m6Bdfc%*4{4yp!_pT*f5 z>M>_&cIj{2-^C9Ik@SXg@TK7IgP#SzrMp0%Z2aBv_iJG4>r%%k@wb_R_IveFPLWg} zp4$4q+2C2=E5Tb-$@5YY_96zMdKxOD5k!^$`xyoXAA-fJ{Ro=GIIqb*Qkn$(F!*Nh zfA)3c-Ct&_S~XL zHMiPPdtSwdE`D3I%Jns(c>F&ajT^N*9Nw3Cf;VuGkE1}4e?9=8nRJ^c(j!NOBBu)@ zFo$JE1g{?>^Ni*c_4ZOS3S8#z1MdiaG5A*Sj3OH~6obL<{kiBnK~*m%?IOAJUrEp922Rz77qWZmK;Yy(IFrM%_}+ z_B719IcKy>q;U{S-?aKiWq=F#eDK%7=R*8Mx0%~95|U0`j5vr8eArNI%P?rYEo9Q; zmePBA$?1E*zXbmTJQchQ&5<;R;sgjK08eY~7M4a75}c{Tfp#tPAo7mD_2S%t|NapCdLdOfhhY;?WA5R7F*|8pC4|t9{}6^GT_Ysei>S5^yeD`I z@E^cqS2$>4OoV=6(?rL$!s*M^sU4;(EpZFHLI%8SaAydy;CF&|0Y3%4H`2R9ll#H8 zEr5XSta;Yd;1+ZhU+phj6y{??U-RzvRq$!x{lObUU;cB-w+H5K4TwY*NhT##CrZwJ z)zv|r<-8C)Q2zbDs<##3Z-S2k9{_&qP}X#?dtA%3ABNLLQR0lOsFP&7@un!F_QwqB zYzjVsuLPd}J{f%ELiL)My)i+*cN~(Hx-oe7mDHy`Ik(llR6=i)ZZGbWf&UEt0{FY& zf9}$sLKYUZXXuvouN^_q3NahqUG&TLXfRHEwAE)dn!T4_FERLh@C@+0q@7=nQH5hJ zYCMY#*Ilpo=sOF9sgx#>cfo^4TzhR#@Qc>S$9V&u3%)6*w~k~^rBjAkbdA6gUhZ85 zCJ8~&*WD3~E&XzR@_*o0foFkV4t;gpRI4wFnU!(Mp;T(sk%Ah?x^^hsXGQ+37dkwp zd-I<2;Df*qgI@=JhG@y*Qd{=c?~7%bXw3cM1@8Oh9v-XcTu->1=tDpM6#NnJGvH&v z^AZ-Ncl#&Vl)RhQy=j~wI6G{udWn3yt-@JI&anDPVuHT_UdK(IhnwJ^aA?Qwk~p68 zEa&!r_G#+Umh8MXYuYfz=$Vgm`a8D!7x<^(SA(a5AJkJ7i!da%N&WE@Rz7x$6|QxW zMR&5zB8<)>&ZDyye2~YZgLeim1fR&QOQyV6km*Ys%b2$01m)f%yAYl!CW|wy-8%Ax zXb*k>{08uU_7$)`d2LqSznNq-yncu?x}zrk(f@c{hCpy6zD4;!6UE&RJlaVM7w1|Vs34iXM?iCkDz6TJUkd&t_|xD!_w2$tb;(|M z|G3__2DSLEEcr(E1TEq15qi!e3Gna0i@^s=vI3npF%Oha;+rxWyHCve<-V~Kb-yhc6!st7x%NK}_-o+5f?o-J z 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

    p^IBb5`}zL)%PBJ7e58JJSWUjpKZworh%>R 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 QWcyk9or>KL|0;t1A3WpVdjJ3c literal 0 HcmV?d00001 diff --git a/latch_cli/services/init/new_example_snakemake/data/genome.fa.sa b/latch_cli/services/init/new_example_snakemake/data/genome.fa.sa new file mode 100644 index 0000000000000000000000000000000000000000..b0d66d28356e837e97b6a3789603cae9c92c8b35 GIT binary patch literal 115160 zcmXt=cU;fy_s1h4D=Q%(8JQt_?~%P%LKKv`#9%1=XK6?z2EQaI@h_bPv-dy4gUYX!{ze-kJ_z*|BzkafBe>hh5kpY z{_p<=2LJKa{n7j9TkwA^VS}Nayigqe+vtD)n6MfC_cZi3{lQOqJ!sHO+UupFUpflC z-0$$0cf*_3$@f3S;&YIH%tZb*4!<8;gL8idbd~g`f5lIsLQway^s93!w0m9j2UP$s zJQn=b3-H(U0d|$ALreRj-*htkAam%v=GZMfPCOA^z+0Z6_-BImt~T};Poft*2)=QD z_?=1cE@!}fIsn`OQScGwv|AU2U)%+|p0>!3SVJ!?qJPDw;=gSr^nct&K6wW6o&S(` z3;^d$5cao^L4Wt9eQu`gXV8x;XKC+H61#+4sT2K>zL*q_jM&}b>`MRp^9(hof6=iu0mMn2CKTEhbU&6e;L+@bqoh|lr> z{F#gNr*|}dANE6@8T@`Y&1`cbfwL*akkv z44lpykF*s0R+y-oja-I&*D~a-g22BX2<@eDa4H60 z+k|+WG_KDizk3Nk-VbR{*?|6%U*K2T1HZT#e&3EjFQhc`+(fA7BIskq@m24wLlp8R z2eALy34dlQh`VGMelC7SJ~$OV{UdzoLD zKQH>Czd0GdZ(c!rbO&#W9kgyb_Ejv1JNW>5{~~A~sCjW*1o(sQq2H+>?O}`1&uXA{ zM{stOfgbsZe&`~_r+NCVp8qI2^b$5gSL%7ETho7si}b_Q80vlozvVZ8cW)1ThxzE2 z*7M!962IR|Lx&zgKST4ScMf)6jG)^WV{g(1KQ^PVD{TOOpd$8l-a(_a&K%UdT~gy| zRSmqQN!Vw(K@&eSP6qMtS2S;Z()>Ag1^%bjr2Xne{M!SUKl`@^aD4G99Teh1{{nm-R0M(*_s`p5+wNA;_%=GWM( zv=^F8`-FAiUe^3EtSjS^b|1ZeNwoI~hT0S(uAW-Qdi$bpSq8dkDsfG}4gUA$$iw=; zU&{l>BNDx91>qmJVLa~|A@}PGzqJnSz0Sc0-2`v-1^8zP=pQ%)KQISBrTY?p@?7YU zqr@HD4ZX8HkT;1%UMm*<AUM?iBh)`|DQd zN1cam8;ktuJp6UjbE+f!{#Nv_h#z<F^!BQA?o*hoE=40e<^?Lhs*(K3Rqzn~m648HiocU-(^k5WRMqM+RzLsninv z$?3HBSO;IT7JRi^;7m*fXVN#~*sFD?M+$!T7e%j;=H)G$;0r$jXJ2LPCme(K84q8n z0^?P)Fn))tKMAYwV?G)><~aJvpV52T4S6X&=gB3&>3tV@n`h8{#?WldZ{3xDXH`aC ze;)Ddx=p-8p2D|GgKyFt+-S}J^S;qvSABmw%7at<9(oV7?#~cEr#%+_O#Bt*Qah*Jk|EcZK-z%K{Uy*MO$3A~?sG~3RDPb6dkHju1 z0sSQ99Wz(M*Nmedw>D#Ns|U1gapEx5eq;A<^bS=gu9Qr0V<)3`OW$)Zf9y|c{V<)6 z-f)P)XywdZ?T1b?7Kz3yKV)ii}Ifo zH}vA(K-0>i_cafGl=7l&&5%cHKhrdgIL@C&KG6?95wg3caj&XzE|%!cpw@2&$ zxa#10W+~os=!Yn;+L-LG@x#>PtWDeSn!(k!EW&&=rw!j)wbA~pGWVm3-Q+3 zjlAe0=+-CrdHV;uoAc1KUPgPzBhXmo^>KQyzV1MNo(~s97&>DTv`&f?l zwbK8r`pqnR;)>5t9FOhM+dmJxp8>@2TkEv(Y1;4I!|rE8+Ot(}dZ2tG+z9)+Y2bD^ zf&KwITXP9Z8EMkt{!_VLh9STkdt-tv`!G{Hd zbNMm)v2UTf8iKp72K4qL^ln@t-g*_Fr!>xw^gUd!ivHvc=m*up{~N_uR&}K=hp^8- zi8!vEME?+a4u9eg$wwYW_Z}{l+*;{G5A;U3LxlPO3|^oQT~G3;eFQM*j|KUr|GO<+*mm zvwi^a^ll4pTmiaK^JZW?__1Z6+qKW^z6U=$lhD7l6F;-ekax2|KS1l^9qnHu;?diC z3cXADvCry4yn)M+f6{!``4IgqoP*ujBk+EzQyDv>UrTwZ^EKM@wB8u%yErjLacVyN z98P?TzaS6033aGX96gMokF-DAae;O-?Kk2y-x)kXp7#RUO?C9!4#e@{8{_M&`K*K| z@h+Z-{=YcdpDMp~EI?dguJrf&CfbXZ()bucUq8ow`cK*;Zh`A!h<#_(iT8Ct?{6gS zQ$w+D{R_P(Er>Hy^WR|Yb5DOmZ_iTNmrTa~&ounC+dzAS@(fGm1^e_}53~n=oazYU zRPQ)n1{|lQ#C6e-em+&*U|nVSuU6o_B%QUuvQ&qk^1qY zJpO-{B;Hunv-Gi2Hp9;@z_m`=5WXTdeUaZHe5p zE;wPD$Gd2Ku|1Fdq~YMXe1~4qK5w(?FW>SZ-}jXGx)!1zM%R#!P`^#Jey8q5Z@bPV zh7CjSgzC?aYQuNi1}&F?{)7MW$REU&)&@G}Bkc!^(Z2#$v1_gG_TPNssjqXly?UOf zW}!Dt-}#KI;N(q%9!X|=-p|2LNGI^~sjjhFb=D)E;9Ips@8@}N>ucW_uKd`047iE= z(0ijiF#a)q?3#hIMD?JjO~6?eMf*^#E9H~H8S#?m_GK-0{_BZv*gWi(JV9@d=F5Nj zzJ91)S;H6H^^VweQvEo83-}YNA4e%~UG|l@8}x$yn}FX&+V76jy1J$8>y^<+> z>vQ<)q5b2B+VGQIpnJ6MIQic>sOAT|T>S0TzN+mg^f%7||G-(=3#(pyR?pKo1bGpi zi-lPdM~2?#O?|;>_k(fT-iz@Z9F1Ldy+=2SBHz6O{pTm~`*kJq+t=Z*76QMB@}r^p zo;s<%xM%`?d{nO*UI{(_za)H(D%%`@jV;jec?a3?r`_x&UO$6f^Y zUNzz`^$VN>s?%82roDYZaC+*y=)WEuFRd$ueu8h=82RP^^vf56ngl~vtKL3H_5HdB z@SATe_N_X~UinbWSE3xb|PwZ{UC9724xB{s`_gBGR zul?3wod*nh!?=Vg-wu5X-(U0bY~_iaY7x)!Wc<$2`EB%ka9gya|Ibyg8NCL+dr9oF z)o&~9M|Yh=u45mAVQauS=LQ{;OC0Mv;jhOw(MaeAZ`yt8)6d6k==a)#@JV0s-&1wg zTbq$5xM4q3dFGvX#i8%JRBhUSIzzj3rrp^HylPAFdt?ypBXwSL(2Tg>C{MetdAF$Y zjrCLU@3$8FHz&Xwt^L(lC)&NWPj~1FZ=-#}R8#QxjDV`VXfQbg-ftao9@DzG{J-_v zfH=2?Fg}hN2lwLmpA&@LFzqKh`ry}I=ULlx(6iM!-6pN$5f89yqJ3Ne8}zE%;m`RO z?JZO{Te=?Hd8&(?zehY3_G9N+8~rcJugw(q8@+!!^uai{0moST_}yc`x!oUHL;KWX z%9|tg-uj)#kKZF`6Wzz@at6HEhS=w7oe6sipI`HI1??M}oJK#!hv(>`_ixZ|o`b$KO%gOpzs*M2Hkb%~BZKbw2OTWEjoqCBI$C3cNeCwJC4b(j9c>mI?lS5@7%ke>TQ zYw+G^-;_`UKTYQ%-xmb#x}Vt3zYL$(6S_osM3l~hR}8~`g3c8TiqqenbCDn22ktDL z-@EIcN-y9IZahP8%rOL`3K0J;SLk1zQ;yUAqsd+LOCDkz{mk&UNOgjvnrKSq;@4Sq zWA7;JHqD?Pt_|?#t^K&85AymtceK@dVxsfVGgtAK90%^|((oG_!Dq&U|KS+?ss_aM zQqOya7U;gZCsS$>dL5&PV_`vfo5REru6j_czMFp;=v5kk-{HH#U!(ne$GMExvJvRb zy-#~1y)SOd;D?QajvIl$%eUdPm7m_OjQ`=z;CcGeuZLO}T6ag^ZW?|fM}y;X89Rr8 z@K*<7H%@uo-$ulJ@4tJ4-O>A^ad)^t`vIM2P1uE>NMHQ)Zwa1}>Ka}j(O**=`4P<< zF}i;-S?6HibgtRv0sT3v@9^JF@Jk;dj%!tEZ>jU39v|U{cBfyxw4P^uz@O!t>}n{_F0K8Yp%ZrbKY?TVg7Iru6gsj7@@G27oI3@auF=S!)JD%|0XY7u z&pgt;@K-(bk5)v_Q~7S^>BRLYhB#yDLks+c#{UI>a8am>^8RV6$DI6#eY&3Kc2o4C zk0Sr5dVBth@X0pN1NqsPxau5muI?ut>&J6Fq557#arC>MreB%8iK~M0|HvHVAA-F5l;c-`wx}x{CoYF&uaIdnpK{97uox7GVI(1`eroxxeF z_cYs@{$&@2PF3A@T5HhTfqcw*tUl(E^-5sy|HE{{3-Z`Z2p7 zcrTTgSJ63?!E5^8XEXK>OMx3P0KXGehr6x&PjB?SP5y&k>uTuzxDI|5<@Zk7_YF`! z+FkcaM(rbB-)ZQ5iZ~L}!SizhuaokaLdt`O=-juT>IZcd&pUnJ?{#jZ>DS{&P|ElMjGbqXgq`-xRt@b-c}f#Ia`x{xWs`^j7XkV-Mf0**$0S(dnltCP=lt=AVT#gg5Tc&z>C*{SrH4p3=OaF)2 zVgF0}q085>8(Rf@vmn~5t3Nw6Kg`y7%NLzH^gPJ8n!FOO_7`T+;Js9S9;x{z{4V|9 zz6|<#7Ji0%^4t!oesDzlnDu7p_0#*lEf3!42!2hc!TVbh_idd&8^+T9vKn#i(z*Hu zt%uE3*PNof`NmD+ebo=VPFioKtNs$F{hQr<;x(E`yyt`Po1^oW_nMFFGV$-He7(HZ z%^wNK!*ma#x8k{ffjAp=1FyLDDe-sEe>e%bpD%uMyAW>&Gve9R4!yUx(EF%5+Vz&` z?^{g2%qC$sPxlokTtS|!e5#n%Q)_o{-am%^)c4^$3;XqR@ar%LntT@j1$C}cC;__* zXYpV5IQ{E43B5wSp?Nw-tGNZeXq_WJ*81V5ar_a7-=7t*3(o;RVg`1u%Ja_;#ZOuR z`ZZ1Uyf<2(wrD?f-HP@`Dd5h!j$OV7^k-mS+6|Q7n!HDT#s$B2iL?*W{?fKL?WNZf z-*xQ|QoDiwOZj2UO8hKRUg0nYoEN%ZwY?_oO}9dwr_-HXcXA1I`!Sri@@}8;sZq~XX-*^c8tGeG%vo&@#tAaCs zKl~`YKeei27dI7ovlQ%CE6+Blgxpc*R%J9#7u9<)*cRLqiO_rh=+9G~ySLN0`9f2lmc zSMR~o_vpEM(0*t$`X#mAmyII6c#T`2Bk}ZC-f~0r3@7DxPqdGYM$KTd*27~@z}Yc? z@hqnCt*v>Xg67A4b@1O^?`v(%-)EE$RnvPhd_LpQQuliv?;-w#{`6;p&JAp|?%ONh zD6G0)L^u@U1? zLEq0Zogd9>Onlx0X}_ZLlih>qfAej`x%MkKXKvuPzUBo(&EI#r(q7sd8dV0ppljfa zIso5m1#yP0#cwOsDV*jaZ}Sv?qd&lRxrbgO?N18t20z@J_8K4HOZ31`_+#jk2>cba zfwtCq__7vw-<7}59YOogR^Tisi~s8v;kRoZ>hA&W*9z!&KEQZQ$%HR)51OmIBz`FR zca}j@?7?ka6253p^u0eoADYm9T=m|e`d}vLK1LzwwK z+G_OE?$AEeoc1yLZiady->UNi%P8V#w3X+RsC!zqmx9wl`-Vr?&@)iJ-M<(8Yt|n8 zr5&K9HJ{Y#hy54bM>*>R{>E7JoHU*%&VloCAkKgR9|VN=k!|hkWUWJzt|=GRD1_-{Dn9TgOK|sftR6u+>~|1;n5zw zb5GHmt$M~j?Z2jIJvgrSYQ64zOjEtmU^xDwv!R`o&z4Z#*sVT(k{9A^8;U5bcLcXuoz# z=bF{R!R@a5Nxr(T*0?YJL$$6R>I%;O@AzMQgMO7?1K&;G|2fsu@26m2Pv?NyS;R9_ z{R-4PeRM4SKQkDdo!U2i@F1>XnoknSVDHlyzwN8R`)a=wtod$m3FIB7fY(WSMdOLT z%s=F|y0=z&)pWZcTUet+eiqyMtceP0*jS!7r?HHp}7I2bn-u+YoQmI`o6qq5r!k z{a&d&aHabBSnu`Hf9UVm?_M70JsS}~+>Y8G4fF+PRsrM&TF*YJp5)t^I10X_y`z5r z@^u6JFuE(^`bI^OVRlhrN(mrmKIXLI$;J4Cj@Y1J% zb6xZ8-!=H}6a%fI=QBciPR3&FE7%d=itpfNYkY1fk7-wxb_3N39;hyMK=l<{tz%Yo z@w2-y{pw^wT+y$w@7o^yE1HK4v`)8eMElAh;^|{WKaN}jXYXBblQ+@6WGM2?6VQ!1 zFTJ62zsBlMt);ZPrQvsx?rW@-zs%mqpZ!KJLgP1F^Ts*VlT^+%XtISk%#w+t#R=$% zZ2CE`iJqe!@*=OH)@`A&Goi!%@i#9LyZ#&D2NuEp%x~!3E$BOGA3gF4dQo2)uQyq= z|Jg@et_`8}lA%|$ZyUb=K11h=yR?q{Qe9(C(>VsHc&@T^!IL~ zKjW0gjnY2kv+Cq?Uw~6n_3*%5jMJJx>_*lBr`!f`FILrf-+->J4t0Nl-A%1$6Y3$i z-G|)eApI|s4o<`E(83n9Pu_=qU>^N3(mlW^)m>e+ub-!L2d8q_o!5P-h01$QE8otn z0bU243pG)l^_dZN#k`5fb0_{HcBAh%5BgU7vf?Xf|EYPWRRDIwZ5W?}nqO8ZKY6Hm z zUub>e`Oy(R#tS}7=jIpkk|j$XrGP{$(ZUCtoRb+^%< zbCdUJMjG;+$>=3|!B?z=-xeLA1C>Wucw)coF!t@b(eAAGX@eX6D4=~-?BP060se}mLOU8F4?CcEn?h$@z|KVT%ZPK}msNf4y!JzTbU5vdB#+&pR=>EFQdBC_fgor4FIQr?r~N9#JJ7X`GKkG0q?Ya ze;P^q)Uw3?UgxtTF2Fl^(w;m4KB+qR=U3qW{W;oKJ)pgC8{&RB4!tM(9dZfPb*`!Y zx1lz6^BWMiSseY`veRS@(=8tpUG|&R-{~EZx;9I{ zyFaKrEaM<{18l*|)i}izMP6Y!cy@!p*^>*6(fegp2EDn;OM|+ge^=l0(tM1=+77aQ+4?pivHRB^mk1NbaM=H zr@z>{%|veW5_(AaZ-~~7kq78Uu@|y$ivJY@pe6_KS4(yBmOz~4d^TZbIXMI(FsaO`h{!6g?6$QUd^_U~dAMT0oJs-UuHK4Qf zeeTkFdsTJO0h$L7YM)$J`M2c_;(aBY;o4{UXdSw!b*-K1@}^q9>*zUTDW9vjg?`=F z_g+BnQ)T5dTUEz0jKW{OZ;a0h)v?E%C;n&QP+#RYTc)G`R{j!|hwV~5Ib3y?pDB#f z^)cX-mg&;9P!>zno9-i2Yuku3E)5XTwV z4L{2`l~2O{SQ!3$Yu{$7b<$M#?J8j`nHF_Z?I>?D`k^lfLL*SN$*Y9rMLdy+7v4--H>>`(=Z>RTUx4wra|7hfh(;aAW#dB>X`kl8R4;saLeIp#ZjAe}H!a?ZeeL=oz2mX935?7Z1+Mkt% z@1b+eb*bp(D30Ibw;8DV-Kuc>#<|jdtq%Ro zXAPaI`LSz1@Ed9#YOC{rf-jLz*ZGT8G<>k~*PiR?XGvS)zazg5FCx!V9zFLl{XCO} zJZUca&8`z)ANgtK0{$cAgO$4~uEOZu*ZwV3e@7+20{II|sQWbfHB#$@Q48cwx?hs0 z`KX00@q7qE|EmptZkQ8anOtZq?>;NV^?J=cE;z4 z@0jjOmM^6Eg3zxt9=(67h;K|faV*hy7_0F!zXXn(G4@#j_-Ppf{~(F>`**;5z74#G z+F#B8iGHhO^bV`Qd0F{UJ}+K98@UzwtH+$#;eQ04zdj_BLBL+%m?Jyace zcXRmK=ZUA9?oX9kLjR+-6IZa_<2k+HqdPGUKW<@n%@o>O`}j8c9&c(N=^?(d@&#$EeNVP1U@c{{r$K_lR$#5%?vmBk$dj_(rM@c|zv}tsgVKCzW4y9*CV)U+_2T z`ByB8d`esNYv{eJ{~LepG(YcAJoJeS_{5?dt~42km3i{b+AF8T~P3@EgAi zIp2TK*bzsOl^4mA`yb9+1xuyYY3wS^E+F zmtjy7Z~UjVC!UTe@SioG=j34*J%+fh`oMdfz`m05xvrWQCusheXvBJ7B>{b-Oz@XG zFdpZt5SN*#zZ-a~v>*5ROMA9{KUG!vvc2j_4Hlsv^oqDzXg!|ij-TUNN6hVMKc;!z zVk!Rp<`Gv5)o;EjuR5)L)uwE4T0O_l5Zw=JJp;Tl-=VWr-y5dy)#eLvS4jikehT(A zDx*I=k9O;GP^a~bcRlS7(v`>Th{Ha(G;w5=h0m4$@@45q`OnaW55Y@tLGQ2jdn10q zPsxv-w{ZG<5SP8qC*SM5b4LN5+c4cT%9%oZ6*V80(>;r#3HV$5miQ{x1;3BxuW72| zb=L1zHfz35-@-V|U5kD_)v=6hiRY2lHv_#-xsDp|Cg?jUPcSvY|8mtU3alW`FG1i; z>JNXbAa?z(G7j%9!0!sD-Ec1P8y&~)Q!V5RGSGj%0r`k1w^Cj2#Sq%ZWe`tT z9cb0N*xRjx572qXvlZx@A~x8ld|^@u{oHhe_SITPwzeYPfabK<(>$^zf;jeSeQWca z_)I&ZU-T6EiCXux> zsO!EkHcwRF~}@hQF)9;9csE{sKLxfT`%8QN6s{LiG0jMczJ>c@pbOIM(0&w=~067;dYD`Txk6FnJ^>+R9+vIgEt=cYT9F9zzox$92+ z9Ct#0u+GswtRS8ojbDm>|FrW9`sqDr->Y??S}uHJ)$?0xysPMUx101GTWbD(sQpoY zXg^s=`ENbdqn1ts*IWDS<|DA{Ssb~)&SBc!Bpz1-{BKh|dt^V2V?Fc( zF2S2IrAvvAg^a{gj^Qg}i`I(|yZbI#+dZXZ$`jryu+EJHL_I7tJ_HyOs9IeU^h$ zA`W`582D9YVDF^!l6t}Pt93)9; zd~k0eatqZ5+Sg(ntTax!nvctBU%I*{<6@)zL5e5w)Kh*uZW8eZ>-=uTP1=oIkbl#@ ztjHDOINuC8|BYN+J8H(MDN8S+N-L5wcil@Z(+n`rFnSP4&vxD8XB&=zgiu|`3-+14T3N^o8JcJVC#9D-S=c{r1Q>RYb@V@367Rfm(5n&9W>bjoR!8VA)wO+9|D7y&Kw&t6Hd%^2!h5Y(^{OoeX zuBh(ASafF`-fG?PRec~;ey8gkGwB0%`%8fPuQ7DI>X5^$f>VAu@fca+*FpQW<(fa% zw55MNbk5tXBRJd5pqo`!O4ht!-j%qU8h~3#=PS3gUynWsp6d^2$S(ZeRQ|f61pMTu zv=7$zVyJi%BJf)=1V6c(=tq_D@GG`rze?||gX*Ei+OM2aeqgBcvyG~A_A8G+^MT+b z>HKb=_7e+LU;OkL{M-J-;WHOIg9g~yI3aKL6Pl9``JNFxj|KS|motyRiP!rT8$&+^ zOvLVh*2e*7;LQqwvr+SPS&e%StwW2A&`VOi=j$K*q$eTYH3R!#TlllOrxIiXA8bQE zo~d3nLhHnpMA}y@g$~Y7KZf2?zp7#P!=L_mYFu~gUQs`NuN!95zV0yn4A6Oki|+M) z>jJJt5Ag0s!?#?Eex~vtAJxBo#?t;_8@Lv&h_9pe<1g;QkI;H@I+}P>l+SO7#6Ei! zjPu}j-ay=2HJ_cIJRNnbD!FF#Yd(SH8}{n~dFez`x-#Xxnh)fd6<`knSs z=ENPSe5JeAt2l4sn=uyq3#y|#S)jk?GkyxKBhDO+L$>N7hw|a)^b)=MvEWDRo`%DC{3IO0uB7sIW7W~_ZNh%G_9dUqh`XH5Uk94v$6a|) zvd#e--9#@``Yu86Ro0?^MfXqQlm}Z?#81au^orOM?|ju$ef^m`30q2I#{83yiAtruPXp}$G_XwxkGXKV%kb0##a0Cpi$Y40(TIKIel=>TvV zXnz{_1;2$FFs>1LFV5E$KhB~8Yz;&%L0(YZveGsw&LMz68pPNJf z8rvezlm88!kZ1NIu5mi2dT$BNPSw@!?1Z0P2!DT-@ANu{eAE&8^G^GRk0tPHR~CPP zmC-BWie5+I%vK$5rVaXawQv7!g5IJ8sGHt%^L>iS8xXYe1GBp zZV~!-_#o{Qy^v>q!|&9+=x6&tJw~DT{v_?i!jO+o!tUgK_}iMl4*US$R`2zAH}n?Q zg*2_>Y;#hGTyTFd{-L1g) z(tCHs40&%${8^lU4r#$S7f^rOgdz96jNDxN%!Zl=SL=CZYToXldk156zhcoX?8lYH zzLM$zZTb@b%$LYl`Vp_U_8C5%c@9rif6J#l*Kt001qx%|^)~(3;sEct8k}bu|GqkZ zzo>Y}>0YarYl8>f(T`L<(NA^2X&o7_%>Cd#ZV&HW1OJco9h7v0AEf((qeMp32SzzhBq6T;*zvQ;}n|54EG;k%f>~?E$|`^Y>DH zU#AO!J1Gc%tu8^|s$Tg=>!+RSrf!wc9~c6Cs`<9SH~bV>L4O1L(LTb2eoYL*{{+=T zT~DK*R2aFf>K~;p6MxNB*p1V=VmTiDR(Z(p>iz2&j-QG;|7h!v|GdrURhNA;<>MwT z@YhcFq2gwv-(KH&R$J^+`x8f=@}ex&dy`dnZ>8_Pv+A+cwNCkHo}JSKKN+f5b@Rec zV!T|KQdx8{NAp+Lk?<}rus^7L_pRz} z=EmTZ+fKV*Mfh8{@!Li3vqyXIw|mm=+=#f>YQ445yyB|*z}||qTlwO@rSjW`Pw~@w zI5>g+;8xIn>Ddpt3$WANKsqZhLpzcH%+)?G%N+m!bos)?U8)n~%8iOWgP zC+`e6eI}yUI!6At<3IN!G)48Ln;XH;myG<^YiQbi;#w9?yWb?_^-3WhqVLYL0{D4t zkeAVS(Nlih^}RZ*qF*Is2dba6*Ex!F1^mY7`K?y{x3A9AQg#2Ml+F#6 zei%e+AGle5y6g9dF8T4Z(wKPvY=gfd`wCi@o9cUriDX<~Pa$r9)j2AbN4`kUapQi* z*-H6mP4%m~5%|}$X5hN58AK1Yvm)xND}TR?p|rVeB(>9oaxFOoF_tg4n zr1{HA=T2G5H^1o|pqJ|G%`}e%cftSq=J;=*dsnfy;H@q}2Zlg5{zSi33Hesi%d z^5qMmZdzAL>0IEQ@Y<-(ouhNIq%?30zteB8iTG(B%sAOKfNv`NWYx`$x**STWqeBN z{!G_x@L%Tg9k{SfUF?&zLENN?nIRF5jE^*GOg zIBlMRTVHiiGo53;-iuxSJ^1VL68%-$XAONy`+U7OqbD*BPiui^rROuGDDsO@^t;VI z+BYPCYo&c!gzjw&);U(}TJYaqK(CnA$FQ#89MyfRnv1|Ybq%@OPW0QUj@ME7Sh_cQ zgH%UP(R=;R1V0Y?4q8s2pOf_bQ*{rgiPni1dLNy~;%`F&v}a@9pX#cIRhkN)r2Wi= z-}twGjee<8#OZSyd0p-2m#O~uM)iceQRp|(zS8Oh@vYYLPrM7ixF32gJ)l$1L#y}4 z&kN1}S@+O)youjAAK_=-K<~*C;tm+ZbFey-~G&D!B-Zb|f7RV6M1cjB#^54**x>sXeCub_Ki z?}hu@2fOt;7rdwY9NVjdzv>3~t5kH8~vX4lbUx6 z_rUJSL)yPzqOSD@MDVL?|N7}W_IvgHd7h))YZ~}Bm0v6hfS*yA z@eV2v?t(7J*B8R?pD^T?pTVc$Lu1G`d zcWt0Q4+h|GwZ_NX1U~*9^qao_e7@kDbU}XOB>hiUzC20!xyw}Kzg5TId=5Kv?dQ|2 z@xNa4OT}5}mmL9aYbB1^jp*;aPuO3dOZ!c&FIPN>KU(|oKGC!Al%YoJXvQyI>ADm+GVElnc(%O2|*@UPhq4GmqieUDS9)96`@a z=b7tNziwBExDTm*l4K75;UoAxASbp`GTqH zNC`R*IH2F_r~k$->OS!-&^%Duf_~jp9llO$+J~LMZ*E=2=d|{>&o!U4QQkM_2kq`! zH-D=hzPK&#!^0fDc&+E{<+rTzim{rPpUuJV{6oYQqxmBJ0rJ{9Pr1^P{>*)c z|CjoX%guwY*8;ykB8cPlXYl%tLvC3J>JdwOedS+wHLs`NVI0<}Zs%oyz27JNZq@p5 z&=h%(S;+r22hT|F^V3trbI~8YCl2`C&>K1~4|?D${=BrmX`uJJMp6157zpn4;ouz5 z{&=gYYS{w2IZzMvvFnf~=^3)c@wL-s->8CvHrN;Z;aN2JvuWIv(ajA0v`~^Cvukp zMdHpbh@X;?@Dm(~FZ&+-K3@jvr}uBeDfD_>2XF0p^rxuqaIZ0V4?aP2wO^>9`0i^z z^e7a&2AUVlwEvvg3V&`vw3n@mpVST-=Um!5b^$y18Q3j4gK;_Q+1w^W060!hW1E+mQwz) zX#{+)!>by_#65qYeUagq95~T zF)j(m7^mH5i9_2!g9*Cl;=c|3R-1^Ujrx(O?=ovV^5Pw#?@B{kY5mVk7L9@<~7RJ`wP=y%iJ;B{;V zy*-;awy3_)RQ2?#nkVeO)80z^ly-Z-8S@GIUz)%79YSxK?!}zax$*)#^wvy(AZeUC0upE<$5o+={`u0MvT)M<;(WU3*2jA9~RCy?4Czl4Ylt% zlYrf_b92dsl~wO;7l6KfIPFEH=PCbXT#)-2<9~p@=b6vx$AQDN zH`opxqJ7|<=HPzOc}tPCjMK+O(8s!0`&{{7sY}FLL+9G(hJtsg3Vz;a!e9SO|4mgN zDldK46ylp%3!M5L;4kSu(G1-uGgkikM)O33>e7D;fjfO7c7@yG_rAWX-GkuI6b8S$ z4^-|D!ceCms==?&sNRe{)y+iDb=l&YE{-x#P#^p`O=VXn@vj zAJr>twU2k{hyLHQ=%ux#-_{cuw>W$FpysqUQ(iVub+m{-$Q^q!E;}`TZB$d27*N`cW|v zy9LSz(>2c&U60*)Gicxj^olgZZl&(|e;z>`PsY*@%hl+aZ-H-d4Zmahz}r@)z1>@A zmiCFAvca*ufZp^A_{m%b?Ww$Hs?Ir91c7_50qvdiyV-Xo>33o6$7<``vE~eL$3KTA zs}5nP`f)?;*B8{Fzrhv3@zg$GvJL)DCK2a(-CG!Vkbcx$OB{YZX83=qhd66L`0XnG=j|q5N1bE&E&_k88@N9D z9!{hakEQD9e@@chT79vfAB?`=0dV)1fX3)PM38=$7NPHXg$Z`m-N2oz_4ljJH{K{; z?xQ+ZvevDuaoCk93Z1u+cn9Ya&kAe&hN*s5MBiVgEBZH!Lr3ZRzOLuvT9G*Z>iu1$ zxPI$iXF1I;8OmSp?nQr}&H;};)3}#`Cf_Em?yrd_pB-}3O^nmqoy0p*`$G?BcyrY) znyiI?GYtDlkBHk!`P;JY3|uft6Eqq@g1Vl(>x%#a^bJ>d9x?cJZtQ2|dH>yG)_sguT2~4xpBYmI z{Zl$GYJ8A>mDT>L%Tn6s2Y_dMhJJj#gM9WL^rv5>{pv2-$7`K)8cSU5RX=^I^ZF0U zZ#@2B@70y(I>{5h;5BgG6oKwl{jcaV{2FRqbkw|7<_qI;Q0qm8zO&%<$a`r0aGy&& z9xuR|l>wdi06)g|#8Ju%yWaZ#Y(@~*;~KP|Y!5$Q_nAY-Vt?g1c!}L;Kdt*C9@@uV zQk{F&e&YC76a7L@!41`UQ`73$Cr?4|Y#GLP^LF%&pFp3bq35shY@z)~W##Qgs&`$S zMSM$)&~K@G_2ca6=hoKX&FoJ5q*eGml8E2pBjG=5KK`uve{oIZf0CfJkKxDbAM~`= z&%`?Lsk&D&~oto1f^0s4is?{9Gs{ju`1Y6JLoC9&(Fx=60}1(TFVAJE@(EK?8rvz75@Xo=l5 zonKgJKYw5Qr?!{SbKF84X{!5lQNDCX?YA{wth5DhQ5etVte$tCe%}(I-wCwWJ+PKt z!QJ+o@$1$Vx=MAIOyvVHns4kC=fN7p^}I0sxuV|{K77u2?AP~XsPFTle(!Zt=W|O| z5NGWa^xaB>4Z)L522HJNltdF0}aPS{XFIn&ZbLFMW7ohjM8G4u8h-=s!=$RX|Km3HBYg!)z znjtTx`fheJ;;LSgek{=b;%R>Deq2KCV@%v#CMo^^?8d0xXZZ`>ZzlRyTIUKVKOCdq zgPvBNcSQc&WnW44r0c3X=2P9c_ZAIS%WTFmKr>Ht|Fp#ZQvnvqDSY{WH`srS{etq4p@Hai);;N74`~0S{KQ3hW7I4B803OyqjmnNA^OhU>G$Iu=v6m|n(4jR zora&ws(VBlqQ9a7cv)3wukDWAZ`D!W&7_~RwQnot!Fc!5_~l9Or|M0v%J&DA0ynZ2 zc=c81jL5}rY9zQ39>gD~dB{!U-P{?yr*=>;?LWq}0XI?gn8ljsa$LX*DNKA1bzZQ@ z2l)e?yF?AApPkBq^E`_9+^)lxL zevasSP13!uxz5(6eQJ(Wp_0?$Yf4?a%i*DF$&mg|wH#`>uou}Kz(7wfxxGrhGx_BA#wyHmb zAI0DI?u_r3Kk)f=|L%wOHPbcUymZID;Bs)AkJbD27ykt}L-#AM8LfG~pYqCq`tEB! zz+blm;FQq4k}f)bFwnf%mu7_@PUpO?%G>6dp}*q} z@y6?%@UY?@wjcYUIZzu5aGo`X_sAoVL6aEo+l|31ZN+%ZutC4$clgDX;0>3d|MDz+ z&_eh?eMg3uz%7%9pIFuFLiU4yYbti76!+A{$n%wi&d_=msyf+Ft=lh7f%mry_$#!} zGuFNP_1Y(So1nK^bb!{oIOTgI`{L)l;-6&;-q9-9Jyl(!k27&r*84a_c};jK<2|$y z?RPX^oOWQGOq{^qJ{#P5sy93;fV_|D(2;qJTagjSzo@QNQF+mx3*ZMkfjcl5zt)L1Pc z)zNb*tNPf29_XhoLvM`(dJA+8n$r}2Z=LXO&>#Jj6#Cz{3I6jmZk=`S_)iXczW2a; zrn=7|fBd{%h22N3i%VOe=UEWkH%;)jQu&`@G32WzfID9AL9F83h}dA7@}peUDduUM zjU2JJUW5OXFW?tHgWnCC;A8BFYp~9vOuXP1f(bw12;&b$MMe{PjyMO;<4 z;s2n%yVc6Kmg{|Zd602wHW|8YBJ{@*@N5@hf8GM#{|A1HX#e{>4}PiU=Q^5aKg=So zQ-h!(T3=IC4>;}y-j6A?AF2)Sb^(7~Bca3gG9Grt=udm?Yo8<{_tNiEO06P}m#eUw zd=I?+o3Lx3bD*DD@O`y^?C@V5Pj#I<&FkadXsl?Sx_t6&WJO8G2XT9<+bKR@irhMF5{dc$mu3HoO8QhHiC04+3VN>`{ zI%jO)hy087i6vTN=Y9zJx=`o?-FIJZPJFXvccTaXu8%^V^b`9AU+^

    J3m=v7IF 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 literal 0 HcmV?d00001 diff --git a/latch_cli/services/init/new_example_snakemake/data/samples/A.fastq b/latch_cli/services/init/new_example_snakemake/data/samples/A.fastq new file mode 100644 index 00000000..4686190e --- /dev/null +++ b/latch_cli/services/init/new_example_snakemake/data/samples/A.fastq @@ -0,0 +1,1000 @@ +@SRR800764.1 1/2 +CATCTTTGGAGTAACTATTATTTCGCCCCTTTTGTTTGCTGCATATCGCCCCGCTCTCTGCATACACGATTGGATAATGACCAAAGCAAGGTTTAATACGC ++ +;:8:DDDDH>F+AEHHGIGECHJGIEHDGHGIHIGIIJJDHGJJGGGEBEFFHG>H?HEFBDBCCCCBDDDDDCD>CACC@CCD@??CC??((49CA:@FF?AABDEF9AEFHHB:CD<BDFFFG)=CHHECA;CE5;B;DE<@;@;;=;?B=9AC(:@> +@SRR800764.3 3/2 +ATTACTCATCAAATCATGTACGAACTTCGATGGCAGTGAACCAGTTGGAGGGCCATTGCTGGTTTCAGGGCCGGAAAAAGTTGAAGGGGGGCGTCCGGTTA ++ +@@CFFFFDHHHHHIIIJJIAIHIJJJGJGFAHIIIJJJFEAH8BF@GGEHGGGGCHJJCHIIIBEE>?CHFFDD;=B?98:>C>CDC@05<&959@9>059 +@SRR800764.4 4/2 +TATAATATTTTTTATTTTTAATTTATAATATATAATAATAAATTATAAATAAATTTTAATTAAAAGTAGTATTAACATATTATAAATAGACAAAAGAGTCT ++ +<:+A:DADDAABH;CFEGH@BC,ABH>@HHCBBF9BFHI>CD@4CGCGGGH<4DBFG49BF??DGC3==FGGGA4CGCE4CG>DGCD>??EF>@BDB#### +@SRR800764.5 5/2 +TATATATAAGTATCCATTTCCATATAATCTTTTAATAAATATTAATAAATATTAAAAAAATAATATTATAATATTTTAGTATATAATTCAATAAAATTCAT ++ +@C@FFFFFHHFHHIJJJJJJJJJJJJIJJIIIIIJJJIIJIJJIJJJJJIIJJJJJJJJJJGJJIIJIIGIJIJJJIIJHIIGHHGHHFBDDFFFDFEEEC +@SRR800764.6 6/2 +AAATTGAAAAATCATAAATTAAAAAAAAAAATCAATTGAATTTTTTTTTTTCATGATTACGTTTTGACATTTTTCCTTTTTTTTTCTCTTATTACGATTTC ++ +CCCFFFFFHHHHFGHGIIJIJFIJJJJJGG<2)=3B@9C)=DGGIHDDDD@((9:(::(3(8??<8+44>ADDA9(:>CCDDDD################# +@SRR800764.7 7/2 +TCATGCGAAAAATGGATTGTACACAGATATTAGTCCCACCAGCTCCAACGGAAGAAGATGTTATGAAGCTCGTAAGCGGCGTTACCCAATTCCTTACTTTA ++ +@;@DF+0+@@?C:AB<++2222A+<3*11?C**1:???D:BG2DHC9B;(77;ACF############################################# +@SRR800764.8 8/2 +TACTCATTCCTAGCCTGAAAATCAAAAAGCTTGGCATAAGGGGTATGTACATAGTCTTCATGAAAGAAATGGAAAATTTTTTCAAGGGATGGCTTCACGGT ++ +@@@FFDDDHHAFDEHEECGEFHGHHGGIGGHBHFBGHHIIIHD)?BDDFB9B@CHGIGGIIJBFHFH;@CGEEE;=AA:@CCEEC;A@BC=??CD?:((9B +@SRR800764.9 9/2 +GTTGTCATTGGAGTTGTAATAGTAATTTTTATCGGATTCATAATTATTAGAAACAGACGAAACGTGAAAAATCACAGCAAAAAGGGCTTTAGCCATGATAT ++ +??@DADBDHFHHFIJJGEJ9J?3CDECBEHGDBBF7)?E6ACFCCFFCE9A8?=1?5>>@@@55>C3@@ +@SRR800764.10 10/2 +ATTACGACAATTTCAGTTCGAAGTTGGAAGAGAGAATTTCGCCCTGATCCATGTTTCACTTGTGCCCGTCATTCATGGTGAACAGAAGACGAAACCCACCC ++ +@CCFFFDDHHFHGJGIHIGIDDHEHGHIJIJIJIJJIIJJJJJJHIBHHHHIJJJIGIJJJJEGHHGGDEDEDDEDC@>@CCDDDDCCCDDD9<@BBDDD5 +@SRR800764.11 11/2 +ACATACCTATCTTGGCAGAACAATTAGGTATGCAATTTTTTGACCAACAGTTAAGCGATTTATGTNTTTCATGGTTGTGGGATACTGTTTATTCTATCAGA ++ +CCCFFFFFHHHHGJJHGHHIJIJJJIIIBHHIIGIJJJJJJIJJJFIJIIJHIJJJJGIIJJJJE#-;BEDDEECCDDDDDGG?F>;;B>D8*9==>*9BGIJI*?F@GEBBB=CFGICGGG>;EGE>AECCHDD?DDFE@@CEE;>@CD +@SRR800764.17 17/2 +ATAATCGTTCGTTCTGTTGATTTGGCTACTTCTGGGGAAGTCTAAGGGGTGTTTCTGAACTCTTTTATTTTTCGTCACTTTGTAGTTATGTGCGCTAAATG ++ +??@DDD722+@?A:E+CB@,,<:+<+2A?19?FHGGB1?F9DF*BF?BD(-;().=@AHI).7=EE################################### +@SRR800764.18 18/2 +TAAACAAGCTGAGCATCTTGGATTTAGAGGATAATAAAATACCCAAAGAAGAGCTTGACCAAGTACAGAGTTATACTCCATTTCATACGGGCATCCCCAAA ++ +@@@DDDFDFHHHGHIEICGHID@HGIGIJJAHIJJGGCHEGIJJJJIJHJFFGIIIJJJJJJJGHGGIIGDHDHGHGHHFEFFBCF>CABDDDDDDDD9?< +@SRR800764.19 19/2 +AAATTTTCTATACTGTTGAACAAGATCTTGCGAAGAATCCTCTATAATCTTTTGAATCAACTCAGAAAGAGATCTTTCCAATTTATAAGTATTAAAAACAT ++ +@@@DFFDDHGHFDHHDGECCGGGCGADGHABF?FHEGGHACA<@9??BGE>>ACD?B@ +@SRR800764.20 20/2 +CGATGCTTGTTCATCATATTTTGTCAGACATTCTTCTTTTAGCTTCACTAGCTGAGATGTTAAAGATCCCAAGTTACCCTTTAAAGGAGCAATCGATTCAT ++ +@@;:??ADD:DCDDGHJIIAGICGGIGG=C@AHGAEE>;?E;B;?=>A@;;ACCDC +@SRR800764.21 21/2 +CTTGTCAATTTCACTTGACTGTTCTTCTAGTTTTGATGATTGTACGGCAGAGGGCGACATAACACNGTGGGGCAATGTCTTTCTAGTAGTTTTGATATGTT ++ +@B@FDDD?DBFBDBHHEGIGE?FFEEH@EE?AEBGBHGHGGGCIIHGJHHG=1?AFE>AECEHDF#,,(5=@B@?CD@D>@>@@CCD>C>@DABDCCDC@@ +@SRR800764.22 22/2 +AAAATACATATTTCATAGTCTTAACGCAAGCGATGAATTAACCCAAGTTAAACTTTTACGTTTAAGTGGTCCAATTGGGCCTTTCGCTCCTTTGGTTACTC ++ +@@@FFDDDHHHDDGIJJJCJHCHHFGIIIEGGIGIGIJJ############################################################## +@SRR800764.23 23/2 +TCCTTGTTATGATGGGTGAAAACGGTACCGGTAAGACCACTTTGATCAAATTACTAGCTGGTGCTTTGAAGCCAGATGAAGGACAAGATATTCCAAAATTG ++ +CCCFFFFFHHHHHJJJFHIHJJIJJHHJJJJGIJJJJJIJIJJJHIJJJJHIJJJJJJIJJHIFIHHHHHHHFFFBCECCEDBBDDDDDDEEEEECDDDD@ +@SRR800764.24 24/2 +AATCATATTGTTTGCCCATGGATACCAATCTTTTTAAAATTAACTCAATTGACGTACCCATCAGAATAAACTCAACTGAAGAGATTGAATATATCGAGTTG ++ +@CCFFFFFGGHGFIJIJGIJJIJJJIGIJJJIJJJGIIJHIIJJJIIGJIEHHGEFHIIGJJFGIJGIIGIIJIJHFH>ABDFBBBCEEDEEEE@@B?>CDCEDE@CDDDDBDCCDECDDC# +@SRR800764.28 28/2 +CTTGTTTATCCTAGTTTGGATGAGGATCCCTTTCTTGCTACGTTGTTTCACAAAAAAAAAAATAACAAAAAAAGACGGCTACGAATAGTAGGGTAAAGGAG ++ +@C@DDFFFHHHHFIICHIIGGJIEGGGECH@HCHIIEIJHCDBFFHHGHIIJJG@@@EEFCB;ADCD@ABDDD@?C9>B@030-+:>@?9>?C>C<8 +@SRR800764.29 29/2 +ACCAACGATATCTTGGAGTATATCAGAGAATTCCGTTTGATTATGGATGATATTTCTCAGAATTACAATGTCAACTTTCAAGATGCAGGGGTCAAAAGTGC ++ +@<=ADDBD+<<CCCH=D;)7)=>CAACE>BD);'9'9;>(;CCAC +@SRR800764.30 30/2 +TGAACGGTCAAAAGATTGTCGTTGTCAGAGCTGAAGCTTTGAACATTTCTGGTGAATTCTTCAGAAACAAGTTGAAGTACCACGACTTTTTGAGAAAGGCT ++ +?@B7DDF+BHGIHIIJJFEHIJEHECEC.;?7;?;3A9=ACDB??B>C#### +@SRR800764.31 31/2 +TGCTTTTGTTCTCGCTAGGCGAAAGCTCCCTAAAAATATCCGTAGAATTTCATATGACACAACCAGGCCTTGATGTAGACGTCAAACTACACATTTCTCAA ++ +CCCFFFFFHHHHFIJGIIIJJJJJ>DHGIJJJJJJJJJJJJIFCGHG>DHGGIIIJIJIJJHHHFFFFDECEEDDFCDEDDBBDBCCDDDDCCCA>CCDEC +@SRR800764.32 32/2 +ACCTCTCTTATATAGAATAAGAAGATCTGCATTTATTCTTGATTGACACTACAGTTCAACAATTAATTATCAACAGAATTAATTACCACCTATCGTTCACA ++ +@C@DFFFFHHHDHJIIJIIEHGIIIJICHHCHEHIGGIJIIIGHHIIGCFHHGIFEHIGIJIIIJJJGIIIGIIIGIIJIIIGHHEEAEEDEFFD@BCCCD +@SRR800764.33 33/2 +GTTGCAAATACAGCTATAATGGTTTGCTTCTGGTCCTCCAAGCAGGACATATGTTTCCTTGAAGTTCAGTTGCAGTAGTTGTGCACATGCAGTTTTTGTTT ++ +@BCFFFDDFHHFHIJJICCHJIBEHGIHHIIJJDFGHGGEHIJIIIJIJIIJIGIHHIIJIGHIFHGII@FHJEDC@D=CHEHECDFFFFED@CECDD;A5 +@SRR800764.34 34/2 +AAGAATCATTCCACGAGAAATTCGGTGACTCTAAGGCTCTTCAGCTATCACAAGTCATTAGATTCTGTAAATTAAATGCGTCATCGAATTCATCATCTTCG ++ +CCCFFFFFHHHGHJJIJIIJIIJJJAGEHGIJJJJIIJJJJJJJFHJJJJJIGIGHHIJJJGIIIJJJIIJJIGEFHGGFDFDDEEDDDDCCEECCDDDED +@SRR800764.35 35/2 +TTAAGAAGTTGATAATTTCCCGAATTTTGCATAATTTCTGTCACGTTAGCAAATAAATTTTCGACNTTTTCAGAATGAGGCAAAATAGATATGGAAATGTT ++ +;B?:?DEBHD,:A,<<2,,,>7)5AAE@;(5>@########### +@SRR800764.36 36/2 +GAGCAAGTGTGTTGATGTAGTATAGTAAGTCAAATCTAAATTTATATCCAACATATGACGCTAGANCAATCAACTTTTGCATTTAATGCACTTTCTCTTTG ++ +?BBAAAD=C=:DDFH@E:ID:@=?E)?=E;BD)7?C>C;;;ACDC;;A> +@SRR800764.37 37/2 +AAAAGAAGTAACGATTTACATATCCTCTATTCCCTTGCATTTACTCCGGGTCTTCGTCTTTACTGNTTGGTCTGGGTATTTCTAACATTCTAGTCCGAAGA ++ +@@@FFFFFDFFHHIJGIJIIHIIIJGIEIJJJJIJIJIHIJIIJGGFEGIFHCHII@CFHHGIGG#-;?H=@@>DE(6;@BDDDDCC@@C>ACCCDB@?B@ +@SRR800764.38 38/2 +GGAAATATGACCATAAAGAGGTCCTGGTATTGGTTGAATTTAATAATTTTGCGGAATGTTTCACTTGTGAACTTTAGATCATCAACAATTGGTAACGGAAT ++ +@CCFFFFFHHHHHJJJJJJJJ?FHIJJGIJJJIGHGIICFHIJJIJIJJJIIIIIJJJFHJJJIIIJGIIIHHHHGHFFFFFFFECEDEDDDDCDCDDDDD +@SRR800764.39 39/2 +ATAACAAGGGTCTGCAATGATCTTGGACTAAATAAAGGTGTCTTACAATCCCAAAGAGCTTGAATCATTCCTTTTATGAGCTAAATAGCACCGTTTGCACT ++ +@@?>C########## +@SRR800764.40 40/2 +TTTAATATAATAATAATAAGATAATTATCAATAAAAATTACATTTTGTAATTTTTACGTTATATANATAAATTAAGTATATATATAATTATAATATATAAA ++ +CCCFFFDFHHHHFJJJJJJJHJJJJJIJHJIJJJJJJJJGFHIIJJJHJJGIJJJJHIHIJJIJG#-BD99 +@SRR800764.42 42/2 +TTTCTTCCCCATGTTTTCCTAGCCTTCTATGCTCAACACTAGCAGATCAAGTTTCTCGATTACAAACTTGTTTCTCTGATACTCTACCTCTCTATGCTAAT ++ +CCCFFFFFHHHHHJIJJJJJIJJIJJJIJJJIJJJIJIIHIIIIGIJJFIFFHIJJJJGIIJIIIJIIEHDHIGIGHEHHGHDDFEDFEEEDEEDDDDACC +@SRR800764.43 43/2 +TGTTGCTGTCTCCTTAGAATGTGGAATAAATTAGCAGGCGTAGTTGGATAAACAACCTGGAAATTACAATCCTGATGTTGTCTCTGTAGCTTTTCTTCAGA ++ +@@?DDDFDHFFFBFH@GGGHGHGEDGHFGHII>HIC>FH2C;;CGAHHGCCEE=BDCC>DACCCA>@@@C>CC@CCC@@3 +@SRR800764.44 44/2 +TCCATGTCCATAAGGTCGAGTGCGTTAGATGCCGGTTGAGGTGGTGGAGGGGGAGGCAATGGCGGTTTTAGGTGTGGAGACTTGGGCTTTGGGGGCAGTGG ++ +@@@DDBDDFBFHHEH?B@)@3ACFAFCGDH?AFHGDGH>BB9?C-;5CFE'5=3;>??>3@:@>8?@<(2+:@>?((+94?9@@@##### +@SRR800764.45 45/2 +GAGAAGTAAGTGGGTAATGAAAATACTTCTGGAACGACAAAGTCATAACGTTACCAGATATGAGGCCTTGGTCCAACCCTGACAGCGAGGAAACTAGCACC ++ +?B@FFF=BFF=CDEFHGEIEIGFHHHJGHIJJJJJJGHGGEIFGGHEIIHGGIJJJJJIJJIGIJJGHEHHGFFFEFDDACCCDDDBBDDD@CCDDDDDDB +@SRR800764.46 46/2 +TTAATGTTCTTTCAAGTGATCTCCTCGCTTGATCAATCCTTCCTTTTTTAACCAGCCACCATGGAGACTCTGGTGCAAAAAAAATACCTACCGCCAAAGGA ++ +BCCFFFFFFDHGHJIJHIIGGGHIJJIJIIJIJJJIJJIJJFIIJIIJJIFGGGGIIJIJJIIFGIGHGHHFF@CEFEDEDDBD?CDDDDDBDBDBBCDC? +@SRR800764.47 47/2 +CAAATGGCTTAAGAGAAGAAAAATCGAGAAGTGCCTTAGAAAAAGAATTCGGTAAAGATATGAGGATAACAGCTGCAGACCATTTTGCCGTCGTCGACTTT ++ +B8@:+A;:+A++AA +@SRR800764.50 50/2 +TACTTATTATAGGCGGTTGTTATTAACAGCCAATCCAGACGCAGATATTTTTATACTAGGAGAAGATACAGCCATAATAAAGGTAAATATACAAAAAATAA ++ +C@CFFFFFHHHHHIJJGIIGIGJJJJJJJJJGJJJJIJJJIIJJIIIIIIHIHHHHHGEHFFFFEDEDEEDDDBDDDDEDCDD:@CCADFEDDDDD?@ACC +@SRR800764.51 51/2 +CAAGTCAGGAGTCGGCTCCGGCTATTCTGGGTTAGAATTTGACGATGAGGATAACAAATCTATCGACTCTGAATTCAGTGGAAGCGCTAGTCTTTCTCAAA ++ +##################################################################################################### +@SRR800764.52 52/2 +GAGTAATGTTCTTTGGCAAATTATGTATCATTGCAGAAGACATCCGCTTGCATTAGGCTTCAAATATGTCGAGAACTCCTCCCAATCGCACGAAAATGAAA ++ +?@@+BDADFAFHGIDGHEIFFHH@AFIGDADE>AHGH>>AAHCEB:BHIB=9?DFAGBGDEE@=BG@@CEH?G@:CAAABDCD9>@>A?=@D@B8@>44@: +@SRR800764.53 53/2 +ACCTCAGCTTTCTGTTGGGCAAAAGACCATTTAAGAATAAATCCTTCAAAGCGTTTAAACTCTGTAAAGCAGAGTTTCTCGATTTTTTGCCACAATATGAA ++ +@?BFBD>DHHHDH>HCBC@ +@SRR800764.54 54/2 +TATGCCATGTCCCGGGGACAGACGCTAACAATGAGGGTATGATCGCGGAAATAGATTGAACTGAAGTATTAGATGGCGCATCCTGCAATACAACAATATTT ++ +@BCFDFFDHHHHGIIJJBHAABDCCC>@ +@SRR800764.55 55/2 +ACTCCACCGAGCCGCAGTTCGATGGTCAAGGAAGCGCTGAACGTACTAGAACACTAACCAAGAGGNATAGCTTCAAGAGGACTAGAATACTGAAGGCTCGA ++ +CCCFFFFFHHHGHJJIIHIIJJIIJHIJJJJHIJJJJJJJJJJ@=CGGFHEHHFFFFFEEDEED?#,;?BDCDDACCCDDBBCCDCACDCDDC@C>ACBD5 +@SRR800764.56 56/2 +ATCCTGGTGGGCTTCAAAATATTGTGGCAGATTTGACCTTTATGCTTTTGGGCTGGCTTTTCAGGCTATTATGTTCTTCATTATCGGTGGTTTAGGATGTT ++ +CCCFFFFDHHHGGJJJJJJJIJJJIIJJIIAHIIIGHIIFIGGIIIJJIFGHGGEIIDIJIGGIIHFHHHGFF@DFFFCEDEDDCDD5?@88?CDD:AC:A +@SRR800764.57 57/2 +CATGCAAACATCTCGACTATTCTGGCGATAGCAGTACCAACAATCACCAGCACAAATTTTGTCACNTGTGCTTTGCTAGAGTTACTTCAGTACTAATTAGA ++ +CCCFFFFFHHHHHIJBHHJJIJJIIIIJIIJJGGHIJJJGGIJIIJIJIFBFHHJJJJIIJGIHH#-;@DFEDEEEEEDDD>ACDDCDBDCDDEEDCDEDC +@SRR800764.58 58/2 +TTTTTTTCCCTTCTGTTTGGTATCTGATAGCTCTAAACCAGATACAATCCTAATGAGAGGAGGGACTTTAGCCTTATCATCGCTATCGACACTATTTTCTT ++ +@<@DAADDHBHFBHEEDH@EGGIJEEBGHJGGHIGIIJGHAB?DBGCD>=7=FHACBACDDCDACBBD:AB5=@94>(4:CDDD +@SRR800764.59 59/2 +TCCTCTGCGCATGTATAGTTAAAAAATCGAAGAATTGGATGTAAATTGATAATTGGCCCGTTTTTAAAATGTCTCTCCCATGTACTCTAGAAATATATTCC ++ +CCCFFFFFHHHHHHJGIJJIJJJJIJJIJGHHHIJJJJGCHDGGEHIJGCHIJJIJJJJI@EHHFDFDEFEBEECEEDDDDDDEDEDDACDDDDDEEDFDC +@SRR800764.60 60/2 +AAAAAATGTGATCTTCCTTTCATCAGAAGAACAACTTGCTGCTAACGCTCTTGCCATAAGTGTTTTACCCGTACCAGGAGGACCATGGAAAAGAACACCCC ++ +CCCFFFFFHHHHHJJJJJIJHJJJJIIJJJJJJJJJJJJIJJGJJJJIJJHIJJJIIJJIFHFHIJIJJHHHFFFFEDDDDDDDDCDDDDDDDDBDDDDDB +@SRR800764.61 61/2 +AAGCAAAGATCACGTGCTAAATCGCAAACATGCTCGTCTACGGGTTATAACAACAGCAGCATTCTGAAAACGTTTGGCATAAGCTCCAAAATTTCTAATTC ++ +CCCFFFFFHHHHHJIIJJIIIIJJJJJJJJJJJJJJIJIJJGJIAGGIIJHIJJIIJJHHHHHFFFDFFEEDACDDDDDDDDDDDDDCCDDDDDDEEEEED +@SRR800764.62 62/2 +CTAAACTAACACTTCAAGTAATTCAAACTATGGTATCATGTTTTTCTGTAGGTGAAAATCCGGCCAATATGATATCCTGTGGGCTAGGAGTTGTAATCTTA ++ +CCCFFFFFGHHHHJJJJIHHJIIIIFGIGHGIIFHIGIIIFIIIJIIGGIHHBFHHIJEGGHIIGIIIJHGAGFFHDFHHEFFCEEACAC;>C;@DDEDAA +@SRR800764.63 63/2 +GATCATACTTTTGTTTCTTGGTGGTTGCTTTCAAACCCTGCCATGGCAAAGAACCCTTACAAAAATAGATCAAGACATAACCTAGTGATTCTAAGTCATCT ++ +@??DDDDDHHDHBBEEDBAIF:CF@DEHBDEFIEFHGHIJEGHGIHGIDHAFG;FGHJJJEFEEGEEAHC>EEFFFEDCCCCACC>>;@CDCDDCDCDDCC +@SRR800764.64 64/2 +GAAGTGGGATGGGATGAGATGATAAGAGATATTAAATTGGATTTAGATAAGGAGAGTGATGGCACACCCAGCGTGCGTGGAGCACTAAGGGCACGTACGAA ++ +@??DBBADFHHHHBFEIBHEHIICHIECAEGIIEIEGHBA?FDGGDFGGHFEIIJIBDFC4C;@CHIGGIGHB?<=BCAD@CDCDDBDDDD?A@@# +@SRR800764.65 65/2 +ATGACAAACTACCTTATTACATTGTAAGCACATTTCCTGCTCTATCAATACCAAATTTGCATGGTAAATACATGCCTTTTTTGAAATAACATTTCAGCTAT ++ +C@CFFFFFHHHHHJJJIJJJEIIJIHHIJJJIJJIJJIIJJJJJIGHIIJJHIIHHHIIHIIJJBGDGHIJJJJIJJJJJJGFFFFDEEEECDDEECDDDD +@SRR800764.66 66/2 +TTAGCAATGATGCCTTTTCTTTTTCATTTTTTTTCGCCAAAGGAAAAGATGTTTGCAATTGTTTTAACAGAACATCTTTTATTGGTTGTTCTACAATTGTT ++ +@CCFFFFFGHDFHJJIJJG@HGGGGIGJIJIEIIIIJBHHIJIIGIGIIJGCEHCEEHGDHDBCDFDCEECCDDDDDDDCDDCCC@BD=AC:4>ADCCCA> +@SRR800764.67 67/2 +GTCATCAACCATTGCAGATAATTTGTTCTGTCTTTTGAAGACATCTGCATATTTAGCCATATCTTCTTCATTTGTGAAGTCATCGAAATAACCTGCATCCG ++ +@=@DDDDFHHHFHIIIJHIIJICGH??CFHDFFHHIJEGFHGIBB?DBBDD@*??4D?DAGCCIJGIIDGHDEH@AFHHEHIIGA;CE=CB7?;>@@C>A6 +@SRR800764.68 68/2 +TAATTATATTAATTAATTAATAATATATATAATTATATTATATATTATATTTTTATATATAATATATATAATATAAACTAATAAAGATCAGGAAATAATTA ++ +@@@FDFFFHFHHGJJHIJJJGHIIJJJJJJIJJJIIIJJJJIJIIGJIIIGIIJJJJIIIJJJIIJIIIJGIEHJJJJGIIIJIIIIHIJIJJIJFHAAHE +@SRR800764.69 69/2 +ATTGCTGAAAACAATCATTGTTGACAAACAGGAAAAGGTGCTGATATTTTCCTTATTCACTCAAGTCCTGGATATTCTAGAGATGGTTTTGTCCACCTTAG ++ +@CCFFFFFHHHHHJJJJJJJIIIJJJJIIJGIGHJJJJ?FEHJJEIJIJJIIFJJIJJJJJJIHJFHIJIEGGGIJJJHHFHFFDF;?BAEBECCDDDDC@ +@SRR800764.70 70/2 +GGCATCTAAATGCAACTGATCCAGTAATCGATCAAATAGGAAACATCGACGGTTTTTCATTACTTTTGAACGATGTGGAAGTGTACGTAGGCAAGAATGAG ++ +=+=???DDHF;;;5@:@ACA############ +@SRR800764.71 71/2 +CTAAACATCAAACATGTTATGACAAGTGGGTGACGTTTTCCCTAGGCTCCTTTCCAAACAATTATNGAAGAGTTTTCCGAATTCGCGCCCTAAATCCCAGT ++ +BCCDDDEFHDFHHJJEHIGIIGGIGE;?ACDDD=B@5CDDCD3 +@SRR800764.72 72/2 +AGAACATACTCTGGGGCTGGCGTAGGCACAAAATCCGGTATTCCTAAAGTTTTGTGGTACAAAACTCCATACCTAAAACACAGAACAAATCTCACCCGTGG ++ +@B@FFFDEHHFFAC@?8CFEHBHHIIBEGGBGHGEFHB(A>D=>CC>G3;=??EEFFFB3>;AE>CCDC@ACBA<<955,98::+:@CDA#### +@SRR800764.73 73/2 +TATTCCTTCGTTTCACGATTTAATGCCCCTTACAGATGATGCTATTGCCTTGGTAATAGGGGTAAACAATCTTTTAGAAAAAACATCAGAGTTGTATCCCT ++ +BCCFFFFFDHBDHIGGIJDHIIJHJJJJIICDGAFFHGCIIJJJGI@@DFD?FFGHIIGGDG@FFGHIJIJGHHHHDBCFDFDBDDCCD@C:AACCD3;CC +@SRR800764.74 74/2 +CCTTCTTTACTTTTTTTTTTTTTTTGGGGATTTTTTATTTTAAAAAATAAAGAAACAAAATTCTTTTCTTTGTTCAAATTCCCCCCTAGTTTTGTTTTTCA ++ +CCCFFFFFHHHHHJJJJJJJJJJJ############################################################################# +@SRR800764.75 75/2 +AGGAAGAATAAACTAATTGCTAACTCTACTCCAAGAAACCCAGATCCTTATGGTTTCGAAGGAATNTTTGCCAGGGATATTGATACTGGCGAATTGCTCTC ++ +1?@D;?B+A22AFE@DBAFHIGGIGGGIGGEDCH>?ACAAA3>???D?ACDA:@> +@SRR800764.76 76/2 +GTGACGCTATCGACACCCGCATGACAGAATCTTAAGGCAATGCTCGCAACTTTCTTCCAAGATGCGTGAAAATGCTTATAAGTCTTACTAAGCTATCAAGA ++ +?===BDFDHHBHDGEAEHHGGIGGA@DHGGE>CCC:;@;@CDC>CCC@CCECC9>@>C@CDD +@SRR800764.77 77/2 +CGGGGCGGACCCCGAAGGAGTTTGGATAAAGAATATAAAGAATAAAAATTAAGAATATTATTTTATTTATTTTTAATATTATATATTAAAATATTAATAGA ++ +1+1+4)@?F;>>ACDD9555>@@(>(5>>(3@AAADC@3A::(:>A4>ACACCCCDCA:+(:3:@CDDC +@SRR800764.78 78/2 +AATAGTGGAGGCCAAACGACCCAACAAATGATCCTTAGCTATAATAAAAGGAGAAAAATAAAGTTAGTAAATGCTAATCTTGGTATTTTTTACTGAGTGGA ++ +:=;DDADDHD=DHEIG@FHDHHIGGIGH@?@<09?DHGE@G??D@GIJGDBFHIHGHGHJE@CHCECFFDDF:?AEC@AC>;;@@ADB;>=5:A5>:A### +@SRR800764.79 79/2 +GATGTTGATGGCACATTCAAATTAATCGAATTGGCGAAAGCCTCGAAGGAATCGTTAAAAATAATCCCCCTAGGGTCTAAAGAAAATCTAAACAATGATCA ++ +?@@;DD>,=AAA++?;)??G@BCDEEDDDDDDDDBCDDCDDDDDDDCCDBDDDDB +@SRR800764.82 82/2 +ATGGTTAACCAAGCTGAAGAGTTCAAGGCTGCCGATGAAGCTTTTGCCAAGAAGCACGAAGCTAGNCAAAGATTGGAATCCTACGTTGCCTCCATCGCACA ++ +;B?BDFFH=DBGBGH>@B3<+A:+2++@EG:81:BD??*9909BCCC65<9/:A@ACCD@#### +@SRR800764.83 83/2 +AGGTGTATGGAATCAAAGAGATGACAACATCGTTATCAGCCAGAACTTTGTCTAAGGCACTGTCATCGGTAACATCCAATGAAATAGCCTTGGATCCAGAG ++ +B@@ABDDDHFHFHJJIIFDHEGGGIHIJFBEGEGIIHGIIIDGGHEGIJIGIICHDGGJJIJIGGIIIGGEHECEEFFFFBE:AEEEDDDDC?CCCCCC:? +@SRR800764.84 84/2 +CCTTTAGTCCCTCGGAATTTGAGGCTAGAGGTGCCAGAAAAGTTACCACAGGGATAACTGGCTTGTGGCAGTCAAGCGTTCATAGCGACATTGCTTTTTGA ++ +CCCFFFFFHHHHHJIIIIJJJJIJIJJJIJIDHIIJJJJJJIBGHJJJJEHIJIEHHIGHIIJJHHGHFCD>ACECED=BBDDECDDBBB@C@C>CCCD@< +@SRR800764.85 85/2 +GTCATCATGGCTCGATGAACATAATAATCAGGAGATCAATGATGCTCTAGTGTCACAAATCATTAAAATGTCCCACCTTATGTTCGGCGGGTTAACTCACG ++ +B??;?DFDC>DFHEG?2:AA?AEF@FFBBAED>??D@?A@@>&0?(:A@CAC8 +@SRR800764.86 86/2 +GAAATAAAAACATGTCAAACAACCGAACGAAAAAAAGAGGCACCAGGGTGGCTAAAAATGCTAAAAATGGGAAAAACAATAAAAATAGTAATAAAGAGAGA ++ +CCCFFFFFHHHHHJJJJJJJJIJJJJJIJIJJIJJJIJCHIIGHHGFF7?>AADDDDDDDDDDDDDCBDDDDDDDDDBDDDDDDCBDC@CDEEDDDDDDDB +@SRR800764.87 87/2 +TGTACTGGCGCAAGGCAAGTAGCTACCATACTAAGAGAACTGAAAAAGGATCAAATCGGGGTTGTTAGTATGTGTATCGGTACTGGTATGGGTGCCGCCGC ++ +@@CFFFFDFHHHHJGEGIGIDEGHIGHIHGGGHGIGFDGHGHHGFGIEE>CBFCGCGGIEH9?CCDCC@CDD@@@CDDBB8@CD>DBDB>AFH:?;))<CF>BG<?BFC9)9(?:=???=@A############### +@SRR800764.89 89/2 +AAGGTGCAAGTGGAAAGAAAGGAAGGCTAAAGCAAAAGTGTTTCTTATATATAATTTTATGTACCAGAGGAAGCAAAGTACGAAAACTATCAGTTGAAATC ++ +=:BB42ABFD<2ABGF8?8?FEH=FE;>>>@C +@SRR800764.90 90/2 +ATTATTTATTATTTGGTTTCCTGCGGATTGTCCATACTTATACCCCCCCCCCCCCCCCCCTCCGGNGGGGGGGGGGGGGAGTAATCATTATTTTTTATATA ++ +@CCFFFFFHHHHHJJJIIIJJJJJJJJJJJIJJIJJIJJIJIIJJJJ@##################################################### +@SRR800764.91 91/2 +ATCCTGAATGGACAAGACTGACACTATAAGGAGACTTATTCTAGATATCGTAGAACAAACATATGTTACTTTAACGTCGCTGGACACTCACAGACAAGCCT ++ +CCCFFFFFHHGHGJIJGIJJIFGJJJJJJJIIJIIGIIJJJJIJJJJJJJHJIIEHFHIJJIIJIHIJJJIJIGIHHHFFDDDDDDDCCDCDCCDDDDBBC +@SRR800764.92 92/2 +CAGTGGAGCTTGGAGCAGCAGAAGTTGTCTTAGCTTCAGTGGAGCTTGGAGCAGCAGAAGAAGACTTATCTTCAGAAGAGCTTGGGGCAGCAGAAGAAGAC ++ +CCCDFFFFHHHHGGIIJJGJJHIIEHHHIJJIJJJIJJJHIIJIIIHHIIFGGIHJGGIJIGHIIGHG:EHFHDHEEFFDFEDDCDD@6=@BDDDDDCACC +@SRR800764.93 93/2 +GAATTCATTGTCCAGTGGCAAGAATTGAGGGACAATTATTTACCAAGATCCAAGTGGTTCGGCGTCCTTGTTTAAGTAAACCATTTATGTAGGATAGTAAA ++ +@@@DFFFFGHCCBFGEGG?@D@BHHEHHDBDBGHIIIIGHGIHGECCCGD?DHCFG;;;5>;?B5>CC@C;@CCDDDD:@CC +@SRR800764.94 94/2 +AAATCCAAACTTATCGCCGAAGAAATACTACGAACTTTATGTCATTATTTTCGACTCATTGACTANTCTATCTACGTACCTCATAGAAAACCATCCTCAAA ++ +CCCFFFFFHHHHHJJJJJJJJJIJIJJJJJJJIJJJJJIJJJJJJJIIJJHIJIIJJIHHHHHHF#,;ADDEEEDDDDDDDDDDCD>CDCDDDD>ACCDCC +@SRR800764.95 95/2 +GCATTGGCGGCCAAGATATCTTGTAGGTTTGAGTTGTGACTCAATGTGAATATAGATGAAGATTCGGTAGCGCTCATTCTGATGTGTAATAATTGAAATTT ++ +CCCFFFFFHHGHFJJHIGIIIIJGIIIDGIIIJDGGDGGIIGGIGIGH@FFCGGIGIGIGHEHHHFF?BCEDDDDBC;C>CC@CEDCFEACDEE>@@C@C@ +@SRR800764.96 96/2 +CAGCAGTTCAGATAAAATACACCCAGCTTTTGCCCCCCTCCCCTTTTCTCCTCTCTTTCCCATCGCTTTAATTACCCTCTAAATTCCCGCTTCCGTTCATC ++ +##################################################################################################### +@SRR800764.97 97/2 +GATAGTGGGGAAATCCAAGAGGATCTAGAAGTTGATCACATTGATCTAGAGACAAAACAGAAACTAGACTGGGAGAACAAAAATGATTTCCGTGAAGCTGA ++ +@@DGGG@CC> +@SRR800764.98 98/2 +GTATTAAAAGATAATAAAAAGTAATATTAATATATTAATTATATATAATATATTTATATATAATTATATATATATATATAAATAATAATAAATATATATAT ++ +@==B?ADDDHHHDIIIIBFAFFHHIEIIIIDHIDHIIGEEEB>GEHIIGIHAHIIJIGIJJHJJJIGIGIEIJJJJJIIJJIGGEGHHGIEHIIIIGHFH# +@SRR800764.99 99/2 +TCTTTTTTCAGGGCATGCAGATTTTGAAATTCATGTACTGCTTGAAACTTAACAACATTCAAACCATTGGGCAAGATACCATCCGGTTTCCTCTTCAACAA ++ +C@@FFFFFGHBHHEIBHIJIJJIJIGJJIIJBGHEEGIIJIIIJBGIJGIGHHHIJJJJJGIJHHJIIIIHHHHEECDEFECEEDB3;B:CCDDCCDCCCA +@SRR800764.100 100/2 +CGAGAACAAAGAAAAGTGTCTGTCCTATTATTTTACGGCACACTAAGCGTTATGCGAAATAACTTCAATCCAATTGCCACCGTTCACCCAAAAACTTAGGA ++ +<@@DBDFFHGHHHJJJEGFHIIHHHIJJJJGIJJICHIJIIIJIJJGIGHFGIIJDGHHHHGGEFFFFFFEEDEDEDCCDDD?@CCD@ABEDEFDDBDD;ABCCCCCDDFCC +@SRR800764.103 103/2 +AGATATGCTATACCGGCGGAACTTTGTTACAGACGGCTCGCGCGAATCCTTAGGGGAAAACATTGCGCTGACTTTCCCCAGAGCTGTTGCCACAACATAAG ++ +@;@ADDADHH<,22<@:EE################################################################################## +@SRR800764.104 104/2 +TTTATAAAGGAGATTAGCTTAATTGGTATAGCATTCGTTTTACACACGAAAGATTATAGGTTCGAACCCTATATTTCCTAAATCTAGATATAATATTATAT ++ +BCCFFEDFHGHHGJJJJJJGIIGIIIDHIJJJJJJJJIJJJIJJJJGIHIIHJJIIGGIIHIEIIIJHHGDFFFFFFEEEEEECDDCCDEEEEEEDFFEED +@SRR800764.105 105/2 +CGAAAAGTCGTCGTCCCAGGTATTTCTTTATTGATTTTCTTCCAGGGATGCCTTATTCTTTTGTTTCTCCAACTCACCTATAAGACTCTTTACTGTAGAAA ++ +BCBFFFFDHHHHHJJJJJJJ>;;;BCD +@SRR800764.108 108/2 +TGCTGGAAATTTCATTGATTTCCTTATGGACTTGGGAAGAATACTCCAATAGTTTGTTTAATTTTAGTAAAGAGCTATATGCCAACGAAAATTTGATCTTG ++ +CCCDDFFFHFHHHCB?J?43?:CF?CCFI4+A?92*111:CDE@CGGHGIIC>C +@SRR800764.111 111/2 +CAGGTATTGCCTTCTCTGGCGCATGTATCAGACGAGCAAAGACGGCCAATTGTTGTATGCGGTTCACTGTATTTATGTGGTGAATTATTACGGATTCACAA ++ +@CCFDEFFHHHHHJJJJIJJJIJIJHIJJJJJJJFGIJJJJJJIIJJJIIEECDECHHGHFFACDEDDDCDDFEEFDCFDCBCDFEDEEDDDDDDDDDDCC +@SRR800764.112 112/2 +CCACTGGCGGTAATGCAGCAGGTGCTGCGGCTACCTCTTCTAATCTTGCGGAAGTATGTATACAAGGTAGAACCGCCTTCGTTGTTGCAAAACCCCAAGCG ++ +8:;1::+=@1))+<49ACA:@C###### +@SRR800764.117 117/2 +AGCGAATGGTAGCAACATCCCTCTGGACAATGCCGCAGGAATTAATAATAGCAATAATAACATCAGTAGTAGTAATTCATTTTTTAACAATGGTCATTTAT ++ +B@@FFADEFADFHGIIIHIJJGHGGIIJJJIJJIHIGIIJIJIIIJJJGGHGHHIGGJIJJJJHHHHHG;CEBEFDDEEEDEEEDDDDDDCDCCCCCCCDD +@SRR800764.118 118/2 +GAACAAGAATTCATCCAAATCCTCTTTGCATGGGACACTGCAGTTTCATAATATAAACCGTTCTCNGAGTACGATGGAGCACACGCCTGACACTCCAAATG ++ +C@@FFDFFHGHFHIIIIJJJFGIJJJJJJJIJJIIJJIIJJAF?FGIIGEFHIIJJEFGGIIIJG#-;CDGEC?CBDDFCDE@B>?@DBDDDDDDDCAAAD +@SRR800764.119 119/2 +TTTTCAACAAACGCTACACCTTCTTTTGACGTTGGCACTACGCAAAAATAGTCTGAGGGTATATTTCTAGCTGATTCTTTATACTCTGAAAAATGGAACGA ++ +=B@DADDDF33ADFFHBFBGGGHHDEHGH@DFHE3BDHGCAGG?:AHIBHAC=77)@CH5?AAD;?BEF>@C;3>;>>@@@CDCACC>>>C@B?####### +@SRR800764.120 120/2 +TTTTACGGTATTTGATTCACTACTGAGAGAGAGGAAGGAACTGGATGAAATCGCACCTGTACCTGATGCGTTTGTCCCGATTATCAAGATAAAGTTCAGTG ++ +BCCFDDDDHHHHHJBHIIIJJJJJJGHFHEFFGHIIJJGHEBGIGIIGIIGIGIJIJJIEHIIJJGGHHFFFDDCEDC@BDDBCDEDCDCCCCD:CDCCC> +@SRR800764.121 121/2 +GGCTATTTTCTATTGGCGGCTCGTCTGTGGTAACAGAGTGGGGTTTAAAAACAGGGTTACCCCTAAGAAACTATTATTGCAATTCAGGAGAGATATGGGCT ++ +:++AA?DDHDF)?B@B################################################################## +@SRR800764.122 122/2 +CTCATAGTAGCAACAAACTTGAAAATGAAAGAAGTACATTGTTGCACAGTCAGTAGATATAAAATATACTGGAAGAAAGCACCAGCTTCATATTTCATAAA ++ +@@@BDAEFAHDHHGHHIFIGBDH9D>D>EFEHBFFFFCDCDDCDACDC; +@SRR800764.123 123/2 +ATTTCAACAATGAGCTTGTGGGGCTTCTTAATACCTCTTTCCATTATCAGCCTCAGCCTTTAATTTCGCATCATCTTTTTAGTTTCCTTTTCTTTTTCCTT ++ +:?+B?,B+A+2++2+2:++++<FDIFCGGGFGEGICJIJJDGHGI?DHHHGGII>HE=B?BDFEEADE;C@CCCCC +@SRR800764.126 126/2 +GGAGAACTATCTAAAGGTATTACAAATAAAGCTTTGCTGGAAAATAAAGAGGAACACAAACTTTACGTTAGTGCTCCAGATTACGGTATATTAAAGAATTA ++ +?@@D?DF>F4DFB@DFDA?F4ICCCBHDHGICHHIHG9BB)?*::4?BFBDDBGEHGI6BHEHGGHI(=3;@DDH>E>EEBCDBDD;2?DDDDACC<<@CC +@SRR800764.127 127/2 +ATCAATATCTTTTTTAGAAAATGTGCCTTCACTTATCAATTTTTCCGTATAGACGTCAATGACAGATTTTTGTTTTGCAATTTTTTTGTACATTAATGGTT ++ +@@@DDDDDBBFA>GBFFHH;(.;>?DBCCCBCCCC@C4: +@SRR800764.128 128/2 +CATCCTCGATGTTTTGGAATAAAGCGACTTCCTCTCCTGTACCAGGATCATCGCTGATTCAGAGTCTTGATTCGACGATTATACATCCCGATATCGTTCAA ++ +?@@FDDFD@FFAFHHHHFFGHIIGGGFBHIEHHJJJJIJ4DDFHGI;?EGEGGHFHEDHGGDDC.==CA;@BDB?==3,5A>A?9<9<@B3<>CBBDB?ACCCCDD@B@@BCACDDDAC +@SRR800764.130 130/2 +AAGACGAGAAGGCCGATGGAAAAGGTGTTGTTATGGCAACTACCCTAGAACAGTCACCTAATCCAGTTGAATTTGATGGTACTGTTTTTCATCATGGAAGA ++ +?@@ADDDD<:FDFHIFGHIGHIIJI?B??D?FHIGAC>>A;5-;A-5(55,,5ABCDDEDCCD>CA# +@SRR800764.131 131/2 +CGTACAGAAGGTATAAAACGTTAGTTTACTCACAGAAGATACCCTGGCTTTTCTTTTATTAATACATGGAGTTGCAAAAAACAAGGGAAAGGAAAATCAAT ++ +???DDDDB?DHADF9CHGJGCGGFAHHFEGGGI=;?ACBDC=?AB5599A<:>CCCC:3 +@SRR800764.132 132/2 +TAATGTCTAGGTTATAAAACATTGACAGCTCAGACGATAGAAAAACATGTGATACGAATCATTTCGCCGTTGTGTGTTTTAAGAAGAAAAATGTTAATGTT ++ +BBBDDADDHFHAAEEGGIJJIIJJIGHJGFCHHEGH:?GGGIJGHEHFF?9?BDGHGIHIBFFIEEEHE,9?,;.;,;=C@>@@CC?ACCA?>+4>>A### +@SRR800764.133 133/2 +TTAGGTTGGGAAATTGGCTTCTAATATCATCATAAATGCTTTTGCGAGATGTTGCACGAGGGCTTTTGCTTGAACTTTTGGTTGATGCTACCGAACTAGTC ++ +BBBDFBDDHH<;;ACDDDB;A@>CD:@>:C<)05?#### +@SRR800764.134 134/2 +ATTAGTTTTCACTATTTAGCCTAAACAACCCAACGCGAAAATGACCACGCGAAAAGAAAAATTAGTAAAAATATTTCACAACGCGAAAAATAAGGACGAAG ++ +:BBDBADDHH:?555(<5@:@:5;:@A9@DD>>CC>A(9@B00)08AC@CD@AB99< +@SRR800764.135 135/2 +AATGACAGAGATAACCTTGATAAGCTTTTTCTTATACGCTGTGTCACGTATTTATTAAATTACCACGTTTTCGCATAACATTCTGTAGTTCATGTGTACTA ++ +C@CFFFFFHHHHHJIJJJJJJJJJIHJJJJIJJJJIJJJJIGIIJJJJBGHIJIJJJIJJJJJIJII=DHGIHHHFFEFFEDEDDEFDEEEEED>CCCDCD +@SRR800764.136 136/2 +TCATTGACGTTGATTTCCTAGAAAACGTTCAATCTCTCTCACACGTAAATGAGCCCTTCACGAGANCCAATTTTGCAATCAGAGCAAACAGTTTGCACCAG ++ +CCCFFFFFHHHHHJJJJJIIJJJIJJJJJJJIJJJJJJIJJJJIIFHIIJIIJDHIJJIJJIFIH#-;A?DCFFFDEEEEECCDDDDDDDDACCDDEDDB@ +@SRR800764.137 137/2 +CCTTGGGACGTAAATGCAGCATTAATCAAAGAGGAAACCCATCCGAGAAAACGGCCCTCATTTTTATCACTGGAGATAATGCCAGGCCCCCAGGCTCCTGG ++ ++8:A4A+A??8AFG4,+AE9CC4++5>>>@############################# +@SRR800764.138 138/2 +TTTCATTAAATTTTAATCAAGCTTTATATAAAGCTGTATTATGAGGTGCTTTAAAAGCTAATAAATCATATAAATAATAAAATTTATCAATTAAAAATAAA ++ +CCCFFFFFHHHHHJIGIJJJIJJJJJJJJJIJJJJJCHIJJJJJJJEGIJFIIJJIIIIIJJIHHIIGJIJJIIIIGIJIICEHCGHHEHHGHFFBDBCCC +@SRR800764.139 139/2 +ATATCTAAGCAGGGGCCAACTTTGTCACCACAGCTTATCAACCGATTTATGCCCCATTTTCCCTCGAGCCCATCACCTCTGCGAAATACATTGGATTTTAG ++ +@@@FFFEFBDDDCCCCACC>CCDDC +@SRR800764.140 140/2 +ACCAGCCATTGCTGCTTTCTGGAGAGATTTTGGTAAAGACAAGGCTTACTTCGATGCCGAACACGNTATTCACATCTCTCACGGTTGGAGAACTTTCAGGT ++ +B==+4=:::AF4A<+2+2A<:AB;3A+A?<4:EHCFEHGEGGIJA?@@GDGHB):@G>@DGG6=@DC@C=;E7773.?C77>3>BBBBB94+4@<8>>>A8A>CAC######### +@SRR800764.142 142/2 +TGGGCAAAATATAAAAAAAATTTGCTTCTTACAAACCTATAGATGGGCACTTTTATAAGTTTCTGCTTTTCAAACTTTCTTGTTTTTTAACCTGAATTCAG ++ +@@@FFFFFGHHHHJIJIJJJJJJJIIJJJIIIJJGIIJIGHIJJJJIJJ?FFHIIJEGHGFHHHHHGFFFFFFEA@CCEEDC;ACDDDBCCDCBDDD>A@C +@SRR800764.143 143/2 +CAGTTTACTTCTTATCTTTCCTAATTCCTCATTAAACTCAACTTTAATCATAAATTCGTTATTTTCTTCATAAGCATCCAAATCAACCGTTGTTTCAACCA ++ +@@@FDE>>FFFFFIBFHGJDHHIIHC,AEH<9CFCHGCH>;C?G>?GHHHDFF@FC4B?DDFHIIIJJGGG=4=D7CFED@4@AEC9ABDB?CDCACD:A= +@SRR800764.144 144/2 +GGGAGGCGACTCGAATCTCTGACTTACTGAAATAGAATCTATTTTTTCGAAATTACTTACACTTTTGACGGCTAGAAAAGGATATACATACATATTAAAAT ++ +@@@FFFFFHHGHHJIJJIIIJIJJJHIIBGGIGIIGIEII@GHIIJJGB;DGHGHGGEHFFFFFFED?ABDDDDDACDDCB?@CC<@>C@CCDECC:B:CC +@SRR800764.145 145/2 +CCTAAATACTTTTTCCTTTTCACATCCCATCGGGTTTATCTTATACCAAATGTTTACCATTCTGAATCGTATAGCCAACAAGTACCCGCAACTGCAATTGT ++ +??1+A+=BD4**?*0*9BDD################################################## +@SRR800764.146 146/2 +TGCCAGAACAACAACACCAGTAGTACCATCACCAATTTCATCATCTTGAGATTTGGAAAGTTGTACTAACAACTTTGCAATCTCATTATCTAGGTCCATTT ++ +???BB;;;DFHHFBGBEBGBHE9AAC@?BBH*?GEBFDBHD@DG?FH9B9)/?B4?DFB@.=.=7=FDHI@@EHEEECA;CB>BD@CDDEEACCE@CDDC; +@SRR800764.147 147/2 +CAATTTCACGTACTTTTTCACTCTCTTTTCAAAGTTCTTTTCATCTTTCCATCACTGTACTTGATCGCTATCGGTCTCTCGCCAATATTTAGCTTTAGATG ++ +1B8+=:=BFHC:;AHBCG?E<FIE@DFAFGGBC@GGDHIIGI>GHG;:DG;?; +@SRR800764.149 149/2 +CAGGAGCAAAAATTTTAGAAAAAGTCTCCAAACGGATGACACGGGCATCTGTATCCAAAGTCAAGAATGATTTCATTAAAAAATCATTCAAATACCGTTCA ++ +CCCFFFFFHHGHHJJJJJJJJIIIHHIJJJJJJJJGIIJJJJIJJIGIJJHEGIJJHIJHHHHGHHFFFFFFEEEEEEEDDDDDDDDEEEDDCDDCD?@DC +@SRR800764.150 150/2 +GGCTCCTCTGGATATTCACTAGTCACTAATAGTTCTACTAGTTTTTCAATAATTGGTAAGTCGATGGAACCTTCGCCAGATTTGTCCCTCCTAATACTGAC ++ +CCCFFFFFHHGDHGIIEGIJIJHHDHIIIIFIHIGGIJIIJGGIJIJJJJIIGIEIGHIIEIIJIGGHIJJGJIEHHHHFEFDFB?A>C@BCA>CCCCCCC +@SRR800764.151 151/2 +CAAGCGGATTCTCCTCTGATTCCTCTCTGATATTGAATAAACCAGAAGTTCGTCAATACTGGTCATCCGTTTCATCTCATATTTCACGCTCAGGTGATGTG ++ +CCCFFFFFHHHHHJJJJJJJIIJJJJJIJIJJJIJIJJJJJIIJJIEHFFEGHIIJJJJJJJGIJJJJH;EHFFFFFFEEEEEEEECDDDDBDDCDCDDB> +@SRR800764.152 152/2 +TATATAATTATTATTTTTAATTATAAATAAAATATAATTATTATTTATTATATAATTTATATAAATATATATATATATTTATTATATATATAAATATAAAT ++ +C@@FFFFFHGHGFIJIIJIJJIJJJJJJIIJIJJJJIJJJJJJJCIHIIIJJJIIAHGIIIJIJJJIIJJJIJIIIIJIGJJCHGGGIIJFI>EAGIIGE= +@SRR800764.153 153/2 +TTCGTCTTTTATTCTAAATTACTCATTCTAGCACTCCAGGTTGATTTGCTCCTCCTTTTAAGCTTTCACTTCCGGCTCTATTTCCTCTTCTTCATCTTCTT ++ +CCCFDFFFHHGHHJJJJJJJJJJJIJJJJJJJJJJJJJJJCGIGGGIIJJJHIIJIJJEEHIJJIJJJJIIJGIIHFGFBEFFFFECCEEDEDCDDDCDDA +@SRR800764.154 154/2 +AATCTGATATGATTGGTGAGGATCTTCCACCGGCTTATCCCGAGGAAGAACTTGGAGTTCAAGAANATAAAAAAATTGAACTAGAAAGGCCACAAATTCTT ++ +C@CFFFFFHHGGHIJJJJIIJFHJJJEGIGEHIJIICGIGIGIGIIJIJIJIIAECH=?EEEEEB#,5??ACCDDB@A@CCDDDDCC4C@ +@SRR800764.155 155/2 +ATTAGATTCTGGCGGGAATCCACCGTACTCAAATAGACGTAGTAAATCATAGTATTGCCCATGAANGTCACCACATATCTAAAAAAAAAAAAAATAAAAAA ++ +B@@DDDEFFDFBBFHGCCDEEDFDDFCCECCDDCC#,8?BDDABBCCAACAC@CC@@DDDDD######### +@SRR800764.156 156/2 +AGAAGATCCGTTGTGGCAAAATGCTAAATACAAAAGCGCTTTGAAGTTTTTCGCAAGCAGCAAGCTACAATTGGGATTGAGTATGATGGAATTGCAAAGAA ++ +<@@DDFBDFHFD=GGA?EGIHHHGBHIEEIGHGBGHEGHGEGGBFG?8?D;B@GB?@;AAE@CA5>CCCC>@CC:ACACCAAAA@CCCC? +@SRR800764.157 157/2 +GAGGCTTGCTAGTATAGAATGGCAGTAGAAGAGGGTGGTTGCGTGACGAAACGTTTACAAAATGAGCTGCTACAGCTACTTAGTTCTACAACAGAAAGTAT ++ +B@@FFFFFHHHHBGHIIIIJJJICHGHHGEHHIIJ:CG:DAGFFHGIIEGGAE@EHBHHDFFFFEEAEECDCDDDCDCAACDC@CDDDDDDDDDA:AC>AB +@SRR800764.158 158/2 +GTGAGGTACGCAATAGCGGTTGAAGCTTCGATTGCCGTATCTATGTATAGAATATCCATGTCTCTTTTTACCAAATCCATTTCTTTTAGAGGTTTTGACAA ++ +BBCFFFDEHHHHHJIJJJJHIJJJJIJIJIIIJIIJJHIJIJJJIGIIIJIIFIEHJIJJJJHHHHHHFFFFFFDEDEEDFEEEDDDDDCDD@<@BDBDCC +@SRR800764.159 159/2 +GGATTATTATTTTCCCTGATTTTAATTATGGAAGCAGTAGAAGTGGCTAAGAACTGAATCATTTCTTGCGAAACAGGTTTTTTGTTGAATTGCAAAAGAGC ++ +?<@ADEFFHHGFHJIIDIIGIJJEGEIJIEIDGE@EEHG@>GDFGIGIGGIIDDCEDG>FBBAGIIGHIA;@EA?CA;;3;?@B=C?C>@CAC>CCCD?33 +@SRR800764.160 160/2 +TTGTAAAAAAAATATCAAAATATTAAACGTACCGGAAGTGTGTGATAAAAATGGATTTAAAATGAGGGAGCTTTTAAATCTACATGATAACAAAGTTTTAG ++ +CCCFFFFFHHHGHIJJIJIJJIJIJJIJIGHIJJJHIJCFCGCGGGGIIJGGCHH@EHHHFFFFFFEDDDBBACCCCCEDDDDDDDDDEDDDDDD>CDDD9 +@SRR800764.161 161/2 +TAGTTGAGGGCAAGGATAACCACGCTGGTATATAGGCTTCTACTTGGTCAAATTTTCTTGTCTTTATCAAACTGAATGGGTCAGTAAATGGACCTGTTTCT ++ +C@@FFFFFHGHGHJJJJJIIGIJJJGII?FHHGGGIJIGII@FGGEGBBCCCCC@CDCC:@CDC +@SRR800764.162 162/2 +CAGTTGCAGCAATTTCTTCATGTTCTGTTTGTTCCCCGTCCTCGTGTACCAGATCAACTACCCAANAACGTCGCGCATCAGATGGAGGTATGTGTTGGAGA ++ +CCCFFFFFHGHHHJJJJJJJJIIIJJJHIIJIJJJJJIHIJIIJHIHHIJIJFIIIJIJJJJJJI#-;CEHFFDDDBDDDDDDDDCDD8>CCDEDDDBDDC +@SRR800764.163 163/2 +GTTTACCAAATGCTCCAGATTTGCAAGCCGCAAGAAAGGTTGCCAAATTCATCGGCTCTATTCATCATGAACACACCTTTACATTACAAGAAGGTTTGGAT ++ +@@CF?DDFFHHGHIJIIIGGIBEGIJGHGGGGBHIJEHG?F@GHGIGIJIIIJ@FGEGCGEEHHFGFFGEEFFFDDDECDCCC>B>CDDDDDD?,:>?<@A +@SRR800764.164 164/2 +CTTCCAAGAAAACTAAAGTAAAAGGAAGCATACCTGTAAAGATTAGACGGAACCTTGAACTCCAGATAGACGATAGGTACGGAGAGTGCCAGTCCGTAAAC ++ +@@<:DDDDBDBH>G@?FDACFEH@FHII?*0??D@DBDF>=CGGACC;=A=DCEG@8/;?BAC:(98@BB85,5:>@::>?8ABBC +@SRR800764.165 165/2 +AATAGAATAAAAAATAAAAAGAATTAATAATATATAAATAATATAAAATATATTATATATATATATAATATATATATATATAAAATAAAAAAAATATATAA ++ +@?@DFDFDHHGHHJIGGIJIJJJJJIIGIIGIIJJGIJJIJJJIIJJJI*?DGIJJJJJIGIJJIIIJIIIJJJJJJJJJIJIJIIFEHHHFBDDCEEEEC +@SRR800764.166 166/2 +TTTTGATGGAAGGTCCAACAAAGAAAAAGAAACGTGCGCTTTTAAAAAAAGAAGCTTTTCCTACCAAAAGTTCTTTGATCTGCTTATTCAACGTAGCATCT ++ +CCCFFFFFHHHHHFHIJJJJJJIJJJJJJJJJJIGIJJJJJJIHIJJIJJHHHHFEFFFEEEEEEDDDDDCDDFDDDDDCEDDDDDDEEDEDDABDDDECD +@SRR800764.167 167/2 +CGAAAAGATTCCAGAAATCCCATTGGTTGTCTCCACTGACTTGGAATCTATTCAAAAGACCAAGGAAGCTGTTGCAGCTTTGAAGGCTGTTGGTGCTCATT ++ +@+=DDFDFDHFGA?DFE???FGHI>?BGG?BDHIIIJGIDGGC=5(5=8?AAC:@# +@SRR800764.168 168/2 +TACCCCTTGCGCTAAAGAAGAATATGTGCCTACTAACGCTTGTCTTTGTCTCTGTCACTAAACACTGGATTATTACTCCCAGATACTTATTTTGGACTAAT ++ +?@?AB2ADD8F61)+;38::::AC +@SRR800764.169 169/2 +GCAGAATCACATTAGGTAGAGAAACGGTTTTGCATGAAGGCTCCAGAAGAAGCAAGGGAATAAGCAGGGAAAATAAAGCAAAGGAAAGGAAGGTAGTCGTC ++ +@CCDDEDEFFHGFEHICEDHGGGGIIJGHIGHAIA?@GHIDGIIIJJIIEDDGGGIGGGHGHJIIB@EFEEEFEFACEEEEDDC?CCA@B>A<:AC@ABD0 +@SRR800764.170 170/2 +TGTTGGGTAAATGTAATAATTCTTCTTACTTAGCACACACACCTGTTCTTTTACTCGAGTTCAGAACACATTAATCGATAACAAACGCAACAGTTAAAATG ++ +@BBFFFFBFHHHHJIJIJJIIJIJGGGIJIGIGHGJJJIJJJJIJHJJJJIIHCHIJFIBDHIJIIJIJJJGGGHFHDFFFDD@BDBBDDDDD5;ADDCD> +@SRR800764.171 171/2 +AAGTTGTCATCTAAAACATTGGAAATATGATTGTCACCCTTGGTTGGAGTCCTAGTTAGCAATGTTGAATTTTCTGGGTTTTTGGACTCATCTGACGTTTG ++ +@@@DDFEFFHHHFJJIIJIJIGGJJJJIJJIIGIJIIIJIJJJHIIEIHDEDG9FHIHJIHIIIGHGGHGIIJIJGGI=AHHFF@A@ACCDDCDCDDD@C< +@SRR800764.172 172/2 +ACTTTCTGCCTGTAGAGTTCAATCTATATATCCTTGCTTTTGCACGTTTCATATCCTCTTTCCAAACAATTCCTGATTGCCCATTGTTTTCTGAAGTTAGG ++ +CCCFFFFFHHHHFIJIJHJJJJJJJJIJJJJIJIJJIIJIJJJJJJCGHIIJJIJJJIIJJJJIJJJJJIGGIIGGHIIGIIICEH?CEDFFF@DE;@EEE +@SRR800764.173 173/2 +ACCCCAGCTATTGCGGAACCTATAAAAGTAGATCCTTTTAGCTCTCTCTTTTCAACTGCAAAGGCATCTGCAGAAGCACCTAGTGCTACTAAAGCATCCCA ++ +??@D+B13;A7@@########################## +@SRR800764.174 174/2 +GACATCGATCTTTAGAGAACCCCATGGCAAGTTAGCTGGGTCTCTTTCTTGGTAGGTAGCGATCTTGACACCATCAATGATGATGTGCTTGTCGTCATGGG ++ +CCCFFFFFHHFHHJIJJJIJGIJDIJIJJJJFGGIIJHJIHGIIIIGIIJGGFBGIFFECGHIJJJCHFEHFBFFFEDEEDCEEDCCA@ACBCBDBBDDD? +@SRR800764.175 175/2 +CTAACTCCTTTTCCTTTGCATGCAGTGACGATGACAGTTTTCTGAATATCACTTCCAAGGAAGCTGGCAATTCGAAAGTTTGGGGTATATGGCAGTTTTCC ++ +@BCDFFBDDAHHHJIIGIGJJJHHJCDHIJCGEGFGIHHJIJIGIEIGEEBGFGHIIIHGHIGGIIFIIJIIIJACAE3?B@?BB3;AA>@>ACDCCAC:5 +@SRR800764.176 176/2 +TCTCTATTTTCGAATGGGAATGGTACCGCTGAAGATTGGTATTTCAAGTTTTTCTTATTAACTTTTTCATTTATGATCACATTTTGTAGATTCTTATCTCT ++ +;@@D;ADDHHGHFIG9?FHECA@C?CEGBIDH==F@CFFHGJAGEDHEEHC>EBDFFFFDEEDEDCEDD:5;@@ +@SRR800764.177 177/2 +AAATCACGAAGACTTTGAACTATTTGAGAGCCAGAGAATGGAGAAACATGTCTACCGTCAATTCCACCGAATCAAGGTTGACTTGGTTATCTATATTGATT ++ +CCCFFFFFHHGHHJGIGHIJJJJJJJJJIIIJJJJJJJIJJIGJIIJJGIAEFGGGHHHHIIDHIGHHHFFEDEDDE3;?CCACCCDDD:A@CDDDDDDE: +@SRR800764.178 178/2 +GAGAAAACCATAGAGGAATTATGATAACGGCACTCGCTATATCGTATGTCATTGCAGAGGGAGTCNGGCCTTTTATTGGTGGTGCATTTAATGAACATTTG ++ +@@@DFFFFHGHHHEGIDGIJJIIJICFGGGF>C;FHG=GIIIGIGGGE=CFDDHIDGCGII8=,7#,,55;@ACCCD@C58<'835;;AADDA:@CCCCC: +@SRR800764.179 179/2 +TTCTTACCCACTCTAATATCGACGTACTTCAGGTAGAATTCTGGATCAACATCACTCAAAATTAATTGATTTGCCTTTATAATTTTTTTTAAATCTGTATC ++ +CCCFFFFFHHHHHJJJJJJJJIJJHIIJJJJJJCGHHIJJJJIJIIIJJJIJJJJJJJJJIJJJJJJIEIHHDHHHFFFFFFFEEEEDDDDDDEDDEEEED +@SRR800764.180 180/2 +AGATGTACTTCTTGACGCTGTTTAAGTTCCATAAGAGGGATACAAATTTACTGGAAATTTTTGAGGCTGCTTTGTATACTCTGTATTCAAGATGGTCTGTG ++ +C@CFFFFFGHHHHIIJGIIIIIJIFHA(;@CCD +@SRR800764.181 181/2 +AGTATCAACCATAACCAAAACTCAGTAAGGGGCTCTACAGCGCAATTGCCTTTCACACCAGGCGGAATTCCCATGAAATCTGTCAAGACAGGTTCAGAACA ++ +@C?DFFFFHHHHHJJFIIJJJJJIJHGIIJH8CCCACD +@SRR800764.182 182/2 +GGTTCAGGTAAATCGAATTTCTTCGCTGCGATTAGATTTGTTCTTAGTGACGATTACTCTAATCTTAAGAGGGAAGAAAGGCAAGGGCTTATCCACCAAGG ++ +@@=DDFFFCFFHHJIJIIJJIJJIJJGEGI8FEHICIEHGHHHHICC################################## +@SRR800764.186 186/2 +ACTAAGTTGATTGTACGACGACAGGTCAAAGTTAAAGTTAAAGTCACCAGGTGTATAGACACCACATTGAAGGGGTGTCACAGCAATTTTTTTTATTTTTT ++ +@BCFDBBDHHFHGHIGIIIJJIJJIDGHIGGDEHGIJ@GFIIJ>BFHIJJG=BHEGHIGHEGHGHGHHHHFFDDC39;CCDDCBCC@CCCCBDDDDDCDCD +@SRR800764.187 187/2 +AAAGGTAAGTTACACTACACCAGAAGTGATATTGAAATTAGATTTATGAAGGATATCAAAAATCACTACGATCCAAATGGAATCTTGAACCCATACAAGTA ++ +B@?D?2A;<,AFD?CEGBFAHIDHGG2?FGII@B>C;>B5;?CCC@A +@SRR800764.188 188/2 +GAGAACATGCATCACGTACTCAATTCAACGAGACCTGACCATCGGTTTTGGTTTTACGATGACGTAACTCAGTACGGCAGAACAAAGTACCTTAATTATTA ++ +CCCFFFFFHHHHHJJJEHIIJJJIIIIJIIIIIBHIJIJJJJJJH7DFHGG@FHIBEIHFEHHFEFEDEEEECCDDDDDBBCACCBC>CC@@AACDCDEE: +@SRR800764.189 189/2 +TATCCTTCGCTGCTCATCTGATCTTTTTTTTATTGTTTCCTGTTGTTTTTATCTTTCTTCCTTTTCTAATTGTTCTTTAGTTTCTTTGCTTCTTTGTAATC ++ +1=+AD44=:C:FHG@F9E,A>,<)8)?FADFGBF;(555;3;(-;@(:>:5:ACCD;5; +@SRR800764.190 190/2 +TTTTGCAGCTTTACCAGTTGCTGATCATTTTTTTCCACTAAAAGTTTGTTCGTGTATTCTAGATGNGTCGTATAATTAATTAAGAAATTCTCCATCGACTG ++ +CCCFFFFFHHHHHJJIJHIIIJJJJJEIIIJJJJJJIJFIJIIJGHIJHIGHHIGHIJJJJIJIG#-;CHBDDEFEFEEEEDCCCDDDDDEDDCDCD?BBB +@SRR800764.191 191/2 +TCAATAATTTTATATATTTATTTATGGACTTATTCAGATACTTTTGCTGATAATGACGCCCCATCNAAACTACCAATTAGAGATTGTCTCTTATATTATAT ++ +@@@DDFDFGHHHHGGJIJGIIJIJGJJHGIJGJJIHJJJJIIIGIIGHIIHIIIJIJIGHIJJIG#-5BEIIHFHHHFEFFFBCEEA@CCCDDDCFDDEED +@SRR800764.192 192/2 +ATCCGAACAAACACTCATACAGGATAGTAACGCAAATCCAATCTTTGACAATTTCTCTTCCATTACCGGGATGTAGGATTAAATTCATAGAAAGAAATAAA ++ +CCCFFFFFHFGHHJIGGIIIJJFEHIGFEGIIIIJIIJJJGGJJJIEIJIGGIJJJJIJJJJJIJIHEHEACDCCCCDDCCCDDEDDDEDACCD>?CCDDC +@SRR800764.193 193/2 +TGATGGTGCAACAACAATAATAATAGTAATAGCAACAGTGGTAGTAACAATAACAATAACAATAACAATATCAATATCAATAATATATTATAATACTAATA ++ +81+4=:AB?F?3A+<;3E4<,ACCCCDDDD@C> +@SRR800764.195 195/2 +AAGACACCAGCGTCGCACAGCATTCGATAAGTAGAAATAAGAGATTTCCGCTAATTCTCGTGTTACCGATTTTTTCCTTTGTTCTTTTGTATCTAATGACT ++ +@@@DFFFDHHFHHIJGGIBBHHIIJJIIIIIHEIGIGHHGGJJFIIDHGJIIEGGHHHHHBDFFFCCD:@@BCDDDDDCCDCCCDDDCDDDDEEDCCCC>> +@SRR800764.196 196/2 +GATTTCTTATTGAGACCAATTAAGCAACGTCATAGAAACGAGGACAAGTACGTGTCGGTGGACGCTGCAGACGGATCGGTGTCTAAAATTGAGCCCATCGC ++ +?@1DD>DBFHFFDH=FHBDFH@HEE?AAB>9;?>==BB/-??@A:BA>@CD########### +@SRR800764.197 197/2 +TGAAAACTTTGCTGAAAGAAGAAGAAATCTCTGGTGGAAAGCTTTCTATTTCGAGAAAACTTTAGCCTCTAAACTTGGCTATCCTTCGAACATTGATGACT ++ +@@@DDDEF?BDFFJJIGIFGG;EHCHGGEIHJIJCAE?FHIAFHIJGIGGDGFBB9:)=CFHJIC4=CHIGCGEEEHE;;BDDEECE?CDD@CCCCCACA@ +@SRR800764.198 198/2 +TGTTGAAGATGGTCCACGTCCATTCAAGGTCTTCTTGGATATTGGTTTGCAAAGAACCACCACTGGTGCCAGAGTTTTCGGTGCTCTAAAGGGTGCTTCTG ++ +BC@FDEFFFFFFHIGCHIGFHGEGGIJJJGDHIGHHFI>GIGIEIBFHEBAGHGHGIIEHHIGGAH=C@EHCCE?EEFFE?5;?CCCC@CCCB(8?ACCCC +@SRR800764.199 199/2 +TCGCTAAAGCCATATGGCTTAAAGGCTGTCTCCATTTCTTACAGTGCTTTAGGTTCCATCAAAGANTTGAACCAACTCTTGAAATTAGTCTCTGAAAAAGA ++ +@@BFFFHIJJ?@FHIBGIIGIIJJGGIIJIJJJGIJJIHGHGHFFFFFDDBCBDDDDDEED@?CBCBBBBBDBDCDACC +@SRR800764.201 201/2 +ATTTTTTATTAACGCTTTTAATTTTTCTTGTCTTAGTCTTCGTAATTTCCAGTTAATCGCAACGTTCAGAATGATAGTATGGCGCTATCATGTTGTGCTCT ++ +;1;?D?)A4CCAFABHIJEF<9/..)).-5;'';.76ACCDD;;?((6>(.6;988''5@DC,(+3?CC>@ +@SRR800764.202 202/2 +GGACATGGTGCTCTATTTGACTATCCCAAAGCTAAAAAATCTGCAAGATATTGCATCCAAGATATATGCCAATGGGGGTGTGATCGCTGCCATCTGTCATG ++ +1:+4BD?322+2+:35>3>:??A###### +@SRR800764.204 204/2 +GTACTTCTGTTCTTGGTCATGTTCTACGTGAGTCGAAATGTCGTTGTAATGAAGGCTTTCTTGATTTTGCCAATTATACTCTAGCGCATCACTTAACAATC ++ +@?EAEEHFDB@CCCDDDDAC:>(5@CD>: +@SRR800764.205 205/2 +GATACTGTTGATGGGAACTTGCTTCGCCGTAAAAAACTTTATGAAAAGGTTTTACCAAAGCTAACTTCGTTGGAAACAATAATAGCTCCAACTGTATTGCA ++ +@???DDFEHGDAFIGIIGIIJIJJJIJJJIJIJJJJGIIIJIIEHGHGJ7=CFHJIIEHHHHHFFFFFFDECDCEDDDDDDDCDDD@CCDCDD>>@ADDDC +@SRR800764.206 206/2 +GGATTGTTAAAGGCTCTTTTTCGGAAGCCACATATTCCTATGCTGCACCAGCAATTGGTGTCTTCGGATCATACTACTTCGCACTAGTTTCTATTCAAGGC ++ +++++42=BFHB@3>@B/3;8:@5;5(5(,5@BCACCDDDCDDEDEEDDDDDDDDDDDDD? +@SRR800764.208 208/2 +CATTTTTACTTTTTTTATATATTAATTTTAATAATATTATTATTATTATATTCATTAAAATTATTAAATTTTTTTATTATTGTTATATCCTTAAGGATAAT ++ +<@@D??AD??CB?EHIGIIGFGIJEIJIIJIJIGGIGGIGGGIIIIJJGIEHIIJJEHIGHEGIIJ<>FHIHIHFFFFEDBCCECEDC@C>CDCC:ACCCC +@SRR800764.209 209/2 +TGGAGTACGGGAGTTAAATCGCTGATCTTTTCCAAAATAGCTTTTCTCACAGTTTCCCAAACGGCAGCCACACCGATCATAATAGTAAGCTTAAACTCAAC ++ +:8=4A=ABFF@8@AEFAHJ@E7B@FHB:C9**:0:BDFG<9*9DFHGD??DB./8/)B=FGE;1:=BBCBEC=;;=8/;>C>ACA:@(4(4::>3>:@C?< +@SRR800764.210 210/2 +ATATATATTTTTTATTCATAAAAATTCCTTTTGAAGATTTTTATTTTATTTTTATATAAATATCTNTTAATATTTATAATAAATAATAATATATTCATTAT ++ +CCCFFFFFHHHHHJJJJJJJJJJJJJJJJJJJJJJJIJJJJJJJJJJIJJIJJIJIJGIIJJJII#.;FHGIJJJIFJHGHHHHHFFFFFFEEECDEEEEE +@SRR800764.211 211/2 +ATTATTTATAAATCATAAATTATTATTAATTAATAATTTAATTAATAAGTATTAACATTTTATAATTAAAATATAAATATTAACTTCTTTATATTTAATAT ++ +CCCFFFFFHHHHHJJJJJIJJJJJIJJJJJJJJJJIJJIJJJJJJJJJJHGIIJJJJJJJJJIHJJJJHJJIJJIIGIIJIJJIJJIIJJJJJIJJJGHGH +@SRR800764.212 212/2 +CACTAAAATTGCAGAAAAAAGTGTACAATATCAGTAAATAAAATTGGCCAAAACAATACCATTAAAACCAGTCATGTCCATGCAACAAGTCCAACATTGTG ++ +B@@DDFFDHFCDCCD +@SRR800764.213 213/2 +TTGAGGCAGAAAACTTGTTCGCTAGCTCACTGTTGATTCGCATAGCTGAAATCCATCAACTACTTTGTTTCCACACCGTTCTGTGAGAATGATTTGTATAA ++ +@=8:=:2A2:AD;?G@+2+3382+1:*1CCH**1***:*))8)(/*9/*).B4B)8@F7@DG3)@G3AE################################ +@SRR800764.214 214/2 +TAAATAAATAAATAATAATTATAATAATAATAAATTTATTATGTAATTAAATTAAATTAAATTACATTGTATTATATTATTCATTATATTAATTATATGAA ++ +?@@DDEDDHDHFDHGIJIEHIIIJGHJJJGHGEHEHEHIJJJGFHIHIHIHGGHIHIGIIJJEGIIJIJDGIHIIECEEFHJIJJJJ>FHHIJGGGCHFF? +@SRR800764.215 215/2 +AACTTCGTCAAATTCTTCCAGGGACATCTTTCCCTTTATTTATTGGTATATTAATGGATGCAACTNTTATTCGATATTAGTCCTTTCGGGACTTTAAAAGC ++ +?=?DB?BDFBHHFBHHEEIIED@GG83='=A;BDFFFE@5>:@;5:A<3>:A? +@SRR800764.216 216/2 +TTTCGGCTTTAAAACCATCATATACCGACACTGCCACTTCTTCCATTACCATCTTCTCCAAATCAGCATCTCTAATCTCTTCTTTTTTGTAACGTCGTTGT ++ +CCCFFFFFHHHHHJJJJJJJJJJIJIJJIIIIIJJJJJJJJJJJJJJJJJIJIJJJJJJJJJJJHHHHHHFFFFFFEEEEEEEDDDDDBACDD@CDDDDC? +@SRR800764.217 217/2 +TAATATAAGATTCTTTTTAATTATAATAATAAATAAATAAAAAGAAGATATTATCAATGATTTATATTAATAATAAATATAAATAATAAAAAATATATATA ++ +?@GIGEFGF?CGGIGFC4AA9?BF@FBAEHHGHCHB=CD1@CC>CBCCCC;5>>CC:<;:3>CDDDCC +@SRR800764.220 220/2 +TCTGTGCTTTAGCTCACGTAAGTACTCCGGATCCTGCTTAAGGCGCGAATAGGCGTAGTGCCATCCGTCCTTGATATGGCCCCCCATATAATCTGAGCCTC ++ +CCCFDDFFHHHHHJJJJJFHJICJJJJJGIFJIIJJJJJJJJJJJJJIJBEHIHHEDFCCDEEEDDDBBDDDDDCEEDCDDDDDBBACCDDDCCDDC@CA< +@SRR800764.221 221/2 +CCGGGTTTTTTTTTCTCTTTCTTTTTCGCCCACTGGAGAGCCTCAGTCATATATGTCAAAGAAGACTGGTTGAGTAGCATGGGCTTCGGTACCAGGATTTA ++ +@@B?BFHBDHGICFF6@D'7CHC3==-(6C>C?77;B7;7;;7;(>A;(5;>AC@B@@?:@5@ACA34?A19?############### +@SRR800764.222 222/2 +AAAACAATAAAACAGCAAATTGATCATAATACTCCAATGAAGAAAGGTTCTATGATATATAACCCGAAAACTATGAAGTGGGAAGGAAATGAAAACGTCTT ++ +CC@DDFFFHGGHHJIEGHJHIGIHIIIIJGEIGHIJJIJIIIJGG@G*BFFGHIGHIEIGIIGHGGIIJHHHEEHDFD;@DAACDBBDDDDCCDACDDDD8 +@SRR800764.223 223/2 +TGCTTCACAACTGTACTTAATGAACTGAATCAATTTCCTTGGCAATGCAAATTCTTCCAGACAAGAGGCGGCCGCGGCGGTATCTCTAGAAAATTTGGCAG ++ +@@<1?;C@@B=35)0)0(4>@C@>>CCD3:3+:@@7 +@SRR800764.224 224/2 +TACAATATGGAGGAAACGTTGCGTAATCGTTGTCGCTATAGATATTGTCCCTCCCTTCCTCTGTGATAGTTCTTCTTTATATAACTTTCACAAAAGCTTCT ++ +@@@FDDDEA?FHHIIFGGFHGEIECEFHFIIIGGHGGGEIIIGJGIIGGIHGIFHCGHIJJHGHHGEFD?CEFFECEEEEEDCDDCEDDDDDCDDCB@@@: +@SRR800764.225 225/2 +TTACTATGCAAGTAATGTTTCTGCCTGCACCGGCTTCGTAGCTGGTGGAGTGCGATAGCGATGATACTACCTGAAAACACAGAGGAAGGCCGTCAGCCCCG ++ +@C@FFFFDFFH>:F@HH9??C@??>9FG??00:?:?B3BECAHHFFFFDCBDDDEDDCDDDDCDCCD<>AC< +@SRR800764.231 231/2 +GCCATTGCAAAATATTAATATTGTAAAAGCAGAGAATACCGGTAACGGTAAATCAGATCCATATAGCTCAATTAAAATAAGCAAACCGACAAAAACCGTGA ++ +B@=D:+ABDB:<?;?@;>A>8?@D<98A< +@SRR800764.232 232/2 +TAACTCTGGTATGCAATTGTGGTGGCATAGGGAAACAAACATCTTCTTCCGTCTCTTGAGAATCTCTCGACGCCTGTGATACGTCACTATCAAAAGAAGCT ++ +@@@FDDFFH=DDFIGHIJI@ADCDDDDDCCDDCACCDFF@BBAHHFFBDDBCDCDDDCC?@CCD>B>3>:>A@>>>ADA +@SRR800764.234 234/2 +TTAAAGTGGAAATAGCCCTCTCTTTTGCTTTTCTTGAGTTTTATCTAATGGCTCTAATAAGGAAANACGGGAAGAAAAGGAAAGAAAAAAAATACAAGAAA ++ +?B;ADADBBA@C6>.6>A(5(;CCDDDCDDEDD@@B>: +@SRR800764.236 236/2 +TATATTCGGCGTCATGGCGTTCAATTCTTCTGCGGAAATCGGTTGGACGGATTTGGCATCCGCTAATATATCTAAAATGGGCAAGAAGGTCTGAGGGGTTT ++ +?;@DDDBBAC6)0)29+A??0):?CHHI9@676@.@;@-;'5)7,99'';5;3;;?CB128>@CAABCCD3>CD####################### +@SRR800764.237 237/2 +CAGAGGAGGCAAAGGCAAAAGCAGTTGCAGAACAAGAGAAAGAGGCAAAGGCAAAAGAAAAGATAGCTGAACCTGAACCTGAACCTGTACCCACACTTCAA ++ +@BCABDDFHH:CBFHGHJIHJIIGFHHDGI@DFEGGGEAFGHIIIAE;5=C;A:5<:BD>@DC?:>BDCBA>CD>:CCD +@SRR800764.239 239/2 +ATCAGCAAAATAGAAAATAAACGGGCAATCAATCAATAACTACAGGAATATTGGGAGGTTTTAACTAAAATTTCCAGGATATTTCAACTTTTCATAAATCA ++ +:?==DD:2A:<<:AE37)))7.?BE######################### +@SRR800764.240 240/2 +CTACCATAGACGACAACTCAATTTTATTTTCAGAGCCTCCTCAGAAACAATCTATGATGATGTCTATATGCGTAGGTGTTTTTGTTGCAGTTGGCGGATTT ++ +@@@FABDABH?CFGHEHHIE;EHIEIHI9FI@GIIDDF9BFEFD>?BFGGGFFIID>AGGHIJIIIEDEHGH?EFDCCE=C>=;AA2>::C@A@C89&95@ +@SRR800764.241 241/2 +AGGAAACGAATAGTGGTTTCAAAAAATGCCTTTCACTCGTAGAGAAAACAATAAAAGTTACCGCACTCCAACACAGGCGATACTGGAGGATTATTTTCAAG ++ +CCCFFFFFGHHHHFHIGHJJJJIJJJJJGIJJJJJJJIJIJJJJJJGIJJHIJJJJJFGIJJJHHFFFEDEEDDDDBDDDGHHDGGIGCIGICFIDH@CBFHGI=FHICHIIFGHHH?DFDFAC;ABDA>@CDDC@>CD;=@? +@SRR800764.244 244/2 +CGAATCTGCCACTGCTTCCTCCGACGCTTCTTCTGCTTCAGAATCCTCTTCAGCTTCTTCTTCCTCTGCTTCAGAATCTTCTTCTGCTGCCTCCTCTTCTG ++ +??@############################# +@SRR800764.245 245/2 +ATAAGTGCGTTCATCTCATGGATCCTCGTGAGCAACATTTTCATATTCATCTTCTGGTCAACCACCTTTGTATCTTTGATCCTTTACTTATTCAATACCGT ++ +?B@FB?AB:AA:DE9A9,??333?;C?8C8*1?CC8?DH9*4BF<4??FI?E)7?CEF:A;C########### +@SRR800764.246 246/2 +ATATATTATTATTTATAATAATAAATAATATTATAATAAGGATGCATATTATATATATATATATTATATTTCTCCTTCCGGGGTTCCGGCTCCCGTGGCCG ++ +CCCFFFFFHHHHHJJJJJJJJJJJJJJJIJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJIJJIJJIIJJJJIJJJ=BDFFDDDDDB@?BD### +@SRR800764.247 247/2 +TAGGAAATGAAGCGGTAAAGGTTTGCGATGAGATGTACCTCCGATGTTTTTTGTCTTTATTCAAATATGGACGAAATAAGCCGCCCAAAGGTCTGACAGCA ++ +CCCFFFFFHGHHGJJFHIIJJFHIIJJIJJIJIIJIIIIIJJIEHHIHIJHIICEHHHHHHFFFFFFFEDDEDBDDDDDDACBDDDDBDDD:CACCDDDDD +@SRR800764.248 248/2 +TGATTATATTATAATATTTTAATATTTATTTCACTTATTATTTATTAGGAACTTTATATCTTAATCTGGGCTGTTTCCCTTTAGATTATTTACCTTATCGC ++ +CCCFFFFFGHHHHJJJJJJJJJJJJJJJJJJJJIJJJJJIIJJJIJIJJIGHIJJJIJIJJJIJJJJJIJJJIGEGIIIIJJJGIJJIIIGHGHHHFFFFE +@SRR800764.249 249/2 +AAGGTAACATGACTGCTGTGCGTCGCTCAACTAGAATAAGGACTAAATCTCAAGTTATTGAGGAAGATTACGATGACGAGCAAAACACCAGCGCACAACAC ++ +@?BDBDDFBDC?FIGEBHGGIJJIGIJIBEFIAFGEHGGIGJGHDFHGEGFHI9CHIGHAA77CD@C;=AHBDDEAEB;,;>C9ABBA?B??@BB@BBDBB +@SRR800764.250 250/2 +CATTGAGTATCAAGTCTGGTAATGCTGCAATTTTGAAGGGTGGTAAAGAGTCTGTGAACACGTTCNGAGAAATGGCAAAGATCGTTAACGACACCATTGCA ++ +?@@FDBDABCDHDEAE:CEHHFG@EHIIEEHDGGFFHHAB??GH58=68?8>CDC# diff --git a/latch_cli/services/init/new_example_snakemake/data/samples/B.fastq b/latch_cli/services/init/new_example_snakemake/data/samples/B.fastq new file mode 100644 index 00000000..e022e580 --- /dev/null +++ b/latch_cli/services/init/new_example_snakemake/data/samples/B.fastq @@ -0,0 +1,1000 @@ +@SRR800764.25001 25001/2 +CTCGTTGATAGCAGCAAAAACTTCTGATTCAATGCGTTGTGTGCATCAGCTACGGCAGTATTTGACGGTACTATCAAAAGACCATTAATATTTTTTAAAGA ++ +??1B=+AB:?:AFB;C:CF??EFDHHGCCBCCF@E?1:@DDGHCC4*?BHCGAAAB;E==;@E>EE=D';>(;>A@5>CCDCDCDCCDDEB@@C@BDDDDA +@SRR800764.25002 25002/2 +TAGCACCTTCAGGACAATGCAAGTGGATAGACGCCTTTTCAAAAAATCTGTTCTCATGGAATTTTTGTGCTAAATACATCTTGGCGAATGAATAAGCAAGT ++ +;?1B4ADEAHD?83EB:FGIII<3ABCBIHJGGBGHJJJG>F@DEBD>GGBB8=C;)==7CAHEH>4?=:@;;7;@;AEEECC;>@@?B::>CDC@@C3<> +@SRR800764.25003 25003/2 +ATTCAAATTGGCAATCACTCAAGGCTCCTAATCCATACTTTTTAGCATAAGTGATATTATAGTGCCCAGTGGCTAGGGCATCCCAACATTCATTTAGGATA ++ +@@@D?DDDHHGFHIGGGIJEHIJIIJJIJIIIGIIJIIIJIIG?13>>>ACC###### +@SRR800764.25004 25004/2 +TATAAATTATTAATATATCCTTTTTAATAAAATAAAAAGGGGCATTATAAATATTAATAATTAATTTTTTTTTTATTTATATTTATATATATATTAAAGAT ++ +@CCFFFFFHHHGGJIJIJIJJJJJJJIJGIJJJIJJJJJJJJIDIJJJIJIIJJIIHIIJJIJIIHJJJIHFDDDDDEEEEFEFEEDEDEEEADECDCCCA +@SRR800764.25005 25005/2 +AACTACTGCTTATATATGGTGCAGAAAAGTGGCTCGGAATGAACACCTCTTTTAATTAAAAATTCATTTATAAAGTACAGGGCCTTCACGCCGCTTAGTAT ++ +@@?BA;B?DCFDFHHBEAEEE>@BAH@@@0?6BA*9?9BB(B(?################################################### +@SRR800764.25006 25006/2 +TTGACAGAAGATCTATATGACGAATTGCTTAAGCACAGATTGAATATTGATGAAGCCTTGAGAAGGCTAGGATCCAAGAGACCAAAAACCAAAATGGTTAG ++ +@B@DDFFFHH8?DHGGGHIGGIIIGGHIHEBFIHIGDHGGGF>D>4?@DGBDEEH?FCHIEE=EGEIJICGHECE>:AB>;;?AC@AA?=AABA:>C>:A# +@SRR800764.25007 25007/2 +TTTTAATATCAATAGATGCTGGTGTTACTAAAGGATTACCAGGAATATAGTTATCAGGATGCTTTTATAATAAATATAAAATGGACTATATCTTCATAAAA ++ +?@@FF?DFF?HHJFGHHIGII@GGGGHBDBHICBGG?DBF?BBGEIEHIG7?EEHFFEC:ACCCDDCEC +@SRR800764.25008 25008/2 +CTGACTTATATATGCGAATGCACATGAATAGACCGCATATGCTTCTTATCAGTCTTACCTCGCTTATCTTTCCCCATTTATTTGCCAATCCATCTTATCTT ++ +@C@DFFFFHHGHHGIIIJIHIIJJJIJJJJJJIIIIIJJJJJIJJIIIIIEFCHIEHGIGIIJJGHHHHFDFFCDCCECDEDEDDCCCCDCCDCCCDDCC@ +@SRR800764.25009 25009/2 +TAACTTTAGTTTTCAAATCTATCATCAATTCTTGAAGAACTGGAGAGCTTTCTAACGTATTCCCATATAATTCTAAAACCACGGCGACCCAATCCGCTACA ++ +CC@FDFFFAFHHHBHIJIJJJJIJJJJJJJIIJIFIJJJIJJHIJFCADHGGHIIGIBFHIFGGIDIJEIIIGIIIGEHDEEEFFDDDDDD?CCCBDDDD@ +@SRR800764.25010 25010/2 +AATAAATAATATACTATGTTTTATTAAATGAGATAATAATAAAATTTTATTATTATTAGATATATATTATAATGTATTATATAACTATCATAAACAACGTA ++ +CC@DFDDFGHHHHJJJIIJJJJJJJJJJJJJJJIIIIJJJIJGIIGIIIJJJJIJJDCGIHHIIIJJJJJJJIIBFGIIIJJIJJJJJJIJGIIJHHHF?> +@SRR800764.25011 25011/2 +TAGTACTTATGATGGTTTTGGTCTAGCTTGGGCAATTGCTGAACATATCGCAAGTAAGATTGGATGTTTCGCTTTGTTTGCAACTCACTTTCATGAATTGA ++ +CCCDFFFFHHHHHJJHIJJJJHIJJJFJIJJJJJJJJJIJJJJJJJIJJJGHIJHJJJJJJJJJJJGHIJHHHFFFFFEEEEEEDDCCDDDDDEDDDEEDC +@SRR800764.25012 25012/2 +GAATATTTATCAAGTGCATAGGATATGAGAAATTCTTTTATTGGATCAATTTCTCTTGAATGAGTTTGCCTCAACGAGTCGAAAGTCAAAATATTAACCAG ++ +?@@D=:ABDFHABHHEBHEGBHC@FEGGBFHEGGDHHG:BDHGCHIJIBFIJBG@HCC;/BB@DECC=>;>C>@BCDDD@ +@SRR800764.25013 25013/2 +CCTCAGCAGTAACTCCATCTACCTTTGGGGATTTGAACCATCTCATTCCAGTTTTGGATAACTGCGATTAGATTAAAAGATTAAAAGATTATCGATTAGAT ++ +CC@FFFFFHFHHHJJJJIJJJIIGJJJJJJ?GHJJJJJIIIJIIJIJIIJHFHIJIJGGIJJEIJIIJJHGHHHGFFFFDEEEEDEEDCDDDDDDDDDDDA +@SRR800764.25014 25014/2 +ACAGACTCTGTTAATATTTAAAAATTTTTCCTTTTCGGCAAGCACTGTGTTAACTAATTGTGCAAAAGCTTTGCTGGTTAACTCGGACTTCAACTTAGACT ++ +@@BF;;DDFHDFDEGGGIHHJIIIJGGIJJJIGIJJJIJJEHGG?FGDBDEGGIG@CHHIEFHCDDEEGGHGCEECCDDFFEEDDDDBBDDACDCCD@CC: +@SRR800764.25015 25015/2 +TATCAATAAATAATTCCTTTGAACTATTTATTATTTTATTATATTTATTTTCTCCTTCATTATTAATTTTTATTAATAATTAAAATCTTATCATTTTATGG ++ +@@CFFFFFHHGAHHGICHGIJIJJJJGIJJJJJJIJJJJJJJJJJIJJJIGFHIIIIGIHIGCAA2;;?BCEECECA@; +@SRR800764.25017 25017/2 +TATAAATCTTGTATACACTTCCTCAAATTCAAAGTTTTTGCCATTTAACTGGGGTGTCTGGGATGAATTCAAAACACGATACAGAATACAACAGTATCAGG ++ +@@@FDBDDHHDDFHAHGDHIIJJIIIIJIJ@EGG?FFHJJGICFHGIIIIE>GGFD7BFHGG9FHE=DGEHEHCHCBE?CCADDDDC@>>>@AB:@BCDDC +@SRR800764.25018 25018/2 +CTGGTAAAGGAGCTTATTTTGCAACCCCACCCGTACAACTAATTAATAGCCTTGATGTAGCCTTGAAAGAAATTCTCGAAGAGGGGTTGCATAAGAGATGG ++ +???DDDFFH>;FFHHGBGIIIIGHGGDHEHIGI8?DGGJDGBGFHIA>;=?B=@@<>>CDCDDDDD@ +@SRR800764.25019 25019/2 +AAAATATCATTGAAAAAGCACTCATTCTGGTTAAAGTCGCTGAACAAATTGGAAAGATCCAGTAAAGCTTTTTCTTTTGTAGTTTCATCTCTTTTCAGAAA ++ +1:8AD+2A4A=,AGHIA)+7)76A3(-=B7?37?################### +@SRR800764.25022 25022/2 +CTAACCTTAAGACCTGAAAAATGAACAGAGTTTTTATAAAATTTCAGTTTAAAATTGAATGTTGCCCTAACAATATGGATTAAAACCCTGACATATTAGGT ++ +@B?D=+ADDD>FHIEIEGHHJGG>HHIJEGHI@>GEDHIJIIIICB>GIG@GHI:D??FEHAF>FABACC@FG;C;CD@;>EHCHBD?;;@CA>;;C@### +@SRR800764.25023 25023/2 +TCTATCTAACGAGACCTTTGATTGAACGACAAAACTTAACATATCAGACAAACGATCCAAAGGATCTCTTAATAACGTGAATAAAGAAAGCGCAGTAAAGG ++ +1?+B=DADFBDFCFB?('5-&2>ACC> +@SRR800764.25024 25024/2 +ACAAGACTAAGCGAAGGAGAGAAAAATGCTTGAAATTTCGATTAAAAAAAAAAGGTGAGATGCAAGGTTGGTTAATATTACTGTGAATTGAATAAATTTCC ++ +@@@DD8BD?BDFA:EG6+<2BGIIEDG(?FHGIIDDC9;(5(=(>@:5AC(555-(2(+4>BD@##################### +@SRR800764.25025 25025/2 +TATATAAAATAAGCCAAGACAGTGGCCTTCCCTTATTATCAGCGTACTAAAATCTCATATGATTTATTTTTCGTGGTCCTGAACGAGTGTGAAAAATTTTG ++ +?;8BDDDFF?FHCBGEEEEEHJE:?FCGCCBGA>GGIDFAI>GHBF6B@??9EG?B)==888CHGHG>DC:@@AC'=?@>;)(6;'35=((;>>>AACC@3 +@SRR800764.25026 25026/2 +CTTCAAAAAGCATCTCTGGAAGAAGATCCGGCAAACCACGAATTCTGTTTGATTCTGCCAGAGCTCAAAGAAACTCCAAACGCAACCATTCTCTGAAAGCG ++ +C@@FFFFFFHFFHEGIFIIIJJIJIFIGIIIDEHGGIJJIGIGGIIJGIJ@FIAFHHIGEGHFHHFFDFFFEE3;;ACCDDDDDDBDDC:BDACDCDDCDB +@SRR800764.25027 25027/2 +AAAGCCAAGTTATCTGCCTACGGTTGTCACAGCAACATTGCGTGCCGTTGTTCTTTTGTTTTTTTTTTTTGTTTTTTTTTGTGGTTTTCGCAGCAACGAAC ++ +B@@B;;D:B2<CE=BCD);BDC>CEEDAACDD@=?@B?A?CDCCDCCDDDCDCC?>3 +@SRR800764.25029 25029/2 +AAATGCTGTAGTTACGAATACAGCTAGTGGCCGCTTCGATGTAACGCCCACTGTTCAAGACTACGTGTTTATACTTGACTTAAAAAAGCCGGAAAAACTAG ++ ++??D:+:DB>CF,1):8@@6@89909B?B####################################################### +@SRR800764.25030 25030/2 +ACAAAAGTTTTATTCGATCAATACATCGTTATACTGAATCTACTTTGGTGAAGCAGGGTTATCTTTACTGCTATACATTGGACAAGATTTATTTGTTCTAA ++ +@@@FDFDDCHFADGGH9EHII@EGIJGG;FCGIJIJJJIIEHIFJGDCBDGDGGI;FGHH=7=CHGDGEHE@CHEHHHHHG;CCC>@=@:;; +@SRR800764.25031 25031/2 +GATTCCAATGATAAGTTTGTGCATGTCCAGCTGTTAATTAACTTGAAAATCTCACCGTTGATGAAAAGTCAATACAATATGGTATTGAGGAACGTTATGGA ++ +CCCFFFFFHHHGGIIGHIIHHJJIJJIJJJJJJAGHIJJIIJIJJJIJII9BDHIFGGHIHGGIJJIJIGHIJJJIJJIFHG7?CEHFFFFFEDACCDDDD +@SRR800764.25032 25032/2 +AATAATTGTAGGGATAAATTTAAATATGGCATAAACTAAATAAGGAGAGCATGAAAAAACTGCAAAATCCAAAAAGCAAAAACGAAGGTCAGAAAGTAAAG ++ +8@1;?BABC4A>1A+H9BA@GGG3300BBFCG<***9--=@)=CHC@DEHC?############################ +@SRR800764.25033 25033/2 +ACTAAAACGTGGTGAAAGGAAATTAATATTTCCTGATCATTTCTTATGACTATAATTTTACGGCTTTCCTTCTTTTTATTTAGCTTTGCAAATTGCAACTC ++ +?;?=DDFFFHH?AE@F+FE@FGE>DF>4BDFHFAGGHIE9*09BF;:'-'=CG@;.7)77)6;???;?B:>CCDDA;;(;>CCDC +@SRR800764.25034 25034/2 +ATAAATAAAATAAAAAATAATAAATATTAATATTATTAAATATTATTTATAATAAATATTAATATTATTAAATATTATTCATATTAATAAATTTTATTATT ++ +BC@FFDBDHADHHBDHBEHHGH>HHGBF@HG?CED?GFHBFFHE@HGHHIH>FGGGIDGFHIJCIE:BCCGGDGGFGHJJIJJBG:@E>CEAE>EEHFFFF +@SRR800764.25035 25035/2 +ATTTATAAAATTATAAAATTAATTTATATATAATTCAATATATATATATTAATTTATATATTTAAATTAAATATAATTAAATAAATAATAAGATCGGAAGA ++ +?@CFDBDDFB?EHCH>?BFAEE@FA;E=4=4AED@ +@SRR800764.25036 25036/2 +CTCAACCACAAACTTTGAAAGTGTATGACTACAAGGGCAGTGGTGGGGCCATGGCCATGTACAATACTGACGAATCCATCGAAGGGTTTGCTCATTCGTCT ++ +;C>C@B=;@CC?>C??B5??BD(:>@:3:>2< +@SRR800764.25037 25037/2 +AGCAACCTACTTTATCTCAATCGAAAACGAAGTAAAGTTGCGGTTCCCTCTGTCTCTCCTAATATTATCCTAAATTTATGTTTACAGTCGCAAATTAGATA ++ +@@@DFFFFHHHGHJJJGIJJJJIJIIGIJIJIHIJJJIIIJJIFGDGIJIFIGGI>DHHIG>EEEFHG>A@@EFDEDEEC@@@ACCDBCBDBB=@ACCDCC +@SRR800764.25038 25038/2 +CTGATTTATCACTGCAAATGAAAAGCAATCAATACGAGATATTTTTCAATCAGTCAATTTCTGTGAAGAAGATCATTTTAGAAACAATGCCTAAATTTGAA ++ +@@@BDADFFAHGG9EGICIIJGIFGIIGDGGHH@DEEGIHHAHFHDB3;;AACECCC;>A@ +@SRR800764.25039 25039/2 +TTCCATGTGTAGATTTTTAAGGCAACGATTATTAATTCATTTACGACCAAAGCAGTGAAGCAAATAGCAACCATCCTTGTGAAATCAGTATCTAATAAAGT ++ +1++4=,,222C?,,<@G>F@9):8)?D?)8CG8B############################################ +@SRR800764.25040 25040/2 +CCCCTGCATTAATCGCTCTTTCATTTTCAATTTCTTTCTCGGAGTCCGCTATCTTTGTATCTTCTTCTTTCTCGTTTTTACTTATTAAAAATTCGATAGCG ++ +1++4A:3BF4+FEGHHHIJIGGHHGGGHIGGGGIGEHHHHHFFFFFFEDEEECEE +@SRR800764.25042 25042/2 +CCGCACGAGAATTTGTGAAACGTGGCATGTGGGGAACCCGCATGAATAGAAAATATGCTAGACACGACTCTTGTTTACATTGCCATTGGTGGTGTATGTAC ++ +:++=B8BA?))A@ADBDB>C>@AC@3>A>A@CC@CCD +@SRR800764.25044 25044/2 +CCGAATAATCTCTCTTTTTGCTATTTAGGGGAGTCAGTAGAAGGTTTTCGTGTGATTCATCAACTGTTTCTTGAGAACTATTCAACTGAGATGAGAGGGCT ++ +BBECEECCD@@CCC>ACA>@A8:?2 +@SRR800764.25045 25045/2 +ACTATTTACAAAGTTGAAGGTTCCGGATGGATACAGAATAGGGATCCTAAATATAAACACTATATTTATTTATTTTTTTCGAATAAAAGTCAAGTTAGCAA ++ +@@@BDFBFFDBHHIIIBHIJHGEGGIB?CHG@>D>DHAE9DGDHH@FDFHHB<8=CBFG@@;FGI4@@@E(7AC;;@DED36;>C;ACDDACC=<<ACAB? +@SRR800764.25047 25047/2 +CAAAGTAATAGAGCAAAAGTGACATCCGCAGCAAGCTGGACAGGTAAATTGCCTCATACAGTCTTACACGAAACATGTCAGAAACGAAAATGGAATAAGGT ++ +;;@;AD>?D?BDDBEGAHHAC?H?F>C@C(-5>@;?BD@CC######## +@SRR800764.25048 25048/2 +TCATCTAAATCGAATTCTGATACATTTTCCATGTCAGTTGGTAATTGATGCGAGCACGCTAGTAAATATGATGTACTTGTAGGTCTCCAGAAGAATGCGAA ++ +@@BFFDDFHFFDDEHFC>CCEEEDCDD?CCDCB@? +@SRR800764.25049 25049/2 +AAACAGGTAATGATACAGTAGGGCAGGATACATCACTTTCTGTACACTATTATACGCAGGCAGCGTTAAAAGGCGATTCTGTGGCAATGTTAGGTTTATGT ++ +@CCFFFFBFHHHHJJJIJIJIJJJJJJJJJJJJJIIJJJIIJIJJJJJJJGIJIJIIIJJJGGGHEHHFFFDFDCBBDDDEDCCDCCDD:>BCC+44?CCC +@SRR800764.25050 25050/2 +TAAGTTTGAATAAATTGAGATATTTGGATGCCGTATCGAGCTTTAATTCAAGTTCAGTCAAGTCGAATTTCGCGTCTAAGGTCAATACCCAGCTAAACCTT ++ +@@?DADDFGHHHFGGHE>HCHIIJIGEGIGGFFEE?DHHG)BDDF<9??D?DBF><88BGF>8@CC=EGI:D==9ACAA5=>3;A@C(>:A?CC +@SRR800764.25051 25051/2 +GACATTGAAGGGCTGATTAAACATAAAATAGAATTTGACTCAAGAAACATGAGCCAAGACGAAATTGAAGATGGCAACTCTTCTCAATCTCTGAATATATA ++ +;=@?BD442A;F7FADGH@HICCFGIJIE?<9C99::?<:DC;??;DBFH3?9D@;FDAA@AAG=D:;CECA3?7)).?>AC;@CEA(5(5@CC@@##### +@SRR800764.25052 25052/2 +CGTCGTGAGACTACCTGGTTGTGATTTGGGTAGTTTCCTACTTATGGATCGGTTCCTTAGATACGGTGGACGGCTACTGGTTGCATACATCTGGCTTCTTA ++ ++:1BD0)+<<2+++<3:<1+AFIEFD1*1:?D4B9 +@SRR800764.25054 25054/2 +AATCCTAGGATCTACCTTTATACGCATTTATCCTATAAAAACCCAATCTTTCAAATACACAGTATTTTATATGTGTGATTTCCTTGATTGACTCAATTTAA ++ +<@=C=D:@AD=CEHHC################### +@SRR800764.25055 25055/2 +TGTCAAGACGTTTTGGTAATAAATGCTACTTGAAAACCCTCAAGAGTCGCTACAAACTTGCCGTTCCTTAATAAATAAAGGCAAGCGTTATATACATGATA ++ +BDFHHFHBDF22CHHIIJEGC9FFBEFCDGIIGIIGD3FH?DAD'7FHHC(.==;);=E?;B;@C>@@C;@A>;5(5==55(58?C3>34@C>:> +@SRR800764.25056 25056/2 +GAAGAAAGAAAACATAACGATGCTTTACTTCGTGGGAAAGACATATTCCAGGATGTGTGGTTCCCTATGTTATTCTGCTTCAATGATACGATCATGACAGC ++ +CCCFFFFFHHHHHJJIJJIJJIGJIJJJJJJJHIJJGJJJIJIJJGIJIIFIEHHFHIIJ@EHIHHGHGHEFFFFFFFEEEEEEEDDEDDBDDDDDDCCCB +@SRR800764.25057 25057/2 +AGAGCCATCTTTACAACCAATAACCATATACTTACCATCATGACTAAACGTACAGCAGCATATTGAATTCTTGAATAGCTCTGAATTAGCAACTGCAGGTT ++ +@@CFDFFFGHHHHGJJJIJJJJJJJJIIJJIIIJIJJJJJJJJDIIJGIIJIJJJEGIEIIIIJIIIJIIIJJJIHFFFFHHCEFFFFEEEEDCDCDDD=@ +@SRR800764.25058 25058/2 +CGGAGGCGTTTTTCTTAGGGTTCAATAACCCAACGCCTGGATTAGAAGCTGAGCACTCAAGCACATCGCCTGCCCCCGAGAACTCCGAAACACATAATAGG ++ +:B?DDD7BC8DFH@FEBGGCIICFIIJJGJ?FHBEGIG=HIIDHECCGGGGAEHEC3?>@@(;;C@>B;?:??99(899<9&::AC?>80=FHIG=7=@A=E?7??>DCD?CCECC@;?A?####### +@SRR800764.25060 25060/2 +ATTCCTTAAAGAACAGTGCCAATTATATATAGGACACCCCCAAGTAATACCCAAAAGAGCTGAATTTGGGTCCAAATTTCTGAAAAACTATAGCAGTAAAG ++ +B@@F?,ABFBEFHGFHHCEAFHGGE;FHBAHG9?FGEGFEHGGH9;@@@GCGDGGH7=?A?>D);@CC@>AAEA;;@(5;;>CC@CACD +@SRR800764.25061 25061/2 +TCATAGTTTCAGTTCACAAGGTAATAATAACGGAGGTGGACGTAAGTCCCTATTTGCACCCTACCTTCCCCAAGCCAACATTCCAGAGCTAATCCAAGAAG ++ +CC@FDADFFFDFHGHH9BHHJ+AFEEHIJJIIFIGI?DFGHE0BBB?DGGFHCDFF/B@FH=;CGGHHFC>DBEDDA3@AEHE>;?7777;>ABD@B?BCACDDE>A@C>4 +@SRR800764.25063 25063/2 +GTCAAGGTTGGGCGCCAATGCTATCCTTGGTGTTTCCTTGTGCGTTGCTCGAGCTGCTGCCGCACAAAAGGGAATTACTCTCTACAAGTATATAGCCGAGT ++ +C@@FFFFFHHHHHJGIIIIJJJIJJJIJGH?DGIIGGJJJIHEHIIGIIJEEIFHH@DFFFB>BDDDD?C?BBA?ACCDDDDC@CCCD:>CE@BCCA>>@B +@SRR800764.25064 25064/2 +ATAATAATAATAATTTTATTTTTATAATTTATTAATAATAATAATAATTATATATATATTATTAATAAATATAGACCTTATCGTCTAATGGTTACGACATC ++ +@1?D?BDDHFHDDEGGBEGHJIGHJECHII9DHCFHIGGIIIGAG9BFGIIGGHIIEHIIGIIJJIHDGIIIGICF>F>GH;2@CCDHIJ@=AECAD?:A?+2AEAH<+<DD<@GB*:1*0::***:?@>>CDDD;AC><:>ACD@>@CDDDDDD@AACCD@CC@ +@SRR800764.25067 25067/2 +GGCATACATCATGAAACTAGATAATTCACCGACAGTCATTGAACCACTTTGAATCATGCTTGTTCCAACCAATAATAACGACAGCATTGCAGTGTTGCCAA ++ +@DD;'6.6(7;7;B'99?A>C############################# +@SRR800764.25070 25070/2 +TGCTGCTTGATGTCTTCGCACTTTTTTTTTCCAGATTTTTCAGGTGATGAGGTGGATCTGGCCGGTTTTACAATAATACTCAAATAATTTGTAGACAACGT ++ +@@CFA,FHII@8)..=C4@77.6(6).7)).(3'''35:@(5(:(:>@C>(9@@CC>@@########### +@SRR800764.25071 25071/2 +TTTTCACCTTTACCCTCGTACAAATCTGGTAAATCCTTTTTTAGAACTAACAATGCACTAATTACAGTATCAACCAAGATTTGAGTTTCTTCCTTAGTAAA ++ +;.6;BBB6@#################### +@SRR800764.25072 25072/2 +TGTAATGGGATGAGTCTATATTTAAACAAATTTCCTGAGATCCATTCCACTTATGATGAATCAAAAGCATGGCATTGTTTCTGGTGTTGTTTTATAATGGA ++ +CCBFFFFFHHHHFIHHGJJFJJJIIIIIIJIIHHIGIDGIGIHJHGHIEIDHIIJHCGIJGGIEGACHHD@CHIHCA=@DHAAE>A;BE3=A@CCCDCC:: +@SRR800764.25073 25073/2 +CAGGATACTTCAAGAATATTAGTAGCTTGAAATTTGAACACATTAATTCCGTATACAGTTCGTCATCATCCAGCAAATCGTCTAAGACGTCCAAATTAGGT ++ +?@BFDD?DDDBFHIBABADECJ>BEHHHIG>HH@HIDHH@EHBHH@DE>F;?;D39?00?B?(;C2==FECC:37.7@CE?;@BDEFDD;>?######### +@SRR800764.25074 25074/2 +CGGCATTTTACTGAATAATAATTGAGATATTCGTAACTCTTCCGAAATGATTCTAGAACTGTCTTCTACTTGCGAAAGAATATATTTTCTATACGTCCTGG ++ +??7;+A:DA:A,2A:EC?,3,,<3+<+3@C@;>CA3AED@@3;77;@C?CED@3-;;>C## +@SRR800764.25076 25076/2 +CTGTAGCTTGAAGCAAACATCACAAGGGACACCACCAGAATAAAGACATATATGAGAGGGGTATAAACGGAGATTGATTTCGTCTCCACAATTGCCTCTTC ++ +?B;;@>A(,89?3@<3?########## +@SRR800764.25077 25077/2 +TATTTTATATAATTTTATTATCATTTTATTATAGCACGTCTATTACCCATATTATAAGGATCATTATGATTTGTATTAATTCCTTTATTTATATTAATAAA ++ +<@FBGI4AHA81?:DBC;C>BF*B<4*?GFG>9CEC4//8>))(6B@''-,?).)>C@C6;5>;=>BA>C############### +@SRR800764.25082 25082/2 +CGCCCCAAACTACTTGACCAAATTTGTTTGATTTCTGCCAGTTCAAGTTTTGATCTATTCTTTGCACTTACTCCAAAAATGCTGATTTCTCCACCGAAACA ++ +=@@++=B7A;DFFABEAC@3CACFEA?)???DF?1*CFBFEFH>>B@*0*9??BCCE).;@6>;;A######## +@SRR800764.25083 25083/2 +AGCAATTTTTCTGGAATTTCAGCTGTTTCCAAACTCAATAAGTATCTTCTAGCAAGAGGGAATAGGTGGGAAAAAAAGAGATTTCGGTTTCTTTTTTTACT ++ +@@@FDEFDHHAHHHEGGHJ>?AFHF?FHB@AHHIJEGIGHHHC?FGIGE>FFHGHGGGGIDCGEHHIIIDAC;=>BA@D?CDCCC:@CDDDB### +@SRR800764.25084 25084/2 +AAAGCCATTTATGACACCTCAGTGGGCTATTGGCTACGTCACAACGTTGATGGATTTCGTATTGACGTAGGCAGCATGTATTCTAAGGATGAGGGCCTACC ++ +?@?BBDB+ABF4CEB+ABAFG>??@D9CB))8=)8(.)=@>CE?CABCC?=>(..5(;@>((-;(:5AA:?'5<>AA +@SRR800764.25085 25085/2 +TCCACGTTCAATTAAGTAACAAGGACTTCTTACATATTTAAAGTTTGAGAATAGGTCAAGGTCATTTCGACCCCGGAACCTCTAATCATTCGCTTTACCTC ++ +=?@+BD2ABFHDDDE>ACFIIIFEDEHCG>B@C>>>A;@CD:? +@SRR800764.25086 25086/2 +TTTCATAAGAAGGGATATGAAGTATTGTCATTCCACAGAGGATGATATAAATCAGTCAGGTCAACACTGCTAACAAACTCCTCTAAAGTACCCAAGTTGTA ++ +<@;;D>>D:4C:<1A:A?CE<43,AEH<2+++AEC3*):?C@9:B9??@B*9EG@@FB9C)8BCH@GEHHIDI(.=C)77;;?DC776.;A####### +@SRR800764.25087 25087/2 +CTGATGAAGCAATCCTGGCCGTGGCCACTGGTTTCTGTGCAGAATCCTCCCTTTTCAAGCATGAAATCGCCTACGTCGTCGGTCAAATAGGTAGTCCGGCT ++ +;@;:?;?+=CDFDG3+CE9A))2E;7.(5=<873.;'3,88280AC@C:>>@:::@#### +@SRR800764.25088 25088/2 +GCTATAATATTATGGATACAGAATATACTTTAGAAGGTCTCCTCGATGATATAGGAATCCTCGAAATGGAATCTATATTTCTACATACTAATATTACGATT ++ +::8D;A4=,ACHHA+C> +@SRR800764.25090 25090/2 +AAAATCTAAGAGATATGAACGGTGATCTTAAGAAACTGCAAGAAGAACTTCCCAGTGTAGAAAAAGACAGTAATATAGTGATTCTTTGCCGCTACGGTAAC ++ +@@CFFFFDFDHFFAE4CEHDHGHI7BFBHCHIG>DHII9DGGEHGII3BDFFGIJFGC>?@BB##### +@SRR800764.25091 25091/2 +TTTAAAACCTAAAGGTAAACCTTTATATTAATAATGTTATTTTTTATTATTTTTATAATAAGAATAATTATTAATAATAATAAACTAAGTGAACTGAAACA ++ +CCCFFFFFHHHHHIJ:CFHIIIIJJJIIJJJJJJJJDIIJJJJJIJJIHGHHHIJJIJJJJJJJJJIJJJJIIJIIIGGGJFHGFGHEFBEDFCEECEEEC +@SRR800764.25092 25092/2 +AGAGATCAATAGGAGCAACATAATGAACAATGCCCATGAAGAGAACATTTCTTCTGTAACAGGGTTTAAGTCTACATCAGGATCACCTGCAATAGGGTCAT ++ +8@@A?D?DBCFHD@GIIH3AEHID@9A9AC9:E?)?:DBB?DDHC3?GGFEII>*9??FGBCG;).;@G;=AEE@=:A>A??CFE;66(66@>:@5,5>A3 +@SRR800764.25093 25093/2 +AACCTTATCCCTTAGACACAAATGATCACATCGAGTGGATGAACTGTCAAACGACCCAAAGTGAATATGATTCCAGAGATTTCTATGCTTTCCATTGTTTT ++ +@@@?DFFBFBDHHGHCDDDD3-;;;;>BCCDD? +@SRR800764.25094 25094/2 +GAATTTATTAGTGCAGAAGAATTGTTTCGAAATGGATTCTTGGAAGATTTCGTGGTAATATTAAAAGGAACAGTAGGTTTAGAAATGAAACTCAACTCAGG ++ +BB@DFFDDHDHFHJJIGHHFGIIJIIIEHGHGHIIGIIJIJIGDFHCEGIIGGGIDFHIDGHHFHIIJGGIIIHEHH=>C@D@DFFDCCACE>CCDDDDCA +@SRR800764.25095 25095/2 +TATACTTTATATTATAATAATTATTATTAATATAAACTTATTATATTATATAATTTAATATAATAATAATAAGATAATTATCAATAAAAATTACATTTTGT ++ +@@<=DDDDH??BHIIIGGHIEHHGHGIADDHEIGG@HHIJIJJIGIJI>GAHHGIE>HCGGHIIIJGGAGH@HIIIIIJIEIIGICGFCCEHHGGHEEHEH +@SRR800764.25096 25096/2 +TTTGGATGTTGTAGTCAGACAAGGTTCTACCATCTTCTAGTTGCTTACCAGCAAAAATCAATCTCTGTTGATCCGGAGGGATACCTTCTTTATCTTGAATC ++ +@BCBDDDFHHHFHIIHJJGGHIIG@CCCCCDDCAC::>CC +@SRR800764.25097 25097/2 +AATGAAGCAAGAACTAGCGTTTATTGAAAACGTAATAGCACAAGATTTCACCACCACATATTCTACTAATAAGAATGATAAAGTGAAAGGTTTGGGAATCG ++ +@CCFFFFFHHHHGIIEGIIAGIJIIJJJJIIJ?GGHJJJJJJJJ@DHGGGHIJIJJIIIJJIJJIJJCHFHFEEFFFFFFCCC>CEDCCB>CC@BD@CDDB +@SRR800764.25098 25098/2 +GTATGGGCACGTATGCCAAGTCGTTGTTCTTGTGAAGAGAATGATATGTGCAGTGGTAAAAAGAGCCCGTGACACCCAGCAGCAAAGTGCGACCGCGCTTC ++ +++1=1B>>D1CD######################################################################################### +@SRR800764.25099 25099/2 +ATATATATACAGGCAACACGCAGATATAGGTGCGACGTGAACAGTGAGCTGTATGTGCGCAGCTCGCGTTGCATTTTCGGAAGCGCTCGTTTTCGGAAACG ++ +@CCFFFFFFHHHGIJIJJIIJJJJJJIICBCGGGIGGDGIGHGIHGIIDDGGHIGGI=HHFFDEEDDDDDDBDDEDEC99@BBDBCED=A>(;3,;@;@3:A>:55 +@SRR800764.25101 25101/2 +TTTCTATTTTATCGATGCCGTGTCTGCTGCCATTACGTACAGGTAGGCAAAAGCAAACAAGAATAGCACTTTTTCACTTGCTGCTTTTTTTTGTGAATGAA ++ +@@@DDFFFBHHFDGI9EEHGDHGHBFGEG@FDDFHGGGGHIEGHDHHE>?BFHIEFF;FDFCGGG;;EHHCFFFCCFBCEE@E;>C@A>@=BBAC:AC>@> +@SRR800764.25102 25102/2 +CCAGCAGCCGCGGTAATTCCAGCTCCAATAGCGTATATTAAAGTTGTTGCAGTTAAAAAGCTCGTAGTTGAACTTTGGGCCCGGTTGGCCGGTCCGATTTT ++ +CCCFFFFFHHHGHFHIIIJGIGGIJJJIJIJIJHIJIJJJIJJHIJIJIJJJGAHIJHHHHFFFDDDADDDDDDDDCCBC@CC################ +@SRR800764.25104 25104/2 +CACATCAGCAAAGTTTCGCTTTTGACATTCTGTTAAATTGGTCCCTAACTGTTGGTGCAGACCTACTGCAAGACTGTTAATTATGGTATATTATATATCAA ++ +CCCFFFFFGGFFHIIIJJJJJJJJJJIJJJJJEHHJJIJIJEHJJJGIJIGEHIIFGHIJIEHDIJJJIIGHCHHHHDFFFEFDFECDCCFDEEEFFEEED +@SRR800764.25105 25105/2 +CAAATCGCAAGTTTTCTCTCTGCATTAACTAAACAATACAAAGACTTAGTGGTCTTCAAAGGCACTTTGAGGGACTTTTTGGTGCAAATCAAAGAAGTCGG ++ +@CCDDFFFGFHHHJIIIJJJIJJJIJJJJIIJJJIJIJJJJJJIJJIIIIHGIGHIJIJEHIIJJJJJGGIJHEFFFFFEDD?@CD:A>CDDDD>BC::?9 +@SRR800764.25106 25106/2 +TCATTTACTATCCATTATGTTATGAACGGGAACTATACAACTAACCTAAGAATTTTGAAATCACAACAAAAATAATCAACATCACAGTCTCGAAGGGATTA ++ +CCCFFFFFHFFHHJJJJJJJJIIIJJJJJJHHIHGHGIJIJIIJJJJJGHIIJJJJIIJJGHIJIIJJIJJJHHGHHHFFFFFEEEECCDDC5=??B@CDC +@SRR800764.25107 25107/2 +ATAAATGTGGAAAGCTTAAATAAAAAGGTCGACGAGGTTATTAGAACAACAACTTTCAAACTGAAACCGCTAATGGATAACTATCAGAAAATTTTGAATTA ++ +CCCFFFFDHHHHHJJIJJJJJJIIJJJJHHGGJJGGI?DFHJJJJJJJJIHHGGIJJJIIJHHHHHHFFDDDDDDDDDEDDDDDDDCDDDDDCDDCDDDDC +@SRR800764.25108 25108/2 +GAAGCTGGTCTGCCTTGCTTGGCCAAGTACTCTTCCAATTCGACTTGTTGCATACATTCGATACCAATACCAGCATCAATCTTACCTTCGATGATGTACTT ++ +B@CDDFFFHGFFGIIJJIJIIJBFGEHJJJIGGGBFEGGIGEHDFGIDG@DHGHJJGICHGCGHGGIJIIIJHHHHEC@DFFDCCACEA?ACCADDADEB5 +@SRR800764.25109 25109/2 +ATTTATTATTATTGTTTTTTAATAATCTTATATATAATATAAAAAATATATATATATTATATATATATATAAATATAATATATATTATTATAAATATTTAT ++ +CCCFFFFFHHHHGIHGJJJJJIJJIJIJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJGGIIJGGIIIJJIJIIGGHIJJIJIHHGHFHHGFCBEFFFDDDC +@SRR800764.25110 25110/2 +AGAATCATTACCTAGATTATAACGAATTGAAAAATTTGATCTACACATTACAGACAGATGAATTGAAACAAGAAACGACAACCGGAGACTTAAACGATGAC ++ +???D1AB4A,=:?F377787=7CEH########################## +@SRR800764.25111 25111/2 +TTTGGGTGGTAAAAATAATACTTCCTTAGTTCCAAGGCTAAAAACAATAGAAATGTATAGACAAAACGTTAAAAAATCTAAAGATCCTGAAGTGTTATTCC ++ +?B@FFFDDDHDHHJJIGIJJIIJJJJJJJDCGGIJ@DGIJIJIIJGIEIEHHIGGGHGIIFDFHGEIGDHHFHHEDCECECDCCC@@CCACD@C;@ACCDA +@SRR800764.25112 25112/2 +GGTGTCAAACGGTTACCCTACGAACAGTTCGCGTCTTGGAGCCCAATAAAAGAAAATGAGGCTTATCAGTTCTATCACTATTTAACTTATTAAAAAACATA ++ +?;BA=BDDHDAAFFI@A2CDH<12?G?*:1:D?0?(?F93BCCG######################################################### +@SRR800764.25113 25113/2 +AGGCATTTCAAATTAATGAAGCAACCCTTATTATGGCAATCCTTTCAAAATCCAAATGATCACCATAATGAGTACTGTGACAGTAACGGCAGCAACAATAA ++ +B@@=??:DDHHBHGHI@EEIC<@H9A@+AFHIIDC9?GIIIGGEHECGCF@DH@BFH@7AC?A#### +@SRR800764.25114 25114/2 +AATTTCAAATTTATTGGTTCCAAAAATGAGATTTGATCTACATTAGCAGCACATGCACGCAAGGTTTTACCACCATCAGCAAAGGCGACGTCTGGAATGGG ++ +@@@BD;BDFHHFBGB+HCD?D):DAFAD>@((:;:@DCCD## +@SRR800764.25116 25116/2 +AGAAATACAAAACGTTAGCATTTGCATTTGTTGGACATGTACTGAATACAGACGACACACCGGGACTTGAAAAAGAACTGGATTGGCCAGATCCTGAACTG ++ +11+4B+A:2AF+<<22+2+AFFFBHIGIIGA;FED@DC@CC(;;>;;;=????CC@ +@SRR800764.25118 25118/2 +AGCGCTTACCACTGCTGTACTGGTCAATCAAACCATTAATGAGCATAACTATCCAAATACTCAACGCTATACAAAAGATTAAGTTAGGTGACTGAAAGGTG ++ +##################################################################################################### +@SRR800764.25119 25119/2 +CATAAGTTTTTCAAATTTTCCTTTTATTATGAATTTGCGCAACGACACCAGCGCTATTGCTAATGCGTTCAAAACAGGGAAAGTACACGTGAAATTTTAAA ++ +BC@BBFFDHHHGFGI@AC>4>4 +@SRR800764.25120 25120/2 +CATGTCATTATTTGTAAACCTTCTCCCCGCTCCACCACTCATCATTTCTGTTAAGGAGGCAGTAGGGCGTAATATTGACCCAGAATCCCCAATTGTTGAAT ++ +@C@FFFFFHHHGHJGFHJGGIJJIIJJJJIEIJIIIIIIGIJJJIIFIGIGIIJIGGGIHGGCEEBEHFACBDDDDDCCCABABCCCCCBC<9:ACCB:>C +@SRR800764.25121 25121/2 +TCCAAGCTGGGTAAAGATTTCAAAATTTAATATAGTCGTCTTTGACCCTTTGAGTAAAAAGTGCTTTTCCCAAAATTTTGTTAGCAAATTAATTGACTGAC ++ +@@@DFFD>?F;2@7BEEHH=;.7?@B>)7;;;66@C(->CC:AC: +@SRR800764.25122 25122/2 +AACGATTCGAACGATACCGACAAGCAACATACACGTCTGGATCCTACCGGTGTGGACGACGCCTACATTCCTCCGGAGCAGCCGGAAAAAAAGCACCAGCG ++ +?@@7DBD>CFFF@E+?:EB<@EG9)0:BG9*??3@(44:909@B529(8<@-003<>@######### +@SRR800764.25123 25123/2 +CTTGACTGACCGTGAATACTACTCCGCCTTCCACGACATCTGGAACTTCCATAAGACCGACATGAACAAGTACTTAGAAAAGCATCATACAGACGAGGTTT ++ +??@DDB,AD:;F@EECCH>??CA;C@A?FEC:8D6DCGBG>BB8=.8CH@CCG>E/C>;ACAA>?C9>53@CCDCCD######## +@SRR800764.25124 25124/2 +AGAAAAAAGTTAACTAAAAAGTAAGAACAGCAAAGTTGATTGTAGCCTATATTGCTGAAATAGATTTCGGAGCTCCCGTATAATATTAAAGTGCACCAAGA ++ +CCCFFFFFHHFHGJJJIIIJIAFHIHIJIGGIJJIGGIIIJJIIG@FCEDEGIIIHIIGGHJJJEEGIGGHHFDFFFC?ABDCDDCDA@CCCCCDDDDDDD +@SRR800764.25125 25125/2 +AGTGTGCAGATAACTATGAGAAAATTCTAATTAAAGGATTTGCCGGTAGAGATTCTGTGAAACTACCGATGTTTGATCTGTTTCTGCTTGGCTGCGCTCCT ++ +?@?DDDDEFH?FAHGHJJJJJJJJJJJJEIJJIGIJJFGHIIJIGIFHGIHG@GHIJIGGIIGCHGGIJHHE7?C>DFEE;ACEECCDCCDD@BDDBDDDC +@SRR800764.25126 25126/2 +CCCGCTTCAGCTTGATTCCGTGCTTGCGCCTCCTGTGATTCTAAGAGTGCAATTCTCAACTGAATGTCGTTTTCTTCATCGGTGTCGCCTGAAAGTTCAAG ++ +@?@BDDDDHFHHFIIJEBH;C@FAHEIGEHIEFB*0?(:@::> +@SRR800764.25127 25127/2 +GTGCTTCTCTCTGGTGGTTTTCTGTTTTTCTAATATTGATCGATTTTACGGTGAGTTAAACTACTTCCTTTTATCGCAATATCATATTTAGAGCGAGAAAG ++ +@?DDCDECCEDDCBACCBCBC@A +@SRR800764.25129 25129/2 +AACGAAGTCAGTACCTTTAGCAAATTGTGGCTTGTTTGGAGATAAGTCTAAAAGAGAGACAGATGCAAAAGTACACGGGTCTAAGTTAGGGGACAATTGGA ++ +?@@BAB;D>AB@:5>;;5(>CD5>?>(5>ACD@AA:@AC +@SRR800764.25131 25131/2 +GAAAAGTCCAAGAACAAATAACGAAGAAAGAAAACAAAGAAAGGCGATTAAGTAAAGTGCTAGTAGAGCAAGTACGAGAGAAGAGGAAGAGGCTTAGACAC ++ +BCCFFFDDHHHHHJJJJJ@HIIJJJIIIJIJIIJJJJIIIJIIIJGIHGGGH4@FHIDHEHIHHHHGHFFDD?CEDDBD??CDDDDBBDDDBB??CCDDD? +@SRR800764.25132 25132/2 +AAAGAGTGGATGTTGAAGAGTCAGGTCTTTTAGACTGTGTAAATTCAGCATTACTGTCTATCCAAAAATCCACACCATTTGTTTCTTCAATACGTTGTACG ++ +?B@DDFA?DHDFHIGGH@F3<GHIIGC7=CHAC@DCCCBBEDACC?=;>AA +@SRR800764.25133 25133/2 +ATGCATGTGCCGTGAAGCGGGACAACCAGAAAAGTCGTCTATAAATGCCGGCACGTGCGATCATCGTGGCGGGGATTTAAAAGTTCATATCACAAAATGTC ++ +@CC@FFDBFFHHFHHEGEIB<1CDGFFHDFHCGE?FE<;BFHGDAHCA@@:9B/9.=A@8ABBCA>5<;@BD############################# +@SRR800764.25134 25134/2 +TTCTGTTCTACAGCTTGAATACATGCCGTGGATCTGTTTATCAAAGATAATGTCATGTAGCGTGGCAAGTCGACACAGCAACGTGTGGATAATGGATGAGA ++ +@@@DFFFDHFHHHGHEBGGHJIG,::EF@CEE3CDGFHC>4BFHGII*?D5(5:A@>:AA +@SRR800764.25135 25135/2 +ATCTGAACTAACAAGTAAAATATCGATGTTAGAAATGGTTACAATAGAAGAAAGTAGTGTCATTCTTTCGCGTCAAAAAAAAAATGGAATTTGTGTCTTTT ++ +@@@DFDDD4CCDFGIGEIGFEC?@?F9D9D?EEHIEGEGDGG:CC4@FHGGIHJJJJIJFGFEGHGGGEFGIICAHGGHECCDFBDCCEEDE +@SRR800764.25144 25144/2 +GAACGCTTCATTTTAATCTCACGCATTTGCAACCCATGCTGATGTCTGAAGCGCTGACAAATACTTCATACGTTCTTCTTGTGACACATTAAGAGGTAGCA ++ +B@@FFDADHGGHHJIGIDHIJIJJGJJJJJJJJJIJJIIIGJJEEGIJE>FHIJJG@FHIHGHJGHHHGFFF@D@BCCEDECCD@AC?CDCACDDD::@CC +@SRR800764.25145 25145/2 +GATGAAAAAGGTGATTTGTCATTTACAAGAGGTAGGTCGAAACAGAACATGAAAGTTGGTCGGTAGGTGGCATGCAGAGGTAGTTTCAAGGTGACAGGTTA ++ +@B@B>CC(::ACCD### +@SRR800764.25146 25146/2 +AGTGTTGGAGTTGGTACTTTCAGTGGTAGTCGCACTAGTCCTGACGTTGATGCTGGCAGTGGTAGTAGCACTAGTCCTGGCGTTGGTGCTGGCAGTGGTAG ++ +?@@1BD??AD?FFEIG4C@EEIIGHDFHH>HGE?@FF@D??D<4D@B?G(>CG<3CC;<+CH9C:B@CC############## +@SRR800764.25150 25150/2 +GAGCACAGTTTTTGAAACTACAGACGTGCATCCATTCGTTAAAGAATGGCTCGCCGGCCGAAAGTTGCGAGAACGGACAACTTTCTTTGCAGTTCAGCAAT ++ +@@@FDFDDFFFHGGGCHGIIIJJIHIGHGGEGDHFIEHHEGIJIIJEBFEFHH:A +@SRR800764.25152 25152/2 +GGAGAACTCGACAAGGTTTCCCTCCAAACACTTAGTAAATGACATCAGTATTTTCTTCCCAAACGGGGAATGCAATAGGGCAAGATATTTGCCTCAAAATC ++ +@C@FFFDFHGHHHJJFEGIJJJJJJJGIIBHJJJJHDGFFHJGIJGIIFHHIIJIJJJIGJCHIIJIHFFFFDEEEEECBCD?@CCDDCCDDCDCDDDDDC +@SRR800764.25153 25153/2 +TATAATTTATATAAATATAAAAAAGTCTCCTTTTTTAATTTTAAGAATAAATAAAAATAATAATTAATCTAATAAAATATTTTTTTAAATATATTTATTTA ++ +?B@FFBDDHDHHFFB:<BDC@>@A@@C@CCCC +@SRR800764.25154 25154/2 +GTCCGTAGTGGATGAAATAACAGGCGCAAATTTATGGCGGCGGAATTTCTTTTCGAGGAGGTACGACTTCAATTCTGTCATTGAACAATATAGCATATTGG ++ +@?BDFBDDBDFHFGICGHIJIIGJIJJJIIIIIIJGJJGIA/=',8@C(5:@C>=2?@0+5(+:&+55<::@AC(:>@:4:@:(:>CC>A:@######### +@SRR800764.25155 25155/2 +ACGAAGAAAATCTAAAAAGAGTACTCTTTGGACATGAAACACAAAATTTTACGGAGGCTACACTAGAACCGGGTGAAATAATCATTAGGCTTTATCTGAGG ++ +??@D;ADBDHHHDFBACF?+3,<<+AA<<11H9::C91??D@GGHAG9BG49F?6'5-.=7.7)).?;76=A>B/;C:@35@################### +@SRR800764.25156 25156/2 +ACAACCTTCTTGGTAGTCTTAGCTTTCTTGTGGAAAACAGGCTTGGTTTGACCACCGAAACCAGATTGTTTACGGTCATAACGTCTCTTACCTTGGGCAAA ++ +@CCBDFFFHHHHHGHEIJJFEHJIIJIGIIHHIFGHIGIJJGIJFIBFG?AACHCGGABE@D;AEEC@;?DDCCD;=BD@>CBC?CDCDCDCCD<>BB?B1 +@SRR800764.25157 25157/2 +TAAACAACCATCAGCTTCAAAAAAACCAATAAATCATTCTAAAAATTCTTTAGATGGTAATTTATTATTAGGTTTAACTTTTTTAAATTCTTTATAAAATT ++ +@@@FDEFFHHHHHIIJIGCH@HGHEHIIIHGGEHGCCAIIHG9DHIIGHJGIIIIIIFCHJGIGIHCHFFFH;@DFFFEECC@??CCACCDEDCDC@>@C> +@SRR800764.25158 25158/2 +TTAGCGTTCGCATGTACACTGAATTGTCCCCTAATGGTTTTAACGTTCGAATGAATAGTTTCTAAAAATCTGTTATTATTGATATTGAAAGTATCAATTTC ++ +?B<=?:D?:@?CBA4ABDAFHC@HCECE9?DGBDHII?BDDE>?;7@BD@3@CCCDE:>C>>;;AC:C@CD +@SRR800764.25159 25159/2 +GGCTGACTGGAGCATTACTAGGTTCATTACTCACTGGTTCTACTCATGAAACCTTACTTATTTGACCTAAAGCTAAAAGACACAGAGAAGCTGGATTGGAA ++ +8=??D=DDD=+2E??DG@CFGIIJI1DFHCCBD4=BFCBCFHIGGF8@C@GE;==>?BEED<9;>>CCC@?@AB9?==BA?@BB03>CCCCDC>>:CC9BBBC +@SRR800764.25163 25163/2 +TCAGCATTAGAAGACCCAGCCACAAATGAAGGCGGTGTCGAGGCCGCCAGTGAAGAGAAGACAGGCCAAGGTAGCGGGGCTGGTTCCCTTCCATGGCAGGC ++ +=?+=1=D,C:C<+:2+<+<3 +@SRR800764.25165 25165/2 +GCAATTGAATCATTCACCTCATTAACCAAATGTGACCCCAAGGTATCCAGGAAGTACCTGCAGCGTAATCACTGGAACATCAATTACGCTCTCAATGATTT ++ +B8+ADDBD>D,+,2ABEEFF:AF4C@C:6-=/58?:(5>>ACF> +@SRR800764.25166 25166/2 +AAGCTTAATTGTATGAATATTTCTATGTTACCGGTTGAATAAACCTGGTCTCAAATAAAATTGGTAGAATGACCTAGAATGACCCATCCGCCGCGGAATCG ++ +=:BD?DEDBD<:DFFCHDGCHDECH>HD:CDBHE4C4?*:CG@F@CGA?4BF9DF:6BBHG4=CF@4C;.==@/459BB@;AC(5=>>@@((-:;5@>(5@ +@SRR800764.25169 25169/2 +ATGCATAGTCACGAATTTTCTTTGTGAGGAAATTGTTAGGGATTGGCGAGATTTCAAAATTTTTCTGAGCTTTAAGGATCCTTTCATAGTAAGAGACGTCT ++ +B@?;:B:B=2:D?C1C:AF@HIDD<;2<8+:;?B?*?*?DBGHH3)*?D'768@)BBHIJJECD=;?)==A>@)..;>C6;CEC35>CADACCCC?C?### +@SRR800764.25170 25170/2 +AAGATTTATTTGCTCCAAATGACAAAACAAAATCATTAATTAGAGAAATTTTATTATCCATCATCAATAGGAATATCACCAAAGGTGCGTCGATAGAGTAT ++ +=;?DDFFBHHHFDHIIJJB@BHGHBH;GGHG?E=@;BAC>?@@?AA@:> +@SRR800764.25171 25171/2 +AAAAAATTAATTCAACTCAAGAAATTAAAAAATGGAGGCACTAGAGGCAAGAAGGCTTAGTGAGTCCTTGCGGATTGCTGTGCTGCACTTAGGCTGTTGGA ++ +?B;A+)A<+2:C,C<<,A+A<3CG9+AH9EHI##################################################################### +@SRR800764.25172 25172/2 +AATCTTTATCATGAGTACCATGAACAAAGAAAGTCACCTATCAGTGGTTCTATCGTATATTGTTTCGGTGCCGTGGGGGGGACGGTTGGTATTTCCTTGGG ++ +CCCDFFFEHHHHHJIDGHHHIJJJIJIJJIJJIJIGIJJJJIIJIHIGGIHGIJIGGIHIIIFGGGGGFGGIHH6BEB:@B9>@B9@B><:>C@:ACDDA< +@SRR800764.25173 25173/2 +GATCAAAGGATAGACAATTTCAATACAGAGTTAAATATCGTCAGCCTAACAGTAAGGGCAGAAAATACTGTCACAGCTAAGCATCACAATGCGTTCCATGG ++ +##################################################################################################### +@SRR800764.25174 25174/2 +AAACGGTTGTTACAAGCAAGAAATGACAAGGCATCCTCAGTAATAACGGGGTTAGCCACATCTTTTACACTCGTGGCAATGACTCAGCCCATTGACGTCGG ++ +?1=DDDD+<;3)=;=)7=?7?B>>>>;..3/(;;>A:@>35A<@CCC@C5BAEGIICHCHGHGHGCCEHCB7<>A@AAC@CD@9@;>CDCCCCDACEA: +@SRR800764.25178 25178/2 +GAATCACCTGTGGGAGTGAACCTCAAAAAAAGAAAACACATATTTCATGCTGCATCATCCTTGCAACACAACGCTTCCTGCAGAAGTTTTCGAACAAAAGG ++ +@??BDB:BFFBFBGGB+2ADFEBFC?HF@GGHGIIEFIGGIEEGGJI=FGHCGIG>@;=3=>==7BD>?=?A>@B(,:@CCCDC>A(:AC>@######### +@SRR800764.25179 25179/2 +AACATTTATAAAACCGTTGACAAGATCGGTGTAAATAGAGTCGGTATTGCCGACACAGTTGGATGTGCCAACCCAAGACAAGTATATGAACTGATCAGAAC ++ +CCCFFFFFHHHHHJJIIIIIJJJJJJJJJEFFFIIIJHIJBGHIDFGIBGGHGGJHHHEECFDCFFCACCD?BBDDDBDDDBACDEEECDACDD@CDCDCD +@SRR800764.25180 25180/2 +AACGTAAGTCTGGATAGAATTGAAGACTGATACAATGGAAATGAAAAGTAACCATTTTGGTAAGTAACCTTTTGGCATTGCTGCCAAGGTGGTCTTGGTTG ++ +?@@DB>ADC,A@B376;.6;?;(;A>5@FGEHGIEEHEHADB@DFF:@>6@DE;@BACD??CCD@AD?',5>@3;5>ACDC# +@SRR800764.25183 25183/2 +ACTGCTACTTATGTCAAGGCAGTGGTCAGGGACATGAAGAAATACATCAAGGCTAGAAAATACAGACAAATTCCGGTAGGTTACTCGGCTGCTGATATCGC ++ +BCBFFFFFGAHHHHIIIJIIHIFGHCHHIIJIJJJIGIJJJJEIJJJIBHFGIIJIIJJJGGIIJJIJJGHCEE>A9BBC@>ACCC?BDDDDCDCCDEDB# +@SRR800764.25184 25184/2 +ATAGATGGAACTTACAAGTATGGAGCTTTGGATGACTTTATCAATTCATTCACAGATTCTGCATCTGCAGGAAAGTATGCTGTAAAAATAATCATCTTTTT ++ +@CCFDFFFHDFD:CDGIAACIEIJFJADCHGIEFEGCBBHHGE@G@HHEHHIGHH;4BBGI>HGIIA)7=DG@EH;==);@>:3;AC>@;>CD +@SRR800764.25185 25185/2 +GTCAGTGGCAAGTTTGATATAATCCAGATCTCTAAGGGGTAGTGCGCTGATTTCGACCATAGATGAAGACGTAGAGCTACTCAAACCAAATGACGAATTAT ++ +@=?BDDDEFD>D2A:CBD4?EDAF<@@H;CAC@A@?BDC:@:?2928@: +@SRR800764.25186 25186/2 +TAGGAAACAACAAATTCCGATGCTTACTTACCCCTTAAATTTTCTCATTGCTCTTCATTGAGGTTGCATAGCTCACCATATTTGTCATGGAAGGTCCCTTA ++ +CCCFFFFFHHHHHJJJJJJJIJJJJJJJJJJJJJJFJJJJJJJJIJJIJJHIJIJJJIJJGJJFHIJGJJJJJHHHHHFDFEFFCEEF@CCEDDACDBDCC +@SRR800764.25187 25187/2 +AGATTACGTTGGCCGAATTGGTTCAAGAATCGATTTTACAACTGTCTGTTTTGAAGACCATTATATTGAGTTTTCCCTTCGAATTGACCATTTCGAAGATT ++ +B@B+AB8DHB;+??9:CFHGDBFF1+A3FEF4?E9EFGIEGI*)?C6DD)??@AFHB@CB:',.;7.;(;@C>3@@:;AB=@8=C>>A@C>:>>@C############ +@SRR800764.25189 25189/2 +CTCTTCAAAGGAGAACAGGCCATACCTTTTGGAATCTCCTTCAGGACTCTTTTCATGTTCACTAGTCAGGTTTTCTCGGACATTCTGCTCGTTAAGATTAT ++ +@@CDFFFFHHHHGJJFIIIJIJJJIJJIJJJICEGJJIJJJIIIICHEIJHHIGIIE@HGEHGIJIIIFG7CGHHHHHBBDBECCEDCDCD@B@?CCCDDD +@SRR800764.25190 25190/2 +GATATAAATAGTTGCAAACTAAAGTAAGATAACTGAAGATGATTAGTCCTGTTTGCATACATAGTTCTGTTCTTGTTCTACGCTGATGCGATCAATAAAGT ++ +@@CFFFDDFFHHHJIIFGIJJJIIHJJIJIJIIHIJJGHIJIJJGI>FGGFHGIIGHGIIGIGIBFIDIGEHGIIGHCHIDGGHHGGFFEC;ABACDDDC; +@SRR800764.25191 25191/2 +TTATAATAGGTTCCTTTTAGATGATCTCCTAATCAACATCCGTTTAACTGATATGATTATTAACGGAAACAATGAATGCATAGAATATGAGAAAGGACATG ++ +CCCFFFFFHHHHHJJJJIJJJIJIJJJJIJJJJGIJIFIJJIDHIGIIJFIJIJIJIJJIIJJJIIJJJIEEGHHHHHHHHFEFFFFEEEEEEEDBDDDD> +@SRR800764.25192 25192/2 +GGAAGAGAATCAAACCAAAGTTCCCAAGAATCACGAAACGAAATTACGAATTGGATGCAAATTGTGTGAAATGGAGTTTTGACACATGATATTGAGTCTCC ++ ++1?7:BDDDC;C################################################################# +@SRR800764.25194 25194/2 +AAACCCGCTCAAACCAAGGCATATAGAGGAAGCCTGGAGAGTACTACAAACAATTGACATGAGGCATAGGGCTTTGACCAACTTTAAAGGTGGTAGACTCA ++ +@@CFFDFFFHHHHJJJJJIIGIIIIIGIJJJIJJIJJJJJGBFEDCGCGG4@@@)7=CC@EHHC>AC@?B;@6>53@=A@A#### +@SRR800764.25197 25197/2 +TGGAATCTAAATTTGCATGATTCAGTTGTTCCCTAGGTGACATTTTATTGAGGATTCCTCTATATGATATAGTGTTCGCTACTTTACTATTTGGGGTCGTT ++ +CCCFFFFFHHHHHIJIJJJHIGGIIHJJGIJIJJJII?EHHIJJJJJJIJJJJJIJIJJJIIIIIJJIJJJJIHHIJIJJJHHHGHFDFFFFFECD8?BD? +@SRR800764.25198 25198/2 +GGCTACGCAATCTGTGTGTTCGTCGCAAAACACAGCGACCACTGACGGTGTACGAAATCAATTTCAGAGTAATGGTTGGTGTTCAAATAACTGTGCTGGTC ++ +@??DFBDDFFC:@>;@;:@5::;>:++2<++(+>C3:A@344>@CCC#### +@SRR800764.25199 25199/2 +CTCTGTTCGTCAGATAAATCACCTGCGTTCAAGAAATAATCCCATCTATGATTCCAGACTACTTCAAATTCTTCTCTCCAATATACGGAGTAAGTAAATGG ++ +:1+442A,2C1C?+CFH+A..=)B=))..)...7)7@D@D;6(;8(--(-5>CDCC +@SRR800764.25200 25200/2 +TCCACCCGTTCAAGTCTTCAAATAAACCTTGAAAATTCTATAGTAATTATTGATGAGGCTCATAATTTGATAGAAACAATAAATTCTATATATTCCTCTCA ++ +CCCFFFFFHHHHHIGEIJJJJJIGIJHIJJIIGJJJIGIJCFIDGIIIJAGHIIGIIIFIJIJJI>GIIIIIGIJJJJJHHHHHBDDFFFFFDF@CEEEDD +@SRR800764.25201 25201/2 +AAGAAAATATAGAACTTCAATGGCAGCACTTGAAAAAGAAATTAAATGAATTGTATTCTAGGTTTAACTTCCACCGAGATCAATTATCCTTTCAAGTTAAC ++ +CCCFFFFFHHHHGJJJJJJJJJJJJJJIJIIJIIJJJJJJJJJIJJJJJIJJJGIJIJJJJJBGHJJJJJIJJJIIHHFFFFCEEEEEEEDDDDDDCCED@ +@SRR800764.25202 25202/2 +TCTAGTCCGGAAGAAATCTGCAAATTATTGTCTTCATTCAAAAAAGTTTCCTTGGTATCCAAATTAGAGACAAACAATGAGCTAGAGGGATTATCGGATGA ++ +@@FHFHIHGJJGGIGGIIJIJGEEGGFIIJEGIJIIE/?DDGGHHICB@FGGCHIJJFJJHHGFHFFDECCACEEECCBDDDCDCDD=BB>> +@SRR800764.25203 25203/2 +TCTATACTTGCAGGCACCTTCAAGTTCTGATCAGTGTCCATCTCTTCATTTTCCAAAGCAGCGTCGTCTGGCTCTTCAGTTATGGCGCCATTATCATCAAA ++ +BCCFFFFFGDGGHIIHGCGGGIIBB>CHHEBCC@CB;>;;?CA;ADEDDD> +@SRR800764.25204 25204/2 +CACAGATTCAATGACTTGGGAGTGTACTTTCAGTTTAGGCCCATTCGCTATTCAACATGTTTGGTGGCTCGCTAAAGGGTCCCTGCTCGTCACCATATTCA ++ +BB??4BB4?:DDFADD<=)=)B=4CF;EEE3?6?(?@7>C@>>6;(;>A;-5555;?BB? +@SRR800764.25206 25206/2 +AAAACACCATACAAGTACGTCGATATGGCAAAAGAGTATAACTACATTTCTCCCTTCATAATGTGCCTTTCAGAGCAATGGAAATACGTTGACAAGAGTGG ++ +@B@FFFDFFHGHFIECFGIDHIIBEGGGGIHGIGII:B9FHIDHIFIIIGAFHDIGIIJCGIIGEHGIIHHHHGHFFFEFCCEECEDD@ABDCCDDCB>@? +@SRR800764.25207 25207/2 +ATATACTTATTAAATTAATATAAATAAATGAATAATATAATATAACTATATTGAATTATAATCTATCTATCTTTTTTTTCCATATAATATTAAATAATAAT ++ +@B?:A=DDB<4CFHIGH?BFCB8=@FGGJIGGEGGDG:CDDEEHFCC@BDFFF:>ACCCC;; +@SRR800764.25209 25209/2 +CGTTCTTCTCAGCACGCTTTTGCATAATGGTAGAAGCACGCAAATGGTCTTTTCTGACAAGCATAAACACTTTTGAGCCGTACTTGGTCAAGAACTGAGCT ++ +CC@FFFFDHHHGHIJIJJJJJIGIJJJIJJFGHCGHIJIIJIIGHGI8BFFGGHHGAFHJI9@EEHEHFEEFDFDE?@CD;@B=ACCCDCCD@?CACACDD +@SRR800764.25210 25210/2 +TAATGCAGAGTACACCTTGAAGAGAGAGAAAAGAAAATCTTTGAATCCATAGCATAATAGCGATCAACGAAACTTTTTAAGAAGTAAAATGAACTGAAAGG ++ +@CCFFFFFHHCFHGIJJJJJJIIJJJIJJIJIJIJJJHIJEIJJJJJJJIGIHIIJJJJJIJJJJJJJHHHHFFFEEDDCEEDDDDDDDECDDDDDDDDD? +@SRR800764.25211 25211/2 +CTTTGCTCTGCTGGTTTCCGATCACTCTATGGCCTTGAGTATCTATTTCTTTGAAACGATCCCTGGATAACGCATTTTTAGAGAGATCTGTTAGTAATGAC ++ +?@?DDADDFHHFHIFGHIIIGGIICHIJJGDGIIJIFGGDBGFIIIJJICGFFHGI@FHGGGGGHIBHIFGFGF?ACCEBCDDDDDCC@@5>CACDDCA:@ +@SRR800764.25212 25212/2 +AGAAAATGAGATAGAAAATGAAACAGTAAACAAAACAGAAGACAAGGCTGAAAAAGGAAAAGAGGAAGAAGTAAATACCAAAGATAACAAGGAAGAAAAAG ++ +@@@FDDDD?FFD?GHIEHEIJIJGHHCCDDDC?(59AC??B# +@SRR800764.25213 25213/2 +CAGGTGAGTTCATTCATACTTTGGGGGATGCACATGTTTATAAAGACCACATTGATGCCTTGAAAGAACAAATCACCAGAAATCCAAGACCATTCCCGAAA ++ +BB@DBDDEDDFHFIGBHGHFJHBF@D8AHIEGHIEGD<9BDGCHF@FF@FBBGGGIGGCAHGGIGIHHH@DBCEDAED?ACCCACCCABCDCD>@B>?BB3 +@SRR800764.25214 25214/2 +AATACCTGAACTCATGGCCAATCCACCTACCAGAAGGCCTGATAACGCAAATCACGATAACAATGAAATAAGCAATAAAAAACTTGAATATGGATACCCCA ++ +CCCFFDFFHHHGHIIJJIJJJIJJJJJJIJIJJIJJIIJIIGJJJGIJGGGEGIIGHGJIHEEHHHHFFFFFFEEEDEEDDDDDDDDDCEADCCCDCCD@7 +@SRR800764.25215 25215/2 +TTCATTATCAGGTGACGAAGCGGCTCACAAATTGCTAAAATTAAAGATTGCGAACAATTTGAAAAAAAGCGTGGTAGATATAATCATCAAATCTAGTTTGC ++ +@@CFFFFFHHHHFHEGGGJDFHAGEGIIJIGIGJG@FEGICDACDDDCCDC@CCAC::4@:@C +@SRR800764.25216 25216/2 +TTAAGCGGTATTCTAAAGGCTCCGCGAGCGAGCCTCTTTAACCTAATGCAAAAAAAAATTGTTACGCACGTTCCCGGCTTTTACCGTAATAGTAGTCAAGA ++ +@@CFFFFF@FHHHJJJJJJGJJJJJJJJJGIIDIEIJJIJEGHFGHHEFFCFFFDDDDDCCDDDDDDDDDBDDDDBDBDDDDDDDD@BDDDD@DDBDDD>3 +@SRR800764.25217 25217/2 +TAATAAAATGAACTATTTATTACCATTAATAATTGGAGCTACAGATACAGCATTTCCAAGAATTAATAACATTGCTTTTTGAGTATTACCTATGGGGTTAG ++ +@@@FFFDDFGHHGHGBEBCHJIHJJ>HIGIHGDFCEFDCEGEAHDHH?DHFDCGGFEDHGGIJJGGHDGFHEHIHHGCHIGCE=?EHFCFBDEA@A##### +@SRR800764.25218 25218/2 +TTAGACGTGTTCCTAAAACTTTTGACGTTTTTTGGCGGGTAATAAGATGCGTCTACCCATTTTAAGGAACGCCCTCGTAACAGACAGAACGAAGAGTGGCA ++ +@@@DDDFDFFHHHGIGIJJJGIGIJIIIGGDE@@DBHHH4=A@@A@C@C>??@@?C:9::CCC@C>>AAA;;>B>B928FEEIEACHBI:>(5;28-)0&&&89BD(3:???BBC######## +@SRR800764.25222 25222/2 +ATTGCCAGAAAACGACTGTCTTTACGCCATTTACGATTTTGAATACGTAATTAATGGTAATGAAGGTAAGAGATCCAAGATTGTTTTCTTCACTTGGTCTC ++ +;?BF;;4BHB?AD:@?C:CFBCA77=BC;@@@:(6;A3;@->;?>555@>CA55>:@C +@SRR800764.25223 25223/2 +TTTGAATCACTGCAGAAATATGCACTGCGCCTTCTTTTTCTTTGCCTGAAGCACCCACACACAAGAACAGGAATGTGAATGGGCTCCCCATATCACTTTTA ++ +=?;;4+,=:=CF:+3+A+33A:,9*?38((-5((--;D3?=AD(6?C########################### +@SRR800764.25224 25224/2 +CTCAGTGCTTCTTTGAATTCTTCCTTTTTAGTCTGCCTGCCCTCTCCTAACCTTTTAGAGCTTGTCAACAAACTTGTATCTATCTTATAATCTTGAAGTTT ++ +CCCFFFFFHHHHGJJIIIJJJIIJJJIJJJJIJJJIJJJIJJJIJJIGIIHIIIJJHIIIIIJICHHIJEJJIIIJFFGHGHFHFFFFFFDEECC>@C@CA +@SRR800764.25225 25225/2 +AAACCAAAAGACTAACCAGGAAAGTTAATCAGAGGATGACTGTTTTTGTGGTGGGGGGGCGAGGATGTCAGATTCTGCTGACTTCGCAGCGGTAGATGACT ++ +:;?+4A;DDBCFHGIGHBB@+CC:ACAC@::449>C:8099&)055<44:>@@ +@SRR800764.25226 25226/2 +TATACTTAGCAATTTCATGTTTAGTCCCGGCCCCAGTCGGGACCCCGAAAAGGAGAACAATTAAAATGTAAACTAGCAGGTACATATCCTGTAAATGTTAT ++ +@C@FFFFFFHFH?CEFHEB?ABFGHEEE@::CFHHEHAFEBD@@CGGGAABEE;BB2ACCCC@CAADDCC@CCC@@CAC?(:(::4((4@@C34:>C>ADD +@SRR800764.25227 25227/2 +TAATAAAGGTCTAATAAGTATTATGTGAAAAAAATGTAAGAAAATAGGATAACAAATTCTAAGACTAAATACTATTAATAAGTATAGTAAGTACCGTAAGG ++ +@@@DD?DDHFHFHIIGGG@JJHIIIIIBFCHIAGCCDHIGEIH9FGHG4?DGGIE@=FCGFGHHEGI@GHIGHHHH>CE?BCDFDFF@CCCEECED@DDDC +@SRR800764.25228 25228/2 +TAAAGGCCACCATCGGAGAGGGTTTAGATATTAATGTAAAAGGCACGCTAAACCGCAGGGGAAAGGGTATCAGAAGGCCTAAAGGCGTATTTTTTAGATAC ++ +;;?D?BD?DDDHDGBB?'<557@E;=HFB8/''55;?,5::;55>((2<>>4>@@<9)0?>:>AB??4>C# +@SRR800764.25229 25229/2 +CAGAACGTCTAAGGGCATCACAGACCTGTTATTGCCTCAAACTTCCATCGGCTTGGAAACGATAGTCCCTCTAAGCAGTGGGTAAACAGGACATGATAACA ++ +@@@DDDDDFCB?FGG=DGFHICDE@HC444FECID8EBGG:)=FHG@GGGCEAD?AHHAHHC +@SRR800764.25231 25231/2 +CAGAATAGAAAAATAGATCGCCGACAATCGAGGGGTCTTAATTGATGGGGACATCGTTGGAGCTTATATAAGTTTGTCGCTACTTGGCGAAGATGGTTGAG ++ +;18=B;BDDAFD8AC:((,9>75AC################ +@SRR800764.25232 25232/2 +AAAGCACGCATAAATTTGGCTAAATGCATTTGCCTTGCGCTTAGTTCACCACGACCAGAAAAATCCGTACGGTATAGAGCCATAACAGAATCGACCACAAT ++ +@@@DFFDADAFHAEHHEHGGCEGGGEGBFHIJIIIJJIIJJIGGBFFIJIGGGEGHGHEFHFED:BCBECDD5=BDDDA>AACCCCDDDACDD?BB>DBBC +@SRR800764.25233 25233/2 +CAAAATTTCGAACAACCTAGCCCTCGTTTTCGCCGCATTGGAACACTTGAAGAATCTAAGCTTATTAGCTGAAGAAGTTGTAGATAAAATTGTTAATAAAT ++ +@@@DDFDFBFBHFGJHGGIIEIB;EADBHCFA:DFGH@FG3C4)=.77;77BCEC).)7));@DE@;3(..>C>@>(53555:;>C@(:;5>34:>@C@## +@SRR800764.25234 25234/2 +TAATACATATAATTCCATTTGTATCCATAATTCTCTTCATGTTGAGATATATATCTTGAGGGGTATTCGTATCGCTTGTATACAATGATAATCGAGGTAAA ++ +B@@B==ABFFHHFIJIGIJIIJIJJIIJIJJIIJIHHIIIJIIIJIGEHIIHAFGAFFGGIGIEFHH)=FHGGC@C@CHFEHAE>DFF>C@ACCA@BDCCC +@SRR800764.25235 25235/2 +TATATATATAAATATAAATATAAAATATACTTTTTATAATATAATATAATCTTTTATATTTATTAAAATATATATTAATTATATTATAAATCTTATTTAAT ++ +CCCFFFFFHHHHHIJJJIJJJJJJJIJJJJJJJJJJJJJJJJIJJJJJJJJJJJJJJIJJJJJJJJIIIJIIJJJIJJJJIJGJJJEIJJJIJJJJJJHHE +@SRR800764.25236 25236/2 +TTCGGGGTTCCGGCTCCCGTGGCCGGGCCCCGGAACTATTAATAATAAATAATATAATAAGTTTATAAATAATAAATATATAGTCTAAACCTCTTTTTTAT ++ +@CCFFFFAHHFHHGGGIJI;AHIJIGEGAGIIG=BFDCCCEEECDDDCDD>CDDEEEEDC>5@CDDDCDCDCEC:@CCCDEDD3>CACC>?9<:<4C:3I:F?FH+???F1B909:90990*00*9/?E?C:?6@AEE:AC: +@SRR800764.25238 25238/2 +CAGAAGCTTTCTAAATTAAGGGTTTTAGAGATATTATCCGGTCATGACATGATCAAGGAACAATACGGAGTACCATTGCTTGATAAAGATGGCAATTCACC ++ +?@@D?DDFHHHHDHIHGEHIII+ACGDHIGIIJIDHIIIEGGGGHCDBGHFEHEIGIJGIIGIGGIJJIHHHFEFFFFDEEE<@@;@@CDCC9>CCCDCC@ +@SRR800764.25239 25239/2 +GGAAGAACCTAAGGTTATATGTGACCTGATATCACCAGCTGCATTTTGTCTCTTAGAGCTCGAGCGTAGTTTTGATTGCAGTTTGTCGGTACTCAAACCGC ++ +B@CFFFFFHFHHHJHIJIJJIHHIJJJIGIJIIJJJIJJJGIJJJIHIIJ>FHIIJIJIIJJGIJIEHHCHFFFFFEEDCEEEEDDDDC?BDCCCCDA@BD +@SRR800764.25240 25240/2 +AAAAGGCTACAATCCTCGCATGAAACTAATAAAAACGAGCACAATATAAGCCGAGACGTAGCGTTTAACGTACTAACACTACTCGCCAAACCATAAGAGCT ++ ++11BD2+2=DH;?BBDCDC@CADDDBACBBDC>>@ +@SRR800764.25242 25242/2 +TACCTCAGAAAATACTGTTGAATTCTTTCAAGGGGTAGCAAAACTGTCCAGAGCTTATATCTACCTGTGCTCAAAATACAGTTGAAACCACCTCTTCCTAC ++ +@@@FFFDEHHHHGIIJGHGIJJJJJIIIEGHHIIJCFGIJGIIIIIIIIIGIIBHEGHGCGGHGIIGGIJJIGGIHFHEHFDDFCEDDCCCCDDCDDCD@A +@SRR800764.25243 25243/2 +TCCCGTGGTCAATGAAATCAAAGAAGGTACTGCAAACCATGCTAACCCACCGATGGCATATGCTTTCAAACTCGCTGCGGGACTAGCAGAAATCGCTTTAT ++ +:+=1+=D:FB?F8D9DGI@HAH>BGHIB@C8CHCHCGH?H;)7?C7;7?9=@>>(5;5>8ACC###### +@SRR800764.25246 25246/2 +TCGATTTTCACTTTAAAAAACCAGTAATTACAGTAAGAAGCAACAGTGAATTTCATTTGGACTGCCAACTTAATATATGTACTAAAATCGTCCATCATTTG ++ +?@@+B,AD8F?DA>EEBDFGEH+31:9:4?99?DGG>FHHAB*?B)=D=@@=D4.7?ACEEE?BBD>?7@C@?########### +@SRR800764.25247 25247/2 +TTGCATTTAGGCCATGAGCTTTTCTGGAAGAGGCTGAAGACCCCTTCAACACATCCTGCTGATCACTTTTACGCATTTCCCTCAAAGCTCTATTGCGCATT ++ +@@@DBFDFHHHDFGB??CHGIJJGIIFEGGIJJBHIHHGIGIJIGIGCACD########## +@SRR800764.25248 25248/2 +CAATCTATTGAAATACTTTAAGGATATATCATAATTAATGATCTCAAAATGAAGTTTTCCTAATTGCACTAGACACCATGGCATTGTGTCTTTAATATGAG ++ +CCCFFFFFHHHHHJIJJJJIHIJJIJJJJJJIJJIJJJJJJJJJJJJJJJHJJIFHHIJJJGIJJIJJJJJIIJIJJJIIIJIJHEEHHFFFFFFDCDEDE +@SRR800764.25249 25249/2 +ATTTAATAAATAATTTTTAATAAATATTGGTATATTATCAATAGGTTTTCAATTATTTAAAATATAATCTTTAATAGCTTCTAATGTTTTTTTTTTTATTT ++ +@@@DFDBDHBDHFGIIIGDFHGGHEJIGFGIJG@HBHGGEEFIGGIGIG>@DFGD@DGIEIIEHGGBC++++3AF<+AFII9***1?**:)))?*?4***9*(0??*9B8))8)/@78C;==7=7)=EEH######################## diff --git a/latch_cli/services/init/new_example_snakemake/data/samples/C.fastq b/latch_cli/services/init/new_example_snakemake/data/samples/C.fastq new file mode 100644 index 00000000..e022e580 --- /dev/null +++ b/latch_cli/services/init/new_example_snakemake/data/samples/C.fastq @@ -0,0 +1,1000 @@ +@SRR800764.25001 25001/2 +CTCGTTGATAGCAGCAAAAACTTCTGATTCAATGCGTTGTGTGCATCAGCTACGGCAGTATTTGACGGTACTATCAAAAGACCATTAATATTTTTTAAAGA ++ +??1B=+AB:?:AFB;C:CF??EFDHHGCCBCCF@E?1:@DDGHCC4*?BHCGAAAB;E==;@E>EE=D';>(;>A@5>CCDCDCDCCDDEB@@C@BDDDDA +@SRR800764.25002 25002/2 +TAGCACCTTCAGGACAATGCAAGTGGATAGACGCCTTTTCAAAAAATCTGTTCTCATGGAATTTTTGTGCTAAATACATCTTGGCGAATGAATAAGCAAGT ++ +;?1B4ADEAHD?83EB:FGIII<3ABCBIHJGGBGHJJJG>F@DEBD>GGBB8=C;)==7CAHEH>4?=:@;;7;@;AEEECC;>@@?B::>CDC@@C3<> +@SRR800764.25003 25003/2 +ATTCAAATTGGCAATCACTCAAGGCTCCTAATCCATACTTTTTAGCATAAGTGATATTATAGTGCCCAGTGGCTAGGGCATCCCAACATTCATTTAGGATA ++ +@@@D?DDDHHGFHIGGGIJEHIJIIJJIJIIIGIIJIIIJIIG?13>>>ACC###### +@SRR800764.25004 25004/2 +TATAAATTATTAATATATCCTTTTTAATAAAATAAAAAGGGGCATTATAAATATTAATAATTAATTTTTTTTTTATTTATATTTATATATATATTAAAGAT ++ +@CCFFFFFHHHGGJIJIJIJJJJJJJIJGIJJJIJJJJJJJJIDIJJJIJIIJJIIHIIJJIJIIHJJJIHFDDDDDEEEEFEFEEDEDEEEADECDCCCA +@SRR800764.25005 25005/2 +AACTACTGCTTATATATGGTGCAGAAAAGTGGCTCGGAATGAACACCTCTTTTAATTAAAAATTCATTTATAAAGTACAGGGCCTTCACGCCGCTTAGTAT ++ +@@?BA;B?DCFDFHHBEAEEE>@BAH@@@0?6BA*9?9BB(B(?################################################### +@SRR800764.25006 25006/2 +TTGACAGAAGATCTATATGACGAATTGCTTAAGCACAGATTGAATATTGATGAAGCCTTGAGAAGGCTAGGATCCAAGAGACCAAAAACCAAAATGGTTAG ++ +@B@DDFFFHH8?DHGGGHIGGIIIGGHIHEBFIHIGDHGGGF>D>4?@DGBDEEH?FCHIEE=EGEIJICGHECE>:AB>;;?AC@AA?=AABA:>C>:A# +@SRR800764.25007 25007/2 +TTTTAATATCAATAGATGCTGGTGTTACTAAAGGATTACCAGGAATATAGTTATCAGGATGCTTTTATAATAAATATAAAATGGACTATATCTTCATAAAA ++ +?@@FF?DFF?HHJFGHHIGII@GGGGHBDBHICBGG?DBF?BBGEIEHIG7?EEHFFEC:ACCCDDCEC +@SRR800764.25008 25008/2 +CTGACTTATATATGCGAATGCACATGAATAGACCGCATATGCTTCTTATCAGTCTTACCTCGCTTATCTTTCCCCATTTATTTGCCAATCCATCTTATCTT ++ +@C@DFFFFHHGHHGIIIJIHIIJJJIJJJJJJIIIIIJJJJJIJJIIIIIEFCHIEHGIGIIJJGHHHHFDFFCDCCECDEDEDDCCCCDCCDCCCDDCC@ +@SRR800764.25009 25009/2 +TAACTTTAGTTTTCAAATCTATCATCAATTCTTGAAGAACTGGAGAGCTTTCTAACGTATTCCCATATAATTCTAAAACCACGGCGACCCAATCCGCTACA ++ +CC@FDFFFAFHHHBHIJIJJJJIJJJJJJJIIJIFIJJJIJJHIJFCADHGGHIIGIBFHIFGGIDIJEIIIGIIIGEHDEEEFFDDDDDD?CCCBDDDD@ +@SRR800764.25010 25010/2 +AATAAATAATATACTATGTTTTATTAAATGAGATAATAATAAAATTTTATTATTATTAGATATATATTATAATGTATTATATAACTATCATAAACAACGTA ++ +CC@DFDDFGHHHHJJJIIJJJJJJJJJJJJJJJIIIIJJJIJGIIGIIIJJJJIJJDCGIHHIIIJJJJJJJIIBFGIIIJJIJJJJJJIJGIIJHHHF?> +@SRR800764.25011 25011/2 +TAGTACTTATGATGGTTTTGGTCTAGCTTGGGCAATTGCTGAACATATCGCAAGTAAGATTGGATGTTTCGCTTTGTTTGCAACTCACTTTCATGAATTGA ++ +CCCDFFFFHHHHHJJHIJJJJHIJJJFJIJJJJJJJJJIJJJJJJJIJJJGHIJHJJJJJJJJJJJGHIJHHHFFFFFEEEEEEDDCCDDDDDEDDDEEDC +@SRR800764.25012 25012/2 +GAATATTTATCAAGTGCATAGGATATGAGAAATTCTTTTATTGGATCAATTTCTCTTGAATGAGTTTGCCTCAACGAGTCGAAAGTCAAAATATTAACCAG ++ +?@@D=:ABDFHABHHEBHEGBHC@FEGGBFHEGGDHHG:BDHGCHIJIBFIJBG@HCC;/BB@DECC=>;>C>@BCDDD@ +@SRR800764.25013 25013/2 +CCTCAGCAGTAACTCCATCTACCTTTGGGGATTTGAACCATCTCATTCCAGTTTTGGATAACTGCGATTAGATTAAAAGATTAAAAGATTATCGATTAGAT ++ +CC@FFFFFHFHHHJJJJIJJJIIGJJJJJJ?GHJJJJJIIIJIIJIJIIJHFHIJIJGGIJJEIJIIJJHGHHHGFFFFDEEEEDEEDCDDDDDDDDDDDA +@SRR800764.25014 25014/2 +ACAGACTCTGTTAATATTTAAAAATTTTTCCTTTTCGGCAAGCACTGTGTTAACTAATTGTGCAAAAGCTTTGCTGGTTAACTCGGACTTCAACTTAGACT ++ +@@BF;;DDFHDFDEGGGIHHJIIIJGGIJJJIGIJJJIJJEHGG?FGDBDEGGIG@CHHIEFHCDDEEGGHGCEECCDDFFEEDDDDBBDDACDCCD@CC: +@SRR800764.25015 25015/2 +TATCAATAAATAATTCCTTTGAACTATTTATTATTTTATTATATTTATTTTCTCCTTCATTATTAATTTTTATTAATAATTAAAATCTTATCATTTTATGG ++ +@@CFFFFFHHGAHHGICHGIJIJJJJGIJJJJJJIJJJJJJJJJJIJJJIGFHIIIIGIHIGCAA2;;?BCEECECA@; +@SRR800764.25017 25017/2 +TATAAATCTTGTATACACTTCCTCAAATTCAAAGTTTTTGCCATTTAACTGGGGTGTCTGGGATGAATTCAAAACACGATACAGAATACAACAGTATCAGG ++ +@@@FDBDDHHDDFHAHGDHIIJJIIIIJIJ@EGG?FFHJJGICFHGIIIIE>GGFD7BFHGG9FHE=DGEHEHCHCBE?CCADDDDC@>>>@AB:@BCDDC +@SRR800764.25018 25018/2 +CTGGTAAAGGAGCTTATTTTGCAACCCCACCCGTACAACTAATTAATAGCCTTGATGTAGCCTTGAAAGAAATTCTCGAAGAGGGGTTGCATAAGAGATGG ++ +???DDDFFH>;FFHHGBGIIIIGHGGDHEHIGI8?DGGJDGBGFHIA>;=?B=@@<>>CDCDDDDD@ +@SRR800764.25019 25019/2 +AAAATATCATTGAAAAAGCACTCATTCTGGTTAAAGTCGCTGAACAAATTGGAAAGATCCAGTAAAGCTTTTTCTTTTGTAGTTTCATCTCTTTTCAGAAA ++ +1:8AD+2A4A=,AGHIA)+7)76A3(-=B7?37?################### +@SRR800764.25022 25022/2 +CTAACCTTAAGACCTGAAAAATGAACAGAGTTTTTATAAAATTTCAGTTTAAAATTGAATGTTGCCCTAACAATATGGATTAAAACCCTGACATATTAGGT ++ +@B?D=+ADDD>FHIEIEGHHJGG>HHIJEGHI@>GEDHIJIIIICB>GIG@GHI:D??FEHAF>FABACC@FG;C;CD@;>EHCHBD?;;@CA>;;C@### +@SRR800764.25023 25023/2 +TCTATCTAACGAGACCTTTGATTGAACGACAAAACTTAACATATCAGACAAACGATCCAAAGGATCTCTTAATAACGTGAATAAAGAAAGCGCAGTAAAGG ++ +1?+B=DADFBDFCFB?('5-&2>ACC> +@SRR800764.25024 25024/2 +ACAAGACTAAGCGAAGGAGAGAAAAATGCTTGAAATTTCGATTAAAAAAAAAAGGTGAGATGCAAGGTTGGTTAATATTACTGTGAATTGAATAAATTTCC ++ +@@@DD8BD?BDFA:EG6+<2BGIIEDG(?FHGIIDDC9;(5(=(>@:5AC(555-(2(+4>BD@##################### +@SRR800764.25025 25025/2 +TATATAAAATAAGCCAAGACAGTGGCCTTCCCTTATTATCAGCGTACTAAAATCTCATATGATTTATTTTTCGTGGTCCTGAACGAGTGTGAAAAATTTTG ++ +?;8BDDDFF?FHCBGEEEEEHJE:?FCGCCBGA>GGIDFAI>GHBF6B@??9EG?B)==888CHGHG>DC:@@AC'=?@>;)(6;'35=((;>>>AACC@3 +@SRR800764.25026 25026/2 +CTTCAAAAAGCATCTCTGGAAGAAGATCCGGCAAACCACGAATTCTGTTTGATTCTGCCAGAGCTCAAAGAAACTCCAAACGCAACCATTCTCTGAAAGCG ++ +C@@FFFFFFHFFHEGIFIIIJJIJIFIGIIIDEHGGIJJIGIGGIIJGIJ@FIAFHHIGEGHFHHFFDFFFEE3;;ACCDDDDDDBDDC:BDACDCDDCDB +@SRR800764.25027 25027/2 +AAAGCCAAGTTATCTGCCTACGGTTGTCACAGCAACATTGCGTGCCGTTGTTCTTTTGTTTTTTTTTTTTGTTTTTTTTTGTGGTTTTCGCAGCAACGAAC ++ +B@@B;;D:B2<CE=BCD);BDC>CEEDAACDD@=?@B?A?CDCCDCCDDDCDCC?>3 +@SRR800764.25029 25029/2 +AAATGCTGTAGTTACGAATACAGCTAGTGGCCGCTTCGATGTAACGCCCACTGTTCAAGACTACGTGTTTATACTTGACTTAAAAAAGCCGGAAAAACTAG ++ ++??D:+:DB>CF,1):8@@6@89909B?B####################################################### +@SRR800764.25030 25030/2 +ACAAAAGTTTTATTCGATCAATACATCGTTATACTGAATCTACTTTGGTGAAGCAGGGTTATCTTTACTGCTATACATTGGACAAGATTTATTTGTTCTAA ++ +@@@FDFDDCHFADGGH9EHII@EGIJGG;FCGIJIJJJIIEHIFJGDCBDGDGGI;FGHH=7=CHGDGEHE@CHEHHHHHG;CCC>@=@:;; +@SRR800764.25031 25031/2 +GATTCCAATGATAAGTTTGTGCATGTCCAGCTGTTAATTAACTTGAAAATCTCACCGTTGATGAAAAGTCAATACAATATGGTATTGAGGAACGTTATGGA ++ +CCCFFFFFHHHGGIIGHIIHHJJIJJIJJJJJJAGHIJJIIJIJJJIJII9BDHIFGGHIHGGIJJIJIGHIJJJIJJIFHG7?CEHFFFFFEDACCDDDD +@SRR800764.25032 25032/2 +AATAATTGTAGGGATAAATTTAAATATGGCATAAACTAAATAAGGAGAGCATGAAAAAACTGCAAAATCCAAAAAGCAAAAACGAAGGTCAGAAAGTAAAG ++ +8@1;?BABC4A>1A+H9BA@GGG3300BBFCG<***9--=@)=CHC@DEHC?############################ +@SRR800764.25033 25033/2 +ACTAAAACGTGGTGAAAGGAAATTAATATTTCCTGATCATTTCTTATGACTATAATTTTACGGCTTTCCTTCTTTTTATTTAGCTTTGCAAATTGCAACTC ++ +?;?=DDFFFHH?AE@F+FE@FGE>DF>4BDFHFAGGHIE9*09BF;:'-'=CG@;.7)77)6;???;?B:>CCDDA;;(;>CCDC +@SRR800764.25034 25034/2 +ATAAATAAAATAAAAAATAATAAATATTAATATTATTAAATATTATTTATAATAAATATTAATATTATTAAATATTATTCATATTAATAAATTTTATTATT ++ +BC@FFDBDHADHHBDHBEHHGH>HHGBF@HG?CED?GFHBFFHE@HGHHIH>FGGGIDGFHIJCIE:BCCGGDGGFGHJJIJJBG:@E>CEAE>EEHFFFF +@SRR800764.25035 25035/2 +ATTTATAAAATTATAAAATTAATTTATATATAATTCAATATATATATATTAATTTATATATTTAAATTAAATATAATTAAATAAATAATAAGATCGGAAGA ++ +?@CFDBDDFB?EHCH>?BFAEE@FA;E=4=4AED@ +@SRR800764.25036 25036/2 +CTCAACCACAAACTTTGAAAGTGTATGACTACAAGGGCAGTGGTGGGGCCATGGCCATGTACAATACTGACGAATCCATCGAAGGGTTTGCTCATTCGTCT ++ +;C>C@B=;@CC?>C??B5??BD(:>@:3:>2< +@SRR800764.25037 25037/2 +AGCAACCTACTTTATCTCAATCGAAAACGAAGTAAAGTTGCGGTTCCCTCTGTCTCTCCTAATATTATCCTAAATTTATGTTTACAGTCGCAAATTAGATA ++ +@@@DFFFFHHHGHJJJGIJJJJIJIIGIJIJIHIJJJIIIJJIFGDGIJIFIGGI>DHHIG>EEEFHG>A@@EFDEDEEC@@@ACCDBCBDBB=@ACCDCC +@SRR800764.25038 25038/2 +CTGATTTATCACTGCAAATGAAAAGCAATCAATACGAGATATTTTTCAATCAGTCAATTTCTGTGAAGAAGATCATTTTAGAAACAATGCCTAAATTTGAA ++ +@@@BDADFFAHGG9EGICIIJGIFGIIGDGGHH@DEEGIHHAHFHDB3;;AACECCC;>A@ +@SRR800764.25039 25039/2 +TTCCATGTGTAGATTTTTAAGGCAACGATTATTAATTCATTTACGACCAAAGCAGTGAAGCAAATAGCAACCATCCTTGTGAAATCAGTATCTAATAAAGT ++ +1++4=,,222C?,,<@G>F@9):8)?D?)8CG8B############################################ +@SRR800764.25040 25040/2 +CCCCTGCATTAATCGCTCTTTCATTTTCAATTTCTTTCTCGGAGTCCGCTATCTTTGTATCTTCTTCTTTCTCGTTTTTACTTATTAAAAATTCGATAGCG ++ +1++4A:3BF4+FEGHHHIJIGGHHGGGHIGGGGIGEHHHHHFFFFFFEDEEECEE +@SRR800764.25042 25042/2 +CCGCACGAGAATTTGTGAAACGTGGCATGTGGGGAACCCGCATGAATAGAAAATATGCTAGACACGACTCTTGTTTACATTGCCATTGGTGGTGTATGTAC ++ +:++=B8BA?))A@ADBDB>C>@AC@3>A>A@CC@CCD +@SRR800764.25044 25044/2 +CCGAATAATCTCTCTTTTTGCTATTTAGGGGAGTCAGTAGAAGGTTTTCGTGTGATTCATCAACTGTTTCTTGAGAACTATTCAACTGAGATGAGAGGGCT ++ +BBECEECCD@@CCC>ACA>@A8:?2 +@SRR800764.25045 25045/2 +ACTATTTACAAAGTTGAAGGTTCCGGATGGATACAGAATAGGGATCCTAAATATAAACACTATATTTATTTATTTTTTTCGAATAAAAGTCAAGTTAGCAA ++ +@@@BDFBFFDBHHIIIBHIJHGEGGIB?CHG@>D>DHAE9DGDHH@FDFHHB<8=CBFG@@;FGI4@@@E(7AC;;@DED36;>C;ACDDACC=<<ACAB? +@SRR800764.25047 25047/2 +CAAAGTAATAGAGCAAAAGTGACATCCGCAGCAAGCTGGACAGGTAAATTGCCTCATACAGTCTTACACGAAACATGTCAGAAACGAAAATGGAATAAGGT ++ +;;@;AD>?D?BDDBEGAHHAC?H?F>C@C(-5>@;?BD@CC######## +@SRR800764.25048 25048/2 +TCATCTAAATCGAATTCTGATACATTTTCCATGTCAGTTGGTAATTGATGCGAGCACGCTAGTAAATATGATGTACTTGTAGGTCTCCAGAAGAATGCGAA ++ +@@BFFDDFHFFDDEHFC>CCEEEDCDD?CCDCB@? +@SRR800764.25049 25049/2 +AAACAGGTAATGATACAGTAGGGCAGGATACATCACTTTCTGTACACTATTATACGCAGGCAGCGTTAAAAGGCGATTCTGTGGCAATGTTAGGTTTATGT ++ +@CCFFFFBFHHHHJJJIJIJIJJJJJJJJJJJJJIIJJJIIJIJJJJJJJGIJIJIIIJJJGGGHEHHFFFDFDCBBDDDEDCCDCCDD:>BCC+44?CCC +@SRR800764.25050 25050/2 +TAAGTTTGAATAAATTGAGATATTTGGATGCCGTATCGAGCTTTAATTCAAGTTCAGTCAAGTCGAATTTCGCGTCTAAGGTCAATACCCAGCTAAACCTT ++ +@@?DADDFGHHHFGGHE>HCHIIJIGEGIGGFFEE?DHHG)BDDF<9??D?DBF><88BGF>8@CC=EGI:D==9ACAA5=>3;A@C(>:A?CC +@SRR800764.25051 25051/2 +GACATTGAAGGGCTGATTAAACATAAAATAGAATTTGACTCAAGAAACATGAGCCAAGACGAAATTGAAGATGGCAACTCTTCTCAATCTCTGAATATATA ++ +;=@?BD442A;F7FADGH@HICCFGIJIE?<9C99::?<:DC;??;DBFH3?9D@;FDAA@AAG=D:;CECA3?7)).?>AC;@CEA(5(5@CC@@##### +@SRR800764.25052 25052/2 +CGTCGTGAGACTACCTGGTTGTGATTTGGGTAGTTTCCTACTTATGGATCGGTTCCTTAGATACGGTGGACGGCTACTGGTTGCATACATCTGGCTTCTTA ++ ++:1BD0)+<<2+++<3:<1+AFIEFD1*1:?D4B9 +@SRR800764.25054 25054/2 +AATCCTAGGATCTACCTTTATACGCATTTATCCTATAAAAACCCAATCTTTCAAATACACAGTATTTTATATGTGTGATTTCCTTGATTGACTCAATTTAA ++ +<@=C=D:@AD=CEHHC################### +@SRR800764.25055 25055/2 +TGTCAAGACGTTTTGGTAATAAATGCTACTTGAAAACCCTCAAGAGTCGCTACAAACTTGCCGTTCCTTAATAAATAAAGGCAAGCGTTATATACATGATA ++ +BDFHHFHBDF22CHHIIJEGC9FFBEFCDGIIGIIGD3FH?DAD'7FHHC(.==;);=E?;B;@C>@@C;@A>;5(5==55(58?C3>34@C>:> +@SRR800764.25056 25056/2 +GAAGAAAGAAAACATAACGATGCTTTACTTCGTGGGAAAGACATATTCCAGGATGTGTGGTTCCCTATGTTATTCTGCTTCAATGATACGATCATGACAGC ++ +CCCFFFFFHHHHHJJIJJIJJIGJIJJJJJJJHIJJGJJJIJIJJGIJIIFIEHHFHIIJ@EHIHHGHGHEFFFFFFFEEEEEEEDDEDDBDDDDDDCCCB +@SRR800764.25057 25057/2 +AGAGCCATCTTTACAACCAATAACCATATACTTACCATCATGACTAAACGTACAGCAGCATATTGAATTCTTGAATAGCTCTGAATTAGCAACTGCAGGTT ++ +@@CFDFFFGHHHHGJJJIJJJJJJJJIIJJIIIJIJJJJJJJJDIIJGIIJIJJJEGIEIIIIJIIIJIIIJJJIHFFFFHHCEFFFFEEEEDCDCDDD=@ +@SRR800764.25058 25058/2 +CGGAGGCGTTTTTCTTAGGGTTCAATAACCCAACGCCTGGATTAGAAGCTGAGCACTCAAGCACATCGCCTGCCCCCGAGAACTCCGAAACACATAATAGG ++ +:B?DDD7BC8DFH@FEBGGCIICFIIJJGJ?FHBEGIG=HIIDHECCGGGGAEHEC3?>@@(;;C@>B;?:??99(899<9&::AC?>80=FHIG=7=@A=E?7??>DCD?CCECC@;?A?####### +@SRR800764.25060 25060/2 +ATTCCTTAAAGAACAGTGCCAATTATATATAGGACACCCCCAAGTAATACCCAAAAGAGCTGAATTTGGGTCCAAATTTCTGAAAAACTATAGCAGTAAAG ++ +B@@F?,ABFBEFHGFHHCEAFHGGE;FHBAHG9?FGEGFEHGGH9;@@@GCGDGGH7=?A?>D);@CC@>AAEA;;@(5;;>CC@CACD +@SRR800764.25061 25061/2 +TCATAGTTTCAGTTCACAAGGTAATAATAACGGAGGTGGACGTAAGTCCCTATTTGCACCCTACCTTCCCCAAGCCAACATTCCAGAGCTAATCCAAGAAG ++ +CC@FDADFFFDFHGHH9BHHJ+AFEEHIJJIIFIGI?DFGHE0BBB?DGGFHCDFF/B@FH=;CGGHHFC>DBEDDA3@AEHE>;?7777;>ABD@B?BCACDDE>A@C>4 +@SRR800764.25063 25063/2 +GTCAAGGTTGGGCGCCAATGCTATCCTTGGTGTTTCCTTGTGCGTTGCTCGAGCTGCTGCCGCACAAAAGGGAATTACTCTCTACAAGTATATAGCCGAGT ++ +C@@FFFFFHHHHHJGIIIIJJJIJJJIJGH?DGIIGGJJJIHEHIIGIIJEEIFHH@DFFFB>BDDDD?C?BBA?ACCDDDDC@CCCD:>CE@BCCA>>@B +@SRR800764.25064 25064/2 +ATAATAATAATAATTTTATTTTTATAATTTATTAATAATAATAATAATTATATATATATTATTAATAAATATAGACCTTATCGTCTAATGGTTACGACATC ++ +@1?D?BDDHFHDDEGGBEGHJIGHJECHII9DHCFHIGGIIIGAG9BFGIIGGHIIEHIIGIIJJIHDGIIIGICF>F>GH;2@CCDHIJ@=AECAD?:A?+2AEAH<+<DD<@GB*:1*0::***:?@>>CDDD;AC><:>ACD@>@CDDDDDD@AACCD@CC@ +@SRR800764.25067 25067/2 +GGCATACATCATGAAACTAGATAATTCACCGACAGTCATTGAACCACTTTGAATCATGCTTGTTCCAACCAATAATAACGACAGCATTGCAGTGTTGCCAA ++ +@DD;'6.6(7;7;B'99?A>C############################# +@SRR800764.25070 25070/2 +TGCTGCTTGATGTCTTCGCACTTTTTTTTTCCAGATTTTTCAGGTGATGAGGTGGATCTGGCCGGTTTTACAATAATACTCAAATAATTTGTAGACAACGT ++ +@@CFA,FHII@8)..=C4@77.6(6).7)).(3'''35:@(5(:(:>@C>(9@@CC>@@########### +@SRR800764.25071 25071/2 +TTTTCACCTTTACCCTCGTACAAATCTGGTAAATCCTTTTTTAGAACTAACAATGCACTAATTACAGTATCAACCAAGATTTGAGTTTCTTCCTTAGTAAA ++ +;.6;BBB6@#################### +@SRR800764.25072 25072/2 +TGTAATGGGATGAGTCTATATTTAAACAAATTTCCTGAGATCCATTCCACTTATGATGAATCAAAAGCATGGCATTGTTTCTGGTGTTGTTTTATAATGGA ++ +CCBFFFFFHHHHFIHHGJJFJJJIIIIIIJIIHHIGIDGIGIHJHGHIEIDHIIJHCGIJGGIEGACHHD@CHIHCA=@DHAAE>A;BE3=A@CCCDCC:: +@SRR800764.25073 25073/2 +CAGGATACTTCAAGAATATTAGTAGCTTGAAATTTGAACACATTAATTCCGTATACAGTTCGTCATCATCCAGCAAATCGTCTAAGACGTCCAAATTAGGT ++ +?@BFDD?DDDBFHIBABADECJ>BEHHHIG>HH@HIDHH@EHBHH@DE>F;?;D39?00?B?(;C2==FECC:37.7@CE?;@BDEFDD;>?######### +@SRR800764.25074 25074/2 +CGGCATTTTACTGAATAATAATTGAGATATTCGTAACTCTTCCGAAATGATTCTAGAACTGTCTTCTACTTGCGAAAGAATATATTTTCTATACGTCCTGG ++ +??7;+A:DA:A,2A:EC?,3,,<3+<+3@C@;>CA3AED@@3;77;@C?CED@3-;;>C## +@SRR800764.25076 25076/2 +CTGTAGCTTGAAGCAAACATCACAAGGGACACCACCAGAATAAAGACATATATGAGAGGGGTATAAACGGAGATTGATTTCGTCTCCACAATTGCCTCTTC ++ +?B;;@>A(,89?3@<3?########## +@SRR800764.25077 25077/2 +TATTTTATATAATTTTATTATCATTTTATTATAGCACGTCTATTACCCATATTATAAGGATCATTATGATTTGTATTAATTCCTTTATTTATATTAATAAA ++ +<@FBGI4AHA81?:DBC;C>BF*B<4*?GFG>9CEC4//8>))(6B@''-,?).)>C@C6;5>;=>BA>C############### +@SRR800764.25082 25082/2 +CGCCCCAAACTACTTGACCAAATTTGTTTGATTTCTGCCAGTTCAAGTTTTGATCTATTCTTTGCACTTACTCCAAAAATGCTGATTTCTCCACCGAAACA ++ +=@@++=B7A;DFFABEAC@3CACFEA?)???DF?1*CFBFEFH>>B@*0*9??BCCE).;@6>;;A######## +@SRR800764.25083 25083/2 +AGCAATTTTTCTGGAATTTCAGCTGTTTCCAAACTCAATAAGTATCTTCTAGCAAGAGGGAATAGGTGGGAAAAAAAGAGATTTCGGTTTCTTTTTTTACT ++ +@@@FDEFDHHAHHHEGGHJ>?AFHF?FHB@AHHIJEGIGHHHC?FGIGE>FFHGHGGGGIDCGEHHIIIDAC;=>BA@D?CDCCC:@CDDDB### +@SRR800764.25084 25084/2 +AAAGCCATTTATGACACCTCAGTGGGCTATTGGCTACGTCACAACGTTGATGGATTTCGTATTGACGTAGGCAGCATGTATTCTAAGGATGAGGGCCTACC ++ +?@?BBDB+ABF4CEB+ABAFG>??@D9CB))8=)8(.)=@>CE?CABCC?=>(..5(;@>((-;(:5AA:?'5<>AA +@SRR800764.25085 25085/2 +TCCACGTTCAATTAAGTAACAAGGACTTCTTACATATTTAAAGTTTGAGAATAGGTCAAGGTCATTTCGACCCCGGAACCTCTAATCATTCGCTTTACCTC ++ +=?@+BD2ABFHDDDE>ACFIIIFEDEHCG>B@C>>>A;@CD:? +@SRR800764.25086 25086/2 +TTTCATAAGAAGGGATATGAAGTATTGTCATTCCACAGAGGATGATATAAATCAGTCAGGTCAACACTGCTAACAAACTCCTCTAAAGTACCCAAGTTGTA ++ +<@;;D>>D:4C:<1A:A?CE<43,AEH<2+++AEC3*):?C@9:B9??@B*9EG@@FB9C)8BCH@GEHHIDI(.=C)77;;?DC776.;A####### +@SRR800764.25087 25087/2 +CTGATGAAGCAATCCTGGCCGTGGCCACTGGTTTCTGTGCAGAATCCTCCCTTTTCAAGCATGAAATCGCCTACGTCGTCGGTCAAATAGGTAGTCCGGCT ++ +;@;:?;?+=CDFDG3+CE9A))2E;7.(5=<873.;'3,88280AC@C:>>@:::@#### +@SRR800764.25088 25088/2 +GCTATAATATTATGGATACAGAATATACTTTAGAAGGTCTCCTCGATGATATAGGAATCCTCGAAATGGAATCTATATTTCTACATACTAATATTACGATT ++ +::8D;A4=,ACHHA+C> +@SRR800764.25090 25090/2 +AAAATCTAAGAGATATGAACGGTGATCTTAAGAAACTGCAAGAAGAACTTCCCAGTGTAGAAAAAGACAGTAATATAGTGATTCTTTGCCGCTACGGTAAC ++ +@@CFFFFDFDHFFAE4CEHDHGHI7BFBHCHIG>DHII9DGGEHGII3BDFFGIJFGC>?@BB##### +@SRR800764.25091 25091/2 +TTTAAAACCTAAAGGTAAACCTTTATATTAATAATGTTATTTTTTATTATTTTTATAATAAGAATAATTATTAATAATAATAAACTAAGTGAACTGAAACA ++ +CCCFFFFFHHHHHIJ:CFHIIIIJJJIIJJJJJJJJDIIJJJJJIJJIHGHHHIJJIJJJJJJJJJIJJJJIIJIIIGGGJFHGFGHEFBEDFCEECEEEC +@SRR800764.25092 25092/2 +AGAGATCAATAGGAGCAACATAATGAACAATGCCCATGAAGAGAACATTTCTTCTGTAACAGGGTTTAAGTCTACATCAGGATCACCTGCAATAGGGTCAT ++ +8@@A?D?DBCFHD@GIIH3AEHID@9A9AC9:E?)?:DBB?DDHC3?GGFEII>*9??FGBCG;).;@G;=AEE@=:A>A??CFE;66(66@>:@5,5>A3 +@SRR800764.25093 25093/2 +AACCTTATCCCTTAGACACAAATGATCACATCGAGTGGATGAACTGTCAAACGACCCAAAGTGAATATGATTCCAGAGATTTCTATGCTTTCCATTGTTTT ++ +@@@?DFFBFBDHHGHCDDDD3-;;;;>BCCDD? +@SRR800764.25094 25094/2 +GAATTTATTAGTGCAGAAGAATTGTTTCGAAATGGATTCTTGGAAGATTTCGTGGTAATATTAAAAGGAACAGTAGGTTTAGAAATGAAACTCAACTCAGG ++ +BB@DFFDDHDHFHJJIGHHFGIIJIIIEHGHGHIIGIIJIJIGDFHCEGIIGGGIDFHIDGHHFHIIJGGIIIHEHH=>C@D@DFFDCCACE>CCDDDDCA +@SRR800764.25095 25095/2 +TATACTTTATATTATAATAATTATTATTAATATAAACTTATTATATTATATAATTTAATATAATAATAATAAGATAATTATCAATAAAAATTACATTTTGT ++ +@@<=DDDDH??BHIIIGGHIEHHGHGIADDHEIGG@HHIJIJJIGIJI>GAHHGIE>HCGGHIIIJGGAGH@HIIIIIJIEIIGICGFCCEHHGGHEEHEH +@SRR800764.25096 25096/2 +TTTGGATGTTGTAGTCAGACAAGGTTCTACCATCTTCTAGTTGCTTACCAGCAAAAATCAATCTCTGTTGATCCGGAGGGATACCTTCTTTATCTTGAATC ++ +@BCBDDDFHHHFHIIHJJGGHIIG@CCCCCDDCAC::>CC +@SRR800764.25097 25097/2 +AATGAAGCAAGAACTAGCGTTTATTGAAAACGTAATAGCACAAGATTTCACCACCACATATTCTACTAATAAGAATGATAAAGTGAAAGGTTTGGGAATCG ++ +@CCFFFFFHHHHGIIEGIIAGIJIIJJJJIIJ?GGHJJJJJJJJ@DHGGGHIJIJJIIIJJIJJIJJCHFHFEEFFFFFFCCC>CEDCCB>CC@BD@CDDB +@SRR800764.25098 25098/2 +GTATGGGCACGTATGCCAAGTCGTTGTTCTTGTGAAGAGAATGATATGTGCAGTGGTAAAAAGAGCCCGTGACACCCAGCAGCAAAGTGCGACCGCGCTTC ++ +++1=1B>>D1CD######################################################################################### +@SRR800764.25099 25099/2 +ATATATATACAGGCAACACGCAGATATAGGTGCGACGTGAACAGTGAGCTGTATGTGCGCAGCTCGCGTTGCATTTTCGGAAGCGCTCGTTTTCGGAAACG ++ +@CCFFFFFFHHHGIJIJJIIJJJJJJIICBCGGGIGGDGIGHGIHGIIDDGGHIGGI=HHFFDEEDDDDDDBDDEDEC99@BBDBCED=A>(;3,;@;@3:A>:55 +@SRR800764.25101 25101/2 +TTTCTATTTTATCGATGCCGTGTCTGCTGCCATTACGTACAGGTAGGCAAAAGCAAACAAGAATAGCACTTTTTCACTTGCTGCTTTTTTTTGTGAATGAA ++ +@@@DDFFFBHHFDGI9EEHGDHGHBFGEG@FDDFHGGGGHIEGHDHHE>?BFHIEFF;FDFCGGG;;EHHCFFFCCFBCEE@E;>C@A>@=BBAC:AC>@> +@SRR800764.25102 25102/2 +CCAGCAGCCGCGGTAATTCCAGCTCCAATAGCGTATATTAAAGTTGTTGCAGTTAAAAAGCTCGTAGTTGAACTTTGGGCCCGGTTGGCCGGTCCGATTTT ++ +CCCFFFFFHHHGHFHIIIJGIGGIJJJIJIJIJHIJIJJJIJJHIJIJIJJJGAHIJHHHHFFFDDDADDDDDDDDCCBC@CC################ +@SRR800764.25104 25104/2 +CACATCAGCAAAGTTTCGCTTTTGACATTCTGTTAAATTGGTCCCTAACTGTTGGTGCAGACCTACTGCAAGACTGTTAATTATGGTATATTATATATCAA ++ +CCCFFFFFGGFFHIIIJJJJJJJJJJIJJJJJEHHJJIJIJEHJJJGIJIGEHIIFGHIJIEHDIJJJIIGHCHHHHDFFFEFDFECDCCFDEEEFFEEED +@SRR800764.25105 25105/2 +CAAATCGCAAGTTTTCTCTCTGCATTAACTAAACAATACAAAGACTTAGTGGTCTTCAAAGGCACTTTGAGGGACTTTTTGGTGCAAATCAAAGAAGTCGG ++ +@CCDDFFFGFHHHJIIIJJJIJJJIJJJJIIJJJIJIJJJJJJIJJIIIIHGIGHIJIJEHIIJJJJJGGIJHEFFFFFEDD?@CD:A>CDDDD>BC::?9 +@SRR800764.25106 25106/2 +TCATTTACTATCCATTATGTTATGAACGGGAACTATACAACTAACCTAAGAATTTTGAAATCACAACAAAAATAATCAACATCACAGTCTCGAAGGGATTA ++ +CCCFFFFFHFFHHJJJJJJJJIIIJJJJJJHHIHGHGIJIJIIJJJJJGHIIJJJJIIJJGHIJIIJJIJJJHHGHHHFFFFFEEEECCDDC5=??B@CDC +@SRR800764.25107 25107/2 +ATAAATGTGGAAAGCTTAAATAAAAAGGTCGACGAGGTTATTAGAACAACAACTTTCAAACTGAAACCGCTAATGGATAACTATCAGAAAATTTTGAATTA ++ +CCCFFFFDHHHHHJJIJJJJJJIIJJJJHHGGJJGGI?DFHJJJJJJJJIHHGGIJJJIIJHHHHHHFFDDDDDDDDDEDDDDDDDCDDDDDCDDCDDDDC +@SRR800764.25108 25108/2 +GAAGCTGGTCTGCCTTGCTTGGCCAAGTACTCTTCCAATTCGACTTGTTGCATACATTCGATACCAATACCAGCATCAATCTTACCTTCGATGATGTACTT ++ +B@CDDFFFHGFFGIIJJIJIIJBFGEHJJJIGGGBFEGGIGEHDFGIDG@DHGHJJGICHGCGHGGIJIIIJHHHHEC@DFFDCCACEA?ACCADDADEB5 +@SRR800764.25109 25109/2 +ATTTATTATTATTGTTTTTTAATAATCTTATATATAATATAAAAAATATATATATATTATATATATATATAAATATAATATATATTATTATAAATATTTAT ++ +CCCFFFFFHHHHGIHGJJJJJIJJIJIJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJGGIIJGGIIIJJIJIIGGHIJJIJIHHGHFHHGFCBEFFFDDDC +@SRR800764.25110 25110/2 +AGAATCATTACCTAGATTATAACGAATTGAAAAATTTGATCTACACATTACAGACAGATGAATTGAAACAAGAAACGACAACCGGAGACTTAAACGATGAC ++ +???D1AB4A,=:?F377787=7CEH########################## +@SRR800764.25111 25111/2 +TTTGGGTGGTAAAAATAATACTTCCTTAGTTCCAAGGCTAAAAACAATAGAAATGTATAGACAAAACGTTAAAAAATCTAAAGATCCTGAAGTGTTATTCC ++ +?B@FFFDDDHDHHJJIGIJJIIJJJJJJJDCGGIJ@DGIJIJIIJGIEIEHHIGGGHGIIFDFHGEIGDHHFHHEDCECECDCCC@@CCACD@C;@ACCDA +@SRR800764.25112 25112/2 +GGTGTCAAACGGTTACCCTACGAACAGTTCGCGTCTTGGAGCCCAATAAAAGAAAATGAGGCTTATCAGTTCTATCACTATTTAACTTATTAAAAAACATA ++ +?;BA=BDDHDAAFFI@A2CDH<12?G?*:1:D?0?(?F93BCCG######################################################### +@SRR800764.25113 25113/2 +AGGCATTTCAAATTAATGAAGCAACCCTTATTATGGCAATCCTTTCAAAATCCAAATGATCACCATAATGAGTACTGTGACAGTAACGGCAGCAACAATAA ++ +B@@=??:DDHHBHGHI@EEIC<@H9A@+AFHIIDC9?GIIIGGEHECGCF@DH@BFH@7AC?A#### +@SRR800764.25114 25114/2 +AATTTCAAATTTATTGGTTCCAAAAATGAGATTTGATCTACATTAGCAGCACATGCACGCAAGGTTTTACCACCATCAGCAAAGGCGACGTCTGGAATGGG ++ +@@@BD;BDFHHFBGB+HCD?D):DAFAD>@((:;:@DCCD## +@SRR800764.25116 25116/2 +AGAAATACAAAACGTTAGCATTTGCATTTGTTGGACATGTACTGAATACAGACGACACACCGGGACTTGAAAAAGAACTGGATTGGCCAGATCCTGAACTG ++ +11+4B+A:2AF+<<22+2+AFFFBHIGIIGA;FED@DC@CC(;;>;;;=????CC@ +@SRR800764.25118 25118/2 +AGCGCTTACCACTGCTGTACTGGTCAATCAAACCATTAATGAGCATAACTATCCAAATACTCAACGCTATACAAAAGATTAAGTTAGGTGACTGAAAGGTG ++ +##################################################################################################### +@SRR800764.25119 25119/2 +CATAAGTTTTTCAAATTTTCCTTTTATTATGAATTTGCGCAACGACACCAGCGCTATTGCTAATGCGTTCAAAACAGGGAAAGTACACGTGAAATTTTAAA ++ +BC@BBFFDHHHGFGI@AC>4>4 +@SRR800764.25120 25120/2 +CATGTCATTATTTGTAAACCTTCTCCCCGCTCCACCACTCATCATTTCTGTTAAGGAGGCAGTAGGGCGTAATATTGACCCAGAATCCCCAATTGTTGAAT ++ +@C@FFFFFHHHGHJGFHJGGIJJIIJJJJIEIJIIIIIIGIJJJIIFIGIGIIJIGGGIHGGCEEBEHFACBDDDDDCCCABABCCCCCBC<9:ACCB:>C +@SRR800764.25121 25121/2 +TCCAAGCTGGGTAAAGATTTCAAAATTTAATATAGTCGTCTTTGACCCTTTGAGTAAAAAGTGCTTTTCCCAAAATTTTGTTAGCAAATTAATTGACTGAC ++ +@@@DFFD>?F;2@7BEEHH=;.7?@B>)7;;;66@C(->CC:AC: +@SRR800764.25122 25122/2 +AACGATTCGAACGATACCGACAAGCAACATACACGTCTGGATCCTACCGGTGTGGACGACGCCTACATTCCTCCGGAGCAGCCGGAAAAAAAGCACCAGCG ++ +?@@7DBD>CFFF@E+?:EB<@EG9)0:BG9*??3@(44:909@B529(8<@-003<>@######### +@SRR800764.25123 25123/2 +CTTGACTGACCGTGAATACTACTCCGCCTTCCACGACATCTGGAACTTCCATAAGACCGACATGAACAAGTACTTAGAAAAGCATCATACAGACGAGGTTT ++ +??@DDB,AD:;F@EECCH>??CA;C@A?FEC:8D6DCGBG>BB8=.8CH@CCG>E/C>;ACAA>?C9>53@CCDCCD######## +@SRR800764.25124 25124/2 +AGAAAAAAGTTAACTAAAAAGTAAGAACAGCAAAGTTGATTGTAGCCTATATTGCTGAAATAGATTTCGGAGCTCCCGTATAATATTAAAGTGCACCAAGA ++ +CCCFFFFFHHFHGJJJIIIJIAFHIHIJIGGIJJIGGIIIJJIIG@FCEDEGIIIHIIGGHJJJEEGIGGHHFDFFFC?ABDCDDCDA@CCCCCDDDDDDD +@SRR800764.25125 25125/2 +AGTGTGCAGATAACTATGAGAAAATTCTAATTAAAGGATTTGCCGGTAGAGATTCTGTGAAACTACCGATGTTTGATCTGTTTCTGCTTGGCTGCGCTCCT ++ +?@?DDDDEFH?FAHGHJJJJJJJJJJJJEIJJIGIJJFGHIIJIGIFHGIHG@GHIJIGGIIGCHGGIJHHE7?C>DFEE;ACEECCDCCDD@BDDBDDDC +@SRR800764.25126 25126/2 +CCCGCTTCAGCTTGATTCCGTGCTTGCGCCTCCTGTGATTCTAAGAGTGCAATTCTCAACTGAATGTCGTTTTCTTCATCGGTGTCGCCTGAAAGTTCAAG ++ +@?@BDDDDHFHHFIIJEBH;C@FAHEIGEHIEFB*0?(:@::> +@SRR800764.25127 25127/2 +GTGCTTCTCTCTGGTGGTTTTCTGTTTTTCTAATATTGATCGATTTTACGGTGAGTTAAACTACTTCCTTTTATCGCAATATCATATTTAGAGCGAGAAAG ++ +@?DDCDECCEDDCBACCBCBC@A +@SRR800764.25129 25129/2 +AACGAAGTCAGTACCTTTAGCAAATTGTGGCTTGTTTGGAGATAAGTCTAAAAGAGAGACAGATGCAAAAGTACACGGGTCTAAGTTAGGGGACAATTGGA ++ +?@@BAB;D>AB@:5>;;5(>CD5>?>(5>ACD@AA:@AC +@SRR800764.25131 25131/2 +GAAAAGTCCAAGAACAAATAACGAAGAAAGAAAACAAAGAAAGGCGATTAAGTAAAGTGCTAGTAGAGCAAGTACGAGAGAAGAGGAAGAGGCTTAGACAC ++ +BCCFFFDDHHHHHJJJJJ@HIIJJJIIIJIJIIJJJJIIIJIIIJGIHGGGH4@FHIDHEHIHHHHGHFFDD?CEDDBD??CDDDDBBDDDBB??CCDDD? +@SRR800764.25132 25132/2 +AAAGAGTGGATGTTGAAGAGTCAGGTCTTTTAGACTGTGTAAATTCAGCATTACTGTCTATCCAAAAATCCACACCATTTGTTTCTTCAATACGTTGTACG ++ +?B@DDFA?DHDFHIGGH@F3<GHIIGC7=CHAC@DCCCBBEDACC?=;>AA +@SRR800764.25133 25133/2 +ATGCATGTGCCGTGAAGCGGGACAACCAGAAAAGTCGTCTATAAATGCCGGCACGTGCGATCATCGTGGCGGGGATTTAAAAGTTCATATCACAAAATGTC ++ +@CC@FFDBFFHHFHHEGEIB<1CDGFFHDFHCGE?FE<;BFHGDAHCA@@:9B/9.=A@8ABBCA>5<;@BD############################# +@SRR800764.25134 25134/2 +TTCTGTTCTACAGCTTGAATACATGCCGTGGATCTGTTTATCAAAGATAATGTCATGTAGCGTGGCAAGTCGACACAGCAACGTGTGGATAATGGATGAGA ++ +@@@DFFFDHFHHHGHEBGGHJIG,::EF@CEE3CDGFHC>4BFHGII*?D5(5:A@>:AA +@SRR800764.25135 25135/2 +ATCTGAACTAACAAGTAAAATATCGATGTTAGAAATGGTTACAATAGAAGAAAGTAGTGTCATTCTTTCGCGTCAAAAAAAAAATGGAATTTGTGTCTTTT ++ +@@@DFDDD4CCDFGIGEIGFEC?@?F9D9D?EEHIEGEGDGG:CC4@FHGGIHJJJJIJFGFEGHGGGEFGIICAHGGHECCDFBDCCEEDE +@SRR800764.25144 25144/2 +GAACGCTTCATTTTAATCTCACGCATTTGCAACCCATGCTGATGTCTGAAGCGCTGACAAATACTTCATACGTTCTTCTTGTGACACATTAAGAGGTAGCA ++ +B@@FFDADHGGHHJIGIDHIJIJJGJJJJJJJJJIJJIIIGJJEEGIJE>FHIJJG@FHIHGHJGHHHGFFF@D@BCCEDECCD@AC?CDCACDDD::@CC +@SRR800764.25145 25145/2 +GATGAAAAAGGTGATTTGTCATTTACAAGAGGTAGGTCGAAACAGAACATGAAAGTTGGTCGGTAGGTGGCATGCAGAGGTAGTTTCAAGGTGACAGGTTA ++ +@B@B>CC(::ACCD### +@SRR800764.25146 25146/2 +AGTGTTGGAGTTGGTACTTTCAGTGGTAGTCGCACTAGTCCTGACGTTGATGCTGGCAGTGGTAGTAGCACTAGTCCTGGCGTTGGTGCTGGCAGTGGTAG ++ +?@@1BD??AD?FFEIG4C@EEIIGHDFHH>HGE?@FF@D??D<4D@B?G(>CG<3CC;<+CH9C:B@CC############## +@SRR800764.25150 25150/2 +GAGCACAGTTTTTGAAACTACAGACGTGCATCCATTCGTTAAAGAATGGCTCGCCGGCCGAAAGTTGCGAGAACGGACAACTTTCTTTGCAGTTCAGCAAT ++ +@@@FDFDDFFFHGGGCHGIIIJJIHIGHGGEGDHFIEHHEGIJIIJEBFEFHH:A +@SRR800764.25152 25152/2 +GGAGAACTCGACAAGGTTTCCCTCCAAACACTTAGTAAATGACATCAGTATTTTCTTCCCAAACGGGGAATGCAATAGGGCAAGATATTTGCCTCAAAATC ++ +@C@FFFDFHGHHHJJFEGIJJJJJJJGIIBHJJJJHDGFFHJGIJGIIFHHIIJIJJJIGJCHIIJIHFFFFDEEEEECBCD?@CCDDCCDDCDCDDDDDC +@SRR800764.25153 25153/2 +TATAATTTATATAAATATAAAAAAGTCTCCTTTTTTAATTTTAAGAATAAATAAAAATAATAATTAATCTAATAAAATATTTTTTTAAATATATTTATTTA ++ +?B@FFBDDHDHHFFB:<BDC@>@A@@C@CCCC +@SRR800764.25154 25154/2 +GTCCGTAGTGGATGAAATAACAGGCGCAAATTTATGGCGGCGGAATTTCTTTTCGAGGAGGTACGACTTCAATTCTGTCATTGAACAATATAGCATATTGG ++ +@?BDFBDDBDFHFGICGHIJIIGJIJJJIIIIIIJGJJGIA/=',8@C(5:@C>=2?@0+5(+:&+55<::@AC(:>@:4:@:(:>CC>A:@######### +@SRR800764.25155 25155/2 +ACGAAGAAAATCTAAAAAGAGTACTCTTTGGACATGAAACACAAAATTTTACGGAGGCTACACTAGAACCGGGTGAAATAATCATTAGGCTTTATCTGAGG ++ +??@D;ADBDHHHDFBACF?+3,<<+AA<<11H9::C91??D@GGHAG9BG49F?6'5-.=7.7)).?;76=A>B/;C:@35@################### +@SRR800764.25156 25156/2 +ACAACCTTCTTGGTAGTCTTAGCTTTCTTGTGGAAAACAGGCTTGGTTTGACCACCGAAACCAGATTGTTTACGGTCATAACGTCTCTTACCTTGGGCAAA ++ +@CCBDFFFHHHHHGHEIJJFEHJIIJIGIIHHIFGHIGIJJGIJFIBFG?AACHCGGABE@D;AEEC@;?DDCCD;=BD@>CBC?CDCDCDCCD<>BB?B1 +@SRR800764.25157 25157/2 +TAAACAACCATCAGCTTCAAAAAAACCAATAAATCATTCTAAAAATTCTTTAGATGGTAATTTATTATTAGGTTTAACTTTTTTAAATTCTTTATAAAATT ++ +@@@FDEFFHHHHHIIJIGCH@HGHEHIIIHGGEHGCCAIIHG9DHIIGHJGIIIIIIFCHJGIGIHCHFFFH;@DFFFEECC@??CCACCDEDCDC@>@C> +@SRR800764.25158 25158/2 +TTAGCGTTCGCATGTACACTGAATTGTCCCCTAATGGTTTTAACGTTCGAATGAATAGTTTCTAAAAATCTGTTATTATTGATATTGAAAGTATCAATTTC ++ +?B<=?:D?:@?CBA4ABDAFHC@HCECE9?DGBDHII?BDDE>?;7@BD@3@CCCDE:>C>>;;AC:C@CD +@SRR800764.25159 25159/2 +GGCTGACTGGAGCATTACTAGGTTCATTACTCACTGGTTCTACTCATGAAACCTTACTTATTTGACCTAAAGCTAAAAGACACAGAGAAGCTGGATTGGAA ++ +8=??D=DDD=+2E??DG@CFGIIJI1DFHCCBD4=BFCBCFHIGGF8@C@GE;==>?BEED<9;>>CCC@?@AB9?==BA?@BB03>CCCCDC>>:CC9BBBC +@SRR800764.25163 25163/2 +TCAGCATTAGAAGACCCAGCCACAAATGAAGGCGGTGTCGAGGCCGCCAGTGAAGAGAAGACAGGCCAAGGTAGCGGGGCTGGTTCCCTTCCATGGCAGGC ++ +=?+=1=D,C:C<+:2+<+<3 +@SRR800764.25165 25165/2 +GCAATTGAATCATTCACCTCATTAACCAAATGTGACCCCAAGGTATCCAGGAAGTACCTGCAGCGTAATCACTGGAACATCAATTACGCTCTCAATGATTT ++ +B8+ADDBD>D,+,2ABEEFF:AF4C@C:6-=/58?:(5>>ACF> +@SRR800764.25166 25166/2 +AAGCTTAATTGTATGAATATTTCTATGTTACCGGTTGAATAAACCTGGTCTCAAATAAAATTGGTAGAATGACCTAGAATGACCCATCCGCCGCGGAATCG ++ +=:BD?DEDBD<:DFFCHDGCHDECH>HD:CDBHE4C4?*:CG@F@CGA?4BF9DF:6BBHG4=CF@4C;.==@/459BB@;AC(5=>>@@((-:;5@>(5@ +@SRR800764.25169 25169/2 +ATGCATAGTCACGAATTTTCTTTGTGAGGAAATTGTTAGGGATTGGCGAGATTTCAAAATTTTTCTGAGCTTTAAGGATCCTTTCATAGTAAGAGACGTCT ++ +B@?;:B:B=2:D?C1C:AF@HIDD<;2<8+:;?B?*?*?DBGHH3)*?D'768@)BBHIJJECD=;?)==A>@)..;>C6;CEC35>CADACCCC?C?### +@SRR800764.25170 25170/2 +AAGATTTATTTGCTCCAAATGACAAAACAAAATCATTAATTAGAGAAATTTTATTATCCATCATCAATAGGAATATCACCAAAGGTGCGTCGATAGAGTAT ++ +=;?DDFFBHHHFDHIIJJB@BHGHBH;GGHG?E=@;BAC>?@@?AA@:> +@SRR800764.25171 25171/2 +AAAAAATTAATTCAACTCAAGAAATTAAAAAATGGAGGCACTAGAGGCAAGAAGGCTTAGTGAGTCCTTGCGGATTGCTGTGCTGCACTTAGGCTGTTGGA ++ +?B;A+)A<+2:C,C<<,A+A<3CG9+AH9EHI##################################################################### +@SRR800764.25172 25172/2 +AATCTTTATCATGAGTACCATGAACAAAGAAAGTCACCTATCAGTGGTTCTATCGTATATTGTTTCGGTGCCGTGGGGGGGACGGTTGGTATTTCCTTGGG ++ +CCCDFFFEHHHHHJIDGHHHIJJJIJIJJIJJIJIGIJJJJIIJIHIGGIHGIJIGGIHIIIFGGGGGFGGIHH6BEB:@B9>@B9@B><:>C@:ACDDA< +@SRR800764.25173 25173/2 +GATCAAAGGATAGACAATTTCAATACAGAGTTAAATATCGTCAGCCTAACAGTAAGGGCAGAAAATACTGTCACAGCTAAGCATCACAATGCGTTCCATGG ++ +##################################################################################################### +@SRR800764.25174 25174/2 +AAACGGTTGTTACAAGCAAGAAATGACAAGGCATCCTCAGTAATAACGGGGTTAGCCACATCTTTTACACTCGTGGCAATGACTCAGCCCATTGACGTCGG ++ +?1=DDDD+<;3)=;=)7=?7?B>>>>;..3/(;;>A:@>35A<@CCC@C5BAEGIICHCHGHGHGCCEHCB7<>A@AAC@CD@9@;>CDCCCCDACEA: +@SRR800764.25178 25178/2 +GAATCACCTGTGGGAGTGAACCTCAAAAAAAGAAAACACATATTTCATGCTGCATCATCCTTGCAACACAACGCTTCCTGCAGAAGTTTTCGAACAAAAGG ++ +@??BDB:BFFBFBGGB+2ADFEBFC?HF@GGHGIIEFIGGIEEGGJI=FGHCGIG>@;=3=>==7BD>?=?A>@B(,:@CCCDC>A(:AC>@######### +@SRR800764.25179 25179/2 +AACATTTATAAAACCGTTGACAAGATCGGTGTAAATAGAGTCGGTATTGCCGACACAGTTGGATGTGCCAACCCAAGACAAGTATATGAACTGATCAGAAC ++ +CCCFFFFFHHHHHJJIIIIIJJJJJJJJJEFFFIIIJHIJBGHIDFGIBGGHGGJHHHEECFDCFFCACCD?BBDDDBDDDBACDEEECDACDD@CDCDCD +@SRR800764.25180 25180/2 +AACGTAAGTCTGGATAGAATTGAAGACTGATACAATGGAAATGAAAAGTAACCATTTTGGTAAGTAACCTTTTGGCATTGCTGCCAAGGTGGTCTTGGTTG ++ +?@@DB>ADC,A@B376;.6;?;(;A>5@FGEHGIEEHEHADB@DFF:@>6@DE;@BACD??CCD@AD?',5>@3;5>ACDC# +@SRR800764.25183 25183/2 +ACTGCTACTTATGTCAAGGCAGTGGTCAGGGACATGAAGAAATACATCAAGGCTAGAAAATACAGACAAATTCCGGTAGGTTACTCGGCTGCTGATATCGC ++ +BCBFFFFFGAHHHHIIIJIIHIFGHCHHIIJIJJJIGIJJJJEIJJJIBHFGIIJIIJJJGGIIJJIJJGHCEE>A9BBC@>ACCC?BDDDDCDCCDEDB# +@SRR800764.25184 25184/2 +ATAGATGGAACTTACAAGTATGGAGCTTTGGATGACTTTATCAATTCATTCACAGATTCTGCATCTGCAGGAAAGTATGCTGTAAAAATAATCATCTTTTT ++ +@CCFDFFFHDFD:CDGIAACIEIJFJADCHGIEFEGCBBHHGE@G@HHEHHIGHH;4BBGI>HGIIA)7=DG@EH;==);@>:3;AC>@;>CD +@SRR800764.25185 25185/2 +GTCAGTGGCAAGTTTGATATAATCCAGATCTCTAAGGGGTAGTGCGCTGATTTCGACCATAGATGAAGACGTAGAGCTACTCAAACCAAATGACGAATTAT ++ +@=?BDDDEFD>D2A:CBD4?EDAF<@@H;CAC@A@?BDC:@:?2928@: +@SRR800764.25186 25186/2 +TAGGAAACAACAAATTCCGATGCTTACTTACCCCTTAAATTTTCTCATTGCTCTTCATTGAGGTTGCATAGCTCACCATATTTGTCATGGAAGGTCCCTTA ++ +CCCFFFFFHHHHHJJJJJJJIJJJJJJJJJJJJJJFJJJJJJJJIJJIJJHIJIJJJIJJGJJFHIJGJJJJJHHHHHFDFEFFCEEF@CCEDDACDBDCC +@SRR800764.25187 25187/2 +AGATTACGTTGGCCGAATTGGTTCAAGAATCGATTTTACAACTGTCTGTTTTGAAGACCATTATATTGAGTTTTCCCTTCGAATTGACCATTTCGAAGATT ++ +B@B+AB8DHB;+??9:CFHGDBFF1+A3FEF4?E9EFGIEGI*)?C6DD)??@AFHB@CB:',.;7.;(;@C>3@@:;AB=@8=C>>A@C>:>>@C############ +@SRR800764.25189 25189/2 +CTCTTCAAAGGAGAACAGGCCATACCTTTTGGAATCTCCTTCAGGACTCTTTTCATGTTCACTAGTCAGGTTTTCTCGGACATTCTGCTCGTTAAGATTAT ++ +@@CDFFFFHHHHGJJFIIIJIJJJIJJIJJJICEGJJIJJJIIIICHEIJHHIGIIE@HGEHGIJIIIFG7CGHHHHHBBDBECCEDCDCD@B@?CCCDDD +@SRR800764.25190 25190/2 +GATATAAATAGTTGCAAACTAAAGTAAGATAACTGAAGATGATTAGTCCTGTTTGCATACATAGTTCTGTTCTTGTTCTACGCTGATGCGATCAATAAAGT ++ +@@CFFFDDFFHHHJIIFGIJJJIIHJJIJIJIIHIJJGHIJIJJGI>FGGFHGIIGHGIIGIGIBFIDIGEHGIIGHCHIDGGHHGGFFEC;ABACDDDC; +@SRR800764.25191 25191/2 +TTATAATAGGTTCCTTTTAGATGATCTCCTAATCAACATCCGTTTAACTGATATGATTATTAACGGAAACAATGAATGCATAGAATATGAGAAAGGACATG ++ +CCCFFFFFHHHHHJJJJIJJJIJIJJJJIJJJJGIJIFIJJIDHIGIIJFIJIJIJIJJIIJJJIIJJJIEEGHHHHHHHHFEFFFFEEEEEEEDBDDDD> +@SRR800764.25192 25192/2 +GGAAGAGAATCAAACCAAAGTTCCCAAGAATCACGAAACGAAATTACGAATTGGATGCAAATTGTGTGAAATGGAGTTTTGACACATGATATTGAGTCTCC ++ ++1?7:BDDDC;C################################################################# +@SRR800764.25194 25194/2 +AAACCCGCTCAAACCAAGGCATATAGAGGAAGCCTGGAGAGTACTACAAACAATTGACATGAGGCATAGGGCTTTGACCAACTTTAAAGGTGGTAGACTCA ++ +@@CFFDFFFHHHHJJJJJIIGIIIIIGIJJJIJJIJJJJJGBFEDCGCGG4@@@)7=CC@EHHC>AC@?B;@6>53@=A@A#### +@SRR800764.25197 25197/2 +TGGAATCTAAATTTGCATGATTCAGTTGTTCCCTAGGTGACATTTTATTGAGGATTCCTCTATATGATATAGTGTTCGCTACTTTACTATTTGGGGTCGTT ++ +CCCFFFFFHHHHHIJIJJJHIGGIIHJJGIJIJJJII?EHHIJJJJJJIJJJJJIJIJJJIIIIIJJIJJJJIHHIJIJJJHHHGHFDFFFFFECD8?BD? +@SRR800764.25198 25198/2 +GGCTACGCAATCTGTGTGTTCGTCGCAAAACACAGCGACCACTGACGGTGTACGAAATCAATTTCAGAGTAATGGTTGGTGTTCAAATAACTGTGCTGGTC ++ +@??DFBDDFFC:@>;@;:@5::;>:++2<++(+>C3:A@344>@CCC#### +@SRR800764.25199 25199/2 +CTCTGTTCGTCAGATAAATCACCTGCGTTCAAGAAATAATCCCATCTATGATTCCAGACTACTTCAAATTCTTCTCTCCAATATACGGAGTAAGTAAATGG ++ +:1+442A,2C1C?+CFH+A..=)B=))..)...7)7@D@D;6(;8(--(-5>CDCC +@SRR800764.25200 25200/2 +TCCACCCGTTCAAGTCTTCAAATAAACCTTGAAAATTCTATAGTAATTATTGATGAGGCTCATAATTTGATAGAAACAATAAATTCTATATATTCCTCTCA ++ +CCCFFFFFHHHHHIGEIJJJJJIGIJHIJJIIGJJJIGIJCFIDGIIIJAGHIIGIIIFIJIJJI>GIIIIIGIJJJJJHHHHHBDDFFFFFDF@CEEEDD +@SRR800764.25201 25201/2 +AAGAAAATATAGAACTTCAATGGCAGCACTTGAAAAAGAAATTAAATGAATTGTATTCTAGGTTTAACTTCCACCGAGATCAATTATCCTTTCAAGTTAAC ++ +CCCFFFFFHHHHGJJJJJJJJJJJJJJIJIIJIIJJJJJJJJJIJJJJJIJJJGIJIJJJJJBGHJJJJJIJJJIIHHFFFFCEEEEEEEDDDDDDCCED@ +@SRR800764.25202 25202/2 +TCTAGTCCGGAAGAAATCTGCAAATTATTGTCTTCATTCAAAAAAGTTTCCTTGGTATCCAAATTAGAGACAAACAATGAGCTAGAGGGATTATCGGATGA ++ +@@FHFHIHGJJGGIGGIIJIJGEEGGFIIJEGIJIIE/?DDGGHHICB@FGGCHIJJFJJHHGFHFFDECCACEEECCBDDDCDCDD=BB>> +@SRR800764.25203 25203/2 +TCTATACTTGCAGGCACCTTCAAGTTCTGATCAGTGTCCATCTCTTCATTTTCCAAAGCAGCGTCGTCTGGCTCTTCAGTTATGGCGCCATTATCATCAAA ++ +BCCFFFFFGDGGHIIHGCGGGIIBB>CHHEBCC@CB;>;;?CA;ADEDDD> +@SRR800764.25204 25204/2 +CACAGATTCAATGACTTGGGAGTGTACTTTCAGTTTAGGCCCATTCGCTATTCAACATGTTTGGTGGCTCGCTAAAGGGTCCCTGCTCGTCACCATATTCA ++ +BB??4BB4?:DDFADD<=)=)B=4CF;EEE3?6?(?@7>C@>>6;(;>A;-5555;?BB? +@SRR800764.25206 25206/2 +AAAACACCATACAAGTACGTCGATATGGCAAAAGAGTATAACTACATTTCTCCCTTCATAATGTGCCTTTCAGAGCAATGGAAATACGTTGACAAGAGTGG ++ +@B@FFFDFFHGHFIECFGIDHIIBEGGGGIHGIGII:B9FHIDHIFIIIGAFHDIGIIJCGIIGEHGIIHHHHGHFFFEFCCEECEDD@ABDCCDDCB>@? +@SRR800764.25207 25207/2 +ATATACTTATTAAATTAATATAAATAAATGAATAATATAATATAACTATATTGAATTATAATCTATCTATCTTTTTTTTCCATATAATATTAAATAATAAT ++ +@B?:A=DDB<4CFHIGH?BFCB8=@FGGJIGGEGGDG:CDDEEHFCC@BDFFF:>ACCCC;; +@SRR800764.25209 25209/2 +CGTTCTTCTCAGCACGCTTTTGCATAATGGTAGAAGCACGCAAATGGTCTTTTCTGACAAGCATAAACACTTTTGAGCCGTACTTGGTCAAGAACTGAGCT ++ +CC@FFFFDHHHGHIJIJJJJJIGIJJJIJJFGHCGHIJIIJIIGHGI8BFFGGHHGAFHJI9@EEHEHFEEFDFDE?@CD;@B=ACCCDCCD@?CACACDD +@SRR800764.25210 25210/2 +TAATGCAGAGTACACCTTGAAGAGAGAGAAAAGAAAATCTTTGAATCCATAGCATAATAGCGATCAACGAAACTTTTTAAGAAGTAAAATGAACTGAAAGG ++ +@CCFFFFFHHCFHGIJJJJJJIIJJJIJJIJIJIJJJHIJEIJJJJJJJIGIHIIJJJJJIJJJJJJJHHHHFFFEEDDCEEDDDDDDDECDDDDDDDDD? +@SRR800764.25211 25211/2 +CTTTGCTCTGCTGGTTTCCGATCACTCTATGGCCTTGAGTATCTATTTCTTTGAAACGATCCCTGGATAACGCATTTTTAGAGAGATCTGTTAGTAATGAC ++ +?@?DDADDFHHFHIFGHIIIGGIICHIJJGDGIIJIFGGDBGFIIIJJICGFFHGI@FHGGGGGHIBHIFGFGF?ACCEBCDDDDDCC@@5>CACDDCA:@ +@SRR800764.25212 25212/2 +AGAAAATGAGATAGAAAATGAAACAGTAAACAAAACAGAAGACAAGGCTGAAAAAGGAAAAGAGGAAGAAGTAAATACCAAAGATAACAAGGAAGAAAAAG ++ +@@@FDDDD?FFD?GHIEHEIJIJGHHCCDDDC?(59AC??B# +@SRR800764.25213 25213/2 +CAGGTGAGTTCATTCATACTTTGGGGGATGCACATGTTTATAAAGACCACATTGATGCCTTGAAAGAACAAATCACCAGAAATCCAAGACCATTCCCGAAA ++ +BB@DBDDEDDFHFIGBHGHFJHBF@D8AHIEGHIEGD<9BDGCHF@FF@FBBGGGIGGCAHGGIGIHHH@DBCEDAED?ACCCACCCABCDCD>@B>?BB3 +@SRR800764.25214 25214/2 +AATACCTGAACTCATGGCCAATCCACCTACCAGAAGGCCTGATAACGCAAATCACGATAACAATGAAATAAGCAATAAAAAACTTGAATATGGATACCCCA ++ +CCCFFDFFHHHGHIIJJIJJJIJJJJJJIJIJJIJJIIJIIGJJJGIJGGGEGIIGHGJIHEEHHHHFFFFFFEEEDEEDDDDDDDDDCEADCCCDCCD@7 +@SRR800764.25215 25215/2 +TTCATTATCAGGTGACGAAGCGGCTCACAAATTGCTAAAATTAAAGATTGCGAACAATTTGAAAAAAAGCGTGGTAGATATAATCATCAAATCTAGTTTGC ++ +@@CFFFFFHHHHFHEGGGJDFHAGEGIIJIGIGJG@FEGICDACDDDCCDC@CCAC::4@:@C +@SRR800764.25216 25216/2 +TTAAGCGGTATTCTAAAGGCTCCGCGAGCGAGCCTCTTTAACCTAATGCAAAAAAAAATTGTTACGCACGTTCCCGGCTTTTACCGTAATAGTAGTCAAGA ++ +@@CFFFFF@FHHHJJJJJJGJJJJJJJJJGIIDIEIJJIJEGHFGHHEFFCFFFDDDDDCCDDDDDDDDDBDDDDBDBDDDDDDDD@BDDDD@DDBDDD>3 +@SRR800764.25217 25217/2 +TAATAAAATGAACTATTTATTACCATTAATAATTGGAGCTACAGATACAGCATTTCCAAGAATTAATAACATTGCTTTTTGAGTATTACCTATGGGGTTAG ++ +@@@FFFDDFGHHGHGBEBCHJIHJJ>HIGIHGDFCEFDCEGEAHDHH?DHFDCGGFEDHGGIJJGGHDGFHEHIHHGCHIGCE=?EHFCFBDEA@A##### +@SRR800764.25218 25218/2 +TTAGACGTGTTCCTAAAACTTTTGACGTTTTTTGGCGGGTAATAAGATGCGTCTACCCATTTTAAGGAACGCCCTCGTAACAGACAGAACGAAGAGTGGCA ++ +@@@DDDFDFFHHHGIGIJJJGIGIJIIIGGDE@@DBHHH4=A@@A@C@C>??@@?C:9::CCC@C>>AAA;;>B>B928FEEIEACHBI:>(5;28-)0&&&89BD(3:???BBC######## +@SRR800764.25222 25222/2 +ATTGCCAGAAAACGACTGTCTTTACGCCATTTACGATTTTGAATACGTAATTAATGGTAATGAAGGTAAGAGATCCAAGATTGTTTTCTTCACTTGGTCTC ++ +;?BF;;4BHB?AD:@?C:CFBCA77=BC;@@@:(6;A3;@->;?>555@>CA55>:@C +@SRR800764.25223 25223/2 +TTTGAATCACTGCAGAAATATGCACTGCGCCTTCTTTTTCTTTGCCTGAAGCACCCACACACAAGAACAGGAATGTGAATGGGCTCCCCATATCACTTTTA ++ +=?;;4+,=:=CF:+3+A+33A:,9*?38((-5((--;D3?=AD(6?C########################### +@SRR800764.25224 25224/2 +CTCAGTGCTTCTTTGAATTCTTCCTTTTTAGTCTGCCTGCCCTCTCCTAACCTTTTAGAGCTTGTCAACAAACTTGTATCTATCTTATAATCTTGAAGTTT ++ +CCCFFFFFHHHHGJJIIIJJJIIJJJIJJJJIJJJIJJJIJJJIJJIGIIHIIIJJHIIIIIJICHHIJEJJIIIJFFGHGHFHFFFFFFDEECC>@C@CA +@SRR800764.25225 25225/2 +AAACCAAAAGACTAACCAGGAAAGTTAATCAGAGGATGACTGTTTTTGTGGTGGGGGGGCGAGGATGTCAGATTCTGCTGACTTCGCAGCGGTAGATGACT ++ +:;?+4A;DDBCFHGIGHBB@+CC:ACAC@::449>C:8099&)055<44:>@@ +@SRR800764.25226 25226/2 +TATACTTAGCAATTTCATGTTTAGTCCCGGCCCCAGTCGGGACCCCGAAAAGGAGAACAATTAAAATGTAAACTAGCAGGTACATATCCTGTAAATGTTAT ++ +@C@FFFFFFHFH?CEFHEB?ABFGHEEE@::CFHHEHAFEBD@@CGGGAABEE;BB2ACCCC@CAADDCC@CCC@@CAC?(:(::4((4@@C34:>C>ADD +@SRR800764.25227 25227/2 +TAATAAAGGTCTAATAAGTATTATGTGAAAAAAATGTAAGAAAATAGGATAACAAATTCTAAGACTAAATACTATTAATAAGTATAGTAAGTACCGTAAGG ++ +@@@DD?DDHFHFHIIGGG@JJHIIIIIBFCHIAGCCDHIGEIH9FGHG4?DGGIE@=FCGFGHHEGI@GHIGHHHH>CE?BCDFDFF@CCCEECED@DDDC +@SRR800764.25228 25228/2 +TAAAGGCCACCATCGGAGAGGGTTTAGATATTAATGTAAAAGGCACGCTAAACCGCAGGGGAAAGGGTATCAGAAGGCCTAAAGGCGTATTTTTTAGATAC ++ +;;?D?BD?DDDHDGBB?'<557@E;=HFB8/''55;?,5::;55>((2<>>4>@@<9)0?>:>AB??4>C# +@SRR800764.25229 25229/2 +CAGAACGTCTAAGGGCATCACAGACCTGTTATTGCCTCAAACTTCCATCGGCTTGGAAACGATAGTCCCTCTAAGCAGTGGGTAAACAGGACATGATAACA ++ +@@@DDDDDFCB?FGG=DGFHICDE@HC444FECID8EBGG:)=FHG@GGGCEAD?AHHAHHC +@SRR800764.25231 25231/2 +CAGAATAGAAAAATAGATCGCCGACAATCGAGGGGTCTTAATTGATGGGGACATCGTTGGAGCTTATATAAGTTTGTCGCTACTTGGCGAAGATGGTTGAG ++ +;18=B;BDDAFD8AC:((,9>75AC################ +@SRR800764.25232 25232/2 +AAAGCACGCATAAATTTGGCTAAATGCATTTGCCTTGCGCTTAGTTCACCACGACCAGAAAAATCCGTACGGTATAGAGCCATAACAGAATCGACCACAAT ++ +@@@DFFDADAFHAEHHEHGGCEGGGEGBFHIJIIIJJIIJJIGGBFFIJIGGGEGHGHEFHFED:BCBECDD5=BDDDA>AACCCCDDDACDD?BB>DBBC +@SRR800764.25233 25233/2 +CAAAATTTCGAACAACCTAGCCCTCGTTTTCGCCGCATTGGAACACTTGAAGAATCTAAGCTTATTAGCTGAAGAAGTTGTAGATAAAATTGTTAATAAAT ++ +@@@DDFDFBFBHFGJHGGIIEIB;EADBHCFA:DFGH@FG3C4)=.77;77BCEC).)7));@DE@;3(..>C>@>(53555:;>C@(:;5>34:>@C@## +@SRR800764.25234 25234/2 +TAATACATATAATTCCATTTGTATCCATAATTCTCTTCATGTTGAGATATATATCTTGAGGGGTATTCGTATCGCTTGTATACAATGATAATCGAGGTAAA ++ +B@@B==ABFFHHFIJIGIJIIJIJJIIJIJJIIJIHHIIIJIIIJIGEHIIHAFGAFFGGIGIEFHH)=FHGGC@C@CHFEHAE>DFF>C@ACCA@BDCCC +@SRR800764.25235 25235/2 +TATATATATAAATATAAATATAAAATATACTTTTTATAATATAATATAATCTTTTATATTTATTAAAATATATATTAATTATATTATAAATCTTATTTAAT ++ +CCCFFFFFHHHHHIJJJIJJJJJJJIJJJJJJJJJJJJJJJJIJJJJJJJJJJJJJJIJJJJJJJJIIIJIIJJJIJJJJIJGJJJEIJJJIJJJJJJHHE +@SRR800764.25236 25236/2 +TTCGGGGTTCCGGCTCCCGTGGCCGGGCCCCGGAACTATTAATAATAAATAATATAATAAGTTTATAAATAATAAATATATAGTCTAAACCTCTTTTTTAT ++ +@CCFFFFAHHFHHGGGIJI;AHIJIGEGAGIIG=BFDCCCEEECDDDCDD>CDDEEEEDC>5@CDDDCDCDCEC:@CCCDEDD3>CACC>?9<:<4C:3I:F?FH+???F1B909:90990*00*9/?E?C:?6@AEE:AC: +@SRR800764.25238 25238/2 +CAGAAGCTTTCTAAATTAAGGGTTTTAGAGATATTATCCGGTCATGACATGATCAAGGAACAATACGGAGTACCATTGCTTGATAAAGATGGCAATTCACC ++ +?@@D?DDFHHHHDHIHGEHIII+ACGDHIGIIJIDHIIIEGGGGHCDBGHFEHEIGIJGIIGIGGIJJIHHHFEFFFFDEEE<@@;@@CDCC9>CCCDCC@ +@SRR800764.25239 25239/2 +GGAAGAACCTAAGGTTATATGTGACCTGATATCACCAGCTGCATTTTGTCTCTTAGAGCTCGAGCGTAGTTTTGATTGCAGTTTGTCGGTACTCAAACCGC ++ +B@CFFFFFHFHHHJHIJIJJIHHIJJJIGIJIIJJJIJJJGIJJJIHIIJ>FHIIJIJIIJJGIJIEHHCHFFFFFEEDCEEEEDDDDC?BDCCCCDA@BD +@SRR800764.25240 25240/2 +AAAAGGCTACAATCCTCGCATGAAACTAATAAAAACGAGCACAATATAAGCCGAGACGTAGCGTTTAACGTACTAACACTACTCGCCAAACCATAAGAGCT ++ ++11BD2+2=DH;?BBDCDC@CADDDBACBBDC>>@ +@SRR800764.25242 25242/2 +TACCTCAGAAAATACTGTTGAATTCTTTCAAGGGGTAGCAAAACTGTCCAGAGCTTATATCTACCTGTGCTCAAAATACAGTTGAAACCACCTCTTCCTAC ++ +@@@FFFDEHHHHGIIJGHGIJJJJJIIIEGHHIIJCFGIJGIIIIIIIIIGIIBHEGHGCGGHGIIGGIJJIGGIHFHEHFDDFCEDDCCCCDDCDDCD@A +@SRR800764.25243 25243/2 +TCCCGTGGTCAATGAAATCAAAGAAGGTACTGCAAACCATGCTAACCCACCGATGGCATATGCTTTCAAACTCGCTGCGGGACTAGCAGAAATCGCTTTAT ++ +:+=1+=D:FB?F8D9DGI@HAH>BGHIB@C8CHCHCGH?H;)7?C7;7?9=@>>(5;5>8ACC###### +@SRR800764.25246 25246/2 +TCGATTTTCACTTTAAAAAACCAGTAATTACAGTAAGAAGCAACAGTGAATTTCATTTGGACTGCCAACTTAATATATGTACTAAAATCGTCCATCATTTG ++ +?@@+B,AD8F?DA>EEBDFGEH+31:9:4?99?DGG>FHHAB*?B)=D=@@=D4.7?ACEEE?BBD>?7@C@?########### +@SRR800764.25247 25247/2 +TTGCATTTAGGCCATGAGCTTTTCTGGAAGAGGCTGAAGACCCCTTCAACACATCCTGCTGATCACTTTTACGCATTTCCCTCAAAGCTCTATTGCGCATT ++ +@@@DBFDFHHHDFGB??CHGIJJGIIFEGGIJJBHIHHGIGIJIGIGCACD########## +@SRR800764.25248 25248/2 +CAATCTATTGAAATACTTTAAGGATATATCATAATTAATGATCTCAAAATGAAGTTTTCCTAATTGCACTAGACACCATGGCATTGTGTCTTTAATATGAG ++ +CCCFFFFFHHHHHJIJJJJIHIJJIJJJJJJIJJIJJJJJJJJJJJJJJJHJJIFHHIJJJGIJJIJJJJJIIJIJJJIIIJIJHEEHHFFFFFFDCDEDE +@SRR800764.25249 25249/2 +ATTTAATAAATAATTTTTAATAAATATTGGTATATTATCAATAGGTTTTCAATTATTTAAAATATAATCTTTAATAGCTTCTAATGTTTTTTTTTTTATTT ++ +@@@DFDBDHBDHFGIIIGDFHGGHEJIGFGIJG@HBHGGEEFIGGIGIG>@DFGD@DGIEIIEHGGBC++++3AF<+AFII9***1?**:)))?*?4***9*(0??*9B8))8)/@78C;==7=7)=EEH######################## diff --git a/latch_cli/services/init/new_example_snakemake/environment.yaml b/latch_cli/services/init/new_example_snakemake/environment.yaml new file mode 100644 index 00000000..732aa896 --- /dev/null +++ b/latch_cli/services/init/new_example_snakemake/environment.yaml @@ -0,0 +1,13 @@ +channels: + - bioconda + - conda-forge +dependencies: + - snakemake-minimal >=7.3 + - jinja2 + - matplotlib + - graphviz + - bcftools =1.15 + - samtools =1.15 + - bwa =0.7.17 + - pysam =0.19 + - pygments diff --git a/latch_cli/services/init/new_example_snakemake/scripts/plot-quals.py b/latch_cli/services/init/new_example_snakemake/scripts/plot-quals.py new file mode 100644 index 00000000..345189e0 --- /dev/null +++ b/latch_cli/services/init/new_example_snakemake/scripts/plot-quals.py @@ -0,0 +1,9 @@ +import matplotlib +matplotlib.use("Agg") +import matplotlib.pyplot as plt +from pysam import VariantFile + +quals = [record.qual for record in VariantFile(snakemake.input[0])] +plt.hist(quals) + +plt.savefig(snakemake.output[0]) diff --git a/latch_cli/services/init/new_example_snakemake/version b/latch_cli/services/init/new_example_snakemake/version new file mode 100644 index 00000000..77d6f4ca --- /dev/null +++ b/latch_cli/services/init/new_example_snakemake/version @@ -0,0 +1 @@ +0.0.0 From ea5f0c892f3b4ec48d90736731412f991f334f15 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Mon, 18 Sep 2023 19:56:22 -0700 Subject: [PATCH 246/356] rename example files --- .../.latch/latch_entrypoint | 0 .../Dockerfile | 0 .../Snakefile | 0 .../config.yaml | 0 .../data/genome.fa | 0 .../data/genome.fa.amb | 0 .../data/genome.fa.ann | 0 .../data/genome.fa.bwt | Bin .../data/genome.fa.fai | 0 .../data/genome.fa.pac | Bin .../data/genome.fa.sa | Bin .../data/samples/A.fastq | 0 .../data/samples/B.fastq | 0 .../data/samples/C.fastq | 0 .../environment.yaml | 0 .../scripts/plot-quals.py | 0 .../version | 0 .../.latch/latch_entrypoint.py | 85 - .../docker-build-logs.txt | 743 ----- .../docker-build-logs.txt | 514 ---- .../docker-build-logs.txt | 757 ----- .../docker-build-logs.txt | 100 - .../docker-build-logs.txt | 65 - .../docker-build-logs.txt | 100 - .../docker-build-logs.txt | 100 - .../docker-build-logs.txt | 98 - .../docker-build-logs.txt | 2627 ----------------- .../docker-build-logs.txt | 100 - .../docker-build-logs.txt | 105 - .../docker-build-logs.txt | 2083 ------------- .../docker-build-logs.txt | 1541 ---------- .../docker-build-logs.txt | 61 - 32 files changed, 9079 deletions(-) rename latch_cli/services/init/{new_example_snakemake => example_snakemake}/.latch/latch_entrypoint (100%) rename latch_cli/services/init/{new_example_snakemake => example_snakemake}/Dockerfile (100%) rename latch_cli/services/init/{new_example_snakemake => example_snakemake}/Snakefile (100%) rename latch_cli/services/init/{new_example_snakemake => example_snakemake}/config.yaml (100%) rename latch_cli/services/init/{new_example_snakemake => example_snakemake}/data/genome.fa (100%) rename latch_cli/services/init/{new_example_snakemake => example_snakemake}/data/genome.fa.amb (100%) rename latch_cli/services/init/{new_example_snakemake => example_snakemake}/data/genome.fa.ann (100%) rename latch_cli/services/init/{new_example_snakemake => example_snakemake}/data/genome.fa.bwt (100%) rename latch_cli/services/init/{new_example_snakemake => example_snakemake}/data/genome.fa.fai (100%) rename latch_cli/services/init/{new_example_snakemake => example_snakemake}/data/genome.fa.pac (100%) rename latch_cli/services/init/{new_example_snakemake => example_snakemake}/data/genome.fa.sa (100%) rename latch_cli/services/init/{new_example_snakemake => example_snakemake}/data/samples/A.fastq (100%) rename latch_cli/services/init/{new_example_snakemake => example_snakemake}/data/samples/B.fastq (100%) rename latch_cli/services/init/{new_example_snakemake => example_snakemake}/data/samples/C.fastq (100%) rename latch_cli/services/init/{new_example_snakemake => example_snakemake}/environment.yaml (100%) rename latch_cli/services/init/{new_example_snakemake => example_snakemake}/scripts/plot-quals.py (100%) rename latch_cli/services/init/{new_example_snakemake => example_snakemake}/version (100%) delete mode 100644 latch_cli/services/init/new_example_snakemake/.latch/latch_entrypoint.py delete mode 100644 latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-1d8b2c/docker-build-logs.txt delete mode 100644 latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-2dd65d/docker-build-logs.txt delete mode 100644 latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-46aaed/docker-build-logs.txt delete mode 100644 latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-56df45/docker-build-logs.txt delete mode 100644 latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-62524a/docker-build-logs.txt delete mode 100644 latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-6975e7/docker-build-logs.txt delete mode 100644 latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-87b6a8/docker-build-logs.txt delete mode 100644 latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-89875a/docker-build-logs.txt delete mode 100644 latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-a00131/docker-build-logs.txt delete mode 100644 latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-a98450/docker-build-logs.txt delete mode 100644 latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-b1b9b5/docker-build-logs.txt delete mode 100644 latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-cdb14b/docker-build-logs.txt delete mode 100644 latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-cddce8/docker-build-logs.txt delete mode 100644 latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-dc4ace/docker-build-logs.txt diff --git a/latch_cli/services/init/new_example_snakemake/.latch/latch_entrypoint b/latch_cli/services/init/example_snakemake/.latch/latch_entrypoint similarity index 100% rename from latch_cli/services/init/new_example_snakemake/.latch/latch_entrypoint rename to latch_cli/services/init/example_snakemake/.latch/latch_entrypoint diff --git a/latch_cli/services/init/new_example_snakemake/Dockerfile b/latch_cli/services/init/example_snakemake/Dockerfile similarity index 100% rename from latch_cli/services/init/new_example_snakemake/Dockerfile rename to latch_cli/services/init/example_snakemake/Dockerfile diff --git a/latch_cli/services/init/new_example_snakemake/Snakefile b/latch_cli/services/init/example_snakemake/Snakefile similarity index 100% rename from latch_cli/services/init/new_example_snakemake/Snakefile rename to latch_cli/services/init/example_snakemake/Snakefile diff --git a/latch_cli/services/init/new_example_snakemake/config.yaml b/latch_cli/services/init/example_snakemake/config.yaml similarity index 100% rename from latch_cli/services/init/new_example_snakemake/config.yaml rename to latch_cli/services/init/example_snakemake/config.yaml diff --git a/latch_cli/services/init/new_example_snakemake/data/genome.fa b/latch_cli/services/init/example_snakemake/data/genome.fa similarity index 100% rename from latch_cli/services/init/new_example_snakemake/data/genome.fa rename to latch_cli/services/init/example_snakemake/data/genome.fa diff --git a/latch_cli/services/init/new_example_snakemake/data/genome.fa.amb b/latch_cli/services/init/example_snakemake/data/genome.fa.amb similarity index 100% rename from latch_cli/services/init/new_example_snakemake/data/genome.fa.amb rename to latch_cli/services/init/example_snakemake/data/genome.fa.amb diff --git a/latch_cli/services/init/new_example_snakemake/data/genome.fa.ann b/latch_cli/services/init/example_snakemake/data/genome.fa.ann similarity index 100% rename from latch_cli/services/init/new_example_snakemake/data/genome.fa.ann rename to latch_cli/services/init/example_snakemake/data/genome.fa.ann diff --git a/latch_cli/services/init/new_example_snakemake/data/genome.fa.bwt b/latch_cli/services/init/example_snakemake/data/genome.fa.bwt similarity index 100% rename from latch_cli/services/init/new_example_snakemake/data/genome.fa.bwt rename to latch_cli/services/init/example_snakemake/data/genome.fa.bwt diff --git a/latch_cli/services/init/new_example_snakemake/data/genome.fa.fai b/latch_cli/services/init/example_snakemake/data/genome.fa.fai similarity index 100% rename from latch_cli/services/init/new_example_snakemake/data/genome.fa.fai rename to latch_cli/services/init/example_snakemake/data/genome.fa.fai diff --git a/latch_cli/services/init/new_example_snakemake/data/genome.fa.pac b/latch_cli/services/init/example_snakemake/data/genome.fa.pac similarity index 100% rename from latch_cli/services/init/new_example_snakemake/data/genome.fa.pac rename to latch_cli/services/init/example_snakemake/data/genome.fa.pac diff --git a/latch_cli/services/init/new_example_snakemake/data/genome.fa.sa b/latch_cli/services/init/example_snakemake/data/genome.fa.sa similarity index 100% rename from latch_cli/services/init/new_example_snakemake/data/genome.fa.sa rename to latch_cli/services/init/example_snakemake/data/genome.fa.sa diff --git a/latch_cli/services/init/new_example_snakemake/data/samples/A.fastq b/latch_cli/services/init/example_snakemake/data/samples/A.fastq similarity index 100% rename from latch_cli/services/init/new_example_snakemake/data/samples/A.fastq rename to latch_cli/services/init/example_snakemake/data/samples/A.fastq diff --git a/latch_cli/services/init/new_example_snakemake/data/samples/B.fastq b/latch_cli/services/init/example_snakemake/data/samples/B.fastq similarity index 100% rename from latch_cli/services/init/new_example_snakemake/data/samples/B.fastq rename to latch_cli/services/init/example_snakemake/data/samples/B.fastq diff --git a/latch_cli/services/init/new_example_snakemake/data/samples/C.fastq b/latch_cli/services/init/example_snakemake/data/samples/C.fastq similarity index 100% rename from latch_cli/services/init/new_example_snakemake/data/samples/C.fastq rename to latch_cli/services/init/example_snakemake/data/samples/C.fastq diff --git a/latch_cli/services/init/new_example_snakemake/environment.yaml b/latch_cli/services/init/example_snakemake/environment.yaml similarity index 100% rename from latch_cli/services/init/new_example_snakemake/environment.yaml rename to latch_cli/services/init/example_snakemake/environment.yaml diff --git a/latch_cli/services/init/new_example_snakemake/scripts/plot-quals.py b/latch_cli/services/init/example_snakemake/scripts/plot-quals.py similarity index 100% rename from latch_cli/services/init/new_example_snakemake/scripts/plot-quals.py rename to latch_cli/services/init/example_snakemake/scripts/plot-quals.py diff --git a/latch_cli/services/init/new_example_snakemake/version b/latch_cli/services/init/example_snakemake/version similarity index 100% rename from latch_cli/services/init/new_example_snakemake/version rename to latch_cli/services/init/example_snakemake/version diff --git a/latch_cli/services/init/new_example_snakemake/.latch/latch_entrypoint.py b/latch_cli/services/init/new_example_snakemake/.latch/latch_entrypoint.py deleted file mode 100644 index 0419cdad..00000000 --- a/latch_cli/services/init/new_example_snakemake/.latch/latch_entrypoint.py +++ /dev/null @@ -1,85 +0,0 @@ -import subprocess -from pathlib import Path -from typing import NamedTuple - -from latch import small_task -from latch.types import LatchFile - -def ensure_parents_exist(path: Path): - path.parent.mkdir(parents=True, exist_ok=True) - return path - - -@small_task -def bwa_map_4(data_genome__fa: LatchFile, data_samples_A__fastq: LatchFile, data_genome__fa__amb: LatchFile, data_genome__fa__ann: LatchFile, data_genome__fa__bwt: LatchFile, data_genome__fa__fai: LatchFile, data_genome__fa__pac: LatchFile, data_genome__fa__sa: LatchFile) -> NamedTuple('bwa_map_4_output', mapped_reads_A__bam=LatchFile): - Path(data_genome__fa).resolve().rename(ensure_parents_exist(Path("data/genome.fa"))) - Path(data_samples_A__fastq).resolve().rename(ensure_parents_exist(Path("data/samples/A.fastq"))) - Path(data_genome__fa__amb).resolve().rename(ensure_parents_exist(Path("data/genome.fa.amb"))) - Path(data_genome__fa__ann).resolve().rename(ensure_parents_exist(Path("data/genome.fa.ann"))) - Path(data_genome__fa__bwt).resolve().rename(ensure_parents_exist(Path("data/genome.fa.bwt"))) - Path(data_genome__fa__fai).resolve().rename(ensure_parents_exist(Path("data/genome.fa.fai"))) - Path(data_genome__fa__pac).resolve().rename(ensure_parents_exist(Path("data/genome.fa.pac"))) - Path(data_genome__fa__sa).resolve().rename(ensure_parents_exist(Path("data/genome.fa.sa"))) - - subprocess.run(["snakemake", "-s", "Snakefile", "--target-jobs", "bwa_map:sample=A", "--allowed-rules", "bwa_map", "--local-groupid", "4", "--cores", "1", "--force-use-threads"], check=True) - return (LatchFile('mapped_reads/A.bam')) - -@small_task -def bwa_map_6(data_genome__fa: LatchFile, data_samples_B__fastq: LatchFile, data_genome__fa__amb: LatchFile, data_genome__fa__ann: LatchFile, data_genome__fa__bwt: LatchFile, data_genome__fa__fai: LatchFile, data_genome__fa__pac: LatchFile, data_genome__fa__sa: LatchFile) -> NamedTuple('bwa_map_6_output', mapped_reads_B__bam=LatchFile): - Path(data_genome__fa).resolve().rename(ensure_parents_exist(Path("data/genome.fa"))) - Path(data_samples_B__fastq).resolve().rename(ensure_parents_exist(Path("data/samples/B.fastq"))) - Path(data_genome__fa__amb).resolve().rename(ensure_parents_exist(Path("data/genome.fa.amb"))) - Path(data_genome__fa__ann).resolve().rename(ensure_parents_exist(Path("data/genome.fa.ann"))) - Path(data_genome__fa__bwt).resolve().rename(ensure_parents_exist(Path("data/genome.fa.bwt"))) - Path(data_genome__fa__fai).resolve().rename(ensure_parents_exist(Path("data/genome.fa.fai"))) - Path(data_genome__fa__pac).resolve().rename(ensure_parents_exist(Path("data/genome.fa.pac"))) - Path(data_genome__fa__sa).resolve().rename(ensure_parents_exist(Path("data/genome.fa.sa"))) - - subprocess.run(["snakemake", "-s", "Snakefile", "--target-jobs", "bwa_map:sample=B", "--allowed-rules", "bwa_map", "--local-groupid", "6", "--cores", "1", "--force-use-threads"], check=True) - return (LatchFile('mapped_reads/B.bam')) - -@small_task -def samtools_sort_3(mapped_reads_A__bam: LatchFile) -> NamedTuple('samtools_sort_3_output', sorted_reads_A__bam=LatchFile): - Path(mapped_reads_A__bam).resolve().rename(ensure_parents_exist(Path("mapped_reads/A.bam"))) - - subprocess.run(["snakemake", "-s", "Snakefile", "--target-jobs", "samtools_sort:sample=A", "--allowed-rules", "samtools_sort", "--local-groupid", "3", "--cores", "1", "--force-use-threads"], check=True) - return (LatchFile('sorted_reads/A.bam')) - -@small_task -def samtools_sort_5(mapped_reads_B__bam: LatchFile) -> NamedTuple('samtools_sort_5_output', sorted_reads_B__bam=LatchFile): - Path(mapped_reads_B__bam).resolve().rename(ensure_parents_exist(Path("mapped_reads/B.bam"))) - - subprocess.run(["snakemake", "-s", "Snakefile", "--target-jobs", "samtools_sort:sample=B", "--allowed-rules", "samtools_sort", "--local-groupid", "5", "--cores", "1", "--force-use-threads"], check=True) - return (LatchFile('sorted_reads/B.bam')) - -@small_task -def samtools_index_7(sorted_reads_A__bam: LatchFile) -> NamedTuple('samtools_index_7_output', sorted_reads_A__bam__bai=LatchFile): - Path(sorted_reads_A__bam).resolve().rename(ensure_parents_exist(Path("sorted_reads/A.bam"))) - - subprocess.run(["snakemake", "-s", "Snakefile", "--target-jobs", "samtools_index:sample=A", "--allowed-rules", "samtools_index", "--local-groupid", "7", "--cores", "1", "--force-use-threads"], check=True) - return (LatchFile('sorted_reads/A.bam.bai')) - -@small_task -def samtools_index_8(sorted_reads_B__bam: LatchFile) -> NamedTuple('samtools_index_8_output', sorted_reads_B__bam__bai=LatchFile): - Path(sorted_reads_B__bam).resolve().rename(ensure_parents_exist(Path("sorted_reads/B.bam"))) - - subprocess.run(["snakemake", "-s", "Snakefile", "--target-jobs", "samtools_index:sample=B", "--allowed-rules", "samtools_index", "--local-groupid", "8", "--cores", "1", "--force-use-threads"], check=True) - return (LatchFile('sorted_reads/B.bam.bai')) - -@small_task -def bcftools_call_2(fa: LatchFile, sorted_reads_A__bam: LatchFile, sorted_reads_B__bam: LatchFile, sorted_reads_A__bam__bai: LatchFile, sorted_reads_B__bam__bai: LatchFile) -> NamedTuple('bcftools_call_2_output', calls_all__vcf=LatchFile): - Path(fa).resolve().rename(ensure_parents_exist(Path("data/genome.fa"))) - Path(sorted_reads_A__bam).resolve().rename(ensure_parents_exist(Path("sorted_reads/A.bam"))) - Path(sorted_reads_B__bam).resolve().rename(ensure_parents_exist(Path("sorted_reads/B.bam"))) - Path(sorted_reads_A__bam__bai).resolve().rename(ensure_parents_exist(Path("sorted_reads/A.bam.bai"))) - Path(sorted_reads_B__bam__bai).resolve().rename(ensure_parents_exist(Path("sorted_reads/B.bam.bai"))) - - subprocess.run(["snakemake", "-s", "Snakefile", "--target-jobs", "bcftools_call:", "--allowed-rules", "bcftools_call", "--local-groupid", "2", "--cores", "1", "--force-use-threads"], check=True) - return (LatchFile('calls/all.vcf')) - -@small_task -def plot_quals_1(calls_all__vcf: LatchFile) -> NamedTuple('plot_quals_1_output', plots_quals__svg=LatchFile): - Path(calls_all__vcf).resolve().rename(ensure_parents_exist(Path("calls/all.vcf"))) - - subprocess.run(["snakemake", "-s", "Snakefile", "--target-jobs", "plot_quals:", "--allowed-rules", "plot_quals", "--local-groupid", "1", "--cores", "1", "--force-use-threads"], check=True) - return (LatchFile('plots/quals.svg', 'latch:///plots/quals.svg')) \ No newline at end of file diff --git a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-1d8b2c/docker-build-logs.txt b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-1d8b2c/docker-build-logs.txt deleted file mode 100644 index 5b55c987..00000000 --- a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-1d8b2c/docker-build-logs.txt +++ /dev/null @@ -1,743 +0,0 @@ -Step 1/14 : from 812206152185.dkr.ecr.us-west-2.amazonaws.com/latch-base:b733-kenny--snakemake - - - ---> 77471241d7a3 - -Step 2/14 : run mkdir /opt/latch - - - ---> Using cache - - ---> 6d1d7399ec34 - -Step 3/14 : RUN curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh && mkdir /root/.conda && bash Mambaforge-Linux-x86_64.sh -b && rm -f Mambaforge-Linux-x86_64.sh - - - ---> Using cache - - ---> e5d7f1c377ad - -Step 4/14 : copy environment.yaml /root/environment.yaml - - - ---> Using cache - - ---> f1895bb6bb01 - -Step 5/14 : run /root/mambaforge/bin/mamba env create --name snakemake-tutorial --file environment.yaml - - - ---> Using cache - - ---> 1c115b179fb8 - -Step 6/14 : env PATH /root/mambaforge/envs/snakemake-tutorial/bin:$PATH - - - ---> Using cache - - ---> 38bcbc3eaccf - -Step 7/14 : copy latch /root/latch - - - ---> 0a6841ad1519 - -Step 8/14 : run cd /root/latch && python3 -m pip install -e . - - - ---> Running in dd7f0cbc398c - -Obtaining file:///root/latch - - Installing build dependencies: started - - Installing build dependencies: finished with status 'done' - Checking if build backend supports build_editable: started - - Checking if build backend supports build_editable: finished with status 'done' - - Getting requirements to build editable: started - - Getting requirements to build editable: finished with status 'done' - - Preparing editable metadata (pyproject.toml): started - - Preparing editable metadata (pyproject.toml): finished with status 'done' - -Collecting asyncssh==2.12.0 (from latch==2.19.11) - - Downloading asyncssh-2.12.0-py3-none-any.whl (346 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 346.7/346.7 kB 8.6 MB/s eta 0:00:00 - - -Collecting aioconsole==0.5.1 (from latch==2.19.11) - - Downloading aioconsole-0.5.1-py3-none-any.whl (30 kB) - -Collecting kubernetes>=24.2.0 (from latch==2.19.11) - - Downloading kubernetes-26.1.0-py2.py3-none-any.whl (1.4 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.4/1.4 MB 44.9 MB/s eta 0:00:00 - - -Collecting pyjwt>=0.2.0 (from latch==2.19.11) - - Downloading PyJWT-2.7.0-py3-none-any.whl (22 kB) - -Requirement already satisfied: requests>=2.28.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from latch==2.19.11) (2.29.0) - -Collecting click>=8.0 (from latch==2.19.11) - - Downloading click-8.1.3-py3-none-any.whl (96 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 96.6/96.6 kB 12.5 MB/s eta 0:00:00 - - -Collecting docker>=5.0 (from latch==2.19.11) - - Downloading docker-6.1.2-py3-none-any.whl (148 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 148.1/148.1 kB 19.4 MB/s eta 0:00:00 - - -Collecting paramiko>=2.11.0 (from latch==2.19.11) - - Downloading paramiko-3.1.0-py3-none-any.whl (211 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 211.2/211.2 kB 24.6 MB/s eta 0:00:00 - - -Collecting scp>=0.14.0 (from latch==2.19.11) - - Downloading scp-0.14.5-py2.py3-none-any.whl (8.7 kB) - -Collecting boto3>=1.24.22 (from latch==2.19.11) - - Using cached boto3-1.26.137-py3-none-any.whl (135 kB) - -Collecting tqdm>=4.63.0 (from latch==2.19.11) - - Downloading tqdm-4.65.0-py3-none-any.whl (77 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 77.1/77.1 kB 10.9 MB/s eta 0:00:00 - - -Collecting lytekit==0.14.10 (from latch==2.19.11) - - Downloading lytekit-0.14.10-py3-none-any.whl (391 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 391.8/391.8 kB 39.4 MB/s eta 0:00:00 - - -Collecting lytekitplugins-pods==0.4.0 (from latch==2.19.11) - - Downloading lytekitplugins_pods-0.4.0-py3-none-any.whl (4.3 kB) - -Requirement already satisfied: typing-extensions==4.5.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from latch==2.19.11) (4.5.0) - -Collecting apscheduler==3.9.1 (from latch==2.19.11) - - Downloading APScheduler-3.9.1-py2.py3-none-any.whl (59 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 59.5/59.5 kB 9.0 MB/s eta 0:00:00 - - -Collecting uvloop==0.17.0 (from latch==2.19.11) - - Downloading uvloop-0.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.1 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.1/4.1 MB 69.9 MB/s eta 0:00:00 - - -Collecting websockets==10.3 (from latch==2.19.11) - - Downloading websockets-10.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (111 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 111.5/111.5 kB 15.2 MB/s eta 0:00:00 - - -Collecting prompt-toolkit==3.0.33 (from latch==2.19.11) - - Downloading prompt_toolkit-3.0.33-py3-none-any.whl (383 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 383.6/383.6 kB 36.6 MB/s eta 0:00:00 - - -Collecting watchfiles==0.18.1 (from latch==2.19.11) - - Downloading watchfiles-0.18.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.2 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.2/1.2 MB 63.8 MB/s eta 0:00:00 - - -Collecting gql==3.4.0 (from latch==2.19.11) - - Downloading gql-3.4.0-py2.py3-none-any.whl (65 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 65.2/65.2 kB 9.5 MB/s eta 0:00:00 - - -Collecting graphql-core==3.2.3 (from latch==2.19.11) - - Downloading graphql_core-3.2.3-py3-none-any.whl (202 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 202.9/202.9 kB 24.1 MB/s eta 0:00:00 - - -Collecting requests-toolbelt==0.10.1 (from latch==2.19.11) - - Downloading requests_toolbelt-0.10.1-py2.py3-none-any.whl (54 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 54.5/54.5 kB 7.2 MB/s eta 0:00:00 - - -Requirement already satisfied: snakemake>=7.25.4 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from latch==2.19.11) (7.25.4) - -Requirement already satisfied: setuptools>=0.7 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from apscheduler==3.9.1->latch==2.19.11) (67.7.2) - -Requirement already satisfied: six>=1.4.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from apscheduler==3.9.1->latch==2.19.11) (1.16.0) - -Collecting pytz (from apscheduler==3.9.1->latch==2.19.11) - - Downloading pytz-2023.3-py2.py3-none-any.whl (502 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 502.3/502.3 kB 43.0 MB/s eta 0:00:00 - - -Collecting tzlocal!=3.*,>=2.0 (from apscheduler==3.9.1->latch==2.19.11) - - Downloading tzlocal-5.0.1-py3-none-any.whl (20 kB) - -Requirement already satisfied: cryptography>=3.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from asyncssh==2.12.0->latch==2.19.11) (39.0.0) - -Collecting yarl<2.0,>=1.6 (from gql==3.4.0->latch==2.19.11) - - Downloading yarl-1.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (268 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 268.8/268.8 kB 29.6 MB/s eta 0:00:00 - - -Collecting backoff<3.0,>=1.11.1 (from gql==3.4.0->latch==2.19.11) - - Downloading backoff-2.2.1-py3-none-any.whl (15 kB) - -Collecting lyteidl==0.2.0a0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading lyteidl-0.2.0a0-py3-none-any.whl (162 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 162.2/162.2 kB 21.9 MB/s eta 0:00:00 - - -Requirement already satisfied: wheel<1.0.0,>=0.30.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (0.40.0) - -Collecting pandas<2.0.0,>=1.0.0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading pandas-1.5.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (12.1 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 12.1/12.1 MB 75.4 MB/s eta 0:00:00 - - -Collecting pyarrow<7.0.0,>=4.0.0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading pyarrow-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (25.6 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 25.6/25.6 MB 53.3 MB/s eta 0:00:00 - - -Collecting croniter<4.0.0,>=0.3.20 (from lytekit==0.14.10->latch==2.19.11) - - Downloading croniter-1.3.14-py2.py3-none-any.whl (18 kB) - -Collecting deprecated<2.0,>=1.0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading Deprecated-1.2.13-py2.py3-none-any.whl (9.6 kB) - -Collecting docker>=5.0 (from latch==2.19.11) - - Downloading docker-5.0.3-py2.py3-none-any.whl (146 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 146.2/146.2 kB 20.1 MB/s eta 0:00:00 - - -Requirement already satisfied: python-dateutil>=2.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (2.8.2) - -Collecting grpcio!=1.45.0,<2.0,>=1.43.0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading grpcio-1.54.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.1 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 5.1/5.1 MB 75.4 MB/s eta 0:00:00 - - -Collecting grpcio-status!=1.45.0,>=1.43 (from lytekit==0.14.10->latch==2.19.11) - - Downloading grpcio_status-1.54.2-py3-none-any.whl (5.1 kB) - -Collecting protobuf<4,>=3.6.1 (from lytekit==0.14.10->latch==2.19.11) - - Downloading protobuf-3.20.3-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (1.1 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.1/1.1 MB 63.2 MB/s eta 0:00:00 - - -Collecting python-json-logger>=2.0.0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading python_json_logger-2.0.7-py3-none-any.whl (8.1 kB) - -Collecting pytimeparse<2.0.0,>=1.1.8 (from lytekit==0.14.10->latch==2.19.11) - - Downloading pytimeparse-1.1.8-py2.py3-none-any.whl (10.0 kB) - -Requirement already satisfied: pyyaml in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (6.0) - -Collecting keyring>=18.0.1 (from lytekit==0.14.10->latch==2.19.11) - - Downloading keyring-23.13.1-py3-none-any.whl (37 kB) - -Collecting responses>=0.10.7 (from lytekit==0.14.10->latch==2.19.11) - - Downloading responses-0.23.1-py3-none-any.whl (52 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 52.1/52.1 kB 7.7 MB/s eta 0:00:00 - - -Collecting sortedcontainers<3.0.0,>=1.5.9 (from lytekit==0.14.10->latch==2.19.11) - - Downloading sortedcontainers-2.4.0-py2.py3-none-any.whl (29 kB) - -Collecting statsd<4.0.0,>=3.0.0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading statsd-3.3.0-py2.py3-none-any.whl (11 kB) - -Requirement already satisfied: urllib3<2.0.0,>=1.22 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (1.26.15) - -Requirement already satisfied: wrapt<2.0.0,>=1.0.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (1.15.0) - -Collecting retry==0.9.2 (from lytekit==0.14.10->latch==2.19.11) - - Downloading retry-0.9.2-py2.py3-none-any.whl (8.0 kB) - -Collecting dataclasses-json>=0.5.2 (from lytekit==0.14.10->latch==2.19.11) - - Downloading dataclasses_json-0.5.7-py3-none-any.whl (25 kB) - -Requirement already satisfied: jsonschema>=4.5.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (4.17.3) - -Collecting marshmallow-jsonschema>=0.12.0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading marshmallow_jsonschema-0.13.0-py3-none-any.whl (11 kB) - -Collecting natsort>=7.0.1 (from lytekit==0.14.10->latch==2.19.11) - - Downloading natsort-8.3.1-py3-none-any.whl (38 kB) - -Collecting docker-image-py>=0.1.10 (from lytekit==0.14.10->latch==2.19.11) - - Downloading docker-image-py-0.1.12.tar.gz (8.2 kB) - - Preparing metadata (setup.py): started - - Preparing metadata (setup.py): finished with status 'done' - -Collecting docstring-parser>=0.9.0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading docstring_parser-0.15-py3-none-any.whl (36 kB) - -Collecting diskcache>=5.2.1 (from lytekit==0.14.10->latch==2.19.11) - - Downloading diskcache-5.6.1-py3-none-any.whl (45 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 45.6/45.6 kB 6.8 MB/s eta 0:00:00 - - -Collecting cloudpickle>=2.0.0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading cloudpickle-2.2.1-py3-none-any.whl (25 kB) - -Collecting cookiecutter>=1.7.3 (from lytekit==0.14.10->latch==2.19.11) - - Downloading cookiecutter-2.1.1-py2.py3-none-any.whl (36 kB) - -Collecting numpy<1.22.0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading numpy-1.21.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (15.9 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 15.9/15.9 MB 72.9 MB/s eta 0:00:00 - - -Collecting wcwidth (from prompt-toolkit==3.0.33->latch==2.19.11) - - Downloading wcwidth-0.2.6-py2.py3-none-any.whl (29 kB) - -Collecting anyio>=3.0.0 (from watchfiles==0.18.1->latch==2.19.11) - - Downloading anyio-3.6.2-py3-none-any.whl (80 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 80.6/80.6 kB 11.6 MB/s eta 0:00:00 - - -Collecting googleapis-common-protos (from lyteidl==0.2.0a0->lytekit==0.14.10->latch==2.19.11) - - Downloading googleapis_common_protos-1.59.0-py2.py3-none-any.whl (223 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 223.6/223.6 kB 28.8 MB/s eta 0:00:00 - - -Collecting protoc-gen-swagger (from lyteidl==0.2.0a0->lytekit==0.14.10->latch==2.19.11) - - Downloading protoc_gen_swagger-0.1.0-py2.py3-none-any.whl (9.4 kB) - -Collecting decorator>=3.4.2 (from retry==0.9.2->lytekit==0.14.10->latch==2.19.11) - - Downloading decorator-5.1.1-py3-none-any.whl (9.1 kB) - -Collecting py<2.0.0,>=1.4.26 (from retry==0.9.2->lytekit==0.14.10->latch==2.19.11) - - Downloading py-1.11.0-py2.py3-none-any.whl (98 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 98.7/98.7 kB 14.9 MB/s eta 0:00:00 - - -Collecting botocore<1.30.0,>=1.29.137 (from boto3>=1.24.22->latch==2.19.11) - - Using cached botocore-1.29.137-py3-none-any.whl (10.8 MB) - -Collecting jmespath<2.0.0,>=0.7.1 (from boto3>=1.24.22->latch==2.19.11) - - Using cached jmespath-1.0.1-py3-none-any.whl (20 kB) - -Collecting s3transfer<0.7.0,>=0.6.0 (from boto3>=1.24.22->latch==2.19.11) - - Using cached s3transfer-0.6.1-py3-none-any.whl (79 kB) - -Collecting websocket-client>=0.32.0 (from docker>=5.0->latch==2.19.11) - - Downloading websocket_client-1.5.2-py3-none-any.whl (56 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 56.6/56.6 kB 9.0 MB/s eta 0:00:00 - - -Requirement already satisfied: certifi>=14.05.14 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from kubernetes>=24.2.0->latch==2.19.11) (2023.5.7) - -Collecting google-auth>=1.0.1 (from kubernetes>=24.2.0->latch==2.19.11) - - Downloading google_auth-2.18.1-py2.py3-none-any.whl (178 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 178.9/178.9 kB 24.0 MB/s eta 0:00:00 - - -Collecting requests-oauthlib (from kubernetes>=24.2.0->latch==2.19.11) - - Downloading requests_oauthlib-1.3.1-py2.py3-none-any.whl (23 kB) - -Collecting bcrypt>=3.2 (from paramiko>=2.11.0->latch==2.19.11) - - Downloading bcrypt-4.0.1-cp36-abi3-manylinux_2_28_x86_64.whl (593 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 593.7/593.7 kB 49.7 MB/s eta 0:00:00 - - -Collecting pynacl>=1.5 (from paramiko>=2.11.0->latch==2.19.11) - - Downloading PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl (856 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 856.7/856.7 kB 58.5 MB/s eta 0:00:00 - - -Requirement already satisfied: charset-normalizer<4,>=2 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from requests>=2.28.1->latch==2.19.11) (3.1.0) - -Requirement already satisfied: idna<4,>=2.5 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from requests>=2.28.1->latch==2.19.11) (3.4) - -Requirement already satisfied: appdirs in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.4.4) - -Requirement already satisfied: configargparse in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.5.3) - -Requirement already satisfied: connection-pool>=0.0.3 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (0.0.3) - -Requirement already satisfied: datrie in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (0.8.2) - -Requirement already satisfied: docutils in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (0.20.1) - -Requirement already satisfied: gitpython in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (3.1.31) - -Requirement already satisfied: humanfriendly in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (10.0) - -Requirement already satisfied: jinja2<4.0,>=3.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (3.1.2) - -Requirement already satisfied: nbformat in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (5.8.0) - -Requirement already satisfied: psutil in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (5.9.5) - -Requirement already satisfied: pulp>=2.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (2.7.0) - -Requirement already satisfied: reretry in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (0.11.8) - -Requirement already satisfied: smart-open>=3.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (6.3.0) - -Requirement already satisfied: stopit in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.1.2) - -Requirement already satisfied: tabulate in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (0.9.0) - -Requirement already satisfied: throttler in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.2.1) - -Requirement already satisfied: toposort>=1.10 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.10) - -Requirement already satisfied: yte<2.0,>=1.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.5.1) - -Collecting sniffio>=1.1 (from anyio>=3.0.0->watchfiles==0.18.1->latch==2.19.11) - - Downloading sniffio-1.3.0-py3-none-any.whl (10 kB) - -Collecting binaryornot>=0.4.4 (from cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) - - Downloading binaryornot-0.4.4-py2.py3-none-any.whl (9.0 kB) - -Collecting jinja2-time>=0.2.0 (from cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) - - Downloading jinja2_time-0.2.0-py2.py3-none-any.whl (6.4 kB) - -Collecting python-slugify>=4.0.0 (from cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) - - Downloading python_slugify-8.0.1-py2.py3-none-any.whl (9.7 kB) - -Requirement already satisfied: cffi>=1.12 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from cryptography>=3.1->asyncssh==2.12.0->latch==2.19.11) (1.15.1) - -Collecting marshmallow<4.0.0,>=3.3.0 (from dataclasses-json>=0.5.2->lytekit==0.14.10->latch==2.19.11) - - Downloading marshmallow-3.19.0-py3-none-any.whl (49 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 49.1/49.1 kB 7.0 MB/s eta 0:00:00 - - -Collecting marshmallow-enum<2.0.0,>=1.5.1 (from dataclasses-json>=0.5.2->lytekit==0.14.10->latch==2.19.11) - - Downloading marshmallow_enum-1.5.1-py2.py3-none-any.whl (4.2 kB) - -Collecting typing-inspect>=0.4.0 (from dataclasses-json>=0.5.2->lytekit==0.14.10->latch==2.19.11) - - Downloading typing_inspect-0.8.0-py3-none-any.whl (8.7 kB) - -Collecting regex>=2019.4.14 (from docker-image-py>=0.1.10->lytekit==0.14.10->latch==2.19.11) - - Downloading regex-2023.5.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (769 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 769.7/769.7 kB 56.9 MB/s eta 0:00:00 - - -Collecting cachetools<6.0,>=2.0.0 (from google-auth>=1.0.1->kubernetes>=24.2.0->latch==2.19.11) - - Downloading cachetools-5.3.0-py3-none-any.whl (9.3 kB) - -Collecting pyasn1-modules>=0.2.1 (from google-auth>=1.0.1->kubernetes>=24.2.0->latch==2.19.11) - - Downloading pyasn1_modules-0.3.0-py2.py3-none-any.whl (181 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 181.3/181.3 kB 21.8 MB/s eta 0:00:00 - - -Collecting rsa<5,>=3.1.4 (from google-auth>=1.0.1->kubernetes>=24.2.0->latch==2.19.11) - - Downloading rsa-4.9-py3-none-any.whl (34 kB) - -INFO: pip is looking at multiple versions of grpcio-status to determine which version is compatible with other requirements. This could take a while. - -Collecting grpcio-status!=1.45.0,>=1.43 (from lytekit==0.14.10->latch==2.19.11) - - Downloading grpcio_status-1.54.0-py3-none-any.whl (5.1 kB) - - Downloading grpcio_status-1.53.1-py3-none-any.whl (5.1 kB) - - Downloading grpcio_status-1.53.0-py3-none-any.whl (5.1 kB) - - Downloading grpcio_status-1.51.3-py3-none-any.whl (5.1 kB) - - Downloading grpcio_status-1.51.1-py3-none-any.whl (5.1 kB) - - Downloading grpcio_status-1.50.0-py3-none-any.whl (14 kB) - - Downloading grpcio_status-1.49.1-py3-none-any.whl (14 kB) - -INFO: pip is looking at multiple versions of grpcio-status to determine which version is compatible with other requirements. This could take a while. - - Downloading grpcio_status-1.48.2-py3-none-any.whl (14 kB) - -Requirement already satisfied: MarkupSafe>=2.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from jinja2<4.0,>=3.0->snakemake>=7.25.4->latch==2.19.11) (2.1.2) - -Requirement already satisfied: attrs>=17.4.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from jsonschema>=4.5.1->lytekit==0.14.10->latch==2.19.11) (23.1.0) - -Requirement already satisfied: pyrsistent!=0.17.0,!=0.17.1,!=0.17.2,>=0.14.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from jsonschema>=4.5.1->lytekit==0.14.10->latch==2.19.11) (0.19.3) - -Collecting jaraco.classes (from keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) - - Downloading jaraco.classes-3.2.3-py3-none-any.whl (6.0 kB) - -Requirement already satisfied: importlib-metadata>=4.11.4 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) (6.6.0) - -Collecting SecretStorage>=3.2 (from keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) - - Downloading SecretStorage-3.3.3-py3-none-any.whl (15 kB) - -Collecting jeepney>=0.4.2 (from keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) - - Downloading jeepney-0.8.0-py3-none-any.whl (48 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 48.4/48.4 kB 7.6 MB/s eta 0:00:00 - - -Collecting types-PyYAML (from responses>=0.10.7->lytekit==0.14.10->latch==2.19.11) - - Downloading types_PyYAML-6.0.12.9-py3-none-any.whl (14 kB) - -Collecting multidict>=4.0 (from yarl<2.0,>=1.6->gql==3.4.0->latch==2.19.11) - - Downloading multidict-6.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (114 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 114.5/114.5 kB 15.6 MB/s eta 0:00:00 - - -Requirement already satisfied: dpath<3.0,>=2.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from yte<2.0,>=1.0->snakemake>=7.25.4->latch==2.19.11) (2.1.6) - -Requirement already satisfied: plac<2.0.0,>=1.3.4 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from yte<2.0,>=1.0->snakemake>=7.25.4->latch==2.19.11) (1.3.5) - -Requirement already satisfied: gitdb<5,>=4.0.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from gitpython->snakemake>=7.25.4->latch==2.19.11) (4.0.10) - -Requirement already satisfied: fastjsonschema in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from nbformat->snakemake>=7.25.4->latch==2.19.11) (2.16.3) - -Requirement already satisfied: jupyter-core in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from nbformat->snakemake>=7.25.4->latch==2.19.11) (5.3.0) - -Requirement already satisfied: traitlets>=5.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from nbformat->snakemake>=7.25.4->latch==2.19.11) (5.9.0) - -Collecting oauthlib>=3.0.0 (from requests-oauthlib->kubernetes>=24.2.0->latch==2.19.11) - - Downloading oauthlib-3.2.2-py3-none-any.whl (151 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 151.7/151.7 kB 20.8 MB/s eta 0:00:00 - - -Collecting chardet>=3.0.2 (from binaryornot>=0.4.4->cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) - - Downloading chardet-5.1.0-py3-none-any.whl (199 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 199.1/199.1 kB 24.7 MB/s eta 0:00:00 - - -Requirement already satisfied: pycparser in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from cffi>=1.12->cryptography>=3.1->asyncssh==2.12.0->latch==2.19.11) (2.21) - -Requirement already satisfied: smmap<6,>=3.0.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from gitdb<5,>=4.0.1->gitpython->snakemake>=7.25.4->latch==2.19.11) (3.0.5) - -Requirement already satisfied: zipp>=0.5 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from importlib-metadata>=4.11.4->keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) (3.15.0) - -Collecting arrow (from jinja2-time>=0.2.0->cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) - - Downloading arrow-1.2.3-py3-none-any.whl (66 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 66.4/66.4 kB 8.8 MB/s eta 0:00:00 - - -Requirement already satisfied: packaging>=17.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from marshmallow<4.0.0,>=3.3.0->dataclasses-json>=0.5.2->lytekit==0.14.10->latch==2.19.11) (23.1) - -Collecting pyasn1<0.6.0,>=0.4.6 (from pyasn1-modules>=0.2.1->google-auth>=1.0.1->kubernetes>=24.2.0->latch==2.19.11) - - Using cached pyasn1-0.5.0-py2.py3-none-any.whl (83 kB) - -Collecting text-unidecode>=1.3 (from python-slugify>=4.0.0->cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) - - Downloading text_unidecode-1.3-py2.py3-none-any.whl (78 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 78.2/78.2 kB 11.7 MB/s eta 0:00:00 - - -Collecting mypy-extensions>=0.3.0 (from typing-inspect>=0.4.0->dataclasses-json>=0.5.2->lytekit==0.14.10->latch==2.19.11) - - Downloading mypy_extensions-1.0.0-py3-none-any.whl (4.7 kB) - -Collecting more-itertools (from jaraco.classes->keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) - - Downloading more_itertools-9.1.0-py3-none-any.whl (54 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 54.2/54.2 kB 7.8 MB/s eta 0:00:00 - - -Requirement already satisfied: platformdirs>=2.5 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from jupyter-core->nbformat->snakemake>=7.25.4->latch==2.19.11) (3.5.1) - -WARNING: The candidate selected for download or install is a yanked version: 'apscheduler' candidate (version 3.9.1 at https://files.pythonhosted.org/packages/e4/9f/c3937d4babe62504b874d4bf2c0d85aa69c7f59fa84cf6050f3b9dc5d83e/APScheduler-3.9.1-py2.py3-none-any.whl (from https://pypi.org/simple/apscheduler/) (requires-python:>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4)) -Reason for being yanked: Not compatible with Python 2.7 - -Building wheels for collected packages: latch, docker-image-py - - Building editable for latch (pyproject.toml): started - - Building editable for latch (pyproject.toml): finished with status 'done' - - Created wheel for latch: filename=latch-2.19.11-0.editable-py3-none-any.whl size=3728 sha256=45c37325a5f77f85cab10dbf6078b5c6c13a16e244e658684de17b426a03da77 - - Stored in directory: /tmp/pip-ephem-wheel-cache-2rp2kq11/wheels/66/25/3a/f25ede02a4206d090762dd0ca4dbdc81da4d61e154ed692990 - - Building wheel for docker-image-py (setup.py): started - - Building wheel for docker-image-py (setup.py): finished with status 'done' - - Created wheel for docker-image-py: filename=docker_image_py-0.1.12-py3-none-any.whl size=8812 sha256=60010da77a8bfeaf7239633bb9e48b81ba0a2431b6a10d6a13a137d18ed8bc30 - - Stored in directory: /root/.cache/pip/wheels/fb/45/02/503244da15fbcecde5c3edabb744ed0c4f9a7643126b2d222c - -Successfully built latch docker-image-py - -Installing collected packages: wcwidth, types-PyYAML, text-unidecode, statsd, sortedcontainers, pytz, pytimeparse, websockets, websocket-client, uvloop, tzlocal, tqdm, sniffio, regex, python-slugify, python-json-logger, pyjwt, pyasn1, py, protobuf, prompt-toolkit, oauthlib, numpy, natsort, mypy-extensions, multidict, more-itertools, marshmallow, jmespath, jeepney, grpcio, graphql-core, docstring-parser, diskcache, deprecated, decorator, cloudpickle, click, chardet, cachetools, bcrypt, backoff, aioconsole, yarl, typing-inspect, rsa, retry, responses, requests-toolbelt, requests-oauthlib, pynacl, pyasn1-modules, pyarrow, protoc-gen-swagger, pandas, marshmallow-jsonschema, marshmallow-enum, jaraco.classes, googleapis-common-protos, docker-image-py, docker, croniter, botocore, binaryornot, arrow, apscheduler, anyio, watchfiles, SecretStorage, s3transfer, paramiko, lyteidl, jinja2-time, grpcio-status, gql, google-auth, dataclasses-json, asyncssh, scp, kubernetes, keyring, cookiecutter, boto3, lytekit, lytekitplugins-pods, latch - - Attempting uninstall: numpy - - Found existing installation: numpy 1.24.3 - - Uninstalling numpy-1.24.3: - - Successfully uninstalled numpy-1.24.3 - -Successfully installed SecretStorage-3.3.3 aioconsole-0.5.1 anyio-3.6.2 apscheduler-3.9.1 arrow-1.2.3 asyncssh-2.12.0 backoff-2.2.1 bcrypt-4.0.1 binaryornot-0.4.4 boto3-1.26.137 botocore-1.29.137 cachetools-5.3.0 chardet-5.1.0 click-8.1.3 cloudpickle-2.2.1 cookiecutter-2.1.1 croniter-1.3.14 dataclasses-json-0.5.7 decorator-5.1.1 deprecated-1.2.13 diskcache-5.6.1 docker-5.0.3 docker-image-py-0.1.12 docstring-parser-0.15 google-auth-2.18.1 googleapis-common-protos-1.59.0 gql-3.4.0 graphql-core-3.2.3 grpcio-1.54.2 grpcio-status-1.48.2 jaraco.classes-3.2.3 jeepney-0.8.0 jinja2-time-0.2.0 jmespath-1.0.1 keyring-23.13.1 kubernetes-26.1.0 latch-2.19.11 lyteidl-0.2.0a0 lytekit-0.14.10 lytekitplugins-pods-0.4.0 marshmallow-3.19.0 marshmallow-enum-1.5.1 marshmallow-jsonschema-0.13.0 more-itertools-9.1.0 multidict-6.0.4 mypy-extensions-1.0.0 natsort-8.3.1 numpy-1.21.6 oauthlib-3.2.2 pandas-1.5.3 paramiko-3.1.0 prompt-toolkit-3.0.33 protobuf-3.20.3 protoc-gen-swagger-0.1.0 py-1.11.0 pyarrow-6.0.1 pyasn1-0.5.0 pyasn1-modules-0.3.0 pyjwt-2.7.0 pynacl-1.5.0 python-json-logger-2.0.7 python-slugify-8.0.1 pytimeparse-1.1.8 pytz-2023.3 regex-2023.5.5 requests-oauthlib-1.3.1 requests-toolbelt-0.10.1 responses-0.23.1 retry-0.9.2 rsa-4.9 s3transfer-0.6.1 scp-0.14.5 sniffio-1.3.0 sortedcontainers-2.4.0 statsd-3.3.0 text-unidecode-1.3 tqdm-4.65.0 types-PyYAML-6.0.12.9 typing-inspect-0.8.0 tzlocal-5.0.1 uvloop-0.17.0 watchfiles-0.18.1 wcwidth-0.2.6 websocket-client-1.5.2 websockets-10.3 yarl-1.9.2 - -WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv - - ---> 987ca2488773 - -Step 9/14 : copy Snakefile config.yaml /root/ - - - ---> ff2efbf9c325 - -Step 10/14 : copy scripts/plot-quals.py /root/scripts/plot-quals.py - - - ---> efa63cf5aa2d - -Step 11/14 : copy .latch/latch_entrypoint.py /root/latch_entrypoint.py - - - ---> 5222bb3def10 - -Step 12/14 : arg tag - - - ---> Running in 0d5670080d49 - - ---> 2b44d6814bf9 - -Step 13/14 : env FLYTE_INTERNAL_IMAGE $tag - - - ---> Running in 7c86bbffcaba - - ---> d60334da0de6 - -Step 14/14 : workdir /root - - - ---> Running in 04fe88e9f8bb - - ---> 2fde7c305cbd - -Successfully built 2fde7c305cbd - -Successfully tagged 812206152185.dkr.ecr.us-west-2.amazonaws.com/x1_test_latch_register:0.0.0-1d8b2c - diff --git a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-2dd65d/docker-build-logs.txt b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-2dd65d/docker-build-logs.txt deleted file mode 100644 index c645afa0..00000000 --- a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-2dd65d/docker-build-logs.txt +++ /dev/null @@ -1,514 +0,0 @@ -Step 1/14 : from 812206152185.dkr.ecr.us-west-2.amazonaws.com/latch-base:9c8f-main - - - ---> b253e8cdab51 - -Step 2/14 : run mkdir /opt/latch - - - ---> Running in b1d3040ec8a1 - - ---> 89e0ab657f0d - -Step 3/14 : RUN curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh && mkdir /root/.conda && bash Mambaforge-Linux-x86_64.sh -b && rm -f Mambaforge-Linux-x86_64.sh - - - ---> Running in 67b55c21f5aa - - % Total % Received % Xferd Aver -age Speed Time Time Time Current - Dload Upload Total Spent Left Speed - 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 - 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 - - 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 - - 0 82.9M 0 718k 0 0 1250k 0 0:01:07 --:--:-- 0:01:07 1250k - 73 82.9M 73 61.0M 0 0 38.7M 0 0:00:02 0:00:01 0:00:01 60.3M - 100 82.9M 100 82.9M 0 0 42.4M 0 0:00:01 0:00:01 --:--:-- 59.7M - -PREFIX=/root/mambaforge - -Unpacking payload ... - -Extracting _libgcc_mutex-0.1-conda_forge.tar.bz2 - -Extracting ca-certificates-2022.12.7-ha878542_0.conda - -Extracting ld_impl_linux-64-2.40-h41732ed_0.conda - -Extracting libstdcxx-ng-12.2.0-h46fd767_19.tar.bz2 - -Extracting pybind11-abi-4-hd8ed1ab_3.tar.bz2 - -Extracting python_abi-3.10-3_cp310.conda - -Extracting tzdata-2023c-h71feb2d_0.conda - -Extracting libgomp-12.2.0-h65d4601_19.tar.bz2 - -Extracting _openmp_mutex-4.5-2_gnu.tar.bz2 - -Extracting libgcc-ng-12.2.0-h65d4601_19.tar.bz2 - -Extracting bzip2-1.0.8-h7f98852_4.tar.bz2 - -Extracting c-ares-1.18.1-h7f98852_0.tar.bz2 - -Extracting fmt-9.1.0-h924138e_0.tar.bz2 - -Extracting icu-72.1-hcb278e6_0.conda - -Extracting keyutils-1.6.1-h166bdaf_0.tar.bz2 - -Extracting libev-4.33-h516909a_1.tar.bz2 - -Extracting libffi-3.4.2-h7f98852_5.tar.bz2 - -Extracting libiconv-1.17-h166bdaf_0.tar.bz2 - -Extracting libnsl-2.0.0-h7f98852_0.tar.bz2 - -Extracting libuuid-2.38.1-h0b41bf4_0.conda - -Extracting libzlib-1.2.13-h166bdaf_4.tar.bz2 - -Extracting lz4-c-1.9.4-hcb278e6_0.conda - -Extracting lzo-2.10-h516909a_1000.tar.bz2 - -Extracting ncurses-6.3-h27087fc_1.tar.bz2 - -Extracting openssl-3.1.0-h0b41bf4_0.conda - -Extracting reproc-14.2.4-h0b41bf4_0.conda - -Extracting xz-5.2.6-h166bdaf_0.tar.bz2 - -Extracting yaml-cpp-0.7.0-h27087fc_2.tar.bz2 - -Extracting libedit-3.1.20191231-he28a2e2_2.tar.bz2 - -Extracting libnghttp2-1.52.0-h61bc06f_0.conda - -Extracting libsolv-0.7.23-h3eb15da_0.conda - -Extracting libsqlite-3.40.0-h753d276_0.tar.bz2 - -Extracting libssh2-1.10.0-hf14f497_3.tar.bz2 - -Extracting libxml2-2.10.3-hfdac1af_6.conda - -Extracting readline-8.2-h8228510_1.conda - -Extracting reproc-cpp-14.2.4-hcb278e6_0.conda - -Extracting tk-8.6.12-h27826a3_0.tar.bz2 - -Extracting zstd-1.5.2-h3eb15da_6.conda - -Extracting krb5-1.20.1-h81ceb04_0.conda - -Extracting libarchive-3.6.2-h3d51595_0.conda - -Extracting python-3.10.10-he550d4f_0_cpython.conda - -Extracting certifi-2022.12.7-pyhd8ed1ab_0.conda - -Extracting charset-normalizer-3.1.0-pyhd8ed1ab_0.conda - -Extracting colorama-0.4.6-pyhd8ed1ab_0.tar.bz2 - -Extracting idna-3.4-pyhd8ed1ab_0.tar.bz2 - -Extracting libcurl-7.88.1-hdc1c0ab_1.conda - -Extracting pluggy-1.0.0-pyhd8ed1ab_5.tar.bz2 - -Extracting pycosat-0.6.4-py310h5764c6d_1.tar.bz2 - -Extracting pycparser-2.21-pyhd8ed1ab_0.tar.bz2 - -Extracting pysocks-1.7.1-pyha2e5f31_6.tar.bz2 - -Extracting ruamel.yaml.clib-0.2.7-py310h1fa729e_1.conda - -Extracting setuptools-65.6.3-pyhd8ed1ab_0.conda - -Extracting toolz-0.12.0-pyhd8ed1ab_0.tar.bz2 - -Extracting wheel-0.40.0-pyhd8ed1ab_0.conda - -Extracting cffi-1.15.1-py310h255011f_3.conda - -Extracting libmamba-1.4.1-hcea66bb_0.conda - -Extracting pip-23.0.1-pyhd8ed1ab_0.conda - -Extracting ruamel.yaml-0.17.21-py310h1fa729e_3.conda - -Extracting tqdm-4.65.0-pyhd8ed1ab_1.conda - -Extracting brotlipy-0.7.0-py310h5764c6d_1005.tar.bz2 - -Extracting cryptography-40.0.1-py310h34c0648_0.conda - -Extracting libmambapy-1.4.1-py310h1428755_0.conda - -Extracting zstandard-0.19.0-py310hdeb6495_1.conda - -Extracting conda-package-streaming-0.7.0-pyhd8ed1ab_1.conda - -Extracting pyopenssl-23.1.1-pyhd8ed1ab_0.conda - -Extracting conda-package-handling-2.0.2-pyh38be061_0.conda - -Extracting urllib3-1.26.15-pyhd8ed1ab_0.conda - -Extracting requests-2.28.2-pyhd8ed1ab_1.conda - -Extracting conda-23.1.0-py310hff52083_0.conda - -Extracting mamba-1.4.1-py310h51d5547_0.conda - - -Installing base environment... - - - - __ - __ ______ ___ ____ _____ ___ / /_ ____ _ - / / / / __ `__ \/ __ `/ __ `__ \/ __ \/ __ `/ - / /_/ / / / / / / /_/ / / / / / / /_/ / /_/ / - / .___/_/ /_/ /_/\__,_/_/ /_/ /_/_.___/\__,_/ - /_/ - - -Transaction - - Prefix: /root/mambaforge - - Updating specs: - - - conda-forge/linux-64::_libgcc_mutex==0.1=conda_forge[md5=d7c89558ba9fa0495403155b64376d81] - - conda-forge/linux-64::ca-certificates==2022.12.7=ha878542_0[md5=ff9f73d45c4a07d6f424495288a26080] - - conda-forge/linux-64::ld_impl_linux-64==2.40=h41732ed_0[md5=7aca3059a1729aa76c597603f10b0dd3] - - conda-forge/linux-64::libstdcxx-ng==12.2.0=h46fd767_19[md5=1030b1f38c129f2634eae026f704fe60] - - conda-forge/noarch::pybind11-abi==4=hd8ed1ab_3[md5=878f923dd6acc8aeb47a75da6c4098be] - - conda-forge/linux-64::python_abi==3.10=3_cp310[md5=4eb33d14d794b0f4be116443ffed3853] - - conda-forge/noarch::tzdata==2023c=h71feb2d_0[md5=939e3e74d8be4dac89ce83b20de2492a] - - conda-forge/linux-64::libgomp==12.2.0=h65d4601_19[md5=cedcee7c064c01c403f962c9e8d3c373] - - conda-forge/linux-64::_openmp_mutex==4.5=2_gnu[md5=73aaf86a425cc6e73fcf236a5a46396d] - - conda-forge/linux-64::libgcc-ng==12.2.0=h65d4601_19[md5=e4c94f80aef025c17ab0828cd85ef535] - - conda-forge/linux-64::bzip2==1.0.8=h7f98852_4[md5=a1fd65c7ccbf10880423d82bca54eb54] - - conda-forge/linux-64::c-ares==1.18.1=h7f98852_0[md5=f26ef8098fab1f719c91eb760d63381a] - - conda-forge/linux-64::fmt==9.1.0=h924138e_0[md5=b57864c85261a0fbc7132d2cc17478c7] - - conda-forge/linux-64::icu==72.1=hcb278e6_0[md5=7c8d20d847bb45f56bd941578fcfa146] - - conda-forge/linux-64::keyutils==1.6.1=h166bdaf_0[md5=30186d27e2c9fa62b45fb1476b7200e3] - - conda-forge/linux-64::libev==4.33=h516909a_1[md5=6f8720dff19e17ce5d48cfe7f3d2f0a3] - - conda-forge/linux-64::libffi==3.4.2=h7f98852_5[md5=d645c6d2ac96843a2bfaccd2d62b3ac3] - - conda-forge/linux-64::libiconv==1.17=h166bdaf_0[md5=b62b52da46c39ee2bc3c162ac7f1804d] - - conda-forge/linux-64::libnsl==2.0.0=h7f98852_0[md5=39b1328babf85c7c3a61636d9cd50206] - - conda-forge/linux-64::libuuid==2.38.1=h0b41bf4_0[md5=40b61aab5c7ba9ff276c41cfffe6b80b] - - - conda-forge/linux-64::libzlib==1.2.13=h166bdaf_4[md5=f3f9de449d32ca9b9c66a22863c96f41] - - conda-forge/linux-64::lz4-c==1.9.4=hcb278e6_0[md5=318b08df404f9c9be5712aaa5a6f0bb0] - - conda-forge/linux-64::lzo==2.10=h516909a_1000[md5=bb14fcb13341b81d5eb386423b9d2bac] - - conda-forge/linux-64::ncurses==6.3=h27087fc_1[md5=4acfc691e64342b9dae57cf2adc63238] - - conda-forge/linux-64::openssl==3.1.0=h0b41bf4_0[md5=2d833be81a21128e317325a01326d36f] - - conda-forge/linux-64::reproc==14.2.4=h0b41bf4_0[md5=0f51393e019df1f0047ef864cd9ddeec] - - conda-forge/linux-64::xz==5.2.6=h166bdaf_0[md5=2161070d867d1b1204ea749c8eec4ef0] - - conda-forge/linux-64::yaml-cpp==0.7.0=h27087fc_2[md5=0449d47d8457feaa3720d4779616dde2] - - conda-forge/linux-64::libedit==3.1.20191231=he28a2e2_2[md5=4d331e44109e3f0e19b4cb8f9b82f3e1] - - conda-forge/linux-64::libnghttp2==1.52.0=h61bc06f_0[md5=613955a50485812985c059e7b269f42e] - - conda-forge/linux-64::libsolv==0.7.23=h3eb15da_0[md5=122332e6deb4aea9eaf22021d2ecd256] - - conda-forge/linux-64::libsqlite==3.40.0=h753d276_0[md5=2e5f9a37d487e1019fd4d8113adb2f9f] - - conda-forge/linux-64::libssh2==1.10.0=hf14f497_3[md5=d85acad4b47dff4e3def14a769a97906] - - conda-forge/linux-64::libxml2==2.10.3=hfdac1af_6[md5=7eecaadc2eaeef464c5fe17702f17c86] - - conda-forge/linux-64::readline==8.2=h8228510_1[md5=47d31b792659ce70f470b5c82fdfb7a4] - - conda-forge/linux-64::reproc-cpp==14.2.4=hcb278e6_0[md5=ede8e0f849f2fee2f78cb488b4ea3b33] - - conda-forge/linux-64::tk==8.6.12=h27826a3_0[md5=5b8c42eb62e9fc961af70bdd6a26e168] - - conda-forge/linux-64::zstd==1.5.2=h3eb15da_6[md5=6b63daed8feeca47be78f323e793d555] - - conda-forge/linux-64::krb5==1.20.1=h81ceb04_0[md5=89a41adce7106749573d883b2f657d78] - - conda-forge/linux-64::libarchive==3.6.2=h3d51595_0[md5=9f915b4adeb9dcfd450b9ad238e2db4c] - - conda-forge/linux-64::python==3.10.10=he550d4f_0_cpython[md5=de25afc7041c103c7f510c746bb63435] - - conda-forge/noarch::certifi==2022.12.7=pyhd8ed1ab_0[md5=fb9addc3db06e56abe03e0e9f21a63e6] - - conda-forge/noarch::charset-normalizer==3.1.0=pyhd8ed1ab_0[md5=7fcff9f6f123696e940bda77bd4d6551] - - conda-forge/noarch::colorama==0.4.6=pyhd8ed1ab_0[md5=3faab06a954c2a04039983f2c4a50d99] - - conda-forge/noarch::idna==3.4=pyhd8ed1ab_0[md5=34272b248891bddccc64479f9a7fffed] - - conda-forge/linux-64::libcurl==7.88.1=hdc1c0ab_1[md5=3d1189864d1c0ed2a5919cb067b5903d] - - - conda-forge/noarch::pluggy==1.0.0=pyhd8ed1ab_5[md5=7d301a0d25f424d96175f810935f0da9] - - conda-forge/linux-64::pycosat==0.6.4=py310h5764c6d_1[md5=0e565d732f6660374b45d76761c09b06] - - conda-forge/noarch::pycparser==2.21=pyhd8ed1ab_0[md5=076becd9e05608f8dc72757d5f3a91ff] - - conda-forge/noarch::pysocks==1.7.1=pyha2e5f31_6[md5=2a7de29fb590ca14b5243c4c812c8025] - - conda-forge/linux-64::ruamel.yaml.clib==0.2.7=py310h1fa729e_1[md5=2f9b517412af46255cef5e53a22c264e] - - conda-forge/noarch::setuptools==65.6.3=pyhd8ed1ab_0[md5=9600fc9524d3f821e6a6d58c52f5bf5a] - - conda-forge/noarch::toolz==0.12.0=pyhd8ed1ab_0[md5=92facfec94bc02d6ccf42e7173831a36] - - conda-forge/noarch::wheel==0.40.0=pyhd8ed1ab_0[md5=49bb0d9e60ce1db25e151780331bb5f3] - - conda-forge/linux-64::cffi==1.15.1=py310h255011f_3[md5=800596144bb613cd7ac58b80900ce835] - - conda-forge/linux-64::libmamba==1.4.1=hcea66bb_0[md5=e512a4c95ff1eca1684642fa32bd2f55] - - conda-forge/noarch::pip==23.0.1=pyhd8ed1ab_0[md5=8025ca83b8ba5430b640b83917c2a6f7] - - conda-forge/linux-64::ruamel.yaml==0.17.21=py310h1fa729e_3[md5=97204ae92b703d74a983db0e6d07d009] - - conda-forge/noarch::tqdm==4.65.0=pyhd8ed1ab_1[md5=ed792aff3acb977d09c7013358097f83] - - conda-forge/linux-64::brotlipy==0.7.0=py310h5764c6d_1005[md5=87669c3468dff637bbd0363bc0f895cf] - - conda-forge/linux-64::cryptography==40.0.1=py310h34c0648_0[md5=deafd9206c2e307874f3777a33cafb79] - - conda-forge/linux-64::libmambapy==1.4.1=py310h1428755_0[md5=323e09e9947b6a415f9d73562e4ca862] - - conda-forge/linux-64::zstandard==0.19.0=py310hdeb6495_1[md5=2cce1a48e6687f64d371d2e7fc9c7fbf] - - conda-forge/noarch::conda-package-streaming==0.7.0=pyhd8ed1ab_1[md5=1a2fa9e53cfbc2e4d9ab21990805a436] - - conda-forge/noarch::pyopenssl==23.1.1=pyhd8ed1ab_0[md5=0b34aa3ab7e7ccb1765a03dd9ed29938] - - conda-forge/noarch::conda-package-handling==2.0.2=pyh38be061_0[md5=44800e9bd13143292097c65e57323038] - - conda-forge/noarch::urllib3==1.26.15=pyhd8ed1ab_0[md5=27db656619a55d727eaf5a6ece3d2fd6] - - conda-forge/noarch::requests==2.28.2=pyhd8ed1ab_1[md5=3bfbd6ead1d7299ed46dab3a7bf0bc8c] - - conda-forge/linux-64::conda==23.1.0=py310hff52083_0[md5=c2f5cd14bf4a8cc673f66fd9839e6602] - - conda-forge/linux-64::mamba==1.4.1=py310h51d5547_0[md5=49170d6752d2326fe16dc2b6e74f9e54] - - - - Package Version Build Channel Size -─────────────────────────────────────────────────────────────────────────────────────── - Install: -─────────────────────────────────────────────────────────────────────────────────────── - - + _libgcc_mutex 0.1 conda_forge conda-forge Cached - + _openmp_mutex 4.5 2_gnu conda-forge Cached - + brotlipy 0.7.0 py310h5764c6d_1005 conda-forge Cached - + bzip2 1.0.8 h7f98852_4 conda-forge Cached - + c-ares 1.18.1 h7f98852_0 conda-forge Cached - + ca-certificates 2022.12.7 ha878542_0 conda-forge Cached - + certifi 2022.12.7 pyhd8ed1ab_0 conda-forge Cached - + cffi 1.15.1 py310h255011f_3 conda-forge Cached - + charset-normalizer 3.1.0 pyhd8ed1ab_0 conda-forge Cached - + colorama 0.4.6 pyhd8ed1ab_0 conda-forge Cached - + conda 23.1.0 py310hff52083_0 conda-forge Cached - + conda-package-handling 2.0.2 pyh38be061_0 conda-forge Cached - + conda-package-streaming 0.7.0 pyhd8ed1ab_1 conda-forge Cached - + cryptography 40.0.1 py310h34c0648_0 conda-forge Cached - + fmt 9.1.0 h924138e_0 conda-forge Cached - + icu 72.1 hcb278e6_0 conda-forge Cached - + idna 3.4 pyhd8ed1ab_0 conda-forge Cached - + keyutils 1.6.1 h166bdaf_0 conda-forge Cached - + krb5 1.20.1 h81ceb04_0 conda-forge Cached - + ld_impl_linux-64 2.40 h41732ed_0 conda-forge Cached - + libarchive 3.6.2 h3d51595_0 conda-forge Cached - + libcurl 7.88.1 hdc1c0ab_1 conda-forge Cached - + libedit 3.1.20191231 he28a2e2_2 conda-forge Cached - + libev 4.33 h516909a_1 conda-forge Cached - + libffi 3.4.2 h7f98852_5 conda-forge Cached - + libgcc-ng 12.2.0 h65d4601_19 conda-forge Cached - + libgomp 12.2.0 h65d4601_19 conda-forge Cached - + libiconv 1.17 h166bdaf_0 conda-forge Cached - + libmamba 1.4.1 hcea66bb_0 conda-forge Cached - + libmambapy 1.4.1 py310h1428755_0 conda-forge Cached - + libnghttp2 1.52.0 h61bc06f_0 conda-forge Cached - + libnsl 2.0.0 h7f98852_0 conda-forge Cached - + libsolv 0.7.23 h3eb15da_0 conda-forge Cached - + libsqlite 3.40.0 h753d276_0 conda-forge Cached - + libssh2 1.10.0 hf14f497_3 conda-forge Cached - + libstdcxx-ng 12.2.0 h46fd767_19 conda-forge Cached - + libuuid 2.38.1 h0b41bf4_0 conda-forge Cached - + libxml2 2.10.3 hfdac1af_6 conda-forge Cached - + libzlib 1.2.13 h166bdaf_4 conda-forge Cached - + lz4-c 1.9.4 hcb278e6_0 conda-forge Cached - + lzo 2.10 h516909a_1000 conda-forge Cached - + mamba 1.4.1 py310h51d5547_0 conda-forge Cached - + ncurses 6.3 h27087fc_1 conda-forge Cached - + openssl 3.1.0 h0b41bf4_0 conda-forge Cached - + pip 23.0.1 pyhd8ed1ab_0 conda-forge Cached - + pluggy 1.0.0 pyhd8ed1ab_5 conda-forge Cached - + pybind11-abi 4 hd8ed1ab_3 conda-forge Cached - + pycosat 0.6.4 py310h5764c6d_1 conda-forge Cached - + pycparser 2.21 pyhd8ed1ab_0 conda-forge Cached - + pyopenssl 23.1.1 pyhd8ed1ab_0 conda-forge Cached - + pysocks 1.7.1 pyha2e5f31_6 conda-forge Cached - + python 3.10.10 he550d4f_0_cpython conda-forge Cached - + python_abi 3.10 3_cp310 conda-forge Cached - + readline 8.2 h8228510_1 conda-forge Cached - + reproc 14.2.4 h0b41bf4_0 conda-forge Cached - + reproc-cpp 14.2.4 hcb278e6_0 conda-forge Cached - + requests 2.28.2 pyhd8ed1ab_1 conda-forge Cached - + ruamel.yaml 0.17.21 py310h1fa729e_3 conda-forge Cached - + ruamel.yaml.clib 0.2.7 py310h1fa729e_1 conda-forge Cached - + setuptools 65.6.3 pyhd8ed1ab_0 conda-forge Cached - + tk 8.6.12 h27826a3_0 conda-forge Cached - + toolz 0.12.0 pyhd8ed1ab_0 conda-forge Cached - + tqdm 4.65.0 pyhd8ed1ab_1 conda-forge Cached - + tzdata 2023c h71feb2d_0 conda-forge Cached - + urllib3 1.26.15 pyhd8ed1ab_0 conda-forge Cached - + wheel 0.40.0 pyhd8ed1ab_0 conda-forge Cached - + xz 5.2.6 h166bdaf_0 conda-forge Cached - + yaml-cpp 0.7.0 h27087fc_2 conda-forge Cached - + zstandard 0.19.0 py310hdeb6495_1 conda-forge Cached - + zstd 1.5.2 h3eb15da_6 conda-forge Cached - - Summary: - - Install: 70 packages - - Total download: 0 B - -─────────────────────────────────────────────────────────────────────────────────────── - - - - -Transaction starting - -Linking _libgcc_mutex-0.1-conda_forge - -Linking ca-certificates-2022.12.7-ha878542_0 - -Linking ld_impl_linux-64-2.40-h41732ed_0 - -Linking libstdcxx-ng-12.2.0-h46fd767_19 - -Linking pybind11-abi-4-hd8ed1ab_3 - -Linking python_abi-3.10-3_cp310 - -Linking tzdata-2023c-h71feb2d_0 - -Linking libgomp-12.2.0-h65d4601_19 - -Linking _openmp_mutex-4.5-2_gnu - -Linking libgcc-ng-12.2.0-h65d4601_19 - -Linking bzip2-1.0.8-h7f98852_4 - -Linking c-ares-1.18.1-h7f98852_0 - -Linking fmt-9.1.0-h924138e_0 - -Linking icu-72.1-hcb278e6_0 - -Linking keyutils-1.6.1-h166bdaf_0 - -Linking libev-4.33-h516909a_1 - -Linking libffi-3.4.2-h7f98852_5 - -Linking libiconv-1.17-h166bdaf_0 - -Linking libnsl-2.0.0-h7f98852_0 - -Linking libuuid-2.38.1-h0b41bf4_0 - -Linking libzlib-1.2.13-h166bdaf_4 - -Linking lz4-c-1.9.4-hcb278e6_0 - -Linking lzo-2.10-h516909a_1000 - -Linking ncurses-6.3-h27087fc_1 - -Linking openssl-3.1.0-h0b41bf4_0 - -Linking reproc-14.2.4-h0b41bf4_0 - -Linking xz-5.2.6-h166bdaf_0 - -Linking yaml-cpp-0.7.0-h27087fc_2 - -Linking libedit-3.1.20191231-he28a2e2_2 - -Linking libnghttp2-1.52.0-h61bc06f_0 - -Linking libsolv-0.7.23-h3eb15da_0 - -Linking libsqlite-3.40.0-h753d276_0 - -Linking libssh2-1.10.0-hf14f497_3 - -Linking libxml2-2.10.3-hfdac1af_6 - -Linking readline-8.2-h8228510_1 - -Linking reproc-cpp-14.2.4-hcb278e6_0 - -Linking tk-8.6.12-h27826a3_0 - -Linking zstd-1.5.2-h3eb15da_6 - -Linking krb5-1.20.1-h81ceb04_0 - -Linking libarchive-3.6.2-h3d51595_0 - -Linking python-3.10.10-he550d4f_0_cpython - -Linking certifi-2022.12.7-pyhd8ed1ab_0 - -Linking charset-normalizer-3.1.0-pyhd8ed1ab_0 - -Linking colorama-0.4.6-pyhd8ed1ab_0 - -Linking idna-3.4-pyhd8ed1ab_0 - -Linking libcurl-7.88.1-hdc1c0ab_1 - -Linking pluggy-1.0.0-pyhd8ed1ab_5 - -Linking pycosat-0.6.4-py310h5764c6d_1 - -Linking pycparser-2.21-pyhd8ed1ab_0 - -Linking pysocks-1.7.1-pyha2e5f31_6 - -Linking ruamel.yaml.clib-0.2.7-py310h1fa729e_1 - -Linking setuptools-65.6.3-pyhd8ed1ab_0 - -Linking toolz-0.12.0-pyhd8ed1ab_0 - -Linking wheel-0.40.0-pyhd8ed1ab_0 - -Linking cffi-1.15.1-py310h255011f_3 - -Linking libmamba-1.4.1-hcea66bb_0 - -Linking pip-23.0.1-pyhd8ed1ab_0 - -Linking ruamel.yaml-0.17.21-py310h1fa729e_3 - -Linking tqdm-4.65.0-pyhd8ed1ab_1 - -Linking brotlipy-0.7.0-py310h5764c6d_1005 - -Linking cryptography-40.0.1-py310h34c0648_0 - -Linking libmambapy-1.4.1-py310h1428755_0 - -Linking zstandard-0.19.0-py310hdeb6495_1 - -Linking conda-package-streaming-0.7.0-pyhd8ed1ab_1 - -Linking pyopenssl-23.1.1-pyhd8ed1ab_0 - -Linking conda-package-handling-2.0.2-pyh38be061_0 - -Linking urllib3-1.26.15-pyhd8ed1ab_0 - -Linking requests-2.28.2-pyhd8ed1ab_1 - -Linking conda-23.1.0-py310hff52083_0 - -Linking mamba-1.4.1-py310h51d5547_0 - -Transaction finished - -installation finished. - -WARNING: - You currently have a PYTHONPATH environment variable set. This may cause - - unexpected behavior when running the Python interpreter in Mambaforge. - For best results, please verify that your PYTHONPATH only points to - directories of packages that are compatible with the Python interpreter - in Mambaforge: /root/mambaforge - - ---> 7741d9d31977 - -Step 4/14 : copy environment.yaml /root/environment.yaml - - -COPY failed: file not found in build context or excluded by .dockerignore: stat environment.yaml: file does not exist diff --git a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-46aaed/docker-build-logs.txt b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-46aaed/docker-build-logs.txt deleted file mode 100644 index 1e3ee461..00000000 --- a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-46aaed/docker-build-logs.txt +++ /dev/null @@ -1,757 +0,0 @@ -Step 1/16 : from 812206152185.dkr.ecr.us-west-2.amazonaws.com/latch-base:1393-kenny--snakemake - - - ---> cf4e007bf7d3 - -Step 2/16 : run mkdir /opt/latch - - - ---> Using cache - - ---> afed690b224b - -Step 3/16 : RUN curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh && mkdir /root/.conda && bash Mambaforge-Linux-x86_64.sh -b && rm -f Mambaforge-Linux-x86_64.sh - - - ---> Using cache - - ---> 6505a24fc87d - -Step 4/16 : copy environment.yaml /root/environment.yaml - - - ---> Using cache - - ---> 2c2042a80716 - -Step 5/16 : run /root/mambaforge/bin/mamba env create --name snakemake-tutorial --file environment.yaml - - - ---> Using cache - - ---> 3c11703ad114 - -Step 6/16 : env PATH /root/mambaforge/envs/snakemake-tutorial/bin:$PATH - - - ---> Using cache - - ---> 48b5620a8619 - -Step 7/16 : copy latch /root/latch - - - ---> ffdf315ee81e - -Step 8/16 : run cd /root/latch && python3 -m pip install -e . - - - ---> Running in d53ee957c71f - -Obtaining file:///root/latch - - Installing build dependencies: started - - Installing build dependencies: finished with status 'done' - - Checking if build backend supports build_editable: started - - Checking if build backend supports build_editable: finished with status 'done' - - Getting requirements to build editable: started - - Getting requirements to build editable: finished with status 'done' - - Preparing editable metadata (pyproject.toml): started - - Preparing editable metadata (pyproject.toml): finished with status 'done' - -Collecting asyncssh==2.12.0 (from latch==2.19.11) - - Downloading asyncssh-2.12.0-py3-none-any.whl (346 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 346.7/346.7 kB 9.5 MB/s eta 0:00:00 - -Collecting aioconsole==0.5.1 (from latch==2.19.11) - - Downloading aioconsole-0.5.1-py3-none-any.whl (30 kB) - -Collecting kubernetes>=24.2.0 (from latch==2.19.11) - - Downloading kubernetes-26.1.0-py2.py3-none-any.whl (1.4 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.4/1.4 MB 50.5 MB/s eta 0:00:00 - - -Collecting pyjwt>=0.2.0 (from latch==2.19.11) - - Downloading PyJWT-2.7.0-py3-none-any.whl (22 kB) - -Requirement already satisfied: requests>=2.28.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from latch==2.19.11) (2.29.0) - -Collecting click>=8.0 (from latch==2.19.11) - - Downloading click-8.1.3-py3-none-any.whl (96 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 96.6/96.6 kB 14.1 MB/s eta 0:00:00 - - -Collecting docker>=5.0 (from latch==2.19.11) - - Downloading docker-6.1.2-py3-none-any.whl (148 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 148.1/148.1 kB 18.9 MB/s eta 0:00:00 - - -Collecting paramiko>=2.11.0 (from latch==2.19.11) - - Downloading paramiko-3.1.0-py3-none-any.whl (211 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 211.2/211.2 kB 26.1 MB/s eta 0:00:00 - - -Collecting scp>=0.14.0 (from latch==2.19.11) - - Downloading scp-0.14.5-py2.py3-none-any.whl (8.7 kB) - -Collecting boto3>=1.24.22 (from latch==2.19.11) - - Using cached boto3-1.26.137-py3-none-any.whl (135 kB) - -Collecting tqdm>=4.63.0 (from latch==2.19.11) - - Downloading tqdm-4.65.0-py3-none-any.whl (77 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 77.1/77.1 kB 11.5 MB/s eta 0:00:00 - - -Collecting lytekit==0.14.10 (from latch==2.19.11) - - Downloading lytekit-0.14.10-py3-none-any.whl (391 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 391.8/391.8 kB 41.2 MB/s eta 0:00:00 - - -Collecting lytekitplugins-pods==0.4.0 (from latch==2.19.11) - - Downloading lytekitplugins_pods-0.4.0-py3-none-any.whl (4.3 kB) - -Requirement already satisfied: typing-extensions==4.5.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from latch==2.19.11) (4.5.0) - -Collecting apscheduler==3.9.1 (from latch==2.19.11) - - Downloading APScheduler-3.9.1-py2.py3-none-any.whl (59 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 59.5/59.5 kB 8.7 MB/s eta 0:00:00 - - -Collecting uvloop==0.17.0 (from latch==2.19.11) - - Downloading uvloop-0.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.1 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.1/4.1 MB 81.6 MB/s eta 0:00:00 - - -Collecting websockets==10.3 (from latch==2.19.11) - - Downloading websockets-10.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (111 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 111.5/111.5 kB 15.6 MB/s eta 0:00:00 - - -Collecting prompt-toolkit==3.0.33 (from latch==2.19.11) - - Downloading prompt_toolkit-3.0.33-py3-none-any.whl (383 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 383.6/383.6 kB 39.2 MB/s eta 0:00:00 - - -Collecting watchfiles==0.18.1 (from latch==2.19.11) - - Downloading watchfiles-0.18.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.2 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.2/1.2 MB 67.6 MB/s eta 0:00:00 - - -Collecting gql==3.4.0 (from latch==2.19.11) - - Downloading gql-3.4.0-py2.py3-none-any.whl (65 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 65.2/65.2 kB 9.4 MB/s eta 0:00:00 - - -Collecting graphql-core==3.2.3 (from latch==2.19.11) - - Downloading graphql_core-3.2.3-py3-none-any.whl (202 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 202.9/202.9 kB 27.8 MB/s eta 0:00:00 - - -Collecting requests-toolbelt==0.10.1 (from latch==2.19.11) - - Downloading requests_toolbelt-0.10.1-py2.py3-none-any.whl (54 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 54.5/54.5 kB 8.8 MB/s eta 0:00:00 - - -Requirement already satisfied: snakemake>=7.25.4 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from latch==2.19.11) (7.25.4) - -Requirement already satisfied: setuptools>=0.7 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from apscheduler==3.9.1->latch==2.19.11) (67.7.2) - -Requirement already satisfied: six>=1.4.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from apscheduler==3.9.1->latch==2.19.11) (1.16.0) - -Collecting pytz (from apscheduler==3.9.1->latch==2.19.11) - - Downloading pytz-2023.3-py2.py3-none-any.whl (502 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 502.3/502.3 kB 48.1 MB/s eta 0:00:00 - - -Collecting tzlocal!=3.*,>=2.0 (from apscheduler==3.9.1->latch==2.19.11) - - Downloading tzlocal-5.0.1-py3-none-any.whl (20 kB) - -Requirement already satisfied: cryptography>=3.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from asyncssh==2.12.0->latch==2.19.11) (39.0.0) - -Collecting yarl<2.0,>=1.6 (from gql==3.4.0->latch==2.19.11) - - Downloading yarl-1.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (268 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 268.8/268.8 kB 31.5 MB/s eta 0:00:00 - - -Collecting backoff<3.0,>=1.11.1 (from gql==3.4.0->latch==2.19.11) - - Downloading backoff-2.2.1-py3-none-any.whl (15 kB) - -Collecting lyteidl==0.2.0a0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading lyteidl-0.2.0a0-py3-none-any.whl (162 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 162.2/162.2 kB 22.9 MB/s eta 0:00:00 - - -Requirement already satisfied: wheel<1.0.0,>=0.30.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (0.40.0) - -Collecting pandas<2.0.0,>=1.0.0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading pandas-1.5.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (12.1 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 12.1/12.1 MB 67.0 MB/s eta 0:00:00 - - -Collecting pyarrow<7.0.0,>=4.0.0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading pyarrow-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (25.6 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 25.6/25.6 MB 47.4 MB/s eta 0:00:00 - - -Collecting croniter<4.0.0,>=0.3.20 (from lytekit==0.14.10->latch==2.19.11) - - Downloading croniter-1.3.14-py2.py3-none-any.whl (18 kB) - -Collecting deprecated<2.0,>=1.0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading Deprecated-1.2.13-py2.py3-none-any.whl (9.6 kB) - -Collecting docker>=5.0 (from latch==2.19.11) - - Downloading docker-5.0.3-py2.py3-none-any.whl (146 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 146.2/146.2 kB 20.6 MB/s eta 0:00:00 - - -Requirement already satisfied: python-dateutil>=2.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (2.8.2) - -Collecting grpcio!=1.45.0,<2.0,>=1.43.0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading grpcio-1.54.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.1 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 5.1/5.1 MB 73.0 MB/s eta 0:00:00 - - -Collecting grpcio-status!=1.45.0,>=1.43 (from lytekit==0.14.10->latch==2.19.11) - - Downloading grpcio_status-1.54.2-py3-none-any.whl (5.1 kB) - -Collecting protobuf<4,>=3.6.1 (from lytekit==0.14.10->latch==2.19.11) - - Downloading protobuf-3.20.3-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (1.1 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.1/1.1 MB 63.5 MB/s eta 0:00:00 - - -Collecting python-json-logger>=2.0.0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading python_json_logger-2.0.7-py3-none-any.whl (8.1 kB) - -Collecting pytimeparse<2.0.0,>=1.1.8 (from lytekit==0.14.10->latch==2.19.11) - - Downloading pytimeparse-1.1.8-py2.py3-none-any.whl (10.0 kB) - -Requirement already satisfied: pyyaml in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (6.0) - -Collecting keyring>=18.0.1 (from lytekit==0.14.10->latch==2.19.11) - - Downloading keyring-23.13.1-py3-none-any.whl (37 kB) - -Collecting responses>=0.10.7 (from lytekit==0.14.10->latch==2.19.11) - - Downloading responses-0.23.1-py3-none-any.whl (52 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 52.1/52.1 kB 7.5 MB/s eta 0:00:00 - - -Collecting sortedcontainers<3.0.0,>=1.5.9 (from lytekit==0.14.10->latch==2.19.11) - - Downloading sortedcontainers-2.4.0-py2.py3-none-any.whl (29 kB) - -Collecting statsd<4.0.0,>=3.0.0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading statsd-3.3.0-py2.py3-none-any.whl (11 kB) - -Requirement already satisfied: urllib3<2.0.0,>=1.22 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (1.26.15) - -Requirement already satisfied: wrapt<2.0.0,>=1.0.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (1.15.0) - -Collecting retry==0.9.2 (from lytekit==0.14.10->latch==2.19.11) - - Downloading retry-0.9.2-py2.py3-none-any.whl (8.0 kB) - -Collecting dataclasses-json>=0.5.2 (from lytekit==0.14.10->latch==2.19.11) - - Downloading dataclasses_json-0.5.7-py3-none-any.whl (25 kB) - -Requirement already satisfied: jsonschema>=4.5.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (4.17.3) - -Collecting marshmallow-jsonschema>=0.12.0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading marshmallow_jsonschema-0.13.0-py3-none-any.whl (11 kB) - -Collecting natsort>=7.0.1 (from lytekit==0.14.10->latch==2.19.11) - - Downloading natsort-8.3.1-py3-none-any.whl (38 kB) - -Collecting docker-image-py>=0.1.10 (from lytekit==0.14.10->latch==2.19.11) - - Downloading docker-image-py-0.1.12.tar.gz (8.2 kB) - - Preparing metadata (setup.py): started - - Preparing metadata (setup.py): finished with status 'done' - -Collecting docstring-parser>=0.9.0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading docstring_parser-0.15-py3-none-any.whl (36 kB) - -Collecting diskcache>=5.2.1 (from lytekit==0.14.10->latch==2.19.11) - - Downloading diskcache-5.6.1-py3-none-any.whl (45 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 45.6/45.6 kB 6.7 MB/s eta 0:00:00 - - -Collecting cloudpickle>=2.0.0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading cloudpickle-2.2.1-py3-none-any.whl (25 kB) - -Collecting cookiecutter>=1.7.3 (from lytekit==0.14.10->latch==2.19.11) - - Downloading cookiecutter-2.1.1-py2.py3-none-any.whl (36 kB) - -Collecting numpy<1.22.0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading numpy-1.21.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (15.9 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 15.9/15.9 MB 63.6 MB/s eta 0:00:00 - - -Collecting wcwidth (from prompt-toolkit==3.0.33->latch==2.19.11) - - Downloading wcwidth-0.2.6-py2.py3-none-any.whl (29 kB) - -Collecting anyio>=3.0.0 (from watchfiles==0.18.1->latch==2.19.11) - - Downloading anyio-3.6.2-py3-none-any.whl (80 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 80.6/80.6 kB 11.5 MB/s eta 0:00:00 - - -Collecting googleapis-common-protos (from lyteidl==0.2.0a0->lytekit==0.14.10->latch==2.19.11) - - Downloading googleapis_common_protos-1.59.0-py2.py3-none-any.whl (223 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 223.6/223.6 kB 28.2 MB/s eta 0:00:00 - - -Collecting protoc-gen-swagger (from lyteidl==0.2.0a0->lytekit==0.14.10->latch==2.19.11) - - Downloading protoc_gen_swagger-0.1.0-py2.py3-none-any.whl (9.4 kB) - -Collecting decorator>=3.4.2 (from retry==0.9.2->lytekit==0.14.10->latch==2.19.11) - - Downloading decorator-5.1.1-py3-none-any.whl (9.1 kB) - -Collecting py<2.0.0,>=1.4.26 (from retry==0.9.2->lytekit==0.14.10->latch==2.19.11) - - Downloading py-1.11.0-py2.py3-none-any.whl (98 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 98.7/98.7 kB 13.5 MB/s eta 0:00:00 - - -Collecting botocore<1.30.0,>=1.29.137 (from boto3>=1.24.22->latch==2.19.11) - - Using cached botocore-1.29.137-py3-none-any.whl (10.8 MB) - -Collecting jmespath<2.0.0,>=0.7.1 (from boto3>=1.24.22->latch==2.19.11) - - Using cached jmespath-1.0.1-py3-none-any.whl (20 kB) - -Collecting s3transfer<0.7.0,>=0.6.0 (from boto3>=1.24.22->latch==2.19.11) - - Using cached s3transfer-0.6.1-py3-none-any.whl (79 kB) - -Collecting websocket-client>=0.32.0 (from docker>=5.0->latch==2.19.11) - - Downloading websocket_client-1.5.2-py3-none-any.whl (56 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 56.6/56.6 kB 8.5 MB/s eta 0:00:00 - - -Requirement already satisfied: certifi>=14.05.14 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from kubernetes>=24.2.0->latch==2.19.11) (2023.5.7) - -Collecting google-auth>=1.0.1 (from kubernetes>=24.2.0->latch==2.19.11) - - Downloading google_auth-2.18.1-py2.py3-none-any.whl (178 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 178.9/178.9 kB 24.4 MB/s eta 0:00:00 - - -Collecting requests-oauthlib (from kubernetes>=24.2.0->latch==2.19.11) - - Downloading requests_oauthlib-1.3.1-py2.py3-none-any.whl (23 kB) - -Collecting bcrypt>=3.2 (from paramiko>=2.11.0->latch==2.19.11) - - Downloading bcrypt-4.0.1-cp36-abi3-manylinux_2_28_x86_64.whl (593 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 593.7/593.7 kB 50.9 MB/s eta 0:00:00 - - -Collecting pynacl>=1.5 (from paramiko>=2.11.0->latch==2.19.11) - - Downloading PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl (856 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 856.7/856.7 kB 60.3 MB/s eta 0:00:00 - - -Requirement already satisfied: charset-normalizer<4,>=2 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from requests>=2.28.1->latch==2.19.11) (3.1.0) - -Requirement already satisfied: idna<4,>=2.5 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from requests>=2.28.1->latch==2.19.11) (3.4) - -Requirement already satisfied: appdirs in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.4.4) - -Requirement already satisfied: configargparse in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.5.3) - -Requirement already satisfied: connection-pool>=0.0.3 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (0.0.3) - -Requirement already satisfied: datrie in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (0.8.2) - -Requirement already satisfied: docutils in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (0.20.1) - -Requirement already satisfied: gitpython in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (3.1.31) - -Requirement already satisfied: humanfriendly in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (10.0) - -Requirement already satisfied: jinja2<4.0,>=3.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (3.1.2) - -Requirement already satisfied: nbformat in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (5.8.0) - -Requirement already satisfied: psutil in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (5.9.5) - -Requirement already satisfied: pulp>=2.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (2.7.0) - -Requirement already satisfied: reretry in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (0.11.8) - -Requirement already satisfied: smart-open>=3.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (6.3.0) - -Requirement already satisfied: stopit in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.1.2) - -Requirement already satisfied: tabulate in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (0.9.0) - -Requirement already satisfied: throttler in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.2.1) - -Requirement already satisfied: toposort>=1.10 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.10) - -Requirement already satisfied: yte<2.0,>=1.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.5.1) - -Collecting sniffio>=1.1 (from anyio>=3.0.0->watchfiles==0.18.1->latch==2.19.11) - - Downloading sniffio-1.3.0-py3-none-any.whl (10 kB) - -Collecting binaryornot>=0.4.4 (from cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) - - Downloading binaryornot-0.4.4-py2.py3-none-any.whl (9.0 kB) - -Collecting jinja2-time>=0.2.0 (from cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) - - Downloading jinja2_time-0.2.0-py2.py3-none-any.whl (6.4 kB) - -Collecting python-slugify>=4.0.0 (from cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) - - Downloading python_slugify-8.0.1-py2.py3-none-any.whl (9.7 kB) - -Requirement already satisfied: cffi>=1.12 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from cryptography>=3.1->asyncssh==2.12.0->latch==2.19.11) (1.15.1) - -Collecting marshmallow<4.0.0,>=3.3.0 (from dataclasses-json>=0.5.2->lytekit==0.14.10->latch==2.19.11) - - Downloading marshmallow-3.19.0-py3-none-any.whl (49 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 49.1/49.1 kB 7.4 MB/s eta 0:00:00 - - -Collecting marshmallow-enum<2.0.0,>=1.5.1 (from dataclasses-json>=0.5.2->lytekit==0.14.10->latch==2.19.11) - - Downloading marshmallow_enum-1.5.1-py2.py3-none-any.whl (4.2 kB) - -Collecting typing-inspect>=0.4.0 (from dataclasses-json>=0.5.2->lytekit==0.14.10->latch==2.19.11) - - Downloading typing_inspect-0.8.0-py3-none-any.whl (8.7 kB) - -Collecting regex>=2019.4.14 (from docker-image-py>=0.1.10->lytekit==0.14.10->latch==2.19.11) - - Downloading regex-2023.5.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (769 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 769.7/769.7 kB 56.4 MB/s eta 0:00:00 - - -Collecting cachetools<6.0,>=2.0.0 (from google-auth>=1.0.1->kubernetes>=24.2.0->latch==2.19.11) - - Downloading cachetools-5.3.0-py3-none-any.whl (9.3 kB) - -Collecting pyasn1-modules>=0.2.1 (from google-auth>=1.0.1->kubernetes>=24.2.0->latch==2.19.11) - - Downloading pyasn1_modules-0.3.0-py2.py3-none-any.whl (181 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 181.3/181.3 kB 24.9 MB/s eta 0:00:00 - - -Collecting rsa<5,>=3.1.4 (from google-auth>=1.0.1->kubernetes>=24.2.0->latch==2.19.11) - - Downloading rsa-4.9-py3-none-any.whl (34 kB) - -INFO: pip is looking at multiple versions of grpcio-status to determine which version is compatible with other requirements. This could take a while. - -Collecting grpcio-status!=1.45.0,>=1.43 (from lytekit==0.14.10->latch==2.19.11) - - Downloading grpcio_status-1.54.0-py3-none-any.whl (5.1 kB) - - Downloading grpcio_status-1.53.1-py3-none-any.whl (5.1 kB) - - Downloading grpcio_status-1.53.0-py3-none-any.whl (5.1 kB) - - Downloading grpcio_status-1.51.3-py3-none-any.whl (5.1 kB) - - Downloading grpcio_status-1.51.1-py3-none-any.whl (5.1 kB) - - Downloading grpcio_status-1.50.0-py3-none-any.whl (14 kB) - - Downloading grpcio_status-1.49.1-py3-none-any.whl (14 kB) - -INFO: pip is looking at multiple versions of grpcio-status to determine which version is compatible with other requirements. This could take a while. - - Downloading grpcio_status-1.48.2-py3-none-any.whl (14 kB) - -Requirement already satisfied: MarkupSafe>=2.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from jinja2<4.0,>=3.0->snakemake>=7.25.4->latch==2.19.11) (2.1.2) - -Requirement already satisfied: attrs>=17.4.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from jsonschema>=4.5.1->lytekit==0.14.10->latch==2.19.11) (23.1.0) - -Requirement already satisfied: pyrsistent!=0.17.0,!=0.17.1,!=0.17.2,>=0.14.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from jsonschema>=4.5.1->lytekit==0.14.10->latch==2.19.11) (0.19.3) - -Collecting jaraco.classes (from keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) - - Downloading jaraco.classes-3.2.3-py3-none-any.whl (6.0 kB) - -Requirement already satisfied: importlib-metadata>=4.11.4 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) (6.6.0) - -Collecting SecretStorage>=3.2 (from keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) - - Downloading SecretStorage-3.3.3-py3-none-any.whl (15 kB) - -Collecting jeepney>=0.4.2 (from keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) - - Downloading jeepney-0.8.0-py3-none-any.whl (48 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 48.4/48.4 kB 7.8 MB/s eta 0:00:00 - - -Collecting types-PyYAML (from responses>=0.10.7->lytekit==0.14.10->latch==2.19.11) - - Downloading types_PyYAML-6.0.12.9-py3-none-any.whl (14 kB) - -Collecting multidict>=4.0 (from yarl<2.0,>=1.6->gql==3.4.0->latch==2.19.11) - - Downloading multidict-6.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (114 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 114.5/114.5 kB 15.4 MB/s eta 0:00:00 - - -Requirement already satisfied: dpath<3.0,>=2.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from yte<2.0,>=1.0->snakemake>=7.25.4->latch==2.19.11) (2.1.6) - -Requirement already satisfied: plac<2.0.0,>=1.3.4 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from yte<2.0,>=1.0->snakemake>=7.25.4->latch==2.19.11) (1.3.5) - -Requirement already satisfied: gitdb<5,>=4.0.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from gitpython->snakemake>=7.25.4->latch==2.19.11) (4.0.10) - -Requirement already satisfied: fastjsonschema in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from nbformat->snakemake>=7.25.4->latch==2.19.11) (2.16.3) - -Requirement already satisfied: jupyter-core in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from nbformat->snakemake>=7.25.4->latch==2.19.11) (5.3.0) - -Requirement already satisfied: traitlets>=5.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from nbformat->snakemake>=7.25.4->latch==2.19.11) (5.9.0) - -Collecting oauthlib>=3.0.0 (from requests-oauthlib->kubernetes>=24.2.0->latch==2.19.11) - - Downloading oauthlib-3.2.2-py3-none-any.whl (151 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 151.7/151.7 kB 20.3 MB/s eta 0:00:00 - - -Collecting chardet>=3.0.2 (from binaryornot>=0.4.4->cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) - - Downloading chardet-5.1.0-py3-none-any.whl (199 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 199.1/199.1 kB 27.3 MB/s eta 0:00:00 - - -Requirement already satisfied: pycparser in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from cffi>=1.12->cryptography>=3.1->asyncssh==2.12.0->latch==2.19.11) (2.21) - -Requirement already satisfied: smmap<6,>=3.0.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from gitdb<5,>=4.0.1->gitpython->snakemake>=7.25.4->latch==2.19.11) (3.0.5) - -Requirement already satisfied: zipp>=0.5 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from importlib-metadata>=4.11.4->keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) (3.15.0) - -Collecting arrow (from jinja2-time>=0.2.0->cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) - - Downloading arrow-1.2.3-py3-none-any.whl (66 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 66.4/66.4 kB 9.6 MB/s eta 0:00:00 - - -Requirement already satisfied: packaging>=17.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from marshmallow<4.0.0,>=3.3.0->dataclasses-json>=0.5.2->lytekit==0.14.10->latch==2.19.11) (23.1) - -Collecting pyasn1<0.6.0,>=0.4.6 (from pyasn1-modules>=0.2.1->google-auth>=1.0.1->kubernetes>=24.2.0->latch==2.19.11) - - Using cached pyasn1-0.5.0-py2.py3-none-any.whl (83 kB) - -Collecting text-unidecode>=1.3 (from python-slugify>=4.0.0->cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) - - Downloading text_unidecode-1.3-py2.py3-none-any.whl (78 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 78.2/78.2 kB 11.0 MB/s eta 0:00:00 - - -Collecting mypy-extensions>=0.3.0 (from typing-inspect>=0.4.0->dataclasses-json>=0.5.2->lytekit==0.14.10->latch==2.19.11) - - Downloading mypy_extensions-1.0.0-py3-none-any.whl (4.7 kB) - -Collecting more-itertools (from jaraco.classes->keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) - - Downloading more_itertools-9.1.0-py3-none-any.whl (54 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 54.2/54.2 kB 8.2 MB/s eta 0:00:00 - - -Requirement already satisfied: platformdirs>=2.5 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from jupyter-core->nbformat->snakemake>=7.25.4->latch==2.19.11) (3.5.1) - -WARNING: The candidate selected for download or install is a yanked version: 'apscheduler' candidate (version 3.9.1 at https://files.pythonhosted.org/packages/e4/9f/c3937d4babe62504b874d4bf2c0d85aa69c7f59fa84cf6050f3b9dc5d83e/APScheduler-3.9.1-py2.py3-none-any.whl (from https://pypi.org/simple/apscheduler/) (requires-python:>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4)) -Reason for being yanked: Not compatible with Python 2.7 - -Building wheels for collected packages: latch, docker-image-py - - Building editable for latch (pyproject.toml): started - - Building editable for latch (pyproject.toml): finished with status 'done' - - Created wheel for latch: filename=latch-2.19.11-0.editable-py3-none-any.whl size=3728 sha256=6e5c6944ce29c7a23983c6b112f2a456fe4624db742ee953550c0a9a217fde91 - - Stored in directory: /tmp/pip-ephem-wheel-cache-5_26ion1/wheels/66/25/3a/f25ede02a4206d090762dd0ca4dbdc81da4d61e154ed692990 - - Building wheel for docker-image-py (setup.py): started - - Building wheel for docker-image-py (setup.py): finished with status 'done' - - Created wheel for docker-image-py: filename=docker_image_py-0.1.12-py3-none-any.whl size=8812 sha256=22b7f08420622d740b9ecca0b8dd40a71e752393484752d465fe0bbd8f16c29c - - Stored in directory: /root/.cache/pip/wheels/fb/45/02/503244da15fbcecde5c3edabb744ed0c4f9a7643126b2d222c - -Successfully built latch docker-image-py - -Installing collected packages: wcwidth, types-PyYAML, text-unidecode, statsd, sortedcontainers, pytz, pytimeparse, websockets, websocket-client, uvloop, tzlocal, tqdm, sniffio, regex, python-slugify, python-json-logger, pyjwt, pyasn1, py, protobuf, prompt-toolkit, oauthlib, numpy, natsort, mypy-extensions, multidict, more-itertools, marshmallow, jmespath, jeepney, grpcio, graphql-core, docstring-parser, diskcache, deprecated, decorator, cloudpickle, click, chardet, cachetools, bcrypt, backoff, aioconsole, yarl, typing-inspect, rsa, retry, responses, requests-toolbelt, requests-oauthlib, pynacl, pyasn1-modules, pyarrow, protoc-gen-swagger, pandas, marshmallow-jsonschema, marshmallow-enum, jaraco.classes, googleapis-common-protos, docker-image-py, docker, croniter, botocore, binaryornot, arrow, apscheduler, anyio, watchfiles, SecretStorage, s3transfer, paramiko, lyteidl, jinja2-time, grpcio-status, gql, google-auth, dataclasses-json, asyncssh, scp, kubernetes, keyring, cookiecutter, boto3, lytekit, lytekitplugins-pods, latch - - Attempting uninstall: numpy - - Found existing installation: numpy 1.24.3 - - Uninstalling numpy-1.24.3: - - Successfully uninstalled numpy-1.24.3 - -Successfully installed SecretStorage-3.3.3 aioconsole-0.5.1 anyio-3.6.2 apscheduler-3.9.1 arrow-1.2.3 asyncssh-2.12.0 backoff-2.2.1 bcrypt-4.0.1 binaryornot-0.4.4 boto3-1.26.137 botocore-1.29.137 cachetools-5.3.0 chardet-5.1.0 click-8.1.3 cloudpickle-2.2.1 cookiecutter-2.1.1 croniter-1.3.14 dataclasses-json-0.5.7 decorator-5.1.1 deprecated-1.2.13 diskcache-5.6.1 docker-5.0.3 docker-image-py-0.1.12 docstring-parser-0.15 google-auth-2.18.1 googleapis-common-protos-1.59.0 gql-3.4.0 graphql-core-3.2.3 grpcio-1.54.2 grpcio-status-1.48.2 jaraco.classes-3.2.3 jeepney-0.8.0 jinja2-time-0.2.0 jmespath-1.0.1 keyring-23.13.1 kubernetes-26.1.0 latch-2.19.11 lyteidl-0.2.0a0 lytekit-0.14.10 lytekitplugins-pods-0.4.0 marshmallow-3.19.0 marshmallow-enum-1.5.1 marshmallow-jsonschema-0.13.0 more-itertools-9.1.0 multidict-6.0.4 mypy-extensions-1.0.0 natsort-8.3.1 numpy-1.21.6 oauthlib-3.2.2 pandas-1.5.3 paramiko-3.1.0 prompt-toolkit-3.0.33 protobuf-3.20.3 protoc-gen-swagger-0.1.0 py-1.11.0 pyarrow-6.0.1 pyasn1-0.5.0 pyasn1-modules-0.3.0 pyjwt-2.7.0 pynacl-1.5.0 python-json-logger-2.0.7 python-slugify-8.0.1 pytimeparse-1.1.8 pytz-2023.3 regex-2023.5.5 requests-oauthlib-1.3.1 requests-toolbelt-0.10.1 responses-0.23.1 retry-0.9.2 rsa-4.9 s3transfer-0.6.1 scp-0.14.5 sniffio-1.3.0 sortedcontainers-2.4.0 statsd-3.3.0 text-unidecode-1.3 tqdm-4.65.0 types-PyYAML-6.0.12.9 typing-inspect-0.8.0 tzlocal-5.0.1 uvloop-0.17.0 watchfiles-0.18.1 wcwidth-0.2.6 websocket-client-1.5.2 websockets-10.3 yarl-1.9.2 - -WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv - - ---> 307c5bcbc386 - -Step 9/16 : copy Snakefile config.yaml /root/ - - - ---> b0ba7cf91375 - -Step 10/16 : copy scripts/plot-quals.py /root/scripts/plot-quals.py - - - ---> 86119263c970 - -Step 11/16 : copy .latch/latch_entrypoint.py /root/latch_entrypoint.py - - - ---> f989dc012176 - -Step 12/16 : arg tag - - - ---> Running in 82457c66aeec - - ---> aaac32c25a4e - -Step 13/16 : env FLYTE_INTERNAL_IMAGE $tag - - - ---> Running in 3489041d8300 - - ---> be966f41400f - -Step 14/16 : env LATCH_SDK_DOMAIN "ligma.ai" - - - ---> Running in 3e7720cf8a94 - - ---> 58f221b01142 - -Step 15/16 : env LATCH_AUTHENTICATION_ENDPOINT https://nucleus.ligma.ai - - - ---> Running in 9ed5e43f9d93 - - ---> 12187158e97a - -Step 16/16 : workdir /root - - - ---> Running in df8101cc4364 - - ---> aa63893ed987 - -Successfully built aa63893ed987 - -Successfully tagged 812206152185.dkr.ecr.us-west-2.amazonaws.com/x1_test_latch_register:0.0.0-46aaed - diff --git a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-56df45/docker-build-logs.txt b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-56df45/docker-build-logs.txt deleted file mode 100644 index eb027596..00000000 --- a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-56df45/docker-build-logs.txt +++ /dev/null @@ -1,100 +0,0 @@ -Step 1/14 : from 812206152185.dkr.ecr.us-west-2.amazonaws.com/latch-base:b733-kenny--snakemake - - - ---> 77471241d7a3 - -Step 2/14 : run mkdir /opt/latch - - - ---> Using cache - - ---> 6d1d7399ec34 - -Step 3/14 : RUN curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh && mkdir /root/.conda && bash Mambaforge-Linux-x86_64.sh -b && rm -f Mambaforge-Linux-x86_64.sh - - - ---> Using cache - - ---> e5d7f1c377ad - -Step 4/14 : copy environment.yaml /root/environment.yaml - - - ---> Using cache - - ---> f1895bb6bb01 - -Step 5/14 : run /root/mambaforge/bin/mamba env create --name snakemake-tutorial --file environment.yaml - - - ---> Using cache - - ---> 1c115b179fb8 - -Step 6/14 : env PATH /root/mambaforge/envs/snakemake-tutorial/bin:$PATH - - - ---> Using cache - - ---> 38bcbc3eaccf - -Step 7/14 : copy latch /root/latch - - - ---> Using cache - - ---> ba86df280c15 - -Step 8/14 : run cd /root/latch && python3 -m pip install -e . - - - ---> Using cache - - ---> e6903b7577c6 - -Step 9/14 : copy Snakefile config.yaml /root/ - - - ---> Using cache - - ---> 93c3fe88c890 - -Step 10/14 : copy scripts/plot-quals.py /root/scripts/plot-quals.py - - - ---> Using cache - - ---> b476a36f6f9c - -Step 11/14 : copy .latch/latch_entrypoint.py /root/latch_entrypoint.py - - - ---> Using cache - - ---> 75cead0538d5 - -Step 12/14 : arg tag - - - ---> Using cache - - ---> 9d8c1d4b5439 - -Step 13/14 : env FLYTE_INTERNAL_IMAGE $tag - - - ---> Running in e5785af71f54 - - ---> 7c55f16d4b30 - -Step 14/14 : workdir /root - - - ---> Running in c8f46c0343b8 - - ---> e2cedb2c4443 - -Successfully built e2cedb2c4443 - -Successfully tagged 812206152185.dkr.ecr.us-west-2.amazonaws.com/x1_test_latch_register:0.0.0-56df45 - diff --git a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-62524a/docker-build-logs.txt b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-62524a/docker-build-logs.txt deleted file mode 100644 index e0305ce3..00000000 --- a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-62524a/docker-build-logs.txt +++ /dev/null @@ -1,65 +0,0 @@ -Step 1/15 : from 812206152185.dkr.ecr.us-west-2.amazonaws.com/latch-base:9c8f-main - - - ---> b253e8cdab51 - -Step 2/15 : run mkdir /opt/latch - - - ---> Using cache - - ---> 89e0ab657f0d - -Step 3/15 : RUN curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh && mkdir /root/.conda && bash Mambaforge-Linux-x86_64.sh -b && rm -f Mambaforge-Linux-x86_64.sh - - - ---> Using cache - - ---> 7741d9d31977 - -Step 4/15 : copy environment.yaml /root/environment.yaml - - - ---> Using cache - - ---> c2d3f498d2d5 - -Step 5/15 : run /root/mambaforge/bin/mamba env create --name snakemake-tutorial --file environment.yaml - - - ---> Using cache - - ---> 0370179f98b9 - -Step 6/15 : env PATH /root/mambaforge/envs/snakemake-tutorial/bin:$PATH - - - ---> Using cache - - ---> 558ea5988368 - -Step 7/15 : run python3 -m pip install latch - - - ---> Using cache - - ---> 73f3b443e340 - -Step 8/15 : copy Snakefile config.yaml /root/ - - - ---> Using cache - - ---> da1c8fa40657 - -Step 9/15 : copy scripts/plot-quals.py /root/scripts/plot-quals.py - - - ---> Using cache - - ---> 6e0a5622727c - -Step 10/15 : copy .latch/latch_entrypoint.py /root/latch_entrypoint.py - - -COPY failed: file not found in build context or excluded by .dockerignore: stat .latch/latch_entrypoint.py: file does not exist diff --git a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-6975e7/docker-build-logs.txt b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-6975e7/docker-build-logs.txt deleted file mode 100644 index e2a4165f..00000000 --- a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-6975e7/docker-build-logs.txt +++ /dev/null @@ -1,100 +0,0 @@ -Step 1/14 : from 812206152185.dkr.ecr.us-west-2.amazonaws.com/latch-base:b733-kenny--snakemake - - - ---> 77471241d7a3 - -Step 2/14 : run mkdir /opt/latch - - - ---> Using cache - - ---> 6d1d7399ec34 - -Step 3/14 : RUN curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh && mkdir /root/.conda && bash Mambaforge-Linux-x86_64.sh -b && rm -f Mambaforge-Linux-x86_64.sh - - - ---> Using cache - - ---> e5d7f1c377ad - -Step 4/14 : copy environment.yaml /root/environment.yaml - - - ---> Using cache - - ---> f1895bb6bb01 - -Step 5/14 : run /root/mambaforge/bin/mamba env create --name snakemake-tutorial --file environment.yaml - - - ---> Using cache - - ---> 1c115b179fb8 - -Step 6/14 : env PATH /root/mambaforge/envs/snakemake-tutorial/bin:$PATH - - - ---> Using cache - - ---> 38bcbc3eaccf - -Step 7/14 : copy latch /root/latch - - - ---> Using cache - - ---> 0a6841ad1519 - -Step 8/14 : run cd /root/latch && python3 -m pip install -e . - - - ---> Using cache - - ---> 987ca2488773 - -Step 9/14 : copy Snakefile config.yaml /root/ - - - ---> Using cache - - ---> ff2efbf9c325 - -Step 10/14 : copy scripts/plot-quals.py /root/scripts/plot-quals.py - - - ---> Using cache - - ---> efa63cf5aa2d - -Step 11/14 : copy .latch/latch_entrypoint.py /root/latch_entrypoint.py - - - ---> Using cache - - ---> 5222bb3def10 - -Step 12/14 : arg tag - - - ---> Using cache - - ---> 2b44d6814bf9 - -Step 13/14 : env FLYTE_INTERNAL_IMAGE $tag - - - ---> Running in badb0a9f44c5 - - ---> 87493969f9ba - -Step 14/14 : workdir /root - - - ---> Running in dc0733710fb0 - - ---> 1aeb3dc3c55a - -Successfully built 1aeb3dc3c55a - -Successfully tagged 812206152185.dkr.ecr.us-west-2.amazonaws.com/x1_test_latch_register:0.0.0-6975e7 - diff --git a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-87b6a8/docker-build-logs.txt b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-87b6a8/docker-build-logs.txt deleted file mode 100644 index 9ff7e2c9..00000000 --- a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-87b6a8/docker-build-logs.txt +++ /dev/null @@ -1,100 +0,0 @@ -Step 1/14 : from 812206152185.dkr.ecr.us-west-2.amazonaws.com/latch-base:b733-kenny--snakemake - - - ---> 77471241d7a3 - -Step 2/14 : run mkdir /opt/latch - - - ---> Using cache - - ---> 6d1d7399ec34 - -Step 3/14 : RUN curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh && mkdir /root/.conda && bash Mambaforge-Linux-x86_64.sh -b && rm -f Mambaforge-Linux-x86_64.sh - - - ---> Using cache - - ---> e5d7f1c377ad - -Step 4/14 : copy environment.yaml /root/environment.yaml - - - ---> Using cache - - ---> f1895bb6bb01 - -Step 5/14 : run /root/mambaforge/bin/mamba env create --name snakemake-tutorial --file environment.yaml - - - ---> Using cache - - ---> 1c115b179fb8 - -Step 6/14 : env PATH /root/mambaforge/envs/snakemake-tutorial/bin:$PATH - - - ---> Using cache - - ---> 38bcbc3eaccf - -Step 7/14 : copy latch /root/latch - - - ---> Using cache - - ---> 0a6841ad1519 - -Step 8/14 : run cd /root/latch && python3 -m pip install -e . - - - ---> Using cache - - ---> 987ca2488773 - -Step 9/14 : copy Snakefile config.yaml /root/ - - - ---> Using cache - - ---> ff2efbf9c325 - -Step 10/14 : copy scripts/plot-quals.py /root/scripts/plot-quals.py - - - ---> Using cache - - ---> efa63cf5aa2d - -Step 11/14 : copy .latch/latch_entrypoint.py /root/latch_entrypoint.py - - - ---> Using cache - - ---> 5222bb3def10 - -Step 12/14 : arg tag - - - ---> Using cache - - ---> 2b44d6814bf9 - -Step 13/14 : env FLYTE_INTERNAL_IMAGE $tag - - - ---> Running in 9d9fe52efd67 - - ---> 865ce9ad87f8 - -Step 14/14 : workdir /root - - - ---> Running in abd69922bebc - - ---> 40606bdcc357 - -Successfully built 40606bdcc357 - -Successfully tagged 812206152185.dkr.ecr.us-west-2.amazonaws.com/x1_test_latch_register:0.0.0-87b6a8 - diff --git a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-89875a/docker-build-logs.txt b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-89875a/docker-build-logs.txt deleted file mode 100644 index bf752653..00000000 --- a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-89875a/docker-build-logs.txt +++ /dev/null @@ -1,98 +0,0 @@ -Step 1/14 : from 812206152185.dkr.ecr.us-west-2.amazonaws.com/latch-base:b733-kenny--snakemake - - - ---> 77471241d7a3 - -Step 2/14 : run mkdir /opt/latch - - - ---> Using cache - - ---> 6d1d7399ec34 - -Step 3/14 : RUN curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh && mkdir /root/.conda && bash Mambaforge-Linux-x86_64.sh -b && rm -f Mambaforge-Linux-x86_64.sh - - - ---> Using cache - - ---> e5d7f1c377ad - -Step 4/14 : copy environment.yaml /root/environment.yaml - - - ---> Using cache - - ---> f1895bb6bb01 - -Step 5/14 : run /root/mambaforge/bin/mamba env create --name snakemake-tutorial --file environment.yaml - - - ---> Using cache - - ---> 1c115b179fb8 - -Step 6/14 : env PATH /root/mambaforge/envs/snakemake-tutorial/bin:$PATH - - - ---> Using cache - - ---> 38bcbc3eaccf - -Step 7/14 : copy latch /root/latch - - - ---> Using cache - - ---> 0a6841ad1519 - -Step 8/14 : run cd /root/latch && python3 -m pip install -e . - - - ---> Using cache - - ---> 987ca2488773 - -Step 9/14 : copy Snakefile config.yaml /root/ - - - ---> Using cache - - ---> ff2efbf9c325 - -Step 10/14 : copy scripts/plot-quals.py /root/scripts/plot-quals.py - - - ---> Using cache - - ---> efa63cf5aa2d - -Step 11/14 : copy .latch/latch_entrypoint.py /root/latch_entrypoint.py - - - ---> 7ff56b528bef - -Step 12/14 : arg tag - - - ---> Running in a7aa5ba593e9 - - ---> 72806a2f7535 - -Step 13/14 : env FLYTE_INTERNAL_IMAGE $tag - - - ---> Running in 9c8313cc6ddd - - ---> 42412bb67f94 - -Step 14/14 : workdir /root - - - ---> Running in 0f6f141d57a8 - - ---> 346d6b9d4401 - -Successfully built 346d6b9d4401 - -Successfully tagged 812206152185.dkr.ecr.us-west-2.amazonaws.com/x1_test_latch_register:0.0.0-89875a - diff --git a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-a00131/docker-build-logs.txt b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-a00131/docker-build-logs.txt deleted file mode 100644 index 6c90709b..00000000 --- a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-a00131/docker-build-logs.txt +++ /dev/null @@ -1,2627 +0,0 @@ -Step 1/15 : from 812206152185.dkr.ecr.us-west-2.amazonaws.com/latch-base:1393-kenny--snakemake - - - ---> cf4e007bf7d3 - -Step 2/15 : run mkdir /opt/latch - - - ---> Running in f3d6dc4c1146 - - ---> afed690b224b - -Step 3/15 : RUN curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh && mkdir /root/.conda && bash Mambaforge-Linux-x86_64.sh -b && rm -f Mambaforge-Linux-x86_64.sh - - - ---> Running in 742a170bb1bf - - % Total % Received % Xferd Average Speed  -Time Time Time Current - Dload Upload Total Spent Left Speed - 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 - 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 - 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 - - 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 - - 25 82.9M 25 20.8M 0 0 20.1M 0 0:00:04 0:00:01 0:00:03 20.1M - 100 82.9M 100 82.9M 0 0 43.0M 0 0:00:01 0:00:01 --:--:-- 69.7M - -PREFIX=/root/mambaforge - -Unpacking payload ... - -Extracting _libgcc_mutex-0.1-conda_forge.tar.bz2 - -Extracting ca-certificates-2022.12.7-ha878542_0.conda - -Extracting ld_impl_linux-64-2.40-h41732ed_0.conda - -Extracting libstdcxx-ng-12.2.0-h46fd767_19.tar.bz2 - -Extracting pybind11-abi-4-hd8ed1ab_3.tar.bz2 - -Extracting python_abi-3.10-3_cp310.conda - -Extracting tzdata-2023c-h71feb2d_0.conda - -Extracting libgomp-12.2.0-h65d4601_19.tar.bz2 - -Extracting _openmp_mutex-4.5-2_gnu.tar.bz2 - -Extracting libgcc-ng-12.2.0-h65d4601_19.tar.bz2 - -Extracting bzip2-1.0.8-h7f98852_4.tar.bz2 - -Extracting c-ares-1.18.1-h7f98852_0.tar.bz2 - -Extracting fmt-9.1.0-h924138e_0.tar.bz2 - -Extracting icu-72.1-hcb278e6_0.conda - -Extracting keyutils-1.6.1-h166bdaf_0.tar.bz2 - -Extracting libev-4.33-h516909a_1.tar.bz2 - -Extracting libffi-3.4.2-h7f98852_5.tar.bz2 - -Extracting libiconv-1.17-h166bdaf_0.tar.bz2 - -Extracting libnsl-2.0.0-h7f98852_0.tar.bz2 - -Extracting libuuid-2.38.1-h0b41bf4_0.conda - -Extracting libzlib-1.2.13-h166bdaf_4.tar.bz2 - -Extracting lz4-c-1.9.4-hcb278e6_0.conda - -Extracting lzo-2.10-h516909a_1000.tar.bz2 - -Extracting ncurses-6.3-h27087fc_1.tar.bz2 - -Extracting openssl-3.1.0-h0b41bf4_0.conda - -Extracting reproc-14.2.4-h0b41bf4_0.conda - -Extracting xz-5.2.6-h166bdaf_0.tar.bz2 - -Extracting yaml-cpp-0.7.0-h27087fc_2.tar.bz2 - -Extracting libedit-3.1.20191231-he28a2e2_2.tar.bz2 - -Extracting libnghttp2-1.52.0-h61bc06f_0.conda - -Extracting libsolv-0.7.23-h3eb15da_0.conda - -Extracting libsqlite-3.40.0-h753d276_0.tar.bz2 - -Extracting libssh2-1.10.0-hf14f497_3.tar.bz2 - -Extracting libxml2-2.10.3-hfdac1af_6.conda - -Extracting readline-8.2-h8228510_1.conda - -Extracting reproc-cpp-14.2.4-hcb278e6_0.conda - -Extracting tk-8.6.12-h27826a3_0.tar.bz2 - -Extracting zstd-1.5.2-h3eb15da_6.conda - -Extracting krb5-1.20.1-h81ceb04_0.conda - -Extracting libarchive-3.6.2-h3d51595_0.conda - -Extracting python-3.10.10-he550d4f_0_cpython.conda - -Extracting certifi-2022.12.7-pyhd8ed1ab_0.conda - -Extracting charset-normalizer-3.1.0-pyhd8ed1ab_0.conda - -Extracting colorama-0.4.6-pyhd8ed1ab_0.tar.bz2 - -Extracting idna-3.4-pyhd8ed1ab_0.tar.bz2 - -Extracting libcurl-7.88.1-hdc1c0ab_1.conda - -Extracting pluggy-1.0.0-pyhd8ed1ab_5.tar.bz2 - -Extracting pycosat-0.6.4-py310h5764c6d_1.tar.bz2 - -Extracting pycparser-2.21-pyhd8ed1ab_0.tar.bz2 - -Extracting pysocks-1.7.1-pyha2e5f31_6.tar.bz2 - -Extracting ruamel.yaml.clib-0.2.7-py310h1fa729e_1.conda - -Extracting setuptools-65.6.3-pyhd8ed1ab_0.conda - -Extracting toolz-0.12.0-pyhd8ed1ab_0.tar.bz2 - -Extracting wheel-0.40.0-pyhd8ed1ab_0.conda - -Extracting cffi-1.15.1-py310h255011f_3.conda - -Extracting libmamba-1.4.1-hcea66bb_0.conda - -Extracting pip-23.0.1-pyhd8ed1ab_0.conda - -Extracting ruamel.yaml-0.17.21-py310h1fa729e_3.conda - -Extracting tqdm-4.65.0-pyhd8ed1ab_1.conda - -Extracting brotlipy-0.7.0-py310h5764c6d_1005.tar.bz2 - -Extracting cryptography-40.0.1-py310h34c0648_0.conda - -Extracting libmambapy-1.4.1-py310h1428755_0.conda - -Extracting zstandard-0.19.0-py310hdeb6495_1.conda - -Extracting conda-package-streaming-0.7.0-pyhd8ed1ab_1.conda - -Extracting pyopenssl-23.1.1-pyhd8ed1ab_0.conda - -Extracting conda-package-handling-2.0.2-pyh38be061_0.conda - -Extracting urllib3-1.26.15-pyhd8ed1ab_0.conda - -Extracting requests-2.28.2-pyhd8ed1ab_1.conda - -Extracting conda-23.1.0-py310hff52083_0.conda - -Extracting mamba-1.4.1-py310h51d5547_0.conda - - -Installing base environment... - - - - __ - __ ______ ___ ____ _____ ___ / /_ ____ _ - / / / / __ `__ \/ __ `/ __ `__ \/ __ \/ __ `/ - / /_/ / / / / / / /_/ / / / / / / /_/ / /_/ / - / .___/_/ /_/ /_/\__,_/_/ /_/ /_/_.___/\__,_/ - /_/ - - -Transaction - - Prefix: /root/mambaforge - - Updating specs: - - - conda-forge/linux-64::_libgcc_mutex==0.1=conda_forge[md5=d7c89558ba9fa0495403155b64376d81] - - conda-forge/linux-64::ca-certificates==2022.12.7=ha878542_0[md5=ff9f73d45c4a07d6f424495288a26080] - - conda-forge/linux-64::ld_impl_linux-64==2.40=h41732ed_0[md5=7aca3059a1729aa76c597603f10b0dd3] - - conda-forge/linux-64::libstdcxx-ng==12.2.0=h46fd767_19[md5=1030b1f38c129f2634eae026f704fe60] - - conda-forge/noarch::pybind11-abi==4=hd8ed1ab_3[md5=878f923dd6acc8aeb47a75da6c4098be] - - conda-forge/linux-64::python_abi==3.10=3_cp310[md5=4eb33d14d794b0f4be116443ffed3853] - - conda-forge/noarch::tzdata==2023c=h71feb2d_0[md5=939e3e74d8be4dac89ce83b20de2492a] - - conda-forge/linux-64::libgomp==12.2.0=h65d4601_19[md5=cedcee7c064c01c403f962c9e8d3c373] - - conda-forge/linux-64::_openmp_mutex==4.5=2_gnu[md5=73aaf86a425cc6e73fcf236a5a46396d] - - conda-forge/linux-64::libgcc-ng==12.2.0=h65d4601_19[md5=e4c94f80aef025c17ab0828cd85ef535] - - conda-forge/linux-64::bzip2==1.0.8=h7f98852_4[md5=a1fd65c7ccbf10880423d82bca54eb54] - - conda-forge/linux-64::c-ares==1.18.1=h7f98852_0[md5=f26ef8098fab1f719c91eb760d63381a] - - conda-forge/linux-64::fmt==9.1.0=h924138e_0[md5=b57864c85261a0fbc7132d2cc17478c7] - - conda-forge/linux-64::icu==72.1=hcb278e6_0[md5=7c8d20d847bb45f56bd941578fcfa146] - - conda-forge/linux-64::keyutils==1.6.1=h166bdaf_0[md5=30186d27e2c9fa62b45fb1476b7200e3] - - conda-forge/linux-64::libev==4.33=h516909a_1[md5=6f8720dff19e17ce5d48cfe7f3d2f0a3] - - conda-forge/linux-64::libffi==3.4.2=h7f98852_5[md5=d645c6d2ac96843a2bfaccd2d62b3ac3] - - conda-forge/linux-64::libiconv==1.17=h166bdaf_0[md5=b62b52da46c39ee2bc3c162ac7f1804d] - - conda-forge/linux-64::libnsl==2.0.0=h7f98852_0[md5=39b1328babf85c7c3a61636d9cd50206] - - - conda-forge/linux-64::libuuid==2.38.1=h0b41bf4_0[md5=40b61aab5c7ba9ff276c41cfffe6b80b] - - conda-forge/linux-64::libzlib==1.2.13=h166bdaf_4[md5=f3f9de449d32ca9b9c66a22863c96f41] - - conda-forge/linux-64::lz4-c==1.9.4=hcb278e6_0[md5=318b08df404f9c9be5712aaa5a6f0bb0] - - conda-forge/linux-64::lzo==2.10=h516909a_1000[md5=bb14fcb13341b81d5eb386423b9d2bac] - - conda-forge/linux-64::ncurses==6.3=h27087fc_1[md5=4acfc691e64342b9dae57cf2adc63238] - - conda-forge/linux-64::openssl==3.1.0=h0b41bf4_0[md5=2d833be81a21128e317325a01326d36f] - - conda-forge/linux-64::reproc==14.2.4=h0b41bf4_0[md5=0f51393e019df1f0047ef864cd9ddeec] - - conda-forge/linux-64::xz==5.2.6=h166bdaf_0[md5=2161070d867d1b1204ea749c8eec4ef0] - - conda-forge/linux-64::yaml-cpp==0.7.0=h27087fc_2[md5=0449d47d8457feaa3720d4779616dde2] - - conda-forge/linux-64::libedit==3.1.20191231=he28a2e2_2[md5=4d331e44109e3f0e19b4cb8f9b82f3e1] - - conda-forge/linux-64::libnghttp2==1.52.0=h61bc06f_0[md5=613955a50485812985c059e7b269f42e] - - conda-forge/linux-64::libsolv==0.7.23=h3eb15da_0[md5=122332e6deb4aea9eaf22021d2ecd256] - - conda-forge/linux-64::libsqlite==3.40.0=h753d276_0[md5=2e5f9a37d487e1019fd4d8113adb2f9f] - - conda-forge/linux-64::libssh2==1.10.0=hf14f497_3[md5=d85acad4b47dff4e3def14a769a97906] - - conda-forge/linux-64::libxml2==2.10.3=hfdac1af_6[md5=7eecaadc2eaeef464c5fe17702f17c86] - - conda-forge/linux-64::readline==8.2=h8228510_1[md5=47d31b792659ce70f470b5c82fdfb7a4] - - conda-forge/linux-64::reproc-cpp==14.2.4=hcb278e6_0[md5=ede8e0f849f2fee2f78cb488b4ea3b33] - - conda-forge/linux-64::tk==8.6.12=h27826a3_0[md5=5b8c42eb62e9fc961af70bdd6a26e168] - - conda-forge/linux-64::zstd==1.5.2=h3eb15da_6[md5=6b63daed8feeca47be78f323e793d555] - - conda-forge/linux-64::krb5==1.20.1=h81ceb04_0[md5=89a41adce7106749573d883b2f657d78] - - conda-forge/linux-64::libarchive==3.6.2=h3d51595_0[md5=9f915b4adeb9dcfd450b9ad238e2db4c] - - conda-forge/linux-64::python==3.10.10=he550d4f_0_cpython[md5=de25afc7041c103c7f510c746bb63435] - - conda-forge/noarch::certifi==2022.12.7=pyhd8ed1ab_0[md5=fb9addc3db06e56abe03e0e9f21a63e6] - - - conda-forge/noarch::charset-normalizer==3.1.0=pyhd8ed1ab_0[md5=7fcff9f6f123696e940bda77bd4d6551] - - conda-forge/noarch::colorama==0.4.6=pyhd8ed1ab_0[md5=3faab06a954c2a04039983f2c4a50d99] - - - conda-forge/noarch::idna==3.4=pyhd8ed1ab_0[md5=34272b248891bddccc64479f9a7fffed] - - conda-forge/linux-64::libcurl==7.88.1=hdc1c0ab_1[md5=3d1189864d1c0ed2a5919cb067b5903d] - - conda-forge/noarch::pluggy==1.0.0=pyhd8ed1ab_5[md5=7d301a0d25f424d96175f810935f0da9] - - conda-forge/linux-64::pycosat==0.6.4=py310h5764c6d_1[md5=0e565d732f6660374b45d76761c09b06] - - conda-forge/noarch::pycparser==2.21=pyhd8ed1ab_0[md5=076becd9e05608f8dc72757d5f3a91ff] - - conda-forge/noarch::pysocks==1.7.1=pyha2e5f31_6[md5=2a7de29fb590ca14b5243c4c812c8025] - - conda-forge/linux-64::ruamel.yaml.clib==0.2.7=py310h1fa729e_1[md5=2f9b517412af46255cef5e53a22c264e] - - conda-forge/noarch::setuptools==65.6.3=pyhd8ed1ab_0[md5=9600fc9524d3f821e6a6d58c52f5bf5a] - - conda-forge/noarch::toolz==0.12.0=pyhd8ed1ab_0[md5=92facfec94bc02d6ccf42e7173831a36] - - conda-forge/noarch::wheel==0.40.0=pyhd8ed1ab_0[md5=49bb0d9e60ce1db25e151780331bb5f3] - - conda-forge/linux-64::cffi==1.15.1=py310h255011f_3[md5=800596144bb613cd7ac58b80900ce835] - - conda-forge/linux-64::libmamba==1.4.1=hcea66bb_0[md5=e512a4c95ff1eca1684642fa32bd2f55] - - - conda-forge/noarch::pip==23.0.1=pyhd8ed1ab_0[md5=8025ca83b8ba5430b640b83917c2a6f7] - - conda-forge/linux-64::ruamel.yaml==0.17.21=py310h1fa729e_3[md5=97204ae92b703d74a983db0e6d07d009] - - conda-forge/noarch::tqdm==4.65.0=pyhd8ed1ab_1[md5=ed792aff3acb977d09c7013358097f83] - - conda-forge/linux-64::brotlipy==0.7.0=py310h5764c6d_1005[md5=87669c3468dff637bbd0363bc0f895cf] - - conda-forge/linux-64::cryptography==40.0.1=py310h34c0648_0[md5=deafd9206c2e307874f3777a33cafb79] - - conda-forge/linux-64::libmambapy==1.4.1=py310h1428755_0[md5=323e09e9947b6a415f9d73562e4ca862] - - conda-forge/linux-64::zstandard==0.19.0=py310hdeb6495_1[md5=2cce1a48e6687f64d371d2e7fc9c7fbf] - - conda-forge/noarch::conda-package-streaming==0.7.0=pyhd8ed1ab_1[md5=1a2fa9e53cfbc2e4d9ab21990805a436] - - conda-forge/noarch::pyopenssl==23.1.1=pyhd8ed1ab_0[md5=0b34aa3ab7e7ccb1765a03dd9ed29938] - - conda-forge/noarch::conda-package-handling==2.0.2=pyh38be061_0[md5=44800e9bd13143292097c65e57323038] - - conda-forge/noarch::urllib3==1.26.15=pyhd8ed1ab_0[md5=27db656619a55d727eaf5a6ece3d2fd6] - - conda-forge/noarch::requests==2.28.2=pyhd8ed1ab_1[md5=3bfbd6ead1d7299ed46dab3a7bf0bc8c] - - conda-forge/linux-64::conda==23.1.0=py310hff52083_0[md5=c2f5cd14bf4a8cc673f66fd9839e6602] - - conda-forge/linux-64::mamba==1.4.1=py310h51d5547_0[md5=49170d6752d2326fe16dc2b6e74f9e54] - - - - Package Version Build Channel Size -─────────────────────────────────────────────────────────────────────────────────────── - Install: -─────────────────────────────────────────────────────────────────────────────────────── - - + _libgcc_mutex 0.1 conda_forge conda-forge Cached - + _openmp_mutex 4.5 2_gnu conda-forge Cached - + brotlipy 0.7.0 py310h5764c6d_1005 conda-forge Cached - + bzip2 1.0.8 h7f98852_4 conda-forge Cached - + c-ares 1.18.1 h7f98852_0 conda-forge Cached - + ca-certificates 2022.12.7 ha878542_0 conda-forge Cached - + certifi 2022.12.7 pyhd8ed1ab_0 conda-forge Cached - + cffi 1.15.1 py310h255011f_3 conda-forge Cached - + charset-normalizer 3.1.0 pyhd8ed1ab_0 conda-forge Cached - + colorama 0.4.6 pyhd8ed1ab_0 conda-forge Cached - + conda 23.1.0 py310hff52083_0 conda-forge Cached - + conda-package-handling 2.0.2 pyh38be061_0 conda-forge Cached - + conda-package-streaming 0.7.0 pyhd8ed1ab_1 conda-forge Cached - + cryptography 40.0.1 py310h34c0648_0 conda-forge Cached - + fmt 9.1.0 h924138e_0 conda-forge Cached - + icu 72.1 hcb278e6_0 conda-forge Cached - + idna 3.4 pyhd8ed1ab_0 conda-forge Cached - + keyutils 1.6.1 h166bdaf_0 conda-forge Cached - + krb5 1.20.1 h81ceb04_0 conda-forge Cached - + ld_impl_linux-64 2.40 h41732ed_0 conda-forge Cached - + libarchive 3.6.2 h3d51595_0 conda-forge Cached - + libcurl 7.88.1 hdc1c0ab_1 conda-forge Cached - + libedit 3.1.20191231 he28a2e2_2 conda-forge Cached - + libev 4.33 h516909a_1 conda-forge Cached - + libffi 3.4.2 h7f98852_5 conda-forge Cached - + libgcc-ng 12.2.0 h65d4601_19 conda-forge Cached - + libgomp 12.2.0 h65d4601_19 conda-forge Cached - + libiconv 1.17 h166bdaf_0 conda-forge Cached - + libmamba 1.4.1 hcea66bb_0 conda-forge Cached - + libmambapy 1.4.1 py310h1428755_0 conda-forge Cached - + libnghttp2 1.52.0 h61bc06f_0 conda-forge Cached - + libnsl 2.0.0 h7f98852_0 conda-forge Cached - + libsolv 0.7.23 h3eb15da_0 conda-forge Cached - + libsqlite 3.40.0 h753d276_0 conda-forge Cached - + libssh2 1.10.0 hf14f497_3 conda-forge Cached - + libstdcxx-ng 12.2.0 h46fd767_19 conda-forge Cached - + libuuid 2.38.1 h0b41bf4_0 conda-forge Cached - + libxml2 2.10.3 hfdac1af_6 conda-forge Cached - + libzlib 1.2.13 h166bdaf_4 conda-forge Cached - + lz4-c 1.9.4 hcb278e6_0 conda-forge Cached - + lzo 2.10 h516909a_1000 conda-forge Cached - + mamba 1.4.1 py310h51d5547_0 conda-forge Cached - + ncurses 6.3 h27087fc_1 conda-forge Cached - + openssl 3.1.0 h0b41bf4_0 conda-forge Cached - + pip 23.0.1 pyhd8ed1ab_0 conda-forge Cached - + pluggy 1.0.0 pyhd8ed1ab_5 conda-forge Cached - + pybind11-abi 4 hd8ed1ab_3 conda-forge Cached - + pycosat 0.6.4 py310h5764c6d_1 conda-forge Cached - + pycparser 2.21 pyhd8ed1ab_0 conda-forge Cached - + pyopenssl 23.1.1 pyhd8ed1ab_0 conda-forge Cached - + pysocks 1.7.1 pyha2e5f31_6 conda-forge Cached - + python 3.10.10 he550d4f_0_cpython conda-forge Cached - + python_abi 3.10 3_cp310 conda-forge Cached - + readline 8.2 h8228510_1 conda-forge Cached - + reproc 14.2.4 h0b41bf4_0 conda-forge Cached - + reproc-cpp 14.2.4 hcb278e6_0 conda-forge Cached - + requests 2.28.2 pyhd8ed1ab_1 conda-forge Cached - + ruamel.yaml 0.17.21 py310h1fa729e_3 conda-forge Cached - + ruamel.yaml.clib 0.2.7 py310h1fa729e_1 conda-forge Cached - + setuptools 65.6.3 pyhd8ed1ab_0 conda-forge Cached - + tk 8.6.12 h27826a3_0 conda-forge Cached - + toolz 0.12.0 pyhd8ed1ab_0 conda-forge Cached - + tqdm 4.65.0 pyhd8ed1ab_1 conda-forge Cached - + tzdata 2023c h71feb2d_0 conda-forge Cached - + urllib3 1.26.15 pyhd8ed1ab_0 conda-forge Cached - + wheel 0.40.0 pyhd8ed1ab_0 conda-forge Cached - + xz 5.2.6 h166bdaf_0 conda-forge Cached - + yaml-cpp 0.7.0 h27087fc_2 conda-forge Cached - + zstandard 0.19.0 py310hdeb6495_1 conda-forge Cached - + zstd 1.5.2 h3eb15da_6 conda-forge Cached - - Summary: - - Install: 70 packages - - Total download: 0 B - -─────────────────────────────────────────────────────────────────────────────────────── - - - - -Transaction starting - -Linking _libgcc_mutex-0.1-conda_forge - -Linking ca-certificates-2022.12.7-ha878542_0 - -Linking ld_impl_linux-64-2.40-h41732ed_0 - -Linking libstdcxx-ng-12.2.0-h46fd767_19 - -Linking pybind11-abi-4-hd8ed1ab_3 - -Linking python_abi-3.10-3_cp310 - -Linking tzdata-2023c-h71feb2d_0 - -Linking libgomp-12.2.0-h65d4601_19 - -Linking _openmp_mutex-4.5-2_gnu - -Linking libgcc-ng-12.2.0-h65d4601_19 - -Linking bzip2-1.0.8-h7f98852_4 - -Linking c-ares-1.18.1-h7f98852_0 - -Linking fmt-9.1.0-h924138e_0 - -Linking icu-72.1-hcb278e6_0 - -Linking keyutils-1.6.1-h166bdaf_0 - -Linking libev-4.33-h516909a_1 - -Linking libffi-3.4.2-h7f98852_5 - -Linking libiconv-1.17-h166bdaf_0 - -Linking libnsl-2.0.0-h7f98852_0 - -Linking libuuid-2.38.1-h0b41bf4_0 - -Linking libzlib-1.2.13-h166bdaf_4 - -Linking lz4-c-1.9.4-hcb278e6_0 - -Linking lzo-2.10-h516909a_1000 - -Linking ncurses-6.3-h27087fc_1 - -Linking openssl-3.1.0-h0b41bf4_0 - -Linking reproc-14.2.4-h0b41bf4_0 - -Linking xz-5.2.6-h166bdaf_0 - -Linking yaml-cpp-0.7.0-h27087fc_2 - -Linking libedit-3.1.20191231-he28a2e2_2 - -Linking libnghttp2-1.52.0-h61bc06f_0 - -Linking libsolv-0.7.23-h3eb15da_0 - -Linking libsqlite-3.40.0-h753d276_0 - -Linking libssh2-1.10.0-hf14f497_3 - -Linking libxml2-2.10.3-hfdac1af_6 - -Linking readline-8.2-h8228510_1 - -Linking reproc-cpp-14.2.4-hcb278e6_0 - -Linking tk-8.6.12-h27826a3_0 - -Linking zstd-1.5.2-h3eb15da_6 - -Linking krb5-1.20.1-h81ceb04_0 - -Linking libarchive-3.6.2-h3d51595_0 - -Linking python-3.10.10-he550d4f_0_cpython - -Linking certifi-2022.12.7-pyhd8ed1ab_0 - -Linking charset-normalizer-3.1.0-pyhd8ed1ab_0 - -Linking colorama-0.4.6-pyhd8ed1ab_0 - -Linking idna-3.4-pyhd8ed1ab_0 - -Linking libcurl-7.88.1-hdc1c0ab_1 - -Linking pluggy-1.0.0-pyhd8ed1ab_5 - -Linking pycosat-0.6.4-py310h5764c6d_1 - -Linking pycparser-2.21-pyhd8ed1ab_0 - -Linking pysocks-1.7.1-pyha2e5f31_6 - -Linking ruamel.yaml.clib-0.2.7-py310h1fa729e_1 - -Linking setuptools-65.6.3-pyhd8ed1ab_0 - -Linking toolz-0.12.0-pyhd8ed1ab_0 - -Linking wheel-0.40.0-pyhd8ed1ab_0 - -Linking cffi-1.15.1-py310h255011f_3 - -Linking libmamba-1.4.1-hcea66bb_0 - -Linking pip-23.0.1-pyhd8ed1ab_0 - -Linking ruamel.yaml-0.17.21-py310h1fa729e_3 - -Linking tqdm-4.65.0-pyhd8ed1ab_1 - -Linking brotlipy-0.7.0-py310h5764c6d_1005 - -Linking cryptography-40.0.1-py310h34c0648_0 - -Linking libmambapy-1.4.1-py310h1428755_0 - -Linking zstandard-0.19.0-py310hdeb6495_1 - -Linking conda-package-streaming-0.7.0-pyhd8ed1ab_1 - -Linking pyopenssl-23.1.1-pyhd8ed1ab_0 - -Linking conda-package-handling-2.0.2-pyh38be061_0 - -Linking urllib3-1.26.15-pyhd8ed1ab_0 - -Linking requests-2.28.2-pyhd8ed1ab_1 - -Linking conda-23.1.0-py310hff52083_0 - -Linking mamba-1.4.1-py310h51d5547_0 - -Transaction finished - -installation finished. - -WARNING: - You currently have a PYTHONPATH environment variable set. This may cause - - unexpected behavior when running the Python interpreter in Mambaforge. - For best results, please verify that your PYTHONPATH only points to - directories of packages that are compatible with the Python interpreter - in Mambaforge: /root/mambaforge - - ---> 6505a24fc87d - -Step 4/15 : copy environment.yaml /root/environment.yaml - - - ---> 2c2042a80716 - -Step 5/15 : run /root/mambaforge/bin/mamba env create --name snakemake-tutorial --file environment.yaml - - - ---> Running in 113cf9e4d1a5 - - - -Looking for: ["snakemake-minimal[version='>=7.3']", 'jinja2', 'matplotlib', 'graphviz', 'bcftools=1.15', 'samtools=1.15', 'bwa=0.7.17', 'pysam=0.19', 'pygments'] - - - -Transaction - - Prefix: /root/mambaforge/envs/snakemake-tutorial - - Updating specs: - - - snakemake-minimal[version='>=7.3'] - - jinja2 - - matplotlib - - graphviz - - bcftools=1.15 - - samtools=1.15 - - bwa=0.7.17 - - pysam=0.19 - - pygments - - - - Package Version Build Channel Size -─────────────────────────────────────────────────────────────────────────────────────────────────── - Install: -─────────────────────────────────────────────────────────────────────────────────────────────────── - - + _libgcc_mutex 0.1 conda_forge conda-forge/linux-64 Cached - + _openmp_mutex 4.5 2_gnu conda-forge/linux-64 Cached - + alsa-lib 1.2.8 h166bdaf_0 conda-forge/linux-64 592kB - + amply 0.1.5 pyhd8ed1ab_0 conda-forge/noarch 21kB - + appdirs 1.4.4 pyh9f0ad1d_0 conda-forge/noarch 13kB - + atk-1.0 2.38.0 hd4edc92_1 conda-forge/linux-64 552kB - + attr 2.5.1 h166bdaf_1 conda-forge/linux-64 71kB - + attrs 23.1.0 pyh71513ae_1 conda-forge/noarch 55kB - + bcftools 1.15.1 hfe4b78e_1 bioconda/linux-64 867kB - + brotli 1.0.9 h166bdaf_8 conda-forge/linux-64 19kB - + brotli-bin 1.0.9 h166bdaf_8 conda-forge/linux-64 20kB - + brotlipy 0.7.0 py310h5764c6d_1005 conda-forge/linux-64 Cached - + bwa 0.7.17 he4a0461_11 bioconda/linux-64 196kB - + bzip2 1.0.8 h7f98852_4 conda-forge/linux-64 Cached - + c-ares 1.19.0 hd590300_0 conda-forge/linux-64 114kB - + ca-certificates 2023.5.7 hbcca054_0 conda-forge/linux-64 148kB - + cairo 1.16.0 ha61ee94_1014 conda-forge/linux-64 2MB - + certifi 2023.5.7 pyhd8ed1ab_0 conda-forge/noarch 152kB - + cffi 1.15.1 py310h255011f_3 conda-forge/linux-64 Cached - + charset-normalizer 3.1.0 pyhd8ed1ab_0 conda-forge/noarch Cached - + coin-or-cbc 2.10.10 h9002f0b_0 conda-forge/linux-64 941kB - + coin-or-cgl 0.60.7 h516709c_0 conda-forge/linux-64 551kB - + coin-or-clp 1.17.8 h1ee7a9c_0 conda-forge/linux-64 1MB - + coin-or-osi 0.108.8 ha2443b9_0 conda-forge/linux-64 389kB - + coin-or-utils 2.11.9 hee58242_0 conda-forge/linux-64 687kB - + coincbc 2.10.10 0_metapackage conda-forge/noarch 12kB - + configargparse 1.5.3 pyhd8ed1ab_0 conda-forge/noarch 33kB - + connection_pool 0.0.3 pyhd3deb0d_0 conda-forge/noarch 8kB - + contourpy 1.0.7 py310hdf3cbec_0 conda-forge/linux-64 216kB - + cryptography 39.0.0 py310h65dfdc0_0 conda-forge/linux-64 1MB - + cycler 0.11.0 pyhd8ed1ab_0 conda-forge/noarch 10kB - + datrie 0.8.2 py310h5764c6d_6 conda-forge/linux-64 148kB - + dbus 1.13.6 h5008d03_3 conda-forge/linux-64 619kB - + docutils 0.20.1 py310hff52083_0 conda-forge/linux-64 721kB - + dpath 2.1.6 pyha770c72_0 conda-forge/noarch 21kB - + expat 2.5.0 hcb278e6_1 conda-forge/linux-64 137kB - + fftw 3.3.10 nompi_hc118613_107 conda-forge/linux-64 2MB - + filelock 3.12.0 pyhd8ed1ab_0 conda-forge/noarch 15kB - + font-ttf-dejavu-sans-mono 2.37 hab24e00_0 conda-forge/noarch 397kB - + font-ttf-inconsolata 3.000 h77eed37_0 conda-forge/noarch 97kB - + font-ttf-source-code-pro 2.038 h77eed37_0 conda-forge/noarch 701kB - + font-ttf-ubuntu 0.83 hab24e00_0 conda-forge/noarch 2MB - + fontconfig 2.14.2 h14ed4e7_0 conda-forge/linux-64 272kB - + fonts-conda-ecosystem 1 0 conda-forge/noarch 4kB - + fonts-conda-forge 1 0 conda-forge/noarch 4kB - + fonttools 4.39.4 py310h2372a71_0 conda-forge/linux-64 2MB - + freetype 2.12.1 hca18f0e_1 conda-forge/linux-64 626kB - + fribidi 1.0.10 h36c2ea0_0 conda-forge/linux-64 114kB - + gdk-pixbuf 2.42.8 hff1cb4f_1 conda-forge/linux-64 612kB - + gettext 0.21.1 h27087fc_0 conda-forge/linux-64 4MB - + giflib 5.2.1 h0b41bf4_3 conda-forge/linux-64 77kB - + gitdb 4.0.10 pyhd8ed1ab_0 conda-forge/noarch 52kB - + gitpython 3.1.31 pyhd8ed1ab_0 conda-forge/noarch 142kB - + glib 2.76.2 hfc55251_0 conda-forge/linux-64 484kB - + glib-tools 2.76.2 hfc55251_0 conda-forge/linux-64 112kB - + graphite2 1.3.13 h58526e2_1001 conda-forge/linux-64 105kB - + graphviz 7.0.5 h2e5815a_0 conda-forge/linux-64 2MB - + gsl 2.7 he838d99_0 conda-forge/linux-64 3MB - + gst-plugins-base 1.21.3 h4243ec0_1 conda-forge/linux-64 3MB - + gstreamer 1.21.3 h25f0c4b_1 conda-forge/linux-64 2MB - + gstreamer-orc 0.4.33 h166bdaf_0 conda-forge/linux-64 306kB - + gtk2 2.24.33 h90689f9_2 conda-forge/linux-64 8MB - + gts 0.7.6 h64030ff_2 conda-forge/linux-64 421kB - + harfbuzz 6.0.0 h8e241bc_0 conda-forge/linux-64 1MB - + htslib 1.16 h6bc39ce_0 bioconda/linux-64 2MB - + humanfriendly 10.0 py310hff52083_4 conda-forge/linux-64 123kB - + icu 70.1 h27087fc_0 conda-forge/linux-64 14MB - + idna 3.4 pyhd8ed1ab_0 conda-forge/noarch Cached - + importlib-metadata 6.6.0 pyha770c72_0 conda-forge/noarch 26kB - + importlib_resources 5.12.0 pyhd8ed1ab_0 conda-forge/noarch 31kB - + jack 1.9.22 h11f4161_0 conda-forge/linux-64 464kB - + jinja2 3.1.2 pyhd8ed1ab_1 conda-forge/noarch 101kB - + jpeg 9e h0b41bf4_3 conda-forge/linux-64 240kB - + jsonschema 4.17.3 pyhd8ed1ab_0 conda-forge/noarch 70kB - + jupyter_core 5.3.0 py310hff52083_0 conda-forge/linux-64 91kB - + keyutils 1.6.1 h166bdaf_0 conda-forge/linux-64 Cached - + kiwisolver 1.4.4 py310hbf28c38_1 conda-forge/linux-64 77kB - + krb5 1.20.1 hf9c8cef_0 conda-forge/linux-64 1MB - + lame 3.100 h166bdaf_1003 conda-forge/linux-64 508kB - + lcms2 2.14 h6ed2654_0 conda-forge/linux-64 262kB - + ld_impl_linux-64 2.40 h41732ed_0 conda-forge/linux-64 Cached - + lerc 4.0.0 h27087fc_0 conda-forge/linux-64 282kB - + libblas 3.9.0 16_linux64_openblas conda-forge/linux-64 13kB - + libbrotlicommon 1.0.9 h166bdaf_8 conda-forge/linux-64 67kB - + libbrotlidec 1.0.9 h166bdaf_8 conda-forge/linux-64 34kB - + libbrotlienc 1.0.9 h166bdaf_8 conda-forge/linux-64 295kB - + libcap 2.66 ha37c62d_0 conda-forge/linux-64 100kB - + libcblas 3.9.0 16_linux64_openblas conda-forge/linux-64 13kB - + libclang 15.0.7 default_h7634d5b_2 conda-forge/linux-64 133kB - + libclang13 15.0.7 default_h9986a30_2 conda-forge/linux-64 10MB - + libcups 2.3.3 h36d4200_3 conda-forge/linux-64 5MB - + libcurl 7.87.0 h6312ad2_0 conda-forge/linux-64 347kB - + libdb 6.2.32 h9c3ff4c_0 conda-forge/linux-64 24MB - + libdeflate 1.13 h166bdaf_0 conda-forge/linux-64 80kB - + libedit 3.1.20191231 he28a2e2_2 conda-forge/linux-64 Cached - + libev 4.33 h516909a_1 conda-forge/linux-64 Cached - + libevent 2.1.10 h9b69904_4 conda-forge/linux-64 1MB - + libexpat 2.5.0 hcb278e6_1 conda-forge/linux-64 78kB - + libffi 3.4.2 h7f98852_5 conda-forge/linux-64 Cached - + libflac 1.4.2 h27087fc_0 conda-forge/linux-64 421kB - + libgcc-ng 12.2.0 h65d4601_19 conda-forge/linux-64 Cached - + libgcrypt 1.10.1 h166bdaf_0 conda-forge/linux-64 720kB - + libgd 2.3.3 h18fbbfe_3 conda-forge/linux-64 272kB - + libgfortran-ng 12.2.0 h69a702a_19 conda-forge/linux-64 23kB - + libgfortran5 12.2.0 h337968e_19 conda-forge/linux-64 2MB - + libglib 2.76.2 hebfc3b9_0 conda-forge/linux-64 3MB - + libgomp 12.2.0 h65d4601_19 conda-forge/linux-64 Cached - + libgpg-error 1.46 h620e276_0 conda-forge/linux-64 258kB - + libiconv 1.17 h166bdaf_0 conda-forge/linux-64 Cached - + liblapack 3.9.0 16_linux64_openblas conda-forge/linux-64 13kB - + liblapacke 3.9.0 16_linux64_openblas conda-forge/linux-64 13kB - + libllvm15 15.0.7 hadd5161_1 conda-forge/linux-64 33MB - + libnghttp2 1.51.0 hdcd2b5c_0 conda-forge/linux-64 623kB - + libnsl 2.0.0 h7f98852_0 conda-forge/linux-64 Cached - + libogg 1.3.4 h7f98852_1 conda-forge/linux-64 211kB - + libopenblas 0.3.21 pthreads_h78a6416_3 conda-forge/linux-64 11MB - + libopus 1.3.1 h7f98852_1 conda-forge/linux-64 261kB - + libpng 1.6.39 h753d276_0 conda-forge/linux-64 283kB - + libpq 15.1 h2baec63_3 conda-forge/linux-64 2MB - + librsvg 2.54.4 h7abd40a_0 conda-forge/linux-64 7MB - + libsndfile 1.2.0 hb75c966_0 conda-forge/linux-64 350kB - + libsqlite 3.42.0 h2797004_0 conda-forge/linux-64 829kB - + libssh2 1.10.0 haa6b8db_3 conda-forge/linux-64 239kB - + libstdcxx-ng 12.2.0 h46fd767_19 conda-forge/linux-64 Cached - + libsystemd0 252 h2a991cd_0 conda-forge/linux-64 393kB - + libtiff 4.4.0 h0e0dad5_3 conda-forge/linux-64 658kB - + libtool 2.4.7 h27087fc_0 conda-forge/linux-64 412kB - + libudev1 253 h0b41bf4_0 conda-forge/linux-64 119kB - + libuuid 2.38.1 h0b41bf4_0 conda-forge/linux-64 Cached - + libvorbis 1.3.7 h9c3ff4c_0 conda-forge/linux-64 286kB - + libwebp 1.2.4 h522a892_0 conda-forge/linux-64 90kB - + libwebp-base 1.2.4 h166bdaf_0 conda-forge/linux-64 413kB - + libxcb 1.13 h7f98852_1004 conda-forge/linux-64 400kB - + libxkbcommon 1.5.0 h79f4944_1 conda-forge/linux-64 563kB - + libxml2 2.10.3 hca2bb57_4 conda-forge/linux-64 714kB - + libzlib 1.2.13 h166bdaf_4 conda-forge/linux-64 Cached - + lz4-c 1.9.4 hcb278e6_0 conda-forge/linux-64 Cached - + markupsafe 2.1.2 py310h1fa729e_0 conda-forge/linux-64 23kB - + matplotlib 3.7.1 py310hff52083_0 conda-forge/linux-64 8kB - + matplotlib-base 3.7.1 py310he60537e_0 conda-forge/linux-64 7MB - + mpg123 1.31.3 hcb278e6_0 conda-forge/linux-64 485kB - + munkres 1.0.7 py_1 bioconda/noarch 10kB - + mysql-common 8.0.32 h14678bc_0 conda-forge/linux-64 803kB - + mysql-libs 8.0.32 h54cf53e_0 conda-forge/linux-64 2MB - + nbformat 5.8.0 pyhd8ed1ab_0 conda-forge/noarch 101kB - + ncurses 6.3 h27087fc_1 conda-forge/linux-64 Cached - + nspr 4.35 h27087fc_0 conda-forge/linux-64 227kB - + nss 3.89 he45b914_0 conda-forge/linux-64 2MB - + numpy 1.24.3 py310ha4c1d20_0 conda-forge/linux-64 7MB - + openjpeg 2.5.0 h7d73246_1 conda-forge/linux-64 546kB - + openssl 1.1.1t h0b41bf4_0 conda-forge/linux-64 2MB - + packaging 23.1 pyhd8ed1ab_0 conda-forge/noarch 46kB - + pango 1.50.14 hd33c08f_0 conda-forge/linux-64 438kB - + pcre2 10.40 hc3806b6_0 conda-forge/linux-64 2MB - + perl 5.32.1 2_h7f98852_perl5 conda-forge/linux-64 15MB - + pillow 9.2.0 py310h454ad03_3 conda-forge/linux-64 47MB - + pip 23.1.2 pyhd8ed1ab_0 conda-forge/noarch 1MB - + pixman 0.40.0 h36c2ea0_0 conda-forge/linux-64 643kB - + pkgutil-resolve-name 1.3.10 pyhd8ed1ab_0 conda-forge/noarch 9kB - + plac 1.3.5 pyhd8ed1ab_0 conda-forge/noarch 23kB - + platformdirs 3.5.1 pyhd8ed1ab_0 conda-forge/noarch 19kB - + ply 3.11 py_1 conda-forge/noarch 45kB - + psutil 5.9.5 py310h1fa729e_0 conda-forge/linux-64 362kB - + pthread-stubs 0.4 h36c2ea0_1001 conda-forge/linux-64 6kB - + pulp 2.7.0 py310hff52083_0 conda-forge/linux-64 141kB - + pulseaudio 16.1 h4ab2085_1 conda-forge/linux-64 2MB - + pycparser 2.21 pyhd8ed1ab_0 conda-forge/noarch Cached - + pygments 2.15.1 pyhd8ed1ab_0 conda-forge/noarch 841kB - + pyopenssl 23.1.1 pyhd8ed1ab_0 conda-forge/noarch Cached - + pyparsing 3.0.9 pyhd8ed1ab_0 conda-forge/noarch 81kB - + pyqt 5.15.7 py310hab646b1_3 conda-forge/linux-64 5MB - + pyqt5-sip 12.11.0 py310heca2aa9_3 conda-forge/linux-64 85kB - + pyrsistent 0.19.3 py310h1fa729e_0 conda-forge/linux-64 100kB - + pysam 0.19.1 py310hff46b53_1 bioconda/linux-64 3MB - + pysocks 1.7.1 pyha2e5f31_6 conda-forge/noarch Cached - + python 3.10.8 h257c98d_0_cpython conda-forge/linux-64 23MB - + python-dateutil 2.8.2 pyhd8ed1ab_0 conda-forge/noarch 246kB - + python-fastjsonschema 2.16.3 pyhd8ed1ab_0 conda-forge/noarch 225kB - + python_abi 3.10 3_cp310 conda-forge/linux-64 Cached - + pyyaml 6.0 py310h5764c6d_5 conda-forge/linux-64 176kB - + qt-main 5.15.6 h18908ee_6 conda-forge/linux-64 55MB - + readline 8.2 h8228510_1 conda-forge/linux-64 Cached - + requests 2.29.0 pyhd8ed1ab_0 conda-forge/noarch 57kB - + reretry 0.11.8 pyhd8ed1ab_0 conda-forge/noarch 12kB - + samtools 1.15.1 h6899075_1 bioconda/linux-64 406kB - + setuptools 67.7.2 pyhd8ed1ab_0 conda-forge/noarch 583kB - + sip 6.7.9 py310hc6cd4ac_0 conda-forge/linux-64 493kB - + six 1.16.0 pyh6c4a22f_0 conda-forge/noarch 14kB - + smart_open 6.3.0 pyhd8ed1ab_1 conda-forge/noarch 47kB - + smmap 3.0.5 pyh44b312d_0 conda-forge/noarch 23kB - + snakemake-minimal 7.25.4 pyhdfd78af_0 bioconda/noarch 266kB - + stopit 1.1.2 py_0 conda-forge/noarch 16kB - + tabulate 0.9.0 pyhd8ed1ab_1 conda-forge/noarch 36kB - + throttler 1.2.1 pyhd8ed1ab_0 conda-forge/noarch 11kB - + tk 8.6.12 h27826a3_0 conda-forge/linux-64 Cached - + toml 0.10.2 pyhd8ed1ab_0 conda-forge/noarch 18kB - + tomli 2.0.1 pyhd8ed1ab_0 conda-forge/noarch 16kB - + toposort 1.10 pyhd8ed1ab_0 conda-forge/noarch 14kB - + tornado 6.3.2 py310h2372a71_0 conda-forge/linux-64 639kB - + traitlets 5.9.0 pyhd8ed1ab_0 conda-forge/noarch 98kB - + typing-extensions 4.5.0 hd8ed1ab_0 conda-forge/noarch 10kB - + typing_extensions 4.5.0 pyha770c72_0 conda-forge/noarch 31kB - + tzdata 2023c h71feb2d_0 conda-forge/noarch Cached - + unicodedata2 15.0.0 py310h5764c6d_0 conda-forge/linux-64 512kB - + urllib3 1.26.15 pyhd8ed1ab_0 conda-forge/noarch Cached - + wheel 0.40.0 pyhd8ed1ab_0 conda-forge/noarch Cached - + wrapt 1.15.0 py310h1fa729e_0 conda-forge/linux-64 54kB - + xcb-util 0.4.0 h516909a_0 conda-forge/linux-64 20kB - + xcb-util-image 0.4.0 h166bdaf_0 conda-forge/linux-64 24kB - + xcb-util-keysyms 0.4.0 h516909a_0 conda-forge/linux-64 12kB - + xcb-util-renderutil 0.3.9 h166bdaf_0 conda-forge/linux-64 16kB - + xcb-util-wm 0.4.1 h516909a_0 conda-forge/linux-64 56kB - + xkeyboard-config 2.38 h0b41bf4_0 conda-forge/linux-64 882kB - + xorg-kbproto 1.0.7 h7f98852_1002 conda-forge/linux-64 27kB - + xorg-libice 1.0.10 h7f98852_0 conda-forge/linux-64 59kB - + xorg-libsm 1.2.3 hd9c2040_1000 conda-forge/linux-64 26kB - + xorg-libx11 1.8.4 h0b41bf4_0 conda-forge/linux-64 830kB - + xorg-libxau 1.0.11 hd590300_0 conda-forge/linux-64 14kB - + xorg-libxdmcp 1.1.3 h7f98852_0 conda-forge/linux-64 19kB - + xorg-libxext 1.3.4 h0b41bf4_2 conda-forge/linux-64 50kB - + xorg-libxrender 0.9.10 h7f98852_1003 conda-forge/linux-64 33kB - + xorg-renderproto 0.11.1 h7f98852_1002 conda-forge/linux-64 10kB - + xorg-xextproto 7.3.0 h0b41bf4_1003 conda-forge/linux-64 30kB - + xorg-xproto 7.0.31 h7f98852_1007 conda-forge/linux-64 75kB - + xz 5.2.6 h166bdaf_0 conda-forge/linux-64 Cached - + yaml 0.2.5 h7f98852_2 conda-forge/linux-64 89kB - + yte 1.5.1 py310hff52083_1 conda-forge/linux-64 18kB - + zipp 3.15.0 pyhd8ed1ab_0 conda-forge/noarch 17kB - + zlib 1.2.13 h166bdaf_4 conda-forge/linux-64 94kB - + zstd 1.5.2 h3eb15da_6 conda-forge/linux-64 Cached - - Summary: - - Install: 230 packages - - Total download: 357MB - -─────────────────────────────────────────────────────────────────────────────────────────────────── - - - - -Downloading and Extracting Packages - -Preparing transaction: ...working... -done - -Verifying transaction: ...working... -done - -Executing transaction: ...working... - - -done - -# -# To activate this environment, use -# -# $ conda activate snakemake-tutorial -# -# To deactivate an active environment, use -# -# $ conda deactivate - - - ---> 3c11703ad114 - -Step 6/15 : env PATH /root/mambaforge/envs/snakemake-tutorial/bin:$PATH - - - ---> Running in 5758f3dd4146 - - ---> 48b5620a8619 - -Step 7/15 : run python3 -m pip install latch - - - ---> Running in 0e3eccd0beb3 - -Collecting latch - - Downloading latch-2.19.11-py3-none-any.whl (150 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 150.6/150.6 kB 4.8 MB/s eta 0:00:00 - - -Collecting awscli==1.25.22 (from latch) - - Downloading awscli-1.25.22-py3-none-any.whl (3.9 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.9/3.9 MB 58.3 MB/s eta 0:00:00 - - -Collecting asyncssh==2.12.0 (from latch) - - Downloading asyncssh-2.12.0-py3-none-any.whl (346 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 346.7/346.7 kB 41.3 MB/s eta 0:00:00 - - -Collecting aioconsole==0.5.1 (from latch) - - Downloading aioconsole-0.5.1-py3-none-any.whl (30 kB) - -Collecting kubernetes>=24.2.0 (from latch) - - Downloading kubernetes-26.1.0-py2.py3-none-any.whl (1.4 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.4/1.4 MB 71.6 MB/s eta 0:00:00 - - -Collecting pyjwt>=0.2.0 (from latch) - - Downloading PyJWT-2.7.0-py3-none-any.whl (22 kB) - -Requirement already satisfied: requests>=2.28.1 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from latch) (2.29.0) - -Collecting click>=8.0 (from latch) - - Downloading click-8.1.3-py3-none-any.whl (96 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 96.6/96.6 kB 14.8 MB/s eta 0:00:00 - - -Collecting docker>=5.0 (from latch) - - Downloading docker-6.1.2-py3-none-any.whl (148 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 148.1/148.1 kB 23.4 MB/s eta 0:00:00 - - -Collecting paramiko>=2.11.0 (from latch) - - Downloading paramiko-3.1.0-py3-none-any.whl (211 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 211.2/211.2 kB 28.6 MB/s eta 0:00:00 - - -Collecting scp>=0.14.0 (from latch) - - Downloading scp-0.14.5-py2.py3-none-any.whl (8.7 kB) - -Collecting boto3>=1.24.22 (from latch) - - Using cached boto3-1.26.137-py3-none-any.whl (135 kB) - -Collecting tqdm>=4.63.0 (from latch) - - Downloading tqdm-4.65.0-py3-none-any.whl (77 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 77.1/77.1 kB 11.9 MB/s eta 0:00:00 - - -Collecting lytekit==0.14.10 (from latch) - - Downloading lytekit-0.14.10-py3-none-any.whl (391 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 391.8/391.8 kB 43.4 MB/s eta 0:00:00 - - -Collecting lytekitplugins-pods==0.4.0 (from latch) - - Downloading lytekitplugins_pods-0.4.0-py3-none-any.whl (4.3 kB) - -Requirement already satisfied: typing-extensions==4.5.0 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from latch) (4.5.0) - -Collecting apscheduler==3.9.1 (from latch) - - Downloading APScheduler-3.9.1-py2.py3-none-any.whl (59 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 59.5/59.5 kB 10.5 MB/s eta 0:00:00 - - -Collecting uvloop==0.17.0 (from latch) - - Downloading uvloop-0.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.1 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.1/4.1 MB 83.0 MB/s eta 0:00:00 - - -Collecting websockets==10.3 (from latch) - - Downloading websockets-10.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (111 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 111.5/111.5 kB 16.7 MB/s eta 0:00:00 - - -Collecting prompt-toolkit==3.0.33 (from latch) - - Downloading prompt_toolkit-3.0.33-py3-none-any.whl (383 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 383.6/383.6 kB 39.0 MB/s eta 0:00:00 - - -Collecting watchfiles==0.18.1 (from latch) - - Downloading watchfiles-0.18.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.2 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.2/1.2 MB 70.7 MB/s eta 0:00:00 - - -Collecting gql==3.4.0 (from latch) - - Downloading gql-3.4.0-py2.py3-none-any.whl (65 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 65.2/65.2 kB 11.3 MB/s eta 0:00:00 - - -Collecting graphql-core==3.2.3 (from latch) - - Downloading graphql_core-3.2.3-py3-none-any.whl (202 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 202.9/202.9 kB 28.2 MB/s eta 0:00:00 - - -Collecting requests-toolbelt==0.10.1 (from latch) - - Downloading requests_toolbelt-0.10.1-py2.py3-none-any.whl (54 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 54.5/54.5 kB 8.7 MB/s eta 0:00:00 - - -Requirement already satisfied: setuptools>=0.7 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from apscheduler==3.9.1->latch) (67.7.2) - -Requirement already satisfied: six>=1.4.0 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from apscheduler==3.9.1->latch) (1.16.0) - -Collecting pytz (from apscheduler==3.9.1->latch) - - Downloading pytz-2023.3-py2.py3-none-any.whl (502 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 502.3/502.3 kB 49.0 MB/s eta 0:00:00 - - -Collecting tzlocal!=3.*,>=2.0 (from apscheduler==3.9.1->latch) - - Downloading tzlocal-5.0.1-py3-none-any.whl (20 kB) - -Requirement already satisfied: cryptography>=3.1 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from asyncssh==2.12.0->latch) (39.0.0) - -Collecting botocore==1.27.22 (from awscli==1.25.22->latch) - - Downloading botocore-1.27.22-py3-none-any.whl (8.9 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.9/8.9 MB 66.8 MB/s eta 0:00:00 - - -Collecting docutils<0.17,>=0.10 (from awscli==1.25.22->latch) - - Using cached docutils-0.16-py2.py3-none-any.whl (548 kB) - -Collecting s3transfer<0.7.0,>=0.6.0 (from awscli==1.25.22->latch) - - Using cached s3transfer-0.6.1-py3-none-any.whl (79 kB) - -Collecting PyYAML<5.5,>=3.10 (from awscli==1.25.22->latch) - - Downloading PyYAML-5.4.1.tar.gz (175 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 175.1/175.1 kB 27.0 MB/s eta 0:00:00 - - - Installing build dependencies: started - - Installing build dependencies: finished with status 'done' - - Getting requirements to build wheel: started - - Getting requirements to build wheel: finished with status 'done' - - Preparing metadata (pyproject.toml): started - - Preparing metadata (pyproject.toml): finished with status 'done' - -Collecting colorama<0.4.5,>=0.2.5 (from awscli==1.25.22->latch) - - Using cached colorama-0.4.4-py2.py3-none-any.whl (16 kB) - -Collecting rsa<4.8,>=3.1.2 (from awscli==1.25.22->latch) - - Using cached rsa-4.7.2-py3-none-any.whl (34 kB) - -Collecting yarl<2.0,>=1.6 (from gql==3.4.0->latch) - - Downloading yarl-1.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (268 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 268.8/268.8 kB 35.2 MB/s eta 0:00:00 - - -Collecting backoff<3.0,>=1.11.1 (from gql==3.4.0->latch) - - Downloading backoff-2.2.1-py3-none-any.whl (15 kB) - -Collecting lyteidl==0.2.0a0 (from lytekit==0.14.10->latch) - - Downloading lyteidl-0.2.0a0-py3-none-any.whl (162 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 162.2/162.2 kB 24.9 MB/s eta 0:00:00 - - -Requirement already satisfied: wheel<1.0.0,>=0.30.0 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch) (0.40.0) - -Collecting pandas<2.0.0,>=1.0.0 (from lytekit==0.14.10->latch) - - Downloading pandas-1.5.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (12.1 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 12.1/12.1 MB 81.4 MB/s eta 0:00:00 - - -Collecting pyarrow<7.0.0,>=4.0.0 (from lytekit==0.14.10->latch) - - Downloading pyarrow-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (25.6 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 25.6/25.6 MB 53.5 MB/s eta 0:00:00 - - -Collecting croniter<4.0.0,>=0.3.20 (from lytekit==0.14.10->latch) - - Downloading croniter-1.3.14-py2.py3-none-any.whl (18 kB) - -Collecting deprecated<2.0,>=1.0 (from lytekit==0.14.10->latch) - - Downloading Deprecated-1.2.13-py2.py3-none-any.whl (9.6 kB) - -Collecting docker>=5.0 (from latch) - - Downloading docker-5.0.3-py2.py3-none-any.whl (146 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 146.2/146.2 kB 21.7 MB/s eta 0:00:00 - - -Requirement already satisfied: python-dateutil>=2.1 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch) (2.8.2) - -Collecting grpcio!=1.45.0,<2.0,>=1.43.0 (from lytekit==0.14.10->latch) - - Downloading grpcio-1.54.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.1 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 5.1/5.1 MB 89.4 MB/s eta 0:00:00 - - -Collecting grpcio-status!=1.45.0,>=1.43 (from lytekit==0.14.10->latch) - - Downloading grpcio_status-1.54.2-py3-none-any.whl (5.1 kB) - -Collecting protobuf<4,>=3.6.1 (from lytekit==0.14.10->latch) - - Downloading protobuf-3.20.3-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (1.1 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.1/1.1 MB 66.5 MB/s eta 0:00:00 - - -Collecting python-json-logger>=2.0.0 (from lytekit==0.14.10->latch) - - Downloading python_json_logger-2.0.7-py3-none-any.whl (8.1 kB) - -Collecting pytimeparse<2.0.0,>=1.1.8 (from lytekit==0.14.10->latch) - - Downloading pytimeparse-1.1.8-py2.py3-none-any.whl (10.0 kB) - -Collecting keyring>=18.0.1 (from lytekit==0.14.10->latch) - - Downloading keyring-23.13.1-py3-none-any.whl (37 kB) - -Collecting responses>=0.10.7 (from lytekit==0.14.10->latch) - - Downloading responses-0.23.1-py3-none-any.whl (52 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 52.1/52.1 kB 8.7 MB/s eta 0:00:00 - - -Collecting sortedcontainers<3.0.0,>=1.5.9 (from lytekit==0.14.10->latch) - - Downloading sortedcontainers-2.4.0-py2.py3-none-any.whl (29 kB) - -Collecting statsd<4.0.0,>=3.0.0 (from lytekit==0.14.10->latch) - - Downloading statsd-3.3.0-py2.py3-none-any.whl (11 kB) - -Requirement already satisfied: urllib3<2.0.0,>=1.22 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch) (1.26.15) - -Requirement already satisfied: wrapt<2.0.0,>=1.0.0 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch) (1.15.0) - -Collecting retry==0.9.2 (from lytekit==0.14.10->latch) - - Downloading retry-0.9.2-py2.py3-none-any.whl (8.0 kB) - -Collecting dataclasses-json>=0.5.2 (from lytekit==0.14.10->latch) - - Downloading dataclasses_json-0.5.7-py3-none-any.whl (25 kB) - -Requirement already satisfied: jsonschema>=4.5.1 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch) (4.17.3) - -Collecting marshmallow-jsonschema>=0.12.0 (from lytekit==0.14.10->latch) - - Downloading marshmallow_jsonschema-0.13.0-py3-none-any.whl (11 kB) - -Collecting natsort>=7.0.1 (from lytekit==0.14.10->latch) - - Downloading natsort-8.3.1-py3-none-any.whl (38 kB) - -Collecting docker-image-py>=0.1.10 (from lytekit==0.14.10->latch) - - Downloading docker-image-py-0.1.12.tar.gz (8.2 kB) - - Preparing metadata (setup.py): started - - Preparing metadata (setup.py): finished with status 'done' - -Collecting docstring-parser>=0.9.0 (from lytekit==0.14.10->latch) - - Downloading docstring_parser-0.15-py3-none-any.whl (36 kB) - -Collecting diskcache>=5.2.1 (from lytekit==0.14.10->latch) - - Downloading diskcache-5.6.1-py3-none-any.whl (45 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 45.6/45.6 kB 7.5 MB/s eta 0:00:00 - - -Collecting cloudpickle>=2.0.0 (from lytekit==0.14.10->latch) - - Downloading cloudpickle-2.2.1-py3-none-any.whl (25 kB) - -Collecting cookiecutter>=1.7.3 (from lytekit==0.14.10->latch) - - Downloading cookiecutter-2.1.1-py2.py3-none-any.whl (36 kB) - -Collecting numpy<1.22.0 (from lytekit==0.14.10->latch) - - Downloading numpy-1.21.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (15.9 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 15.9/15.9 MB 75.7 MB/s eta 0:00:00 - - -Collecting wcwidth (from prompt-toolkit==3.0.33->latch) - - Downloading wcwidth-0.2.6-py2.py3-none-any.whl (29 kB) - -Collecting anyio>=3.0.0 (from watchfiles==0.18.1->latch) - - Downloading anyio-3.6.2-py3-none-any.whl (80 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 80.6/80.6 kB 12.7 MB/s eta 0:00:00 - - -Collecting jmespath<2.0.0,>=0.7.1 (from botocore==1.27.22->awscli==1.25.22->latch) - - Using cached jmespath-1.0.1-py3-none-any.whl (20 kB) - -Collecting googleapis-common-protos (from lyteidl==0.2.0a0->lytekit==0.14.10->latch) - - Downloading googleapis_common_protos-1.59.0-py2.py3-none-any.whl (223 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 223.6/223.6 kB 31.5 MB/s eta 0:00:00 - - -Collecting protoc-gen-swagger (from lyteidl==0.2.0a0->lytekit==0.14.10->latch) - - Downloading protoc_gen_swagger-0.1.0-py2.py3-none-any.whl (9.4 kB) - -Collecting decorator>=3.4.2 (from retry==0.9.2->lytekit==0.14.10->latch) - - Downloading decorator-5.1.1-py3-none-any.whl (9.1 kB) - -Collecting py<2.0.0,>=1.4.26 (from retry==0.9.2->lytekit==0.14.10->latch) - - Downloading py-1.11.0-py2.py3-none-any.whl (98 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 98.7/98.7 kB 15.6 MB/s eta 0:00:00 - - -INFO: pip is looking at multiple versions of boto3 to determine which version is compatible with other requirements. This could take a while. - -Collecting boto3>=1.24.22 (from latch) - - Downloading boto3-1.26.136-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 21.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.135-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.4 MB/s eta 0:00:00 - - - Downloading boto3-1.26.134-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.133-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.6 MB/s eta 0:00:00 - - - Downloading boto3-1.26.132-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.9 MB/s eta 0:00:00 - - - Downloading boto3-1.26.131-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.9 MB/s eta 0:00:00 - - - Downloading boto3-1.26.130-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.8 MB/s eta 0:00:00 - - -INFO: pip is looking at multiple versions of boto3 to determine which version is compatible with other requirements. This could take a while. - - Downloading boto3-1.26.129-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.6 MB/s eta 0:00:00 - - - Downloading boto3-1.26.128-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.9 MB/s eta 0:00:00 - - - Downloading boto3-1.26.127-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.6 MB/s eta 0:00:00 - - - Downloading boto3-1.26.126-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.125-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.7 MB/s eta 0:00:00 - - -INFO: This is taking longer than usual. You might need to provide the dependency resolver with stricter constraints to reduce runtime. See https://pip.pypa.io/warnings/backtracking for guidance. If you want to abort this run, press Ctrl + C. - - Downloading boto3-1.26.124-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.0 MB/s eta 0:00:00 - - - Downloading boto3-1.26.123-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.3 MB/s eta 0:00:00 - - - Downloading boto3-1.26.122-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 21.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.121-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.3 MB/s eta 0:00:00 - - - Downloading boto3-1.26.120-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.9 MB/s eta 0:00:00 - - - Downloading boto3-1.26.119-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.5 MB/s eta 0:00:00 - - - Downloading boto3-1.26.118-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.5 MB/s eta 0:00:00 - - - Downloading boto3-1.26.117-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.3 MB/s eta 0:00:00 - - - Downloading boto3-1.26.116-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.6 MB/s eta 0:00:00 - - - Downloading boto3-1.26.115-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.8 MB/s eta 0:00:00 - - - Downloading boto3-1.26.114-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.4 MB/s eta 0:00:00 - - - Downloading boto3-1.26.113-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.5 MB/s eta 0:00:00 - - - Downloading boto3-1.26.112-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.111-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.6 MB/s eta 0:00:00 - - - Downloading boto3-1.26.110-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 21.4 MB/s eta 0:00:00 - - - Downloading boto3-1.26.109-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.8 MB/s eta 0:00:00 - - - Downloading boto3-1.26.108-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.6 MB/s eta 0:00:00 - - - Downloading boto3-1.26.107-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 21.5 MB/s eta 0:00:00 - - - Downloading boto3-1.26.106-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 21.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.105-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.0 MB/s eta 0:00:00 - - - Downloading boto3-1.26.104-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.8 MB/s eta 0:00:00 - - - Downloading boto3-1.26.103-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.5 MB/s eta 0:00:00 - - - Downloading boto3-1.26.102-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.5 MB/s eta 0:00:00 - - - Downloading boto3-1.26.101-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.5/135.5 kB 21.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.100-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.5/135.5 kB 20.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.99-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.5/135.5 kB 21.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.98-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.5/135.5 kB 21.5 MB/s eta 0:00:00 - - - Downloading boto3-1.26.97-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.5/135.5 kB 19.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.96-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.5/135.5 kB 21.8 MB/s eta 0:00:00 - - - Downloading boto3-1.26.95-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.5/135.5 kB 19.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.94-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.1/135.1 kB 21.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.93-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.1/135.1 kB 21.8 MB/s eta 0:00:00 - - - Downloading boto3-1.26.92-py3-none-any.whl (134 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 21.3 MB/s eta 0:00:00 - - - Downloading boto3-1.26.91-py3-none-any.whl (134 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 20.6 MB/s eta 0:00:00 - - - Downloading boto3-1.26.90-py3-none-any.whl (134 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 19.0 MB/s eta 0:00:00 - - - Downloading boto3-1.26.89-py3-none-any.whl (134 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 20.3 MB/s eta 0:00:00 - - - Downloading boto3-1.26.88-py3-none-any.whl (134 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 19.6 MB/s eta 0:00:00 - - - Downloading boto3-1.26.87-py3-none-any.whl (134 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 19.9 MB/s eta 0:00:00 - - - Downloading boto3-1.26.86-py3-none-any.whl (134 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 19.8 MB/s eta 0:00:00 - - - Downloading boto3-1.26.85-py3-none-any.whl (134 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 6.0 MB/s eta 0:00:00 - - - Downloading boto3-1.26.84-py3-none-any.whl (134 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 19.8 MB/s eta 0:00:00 - - - Downloading boto3-1.26.83-py3-none-any.whl (134 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 18.8 MB/s eta 0:00:00 - - - Downloading boto3-1.26.82-py3-none-any.whl (134 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 20.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.81-py3-none-any.whl (134 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 20.8 MB/s eta 0:00:00 - - - Downloading boto3-1.26.80-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.9 MB/s eta 0:00:00 - - - Downloading boto3-1.26.79-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.5 MB/s eta 0:00:00 - - - Downloading boto3-1.26.78-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 21.0 MB/s eta 0:00:00 - - - Downloading boto3-1.26.77-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.76-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.0 MB/s eta 0:00:00 - - - Downloading boto3-1.26.75-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.6 MB/s eta 0:00:00 - - - Downloading boto3-1.26.74-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.5 MB/s eta 0:00:00 - - - Downloading boto3-1.26.73-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.72-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 21.5 MB/s eta 0:00:00 - - - Downloading boto3-1.26.71-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 21.0 MB/s eta 0:00:00 - - - Downloading boto3-1.26.70-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.0 MB/s eta 0:00:00 - - - Downloading boto3-1.26.69-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 21.0 MB/s eta 0:00:00 - - - Downloading boto3-1.26.68-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.67-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.8 MB/s eta 0:00:00 - - - Downloading boto3-1.26.66-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.8 MB/s eta 0:00:00 - - - Downloading boto3-1.26.65-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.4 MB/s eta 0:00:00 - - - Downloading boto3-1.26.64-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.63-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.4 MB/s eta 0:00:00 - - - Downloading boto3-1.26.62-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.6 MB/s eta 0:00:00 - - - Downloading boto3-1.26.61-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.3 MB/s eta 0:00:00 - - - Downloading boto3-1.26.60-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.9 MB/s eta 0:00:00 - - - Downloading boto3-1.26.59-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.4 MB/s eta 0:00:00 - - - Downloading boto3-1.26.58-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.8 MB/s eta 0:00:00 - - - Downloading boto3-1.26.57-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.8 MB/s eta 0:00:00 - - - Downloading boto3-1.26.56-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.6 MB/s eta 0:00:00 - - - Downloading boto3-1.26.55-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.9 MB/s eta 0:00:00 - - - Downloading boto3-1.26.54-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.53-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.8 MB/s eta 0:00:00 - - - Downloading boto3-1.26.52-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.1 MB/s eta 0:00:00 - - - Downloading boto3-1.26.51-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.1 MB/s eta 0:00:00 - - - Downloading boto3-1.26.50-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 17.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.49-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.1 MB/s eta 0:00:00 - - - Downloading boto3-1.26.48-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.3 MB/s eta 0:00:00 - - - Downloading boto3-1.26.47-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.6 MB/s eta 0:00:00 - - - Downloading boto3-1.26.46-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.45-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.3 MB/s eta 0:00:00 - - - Downloading boto3-1.26.44-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.43-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.9 MB/s eta 0:00:00 - - - Downloading boto3-1.26.42-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.41-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.40-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.6 MB/s eta 0:00:00 - - - Downloading boto3-1.26.39-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.6 MB/s eta 0:00:00 - - - Downloading boto3-1.26.38-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 21.5 MB/s eta 0:00:00 - - - Downloading boto3-1.26.37-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 21.6 MB/s eta 0:00:00 - - - Downloading boto3-1.26.36-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.5 MB/s eta 0:00:00 - - - Downloading boto3-1.26.35-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.4 MB/s eta 0:00:00 - - - Downloading boto3-1.26.34-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.1 MB/s eta 0:00:00 - - - Downloading boto3-1.26.33-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.1 MB/s eta 0:00:00 - - - Downloading boto3-1.26.32-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.5 MB/s eta 0:00:00 - - - Downloading boto3-1.26.31-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 19.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.30-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 18.9 MB/s eta 0:00:00 - - - Downloading boto3-1.26.29-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 19.0 MB/s eta 0:00:00 - - - Downloading boto3-1.26.28-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 19.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.27-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 18.6 MB/s eta 0:00:00 - - - Downloading boto3-1.26.26-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 19.6 MB/s eta 0:00:00 - - - Downloading boto3-1.26.25-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 19.0 MB/s eta 0:00:00 - - - Downloading boto3-1.26.24-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 20.3 MB/s eta 0:00:00 - - - Downloading boto3-1.26.23-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 21.6 MB/s eta 0:00:00 - - - Downloading boto3-1.26.22-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 20.3 MB/s eta 0:00:00 - - - Downloading boto3-1.26.21-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 19.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.20-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 18.9 MB/s eta 0:00:00 - - - Downloading boto3-1.26.19-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 19.1 MB/s eta 0:00:00 - - - Downloading boto3-1.26.18-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 20.1 MB/s eta 0:00:00 - - - Downloading boto3-1.26.17-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 21.1 MB/s eta 0:00:00 - - - Downloading boto3-1.26.16-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 21.5 MB/s eta 0:00:00 - - - Downloading boto3-1.26.15-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.1 MB/s eta 0:00:00 - - - Downloading boto3-1.26.14-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.4 MB/s eta 0:00:00 - - - Downloading boto3-1.26.13-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.4 MB/s eta 0:00:00 - - - Downloading boto3-1.26.12-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.0 MB/s eta 0:00:00 - - - Downloading boto3-1.26.11-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.4 MB/s eta 0:00:00 - - - Downloading boto3-1.26.10-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.9-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.3 MB/s eta 0:00:00 - - - Downloading boto3-1.26.8-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.6 MB/s eta 0:00:00 - - - Downloading boto3-1.26.7-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.3 MB/s eta 0:00:00 - - - Downloading boto3-1.26.6-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.1 MB/s eta 0:00:00 - - - Downloading boto3-1.26.5-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.6 MB/s eta 0:00:00 - - - Downloading boto3-1.26.4-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.8 MB/s eta 0:00:00 - - - Downloading boto3-1.26.3-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.3 MB/s eta 0:00:00 - - - Downloading boto3-1.26.2-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.3 MB/s eta 0:00:00 - - - Downloading boto3-1.26.1-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.0-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.9 MB/s eta 0:00:00 - - - Downloading boto3-1.25.5-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.3 MB/s eta 0:00:00 - - - Downloading boto3-1.25.4-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.3 MB/s eta 0:00:00 - - - Downloading boto3-1.25.3-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 11.4 MB/s eta 0:00:00 - - - Downloading boto3-1.25.2-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.7 MB/s eta 0:00:00 - - - Downloading boto3-1.25.1-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.9 MB/s eta 0:00:00 - - - Downloading boto3-1.25.0-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 21.3 MB/s eta 0:00:00 - - - Downloading boto3-1.24.96-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.2 MB/s eta 0:00:00 - - - Downloading boto3-1.24.95-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.3 MB/s eta 0:00:00 - - - Downloading boto3-1.24.94-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.3 MB/s eta 0:00:00 - - - Downloading boto3-1.24.93-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.6 MB/s eta 0:00:00 - - - Downloading boto3-1.24.92-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.7 MB/s eta 0:00:00 - - - Downloading boto3-1.24.91-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.9 MB/s eta 0:00:00 - - - Downloading boto3-1.24.90-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.5 MB/s eta 0:00:00 - - - Downloading boto3-1.24.89-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.1 MB/s eta 0:00:00 - - - Downloading boto3-1.24.88-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.0 MB/s eta 0:00:00 - - - Downloading boto3-1.24.87-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.0 MB/s eta 0:00:00 - - - Downloading boto3-1.24.86-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.3 MB/s eta 0:00:00 - - - Downloading boto3-1.24.85-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.4 MB/s eta 0:00:00 - - - Downloading boto3-1.24.84-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.6 MB/s eta 0:00:00 - - - Downloading boto3-1.24.83-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.6 MB/s eta 0:00:00 - - - Downloading boto3-1.24.82-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.6 MB/s eta 0:00:00 - - - Downloading boto3-1.24.81-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.1 MB/s eta 0:00:00 - - - Downloading boto3-1.24.80-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.6 MB/s eta 0:00:00 - - - Downloading boto3-1.24.79-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.3 MB/s eta 0:00:00 - - - Downloading boto3-1.24.78-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.0 MB/s eta 0:00:00 - - - Downloading boto3-1.24.77-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.1 MB/s eta 0:00:00 - - - Downloading boto3-1.24.76-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 13.1 MB/s eta 0:00:00 - - - Downloading boto3-1.24.75-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.9 MB/s eta 0:00:00 - - - Downloading boto3-1.24.74-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.2 MB/s eta 0:00:00 - - - Downloading boto3-1.24.73-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.6 MB/s eta 0:00:00 - - - Downloading boto3-1.24.72-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.2 MB/s eta 0:00:00 - - - Downloading boto3-1.24.71-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.6 MB/s eta 0:00:00 - - - Downloading boto3-1.24.70-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.4 MB/s eta 0:00:00 - - - Downloading boto3-1.24.69-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.4 MB/s eta 0:00:00 - - - Downloading boto3-1.24.68-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.3 MB/s eta 0:00:00 - - - Downloading boto3-1.24.67-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.1 MB/s eta 0:00:00 - - - Downloading boto3-1.24.66-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.5 MB/s eta 0:00:00 - - - Downloading boto3-1.24.65-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.7 MB/s eta 0:00:00 - - - Downloading boto3-1.24.64-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 21.3 MB/s eta 0:00:00 - - - Downloading boto3-1.24.63-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.9 MB/s eta 0:00:00 - - - Downloading boto3-1.24.62-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.6 MB/s eta 0:00:00 - - - Downloading boto3-1.24.61-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.7 MB/s eta 0:00:00 - - - Downloading boto3-1.24.60-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.3 MB/s eta 0:00:00 - - - Downloading boto3-1.24.59-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.1 MB/s eta 0:00:00 - - - Downloading boto3-1.24.58-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.4 MB/s eta 0:00:00 - - - Downloading boto3-1.24.57-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.1 MB/s eta 0:00:00 - - - Downloading boto3-1.24.56-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 21.0 MB/s eta 0:00:00 - - - Downloading boto3-1.24.55-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.3 MB/s eta 0:00:00 - - - Downloading boto3-1.24.54-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.3 MB/s eta 0:00:00 - - - Downloading boto3-1.24.53-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.0 MB/s eta 0:00:00 - - - Downloading boto3-1.24.52-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.4 MB/s eta 0:00:00 - - - Downloading boto3-1.24.51-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 21.5 MB/s eta 0:00:00 - - - Downloading boto3-1.24.50-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.7 MB/s eta 0:00:00 - - - Downloading boto3-1.24.49-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.2 MB/s eta 0:00:00 - - - Downloading boto3-1.24.48-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.8 MB/s eta 0:00:00 - - - Downloading boto3-1.24.47-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.7 MB/s eta 0:00:00 - - - Downloading boto3-1.24.46-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.7 MB/s eta 0:00:00 - - - Downloading boto3-1.24.45-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.3 MB/s eta 0:00:00 - - - Downloading boto3-1.24.44-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.1 MB/s eta 0:00:00 - - - Downloading boto3-1.24.43-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.0 MB/s eta 0:00:00 - - - Downloading boto3-1.24.42-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.8 MB/s eta 0:00:00 - - - Downloading boto3-1.24.41-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 9.5 MB/s eta 0:00:00 - - - Downloading boto3-1.24.40-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.3 MB/s eta 0:00:00 - - - Downloading boto3-1.24.39-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.0 MB/s eta 0:00:00 - - - Downloading boto3-1.24.38-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.0 MB/s eta 0:00:00 - - - Downloading boto3-1.24.37-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.0 MB/s eta 0:00:00 - - - Downloading boto3-1.24.36-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.6 MB/s eta 0:00:00 - - - Downloading boto3-1.24.35-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.2 MB/s eta 0:00:00 - - - Downloading boto3-1.24.34-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.4 MB/s eta 0:00:00 - - - Downloading boto3-1.24.33-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.5 MB/s eta 0:00:00 - - - Downloading boto3-1.24.32-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.6 MB/s eta 0:00:00 - - - Downloading boto3-1.24.31-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.4 MB/s eta 0:00:00 - - - Downloading boto3-1.24.30-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.8 MB/s eta 0:00:00 - - - Downloading boto3-1.24.29-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.6 MB/s eta 0:00:00 - - - Downloading boto3-1.24.28-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.8 MB/s eta 0:00:00 - - - Downloading boto3-1.24.27-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 21.3 MB/s eta 0:00:00 - - - Downloading boto3-1.24.26-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.7 MB/s eta 0:00:00 - - - Downloading boto3-1.24.25-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.3 MB/s eta 0:00:00 - - - Downloading boto3-1.24.24-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.9 MB/s eta 0:00:00 - - - Downloading boto3-1.24.23-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.4 MB/s eta 0:00:00 - - - Downloading boto3-1.24.22-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.3 MB/s eta 0:00:00 - - -Collecting websocket-client>=0.32.0 (from docker>=5.0->latch) - - Downloading websocket_client-1.5.2-py3-none-any.whl (56 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 56.6/56.6 kB 9.0 MB/s eta 0:00:00 - - -Requirement already satisfied: certifi>=14.05.14 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from kubernetes>=24.2.0->latch) (2023.5.7) - -Collecting google-auth>=1.0.1 (from kubernetes>=24.2.0->latch) - - Downloading google_auth-2.18.1-py2.py3-none-any.whl (178 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 178.9/178.9 kB 24.9 MB/s eta 0:00:00 - - -Collecting requests-oauthlib (from kubernetes>=24.2.0->latch) - - Downloading requests_oauthlib-1.3.1-py2.py3-none-any.whl (23 kB) - -Collecting bcrypt>=3.2 (from paramiko>=2.11.0->latch) - - Downloading bcrypt-4.0.1-cp36-abi3-manylinux_2_28_x86_64.whl (593 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 593.7/593.7 kB 54.4 MB/s eta 0:00:00 - - -Collecting pynacl>=1.5 (from paramiko>=2.11.0->latch) - - Downloading PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl (856 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 856.7/856.7 kB 67.4 MB/s eta 0:00:00 - - -Requirement already satisfied: charset-normalizer<4,>=2 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from requests>=2.28.1->latch) (3.1.0) - -Requirement already satisfied: idna<4,>=2.5 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from requests>=2.28.1->latch) (3.4) - -Collecting sniffio>=1.1 (from anyio>=3.0.0->watchfiles==0.18.1->latch) - - Downloading sniffio-1.3.0-py3-none-any.whl (10 kB) - -Collecting binaryornot>=0.4.4 (from cookiecutter>=1.7.3->lytekit==0.14.10->latch) - - Downloading binaryornot-0.4.4-py2.py3-none-any.whl (9.0 kB) - -Requirement already satisfied: Jinja2<4.0.0,>=2.7 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from cookiecutter>=1.7.3->lytekit==0.14.10->latch) (3.1.2) - -Collecting jinja2-time>=0.2.0 (from cookiecutter>=1.7.3->lytekit==0.14.10->latch) - - Downloading jinja2_time-0.2.0-py2.py3-none-any.whl (6.4 kB) - -Collecting python-slugify>=4.0.0 (from cookiecutter>=1.7.3->lytekit==0.14.10->latch) - - Downloading python_slugify-8.0.1-py2.py3-none-any.whl (9.7 kB) - -Requirement already satisfied: cffi>=1.12 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from cryptography>=3.1->asyncssh==2.12.0->latch) (1.15.1) - -Collecting marshmallow<4.0.0,>=3.3.0 (from dataclasses-json>=0.5.2->lytekit==0.14.10->latch) - - Downloading marshmallow-3.19.0-py3-none-any.whl (49 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 49.1/49.1 kB 7.9 MB/s eta 0:00:00 - - -Collecting marshmallow-enum<2.0.0,>=1.5.1 (from dataclasses-json>=0.5.2->lytekit==0.14.10->latch) - - Downloading marshmallow_enum-1.5.1-py2.py3-none-any.whl (4.2 kB) - -Collecting typing-inspect>=0.4.0 (from dataclasses-json>=0.5.2->lytekit==0.14.10->latch) - - Downloading typing_inspect-0.8.0-py3-none-any.whl (8.7 kB) - -Collecting regex>=2019.4.14 (from docker-image-py>=0.1.10->lytekit==0.14.10->latch) - - Downloading regex-2023.5.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (769 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 769.7/769.7 kB 62.7 MB/s eta 0:00:00 - - -Collecting cachetools<6.0,>=2.0.0 (from google-auth>=1.0.1->kubernetes>=24.2.0->latch) - - Downloading cachetools-5.3.0-py3-none-any.whl (9.3 kB) - -Collecting pyasn1-modules>=0.2.1 (from google-auth>=1.0.1->kubernetes>=24.2.0->latch) - - Downloading pyasn1_modules-0.3.0-py2.py3-none-any.whl (181 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 181.3/181.3 kB 26.0 MB/s eta 0:00:00 - - -INFO: pip is looking at multiple versions of grpcio-status to determine which version is compatible with other requirements. This could take a while. - -Collecting grpcio-status!=1.45.0,>=1.43 (from lytekit==0.14.10->latch) - - Downloading grpcio_status-1.54.0-py3-none-any.whl (5.1 kB) - - Downloading grpcio_status-1.53.1-py3-none-any.whl (5.1 kB) - - Downloading grpcio_status-1.53.0-py3-none-any.whl (5.1 kB) - - Downloading grpcio_status-1.51.3-py3-none-any.whl (5.1 kB) - - Downloading grpcio_status-1.51.1-py3-none-any.whl (5.1 kB) - - Downloading grpcio_status-1.50.0-py3-none-any.whl (14 kB) - - Downloading grpcio_status-1.49.1-py3-none-any.whl (14 kB) - -INFO: pip is looking at multiple versions of grpcio-status to determine which version is compatible with other requirements. This could take a while. - - Downloading grpcio_status-1.48.2-py3-none-any.whl (14 kB) - -Requirement already satisfied: attrs>=17.4.0 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from jsonschema>=4.5.1->lytekit==0.14.10->latch) (23.1.0) - -Requirement already satisfied: pyrsistent!=0.17.0,!=0.17.1,!=0.17.2,>=0.14.0 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from jsonschema>=4.5.1->lytekit==0.14.10->latch) (0.19.3) - -Collecting jaraco.classes (from keyring>=18.0.1->lytekit==0.14.10->latch) - - Downloading jaraco.classes-3.2.3-py3-none-any.whl (6.0 kB) - -Requirement already satisfied: importlib-metadata>=4.11.4 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from keyring>=18.0.1->lytekit==0.14.10->latch) (6.6.0) - -Collecting SecretStorage>=3.2 (from keyring>=18.0.1->lytekit==0.14.10->latch) - - Downloading SecretStorage-3.3.3-py3-none-any.whl (15 kB) - -Collecting jeepney>=0.4.2 (from keyring>=18.0.1->lytekit==0.14.10->latch) - - Downloading jeepney-0.8.0-py3-none-any.whl (48 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 48.4/48.4 kB 7.6 MB/s eta 0:00:00 - - -Collecting types-PyYAML (from responses>=0.10.7->lytekit==0.14.10->latch) - - Downloading types_PyYAML-6.0.12.9-py3-none-any.whl (14 kB) - -Collecting pyasn1>=0.1.3 (from rsa<4.8,>=3.1.2->awscli==1.25.22->latch) - - Using cached pyasn1-0.5.0-py2.py3-none-any.whl (83 kB) - -Collecting multidict>=4.0 (from yarl<2.0,>=1.6->gql==3.4.0->latch) - - Downloading multidict-6.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (114 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 114.5/114.5 kB 16.9 MB/s eta 0:00:00 - - -Collecting oauthlib>=3.0.0 (from requests-oauthlib->kubernetes>=24.2.0->latch) - - Downloading oauthlib-3.2.2-py3-none-any.whl (151 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 151.7/151.7 kB 22.3 MB/s eta 0:00:00 - - -Collecting chardet>=3.0.2 (from binaryornot>=0.4.4->cookiecutter>=1.7.3->lytekit==0.14.10->latch) - - Downloading chardet-5.1.0-py3-none-any.whl (199 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 199.1/199.1 kB 28.4 MB/s eta 0:00:00 - - -Requirement already satisfied: pycparser in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from cffi>=1.12->cryptography>=3.1->asyncssh==2.12.0->latch) (2.21) - -Requirement already satisfied: zipp>=0.5 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from importlib-metadata>=4.11.4->keyring>=18.0.1->lytekit==0.14.10->latch) (3.15.0) - -Requirement already satisfied: MarkupSafe>=2.0 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from Jinja2<4.0.0,>=2.7->cookiecutter>=1.7.3->lytekit==0.14.10->latch) (2.1.2) - -Collecting arrow (from jinja2-time>=0.2.0->cookiecutter>=1.7.3->lytekit==0.14.10->latch) - - Downloading arrow-1.2.3-py3-none-any.whl (66 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 66.4/66.4 kB 11.5 MB/s eta 0:00:00 - - -Requirement already satisfied: packaging>=17.0 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from marshmallow<4.0.0,>=3.3.0->dataclasses-json>=0.5.2->lytekit==0.14.10->latch) (23.1) - -Collecting text-unidecode>=1.3 (from python-slugify>=4.0.0->cookiecutter>=1.7.3->lytekit==0.14.10->latch) - - Downloading text_unidecode-1.3-py2.py3-none-any.whl (78 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 78.2/78.2 kB 13.0 MB/s eta 0:00:00 - - -Collecting mypy-extensions>=0.3.0 (from typing-inspect>=0.4.0->dataclasses-json>=0.5.2->lytekit==0.14.10->latch) - - Downloading mypy_extensions-1.0.0-py3-none-any.whl (4.7 kB) - -Collecting more-itertools (from jaraco.classes->keyring>=18.0.1->lytekit==0.14.10->latch) - - Downloading more_itertools-9.1.0-py3-none-any.whl (54 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 54.2/54.2 kB 9.2 MB/s eta 0:00:00 - - -WARNING: The candidate selected for download or install is a yanked version: 'apscheduler' candidate (version 3.9.1 at https://files.pythonhosted.org/packages/e4/9f/c3937d4babe62504b874d4bf2c0d85aa69c7f59fa84cf6050f3b9dc5d83e/APScheduler-3.9.1-py2.py3-none-any.whl (from https://pypi.org/simple/apscheduler/) (requires-python:>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4)) -Reason for being yanked: Not compatible with Python 2.7 - -Building wheels for collected packages: docker-image-py, PyYAML - - Building wheel for docker-image-py (setup.py): started - - Building wheel for docker-image-py (setup.py): finished with status 'done' - - Created wheel for docker-image-py: filename=docker_image_py-0.1.12-py3-none-any.whl size=8812 sha256=93f4864d5ecf3e832cba553638eb71bbc1a0f5f4f31a779334241dcdecafb163 - - Stored in directory: /root/.cache/pip/wheels/fb/45/02/503244da15fbcecde5c3edabb744ed0c4f9a7643126b2d222c - - Building wheel for PyYAML (pyproject.toml): started - - Building wheel for PyYAML (pyproject.toml): finished with status 'done' - - Created wheel for PyYAML: filename=PyYAML-5.4.1-cp310-cp310-linux_x86_64.whl size=141558 sha256=9ab4cce95121a88969a26fe93edc3bdaba68290248a821377df0b3f1da06d102 - - Stored in directory: /root/.cache/pip/wheels/c7/0d/22/696ee92245ad710f506eee79bb05c740d8abccd3ecdb778683 - -Successfully built docker-image-py PyYAML - -Installing collected packages: wcwidth, types-PyYAML, text-unidecode, statsd, sortedcontainers, pytz, pytimeparse, websockets, websocket-client, uvloop, tzlocal, tqdm, sniffio, regex, PyYAML, python-slugify, python-json-logger, pyjwt, pyasn1, py, protobuf, prompt-toolkit, oauthlib, numpy, natsort, mypy-extensions, multidict, more-itertools, marshmallow, jmespath, jeepney, grpcio, graphql-core, docutils, docstring-parser, diskcache, deprecated, decorator, colorama, cloudpickle, click, chardet, cachetools, bcrypt, backoff, aioconsole, yarl, typing-inspect, rsa, retry, responses, requests-toolbelt, requests-oauthlib, pynacl, pyasn1-modules, pyarrow, protoc-gen-swagger, pandas, marshmallow-jsonschema, marshmallow-enum, jaraco.classes, googleapis-common-protos, docker-image-py, docker, croniter, botocore, binaryornot, arrow, apscheduler, anyio, watchfiles, SecretStorage, s3transfer, paramiko, lyteidl, jinja2-time, grpcio-status, gql, google-auth, dataclasses-json, asyncssh, scp, kubernetes, keyring, cookiecutter, boto3, awscli, lytekit, lytekitplugins-pods, latch - - Attempting uninstall: PyYAML - - Found existing installation: PyYAML 6.0 - - Uninstalling PyYAML-6.0: - - Successfully uninstalled PyYAML-6.0 - - Attempting uninstall: numpy - - Found existing installation: numpy 1.24.3 - - Uninstalling numpy-1.24.3: - - Successfully uninstalled numpy-1.24.3 - - Attempting uninstall: docutils - - Found existing installation: docutils 0.20.1 - - Uninstalling docutils-0.20.1: - - Successfully uninstalled docutils-0.20.1 - -ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts. -yte 1.5.1 requires pyyaml<7.0,>=6.0, but you have pyyaml 5.4.1 which is incompatible. - -Successfully installed PyYAML-5.4.1 SecretStorage-3.3.3 aioconsole-0.5.1 anyio-3.6.2 apscheduler-3.9.1 arrow-1.2.3 asyncssh-2.12.0 awscli-1.25.22 backoff-2.2.1 bcrypt-4.0.1 binaryornot-0.4.4 boto3-1.24.22 botocore-1.27.22 cachetools-5.3.0 chardet-5.1.0 click-8.1.3 cloudpickle-2.2.1 colorama-0.4.4 cookiecutter-2.1.1 croniter-1.3.14 dataclasses-json-0.5.7 decorator-5.1.1 deprecated-1.2.13 diskcache-5.6.1 docker-5.0.3 docker-image-py-0.1.12 docstring-parser-0.15 docutils-0.16 google-auth-2.18.1 googleapis-common-protos-1.59.0 gql-3.4.0 graphql-core-3.2.3 grpcio-1.54.2 grpcio-status-1.48.2 jaraco.classes-3.2.3 jeepney-0.8.0 jinja2-time-0.2.0 jmespath-1.0.1 keyring-23.13.1 kubernetes-26.1.0 latch-2.19.11 lyteidl-0.2.0a0 lytekit-0.14.10 lytekitplugins-pods-0.4.0 marshmallow-3.19.0 marshmallow-enum-1.5.1 marshmallow-jsonschema-0.13.0 more-itertools-9.1.0 multidict-6.0.4 mypy-extensions-1.0.0 natsort-8.3.1 numpy-1.21.6 oauthlib-3.2.2 pandas-1.5.3 paramiko-3.1.0 prompt-toolkit-3.0.33 protobuf-3.20.3 protoc-gen-swagger-0.1.0 py-1.11.0 pyarrow-6.0.1 pyasn1-0.5.0 pyasn1-modules-0.3.0 pyjwt-2.7.0 pynacl-1.5.0 python-json-logger-2.0.7 python-slugify-8.0.1 pytimeparse-1.1.8 pytz-2023.3 regex-2023.5.5 requests-oauthlib-1.3.1 requests-toolbelt-0.10.1 responses-0.23.1 retry-0.9.2 rsa-4.7.2 s3transfer-0.6.1 scp-0.14.5 sniffio-1.3.0 sortedcontainers-2.4.0 statsd-3.3.0 text-unidecode-1.3 tqdm-4.65.0 types-PyYAML-6.0.12.9 typing-inspect-0.8.0 tzlocal-5.0.1 uvloop-0.17.0 watchfiles-0.18.1 wcwidth-0.2.6 websocket-client-1.5.2 websockets-10.3 yarl-1.9.2 - -WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv - - ---> ffa1fac95dd6 - -Step 8/15 : copy Snakefile config.yaml /root/ - - - ---> a58a3f610970 - -Step 9/15 : copy scripts/plot-quals.py /root/scripts/plot-quals.py - - - ---> 9fd8716c7a1e - -Step 10/15 : copy .latch/latch_entrypoint.py /root/latch_entrypoint.py - - - ---> b09ea9d0c599 - -Step 11/15 : arg tag - - - ---> Running in f3c75e94104c - - ---> 2755cc88c429 - -Step 12/15 : env FLYTE_INTERNAL_IMAGE $tag - - - ---> Running in d86eea5f113a - - ---> 686cc29564c2 - -Step 13/15 : env LATCH_SDK_DOMAIN "ligma.ai" - - - ---> Running in 8993581c5d61 - - ---> c6ba5312e42f - -Step 14/15 : env LATCH_AUTHENTICATION_ENDPOINT https://nucleus.ligma.ai - - - ---> Running in dd29a31f7c0c - - ---> 3475adc97799 - -Step 15/15 : workdir /root - - - ---> Running in 99d0cec86fe9 - - ---> ef73abcf99bc - -Successfully built ef73abcf99bc - -Successfully tagged 812206152185.dkr.ecr.us-west-2.amazonaws.com/x1_test_latch_register:0.0.0-a00131 - diff --git a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-a98450/docker-build-logs.txt b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-a98450/docker-build-logs.txt deleted file mode 100644 index be6a3c99..00000000 --- a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-a98450/docker-build-logs.txt +++ /dev/null @@ -1,100 +0,0 @@ -Step 1/14 : from 812206152185.dkr.ecr.us-west-2.amazonaws.com/latch-base:b733-kenny--snakemake - - - ---> 77471241d7a3 - -Step 2/14 : run mkdir /opt/latch - - - ---> Using cache - - ---> 6d1d7399ec34 - -Step 3/14 : RUN curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh && mkdir /root/.conda && bash Mambaforge-Linux-x86_64.sh -b && rm -f Mambaforge-Linux-x86_64.sh - - - ---> Using cache - - ---> e5d7f1c377ad - -Step 4/14 : copy environment.yaml /root/environment.yaml - - - ---> Using cache - - ---> f1895bb6bb01 - -Step 5/14 : run /root/mambaforge/bin/mamba env create --name snakemake-tutorial --file environment.yaml - - - ---> Using cache - - ---> 1c115b179fb8 - -Step 6/14 : env PATH /root/mambaforge/envs/snakemake-tutorial/bin:$PATH - - - ---> Using cache - - ---> 38bcbc3eaccf - -Step 7/14 : copy latch /root/latch - - - ---> Using cache - - ---> ba86df280c15 - -Step 8/14 : run cd /root/latch && python3 -m pip install -e . - - - ---> Using cache - - ---> e6903b7577c6 - -Step 9/14 : copy Snakefile config.yaml /root/ - - - ---> Using cache - - ---> 93c3fe88c890 - -Step 10/14 : copy scripts/plot-quals.py /root/scripts/plot-quals.py - - - ---> Using cache - - ---> b476a36f6f9c - -Step 11/14 : copy .latch/latch_entrypoint.py /root/latch_entrypoint.py - - - ---> Using cache - - ---> 75cead0538d5 - -Step 12/14 : arg tag - - - ---> Using cache - - ---> 9d8c1d4b5439 - -Step 13/14 : env FLYTE_INTERNAL_IMAGE $tag - - - ---> Running in ec0261fc5544 - - ---> 10c776472c10 - -Step 14/14 : workdir /root - - - ---> Running in f4346ef370f3 - - ---> 068eab68ef5b - -Successfully built 068eab68ef5b - -Successfully tagged 812206152185.dkr.ecr.us-west-2.amazonaws.com/x1_test_latch_register:0.0.0-a98450 - diff --git a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-b1b9b5/docker-build-logs.txt b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-b1b9b5/docker-build-logs.txt deleted file mode 100644 index d3f998d6..00000000 --- a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-b1b9b5/docker-build-logs.txt +++ /dev/null @@ -1,105 +0,0 @@ -Step 1/15 : from 812206152185.dkr.ecr.us-west-2.amazonaws.com/latch-base:9c8f-main - - - ---> b253e8cdab51 - -Step 2/15 : run mkdir /opt/latch - - - ---> Using cache - - ---> 89e0ab657f0d - -Step 3/15 : RUN curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh && mkdir /root/.conda && bash Mambaforge-Linux-x86_64.sh -b && rm -f Mambaforge-Linux-x86_64.sh - - - ---> Using cache - - ---> 7741d9d31977 - -Step 4/15 : copy environment.yaml /root/environment.yaml - - - ---> Using cache - - ---> c2d3f498d2d5 - -Step 5/15 : run /root/mambaforge/bin/mamba env create --name snakemake-tutorial --file environment.yaml - - - ---> Using cache - - ---> 0370179f98b9 - -Step 6/15 : env PATH /root/mambaforge/envs/snakemake-tutorial/bin:$PATH - - - ---> Using cache - - ---> 558ea5988368 - -Step 7/15 : run python3 -m pip install latch - - - ---> Using cache - - ---> 73f3b443e340 - -Step 8/15 : copy Snakefile config.yaml /root/ - - - ---> Using cache - - ---> da1c8fa40657 - -Step 9/15 : copy scripts/plot-quals.py /root/scripts/plot-quals.py - - - ---> Using cache - - ---> 6e0a5622727c - -Step 10/15 : copy .latch/latch_entrypoint.py /root/latch_entrypoint.py - - - ---> 2c641c26711a - -Step 11/15 : arg tag - - - ---> Running in 35395e4bff4b - - ---> 6c77e2242b73 - -Step 12/15 : env FLYTE_INTERNAL_IMAGE $tag - - - ---> Running in 75382a292780 - - ---> c2b2d52f48dd - -Step 13/15 : env LATCH_SDK_DOMAIN "ligma.ai" - - - ---> Running in 1eaeb43fcdb6 - - ---> b99ac2abf3bf - -Step 14/15 : env LATCH_AUTHENTICATION_ENDPOINT https://nucleus.ligma.ai - - - ---> Running in 8334c0825385 - - ---> d8f22dea8baa - -Step 15/15 : workdir /root - - - ---> Running in 74f859724d35 - - ---> 957f49e6cff2 - -Successfully built 957f49e6cff2 - -Successfully tagged 812206152185.dkr.ecr.us-west-2.amazonaws.com/x1_test_latch_register:0.0.0-b1b9b5 - diff --git a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-cdb14b/docker-build-logs.txt b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-cdb14b/docker-build-logs.txt deleted file mode 100644 index aedd7386..00000000 --- a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-cdb14b/docker-build-logs.txt +++ /dev/null @@ -1,2083 +0,0 @@ -Step 1/14 : from 812206152185.dkr.ecr.us-west-2.amazonaws.com/latch-base:9c8f-main - - - ---> b253e8cdab51 - -Step 2/14 : run mkdir /opt/latch - - - ---> Using cache - - ---> 89e0ab657f0d - -Step 3/14 : RUN curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh && mkdir /root/.conda && bash Mambaforge-Linux-x86_64.sh -b && rm -f Mambaforge-Linux-x86_64.sh - - - ---> Using cache - - ---> 7741d9d31977 - -Step 4/14 : copy environment.yaml /root/environment.yaml - - - ---> c2d3f498d2d5 - -Step 5/14 : run /root/mambaforge/bin/mamba env create --name snakemake-tutorial --file environment.yaml - - - ---> Running in 3f2a1a3e5042 - - - -Looking for: ["snakemake-minimal[version='>=7.3']", 'jinja2', 'matplotlib', 'graphviz', 'bcftools=1.15', 'samtools=1.15', 'bwa=0.7.17', 'pysam=0.19', 'pygments'] - - - -Transaction - - Prefix: /root/mambaforge/envs/snakemake-tutorial - - Updating specs: - - - snakemake-minimal[version='>=7.3'] - - jinja2 - - matplotlib - - graphviz - - bcftools=1.15 - - samtools=1.15 - - bwa=0.7.17 - - pysam=0.19 - - pygments - - - - Package Version Build Channel Size -─────────────────────────────────────────────────────────────────────────────────────────────────── - Install: -─────────────────────────────────────────────────────────────────────────────────────────────────── - - + _libgcc_mutex 0.1 conda_forge conda-forge/linux-64 Cached - + _openmp_mutex 4.5 2_gnu conda-forge/linux-64 Cached - + alsa-lib 1.2.8 h166bdaf_0 conda-forge/linux-64 592kB - + amply 0.1.5 pyhd8ed1ab_0 conda-forge/noarch 21kB - + appdirs 1.4.4 pyh9f0ad1d_0 conda-forge/noarch 13kB - + atk-1.0 2.38.0 hd4edc92_1 conda-forge/linux-64 552kB - + attr 2.5.1 h166bdaf_1 conda-forge/linux-64 71kB - + attrs 23.1.0 pyh71513ae_1 conda-forge/noarch 55kB - + bcftools 1.15.1 hfe4b78e_1 bioconda/linux-64 867kB - + brotli 1.0.9 h166bdaf_8 conda-forge/linux-64 19kB - + brotli-bin 1.0.9 h166bdaf_8 conda-forge/linux-64 20kB - + brotlipy 0.7.0 py310h5764c6d_1005 conda-forge/linux-64 Cached - + bwa 0.7.17 he4a0461_11 bioconda/linux-64 196kB - + bzip2 1.0.8 h7f98852_4 conda-forge/linux-64 Cached - + c-ares 1.19.0 hd590300_0 conda-forge/linux-64 114kB - + ca-certificates 2023.5.7 hbcca054_0 conda-forge/linux-64 148kB - + cairo 1.16.0 ha61ee94_1014 conda-forge/linux-64 2MB - + certifi 2023.5.7 pyhd8ed1ab_0 conda-forge/noarch 152kB - + cffi 1.15.1 py310h255011f_3 conda-forge/linux-64 Cached - + charset-normalizer 3.1.0 pyhd8ed1ab_0 conda-forge/noarch Cached - + coin-or-cbc 2.10.10 h9002f0b_0 conda-forge/linux-64 941kB - + coin-or-cgl 0.60.7 h516709c_0 conda-forge/linux-64 551kB - + coin-or-clp 1.17.8 h1ee7a9c_0 conda-forge/linux-64 1MB - + coin-or-osi 0.108.8 ha2443b9_0 conda-forge/linux-64 389kB - + coin-or-utils 2.11.9 hee58242_0 conda-forge/linux-64 687kB - + coincbc 2.10.10 0_metapackage conda-forge/noarch 12kB - + configargparse 1.5.3 pyhd8ed1ab_0 conda-forge/noarch 33kB - + connection_pool 0.0.3 pyhd3deb0d_0 conda-forge/noarch 8kB - + contourpy 1.0.7 py310hdf3cbec_0 conda-forge/linux-64 216kB - + cryptography 39.0.0 py310h65dfdc0_0 conda-forge/linux-64 1MB - + cycler 0.11.0 pyhd8ed1ab_0 conda-forge/noarch 10kB - + datrie 0.8.2 py310h5764c6d_6 conda-forge/linux-64 148kB - + dbus 1.13.6 h5008d03_3 conda-forge/linux-64 619kB - + docutils 0.20.1 py310hff52083_0 conda-forge/linux-64 721kB - + dpath 2.1.5 pyha770c72_1 conda-forge/noarch 21kB - + expat 2.5.0 hcb278e6_1 conda-forge/linux-64 137kB - + fftw 3.3.10 nompi_hc118613_107 conda-forge/linux-64 2MB - + filelock 3.12.0 pyhd8ed1ab_0 conda-forge/noarch 15kB - + font-ttf-dejavu-sans-mono 2.37 hab24e00_0 conda-forge/noarch 397kB - + font-ttf-inconsolata 3.000 h77eed37_0 conda-forge/noarch 97kB - + font-ttf-source-code-pro 2.038 h77eed37_0 conda-forge/noarch 701kB - + font-ttf-ubuntu 0.83 hab24e00_0 conda-forge/noarch 2MB - + fontconfig 2.14.2 h14ed4e7_0 conda-forge/linux-64 272kB - + fonts-conda-ecosystem 1 0 conda-forge/noarch 4kB - + fonts-conda-forge 1 0 conda-forge/noarch 4kB - + fonttools 4.39.4 py310h2372a71_0 conda-forge/linux-64 2MB - + freetype 2.12.1 hca18f0e_1 conda-forge/linux-64 626kB - + fribidi 1.0.10 h36c2ea0_0 conda-forge/linux-64 114kB - + gdk-pixbuf 2.42.8 hff1cb4f_1 conda-forge/linux-64 612kB - + gettext 0.21.1 h27087fc_0 conda-forge/linux-64 4MB - + giflib 5.2.1 h0b41bf4_3 conda-forge/linux-64 77kB - + gitdb 4.0.10 pyhd8ed1ab_0 conda-forge/noarch 52kB - + gitpython 3.1.31 pyhd8ed1ab_0 conda-forge/noarch 142kB - + glib 2.76.2 hfc55251_0 conda-forge/linux-64 484kB - + glib-tools 2.76.2 hfc55251_0 conda-forge/linux-64 112kB - + graphite2 1.3.13 h58526e2_1001 conda-forge/linux-64 105kB - + graphviz 7.0.5 h2e5815a_0 conda-forge/linux-64 2MB - + gsl 2.7 he838d99_0 conda-forge/linux-64 3MB - + gst-plugins-base 1.21.3 h4243ec0_1 conda-forge/linux-64 3MB - + gstreamer 1.21.3 h25f0c4b_1 conda-forge/linux-64 2MB - + gstreamer-orc 0.4.33 h166bdaf_0 conda-forge/linux-64 306kB - + gtk2 2.24.33 h90689f9_2 conda-forge/linux-64 8MB - + gts 0.7.6 h64030ff_2 conda-forge/linux-64 421kB - + harfbuzz 6.0.0 h8e241bc_0 conda-forge/linux-64 1MB - + htslib 1.16 h6bc39ce_0 bioconda/linux-64 2MB - + humanfriendly 10.0 py310hff52083_4 conda-forge/linux-64 123kB - + icu 70.1 h27087fc_0 conda-forge/linux-64 14MB - + idna 3.4 pyhd8ed1ab_0 conda-forge/noarch Cached - + importlib-metadata 6.6.0 pyha770c72_0 conda-forge/noarch 26kB - + importlib_resources 5.12.0 pyhd8ed1ab_0 conda-forge/noarch 31kB - + jack 1.9.22 h11f4161_0 conda-forge/linux-64 464kB - + jinja2 3.1.2 pyhd8ed1ab_1 conda-forge/noarch 101kB - + jpeg 9e h0b41bf4_3 conda-forge/linux-64 240kB - + jsonschema 4.17.3 pyhd8ed1ab_0 conda-forge/noarch 70kB - + jupyter_core 5.3.0 py310hff52083_0 conda-forge/linux-64 91kB - + keyutils 1.6.1 h166bdaf_0 conda-forge/linux-64 Cached - + kiwisolver 1.4.4 py310hbf28c38_1 conda-forge/linux-64 77kB - + krb5 1.20.1 hf9c8cef_0 conda-forge/linux-64 1MB - + lame 3.100 h166bdaf_1003 conda-forge/linux-64 508kB - + lcms2 2.14 h6ed2654_0 conda-forge/linux-64 262kB - + ld_impl_linux-64 2.40 h41732ed_0 conda-forge/linux-64 Cached - + lerc 4.0.0 h27087fc_0 conda-forge/linux-64 282kB - + libblas 3.9.0 16_linux64_openblas conda-forge/linux-64 13kB - + libbrotlicommon 1.0.9 h166bdaf_8 conda-forge/linux-64 67kB - + libbrotlidec 1.0.9 h166bdaf_8 conda-forge/linux-64 34kB - + libbrotlienc 1.0.9 h166bdaf_8 conda-forge/linux-64 295kB - + libcap 2.66 ha37c62d_0 conda-forge/linux-64 100kB - + libcblas 3.9.0 16_linux64_openblas conda-forge/linux-64 13kB - + libclang 15.0.7 default_h7634d5b_2 conda-forge/linux-64 133kB - + libclang13 15.0.7 default_h9986a30_2 conda-forge/linux-64 10MB - + libcups 2.3.3 h36d4200_3 conda-forge/linux-64 5MB - + libcurl 7.87.0 h6312ad2_0 conda-forge/linux-64 347kB - + libdb 6.2.32 h9c3ff4c_0 conda-forge/linux-64 24MB - + libdeflate 1.13 h166bdaf_0 conda-forge/linux-64 80kB - + libedit 3.1.20191231 he28a2e2_2 conda-forge/linux-64 Cached - + libev 4.33 h516909a_1 conda-forge/linux-64 Cached - + libevent 2.1.10 h9b69904_4 conda-forge/linux-64 1MB - + libexpat 2.5.0 hcb278e6_1 conda-forge/linux-64 78kB - + libffi 3.4.2 h7f98852_5 conda-forge/linux-64 Cached - + libflac 1.4.2 h27087fc_0 conda-forge/linux-64 421kB - + libgcc-ng 12.2.0 h65d4601_19 conda-forge/linux-64 Cached - + libgcrypt 1.10.1 h166bdaf_0 conda-forge/linux-64 720kB - + libgd 2.3.3 h18fbbfe_3 conda-forge/linux-64 272kB - + libgfortran-ng 12.2.0 h69a702a_19 conda-forge/linux-64 23kB - + libgfortran5 12.2.0 h337968e_19 conda-forge/linux-64 2MB - + libglib 2.76.2 hebfc3b9_0 conda-forge/linux-64 3MB - + libgomp 12.2.0 h65d4601_19 conda-forge/linux-64 Cached - + libgpg-error 1.46 h620e276_0 conda-forge/linux-64 258kB - + libiconv 1.17 h166bdaf_0 conda-forge/linux-64 Cached - + liblapack 3.9.0 16_linux64_openblas conda-forge/linux-64 13kB - + liblapacke 3.9.0 16_linux64_openblas conda-forge/linux-64 13kB - + libllvm15 15.0.7 hadd5161_1 conda-forge/linux-64 33MB - + libnghttp2 1.51.0 hdcd2b5c_0 conda-forge/linux-64 623kB - + libnsl 2.0.0 h7f98852_0 conda-forge/linux-64 Cached - + libogg 1.3.4 h7f98852_1 conda-forge/linux-64 211kB - + libopenblas 0.3.21 pthreads_h78a6416_3 conda-forge/linux-64 11MB - + libopus 1.3.1 h7f98852_1 conda-forge/linux-64 261kB - + libpng 1.6.39 h753d276_0 conda-forge/linux-64 283kB - + libpq 15.1 h2baec63_3 conda-forge/linux-64 2MB - + librsvg 2.54.4 h7abd40a_0 conda-forge/linux-64 7MB - + libsndfile 1.2.0 hb75c966_0 conda-forge/linux-64 350kB - + libsqlite 3.42.0 h2797004_0 conda-forge/linux-64 829kB - + libssh2 1.10.0 haa6b8db_3 conda-forge/linux-64 239kB - + libstdcxx-ng 12.2.0 h46fd767_19 conda-forge/linux-64 Cached - + libsystemd0 252 h2a991cd_0 conda-forge/linux-64 393kB - + libtiff 4.4.0 h0e0dad5_3 conda-forge/linux-64 658kB - + libtool 2.4.7 h27087fc_0 conda-forge/linux-64 412kB - + libudev1 253 h0b41bf4_0 conda-forge/linux-64 119kB - + libuuid 2.38.1 h0b41bf4_0 conda-forge/linux-64 Cached - + libvorbis 1.3.7 h9c3ff4c_0 conda-forge/linux-64 286kB - + libwebp 1.2.4 h522a892_0 conda-forge/linux-64 90kB - + libwebp-base 1.2.4 h166bdaf_0 conda-forge/linux-64 413kB - + libxcb 1.13 h7f98852_1004 conda-forge/linux-64 400kB - + libxkbcommon 1.5.0 h79f4944_1 conda-forge/linux-64 563kB - + libxml2 2.10.3 hca2bb57_4 conda-forge/linux-64 714kB - + libzlib 1.2.13 h166bdaf_4 conda-forge/linux-64 Cached - + lz4-c 1.9.4 hcb278e6_0 conda-forge/linux-64 Cached - + markupsafe 2.1.2 py310h1fa729e_0 conda-forge/linux-64 23kB - + matplotlib 3.7.1 py310hff52083_0 conda-forge/linux-64 8kB - + matplotlib-base 3.7.1 py310he60537e_0 conda-forge/linux-64 7MB - + mpg123 1.31.3 hcb278e6_0 conda-forge/linux-64 485kB - + munkres 1.0.7 py_1 bioconda/noarch 10kB - + mysql-common 8.0.32 h14678bc_0 conda-forge/linux-64 803kB - + mysql-libs 8.0.32 h54cf53e_0 conda-forge/linux-64 2MB - + nbformat 5.8.0 pyhd8ed1ab_0 conda-forge/noarch 101kB - + ncurses 6.3 h27087fc_1 conda-forge/linux-64 Cached - + nspr 4.35 h27087fc_0 conda-forge/linux-64 227kB - + nss 3.89 he45b914_0 conda-forge/linux-64 2MB - + numpy 1.24.3 py310ha4c1d20_0 conda-forge/linux-64 7MB - + openjpeg 2.5.0 h7d73246_1 conda-forge/linux-64 546kB - + openssl 1.1.1t h0b41bf4_0 conda-forge/linux-64 2MB - + packaging 23.1 pyhd8ed1ab_0 conda-forge/noarch 46kB - + pango 1.50.14 hd33c08f_0 conda-forge/linux-64 438kB - + pcre2 10.40 hc3806b6_0 conda-forge/linux-64 2MB - + perl 5.32.1 2_h7f98852_perl5 conda-forge/linux-64 15MB - + pillow 9.2.0 py310h454ad03_3 conda-forge/linux-64 47MB - + pip 23.1.2 pyhd8ed1ab_0 conda-forge/noarch 1MB - + pixman 0.40.0 h36c2ea0_0 conda-forge/linux-64 643kB - + pkgutil-resolve-name 1.3.10 pyhd8ed1ab_0 conda-forge/noarch 9kB - + plac 1.3.5 pyhd8ed1ab_0 conda-forge/noarch 23kB - + platformdirs 3.5.1 pyhd8ed1ab_0 conda-forge/noarch 19kB - + ply 3.11 py_1 conda-forge/noarch 45kB - + psutil 5.9.5 py310h1fa729e_0 conda-forge/linux-64 362kB - + pthread-stubs 0.4 h36c2ea0_1001 conda-forge/linux-64 6kB - + pulp 2.7.0 py310hff52083_0 conda-forge/linux-64 141kB - + pulseaudio 16.1 h4ab2085_1 conda-forge/linux-64 2MB - + pycparser 2.21 pyhd8ed1ab_0 conda-forge/noarch Cached - + pygments 2.15.1 pyhd8ed1ab_0 conda-forge/noarch 841kB - + pyopenssl 23.1.1 pyhd8ed1ab_0 conda-forge/noarch Cached - + pyparsing 3.0.9 pyhd8ed1ab_0 conda-forge/noarch 81kB - + pyqt 5.15.7 py310hab646b1_3 conda-forge/linux-64 5MB - + pyqt5-sip 12.11.0 py310heca2aa9_3 conda-forge/linux-64 85kB - + pyrsistent 0.19.3 py310h1fa729e_0 conda-forge/linux-64 100kB - + pysam 0.19.1 py310hff46b53_1 bioconda/linux-64 3MB - + pysocks 1.7.1 pyha2e5f31_6 conda-forge/noarch Cached - + python 3.10.8 h257c98d_0_cpython conda-forge/linux-64 23MB - + python-dateutil 2.8.2 pyhd8ed1ab_0 conda-forge/noarch 246kB - + python-fastjsonschema 2.16.3 pyhd8ed1ab_0 conda-forge/noarch 225kB - + python_abi 3.10 3_cp310 conda-forge/linux-64 Cached - + pyyaml 6.0 py310h5764c6d_5 conda-forge/linux-64 176kB - + qt-main 5.15.6 h18908ee_6 conda-forge/linux-64 55MB - + readline 8.2 h8228510_1 conda-forge/linux-64 Cached - + requests 2.29.0 pyhd8ed1ab_0 conda-forge/noarch 57kB - + reretry 0.11.8 pyhd8ed1ab_0 conda-forge/noarch 12kB - + samtools 1.15.1 h6899075_1 bioconda/linux-64 406kB - + setuptools 67.7.2 pyhd8ed1ab_0 conda-forge/noarch 583kB - + sip 6.7.9 py310hc6cd4ac_0 conda-forge/linux-64 493kB - + six 1.16.0 pyh6c4a22f_0 conda-forge/noarch 14kB - + smart_open 6.3.0 pyhd8ed1ab_1 conda-forge/noarch 47kB - + smmap 3.0.5 pyh44b312d_0 conda-forge/noarch 23kB - + snakemake-minimal 7.25.4 pyhdfd78af_0 bioconda/noarch 266kB - + stopit 1.1.2 py_0 conda-forge/noarch 16kB - + tabulate 0.9.0 pyhd8ed1ab_1 conda-forge/noarch 36kB - + throttler 1.2.1 pyhd8ed1ab_0 conda-forge/noarch 11kB - + tk 8.6.12 h27826a3_0 conda-forge/linux-64 Cached - + toml 0.10.2 pyhd8ed1ab_0 conda-forge/noarch 18kB - + tomli 2.0.1 pyhd8ed1ab_0 conda-forge/noarch 16kB - + toposort 1.10 pyhd8ed1ab_0 conda-forge/noarch 14kB - + tornado 6.3.2 py310h2372a71_0 conda-forge/linux-64 639kB - + traitlets 5.9.0 pyhd8ed1ab_0 conda-forge/noarch 98kB - + typing-extensions 4.5.0 hd8ed1ab_0 conda-forge/noarch 10kB - + typing_extensions 4.5.0 pyha770c72_0 conda-forge/noarch 31kB - + tzdata 2023c h71feb2d_0 conda-forge/noarch Cached - + unicodedata2 15.0.0 py310h5764c6d_0 conda-forge/linux-64 512kB - + urllib3 1.26.15 pyhd8ed1ab_0 conda-forge/noarch Cached - + wheel 0.40.0 pyhd8ed1ab_0 conda-forge/noarch Cached - + wrapt 1.15.0 py310h1fa729e_0 conda-forge/linux-64 54kB - + xcb-util 0.4.0 h516909a_0 conda-forge/linux-64 20kB - + xcb-util-image 0.4.0 h166bdaf_0 conda-forge/linux-64 24kB - + xcb-util-keysyms 0.4.0 h516909a_0 conda-forge/linux-64 12kB - + xcb-util-renderutil 0.3.9 h166bdaf_0 conda-forge/linux-64 16kB - + xcb-util-wm 0.4.1 h516909a_0 conda-forge/linux-64 56kB - + xkeyboard-config 2.38 h0b41bf4_0 conda-forge/linux-64 882kB - + xorg-kbproto 1.0.7 h7f98852_1002 conda-forge/linux-64 27kB - + xorg-libice 1.0.10 h7f98852_0 conda-forge/linux-64 59kB - + xorg-libsm 1.2.3 hd9c2040_1000 conda-forge/linux-64 26kB - + xorg-libx11 1.8.4 h0b41bf4_0 conda-forge/linux-64 830kB - + xorg-libxau 1.0.9 h7f98852_0 conda-forge/linux-64 13kB - + xorg-libxdmcp 1.1.3 h7f98852_0 conda-forge/linux-64 19kB - + xorg-libxext 1.3.4 h0b41bf4_2 conda-forge/linux-64 50kB - + xorg-libxrender 0.9.10 h7f98852_1003 conda-forge/linux-64 33kB - + xorg-renderproto 0.11.1 h7f98852_1002 conda-forge/linux-64 10kB - + xorg-xextproto 7.3.0 h0b41bf4_1003 conda-forge/linux-64 30kB - + xorg-xproto 7.0.31 h7f98852_1007 conda-forge/linux-64 75kB - + xz 5.2.6 h166bdaf_0 conda-forge/linux-64 Cached - + yaml 0.2.5 h7f98852_2 conda-forge/linux-64 89kB - + yte 1.5.1 py310hff52083_1 conda-forge/linux-64 18kB - + zipp 3.15.0 pyhd8ed1ab_0 conda-forge/noarch 17kB - + zlib 1.2.13 h166bdaf_4 conda-forge/linux-64 94kB - + zstd 1.5.2 h3eb15da_6 conda-forge/linux-64 Cached - - Summary: - - Install: 230 packages - - Total download: 357MB - -─────────────────────────────────────────────────────────────────────────────────────────────────── - - - - -Downloading and Extracting Packages - -Preparing transaction: ...working... -done - -Verifying transaction: ...working... -done - -Executing transaction: ...working... - - -done - -# -# To activate this environment, use -# -# $ conda activate snakemake-tutorial -# -# To deactivate an active environment, use -# -# $ conda deactivate - - - ---> 0370179f98b9 - -Step 6/14 : env PATH /root/mambaforge/envs/snakemake-tutorial/bin:$PATH - - - ---> Running in 3e94901f04ce - - ---> 558ea5988368 - -Step 7/14 : run python3 -m pip install latch - - - ---> Running in f3dc76132437 - -Collecting latch - - Downloading latch-2.19.11-py3-none-any.whl (150 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 150.6/150.6 kB 7.0 MB/s eta 0:00:00 - - -Collecting awscli==1.25.22 (from latch) - - Downloading awscli-1.25.22-py3-none-any.whl (3.9 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.9/3.9 MB 59.9 MB/s eta 0:00:00 - - -Collecting asyncssh==2.12.0 (from latch) - - Downloading asyncssh-2.12.0-py3-none-any.whl (346 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 346.7/346.7 kB 35.0 MB/s eta 0:00:00 - - -Collecting aioconsole==0.5.1 (from latch) - - Downloading aioconsole-0.5.1-py3-none-any.whl (30 kB) - -Collecting kubernetes>=24.2.0 (from latch) - - Downloading kubernetes-26.1.0-py2.py3-none-any.whl (1.4 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.4/1.4 MB 64.9 MB/s eta 0:00:00 - - -Collecting pyjwt>=0.2.0 (from latch) - - Downloading PyJWT-2.7.0-py3-none-any.whl (22 kB) - -Requirement already satisfied: requests>=2.28.1 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from latch) (2.29.0) - -Collecting click>=8.0 (from latch) - - Downloading click-8.1.3-py3-none-any.whl (96 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 96.6/96.6 kB 14.5 MB/s eta 0:00:00 - - -Collecting docker>=5.0 (from latch) - - Downloading docker-6.1.2-py3-none-any.whl (148 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 148.1/148.1 kB 20.4 MB/s eta 0:00:00 - - -Collecting paramiko>=2.11.0 (from latch) - - Downloading paramiko-3.1.0-py3-none-any.whl (211 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 211.2/211.2 kB 26.5 MB/s eta 0:00:00 - - -Collecting scp>=0.14.0 (from latch) - - Downloading scp-0.14.5-py2.py3-none-any.whl (8.7 kB) - -Collecting boto3>=1.24.22 (from latch) - - Downloading boto3-1.26.136-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 16.9 MB/s eta 0:00:00 - - -Collecting tqdm>=4.63.0 (from latch) - - Downloading tqdm-4.65.0-py3-none-any.whl (77 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 77.1/77.1 kB 11.3 MB/s eta 0:00:00 - - -Collecting lytekit==0.14.10 (from latch) - - Downloading lytekit-0.14.10-py3-none-any.whl (391 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 391.8/391.8 kB 41.6 MB/s eta 0:00:00 - - -Collecting lytekitplugins-pods==0.4.0 (from latch) - - Downloading lytekitplugins_pods-0.4.0-py3-none-any.whl (4.3 kB) - -Requirement already satisfied: typing-extensions==4.5.0 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from latch) (4.5.0) - -Collecting apscheduler==3.9.1 (from latch) - - Downloading APScheduler-3.9.1-py2.py3-none-any.whl (59 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 59.5/59.5 kB 9.5 MB/s eta 0:00:00 - - -Collecting uvloop==0.17.0 (from latch) - - Downloading uvloop-0.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.1 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.1/4.1 MB 63.5 MB/s eta 0:00:00 - - -Collecting websockets==10.3 (from latch) - - Downloading websockets-10.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (111 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 111.5/111.5 kB 15.6 MB/s eta 0:00:00 - - -Collecting prompt-toolkit==3.0.33 (from latch) - - Downloading prompt_toolkit-3.0.33-py3-none-any.whl (383 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 383.6/383.6 kB 41.3 MB/s eta 0:00:00 - - -Collecting watchfiles==0.18.1 (from latch) - - Downloading watchfiles-0.18.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.2 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.2/1.2 MB 67.5 MB/s eta 0:00:00 - - -Collecting gql==3.4.0 (from latch) - - Downloading gql-3.4.0-py2.py3-none-any.whl (65 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 65.2/65.2 kB 9.6 MB/s eta 0:00:00 - - -Collecting graphql-core==3.2.3 (from latch) - - Downloading graphql_core-3.2.3-py3-none-any.whl (202 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 202.9/202.9 kB 26.3 MB/s eta 0:00:00 - - -Collecting requests-toolbelt==0.10.1 (from latch) - - Downloading requests_toolbelt-0.10.1-py2.py3-none-any.whl (54 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 54.5/54.5 kB 8.8 MB/s eta 0:00:00 - - -Requirement already satisfied: setuptools>=0.7 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from apscheduler==3.9.1->latch) (67.7.2) - -Requirement already satisfied: six>=1.4.0 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from apscheduler==3.9.1->latch) (1.16.0) - -Collecting pytz (from apscheduler==3.9.1->latch) - - Downloading pytz-2023.3-py2.py3-none-any.whl (502 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 502.3/502.3 kB 46.3 MB/s eta 0:00:00 - - -Collecting tzlocal!=3.*,>=2.0 (from apscheduler==3.9.1->latch) - - Downloading tzlocal-5.0.1-py3-none-any.whl (20 kB) - -Requirement already satisfied: cryptography>=3.1 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from asyncssh==2.12.0->latch) (39.0.0) - -Collecting botocore==1.27.22 (from awscli==1.25.22->latch) - - Downloading botocore-1.27.22-py3-none-any.whl (8.9 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.9/8.9 MB 85.4 MB/s eta 0:00:00 - - -Collecting docutils<0.17,>=0.10 (from awscli==1.25.22->latch) - - Using cached docutils-0.16-py2.py3-none-any.whl (548 kB) - -Collecting s3transfer<0.7.0,>=0.6.0 (from awscli==1.25.22->latch) - - Downloading s3transfer-0.6.1-py3-none-any.whl (79 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 79.8/79.8 kB 12.2 MB/s eta 0:00:00 - - -Collecting PyYAML<5.5,>=3.10 (from awscli==1.25.22->latch) - - Downloading PyYAML-5.4.1.tar.gz (175 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 175.1/175.1 kB 23.4 MB/s eta 0:00:00 - - - Installing build dependencies: started - - Installing build dependencies: finished with status 'done' - Getting requirements to build wheel: started - - Getting requirements to build wheel: finished with status 'done' - Preparing metadata (pyproject.toml): started - - Preparing metadata (pyproject.toml): finished with status 'done' - -Collecting colorama<0.4.5,>=0.2.5 (from awscli==1.25.22->latch) - - Using cached colorama-0.4.4-py2.py3-none-any.whl (16 kB) - -Collecting rsa<4.8,>=3.1.2 (from awscli==1.25.22->latch) - - Using cached rsa-4.7.2-py3-none-any.whl (34 kB) - -Collecting yarl<2.0,>=1.6 (from gql==3.4.0->latch) - - Downloading yarl-1.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (268 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 268.8/268.8 kB 32.0 MB/s eta 0:00:00 - - -Collecting backoff<3.0,>=1.11.1 (from gql==3.4.0->latch) - - Downloading backoff-2.2.1-py3-none-any.whl (15 kB) - -Collecting lyteidl==0.2.0a0 (from lytekit==0.14.10->latch) - - Downloading lyteidl-0.2.0a0-py3-none-any.whl (162 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 162.2/162.2 kB 22.7 MB/s eta 0:00:00 - - -Requirement already satisfied: wheel<1.0.0,>=0.30.0 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch) (0.40.0) - -Collecting pandas<2.0.0,>=1.0.0 (from lytekit==0.14.10->latch) - - Downloading pandas-1.5.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (12.1 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 12.1/12.1 MB 79.6 MB/s eta 0:00:00 - - -Collecting pyarrow<7.0.0,>=4.0.0 (from lytekit==0.14.10->latch) - - Downloading pyarrow-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (25.6 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 25.6/25.6 MB 37.9 MB/s eta 0:00:00 - - -Collecting croniter<4.0.0,>=0.3.20 (from lytekit==0.14.10->latch) - - Downloading croniter-1.3.14-py2.py3-none-any.whl (18 kB) - -Collecting deprecated<2.0,>=1.0 (from lytekit==0.14.10->latch) - - Downloading Deprecated-1.2.13-py2.py3-none-any.whl (9.6 kB) - -Collecting docker>=5.0 (from latch) - - Downloading docker-5.0.3-py2.py3-none-any.whl (146 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 146.2/146.2 kB 20.4 MB/s eta 0:00:00 - - -Requirement already satisfied: python-dateutil>=2.1 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch) (2.8.2) - -Collecting grpcio!=1.45.0,<2.0,>=1.43.0 (from lytekit==0.14.10->latch) - - Downloading grpcio-1.54.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.1 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 5.1/5.1 MB 60.8 MB/s eta 0:00:00 - - -Collecting grpcio-status!=1.45.0,>=1.43 (from lytekit==0.14.10->latch) - - Downloading grpcio_status-1.54.2-py3-none-any.whl (5.1 kB) - -Collecting protobuf<4,>=3.6.1 (from lytekit==0.14.10->latch) - - Downloading protobuf-3.20.3-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (1.1 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.1/1.1 MB 56.8 MB/s eta 0:00:00 - - -Collecting python-json-logger>=2.0.0 (from lytekit==0.14.10->latch) - - Downloading python_json_logger-2.0.7-py3-none-any.whl (8.1 kB) - -Collecting pytimeparse<2.0.0,>=1.1.8 (from lytekit==0.14.10->latch) - - Downloading pytimeparse-1.1.8-py2.py3-none-any.whl (10.0 kB) - -Collecting keyring>=18.0.1 (from lytekit==0.14.10->latch) - - Downloading keyring-23.13.1-py3-none-any.whl (37 kB) - -Collecting responses>=0.10.7 (from lytekit==0.14.10->latch) - - Downloading responses-0.23.1-py3-none-any.whl (52 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 52.1/52.1 kB 8.2 MB/s eta 0:00:00 - - -Collecting sortedcontainers<3.0.0,>=1.5.9 (from lytekit==0.14.10->latch) - - Downloading sortedcontainers-2.4.0-py2.py3-none-any.whl (29 kB) - -Collecting statsd<4.0.0,>=3.0.0 (from lytekit==0.14.10->latch) - - Downloading statsd-3.3.0-py2.py3-none-any.whl (11 kB) - -Requirement already satisfied: urllib3<2.0.0,>=1.22 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch) (1.26.15) - -Requirement already satisfied: wrapt<2.0.0,>=1.0.0 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch) (1.15.0) - -Collecting retry==0.9.2 (from lytekit==0.14.10->latch) - - Downloading retry-0.9.2-py2.py3-none-any.whl (8.0 kB) - -Collecting dataclasses-json>=0.5.2 (from lytekit==0.14.10->latch) - - Downloading dataclasses_json-0.5.7-py3-none-any.whl (25 kB) - -Requirement already satisfied: jsonschema>=4.5.1 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch) (4.17.3) - -Collecting marshmallow-jsonschema>=0.12.0 (from lytekit==0.14.10->latch) - - Downloading marshmallow_jsonschema-0.13.0-py3-none-any.whl (11 kB) - -Collecting natsort>=7.0.1 (from lytekit==0.14.10->latch) - - Downloading natsort-8.3.1-py3-none-any.whl (38 kB) - -Collecting docker-image-py>=0.1.10 (from lytekit==0.14.10->latch) - - Downloading docker-image-py-0.1.12.tar.gz (8.2 kB) - - Preparing metadata (setup.py): started - - Preparing metadata (setup.py): finished with status 'done' - -Collecting docstring-parser>=0.9.0 (from lytekit==0.14.10->latch) - - Downloading docstring_parser-0.15-py3-none-any.whl (36 kB) - -Collecting diskcache>=5.2.1 (from lytekit==0.14.10->latch) - - Downloading diskcache-5.6.1-py3-none-any.whl (45 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 45.6/45.6 kB 6.4 MB/s eta 0:00:00 - - -Collecting cloudpickle>=2.0.0 (from lytekit==0.14.10->latch) - - Downloading cloudpickle-2.2.1-py3-none-any.whl (25 kB) - -Collecting cookiecutter>=1.7.3 (from lytekit==0.14.10->latch) - - Downloading cookiecutter-2.1.1-py2.py3-none-any.whl (36 kB) - -Collecting numpy<1.22.0 (from lytekit==0.14.10->latch) - - Downloading numpy-1.21.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (15.9 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 15.9/15.9 MB 57.7 MB/s eta 0:00:00 - - -Collecting wcwidth (from prompt-toolkit==3.0.33->latch) - - Downloading wcwidth-0.2.6-py2.py3-none-any.whl (29 kB) - -Collecting anyio>=3.0.0 (from watchfiles==0.18.1->latch) - - Downloading anyio-3.6.2-py3-none-any.whl (80 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 80.6/80.6 kB 12.7 MB/s eta 0:00:00 - - -Collecting jmespath<2.0.0,>=0.7.1 (from botocore==1.27.22->awscli==1.25.22->latch) - - Using cached jmespath-1.0.1-py3-none-any.whl (20 kB) - -Collecting googleapis-common-protos (from lyteidl==0.2.0a0->lytekit==0.14.10->latch) - - Downloading googleapis_common_protos-1.59.0-py2.py3-none-any.whl (223 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 223.6/223.6 kB 29.0 MB/s eta 0:00:00 - - -Collecting protoc-gen-swagger (from lyteidl==0.2.0a0->lytekit==0.14.10->latch) - - Downloading protoc_gen_swagger-0.1.0-py2.py3-none-any.whl (9.4 kB) - -Collecting decorator>=3.4.2 (from retry==0.9.2->lytekit==0.14.10->latch) - - Downloading decorator-5.1.1-py3-none-any.whl (9.1 kB) - -Collecting py<2.0.0,>=1.4.26 (from retry==0.9.2->lytekit==0.14.10->latch) - - Downloading py-1.11.0-py2.py3-none-any.whl (98 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 98.7/98.7 kB 14.4 MB/s eta 0:00:00 - - -INFO: pip is looking at multiple versions of boto3 to determine which version is compatible with other requirements. This could take a while. - -Collecting boto3>=1.24.22 (from latch) - - Downloading boto3-1.26.135-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.3 MB/s eta 0:00:00 - - - Downloading boto3-1.26.134-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.8 MB/s eta 0:00:00 - - - Downloading boto3-1.26.133-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.132-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.9 MB/s eta 0:00:00 - - - Downloading boto3-1.26.131-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.1 MB/s eta 0:00:00 - - - Downloading boto3-1.26.130-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.0 MB/s eta 0:00:00 - - - Downloading boto3-1.26.129-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.2 MB/s eta 0:00:00 - - -INFO: pip is looking at multiple versions of boto3 to determine which version is compatible with other requirements. This could take a while. - - Downloading boto3-1.26.128-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.6 MB/s eta 0:00:00 - - - Downloading boto3-1.26.127-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.126-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.6 MB/s eta 0:00:00 - - - Downloading boto3-1.26.125-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.9 MB/s eta 0:00:00 - - - Downloading boto3-1.26.124-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.8 MB/s eta 0:00:00 - - -INFO: This is taking longer than usual. You might need to provide the dependency resolver with stricter constraints to reduce runtime. See https://pip.pypa.io/warnings/backtracking for guidance. If you want to abort this run, press Ctrl + C. - - Downloading boto3-1.26.123-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.3 MB/s eta 0:00:00 - - - Downloading boto3-1.26.122-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.6 MB/s eta 0:00:00 - - - Downloading boto3-1.26.121-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 17.6 MB/s eta 0:00:00 - - - Downloading boto3-1.26.120-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.119-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.118-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.9 MB/s eta 0:00:00 - - - Downloading boto3-1.26.117-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.4 MB/s eta 0:00:00 - - - Downloading boto3-1.26.116-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.115-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.114-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 17.4 MB/s eta 0:00:00 - - - Downloading boto3-1.26.113-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 17.9 MB/s eta 0:00:00 - - - Downloading boto3-1.26.112-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.9 MB/s eta 0:00:00 - - - Downloading boto3-1.26.111-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.110-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.109-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.108-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.107-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.4 MB/s eta 0:00:00 - - - Downloading boto3-1.26.106-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.9 MB/s eta 0:00:00 - - - Downloading boto3-1.26.105-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 18.6 MB/s eta 0:00:00 - - - Downloading boto3-1.26.104-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.0 MB/s eta 0:00:00 - - - Downloading boto3-1.26.103-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 19.3 MB/s eta 0:00:00 - - - Downloading boto3-1.26.102-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.6/135.6 kB 20.1 MB/s eta 0:00:00 - - - Downloading boto3-1.26.101-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.5/135.5 kB 17.6 MB/s eta 0:00:00 - - - Downloading boto3-1.26.100-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.5/135.5 kB 16.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.99-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.5/135.5 kB 9.5 MB/s eta 0:00:00 - - - Downloading boto3-1.26.98-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.5/135.5 kB 18.4 MB/s eta 0:00:00 - - - Downloading boto3-1.26.97-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.5/135.5 kB 18.3 MB/s eta 0:00:00 - - - Downloading boto3-1.26.96-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.5/135.5 kB 18.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.95-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.5/135.5 kB 18.8 MB/s eta 0:00:00 - - - Downloading boto3-1.26.94-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.1/135.1 kB 17.9 MB/s eta 0:00:00 - - - Downloading boto3-1.26.93-py3-none-any.whl (135 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 135.1/135.1 kB 18.9 MB/s eta 0:00:00 - - - Downloading boto3-1.26.92-py3-none-any.whl (134 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 19.6 MB/s eta 0:00:00 - - - Downloading boto3-1.26.91-py3-none-any.whl (134 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 19.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.90-py3-none-any.whl (134 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 18.9 MB/s eta 0:00:00 - - - Downloading boto3-1.26.89-py3-none-any.whl (134 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 19.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.88-py3-none-any.whl (134 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 17.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.87-py3-none-any.whl (134 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 18.8 MB/s eta 0:00:00 - - - Downloading boto3-1.26.86-py3-none-any.whl (134 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 18.8 MB/s eta 0:00:00 - - - Downloading boto3-1.26.85-py3-none-any.whl (134 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 17.9 MB/s eta 0:00:00 - - - Downloading boto3-1.26.84-py3-none-any.whl (134 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 18.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.83-py3-none-any.whl (134 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 19.5 MB/s eta 0:00:00 - - - Downloading boto3-1.26.82-py3-none-any.whl (134 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 19.1 MB/s eta 0:00:00 - - - Downloading boto3-1.26.81-py3-none-any.whl (134 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.7/134.7 kB 19.1 MB/s eta 0:00:00 - - - Downloading boto3-1.26.80-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.3 MB/s eta 0:00:00 - - - Downloading boto3-1.26.79-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.0 MB/s eta 0:00:00 - - - Downloading boto3-1.26.78-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.4 MB/s eta 0:00:00 - - - Downloading boto3-1.26.77-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.3 MB/s eta 0:00:00 - - - Downloading boto3-1.26.76-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.0 MB/s eta 0:00:00 - - - Downloading boto3-1.26.75-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.2 MB/s eta 0:00:00 - - - Using cached boto3-1.26.74-py3-none-any.whl (132 kB) - - Downloading boto3-1.26.73-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.1 MB/s eta 0:00:00 - - - Downloading boto3-1.26.72-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.0 MB/s eta 0:00:00 - - - Downloading boto3-1.26.71-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.8 MB/s eta 0:00:00 - - - Downloading boto3-1.26.70-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.69-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.68-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.67-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.66-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.8 MB/s eta 0:00:00 - - - Downloading boto3-1.26.65-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.64-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.1 MB/s eta 0:00:00 - - - Downloading boto3-1.26.63-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.62-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.3 MB/s eta 0:00:00 - - - Downloading boto3-1.26.61-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 17.8 MB/s eta 0:00:00 - - - Downloading boto3-1.26.60-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.0 MB/s eta 0:00:00 - - - Downloading boto3-1.26.59-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.58-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.1 MB/s eta 0:00:00 - - - Downloading boto3-1.26.57-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 17.3 MB/s eta 0:00:00 - - - Downloading boto3-1.26.56-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 17.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.55-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 17.5 MB/s eta 0:00:00 - - - Downloading boto3-1.26.54-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.9 MB/s eta 0:00:00 - - - Downloading boto3-1.26.53-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.1 MB/s eta 0:00:00 - - - Downloading boto3-1.26.52-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.8 MB/s eta 0:00:00 - - - Downloading boto3-1.26.51-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.5 MB/s eta 0:00:00 - - - Downloading boto3-1.26.50-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.49-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.48-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.4 MB/s eta 0:00:00 - - - Downloading boto3-1.26.47-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.9 MB/s eta 0:00:00 - - - Downloading boto3-1.26.46-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 17.1 MB/s eta 0:00:00 - - - Downloading boto3-1.26.45-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 17.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.44-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 17.3 MB/s eta 0:00:00 - - - Downloading boto3-1.26.43-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 17.3 MB/s eta 0:00:00 - - - Downloading boto3-1.26.42-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.41-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 20.6 MB/s eta 0:00:00 - - - Downloading boto3-1.26.40-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.39-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.8 MB/s eta 0:00:00 - - - Downloading boto3-1.26.38-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.4 MB/s eta 0:00:00 - - - Downloading boto3-1.26.37-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.5 MB/s eta 0:00:00 - - - Downloading boto3-1.26.36-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 17.9 MB/s eta 0:00:00 - - - Downloading boto3-1.26.35-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 18.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.34-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 17.5 MB/s eta 0:00:00 - - - Downloading boto3-1.26.33-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.8 MB/s eta 0:00:00 - - - Downloading boto3-1.26.32-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.7/132.7 kB 19.5 MB/s eta 0:00:00 - - - Downloading boto3-1.26.31-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 18.0 MB/s eta 0:00:00 - - - Downloading boto3-1.26.30-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 18.5 MB/s eta 0:00:00 - - - Downloading boto3-1.26.29-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 17.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.28-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 18.5 MB/s eta 0:00:00 - - - Downloading boto3-1.26.27-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 16.5 MB/s eta 0:00:00 - - - Downloading boto3-1.26.26-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 18.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.25-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 17.1 MB/s eta 0:00:00 - - - Downloading boto3-1.26.24-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 18.5 MB/s eta 0:00:00 - - - Downloading boto3-1.26.23-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 19.1 MB/s eta 0:00:00 - - - Downloading boto3-1.26.22-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 19.6 MB/s eta 0:00:00 - - - Downloading boto3-1.26.21-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 18.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.20-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 18.6 MB/s eta 0:00:00 - - - Downloading boto3-1.26.19-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 18.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.18-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 18.1 MB/s eta 0:00:00 - - - Downloading boto3-1.26.17-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.6/132.6 kB 17.5 MB/s eta 0:00:00 - - - Downloading boto3-1.26.16-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.15-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.0 MB/s eta 0:00:00 - - - Downloading boto3-1.26.14-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.13-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 16.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.12-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.3 MB/s eta 0:00:00 - - - Downloading boto3-1.26.11-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.5 MB/s eta 0:00:00 - - - Downloading boto3-1.26.10-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.4 MB/s eta 0:00:00 - - - Downloading boto3-1.26.9-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.8-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.2 MB/s eta 0:00:00 - - - Downloading boto3-1.26.7-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.5 MB/s eta 0:00:00 - - - Downloading boto3-1.26.6-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.4 MB/s eta 0:00:00 - - - Downloading boto3-1.26.5-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.6 MB/s eta 0:00:00 - - - Downloading boto3-1.26.4-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 11.5 MB/s eta 0:00:00 - - - Downloading boto3-1.26.3-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.3 MB/s eta 0:00:00 - - - Downloading boto3-1.26.2-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.0 MB/s eta 0:00:00 - - - Downloading boto3-1.26.1-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.7 MB/s eta 0:00:00 - - - Downloading boto3-1.26.0-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.4 MB/s eta 0:00:00 - - - Downloading boto3-1.25.5-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 16.3 MB/s eta 0:00:00 - - - Downloading boto3-1.25.4-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.9 MB/s eta 0:00:00 - - - Downloading boto3-1.25.3-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.2 MB/s eta 0:00:00 - - - Downloading boto3-1.25.2-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.7 MB/s eta 0:00:00 - - - Downloading boto3-1.25.1-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.4 MB/s eta 0:00:00 - - - Downloading boto3-1.25.0-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.9 MB/s eta 0:00:00 - - - Downloading boto3-1.24.96-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.1 MB/s eta 0:00:00 - - - Downloading boto3-1.24.95-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 16.6 MB/s eta 0:00:00 - - - Downloading boto3-1.24.94-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.7 MB/s eta 0:00:00 - - - Downloading boto3-1.24.93-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.2 MB/s eta 0:00:00 - - - Downloading boto3-1.24.92-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 15.9 MB/s eta 0:00:00 - - - Downloading boto3-1.24.91-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.7 MB/s eta 0:00:00 - - - Downloading boto3-1.24.90-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.2 MB/s eta 0:00:00 - - - Downloading boto3-1.24.89-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.1 MB/s eta 0:00:00 - - - Downloading boto3-1.24.88-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.0 MB/s eta 0:00:00 - - - Downloading boto3-1.24.87-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 16.7 MB/s eta 0:00:00 - - - Downloading boto3-1.24.86-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.5 MB/s eta 0:00:00 - - - Downloading boto3-1.24.85-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.5 MB/s eta 0:00:00 - - - Downloading boto3-1.24.84-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.5 MB/s eta 0:00:00 - - - Downloading boto3-1.24.83-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.6 MB/s eta 0:00:00 - - - Downloading boto3-1.24.82-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.9 MB/s eta 0:00:00 - - - Downloading boto3-1.24.81-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.0 MB/s eta 0:00:00 - - - Downloading boto3-1.24.80-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.5 MB/s eta 0:00:00 - - - Downloading boto3-1.24.79-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 16.9 MB/s eta 0:00:00 - - - Downloading boto3-1.24.78-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.0 MB/s eta 0:00:00 - - - Downloading boto3-1.24.77-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.1 MB/s eta 0:00:00 - - - Downloading boto3-1.24.76-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 16.1 MB/s eta 0:00:00 - - - Downloading boto3-1.24.75-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.1 MB/s eta 0:00:00 - - - Downloading boto3-1.24.74-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.0 MB/s eta 0:00:00 - - - Downloading boto3-1.24.73-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 16.9 MB/s eta 0:00:00 - - - Downloading boto3-1.24.72-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.0 MB/s eta 0:00:00 - - - Downloading boto3-1.24.71-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.8 MB/s eta 0:00:00 - - - Downloading boto3-1.24.70-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.0 MB/s eta 0:00:00 - - - Downloading boto3-1.24.69-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.8 MB/s eta 0:00:00 - - - Downloading boto3-1.24.68-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.6 MB/s eta 0:00:00 - - - Downloading boto3-1.24.67-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.7 MB/s eta 0:00:00 - - - Downloading boto3-1.24.66-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.9 MB/s eta 0:00:00 - - - Downloading boto3-1.24.65-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.4 MB/s eta 0:00:00 - - - Downloading boto3-1.24.64-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.1 MB/s eta 0:00:00 - - - Downloading boto3-1.24.63-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.5 MB/s eta 0:00:00 - - - Downloading boto3-1.24.62-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.1 MB/s eta 0:00:00 - - - Downloading boto3-1.24.61-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.9 MB/s eta 0:00:00 - - - Downloading boto3-1.24.60-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.0 MB/s eta 0:00:00 - - - Downloading boto3-1.24.59-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.8 MB/s eta 0:00:00 - - - Downloading boto3-1.24.58-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.9 MB/s eta 0:00:00 - - - Downloading boto3-1.24.57-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.7 MB/s eta 0:00:00 - - - Downloading boto3-1.24.56-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.0 MB/s eta 0:00:00 - - - Downloading boto3-1.24.55-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.8 MB/s eta 0:00:00 - - - Downloading boto3-1.24.54-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.4 MB/s eta 0:00:00 - - - Downloading boto3-1.24.53-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.8 MB/s eta 0:00:00 - - - Downloading boto3-1.24.52-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.4 MB/s eta 0:00:00 - - - Downloading boto3-1.24.51-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 13.7 MB/s eta 0:00:00 - - - Downloading boto3-1.24.50-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.4 MB/s eta 0:00:00 - - - Downloading boto3-1.24.49-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.4 MB/s eta 0:00:00 - - - Downloading boto3-1.24.48-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.5 MB/s eta 0:00:00 - - - Downloading boto3-1.24.47-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.0 MB/s eta 0:00:00 - - - Downloading boto3-1.24.46-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 20.3 MB/s eta 0:00:00 - - - Downloading boto3-1.24.45-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.3 MB/s eta 0:00:00 - - - Downloading boto3-1.24.44-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.2 MB/s eta 0:00:00 - - - Downloading boto3-1.24.43-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.5 MB/s eta 0:00:00 - - - Downloading boto3-1.24.42-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.2 MB/s eta 0:00:00 - - - Downloading boto3-1.24.41-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.7 MB/s eta 0:00:00 - - - Downloading boto3-1.24.40-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.6 MB/s eta 0:00:00 - - - Downloading boto3-1.24.39-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 16.8 MB/s eta 0:00:00 - - - Downloading boto3-1.24.38-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.2 MB/s eta 0:00:00 - - - Downloading boto3-1.24.37-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.0 MB/s eta 0:00:00 - - - Downloading boto3-1.24.36-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.0 MB/s eta 0:00:00 - - - Downloading boto3-1.24.35-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.6 MB/s eta 0:00:00 - - - Downloading boto3-1.24.34-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.7 MB/s eta 0:00:00 - - - Downloading boto3-1.24.33-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.3 MB/s eta 0:00:00 - - - Downloading boto3-1.24.32-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.4 MB/s eta 0:00:00 - - - Downloading boto3-1.24.31-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 18.8 MB/s eta 0:00:00 - - - Downloading boto3-1.24.30-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.5 MB/s eta 0:00:00 - - - Downloading boto3-1.24.29-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 16.4 MB/s eta 0:00:00 - - - Downloading boto3-1.24.28-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.5 MB/s eta 0:00:00 - - - Downloading boto3-1.24.27-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.8 MB/s eta 0:00:00 - - - Downloading boto3-1.24.26-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.9 MB/s eta 0:00:00 - - - Downloading boto3-1.24.25-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 19.7 MB/s eta 0:00:00 - - - Downloading boto3-1.24.24-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.7 MB/s eta 0:00:00 - - - Downloading boto3-1.24.23-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 14.9 MB/s eta 0:00:00 - - - Downloading boto3-1.24.22-py3-none-any.whl (132 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.5/132.5 kB 17.6 MB/s eta 0:00:00 - - -Collecting websocket-client>=0.32.0 (from docker>=5.0->latch) - - Downloading websocket_client-1.5.1-py3-none-any.whl (55 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 55.9/55.9 kB 9.6 MB/s eta 0:00:00 - - -Requirement already satisfied: certifi>=14.05.14 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from kubernetes>=24.2.0->latch) (2023.5.7) - -Collecting google-auth>=1.0.1 (from kubernetes>=24.2.0->latch) - - Downloading google_auth-2.18.1-py2.py3-none-any.whl (178 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 178.9/178.9 kB 26.7 MB/s eta 0:00:00 - - -Collecting requests-oauthlib (from kubernetes>=24.2.0->latch) - - Downloading requests_oauthlib-1.3.1-py2.py3-none-any.whl (23 kB) - -Collecting bcrypt>=3.2 (from paramiko>=2.11.0->latch) - - Downloading bcrypt-4.0.1-cp36-abi3-manylinux_2_28_x86_64.whl (593 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 593.7/593.7 kB 46.7 MB/s eta 0:00:00 - - -Collecting pynacl>=1.5 (from paramiko>=2.11.0->latch) - - Downloading PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl (856 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 856.7/856.7 kB 57.8 MB/s eta 0:00:00 - - -Requirement already satisfied: charset-normalizer<4,>=2 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from requests>=2.28.1->latch) (3.1.0) - -Requirement already satisfied: idna<4,>=2.5 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from requests>=2.28.1->latch) (3.4) - -Collecting sniffio>=1.1 (from anyio>=3.0.0->watchfiles==0.18.1->latch) - - Downloading sniffio-1.3.0-py3-none-any.whl (10 kB) - -Collecting binaryornot>=0.4.4 (from cookiecutter>=1.7.3->lytekit==0.14.10->latch) - - Downloading binaryornot-0.4.4-py2.py3-none-any.whl (9.0 kB) - -Requirement already satisfied: Jinja2<4.0.0,>=2.7 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from cookiecutter>=1.7.3->lytekit==0.14.10->latch) (3.1.2) - -Collecting jinja2-time>=0.2.0 (from cookiecutter>=1.7.3->lytekit==0.14.10->latch) - - Downloading jinja2_time-0.2.0-py2.py3-none-any.whl (6.4 kB) - -Collecting python-slugify>=4.0.0 (from cookiecutter>=1.7.3->lytekit==0.14.10->latch) - - Downloading python_slugify-8.0.1-py2.py3-none-any.whl (9.7 kB) - -Requirement already satisfied: cffi>=1.12 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from cryptography>=3.1->asyncssh==2.12.0->latch) (1.15.1) - -Collecting marshmallow<4.0.0,>=3.3.0 (from dataclasses-json>=0.5.2->lytekit==0.14.10->latch) - - Downloading marshmallow-3.19.0-py3-none-any.whl (49 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 49.1/49.1 kB 7.0 MB/s eta 0:00:00 - - -Collecting marshmallow-enum<2.0.0,>=1.5.1 (from dataclasses-json>=0.5.2->lytekit==0.14.10->latch) - - Downloading marshmallow_enum-1.5.1-py2.py3-none-any.whl (4.2 kB) - -Collecting typing-inspect>=0.4.0 (from dataclasses-json>=0.5.2->lytekit==0.14.10->latch) - - Downloading typing_inspect-0.8.0-py3-none-any.whl (8.7 kB) - -Collecting regex>=2019.4.14 (from docker-image-py>=0.1.10->lytekit==0.14.10->latch) - - Downloading regex-2023.5.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (769 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 769.7/769.7 kB 53.6 MB/s eta 0:00:00 - - -Collecting cachetools<6.0,>=2.0.0 (from google-auth>=1.0.1->kubernetes>=24.2.0->latch) - - Downloading cachetools-5.3.0-py3-none-any.whl (9.3 kB) - -Collecting pyasn1-modules>=0.2.1 (from google-auth>=1.0.1->kubernetes>=24.2.0->latch) - - Downloading pyasn1_modules-0.3.0-py2.py3-none-any.whl (181 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 181.3/181.3 kB 22.4 MB/s eta 0:00:00 - - -INFO: pip is looking at multiple versions of grpcio-status to determine which version is compatible with other requirements. This could take a while. - -Collecting grpcio-status!=1.45.0,>=1.43 (from lytekit==0.14.10->latch) - - Downloading grpcio_status-1.54.0-py3-none-any.whl (5.1 kB) - - Downloading grpcio_status-1.53.1-py3-none-any.whl (5.1 kB) - - Downloading grpcio_status-1.53.0-py3-none-any.whl (5.1 kB) - - Downloading grpcio_status-1.51.3-py3-none-any.whl (5.1 kB) - - Downloading grpcio_status-1.51.1-py3-none-any.whl (5.1 kB) - - Downloading grpcio_status-1.50.0-py3-none-any.whl (14 kB) - - Downloading grpcio_status-1.49.1-py3-none-any.whl (14 kB) - -INFO: pip is looking at multiple versions of grpcio-status to determine which version is compatible with other requirements. This could take a while. - - Downloading grpcio_status-1.48.2-py3-none-any.whl (14 kB) - -Requirement already satisfied: attrs>=17.4.0 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from jsonschema>=4.5.1->lytekit==0.14.10->latch) (23.1.0) - -Requirement already satisfied: pyrsistent!=0.17.0,!=0.17.1,!=0.17.2,>=0.14.0 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from jsonschema>=4.5.1->lytekit==0.14.10->latch) (0.19.3) - -Collecting jaraco.classes (from keyring>=18.0.1->lytekit==0.14.10->latch) - - Downloading jaraco.classes-3.2.3-py3-none-any.whl (6.0 kB) - -Requirement already satisfied: importlib-metadata>=4.11.4 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from keyring>=18.0.1->lytekit==0.14.10->latch) (6.6.0) - -Collecting SecretStorage>=3.2 (from keyring>=18.0.1->lytekit==0.14.10->latch) - - Downloading SecretStorage-3.3.3-py3-none-any.whl (15 kB) - -Collecting jeepney>=0.4.2 (from keyring>=18.0.1->lytekit==0.14.10->latch) - - Downloading jeepney-0.8.0-py3-none-any.whl (48 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 48.4/48.4 kB 7.7 MB/s eta 0:00:00 - - -Collecting types-PyYAML (from responses>=0.10.7->lytekit==0.14.10->latch) - - Downloading types_PyYAML-6.0.12.9-py3-none-any.whl (14 kB) - -Collecting pyasn1>=0.1.3 (from rsa<4.8,>=3.1.2->awscli==1.25.22->latch) - - Downloading pyasn1-0.5.0-py2.py3-none-any.whl (83 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 83.9/83.9 kB 13.4 MB/s eta 0:00:00 - - -Collecting multidict>=4.0 (from yarl<2.0,>=1.6->gql==3.4.0->latch) - - Downloading multidict-6.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (114 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 114.5/114.5 kB 17.1 MB/s eta 0:00:00 - - -Collecting oauthlib>=3.0.0 (from requests-oauthlib->kubernetes>=24.2.0->latch) - - Downloading oauthlib-3.2.2-py3-none-any.whl (151 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 151.7/151.7 kB 5.8 MB/s eta 0:00:00 - - -Collecting chardet>=3.0.2 (from binaryornot>=0.4.4->cookiecutter>=1.7.3->lytekit==0.14.10->latch) - - Downloading chardet-5.1.0-py3-none-any.whl (199 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 199.1/199.1 kB 27.7 MB/s eta 0:00:00 - - -Requirement already satisfied: pycparser in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from cffi>=1.12->cryptography>=3.1->asyncssh==2.12.0->latch) (2.21) - -Requirement already satisfied: zipp>=0.5 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from importlib-metadata>=4.11.4->keyring>=18.0.1->lytekit==0.14.10->latch) (3.15.0) - -Requirement already satisfied: MarkupSafe>=2.0 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from Jinja2<4.0.0,>=2.7->cookiecutter>=1.7.3->lytekit==0.14.10->latch) (2.1.2) - -Collecting arrow (from jinja2-time>=0.2.0->cookiecutter>=1.7.3->lytekit==0.14.10->latch) - - Downloading arrow-1.2.3-py3-none-any.whl (66 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 66.4/66.4 kB 8.7 MB/s eta 0:00:00 - - -Requirement already satisfied: packaging>=17.0 in ./mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from marshmallow<4.0.0,>=3.3.0->dataclasses-json>=0.5.2->lytekit==0.14.10->latch) (23.1) - -Collecting text-unidecode>=1.3 (from python-slugify>=4.0.0->cookiecutter>=1.7.3->lytekit==0.14.10->latch) - - Downloading text_unidecode-1.3-py2.py3-none-any.whl (78 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 78.2/78.2 kB 10.4 MB/s eta 0:00:00 - - -Collecting mypy-extensions>=0.3.0 (from typing-inspect>=0.4.0->dataclasses-json>=0.5.2->lytekit==0.14.10->latch) - - Downloading mypy_extensions-1.0.0-py3-none-any.whl (4.7 kB) - -Collecting more-itertools (from jaraco.classes->keyring>=18.0.1->lytekit==0.14.10->latch) - - Downloading more_itertools-9.1.0-py3-none-any.whl (54 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 54.2/54.2 kB 8.6 MB/s eta 0:00:00 - - -WARNING: The candidate selected for download or install is a yanked version: 'apscheduler' candidate (version 3.9.1 at https://files.pythonhosted.org/packages/e4/9f/c3937d4babe62504b874d4bf2c0d85aa69c7f59fa84cf6050f3b9dc5d83e/APScheduler-3.9.1-py2.py3-none-any.whl (from https://pypi.org/simple/apscheduler/) (requires-python:>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4)) -Reason for being yanked: Not compatible with Python 2.7 - -Building wheels for collected packages: docker-image-py, PyYAML - - Building wheel for docker-image-py (setup.py): started - - Building wheel for docker-image-py (setup.py): finished with status 'done' - - Created wheel for docker-image-py: filename=docker_image_py-0.1.12-py3-none-any.whl size=8812 sha256=ea8e3c15a24840f8e9dd8f96be35bfe8807c4ac208bf6a7980dff5cab2708b31 - - Stored in directory: /root/.cache/pip/wheels/fb/45/02/503244da15fbcecde5c3edabb744ed0c4f9a7643126b2d222c - - Building wheel for PyYAML (pyproject.toml): started - - Building wheel for PyYAML (pyproject.toml): finished with status 'done' - - Created wheel for PyYAML: filename=PyYAML-5.4.1-cp310-cp310-linux_x86_64.whl size=141558 sha256=c9a8c01805f3c3f49d01b9022369a08c8f9bcbd8818988d9c967f0932b6bb652 - - Stored in directory: /root/.cache/pip/wheels/c7/0d/22/696ee92245ad710f506eee79bb05c740d8abccd3ecdb778683 - -Successfully built docker-image-py PyYAML - -Installing collected packages: wcwidth, types-PyYAML, text-unidecode, statsd, sortedcontainers, pytz, pytimeparse, websockets, websocket-client, uvloop, tzlocal, tqdm, sniffio, regex, PyYAML, python-slugify, python-json-logger, pyjwt, pyasn1, py, protobuf, prompt-toolkit, oauthlib, numpy, natsort, mypy-extensions, multidict, more-itertools, marshmallow, jmespath, jeepney, grpcio, graphql-core, docutils, docstring-parser, diskcache, deprecated, decorator, colorama, cloudpickle, click, chardet, cachetools, bcrypt, backoff, aioconsole, yarl, typing-inspect, rsa, retry, responses, requests-toolbelt, requests-oauthlib, pynacl, pyasn1-modules, pyarrow, protoc-gen-swagger, pandas, marshmallow-jsonschema, marshmallow-enum, jaraco.classes, googleapis-common-protos, docker-image-py, docker, croniter, botocore, binaryornot, arrow, apscheduler, anyio, watchfiles, SecretStorage, s3transfer, paramiko, lyteidl, jinja2-time, grpcio-status, gql, google-auth, dataclasses-json, asyncssh, scp, kubernetes, keyring, cookiecutter, boto3, awscli, lytekit, lytekitplugins-pods, latch - - Attempting uninstall: PyYAML - - Found existing installation: PyYAML 6.0 - - Uninstalling PyYAML-6.0: - - Successfully uninstalled PyYAML-6.0 - - Attempting uninstall: numpy - - Found existing installation: numpy 1.24.3 - - Uninstalling numpy-1.24.3: - - Successfully uninstalled numpy-1.24.3 - - Attempting uninstall: docutils - - Found existing installation: docutils 0.20.1 - - Uninstalling docutils-0.20.1: - - Successfully uninstalled docutils-0.20.1 - -ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts. -yte 1.5.1 requires pyyaml<7.0,>=6.0, but you have pyyaml 5.4.1 which is incompatible. - -Successfully installed PyYAML-5.4.1 SecretStorage-3.3.3 aioconsole-0.5.1 anyio-3.6.2 apscheduler-3.9.1 arrow-1.2.3 asyncssh-2.12.0 awscli-1.25.22 backoff-2.2.1 bcrypt-4.0.1 binaryornot-0.4.4 boto3-1.24.22 botocore-1.27.22 cachetools-5.3.0 chardet-5.1.0 click-8.1.3 cloudpickle-2.2.1 colorama-0.4.4 cookiecutter-2.1.1 croniter-1.3.14 dataclasses-json-0.5.7 decorator-5.1.1 deprecated-1.2.13 diskcache-5.6.1 docker-5.0.3 docker-image-py-0.1.12 docstring-parser-0.15 docutils-0.16 google-auth-2.18.1 googleapis-common-protos-1.59.0 gql-3.4.0 graphql-core-3.2.3 grpcio-1.54.2 grpcio-status-1.48.2 jaraco.classes-3.2.3 jeepney-0.8.0 jinja2-time-0.2.0 jmespath-1.0.1 keyring-23.13.1 kubernetes-26.1.0 latch-2.19.11 lyteidl-0.2.0a0 lytekit-0.14.10 lytekitplugins-pods-0.4.0 marshmallow-3.19.0 marshmallow-enum-1.5.1 marshmallow-jsonschema-0.13.0 more-itertools-9.1.0 multidict-6.0.4 mypy-extensions-1.0.0 natsort-8.3.1 numpy-1.21.6 oauthlib-3.2.2 pandas-1.5.3 paramiko-3.1.0 prompt-toolkit-3.0.33 protobuf-3.20.3 protoc-gen-swagger-0.1.0 py-1.11.0 pyarrow-6.0.1 pyasn1-0.5.0 pyasn1-modules-0.3.0 pyjwt-2.7.0 pynacl-1.5.0 python-json-logger-2.0.7 python-slugify-8.0.1 pytimeparse-1.1.8 pytz-2023.3 regex-2023.5.5 requests-oauthlib-1.3.1 requests-toolbelt-0.10.1 responses-0.23.1 retry-0.9.2 rsa-4.7.2 s3transfer-0.6.1 scp-0.14.5 sniffio-1.3.0 sortedcontainers-2.4.0 statsd-3.3.0 text-unidecode-1.3 tqdm-4.65.0 types-PyYAML-6.0.12.9 typing-inspect-0.8.0 tzlocal-5.0.1 uvloop-0.17.0 watchfiles-0.18.1 wcwidth-0.2.6 websocket-client-1.5.1 websockets-10.3 yarl-1.9.2 - -WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv - - ---> 73f3b443e340 - -Step 8/14 : copy Snakefile config.yaml latch_entrypoint.py /root/ - - -COPY failed: file not found in build context or excluded by .dockerignore: stat config.yaml: file does not exist diff --git a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-cddce8/docker-build-logs.txt b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-cddce8/docker-build-logs.txt deleted file mode 100644 index 9fde0450..00000000 --- a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-cddce8/docker-build-logs.txt +++ /dev/null @@ -1,1541 +0,0 @@ -Step 1/16 : from 812206152185.dkr.ecr.us-west-2.amazonaws.com/latch-base:b733-kenny--snakemake - - - ---> 77471241d7a3 - -Step 2/16 : run mkdir /opt/latch - - - ---> Running in cb2296ae24de - - ---> 6d1d7399ec34 - -Step 3/16 : RUN curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh && mkdir /root/.conda && bash Mambaforge-Linux-x86_64.sh -b && rm -f Mambaforge-Linux-x86_64.sh - - - ---> Running in 12dceda47752 - - % Total % Received % Xferd Average Speed Time Time Time Current - Dload Upload Total  -Spent Left Speed - 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 - 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 - - 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 - - 19 82.9M 19 15.9M 0 0 20.1M 0 0:00:04 --:--:-- 0:00:04 20.1M - 100 82.9M 100 82.9M 0 0 47.2M 0 0:00:01 0:00:01 --:--:-- 69.8M - -PREFIX=/root/mambaforge - -Unpacking payload ... - -Extracting _libgcc_mutex-0.1-conda_forge.tar.bz2 - -Extracting ca-certificates-2022.12.7-ha878542_0.conda - -Extracting ld_impl_linux-64-2.40-h41732ed_0.conda - -Extracting libstdcxx-ng-12.2.0-h46fd767_19.tar.bz2 - -Extracting pybind11-abi-4-hd8ed1ab_3.tar.bz2 - -Extracting python_abi-3.10-3_cp310.conda - -Extracting tzdata-2023c-h71feb2d_0.conda - -Extracting libgomp-12.2.0-h65d4601_19.tar.bz2 - -Extracting _openmp_mutex-4.5-2_gnu.tar.bz2 - -Extracting libgcc-ng-12.2.0-h65d4601_19.tar.bz2 - -Extracting bzip2-1.0.8-h7f98852_4.tar.bz2 - -Extracting c-ares-1.18.1-h7f98852_0.tar.bz2 - -Extracting fmt-9.1.0-h924138e_0.tar.bz2 - -Extracting icu-72.1-hcb278e6_0.conda - -Extracting keyutils-1.6.1-h166bdaf_0.tar.bz2 - -Extracting libev-4.33-h516909a_1.tar.bz2 - -Extracting libffi-3.4.2-h7f98852_5.tar.bz2 - -Extracting libiconv-1.17-h166bdaf_0.tar.bz2 - -Extracting libnsl-2.0.0-h7f98852_0.tar.bz2 - -Extracting libuuid-2.38.1-h0b41bf4_0.conda - -Extracting libzlib-1.2.13-h166bdaf_4.tar.bz2 - -Extracting lz4-c-1.9.4-hcb278e6_0.conda - -Extracting lzo-2.10-h516909a_1000.tar.bz2 - -Extracting ncurses-6.3-h27087fc_1.tar.bz2 - -Extracting openssl-3.1.0-h0b41bf4_0.conda - -Extracting reproc-14.2.4-h0b41bf4_0.conda - -Extracting xz-5.2.6-h166bdaf_0.tar.bz2 - -Extracting yaml-cpp-0.7.0-h27087fc_2.tar.bz2 - -Extracting libedit-3.1.20191231-he28a2e2_2.tar.bz2 - -Extracting libnghttp2-1.52.0-h61bc06f_0.conda - -Extracting libsolv-0.7.23-h3eb15da_0.conda - -Extracting libsqlite-3.40.0-h753d276_0.tar.bz2 - -Extracting libssh2-1.10.0-hf14f497_3.tar.bz2 - -Extracting libxml2-2.10.3-hfdac1af_6.conda - -Extracting readline-8.2-h8228510_1.conda - -Extracting reproc-cpp-14.2.4-hcb278e6_0.conda - -Extracting tk-8.6.12-h27826a3_0.tar.bz2 - -Extracting zstd-1.5.2-h3eb15da_6.conda - -Extracting krb5-1.20.1-h81ceb04_0.conda - -Extracting libarchive-3.6.2-h3d51595_0.conda - -Extracting python-3.10.10-he550d4f_0_cpython.conda - -Extracting certifi-2022.12.7-pyhd8ed1ab_0.conda - -Extracting charset-normalizer-3.1.0-pyhd8ed1ab_0.conda - -Extracting colorama-0.4.6-pyhd8ed1ab_0.tar.bz2 - -Extracting idna-3.4-pyhd8ed1ab_0.tar.bz2 - -Extracting libcurl-7.88.1-hdc1c0ab_1.conda - -Extracting pluggy-1.0.0-pyhd8ed1ab_5.tar.bz2 - -Extracting pycosat-0.6.4-py310h5764c6d_1.tar.bz2 - -Extracting pycparser-2.21-pyhd8ed1ab_0.tar.bz2 - -Extracting pysocks-1.7.1-pyha2e5f31_6.tar.bz2 - -Extracting ruamel.yaml.clib-0.2.7-py310h1fa729e_1.conda - -Extracting setuptools-65.6.3-pyhd8ed1ab_0.conda - -Extracting toolz-0.12.0-pyhd8ed1ab_0.tar.bz2 - -Extracting wheel-0.40.0-pyhd8ed1ab_0.conda - -Extracting cffi-1.15.1-py310h255011f_3.conda - -Extracting libmamba-1.4.1-hcea66bb_0.conda - -Extracting pip-23.0.1-pyhd8ed1ab_0.conda - -Extracting ruamel.yaml-0.17.21-py310h1fa729e_3.conda - -Extracting tqdm-4.65.0-pyhd8ed1ab_1.conda - -Extracting brotlipy-0.7.0-py310h5764c6d_1005.tar.bz2 - -Extracting cryptography-40.0.1-py310h34c0648_0.conda - -Extracting libmambapy-1.4.1-py310h1428755_0.conda - -Extracting zstandard-0.19.0-py310hdeb6495_1.conda - -Extracting conda-package-streaming-0.7.0-pyhd8ed1ab_1.conda - -Extracting pyopenssl-23.1.1-pyhd8ed1ab_0.conda - -Extracting conda-package-handling-2.0.2-pyh38be061_0.conda - -Extracting urllib3-1.26.15-pyhd8ed1ab_0.conda - -Extracting requests-2.28.2-pyhd8ed1ab_1.conda - -Extracting conda-23.1.0-py310hff52083_0.conda - -Extracting mamba-1.4.1-py310h51d5547_0.conda - - -Installing base environment... - - - - __ - __ ______ ___ ____ _____ ___ / /_ ____ _ - / / / / __ `__ \/ __ `/ __ `__ \/ __ \/ __ `/ - / /_/ / / / / / / /_/ / / / / / / /_/ / /_/ / - / .___/_/ /_/ /_/\__,_/_/ /_/ /_/_.___/\__,_/ - /_/ - - -Transaction - - Prefix: /root/mambaforge - - Updating specs: - - - conda-forge/linux-64::_libgcc_mutex==0.1=conda_forge[md5=d7c89558ba9fa0495403155b64376d81] - - conda-forge/linux-64::ca-certificates==2022.12.7=ha878542_0[md5=ff9f73d45c4a07d6f424495288a26080] - - conda-forge/linux-64::ld_impl_linux-64==2.40=h41732ed_0[md5=7aca3059a1729aa76c597603f10b0dd3] - - conda-forge/linux-64::libstdcxx-ng==12.2.0=h46fd767_19[md5=1030b1f38c129f2634eae026f704fe60] - - conda-forge/noarch::pybind11-abi==4=hd8ed1ab_3[md5=878f923dd6acc8aeb47a75da6c4098be] - - conda-forge/linux-64::python_abi==3.10=3_cp310[md5=4eb33d14d794b0f4be116443ffed3853] - - conda-forge/noarch::tzdata==2023c=h71feb2d_0[md5=939e3e74d8be4dac89ce83b20de2492a] - - conda-forge/linux-64::libgomp==12.2.0=h65d4601_19[md5=cedcee7c064c01c403f962c9e8d3c373] - - conda-forge/linux-64::_openmp_mutex==4.5=2_gnu[md5=73aaf86a425cc6e73fcf236a5a46396d] - - conda-forge/linux-64::libgcc-ng==12.2.0=h65d4601_19[md5=e4c94f80aef025c17ab0828cd85ef535] - - conda-forge/linux-64::bzip2==1.0.8=h7f98852_4[md5=a1fd65c7ccbf10880423d82bca54eb54] - - conda-forge/linux-64::c-ares==1.18.1=h7f98852_0[md5=f26ef8098fab1f719c91eb760d63381a] - - conda-forge/linux-64::fmt==9.1.0=h924138e_0[md5=b57864c85261a0fbc7132d2cc17478c7] - - conda-forge/linux-64::icu==72.1=hcb278e6_0[md5=7c8d20d847bb45f56bd941578fcfa146] - - conda-forge/linux-64::keyutils==1.6.1=h166bdaf_0[md5=30186d27e2c9fa62b45fb1476b7200e3] - - conda-forge/linux-64::libev==4.33=h516909a_1[md5=6f8720dff19e17ce5d48cfe7f3d2f0a3] - - conda-forge/linux-64::libffi==3.4.2=h7f98852_5[md5=d645c6d2ac96843a2bfaccd2d62b3ac3] - - conda-forge/linux-64::libiconv==1.17=h166bdaf_0[md5=b62b52da46c39ee2bc3c162ac7f1804d] - - conda-forge/linux-64::libnsl==2.0.0=h7f98852_0[md5=39b1328babf85c7c3a61636d9cd50206] - - conda-forge/linux-64::libuuid==2.38.1=h0b41bf4_0[md5=40b61aab5c7ba9ff276c41cfffe6b80b] - - conda-forge/linux-64::libzlib==1.2.13=h166bdaf_4[md5=f3f9de449d32ca9b9c66a22863c96f41] - - conda-forge/linux-64::lz4-c==1.9.4=hcb278e6_0[md5=318b08df404f9c9be5712aaa5a6f0bb0] - - conda-forge/linux-64::lzo==2.10=h516909a_1000[md5=bb14fcb13341b81d5eb386423b9d2bac] - - conda-forge/linux-64::ncurses==6.3=h27087fc_1[md5=4acfc691e64342b9dae57cf2adc63238] - - conda-forge/linux-64::openssl==3.1.0=h0b41bf4_0[md5=2d833be81a21128e317325a01326d36f] - - conda-forge/linux-64::reproc==14.2.4=h0b41bf4_0[md5=0f51393e019df1f0047ef864cd9ddeec] - - conda-forge/linux-64::xz==5.2.6=h166bdaf_0[md5=2161070d867d1b1204ea749c8eec4ef0] - - - conda-forge/linux-64::yaml-cpp==0.7.0=h27087fc_2[md5=0449d47d8457feaa3720d4779616dde2] - - conda-forge/linux-64::libedit==3.1.20191231=he28a2e2_2[md5=4d331e44109e3f0e19b4cb8f9b82f3e1] - - conda-forge/linux-64::libnghttp2==1.52.0=h61bc06f_0[md5=613955a50485812985c059e7b269f42e] - - conda-forge/linux-64::libsolv==0.7.23=h3eb15da_0[md5=122332e6deb4aea9eaf22021d2ecd256] - - conda-forge/linux-64::libsqlite==3.40.0=h753d276_0[md5=2e5f9a37d487e1019fd4d8113adb2f9f] - - conda-forge/linux-64::libssh2==1.10.0=hf14f497_3[md5=d85acad4b47dff4e3def14a769a97906] - - conda-forge/linux-64::libxml2==2.10.3=hfdac1af_6[md5=7eecaadc2eaeef464c5fe17702f17c86] - - conda-forge/linux-64::readline==8.2=h8228510_1[md5=47d31b792659ce70f470b5c82fdfb7a4] - - conda-forge/linux-64::reproc-cpp==14.2.4=hcb278e6_0[md5=ede8e0f849f2fee2f78cb488b4ea3b33] - - - conda-forge/linux-64::tk==8.6.12=h27826a3_0[md5=5b8c42eb62e9fc961af70bdd6a26e168] - - conda-forge/linux-64::zstd==1.5.2=h3eb15da_6[md5=6b63daed8feeca47be78f323e793d555] - - conda-forge/linux-64::krb5==1.20.1=h81ceb04_0[md5=89a41adce7106749573d883b2f657d78] - - - conda-forge/linux-64::libarchive==3.6.2=h3d51595_0[md5=9f915b4adeb9dcfd450b9ad238e2db4c] - - conda-forge/linux-64::python==3.10.10=he550d4f_0_cpython[md5=de25afc7041c103c7f510c746bb63435] - - conda-forge/noarch::certifi==2022.12.7=pyhd8ed1ab_0[md5=fb9addc3db06e56abe03e0e9f21a63e6] - - conda-forge/noarch::charset-normalizer==3.1.0=pyhd8ed1ab_0[md5=7fcff9f6f123696e940bda77bd4d6551] - - conda-forge/noarch::colorama==0.4.6=pyhd8ed1ab_0[md5=3faab06a954c2a04039983f2c4a50d99] - - conda-forge/noarch::idna==3.4=pyhd8ed1ab_0[md5=34272b248891bddccc64479f9a7fffed] - - conda-forge/linux-64::libcurl==7.88.1=hdc1c0ab_1[md5=3d1189864d1c0ed2a5919cb067b5903d] - - conda-forge/noarch::pluggy==1.0.0=pyhd8ed1ab_5[md5=7d301a0d25f424d96175f810935f0da9] - - conda-forge/linux-64::pycosat==0.6.4=py310h5764c6d_1[md5=0e565d732f6660374b45d76761c09b06] - - conda-forge/noarch::pycparser==2.21=pyhd8ed1ab_0[md5=076becd9e05608f8dc72757d5f3a91ff] - - conda-forge/noarch::pysocks==1.7.1=pyha2e5f31_6[md5=2a7de29fb590ca14b5243c4c812c8025] - - conda-forge/linux-64::ruamel.yaml.clib==0.2.7=py310h1fa729e_1[md5=2f9b517412af46255cef5e53a22c264e] - - conda-forge/noarch::setuptools==65.6.3=pyhd8ed1ab_0[md5=9600fc9524d3f821e6a6d58c52f5bf5a] - - conda-forge/noarch::toolz==0.12.0=pyhd8ed1ab_0[md5=92facfec94bc02d6ccf42e7173831a36] - - conda-forge/noarch::wheel==0.40.0=pyhd8ed1ab_0[md5=49bb0d9e60ce1db25e151780331bb5f3] - - conda-forge/linux-64::cffi==1.15.1=py310h255011f_3[md5=800596144bb613cd7ac58b80900ce835] - - conda-forge/linux-64::libmamba==1.4.1=hcea66bb_0[md5=e512a4c95ff1eca1684642fa32bd2f55] - - conda-forge/noarch::pip==23.0.1=pyhd8ed1ab_0[md5=8025ca83b8ba5430b640b83917c2a6f7] - - conda-forge/linux-64::ruamel.yaml==0.17.21=py310h1fa729e_3[md5=97204ae92b703d74a983db0e6d07d009] - - conda-forge/noarch::tqdm==4.65.0=pyhd8ed1ab_1[md5=ed792aff3acb977d09c7013358097f83] - - conda-forge/linux-64::brotlipy==0.7.0=py310h5764c6d_1005[md5=87669c3468dff637bbd0363bc0f895cf] - - conda-forge/linux-64::cryptography==40.0.1=py310h34c0648_0[md5=deafd9206c2e307874f3777a33cafb79] - - conda-forge/linux-64::libmambapy==1.4.1=py310h1428755_0[md5=323e09e9947b6a415f9d73562e4ca862] - - conda-forge/linux-64::zstandard==0.19.0=py310hdeb6495_1[md5=2cce1a48e6687f64d371d2e7fc9c7fbf] - - conda-forge/noarch::conda-package-streaming==0.7.0=pyhd8ed1ab_1[md5=1a2fa9e53cfbc2e4d9ab21990805a436] - - conda-forge/noarch::pyopenssl==23.1.1=pyhd8ed1ab_0[md5=0b34aa3ab7e7ccb1765a03dd9ed29938] - - conda-forge/noarch::conda-package-handling==2.0.2=pyh38be061_0[md5=44800e9bd13143292097c65e57323038] - - conda-forge/noarch::urllib3==1.26.15=pyhd8ed1ab_0[md5=27db656619a55d727eaf5a6ece3d2fd6] - - - conda-forge/noarch::requests==2.28.2=pyhd8ed1ab_1[md5=3bfbd6ead1d7299ed46dab3a7bf0bc8c] - - conda-forge/linux-64::conda==23.1.0=py310hff52083_0[md5=c2f5cd14bf4a8cc673f66fd9839e6602] - - conda-forge/linux-64::mamba==1.4.1=py310h51d5547_0[md5=49170d6752d2326fe16dc2b6e74f9e54] - - - - Package Version Build Channel Size -─────────────────────────────────────────────────────────────────────────────────────── - Install: -─────────────────────────────────────────────────────────────────────────────────────── - - + _libgcc_mutex 0.1 conda_forge conda-forge Cached - + _openmp_mutex 4.5 2_gnu conda-forge Cached - + brotlipy 0.7.0 py310h5764c6d_1005 conda-forge Cached - + bzip2 1.0.8 h7f98852_4 conda-forge Cached - + c-ares 1.18.1 h7f98852_0 conda-forge Cached - + ca-certificates 2022.12.7 ha878542_0 conda-forge Cached - + certifi 2022.12.7 pyhd8ed1ab_0 conda-forge Cached - + cffi 1.15.1 py310h255011f_3 conda-forge Cached - + charset-normalizer 3.1.0 pyhd8ed1ab_0 conda-forge Cached - + colorama 0.4.6 pyhd8ed1ab_0 conda-forge Cached - + conda 23.1.0 py310hff52083_0 conda-forge Cached - + conda-package-handling 2.0.2 pyh38be061_0 conda-forge Cached - + conda-package-streaming 0.7.0 pyhd8ed1ab_1 conda-forge Cached - + cryptography 40.0.1 py310h34c0648_0 conda-forge Cached - + fmt 9.1.0 h924138e_0 conda-forge Cached - + icu 72.1 hcb278e6_0 conda-forge Cached - + idna 3.4 pyhd8ed1ab_0 conda-forge Cached - + keyutils 1.6.1 h166bdaf_0 conda-forge Cached - + krb5 1.20.1 h81ceb04_0 conda-forge Cached - + ld_impl_linux-64 2.40 h41732ed_0 conda-forge Cached - + libarchive 3.6.2 h3d51595_0 conda-forge Cached - + libcurl 7.88.1 hdc1c0ab_1 conda-forge Cached - + libedit 3.1.20191231 he28a2e2_2 conda-forge Cached - + libev 4.33 h516909a_1 conda-forge Cached - + libffi 3.4.2 h7f98852_5 conda-forge Cached - + libgcc-ng 12.2.0 h65d4601_19 conda-forge Cached - + libgomp 12.2.0 h65d4601_19 conda-forge Cached - + libiconv 1.17 h166bdaf_0 conda-forge Cached - + libmamba 1.4.1 hcea66bb_0 conda-forge Cached - + libmambapy 1.4.1 py310h1428755_0 conda-forge Cached - + libnghttp2 1.52.0 h61bc06f_0 conda-forge Cached - + libnsl 2.0.0 h7f98852_0 conda-forge Cached - + libsolv 0.7.23 h3eb15da_0 conda-forge Cached - + libsqlite 3.40.0 h753d276_0 conda-forge Cached - + libssh2 1.10.0 hf14f497_3 conda-forge Cached - + libstdcxx-ng 12.2.0 h46fd767_19 conda-forge Cached - + libuuid 2.38.1 h0b41bf4_0 conda-forge Cached - + libxml2 2.10.3 hfdac1af_6 conda-forge Cached - + libzlib 1.2.13 h166bdaf_4 conda-forge Cached - + lz4-c 1.9.4 hcb278e6_0 conda-forge Cached - + lzo 2.10 h516909a_1000 conda-forge Cached - + mamba 1.4.1 py310h51d5547_0 conda-forge Cached - + ncurses 6.3 h27087fc_1 conda-forge Cached - + openssl 3.1.0 h0b41bf4_0 conda-forge Cached - + pip 23.0.1 pyhd8ed1ab_0 conda-forge Cached - + pluggy 1.0.0 pyhd8ed1ab_5 conda-forge Cached - + pybind11-abi 4 hd8ed1ab_3 conda-forge Cached - + pycosat 0.6.4 py310h5764c6d_1 conda-forge Cached - + pycparser 2.21 pyhd8ed1ab_0 conda-forge Cached - + pyopenssl 23.1.1 pyhd8ed1ab_0 conda-forge Cached - + pysocks 1.7.1 pyha2e5f31_6 conda-forge Cached - + python 3.10.10 he550d4f_0_cpython conda-forge Cached - + python_abi 3.10 3_cp310 conda-forge Cached - + readline 8.2 h8228510_1 conda-forge Cached - + reproc 14.2.4 h0b41bf4_0 conda-forge Cached - + reproc-cpp 14.2.4 hcb278e6_0 conda-forge Cached - + requests 2.28.2 pyhd8ed1ab_1 conda-forge Cached - + ruamel.yaml 0.17.21 py310h1fa729e_3 conda-forge Cached - + ruamel.yaml.clib 0.2.7 py310h1fa729e_1 conda-forge Cached - + setuptools 65.6.3 pyhd8ed1ab_0 conda-forge Cached - + tk 8.6.12 h27826a3_0 conda-forge Cached - + toolz 0.12.0 pyhd8ed1ab_0 conda-forge Cached - + tqdm 4.65.0 pyhd8ed1ab_1 conda-forge Cached - + tzdata 2023c h71feb2d_0 conda-forge Cached - + urllib3 1.26.15 pyhd8ed1ab_0 conda-forge Cached - + wheel 0.40.0 pyhd8ed1ab_0 conda-forge Cached - + xz 5.2.6 h166bdaf_0 conda-forge Cached - + yaml-cpp 0.7.0 h27087fc_2 conda-forge Cached - + zstandard 0.19.0 py310hdeb6495_1 conda-forge Cached - + zstd 1.5.2 h3eb15da_6 conda-forge Cached - - Summary: - - Install: 70 packages - - Total download: 0 B - -─────────────────────────────────────────────────────────────────────────────────────── - - - - -Transaction starting - -Linking _libgcc_mutex-0.1-conda_forge - -Linking ca-certificates-2022.12.7-ha878542_0 - -Linking ld_impl_linux-64-2.40-h41732ed_0 - -Linking libstdcxx-ng-12.2.0-h46fd767_19 - -Linking pybind11-abi-4-hd8ed1ab_3 - -Linking python_abi-3.10-3_cp310 - -Linking tzdata-2023c-h71feb2d_0 - -Linking libgomp-12.2.0-h65d4601_19 - -Linking _openmp_mutex-4.5-2_gnu - -Linking libgcc-ng-12.2.0-h65d4601_19 - -Linking bzip2-1.0.8-h7f98852_4 - -Linking c-ares-1.18.1-h7f98852_0 - -Linking fmt-9.1.0-h924138e_0 - -Linking icu-72.1-hcb278e6_0 - -Linking keyutils-1.6.1-h166bdaf_0 - -Linking libev-4.33-h516909a_1 - -Linking libffi-3.4.2-h7f98852_5 - -Linking libiconv-1.17-h166bdaf_0 - -Linking libnsl-2.0.0-h7f98852_0 - -Linking libuuid-2.38.1-h0b41bf4_0 - -Linking libzlib-1.2.13-h166bdaf_4 - -Linking lz4-c-1.9.4-hcb278e6_0 - -Linking lzo-2.10-h516909a_1000 - -Linking ncurses-6.3-h27087fc_1 - -Linking openssl-3.1.0-h0b41bf4_0 - -Linking reproc-14.2.4-h0b41bf4_0 - -Linking xz-5.2.6-h166bdaf_0 - -Linking yaml-cpp-0.7.0-h27087fc_2 - -Linking libedit-3.1.20191231-he28a2e2_2 - -Linking libnghttp2-1.52.0-h61bc06f_0 - -Linking libsolv-0.7.23-h3eb15da_0 - -Linking libsqlite-3.40.0-h753d276_0 - -Linking libssh2-1.10.0-hf14f497_3 - -Linking libxml2-2.10.3-hfdac1af_6 - -Linking readline-8.2-h8228510_1 - -Linking reproc-cpp-14.2.4-hcb278e6_0 - -Linking tk-8.6.12-h27826a3_0 - -Linking zstd-1.5.2-h3eb15da_6 - -Linking krb5-1.20.1-h81ceb04_0 - -Linking libarchive-3.6.2-h3d51595_0 - -Linking python-3.10.10-he550d4f_0_cpython - -Linking certifi-2022.12.7-pyhd8ed1ab_0 - -Linking charset-normalizer-3.1.0-pyhd8ed1ab_0 - -Linking colorama-0.4.6-pyhd8ed1ab_0 - -Linking idna-3.4-pyhd8ed1ab_0 - -Linking libcurl-7.88.1-hdc1c0ab_1 - -Linking pluggy-1.0.0-pyhd8ed1ab_5 - -Linking pycosat-0.6.4-py310h5764c6d_1 - -Linking pycparser-2.21-pyhd8ed1ab_0 - -Linking pysocks-1.7.1-pyha2e5f31_6 - -Linking ruamel.yaml.clib-0.2.7-py310h1fa729e_1 - -Linking setuptools-65.6.3-pyhd8ed1ab_0 - -Linking toolz-0.12.0-pyhd8ed1ab_0 - -Linking wheel-0.40.0-pyhd8ed1ab_0 - -Linking cffi-1.15.1-py310h255011f_3 - -Linking libmamba-1.4.1-hcea66bb_0 - -Linking pip-23.0.1-pyhd8ed1ab_0 - -Linking ruamel.yaml-0.17.21-py310h1fa729e_3 - -Linking tqdm-4.65.0-pyhd8ed1ab_1 - -Linking brotlipy-0.7.0-py310h5764c6d_1005 - -Linking cryptography-40.0.1-py310h34c0648_0 - -Linking libmambapy-1.4.1-py310h1428755_0 - -Linking zstandard-0.19.0-py310hdeb6495_1 - -Linking conda-package-streaming-0.7.0-pyhd8ed1ab_1 - -Linking pyopenssl-23.1.1-pyhd8ed1ab_0 - -Linking conda-package-handling-2.0.2-pyh38be061_0 - -Linking urllib3-1.26.15-pyhd8ed1ab_0 - -Linking requests-2.28.2-pyhd8ed1ab_1 - -Linking conda-23.1.0-py310hff52083_0 - -Linking mamba-1.4.1-py310h51d5547_0 - -Transaction finished - -installation finished. - -WARNING: - You currently have a PYTHONPATH environment variable set. This may cause - unexpected behavior when running the Python interpreter in Mambaforge. - For best results, please verify that your PYTHONPATH only points to - directories of packages that are compatible with the Python interpreter - in Mambaforge: /root/mambaforge - - ---> e5d7f1c377ad - -Step 4/16 : copy environment.yaml /root/environment.yaml - - - ---> f1895bb6bb01 - -Step 5/16 : run /root/mambaforge/bin/mamba env create --name snakemake-tutorial --file environment.yaml - - - ---> Running in f846c7f12119 - - - -Looking for: ["snakemake-minimal[version='>=7.3']", 'jinja2', 'matplotlib', 'graphviz', 'bcftools=1.15', 'samtools=1.15', 'bwa=0.7.17', 'pysam=0.19', 'pygments'] - - - -Transaction - - Prefix: /root/mambaforge/envs/snakemake-tutorial - - Updating specs: - - - snakemake-minimal[version='>=7.3'] - - jinja2 - - matplotlib - - graphviz - - bcftools=1.15 - - samtools=1.15 - - bwa=0.7.17 - - pysam=0.19 - - pygments - - - - Package Version Build Channel Size -─────────────────────────────────────────────────────────────────────────────────────────────────── - Install: -─────────────────────────────────────────────────────────────────────────────────────────────────── - - + _libgcc_mutex 0.1 conda_forge conda-forge/linux-64 Cached - + _openmp_mutex 4.5 2_gnu conda-forge/linux-64 Cached - + alsa-lib 1.2.8 h166bdaf_0 conda-forge/linux-64 592kB - + amply 0.1.5 pyhd8ed1ab_0 conda-forge/noarch 21kB - + appdirs 1.4.4 pyh9f0ad1d_0 conda-forge/noarch 13kB - + atk-1.0 2.38.0 hd4edc92_1 conda-forge/linux-64 552kB - + attr 2.5.1 h166bdaf_1 conda-forge/linux-64 71kB - + attrs 23.1.0 pyh71513ae_1 conda-forge/noarch 55kB - + bcftools 1.15.1 hfe4b78e_1 bioconda/linux-64 867kB - + brotli 1.0.9 h166bdaf_8 conda-forge/linux-64 19kB - + brotli-bin 1.0.9 h166bdaf_8 conda-forge/linux-64 20kB - + brotlipy 0.7.0 py310h5764c6d_1005 conda-forge/linux-64 Cached - + bwa 0.7.17 he4a0461_11 bioconda/linux-64 196kB - + bzip2 1.0.8 h7f98852_4 conda-forge/linux-64 Cached - + c-ares 1.19.0 hd590300_0 conda-forge/linux-64 114kB - + ca-certificates 2023.5.7 hbcca054_0 conda-forge/linux-64 148kB - + cairo 1.16.0 ha61ee94_1014 conda-forge/linux-64 2MB - + certifi 2023.5.7 pyhd8ed1ab_0 conda-forge/noarch 152kB - + cffi 1.15.1 py310h255011f_3 conda-forge/linux-64 Cached - + charset-normalizer 3.1.0 pyhd8ed1ab_0 conda-forge/noarch Cached - + coin-or-cbc 2.10.10 h9002f0b_0 conda-forge/linux-64 941kB - + coin-or-cgl 0.60.7 h516709c_0 conda-forge/linux-64 551kB - + coin-or-clp 1.17.8 h1ee7a9c_0 conda-forge/linux-64 1MB - + coin-or-osi 0.108.8 ha2443b9_0 conda-forge/linux-64 389kB - + coin-or-utils 2.11.9 hee58242_0 conda-forge/linux-64 687kB - + coincbc 2.10.10 0_metapackage conda-forge/noarch 12kB - + configargparse 1.5.3 pyhd8ed1ab_0 conda-forge/noarch 33kB - + connection_pool 0.0.3 pyhd3deb0d_0 conda-forge/noarch 8kB - + contourpy 1.0.7 py310hdf3cbec_0 conda-forge/linux-64 216kB - + cryptography 39.0.0 py310h65dfdc0_0 conda-forge/linux-64 1MB - + cycler 0.11.0 pyhd8ed1ab_0 conda-forge/noarch 10kB - + datrie 0.8.2 py310h5764c6d_6 conda-forge/linux-64 148kB - + dbus 1.13.6 h5008d03_3 conda-forge/linux-64 619kB - + docutils 0.20.1 py310hff52083_0 conda-forge/linux-64 721kB - + dpath 2.1.6 pyha770c72_0 conda-forge/noarch 21kB - + expat 2.5.0 hcb278e6_1 conda-forge/linux-64 137kB - + fftw 3.3.10 nompi_hc118613_107 conda-forge/linux-64 2MB - + filelock 3.12.0 pyhd8ed1ab_0 conda-forge/noarch 15kB - + font-ttf-dejavu-sans-mono 2.37 hab24e00_0 conda-forge/noarch 397kB - + font-ttf-inconsolata 3.000 h77eed37_0 conda-forge/noarch 97kB - + font-ttf-source-code-pro 2.038 h77eed37_0 conda-forge/noarch 701kB - + font-ttf-ubuntu 0.83 hab24e00_0 conda-forge/noarch 2MB - + fontconfig 2.14.2 h14ed4e7_0 conda-forge/linux-64 272kB - + fonts-conda-ecosystem 1 0 conda-forge/noarch 4kB - + fonts-conda-forge 1 0 conda-forge/noarch 4kB - + fonttools 4.39.4 py310h2372a71_0 conda-forge/linux-64 2MB - + freetype 2.12.1 hca18f0e_1 conda-forge/linux-64 626kB - + fribidi 1.0.10 h36c2ea0_0 conda-forge/linux-64 114kB - + gdk-pixbuf 2.42.8 hff1cb4f_1 conda-forge/linux-64 612kB - + gettext 0.21.1 h27087fc_0 conda-forge/linux-64 4MB - + giflib 5.2.1 h0b41bf4_3 conda-forge/linux-64 77kB - + gitdb 4.0.10 pyhd8ed1ab_0 conda-forge/noarch 52kB - + gitpython 3.1.31 pyhd8ed1ab_0 conda-forge/noarch 142kB - + glib 2.76.2 hfc55251_0 conda-forge/linux-64 484kB - + glib-tools 2.76.2 hfc55251_0 conda-forge/linux-64 112kB - + graphite2 1.3.13 h58526e2_1001 conda-forge/linux-64 105kB - + graphviz 7.0.5 h2e5815a_0 conda-forge/linux-64 2MB - + gsl 2.7 he838d99_0 conda-forge/linux-64 3MB - + gst-plugins-base 1.21.3 h4243ec0_1 conda-forge/linux-64 3MB - + gstreamer 1.21.3 h25f0c4b_1 conda-forge/linux-64 2MB - + gstreamer-orc 0.4.33 h166bdaf_0 conda-forge/linux-64 306kB - + gtk2 2.24.33 h90689f9_2 conda-forge/linux-64 8MB - + gts 0.7.6 h64030ff_2 conda-forge/linux-64 421kB - + harfbuzz 6.0.0 h8e241bc_0 conda-forge/linux-64 1MB - + htslib 1.16 h6bc39ce_0 bioconda/linux-64 2MB - + humanfriendly 10.0 py310hff52083_4 conda-forge/linux-64 123kB - + icu 70.1 h27087fc_0 conda-forge/linux-64 14MB - + idna 3.4 pyhd8ed1ab_0 conda-forge/noarch Cached - + importlib-metadata 6.6.0 pyha770c72_0 conda-forge/noarch 26kB - + importlib_resources 5.12.0 pyhd8ed1ab_0 conda-forge/noarch 31kB - + jack 1.9.22 h11f4161_0 conda-forge/linux-64 464kB - + jinja2 3.1.2 pyhd8ed1ab_1 conda-forge/noarch 101kB - + jpeg 9e h0b41bf4_3 conda-forge/linux-64 240kB - + jsonschema 4.17.3 pyhd8ed1ab_0 conda-forge/noarch 70kB - + jupyter_core 5.3.0 py310hff52083_0 conda-forge/linux-64 91kB - + keyutils 1.6.1 h166bdaf_0 conda-forge/linux-64 Cached - + kiwisolver 1.4.4 py310hbf28c38_1 conda-forge/linux-64 77kB - + krb5 1.20.1 hf9c8cef_0 conda-forge/linux-64 1MB - + lame 3.100 h166bdaf_1003 conda-forge/linux-64 508kB - + lcms2 2.14 h6ed2654_0 conda-forge/linux-64 262kB - + ld_impl_linux-64 2.40 h41732ed_0 conda-forge/linux-64 Cached - + lerc 4.0.0 h27087fc_0 conda-forge/linux-64 282kB - + libblas 3.9.0 16_linux64_openblas conda-forge/linux-64 13kB - + libbrotlicommon 1.0.9 h166bdaf_8 conda-forge/linux-64 67kB - + libbrotlidec 1.0.9 h166bdaf_8 conda-forge/linux-64 34kB - + libbrotlienc 1.0.9 h166bdaf_8 conda-forge/linux-64 295kB - + libcap 2.66 ha37c62d_0 conda-forge/linux-64 100kB - + libcblas 3.9.0 16_linux64_openblas conda-forge/linux-64 13kB - + libclang 15.0.7 default_h7634d5b_2 conda-forge/linux-64 133kB - + libclang13 15.0.7 default_h9986a30_2 conda-forge/linux-64 10MB - + libcups 2.3.3 h36d4200_3 conda-forge/linux-64 5MB - + libcurl 7.87.0 h6312ad2_0 conda-forge/linux-64 347kB - + libdb 6.2.32 h9c3ff4c_0 conda-forge/linux-64 24MB - + libdeflate 1.13 h166bdaf_0 conda-forge/linux-64 80kB - + libedit 3.1.20191231 he28a2e2_2 conda-forge/linux-64 Cached - + libev 4.33 h516909a_1 conda-forge/linux-64 Cached - + libevent 2.1.10 h9b69904_4 conda-forge/linux-64 1MB - + libexpat 2.5.0 hcb278e6_1 conda-forge/linux-64 78kB - + libffi 3.4.2 h7f98852_5 conda-forge/linux-64 Cached - + libflac 1.4.2 h27087fc_0 conda-forge/linux-64 421kB - + libgcc-ng 12.2.0 h65d4601_19 conda-forge/linux-64 Cached - + libgcrypt 1.10.1 h166bdaf_0 conda-forge/linux-64 720kB - + libgd 2.3.3 h18fbbfe_3 conda-forge/linux-64 272kB - + libgfortran-ng 12.2.0 h69a702a_19 conda-forge/linux-64 23kB - + libgfortran5 12.2.0 h337968e_19 conda-forge/linux-64 2MB - + libglib 2.76.2 hebfc3b9_0 conda-forge/linux-64 3MB - + libgomp 12.2.0 h65d4601_19 conda-forge/linux-64 Cached - + libgpg-error 1.46 h620e276_0 conda-forge/linux-64 258kB - + libiconv 1.17 h166bdaf_0 conda-forge/linux-64 Cached - + liblapack 3.9.0 16_linux64_openblas conda-forge/linux-64 13kB - + liblapacke 3.9.0 16_linux64_openblas conda-forge/linux-64 13kB - + libllvm15 15.0.7 hadd5161_1 conda-forge/linux-64 33MB - + libnghttp2 1.51.0 hdcd2b5c_0 conda-forge/linux-64 623kB - + libnsl 2.0.0 h7f98852_0 conda-forge/linux-64 Cached - + libogg 1.3.4 h7f98852_1 conda-forge/linux-64 211kB - + libopenblas 0.3.21 pthreads_h78a6416_3 conda-forge/linux-64 11MB - + libopus 1.3.1 h7f98852_1 conda-forge/linux-64 261kB - + libpng 1.6.39 h753d276_0 conda-forge/linux-64 283kB - + libpq 15.1 h2baec63_3 conda-forge/linux-64 2MB - + librsvg 2.54.4 h7abd40a_0 conda-forge/linux-64 7MB - + libsndfile 1.2.0 hb75c966_0 conda-forge/linux-64 350kB - + libsqlite 3.42.0 h2797004_0 conda-forge/linux-64 829kB - + libssh2 1.10.0 haa6b8db_3 conda-forge/linux-64 239kB - + libstdcxx-ng 12.2.0 h46fd767_19 conda-forge/linux-64 Cached - + libsystemd0 252 h2a991cd_0 conda-forge/linux-64 393kB - + libtiff 4.4.0 h0e0dad5_3 conda-forge/linux-64 658kB - + libtool 2.4.7 h27087fc_0 conda-forge/linux-64 412kB - + libudev1 253 h0b41bf4_0 conda-forge/linux-64 119kB - + libuuid 2.38.1 h0b41bf4_0 conda-forge/linux-64 Cached - + libvorbis 1.3.7 h9c3ff4c_0 conda-forge/linux-64 286kB - + libwebp 1.2.4 h522a892_0 conda-forge/linux-64 90kB - + libwebp-base 1.2.4 h166bdaf_0 conda-forge/linux-64 413kB - + libxcb 1.13 h7f98852_1004 conda-forge/linux-64 400kB - + libxkbcommon 1.5.0 h79f4944_1 conda-forge/linux-64 563kB - + libxml2 2.10.3 hca2bb57_4 conda-forge/linux-64 714kB - + libzlib 1.2.13 h166bdaf_4 conda-forge/linux-64 Cached - + lz4-c 1.9.4 hcb278e6_0 conda-forge/linux-64 Cached - + markupsafe 2.1.2 py310h1fa729e_0 conda-forge/linux-64 23kB - + matplotlib 3.7.1 py310hff52083_0 conda-forge/linux-64 8kB - + matplotlib-base 3.7.1 py310he60537e_0 conda-forge/linux-64 7MB - + mpg123 1.31.3 hcb278e6_0 conda-forge/linux-64 485kB - + munkres 1.0.7 py_1 bioconda/noarch 10kB - + mysql-common 8.0.32 h14678bc_0 conda-forge/linux-64 803kB - + mysql-libs 8.0.32 h54cf53e_0 conda-forge/linux-64 2MB - + nbformat 5.8.0 pyhd8ed1ab_0 conda-forge/noarch 101kB - + ncurses 6.3 h27087fc_1 conda-forge/linux-64 Cached - + nspr 4.35 h27087fc_0 conda-forge/linux-64 227kB - + nss 3.89 he45b914_0 conda-forge/linux-64 2MB - + numpy 1.24.3 py310ha4c1d20_0 conda-forge/linux-64 7MB - + openjpeg 2.5.0 h7d73246_1 conda-forge/linux-64 546kB - + openssl 1.1.1t h0b41bf4_0 conda-forge/linux-64 2MB - + packaging 23.1 pyhd8ed1ab_0 conda-forge/noarch 46kB - + pango 1.50.14 hd33c08f_0 conda-forge/linux-64 438kB - + pcre2 10.40 hc3806b6_0 conda-forge/linux-64 2MB - + perl 5.32.1 2_h7f98852_perl5 conda-forge/linux-64 15MB - + pillow 9.2.0 py310h454ad03_3 conda-forge/linux-64 47MB - + pip 23.1.2 pyhd8ed1ab_0 conda-forge/noarch 1MB - + pixman 0.40.0 h36c2ea0_0 conda-forge/linux-64 643kB - + pkgutil-resolve-name 1.3.10 pyhd8ed1ab_0 conda-forge/noarch 9kB - + plac 1.3.5 pyhd8ed1ab_0 conda-forge/noarch 23kB - + platformdirs 3.5.1 pyhd8ed1ab_0 conda-forge/noarch 19kB - + ply 3.11 py_1 conda-forge/noarch 45kB - + psutil 5.9.5 py310h1fa729e_0 conda-forge/linux-64 362kB - + pthread-stubs 0.4 h36c2ea0_1001 conda-forge/linux-64 6kB - + pulp 2.7.0 py310hff52083_0 conda-forge/linux-64 141kB - + pulseaudio 16.1 h4ab2085_1 conda-forge/linux-64 2MB - + pycparser 2.21 pyhd8ed1ab_0 conda-forge/noarch Cached - + pygments 2.15.1 pyhd8ed1ab_0 conda-forge/noarch 841kB - + pyopenssl 23.1.1 pyhd8ed1ab_0 conda-forge/noarch Cached - + pyparsing 3.0.9 pyhd8ed1ab_0 conda-forge/noarch 81kB - + pyqt 5.15.7 py310hab646b1_3 conda-forge/linux-64 5MB - + pyqt5-sip 12.11.0 py310heca2aa9_3 conda-forge/linux-64 85kB - + pyrsistent 0.19.3 py310h1fa729e_0 conda-forge/linux-64 100kB - + pysam 0.19.1 py310hff46b53_1 bioconda/linux-64 3MB - + pysocks 1.7.1 pyha2e5f31_6 conda-forge/noarch Cached - + python 3.10.8 h257c98d_0_cpython conda-forge/linux-64 23MB - + python-dateutil 2.8.2 pyhd8ed1ab_0 conda-forge/noarch 246kB - + python-fastjsonschema 2.16.3 pyhd8ed1ab_0 conda-forge/noarch 225kB - + python_abi 3.10 3_cp310 conda-forge/linux-64 Cached - + pyyaml 6.0 py310h5764c6d_5 conda-forge/linux-64 176kB - + qt-main 5.15.6 h18908ee_6 conda-forge/linux-64 55MB - + readline 8.2 h8228510_1 conda-forge/linux-64 Cached - + requests 2.29.0 pyhd8ed1ab_0 conda-forge/noarch 57kB - + reretry 0.11.8 pyhd8ed1ab_0 conda-forge/noarch 12kB - + samtools 1.15.1 h6899075_1 bioconda/linux-64 406kB - + setuptools 67.7.2 pyhd8ed1ab_0 conda-forge/noarch 583kB - + sip 6.7.9 py310hc6cd4ac_0 conda-forge/linux-64 493kB - + six 1.16.0 pyh6c4a22f_0 conda-forge/noarch 14kB - + smart_open 6.3.0 pyhd8ed1ab_1 conda-forge/noarch 47kB - + smmap 3.0.5 pyh44b312d_0 conda-forge/noarch 23kB - + snakemake-minimal 7.25.4 pyhdfd78af_0 bioconda/noarch 266kB - + stopit 1.1.2 py_0 conda-forge/noarch 16kB - + tabulate 0.9.0 pyhd8ed1ab_1 conda-forge/noarch 36kB - + throttler 1.2.1 pyhd8ed1ab_0 conda-forge/noarch 11kB - + tk 8.6.12 h27826a3_0 conda-forge/linux-64 Cached - + toml 0.10.2 pyhd8ed1ab_0 conda-forge/noarch 18kB - + tomli 2.0.1 pyhd8ed1ab_0 conda-forge/noarch 16kB - + toposort 1.10 pyhd8ed1ab_0 conda-forge/noarch 14kB - + tornado 6.3.2 py310h2372a71_0 conda-forge/linux-64 639kB - + traitlets 5.9.0 pyhd8ed1ab_0 conda-forge/noarch 98kB - + typing-extensions 4.5.0 hd8ed1ab_0 conda-forge/noarch 10kB - + typing_extensions 4.5.0 pyha770c72_0 conda-forge/noarch 31kB - + tzdata 2023c h71feb2d_0 conda-forge/noarch Cached - + unicodedata2 15.0.0 py310h5764c6d_0 conda-forge/linux-64 512kB - + urllib3 1.26.15 pyhd8ed1ab_0 conda-forge/noarch Cached - + wheel 0.40.0 pyhd8ed1ab_0 conda-forge/noarch Cached - + wrapt 1.15.0 py310h1fa729e_0 conda-forge/linux-64 54kB - + xcb-util 0.4.0 h516909a_0 conda-forge/linux-64 20kB - + xcb-util-image 0.4.0 h166bdaf_0 conda-forge/linux-64 24kB - + xcb-util-keysyms 0.4.0 h516909a_0 conda-forge/linux-64 12kB - + xcb-util-renderutil 0.3.9 h166bdaf_0 conda-forge/linux-64 16kB - + xcb-util-wm 0.4.1 h516909a_0 conda-forge/linux-64 56kB - + xkeyboard-config 2.38 h0b41bf4_0 conda-forge/linux-64 882kB - + xorg-kbproto 1.0.7 h7f98852_1002 conda-forge/linux-64 27kB - + xorg-libice 1.0.10 h7f98852_0 conda-forge/linux-64 59kB - + xorg-libsm 1.2.3 hd9c2040_1000 conda-forge/linux-64 26kB - + xorg-libx11 1.8.4 h0b41bf4_0 conda-forge/linux-64 830kB - + xorg-libxau 1.0.11 hd590300_0 conda-forge/linux-64 14kB - + xorg-libxdmcp 1.1.3 h7f98852_0 conda-forge/linux-64 19kB - + xorg-libxext 1.3.4 h0b41bf4_2 conda-forge/linux-64 50kB - + xorg-libxrender 0.9.10 h7f98852_1003 conda-forge/linux-64 33kB - + xorg-renderproto 0.11.1 h7f98852_1002 conda-forge/linux-64 10kB - + xorg-xextproto 7.3.0 h0b41bf4_1003 conda-forge/linux-64 30kB - + xorg-xproto 7.0.31 h7f98852_1007 conda-forge/linux-64 75kB - + xz 5.2.6 h166bdaf_0 conda-forge/linux-64 Cached - + yaml 0.2.5 h7f98852_2 conda-forge/linux-64 89kB - + yte 1.5.1 py310hff52083_1 conda-forge/linux-64 18kB - + zipp 3.15.0 pyhd8ed1ab_0 conda-forge/noarch 17kB - + zlib 1.2.13 h166bdaf_4 conda-forge/linux-64 94kB - + zstd 1.5.2 h3eb15da_6 conda-forge/linux-64 Cached - - Summary: - - Install: 230 packages - - Total download: 357MB - -─────────────────────────────────────────────────────────────────────────────────────────────────── - - - - -Downloading and Extracting Packages - -Preparing transaction: ...working... -done - -Verifying transaction: ...working... -done - -Executing transaction: ...working... - - -done - -# -# To activate this environment, use -# -# $ conda activate snakemake-tutorial -# -# To deactivate an active environment, use -# -# $ conda deactivate - - - ---> 1c115b179fb8 - -Step 6/16 : env PATH /root/mambaforge/envs/snakemake-tutorial/bin:$PATH - - - ---> Running in 95f9cd4a0f89 - - ---> 38bcbc3eaccf - -Step 7/16 : copy latch /root/latch - - - ---> ba86df280c15 - -Step 8/16 : run cd /root/latch && python3 -m pip install -e . - - - ---> Running in 1ec44e1a4125 - -Obtaining file:///root/latch - - Installing build dependencies: started - - Installing build dependencies: finished with status 'done' - - Checking if build backend supports build_editable: started - - Checking if build backend supports build_editable: finished with status 'done' - - Getting requirements to build editable: started - - Getting requirements to build editable: finished with status 'done' - - Preparing editable metadata (pyproject.toml): started - - Preparing editable metadata (pyproject.toml): finished with status 'done' - -Collecting asyncssh==2.12.0 (from latch==2.19.11) - - Downloading asyncssh-2.12.0-py3-none-any.whl (346 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 346.7/346.7 kB 10.5 MB/s eta 0:00:00 - - -Collecting aioconsole==0.5.1 (from latch==2.19.11) - - Downloading aioconsole-0.5.1-py3-none-any.whl (30 kB) - -Collecting kubernetes>=24.2.0 (from latch==2.19.11) - - Downloading kubernetes-26.1.0-py2.py3-none-any.whl (1.4 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.4/1.4 MB 52.6 MB/s eta 0:00:00 - - -Collecting pyjwt>=0.2.0 (from latch==2.19.11) - - Downloading PyJWT-2.7.0-py3-none-any.whl (22 kB) - -Requirement already satisfied: requests>=2.28.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from latch==2.19.11) (2.29.0) - -Collecting click>=8.0 (from latch==2.19.11) - - Downloading click-8.1.3-py3-none-any.whl (96 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 96.6/96.6 kB 13.3 MB/s eta 0:00:00 - - -Collecting docker>=5.0 (from latch==2.19.11) - - Downloading docker-6.1.2-py3-none-any.whl (148 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 148.1/148.1 kB 20.4 MB/s eta 0:00:00 - - -Collecting paramiko>=2.11.0 (from latch==2.19.11) - - Downloading paramiko-3.1.0-py3-none-any.whl (211 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 211.2/211.2 kB 22.3 MB/s eta 0:00:00 - - -Collecting scp>=0.14.0 (from latch==2.19.11) - - Downloading scp-0.14.5-py2.py3-none-any.whl (8.7 kB) - -Collecting boto3>=1.24.22 (from latch==2.19.11) - - Using cached boto3-1.26.137-py3-none-any.whl (135 kB) - -Collecting tqdm>=4.63.0 (from latch==2.19.11) - - Downloading tqdm-4.65.0-py3-none-any.whl (77 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 77.1/77.1 kB 10.7 MB/s eta 0:00:00 - - -Collecting lytekit==0.14.10 (from latch==2.19.11) - - Downloading lytekit-0.14.10-py3-none-any.whl (391 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 391.8/391.8 kB 34.1 MB/s eta 0:00:00 - - -Collecting lytekitplugins-pods==0.4.0 (from latch==2.19.11) - - Downloading lytekitplugins_pods-0.4.0-py3-none-any.whl (4.3 kB) - -Requirement already satisfied: typing-extensions==4.5.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from latch==2.19.11) (4.5.0) - -Collecting apscheduler==3.9.1 (from latch==2.19.11) - - Downloading APScheduler-3.9.1-py2.py3-none-any.whl (59 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 59.5/59.5 kB 8.6 MB/s eta 0:00:00 - - -Collecting uvloop==0.17.0 (from latch==2.19.11) - - Downloading uvloop-0.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.1 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.1/4.1 MB 70.6 MB/s eta 0:00:00 - - -Collecting websockets==10.3 (from latch==2.19.11) - - Downloading websockets-10.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (111 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 111.5/111.5 kB 12.4 MB/s eta 0:00:00 - - -Collecting prompt-toolkit==3.0.33 (from latch==2.19.11) - - Downloading prompt_toolkit-3.0.33-py3-none-any.whl (383 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 383.6/383.6 kB 39.0 MB/s eta 0:00:00 - - -Collecting watchfiles==0.18.1 (from latch==2.19.11) - - Downloading watchfiles-0.18.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.2 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.2/1.2 MB 63.9 MB/s eta 0:00:00 - - -Collecting gql==3.4.0 (from latch==2.19.11) - - Downloading gql-3.4.0-py2.py3-none-any.whl (65 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 65.2/65.2 kB 10.1 MB/s eta 0:00:00 - - -Collecting graphql-core==3.2.3 (from latch==2.19.11) - - Downloading graphql_core-3.2.3-py3-none-any.whl (202 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 202.9/202.9 kB 25.7 MB/s eta 0:00:00 - - -Collecting requests-toolbelt==0.10.1 (from latch==2.19.11) - - Downloading requests_toolbelt-0.10.1-py2.py3-none-any.whl (54 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 54.5/54.5 kB 8.1 MB/s eta 0:00:00 - - -Requirement already satisfied: snakemake>=7.25.4 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from latch==2.19.11) (7.25.4) - -Requirement already satisfied: setuptools>=0.7 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from apscheduler==3.9.1->latch==2.19.11) (67.7.2) - -Requirement already satisfied: six>=1.4.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from apscheduler==3.9.1->latch==2.19.11) (1.16.0) - -Collecting pytz (from apscheduler==3.9.1->latch==2.19.11) - - Downloading pytz-2023.3-py2.py3-none-any.whl (502 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 502.3/502.3 kB 44.6 MB/s eta 0:00:00 - - -Collecting tzlocal!=3.*,>=2.0 (from apscheduler==3.9.1->latch==2.19.11) - - Downloading tzlocal-5.0.1-py3-none-any.whl (20 kB) - -Requirement already satisfied: cryptography>=3.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from asyncssh==2.12.0->latch==2.19.11) (39.0.0) - -Collecting yarl<2.0,>=1.6 (from gql==3.4.0->latch==2.19.11) - - Downloading yarl-1.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (268 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 268.8/268.8 kB 30.1 MB/s eta 0:00:00 - - -Collecting backoff<3.0,>=1.11.1 (from gql==3.4.0->latch==2.19.11) - - Downloading backoff-2.2.1-py3-none-any.whl (15 kB) - -Collecting lyteidl==0.2.0a0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading lyteidl-0.2.0a0-py3-none-any.whl (162 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 162.2/162.2 kB 21.3 MB/s eta 0:00:00 - - -Requirement already satisfied: wheel<1.0.0,>=0.30.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (0.40.0) - -Collecting pandas<2.0.0,>=1.0.0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading pandas-1.5.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (12.1 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 12.1/12.1 MB 68.4 MB/s eta 0:00:00 - - -Collecting pyarrow<7.0.0,>=4.0.0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading pyarrow-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (25.6 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 25.6/25.6 MB 46.2 MB/s eta 0:00:00 - - -Collecting croniter<4.0.0,>=0.3.20 (from lytekit==0.14.10->latch==2.19.11) - - Downloading croniter-1.3.14-py2.py3-none-any.whl (18 kB) - -Collecting deprecated<2.0,>=1.0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading Deprecated-1.2.13-py2.py3-none-any.whl (9.6 kB) - -Collecting docker>=5.0 (from latch==2.19.11) - - Downloading docker-5.0.3-py2.py3-none-any.whl (146 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 146.2/146.2 kB 19.9 MB/s eta 0:00:00 - - -Requirement already satisfied: python-dateutil>=2.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (2.8.2) - -Collecting grpcio!=1.45.0,<2.0,>=1.43.0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading grpcio-1.54.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.1 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 5.1/5.1 MB 69.4 MB/s eta 0:00:00 - - -Collecting grpcio-status!=1.45.0,>=1.43 (from lytekit==0.14.10->latch==2.19.11) - - Downloading grpcio_status-1.54.2-py3-none-any.whl (5.1 kB) - -Collecting protobuf<4,>=3.6.1 (from lytekit==0.14.10->latch==2.19.11) - - Downloading protobuf-3.20.3-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (1.1 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.1/1.1 MB 63.6 MB/s eta 0:00:00 - - -Collecting python-json-logger>=2.0.0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading python_json_logger-2.0.7-py3-none-any.whl (8.1 kB) - -Collecting pytimeparse<2.0.0,>=1.1.8 (from lytekit==0.14.10->latch==2.19.11) - - Downloading pytimeparse-1.1.8-py2.py3-none-any.whl (10.0 kB) - -Requirement already satisfied: pyyaml in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (6.0) - -Collecting keyring>=18.0.1 (from lytekit==0.14.10->latch==2.19.11) - - Downloading keyring-23.13.1-py3-none-any.whl (37 kB) - -Collecting responses>=0.10.7 (from lytekit==0.14.10->latch==2.19.11) - - Downloading responses-0.23.1-py3-none-any.whl (52 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 52.1/52.1 kB 6.9 MB/s eta 0:00:00 - - -Collecting sortedcontainers<3.0.0,>=1.5.9 (from lytekit==0.14.10->latch==2.19.11) - - Downloading sortedcontainers-2.4.0-py2.py3-none-any.whl (29 kB) - -Collecting statsd<4.0.0,>=3.0.0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading statsd-3.3.0-py2.py3-none-any.whl (11 kB) - -Requirement already satisfied: urllib3<2.0.0,>=1.22 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (1.26.15) - -Requirement already satisfied: wrapt<2.0.0,>=1.0.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (1.15.0) - -Collecting retry==0.9.2 (from lytekit==0.14.10->latch==2.19.11) - - Downloading retry-0.9.2-py2.py3-none-any.whl (8.0 kB) - -Collecting dataclasses-json>=0.5.2 (from lytekit==0.14.10->latch==2.19.11) - - Downloading dataclasses_json-0.5.7-py3-none-any.whl (25 kB) - -Requirement already satisfied: jsonschema>=4.5.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from lytekit==0.14.10->latch==2.19.11) (4.17.3) - -Collecting marshmallow-jsonschema>=0.12.0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading marshmallow_jsonschema-0.13.0-py3-none-any.whl (11 kB) - -Collecting natsort>=7.0.1 (from lytekit==0.14.10->latch==2.19.11) - - Downloading natsort-8.3.1-py3-none-any.whl (38 kB) - -Collecting docker-image-py>=0.1.10 (from lytekit==0.14.10->latch==2.19.11) - - Downloading docker-image-py-0.1.12.tar.gz (8.2 kB) - - Preparing metadata (setup.py): started - - Preparing metadata (setup.py): finished with status 'done' - -Collecting docstring-parser>=0.9.0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading docstring_parser-0.15-py3-none-any.whl (36 kB) - -Collecting diskcache>=5.2.1 (from lytekit==0.14.10->latch==2.19.11) - - Downloading diskcache-5.6.1-py3-none-any.whl (45 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 45.6/45.6 kB 6.9 MB/s eta 0:00:00 - - -Collecting cloudpickle>=2.0.0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading cloudpickle-2.2.1-py3-none-any.whl (25 kB) - -Collecting cookiecutter>=1.7.3 (from lytekit==0.14.10->latch==2.19.11) - - Downloading cookiecutter-2.1.1-py2.py3-none-any.whl (36 kB) - -Collecting numpy<1.22.0 (from lytekit==0.14.10->latch==2.19.11) - - Downloading numpy-1.21.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (15.9 MB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 15.9/15.9 MB 59.3 MB/s eta 0:00:00 - - -Collecting wcwidth (from prompt-toolkit==3.0.33->latch==2.19.11) - - Downloading wcwidth-0.2.6-py2.py3-none-any.whl (29 kB) - -Collecting anyio>=3.0.0 (from watchfiles==0.18.1->latch==2.19.11) - - Downloading anyio-3.6.2-py3-none-any.whl (80 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 80.6/80.6 kB 12.1 MB/s eta 0:00:00 - - -Collecting googleapis-common-protos (from lyteidl==0.2.0a0->lytekit==0.14.10->latch==2.19.11) - - Downloading googleapis_common_protos-1.59.0-py2.py3-none-any.whl (223 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 223.6/223.6 kB 27.8 MB/s eta 0:00:00 - - -Collecting protoc-gen-swagger (from lyteidl==0.2.0a0->lytekit==0.14.10->latch==2.19.11) - - Downloading protoc_gen_swagger-0.1.0-py2.py3-none-any.whl (9.4 kB) - -Collecting decorator>=3.4.2 (from retry==0.9.2->lytekit==0.14.10->latch==2.19.11) - - Downloading decorator-5.1.1-py3-none-any.whl (9.1 kB) - -Collecting py<2.0.0,>=1.4.26 (from retry==0.9.2->lytekit==0.14.10->latch==2.19.11) - - Downloading py-1.11.0-py2.py3-none-any.whl (98 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 98.7/98.7 kB 15.4 MB/s eta 0:00:00 - - -Collecting botocore<1.30.0,>=1.29.137 (from boto3>=1.24.22->latch==2.19.11) - - Using cached botocore-1.29.137-py3-none-any.whl (10.8 MB) - -Collecting jmespath<2.0.0,>=0.7.1 (from boto3>=1.24.22->latch==2.19.11) - - Using cached jmespath-1.0.1-py3-none-any.whl (20 kB) - -Collecting s3transfer<0.7.0,>=0.6.0 (from boto3>=1.24.22->latch==2.19.11) - - Using cached s3transfer-0.6.1-py3-none-any.whl (79 kB) - -Collecting websocket-client>=0.32.0 (from docker>=5.0->latch==2.19.11) - - Downloading websocket_client-1.5.2-py3-none-any.whl (56 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 56.6/56.6 kB 9.2 MB/s eta 0:00:00 - - -Requirement already satisfied: certifi>=14.05.14 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from kubernetes>=24.2.0->latch==2.19.11) (2023.5.7) - -Collecting google-auth>=1.0.1 (from kubernetes>=24.2.0->latch==2.19.11) - - Downloading google_auth-2.18.1-py2.py3-none-any.whl (178 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 178.9/178.9 kB 20.4 MB/s eta 0:00:00 - - -Collecting requests-oauthlib (from kubernetes>=24.2.0->latch==2.19.11) - - Downloading requests_oauthlib-1.3.1-py2.py3-none-any.whl (23 kB) - -Collecting bcrypt>=3.2 (from paramiko>=2.11.0->latch==2.19.11) - - Downloading bcrypt-4.0.1-cp36-abi3-manylinux_2_28_x86_64.whl (593 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 593.7/593.7 kB 46.7 MB/s eta 0:00:00 - - -Collecting pynacl>=1.5 (from paramiko>=2.11.0->latch==2.19.11) - - Downloading PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl (856 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 856.7/856.7 kB 53.9 MB/s eta 0:00:00 - - -Requirement already satisfied: charset-normalizer<4,>=2 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from requests>=2.28.1->latch==2.19.11) (3.1.0) - -Requirement already satisfied: idna<4,>=2.5 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from requests>=2.28.1->latch==2.19.11) (3.4) - -Requirement already satisfied: appdirs in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.4.4) - -Requirement already satisfied: configargparse in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.5.3) - -Requirement already satisfied: connection-pool>=0.0.3 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (0.0.3) - -Requirement already satisfied: datrie in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (0.8.2) - -Requirement already satisfied: docutils in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (0.20.1) - -Requirement already satisfied: gitpython in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (3.1.31) - -Requirement already satisfied: humanfriendly in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (10.0) - -Requirement already satisfied: jinja2<4.0,>=3.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (3.1.2) - -Requirement already satisfied: nbformat in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (5.8.0) - -Requirement already satisfied: psutil in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (5.9.5) - -Requirement already satisfied: pulp>=2.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (2.7.0) - -Requirement already satisfied: reretry in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (0.11.8) - -Requirement already satisfied: smart-open>=3.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (6.3.0) - -Requirement already satisfied: stopit in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.1.2) - -Requirement already satisfied: tabulate in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (0.9.0) - -Requirement already satisfied: throttler in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.2.1) - -Requirement already satisfied: toposort>=1.10 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.10) - -Requirement already satisfied: yte<2.0,>=1.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from snakemake>=7.25.4->latch==2.19.11) (1.5.1) - -Collecting sniffio>=1.1 (from anyio>=3.0.0->watchfiles==0.18.1->latch==2.19.11) - - Downloading sniffio-1.3.0-py3-none-any.whl (10 kB) - -Collecting binaryornot>=0.4.4 (from cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) - - Downloading binaryornot-0.4.4-py2.py3-none-any.whl (9.0 kB) - -Collecting jinja2-time>=0.2.0 (from cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) - - Downloading jinja2_time-0.2.0-py2.py3-none-any.whl (6.4 kB) - -Collecting python-slugify>=4.0.0 (from cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) - - Downloading python_slugify-8.0.1-py2.py3-none-any.whl (9.7 kB) - -Requirement already satisfied: cffi>=1.12 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from cryptography>=3.1->asyncssh==2.12.0->latch==2.19.11) (1.15.1) - -Collecting marshmallow<4.0.0,>=3.3.0 (from dataclasses-json>=0.5.2->lytekit==0.14.10->latch==2.19.11) - - Downloading marshmallow-3.19.0-py3-none-any.whl (49 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 49.1/49.1 kB 7.3 MB/s eta 0:00:00 - - -Collecting marshmallow-enum<2.0.0,>=1.5.1 (from dataclasses-json>=0.5.2->lytekit==0.14.10->latch==2.19.11) - - Downloading marshmallow_enum-1.5.1-py2.py3-none-any.whl (4.2 kB) - -Collecting typing-inspect>=0.4.0 (from dataclasses-json>=0.5.2->lytekit==0.14.10->latch==2.19.11) - - Downloading typing_inspect-0.8.0-py3-none-any.whl (8.7 kB) - -Collecting regex>=2019.4.14 (from docker-image-py>=0.1.10->lytekit==0.14.10->latch==2.19.11) - - Downloading regex-2023.5.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (769 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 769.7/769.7 kB 59.9 MB/s eta 0:00:00 - - -Collecting cachetools<6.0,>=2.0.0 (from google-auth>=1.0.1->kubernetes>=24.2.0->latch==2.19.11) - - Downloading cachetools-5.3.0-py3-none-any.whl (9.3 kB) - -Collecting pyasn1-modules>=0.2.1 (from google-auth>=1.0.1->kubernetes>=24.2.0->latch==2.19.11) - - Downloading pyasn1_modules-0.3.0-py2.py3-none-any.whl (181 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 181.3/181.3 kB 20.5 MB/s eta 0:00:00 - - -Collecting rsa<5,>=3.1.4 (from google-auth>=1.0.1->kubernetes>=24.2.0->latch==2.19.11) - - Downloading rsa-4.9-py3-none-any.whl (34 kB) - -INFO: pip is looking at multiple versions of grpcio-status to determine which version is compatible with other requirements. This could take a while. - -Collecting grpcio-status!=1.45.0,>=1.43 (from lytekit==0.14.10->latch==2.19.11) - - Downloading grpcio_status-1.54.0-py3-none-any.whl (5.1 kB) - - Downloading grpcio_status-1.53.1-py3-none-any.whl (5.1 kB) - - Downloading grpcio_status-1.53.0-py3-none-any.whl (5.1 kB) - - Downloading grpcio_status-1.51.3-py3-none-any.whl (5.1 kB) - - Downloading grpcio_status-1.51.1-py3-none-any.whl (5.1 kB) - - Downloading grpcio_status-1.50.0-py3-none-any.whl (14 kB) - - Downloading grpcio_status-1.49.1-py3-none-any.whl (14 kB) - -INFO: pip is looking at multiple versions of grpcio-status to determine which version is compatible with other requirements. This could take a while. - - Downloading grpcio_status-1.48.2-py3-none-any.whl (14 kB) - -Requirement already satisfied: MarkupSafe>=2.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from jinja2<4.0,>=3.0->snakemake>=7.25.4->latch==2.19.11) (2.1.2) - -Requirement already satisfied: attrs>=17.4.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from jsonschema>=4.5.1->lytekit==0.14.10->latch==2.19.11) (23.1.0) - -Requirement already satisfied: pyrsistent!=0.17.0,!=0.17.1,!=0.17.2,>=0.14.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from jsonschema>=4.5.1->lytekit==0.14.10->latch==2.19.11) (0.19.3) - -Collecting jaraco.classes (from keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) - - Downloading jaraco.classes-3.2.3-py3-none-any.whl (6.0 kB) - -Requirement already satisfied: importlib-metadata>=4.11.4 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) (6.6.0) - -Collecting SecretStorage>=3.2 (from keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) - - Downloading SecretStorage-3.3.3-py3-none-any.whl (15 kB) - -Collecting jeepney>=0.4.2 (from keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) - - Downloading jeepney-0.8.0-py3-none-any.whl (48 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 48.4/48.4 kB 7.3 MB/s eta 0:00:00 - - -Collecting types-PyYAML (from responses>=0.10.7->lytekit==0.14.10->latch==2.19.11) - - Downloading types_PyYAML-6.0.12.9-py3-none-any.whl (14 kB) - -Collecting multidict>=4.0 (from yarl<2.0,>=1.6->gql==3.4.0->latch==2.19.11) - - Downloading multidict-6.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (114 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 114.5/114.5 kB 14.5 MB/s eta 0:00:00 - - -Requirement already satisfied: dpath<3.0,>=2.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from yte<2.0,>=1.0->snakemake>=7.25.4->latch==2.19.11) (2.1.6) - -Requirement already satisfied: plac<2.0.0,>=1.3.4 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from yte<2.0,>=1.0->snakemake>=7.25.4->latch==2.19.11) (1.3.5) - -Requirement already satisfied: gitdb<5,>=4.0.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from gitpython->snakemake>=7.25.4->latch==2.19.11) (4.0.10) - -Requirement already satisfied: fastjsonschema in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from nbformat->snakemake>=7.25.4->latch==2.19.11) (2.16.3) - -Requirement already satisfied: jupyter-core in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from nbformat->snakemake>=7.25.4->latch==2.19.11) (5.3.0) - -Requirement already satisfied: traitlets>=5.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from nbformat->snakemake>=7.25.4->latch==2.19.11) (5.9.0) - -Collecting oauthlib>=3.0.0 (from requests-oauthlib->kubernetes>=24.2.0->latch==2.19.11) - - Downloading oauthlib-3.2.2-py3-none-any.whl (151 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 151.7/151.7 kB 17.6 MB/s eta 0:00:00 - - -Collecting chardet>=3.0.2 (from binaryornot>=0.4.4->cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) - - Downloading chardet-5.1.0-py3-none-any.whl (199 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 199.1/199.1 kB 24.8 MB/s eta 0:00:00 - - -Requirement already satisfied: pycparser in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from cffi>=1.12->cryptography>=3.1->asyncssh==2.12.0->latch==2.19.11) (2.21) - -Requirement already satisfied: smmap<6,>=3.0.1 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from gitdb<5,>=4.0.1->gitpython->snakemake>=7.25.4->latch==2.19.11) (3.0.5) - -Requirement already satisfied: zipp>=0.5 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from importlib-metadata>=4.11.4->keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) (3.15.0) - -Collecting arrow (from jinja2-time>=0.2.0->cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) - - Downloading arrow-1.2.3-py3-none-any.whl (66 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 66.4/66.4 kB 8.5 MB/s eta 0:00:00 - - -Requirement already satisfied: packaging>=17.0 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from marshmallow<4.0.0,>=3.3.0->dataclasses-json>=0.5.2->lytekit==0.14.10->latch==2.19.11) (23.1) - -Collecting pyasn1<0.6.0,>=0.4.6 (from pyasn1-modules>=0.2.1->google-auth>=1.0.1->kubernetes>=24.2.0->latch==2.19.11) - - Using cached pyasn1-0.5.0-py2.py3-none-any.whl (83 kB) - -Collecting text-unidecode>=1.3 (from python-slugify>=4.0.0->cookiecutter>=1.7.3->lytekit==0.14.10->latch==2.19.11) - - Downloading text_unidecode-1.3-py2.py3-none-any.whl (78 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 78.2/78.2 kB 11.3 MB/s eta 0:00:00 - - -Collecting mypy-extensions>=0.3.0 (from typing-inspect>=0.4.0->dataclasses-json>=0.5.2->lytekit==0.14.10->latch==2.19.11) - - Downloading mypy_extensions-1.0.0-py3-none-any.whl (4.7 kB) - -Collecting more-itertools (from jaraco.classes->keyring>=18.0.1->lytekit==0.14.10->latch==2.19.11) - - Downloading more_itertools-9.1.0-py3-none-any.whl (54 kB) - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 54.2/54.2 kB 7.8 MB/s eta 0:00:00 - - -Requirement already satisfied: platformdirs>=2.5 in /root/mambaforge/envs/snakemake-tutorial/lib/python3.10/site-packages (from jupyter-core->nbformat->snakemake>=7.25.4->latch==2.19.11) (3.5.1) - -WARNING: The candidate selected for download or install is a yanked version: 'apscheduler' candidate (version 3.9.1 at https://files.pythonhosted.org/packages/e4/9f/c3937d4babe62504b874d4bf2c0d85aa69c7f59fa84cf6050f3b9dc5d83e/APScheduler-3.9.1-py2.py3-none-any.whl (from https://pypi.org/simple/apscheduler/) (requires-python:>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4)) -Reason for being yanked: Not compatible with Python 2.7 - -Building wheels for collected packages: latch, docker-image-py - - Building editable for latch (pyproject.toml): started - - Building editable for latch (pyproject.toml): finished with status 'done' - - Created wheel for latch: filename=latch-2.19.11-0.editable-py3-none-any.whl size=3728 sha256=99f87f896350c5424c539c4f3a3aae13c22ac4c8712d098aad89f087721ddffd - - Stored in directory: /tmp/pip-ephem-wheel-cache-26oiq4k4/wheels/66/25/3a/f25ede02a4206d090762dd0ca4dbdc81da4d61e154ed692990 - - Building wheel for docker-image-py (setup.py): started - - Building wheel for docker-image-py (setup.py): finished with status 'done' - - Created wheel for docker-image-py: filename=docker_image_py-0.1.12-py3-none-any.whl size=8812 sha256=433616dac59187300c1a2a34fb46d818e7098983f2031e72ee00be9a7c146420 - - Stored in directory: /root/.cache/pip/wheels/fb/45/02/503244da15fbcecde5c3edabb744ed0c4f9a7643126b2d222c - -Successfully built latch docker-image-py - -Installing collected packages: wcwidth, types-PyYAML, text-unidecode, statsd, sortedcontainers, pytz, pytimeparse, websockets, websocket-client, uvloop, tzlocal, tqdm, sniffio, regex, python-slugify, python-json-logger, pyjwt, pyasn1, py, protobuf, prompt-toolkit, oauthlib, numpy, natsort, mypy-extensions, multidict, more-itertools, marshmallow, jmespath, jeepney, grpcio, graphql-core, docstring-parser, diskcache, deprecated, decorator, cloudpickle, click, chardet, cachetools, bcrypt, backoff, aioconsole, yarl, typing-inspect, rsa, retry, responses, requests-toolbelt, requests-oauthlib, pynacl, pyasn1-modules, pyarrow, protoc-gen-swagger, pandas, marshmallow-jsonschema, marshmallow-enum, jaraco.classes, googleapis-common-protos, docker-image-py, docker, croniter, botocore, binaryornot, arrow, apscheduler, anyio, watchfiles, SecretStorage, s3transfer, paramiko, lyteidl, jinja2-time, grpcio-status, gql, google-auth, dataclasses-json, asyncssh, scp, kubernetes, keyring, cookiecutter, boto3, lytekit, lytekitplugins-pods, latch - - Attempting uninstall: numpy - - Found existing installation: numpy 1.24.3 - - Uninstalling numpy-1.24.3: - - Successfully uninstalled numpy-1.24.3 - -Successfully installed SecretStorage-3.3.3 aioconsole-0.5.1 anyio-3.6.2 apscheduler-3.9.1 arrow-1.2.3 asyncssh-2.12.0 backoff-2.2.1 bcrypt-4.0.1 binaryornot-0.4.4 boto3-1.26.137 botocore-1.29.137 cachetools-5.3.0 chardet-5.1.0 click-8.1.3 cloudpickle-2.2.1 cookiecutter-2.1.1 croniter-1.3.14 dataclasses-json-0.5.7 decorator-5.1.1 deprecated-1.2.13 diskcache-5.6.1 docker-5.0.3 docker-image-py-0.1.12 docstring-parser-0.15 google-auth-2.18.1 googleapis-common-protos-1.59.0 gql-3.4.0 graphql-core-3.2.3 grpcio-1.54.2 grpcio-status-1.48.2 jaraco.classes-3.2.3 jeepney-0.8.0 jinja2-time-0.2.0 jmespath-1.0.1 keyring-23.13.1 kubernetes-26.1.0 latch-2.19.11 lyteidl-0.2.0a0 lytekit-0.14.10 lytekitplugins-pods-0.4.0 marshmallow-3.19.0 marshmallow-enum-1.5.1 marshmallow-jsonschema-0.13.0 more-itertools-9.1.0 multidict-6.0.4 mypy-extensions-1.0.0 natsort-8.3.1 numpy-1.21.6 oauthlib-3.2.2 pandas-1.5.3 paramiko-3.1.0 prompt-toolkit-3.0.33 protobuf-3.20.3 protoc-gen-swagger-0.1.0 py-1.11.0 pyarrow-6.0.1 pyasn1-0.5.0 pyasn1-modules-0.3.0 pyjwt-2.7.0 pynacl-1.5.0 python-json-logger-2.0.7 python-slugify-8.0.1 pytimeparse-1.1.8 pytz-2023.3 regex-2023.5.5 requests-oauthlib-1.3.1 requests-toolbelt-0.10.1 responses-0.23.1 retry-0.9.2 rsa-4.9 s3transfer-0.6.1 scp-0.14.5 sniffio-1.3.0 sortedcontainers-2.4.0 statsd-3.3.0 text-unidecode-1.3 tqdm-4.65.0 types-PyYAML-6.0.12.9 typing-inspect-0.8.0 tzlocal-5.0.1 uvloop-0.17.0 watchfiles-0.18.1 wcwidth-0.2.6 websocket-client-1.5.2 websockets-10.3 yarl-1.9.2 - -WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv - - ---> e6903b7577c6 - -Step 9/16 : copy Snakefile config.yaml /root/ - - - ---> 93c3fe88c890 - -Step 10/16 : copy scripts/plot-quals.py /root/scripts/plot-quals.py - - - ---> b476a36f6f9c - -Step 11/16 : copy .latch/latch_entrypoint.py /root/latch_entrypoint.py - - - ---> 75cead0538d5 - -Step 12/16 : arg tag - - - ---> Running in 7008c22c3f2f - - ---> 9d8c1d4b5439 - -Step 13/16 : env FLYTE_INTERNAL_IMAGE $tag - - - ---> Running in a2dae98974d2 - - ---> 937b6876b211 - -Step 14/16 : env LATCH_SDK_DOMAIN "ligma.ai" - - - ---> Running in 55f4bfc3f1d1 - - ---> 166b7adade89 - -Step 15/16 : env LATCH_AUTHENTICATION_ENDPOINT https://nucleus.ligma.ai - - - ---> Running in 813f919f4581 - - ---> a58bd3d35779 - -Step 16/16 : workdir /root - - - ---> Running in 7a31c27da0c0 - - ---> 6157f3b85044 - -Successfully built 6157f3b85044 - -Successfully tagged 812206152185.dkr.ecr.us-west-2.amazonaws.com/x1_test_latch_register:0.0.0-cddce8 - diff --git a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-dc4ace/docker-build-logs.txt b/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-dc4ace/docker-build-logs.txt deleted file mode 100644 index 3e113e62..00000000 --- a/latch_cli/services/init/new_example_snakemake/.logs/x1_test_latch_register:0.0.0-dc4ace/docker-build-logs.txt +++ /dev/null @@ -1,61 +0,0 @@ -Step 1/15 : from 812206152185.dkr.ecr.us-west-2.amazonaws.com/latch-base:9c8f-main - - - ---> b253e8cdab51 - -Step 2/15 : run mkdir /opt/latch - - - ---> Using cache - - ---> 89e0ab657f0d - -Step 3/15 : RUN curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh && mkdir /root/.conda && bash Mambaforge-Linux-x86_64.sh -b && rm -f Mambaforge-Linux-x86_64.sh - - - ---> Using cache - - ---> 7741d9d31977 - -Step 4/15 : copy environment.yaml /root/environment.yaml - - - ---> Using cache - - ---> c2d3f498d2d5 - -Step 5/15 : run /root/mambaforge/bin/mamba env create --name snakemake-tutorial --file environment.yaml - - - ---> Using cache - - ---> 0370179f98b9 - -Step 6/15 : env PATH /root/mambaforge/envs/snakemake-tutorial/bin:$PATH - - - ---> Using cache - - ---> 558ea5988368 - -Step 7/15 : run python3 -m pip install latch - - - ---> Using cache - - ---> 73f3b443e340 - -Step 8/15 : copy Snakefile config.yaml /root/ - - - ---> da1c8fa40657 - -Step 9/15 : copy scripts/plot-quals.py /root/scripts/plot-quals.py - - - ---> 6e0a5622727c - -Step 10/15 : copy .latch/latch_entrypoint.py /root/latch_entrypoint.py - - -COPY failed: file not found in build context or excluded by .dockerignore: stat .latch/latch_entrypoint.py: file does not exist From 65ff66a795269174e391fe9c754463cc670580bc Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Mon, 18 Sep 2023 20:03:36 -0700 Subject: [PATCH 247/356] fixes --- latch_cli/services/init/init.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/latch_cli/services/init/init.py b/latch_cli/services/init/init.py index 6686243f..b0ec4a37 100644 --- a/latch_cli/services/init/init.py +++ b/latch_cli/services/init/init.py @@ -13,15 +13,16 @@ from latch_cli.workflow_config import BaseImageOptions, create_and_write_config -def _get_boilerplate(pkg_root: Path, source_path: Path): +def _get_boilerplate(pkg_root: Path, source_path: Path, copy_wf_dir: bool = True): pkg_root = pkg_root.resolve() source_path = source_path.resolve() wf_root = pkg_root / "wf" wf_root.mkdir(exist_ok=True) - for f in source_path.glob("*.py"): - shutil.copy(f, wf_root) + if copy_wf_dir is True: + for f in source_path.glob("*.py"): + shutil.copy(f, wf_root) pkg_root_globs = [ "LICENSE*", @@ -177,7 +178,19 @@ def _gen_example_snakemake(pkg_root: Path): pkg_root = pkg_root.resolve() source_path = Path(__file__).parent / "example_snakemake" - _get_boilerplate(pkg_root, source_path) + _get_boilerplate(pkg_root, source_path, copy_wf_dir=False) + + snakefile_dest = pkg_root / "Snakefile" + snakefile_src = source_path / "Snakefile" + shutil.copy(snakefile_src, snakefile_dest) + + data_dest = pkg_root / "data" + data_src = source_path / "data" + shutil.copytree(data_src, data_dest) + + scripts_dest = pkg_root / "scripts" + scripts_src = source_path / "scripts" + shutil.copytree(scripts_src, scripts_dest) def _gen_example_nfcore(pkg_root: Path): From 7342b49a4d542b322425dc3e1f2d28fc317fe402 Mon Sep 17 00:00:00 2001 From: AidanAbd Date: Mon, 18 Sep 2023 21:21:39 -0700 Subject: [PATCH 248/356] fix: PR comments --- doc-requirements.txt | 4 ++-- docs/source/basics/defining_cloud_resources.md | 8 ++++---- docs/source/getting_started/authoring_your_workflow.md | 4 ++-- docs/source/index.md | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/doc-requirements.txt b/doc-requirements.txt index 081c5844..bd3ca716 100644 --- a/doc-requirements.txt +++ b/doc-requirements.txt @@ -1,6 +1,6 @@ # -# This file is autogenerated by pip-compile with python 3.10 -# To update, run: +# This file is autogenerated by pip-compile with Python 3.10 +# by the following command: # # pip-compile doc-requirements.in # diff --git a/docs/source/basics/defining_cloud_resources.md b/docs/source/basics/defining_cloud_resources.md index 8de53bc8..9616e03c 100644 --- a/docs/source/basics/defining_cloud_resources.md +++ b/docs/source/basics/defining_cloud_resources.md @@ -9,15 +9,15 @@ RAM, Storage, GPU) at runtime and these requests will be fullfilled during the s process. ## CPU -The number of cpu cores available to the task. If your task uses more than the alotted +The number of cpu cores available to the task. If the task uses more than the alotted number of cores, the task can continue running but will be throttled. ## Memory -The amount of memory available to the task. If your task uses more than the alotted +The amount of memory available to the task. If the task uses more than the alotted amount of memory, the task will crash. ## Storage -The amount of disc space available to the task. If your task uses more than the alotted +The amount of disc space available to the task. If the task uses more than the alotted amount of storage, the task will crash. ## GPU @@ -60,7 +60,7 @@ You can also specify task resources using `@custom_task`: ```python from latch import custom_task -@custom_task(cpu, memory, storage_gib = storage_gib) # cpu: int, memory: int, storage_gib: int +@custom_task(cpu=8, memory=64, storage_gib=1000) def my_task( ... ): diff --git a/docs/source/getting_started/authoring_your_workflow.md b/docs/source/getting_started/authoring_your_workflow.md index e6f81a99..8bc648cd 100644 --- a/docs/source/getting_started/authoring_your_workflow.md +++ b/docs/source/getting_started/authoring_your_workflow.md @@ -113,7 +113,7 @@ def my_task( ): ... -@large_gpu_task #31 cpus, 120 gigs of memory, 2000 GiB of storage, 1 gpu +@large_gpu_task # 31 cpus, 120 gigs of memory, 2000 GiB of storage, 1 gpu def inference( ... ): @@ -126,7 +126,7 @@ To arbitrarily specify resource requirements, use: ```python from latch import custom_task -@custom_task(cpu, memory, storage_gib = storage_gib) +@custom_task(cpu=8, memory=64, storage_gib=1000) def my_task( ... ): diff --git a/docs/source/index.md b/docs/source/index.md index 75252651..cd8d6204 100644 --- a/docs/source/index.md +++ b/docs/source/index.md @@ -24,7 +24,7 @@ Lacth SDK allows developers to upload workflows to the full-featured [Latch Plat With Latch SDK, developers can write the description to their workflow and customize input parameters using plain Markdown. Latch automatically parses the written text and Python function headers to compile a type-safe UI. -**Specifying arbitrary cloud compute and storage resources for bioinformatics pipelines is difficult.** With the Latch SDK, there are several Python task decorators that easily allow you to define the resources available at runtime. The framework starts at 2 CPUs and 4 GiBs of memory and goes all the way to 95 CPUs, 490 GBs of memory, 4949 GiB of storage, and 1 GPU (24 GBs of VRAM, 9,216 CUDA cores) to easily handle all processing needs. +**Specifying arbitrary cloud compute and storage resources for bioinformatics pipelines is difficult.** With the Latch SDK, there are several Python task decorators that easily allow you to define the resources available at runtime. The framework starts at 2 CPUs and 4 GiBs of memory and goes all the way to 95 CPUs, 490 GiBs of memory, 4949 GiB of storage, and 1 GPU (24 GiBs of VRAM, 9,216 CUDA cores) to easily handle all processing needs. **Bioinformatics tools face the challenges of irreproducibility.** The lack of proper versioning and dependencies management results in a long tail of poorly documented and unusable bioinformatics software tools. From b1edb12b6d28d80c99b0f3301301c6a8d363239b Mon Sep 17 00:00:00 2001 From: AidanAbd Date: Mon, 18 Sep 2023 21:24:48 -0700 Subject: [PATCH 249/356] fix: PR comments --- docs/source/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/source/index.md b/docs/source/index.md index 01632c28..c2c55570 100644 --- a/docs/source/index.md +++ b/docs/source/index.md @@ -5,6 +5,7 @@ It takes months to build infrastructure with the compute, storage, and user-frie The Latch SDK is an open-source toolchain to define serverless bioinformatics workflows with plain python and deploy associated no-code interfaces using single command. Bioinformatics workflows developed with the SDK automatically receive: + - Instant no-code interfaces for accessibility and publication - First class static typing - Containerization and versioning of every registered change From a88de860e1432443426f1717afc4ebda0cff25e9 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Thu, 21 Sep 2023 14:31:01 -0700 Subject: [PATCH 250/356] version + changelog --- CHANGELOG.md | 9 +++++++++ setup.py | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa118d63..959eab87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,15 @@ Types of changes ### Fixed +* Snakemake: + * `--snakemake` for `latch dockerfile` command to generate `Dockerfile` with + necessary instructions + * Snakemake example for `latch init` + +## 2.32.6 - 2023-09-07 + +### Fixed + * A bug in `latch develop` where images for newly registered workflows could not be found. ## 2.32.5 - 2023-08-28 diff --git a/setup.py b/setup.py index cf91c836..4a9acc75 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ setup( name="latch", - version="v2.32.6", + version="v2.32.7", author_email="kenny@latch.bio", description="The Latch SDK", packages=find_packages(), From a76b8f3a3cd822bd8184129efba105142f8a538a Mon Sep 17 00:00:00 2001 From: Hannah Le Date: Thu, 21 Sep 2023 15:03:57 -0700 Subject: [PATCH 251/356] Update docs/source/manual/tutorial.md Co-authored-by: Kenny Workman <31255434+kennyworkman@users.noreply.github.com> --- docs/source/manual/tutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/manual/tutorial.md b/docs/source/manual/tutorial.md index fe22e11d..4ea6aed0 100644 --- a/docs/source/manual/tutorial.md +++ b/docs/source/manual/tutorial.md @@ -63,7 +63,7 @@ The `latch_metadata.py` is used to specify the input parameters that the Snakema For example, by parsing the Snakefile, we determine there are two parameters that the workflow needs: a reference genome and a list of samples to be aligned against the reference genome. -For each parameter, the `path` key specifies the location of the input data; hence, values defined here must match the paths of the inputs for each rule in the Snakefile. +For each `LatchFile`/`LatchDir` parameter, the `path` keyword specifies the path where files will be copied before the Snakemake workflow is run and should match the paths of the inputs for each rule in the Snakefile. ## Step 3: Add dependencies From 0cfafc2365b91ac089fc65ea0c49b3659d0f3361 Mon Sep 17 00:00:00 2001 From: Hannah Le Date: Thu, 21 Sep 2023 15:04:02 -0700 Subject: [PATCH 252/356] Update docs/source/manual/tutorial.md Co-authored-by: Kenny Workman <31255434+kennyworkman@users.noreply.github.com> --- docs/source/manual/tutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/manual/tutorial.md b/docs/source/manual/tutorial.md index 4ea6aed0..910ac19f 100644 --- a/docs/source/manual/tutorial.md +++ b/docs/source/manual/tutorial.md @@ -99,7 +99,7 @@ During registration, a workflow image is built based on dependencies specified i ![Snakemake workflow interface on Latch](../assets/snakemake/tutorial.png) ## Step 4: Run the workflow -Snakemake support is currently based on JIT (Just-In-Time) registration. This means that the workflow produced by `latch register` will only register a second workflow, which will run the actual pipeline tasks. +Snakemake support is currently uses JIT (Just-In-Time) registration. This means that the workflow produced by `latch register` will register a second workflow, which will run the actual Snakemake jobs. Once the workflow finishes running, results will be deposited to [Latch Data](https://console.latch.bio/data) under the `Snakemake Outputs` folder. From 52901c863a5bc63752168299e0606aed43a1ce6b Mon Sep 17 00:00:00 2001 From: Hannah Le Date: Thu, 21 Sep 2023 15:31:46 -0700 Subject: [PATCH 253/356] changed based on kennys new sm template --- docs/source/manual/tutorial.md | 67 ++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 16 deletions(-) diff --git a/docs/source/manual/tutorial.md b/docs/source/manual/tutorial.md index 910ac19f..91135dbe 100644 --- a/docs/source/manual/tutorial.md +++ b/docs/source/manual/tutorial.md @@ -6,29 +6,61 @@ The example being used here comes from the [short tutorial in Snakemake's docume ## Prerequisites -* Install the [Latch SDK](https://github.com/latchbio/latch#installation) -* Install [snakemake](https://snakemake.readthedocs.io/en/stable/getting_started/installation.html) +* Install the [Latch SDK](https://github.com/latchbio/latch#installation) and [snakemake](https://snakemake.readthedocs.io/en/stable/getting_started/installation.html) with: + +```console +pip install latch[snakemake] +``` + * Install [Docker](https://www.docker.com/get-started/) and have Docker run locally ## Step 1 -First, clone the Snakemake example repository: + +First, initialize an example Snakemake workflow: ```console -git clone https://github.com/latchbio/snakemake-short-tutorial.git &&\ -cd snakemake-short-tutorial +latch init snakemake-wf --template snakemake ``` -The directory tree consists of a simple Python script and a Snakefile: -``` -snakemake-short-tutorial +The workflow generated contains what is typically seen in a Snakemake workflow, such as python scripts and a Snakefile. + +```console +snakemake-wf +├── Dockerfile # Latch specific +├── Snakefile +├── data +│   ├── genome.fa +│   ├── genome.fa.amb +│   ├── genome.fa.ann +│   ├── genome.fa.bwt +│   ├── genome.fa.fai +│   ├── genome.fa.pac +│   ├── genome.fa.sa +│   └── samples +│   ├── A.fastq +│   ├── B.fastq +│   └── C.fastq +├── environment.yaml ├── scripts -│ └── plot-quals.py -└── workflow - └── Snakefile +│   ├── __pycache__ +│   │   └── plot-quals.cpython-39.pyc +│   └── plot-quals.py +├── version +└── wf ``` +To make the workflow compatible to execute on Latch, two additional files are needed: + +* `Dockerfile` to specify dependencies the workflow needs to run +* `latch_metadata.py` to specify workflow parameters to expose on the user interface. + +In this tutorial, we will walk through how these two files can be constructed. + ## Step 2: Add a metadata file -Next, add a `latch_metadata.py` file in the `snakemake-short-tutorial` directory like so: + +The `latch_metadata.py` is used to specify the input parameters that the Snakemake workflow needs to run. + +For example, by examining the Snakefile, we determine there are two parameters that the workflow needs: a reference genome and a list of samples to be aligned against the reference genome. ```python # latch_metadata.py @@ -59,10 +91,6 @@ SnakemakeMetadata( ) ``` -The `latch_metadata.py` is used to specify the input parameters that the Snakemake workflow needs to run. - -For example, by parsing the Snakefile, we determine there are two parameters that the workflow needs: a reference genome and a list of samples to be aligned against the reference genome. - For each `LatchFile`/`LatchDir` parameter, the `path` keyword specifies the path where files will be copied before the Snakemake workflow is run and should match the paths of the inputs for each rule in the Snakefile. ## Step 3: Add dependencies @@ -86,11 +114,17 @@ dependencies: - pygments ``` +A Dockerfile can be automatically generated by typing: +```console +latch dockerfile snakemake-wf +``` + ## Step 3: Upload the workflow to Latch Finally, type the following command to register the workflow to Latch: ```console +cd snakemake-wf &&\ latch register . --snakefile workflow/Snakefile ``` @@ -99,6 +133,7 @@ During registration, a workflow image is built based on dependencies specified i ![Snakemake workflow interface on Latch](../assets/snakemake/tutorial.png) ## Step 4: Run the workflow + Snakemake support is currently uses JIT (Just-In-Time) registration. This means that the workflow produced by `latch register` will register a second workflow, which will run the actual Snakemake jobs. Once the workflow finishes running, results will be deposited to [Latch Data](https://console.latch.bio/data) under the `Snakemake Outputs` folder. From 75ab69fc231534b24182ff68f6bf4d7f97b5f314 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Thu, 21 Sep 2023 15:44:51 -0700 Subject: [PATCH 254/356] fix init --- .../services/init/example_snakemake/Snakefile | 21 -------------- .../init/example_snakemake/latch_metadata.py | 29 +++++++++++++++++++ latch_cli/services/init/init.py | 4 +++ 3 files changed, 33 insertions(+), 21 deletions(-) create mode 100644 latch_cli/services/init/example_snakemake/latch_metadata.py diff --git a/latch_cli/services/init/example_snakemake/Snakefile b/latch_cli/services/init/example_snakemake/Snakefile index 03a9e038..8404f5b0 100644 --- a/latch_cli/services/init/example_snakemake/Snakefile +++ b/latch_cli/services/init/example_snakemake/Snakefile @@ -2,27 +2,6 @@ from latch.types.metadata import SnakemakeMetadata, SnakemakeFileParameter from latch.types.directory import LatchDir from latch.types.metadata import LatchAuthor, LatchMetadata, LatchParameter -SnakemakeMetadata( - output_dir = LatchDir("latch:///sample_output"), - display_name="snakemake_tutorial_workflow", - author=LatchAuthor( - name="Kenneth", - ), - parameters={ - "samples" : SnakemakeFileParameter( - display_name="Sample Input Directory", - description="A directory full of FastQ files", - type=LatchDir, - path=Path("data/samples"), - ), - "ref_genome" : SnakemakeFileParameter( - display_name="Indexed Reference Genome", - description="A directory with a reference Fasta file and the 6 index files produced from `bwa index`", - type=LatchDir, - path=Path("genome"), - ), - }, -) SAMPLES = ["A", "B"] diff --git a/latch_cli/services/init/example_snakemake/latch_metadata.py b/latch_cli/services/init/example_snakemake/latch_metadata.py new file mode 100644 index 00000000..386d71d9 --- /dev/null +++ b/latch_cli/services/init/example_snakemake/latch_metadata.py @@ -0,0 +1,29 @@ +from pathlib import Path + +from latch.types import LatchDir +from latch.types.metadata import LatchAuthor, SnakemakeFileParameter, SnakemakeMetadata + +SnakemakeMetadata( + output_dir=LatchDir("latch:///sample_output"), + display_name="snakemake_tutorial_workflow", + author=LatchAuthor( + name="Kenneth", + ), + parameters={ + "samples": SnakemakeFileParameter( + display_name="Sample Input Directory", + description="A directory full of FastQ files", + type=LatchDir, + path=Path("data/samples"), + ), + "ref_genome": SnakemakeFileParameter( + display_name="Indexed Reference Genome", + description=( + "A directory with a reference Fasta file and the 6 index files produced" + " from `bwa index`" + ), + type=LatchDir, + path=Path("genome"), + ), + }, +) diff --git a/latch_cli/services/init/init.py b/latch_cli/services/init/init.py index b0ec4a37..f34b9fc2 100644 --- a/latch_cli/services/init/init.py +++ b/latch_cli/services/init/init.py @@ -184,6 +184,10 @@ def _gen_example_snakemake(pkg_root: Path): snakefile_src = source_path / "Snakefile" shutil.copy(snakefile_src, snakefile_dest) + snakefile_dest = pkg_root / "latch_metadata.py" + snakefile_src = source_path / "latch_metadata.py" + shutil.copy(snakefile_src, snakefile_dest) + data_dest = pkg_root / "data" data_src = source_path / "data" shutil.copytree(data_src, data_dest) From d2755b6427e87acea411c0fb1d95ed55253f87e5 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Thu, 21 Sep 2023 15:52:25 -0700 Subject: [PATCH 255/356] better error messages --- latch_cli/centromere/ctx.py | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/latch_cli/centromere/ctx.py b/latch_cli/centromere/ctx.py index c6abb712..97657f2b 100644 --- a/latch_cli/centromere/ctx.py +++ b/latch_cli/centromere/ctx.py @@ -120,6 +120,11 @@ def __init__( image_name=self.task_image_name(entity.name), pkg_dir=entity.dockerfile_path.parent, ) + if hasattr(self, "workflow_name"): + raise ValueError("""Unable to locate workflow code. If you + are a registering a Snakemake project, + make sure to pass the Snakefile path with + the --snakefile flag.""") else: assert snakefile is not None @@ -148,11 +153,13 @@ def __init__( fg="red", ) click.secho( - "\nIt is possible to avoid including the Snakefile prior to" - " registration by providing a `latch_metadata.py` file in" - " the workflow root.\nThis way it is not necessary to" - " install dependencies or ensure that Snakemake inputs" - " locally.", + ( + "\nIt is possible to avoid including the Snakefile" + " prior to registration by providing a" + " `latch_metadata.py` file in the workflow root.\nThis" + " way it is not necessary to install dependencies or" + " ensure that Snakemake inputs locally." + ), fg="red", ) click.secho("\nExample ", fg="red", nl=False) @@ -205,8 +212,14 @@ def __init__( click.secho("Failed to open file", fg="red") sys.exit(1) - assert metadata._snakemake_metadata is not None - assert metadata._snakemake_metadata.name is not None + if ( + metadata._snakemake_metadata is None + or metadata._snakemake_metadata.name is None + ): + raise ValueError( + "Make sure a `latch_metadata.py` file exists in the Snakemake" + " project root." + ) # todo(kenny): support per container task and custom workflow # name for snakemake @@ -230,8 +243,10 @@ def __init__( if self.nucleus_check_version(self.version, self.workflow_name): click.secho( - f"\nVersion ({self.version}) already exists." - " Make sure that you've saved any changes you made.", + ( + f"\nVersion ({self.version}) already exists." + " Make sure that you've saved any changes you made." + ), fg="red", bold=True, ) From 2f8f284cb2fa37ab870a5694b7f2e8157a97a95d Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Thu, 21 Sep 2023 16:07:34 -0700 Subject: [PATCH 256/356] update init files --- latch_cli/services/init/common/.dockerignore | 2 +- latch_cli/services/init/example_snakemake/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/latch_cli/services/init/common/.dockerignore b/latch_cli/services/init/common/.dockerignore index 737a4ec4..28605f0e 100644 --- a/latch_cli/services/init/common/.dockerignore +++ b/latch_cli/services/init/common/.dockerignore @@ -3,7 +3,7 @@ README.md CHANGELOG.md docker-compose.yml Dockerfile -.latch +.latch/.logs .git **/__pycache__ .latch_report.tar.gz diff --git a/latch_cli/services/init/example_snakemake/Dockerfile b/latch_cli/services/init/example_snakemake/Dockerfile index e7ac1c14..e3685216 100644 --- a/latch_cli/services/init/example_snakemake/Dockerfile +++ b/latch_cli/services/init/example_snakemake/Dockerfile @@ -18,7 +18,7 @@ run mkdir /opt/latch copy . /root/ -copy .latch/jit_entrypoint.py /root/jit_entrypoint.py +copy .latch/snakemake_jit_entrypoint.py /root/snakemake_jit_entrypoint.py arg tag env FLYTE_INTERNAL_IMAGE $tag From d8df2091f1d05ebc90d577bf831b6e4b468bc0f8 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Thu, 21 Sep 2023 16:09:09 -0700 Subject: [PATCH 257/356] changelog --- CHANGELOG.md | 10 +++++++++- setup.py | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 959eab87..9515c75f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,15 @@ Types of changes # Latch SDK Changelog -## 2.32.6 - 2023-09-07 +## 2.32.8 - 2023-09-07 + +### Fixed + +* Snakemake: + * Better errors if `Snakefile` or `latch_metadata.py` file missing + * Correct issues with snakemake example project + +## 2.32.7 - 2023-09-07 ### Fixed diff --git a/setup.py b/setup.py index 4a9acc75..d09f1f05 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ setup( name="latch", - version="v2.32.7", + version="v2.32.8", author_email="kenny@latch.bio", description="The Latch SDK", packages=find_packages(), From 880d7dda2f4179593b7c4a23cc8175bc3e95c945 Mon Sep 17 00:00:00 2001 From: Hannah Le Date: Thu, 21 Sep 2023 16:29:48 -0700 Subject: [PATCH 258/356] change snakefile path --- docs/source/manual/tutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/manual/tutorial.md b/docs/source/manual/tutorial.md index 91135dbe..493d9329 100644 --- a/docs/source/manual/tutorial.md +++ b/docs/source/manual/tutorial.md @@ -125,7 +125,7 @@ Finally, type the following command to register the workflow to Latch: ```console cd snakemake-wf &&\ -latch register . --snakefile workflow/Snakefile +latch register . --snakefile Snakefile ``` During registration, a workflow image is built based on dependencies specified in the `environment.yaml` file. Once the registration finishes, the `stdout` provides a link to your workflow on Latch. From 424415e59ae7f6020ab256f39e3b94b540a47a75 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Thu, 21 Sep 2023 16:33:39 -0700 Subject: [PATCH 259/356] mistake --- latch_cli/centromere/ctx.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/latch_cli/centromere/ctx.py b/latch_cli/centromere/ctx.py index 97657f2b..7b17ec54 100644 --- a/latch_cli/centromere/ctx.py +++ b/latch_cli/centromere/ctx.py @@ -3,6 +3,7 @@ import traceback from dataclasses import dataclass from pathlib import Path +from textwrap import dedent from typing import Dict, Optional, Tuple import click @@ -120,11 +121,12 @@ def __init__( image_name=self.task_image_name(entity.name), pkg_dir=entity.dockerfile_path.parent, ) - if hasattr(self, "workflow_name"): - raise ValueError("""Unable to locate workflow code. If you + if not hasattr(self, "workflow_name"): + raise ValueError(dedent(""" + Unable to locate workflow code. If you are a registering a Snakemake project, make sure to pass the Snakefile path with - the --snakefile flag.""") + the --snakefile flag.""")) else: assert snakefile is not None From be7601b2afc71156fe048fc9de5dccdac8e1d95e Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Thu, 21 Sep 2023 16:44:34 -0700 Subject: [PATCH 260/356] put data in s3 --- .../init/example_snakemake/data/genome.fa | 3838 ----------------- .../init/example_snakemake/data/genome.fa.amb | 228 - .../init/example_snakemake/data/genome.fa.ann | 3 - .../init/example_snakemake/data/genome.fa.bwt | Bin 230320 -> 0 bytes .../init/example_snakemake/data/genome.fa.fai | 1 - .../init/example_snakemake/data/genome.fa.pac | Bin 57556 -> 0 bytes .../init/example_snakemake/data/genome.fa.sa | Bin 115160 -> 0 bytes .../example_snakemake/data/samples/A.fastq | 1000 ----- .../example_snakemake/data/samples/B.fastq | 1000 ----- .../example_snakemake/data/samples/C.fastq | 1000 ----- latch_cli/services/init/init.py | 18 +- 11 files changed, 15 insertions(+), 7073 deletions(-) delete mode 100644 latch_cli/services/init/example_snakemake/data/genome.fa delete mode 100644 latch_cli/services/init/example_snakemake/data/genome.fa.amb delete mode 100644 latch_cli/services/init/example_snakemake/data/genome.fa.ann delete mode 100644 latch_cli/services/init/example_snakemake/data/genome.fa.bwt delete mode 100644 latch_cli/services/init/example_snakemake/data/genome.fa.fai delete mode 100644 latch_cli/services/init/example_snakemake/data/genome.fa.pac delete mode 100644 latch_cli/services/init/example_snakemake/data/genome.fa.sa delete mode 100644 latch_cli/services/init/example_snakemake/data/samples/A.fastq delete mode 100644 latch_cli/services/init/example_snakemake/data/samples/B.fastq delete mode 100644 latch_cli/services/init/example_snakemake/data/samples/C.fastq diff --git a/latch_cli/services/init/example_snakemake/data/genome.fa b/latch_cli/services/init/example_snakemake/data/genome.fa deleted file mode 100644 index 63982cc2..00000000 --- a/latch_cli/services/init/example_snakemake/data/genome.fa +++ /dev/null @@ -1,3838 +0,0 @@ ->I dna_rm:chromosome chromosome:R64-1-1:I:1:230218:1 REF -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNTCCTAACACTACCCTAACACAGCCCTAATCTAACCCTGGCCAACCTGTCTCTCAACTT -ACCCTCCATTACCCTGCCTCCACTCGTTACCCTGTCCCATTCAACCATACCACTCCGAAC -CACCATCCATCCCTCTACTTACTACCACTCACCCACCGTTACCCTCCAATTACCCATATC -CAACCCACTGCCACTTACCCTACCATTACCCTACCATCCACCATGACCTACTCACCATAC -TGTTCTTCTACCCACCATATTGAAACGCTAACAAATGATCGTAAATAACACACACGTGCT -TACCCTACCACTTTATACCACCACCACATGCCATACTCACCCTCACTTGTATACTGATTT -TACGTACGCACACGGATGCTACAGTATATACCATCTCAAACTTACCCTACTCTCAGATTC -CACTTCACTCCATGGCCCATCTCTCACTGAATCAGTACCAAATGCACTCACATCATTATG -CACGGCACTTGCCTCAGCGGTCTATACCCTGTGCCATTTACCCATAACGCCCATCATTAT -CCACATTTTGATATCTATATCTCATTCGGCGGTCCCAAATATTGTATAACTGCCCTTAAT -ACATACGTTATACCACTTTTGCACCATATACTTACCACTCCATTTATATACACTTATGTC -AATATTACAGAAAAATCCCCACAAAAATCACCTAAACATAAAAATATTCTACTTTTCAAC -AATAATACATAAACATATTGGCTTGTGGTAGCAACACTATCATGGTATCACTAACGTAAA -AGTTCCTCAATATTGCAATTTGCTTGAACGGATGCTATTTCAGAATATTTCGTACTTACA -CAGGCCATACATTAGAATAATATGTCACATCACTGTCGTAACACTCTTTATTCACCGAGC -AATAATACGGTAGTGGCTCAAACTCATGCGGGTGCTATGATACAATTATATCTTATTTCC -ATTCCCATATGCTAACCGCAATATCCTAAAAGCATAACTGATGCATCTTTAATCTTGTAT -GTGACACTACTCATACGAAGGGACTATATCTAGTCAAGACGATACTGTGATAGGTACGTT -ATTTAATAGGATCTATAACGAAATGTCAAATAATTTTACGGTAATATAACTTATCAGCGG -CGTATACTAAAACGGACGTTACGATATTGTCTCACTTCATCTTACCACCCTCTATCTTAT -TGCTGATAGAACACTAACCCCTCAGCTTTATTTCTAGTTACAGTTACACAAAAAACTATG -CCAACCCAGAAATCTTGATATTTTACGTGTCAAAAAATGAGGGTCTCTAAATGAGAGTTT -GGTACCATGACTTGTAACTCGCACTGCCCTGATCTGCAATCTTGTTCTTAGAAGTGACGC -ATATTCTATACGGCCCGACGCGACGCGCCAAAAAATGAAAAACGAAGCAGCGACTCATTT -TTATTTAAGGACAAAGGTTGCGAAGCCGCACATTTCCAATTTCATTGTTGTTTATTGGAC -ATACACTGTTAGCTTTATTACCGTCCACGTTTTTTCTACAATAGTGTAGAAGTTTCTTTC -TTATGTTCATCGTATTCATAAAATGCTTCACGAACACCGTCATTGATCAAATAGGTCTAT -AATATTAATATACATTTATATAATCTACGGTATTTATATCATCNNNNNNNNGTAGNNNNN -NNNNNNNNNNNNGTTCGTTAATTTTCAATTTCTATGGAAACCCGTTCGTAAAATTGGCGT -TTGTCTCTAGTTTGCGATAGTGTAGATACCGTCCTTGGATAGAGCACTGGAGATGGCTGG -CTTTAATCTGCTGGAGTACCATGGAACACCGGTGATCATTCTGGTCACTTGGTCTGGAGC -AATACCGGTCAACATGGTGGTGAAGTCACCGTAGTTGAAAACGGCTTCAGCAACTTCGAC -TGGGTAGGTTTCAGTTGGGTGGGCGGCTTGGAACATGTAGTATTGGGCTAAGTGAGCTCT -GATATCAGAGACGTAGACACCCAATTCCACCAAGTTGACTCTTTCGTCAGATTGAGCTAG -AGTGGTGGTTGCAGAAGCAGTAGCAGCGATGGCAGCGACACCAGCGGCGATTGAAGTTAA -TTTGACCATTGTATTTGTTTTGTTTGTTAGTGCTGATATAAGCTTAACAGGAAAGGAAAG -AATAAAGACATATTCTCAAAGGCATATAGTTGAAGCAGCTCTATTTATACCCATTCCCTC -ATGGGTTGTTGCTATTTAAACGATCGCTGACTGGCACCAGTTCCTCATCAAATATTCTCT -ATATCTCATCTTTCACACAATCTCATTATCTCTATGGAGATGCTCTTGTTTCTGAACGAA -TCATAAATCTTTCATAGGTTTCGTATGTGGAGTACTGTTTTATGGCGCTTATGTGTATTC -GTATGCGCAGAATGTGGGAATGCCAATTATAGGGGTGCCGAGGTGCCTTATAAAACCCTT -TTCTGTGCCTGTGACATTTCCTTTTTCGGTCAAAAAGAATATCCGAATTTTAGATTTGGA -CCCTCGTACAGAAGCTTATTGTCTAAGCCTGAATTCAGTCTGCTTTAAACGGCTTCCGCG -GAGGAAATATTTCCATCTCTTGAATTCGTACAACATTAAACGTGTGTTGGGAGTCGTATA -CTGTTAGGGTCTGTAAACTTGTGAACTCTCGGCAAATGCCTTGGTGCAATTACGTAATTT -TAGCCGCTGAGAAGCGGATGGTAATGAGACAAGTTGATATCAAACAGATACATATTTAAA -AGAGGGTACCGCTAATTTAGCAGGGCAGTATTATTGTAGTTTGATATGTACGGCTAACTG -AACCTAAGTAGGGATATGAGAGTAAGAACGTTCGGCTACTCTTCTTTCTAAGTGGGATTT -TTCTTAATCCTTGGATTCTTAAAAGGTTATTAAAGTTCCGCACAAAGAACGCTTGGAAAT -CGCATTCATCAAAGAACAACTCTTCGTTTTCCAAACAATCTTCCCGAAAAAGTAGCCGTT -CATTTCCCTTCCGATTTCATTCCTAGACTGCCAAATTTTTCTTGCTCATTTATAATGATT -GATAAGAATTGTATTTGTGTCCCATTCTCGTAGATAAAATTCTTGGATGTTAAAAAATTA -TTATTTTCTTCATAAAGAAGCTTTCAAGATATAAGATACGAAATAGGGGTTGATAATTGC -ATGACAGTAGCTTTAGATCAAAAAGGAAAGCATGGAGGGAAACAGTAAACAGTGAAAATT -CTCTTGAGAACCAAAGTAAACCTTCATTGAAGAGCTTCCTTAAAAAATTTAGAATCTCCC -ATGTCAACGGGTTTCCATACCTCCCCAGCATCATACATCTTTTTTCAAAGAAACTTCAAA -TGCCTCTTTTATGCAAGGGGCAAAATCCTGAAATGACTTAAACTTAGCAGTTTCGTCTTT -TTTCAAAGAGAATGGTTGAAGAAGAATTGTTTTGGACGCTTATTGACAATCTGTTGCATT -GATAAAGTACCTACTATCCCAGACTATATTTGTATACAAGTACAAAATTAGGTTTGTTGA -AACAACTTTCCGATCATTGGTGCCCGTATCTGATGTTTTTTTAGTAATTTCTTTGTAAAT -ACAGGGAGTTGTTTCGAAAGCTTATGAGAAAAATACATGAATGACAGGTAAAAATATTGG -CTCGAAAAAGAGGACAAAAAGAGAAATCATAAATGAGTAAACCCACTTGCTGGACATTAT -CCAGTAAAGGCTTGGTAGTAACCATAATATTACCCAGGTACGAAACGCTAAGAACTTGAA -AGACTCATAAAACTTCCAGGTTAAGCTATTTTTGAAAATATTCTGAGGTAAAAGCCATTA -AGGTCCAGATAACCAAGGGACAATAAACCTATGCTTTTCTTGTCTTCAATTTCAGTATCT -TTCCATTTTGATAATGAGCTAGTGATCCGGAAAGCTACTTTATGATGTTTCAAGGCCTGA -AGTTTGAATATTTATGTAGTTCAACATCAAATGTGTCTATTTTGTGATGAGGCAACCGTC -GACAACCTTATTATCGAAAAAGAACAACAAGTTCACATGCTTGTTACTCTCTATAACTAG -AGAGTACTTTTTTTGGAAGCAAGTAAGAATAAGTCAATTTCTACTTACCTCATTAGGGAA -AAATTTAATAGCAGTTGTTATAACGACAAATACAGGCCCTAAAAAATTCACTGTATTCAA -TGGTCTACGAATCGTCAATCGCTTGCGGTTATGGCACGAAGAACAATGCAATAGCTCTTA -CAAGCCACTACATGACAAGCAACTCATAATTTAAGTGGATAGCTTGTGATAAATTGAATT -TTCTCTGTTTAGTACTTGCCGAATAGTTACTTGTTAGTTGCAGATGCTTTTTGATGACAA -AGTTATCAATCTCAATATTAAACTTTTTAGGCTTTCAGGTTTAATCTTTCTTTGAGGGTG -TATTAATTTTCATACAAATATTTGATTCATTATTCGTTTTACTGTTACATTAGACCTGCT -CATTACATGGAGTAACTTAAGTTTTCTCAAACGCTTGATAGCATGATTTGATGTAGTNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNTTGTTAATCGACAAAGTTAATATTATGGTGGTAG -TATCTCAAATATCTGGATAACCAGATCGTACATCTCTGATAAACAATCTTTGCCACTGCT -TTATCCTTTTAAATTGTATTGAGTGCTTCAGTCATTGCAAAATTTTACGAGATTTAAAAT -TTGTGAACCCGACCTTACCGAGAAATGATGAGCTAATTTTTATAGGTCGACCCTTCTGTC -GCTTACTGGGTTGATTATCTTGTGCTTTCTTAGTATCTATCACAAAGGAGACAAAATCGT -TGATAAAAAGTGCATCAACATTCCCAGCCAGAAAATGCACATCATAAAGACATGTTATTC -AAGAGCCACGACCGTCTTCAATTTATCTTTTATAAAAAACCCTTGTTCTACTGACAGGAT -GGAATAGATATTAAATATACATTTTGCANNNNNNNNNNNNNCTGTATTGAAGATTTGTAT -ATGAAAGATGTTTATACATCAAATGCTTTGAATAAAGCCATCTTAATTTCAATTTCATGC -CCTCCTTCACCGTTTTCTGTTGGTCTAGAGGTAGCTTGTTGTGGTCACTAATGAGAACTT -AAATAGTTTTCAACTGCTGGTGATAAATCAATAATTTATGTTCTTAACCTAACATTTGAT -GACCTTTGATGCGTTGGTTATGTTGAAGACAAATTGCCTCTAATCAGTTCCATTAAGAAA -TCTTCTTAACTCCTCCAAATATTCTGCCCATACGATACCTATTTGTTTACTTTGTCATTT -TGCCATAAGATTGGTATCCACTTCTTGTCTGTAAAATAATTAGAAAGTAGCACAATTTTT -ACAGTAATGTAGCACGCGTAACTCCTAAACTTTGTCATAATGGTTGAAATGAATGTATGA -TATAAAAACTCGGACCCTGTTTTACTTCTTTTATAGAACCTTATTTTTGACGCAGGGAGG -CGACATTTATCCAAATTAAGTTTTGACATGGCGCATCAGGGAATNNNNNNNNCTTTATTA -TGTGGCCGAATCAACATTAATCAAATGCACTAATATTGTAACGTTCTTACAAAGGGCAGA -CAACTTGAGAACTTTCATGCGTGCAACAGTATTAATATTTTACTGTCTTGATATCGTTAT -CCTCATCGTAACGTGAATTTTTTTGTCTCATACGTTAAGGTAAATTTTGATGACCCCCGT -TGTCCTTGTTTGCCTTACTGTATAAAGCACCCTTTTATTGTTTAGAATACTAGAATGATA -ACTGCATTCGGACTATGAAAGAAAAAATGGTAGTAGCAAAGGATAGGCATCGCCGTATTT -ACTACTTTGTAAACCAGTGGATTTTTGCTCAACATATAAAAAACTAAAGACCTTTTTTTC -ATCAATATACTTCTGAGACGTGCAGATGTGATATTCGGGTTTGAGCTTGTAGTCAACGAA -GCGGGTTCATGGGCAAANNNNNNNNNNNNNNNNNNNNNNNNNGTCTAGATTATTTCGAAT -ATGAGTTAATCATACGTTGATTAGTACTGTTGGTCTCTCATTGAAATTTTACGTGACACC -ATCATTTTACTTCCACATAAGTTCTAATGTTACGTAGTTCAATTTTAGTCGACCTAGCTT -CATATTTATTTTAGAAGCAATTCGTAATTATCATTTTGCTTTCGAAGAAAATTAAGACTT -CATTTACTATTCTCGTGATATTTTAGTAGGCGCTTCTTTTGTATCGAACCATTTTATTGC -AATGGCCCTTAAGTTACCGTTATTCATACCAATTTGACGTTAATTTTAAATGCGTTCTGA -AGTTTCTTAAATAACCCGGATTGGTTAGGTTCAGCCATGCCTGGCGCGTACATTGAGGCA -TTAGAAGATCCGCAGATAAATAATAAGCTTAGTAAATCCTAAAGATAACAACTAAAATTA -TATTTCCATCAGCTCAATACCGCAGTACTTTGAAACCTGATTTATATATTGCAGAACTTA -ATTAAAAGTACATTGTAGTTCAAAAAATAAATATCAAACTTTTGGACCCTCTCTTATTGC -CTCCCAATTAATTAAAACATCTTTTCTTCCAATCTACAGGTTTGAAAAGGTAATAAGTAA -TATAAACTTGAGAACCNNNNNNNNNNNNNNNNNNNTACTGATCCTTACAGGTTTTAAGGT -TGCAAAGGGAACATTTATTGAAAGGAGCTAACAATAGTGGGTATGAGTAAAGATATATAG -ATCGATATTTTGAATTCTAAATGATGAACTAGGGAAGTAATTTAGGTGAAACATTGCAAC -CAATCATTTTACACTTTTGGTTGCACGTAATGTACCTTTTTATGATANNNNNNNNNNATA -GTAGTAGTGTGAAAATTTCTTCAGGACTTGCAAAAAGAATCTAACTGATCTTCGGATGAG -CCTTTATCGATTATTTTTTTCCTAAATATAATACTTTACAAGCGAATGTTTTGTTAGGAG -AAAGATATAAAAATTATGCGGCATAGGCATATTATCCAATAAAAAGGAAATTTATATATA -AACTTCATTTACGTCATAAGAAAATGTTAAGTTCTCTTAACGAAAACTGTGCGAATTTTG -TGTTAAAGCTGGATGATGAGAAATTATTCTCGTATTATTTTTCATCAGATACTGATAAGG -TTTCAACGTCTTTTGACGTTGGCTTTTCCACACCATGTTTAGAGTTATAAAGCACAATAC -CGTTCTTCTTGGCATTGTTCCTTTCATCACGTTTATAGAAGTAGAGTACAACAAAAGTCC -AAATGGAGAGACAAAAAGCAGAACATGCAGTGAAAGTAAACCCCTTTAAATACCTGGGAG -CTTCTTCTGTTTTCCAAACCAAAACACTTATCCATGCGGTAGATGATTGAGCCATAATAT -TCATTGTAACTAAAGTAATAGCTCTAGTTTGAGCATCTCGGCGACAAATATCGTTTTGCC -AAGAGTATAAAACAGGAGCCATAGCCCAACCAAAACATTGCAGCATAAATGCAAACCATT -TGGCTCCTTCTGCGACGTCCCAAGCGGCTAATATGGAGTTACCAATGATATTGAAAACCT -GAGTAAAAATAATCGCAAACCAACGAGAGTGTAATTTATCTGCAATAATACCAGTAAGCA -TCAAATAAACCATACCTAAACCCGGAGTAATCATGGATAACTGATTGAGCTTAGGAATAG -AGTATCTTTTCAAAGATTTCAACCATAGTAGGTATGCCCCAGATGAAACATTACTGTCAT -TCCAACAGAAAATATTCCATAAAGTTAAAATGTATATTTTCCAATCACTGAAAATTGTTT -TCCACAGTTTAATATCGAATACTTTTGTTTCAAAATCACTTTTACCTGTTTGGTTTTCTT -TTAATCTTTTCCTCGCCAACCTAATTTCATCATCAGTTAAGAAAATAGAATAACAGTTGT -ATGGGTCACCTGGCAGGGAGTAAAATCCAATAAGGCCCACTACGACAGACACAATAGCGT -CAATAATAAAGTTCCATCTCCATCCCTCTAAACCATTTACACCATTTAACGATGAATATA -CGGCTGACTGGATCCCACCAGCGGATAGAATACCGATATACTGGCCCAAATAGTAAAAAG -CAGAACGACGCACCATTTCATCATGTTTGTAAAAGGAACCAAACAAATATTGGTATGCCA -AATAACTTGGCGCTTCAAAAGCCCCAATGAAAAACCTAATTGCTTTCAAGTGTGGTACAG -AATTGACATATGCAGCACCAACGGTTAAAAGCGACCAACATAAGTCGAGGCTTGGTAAAA -CATAGTTTAATGGGAGCTTGTTCAGGTAAATCAAAAATGGCAATTGAAATATAATATTAC -CAACTGTGTACATTACTTGAGTATGCACCAAATCATTACCTTGAAAGCCTAAATCTTCCT -TCATTCCCGAAACGTAAGCGTTGTTTATATTAACCGTATCCAGATATTTCACCCAATAAG -CAATACAAGAATAAAAGGCTAAAAGGACATCCAATTTAATTAATAANNNNNNNNCTTTGA -AAGAGGTACCCTGTTTGAACCAACTATACCATTTATTGTGAGATCTTTCCTTTTCATTGA -TCCGATACTCTTGTTCATCGAAAAATCTCCACCATGGCCTATCGGCTTCATCTCTATATT -CATAACTTCTAGTAACGTTCACATTGTCTTTATGTTCACTATAGCTACTAGTCTCAAAAT -GTAGTTGATCTTTTTCACTTGTAGTCGTGATGAAATTTTCAGCTGTTTCATGACTCTGGA -TACTGTTGGAGATAGTGACAATTTCTGTTGAATTTAAGTCATCTGGCAGGTCTTCCACCT -GCCGCTTTACTGGAATAAAACCCCATTTTAGTCTTTTGTAAGGATCTACAATAATCTCTT -TAACAATTGAATACATGTATGTTATTTATATATGCAGTAGTTCTCTTTGTAANNNNNNNN -AACAAATAGAGAGTAAGATATGTAGCGAATGTCCATTCATCATAACAGGTAAACTAGATG -CTCTTTTATATAGTCTGGTTGTATAAATAATTTATATCCTCATCTAAACGCATGTCTCCG -CTTGGTTTCTTATCTATTTGTGGAGGCACCCGTAGTACTGTGCNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNCCAGTGACACAATCTTTACCATTACACAGTTTTT -ACTATTTCTAATGATTACATTGGACCATCGGAAAACTGCGCTAACTTTGGATAACGCCAC -AGAACGTGATCTGACTATTGTAAAGGTGTCATTCGGTAAGGTAAACCTTCAAGGCGTCCA -CACCTTTAACCATATAACAGCGTAAACTCTTGTTAAAATACAGGGGTAAGACATTGGTGG -ATATTCAACAAGATCCGATACCTCCAATTCCGATTTCTACAAATTGTGCTCTACATATTA -CTGCGATGCAATTATCCACACATAAAATCGATGCCTTTAGAAAAAGACATAAAGCAGACG -GCATTGTAGATATTTGACCAATTAGAATTGAATGAGATGAATATCTCACCAAGCTATTCG -ATATTATAGATAAAGTTTGTATCTTAGTTATGCATTGTGAGTTGGTTGCTCTACTCGCGG -TTACCAGTCTCTTCTAAAAAATCTAAGGCCAATGGTATCCATGACATTTCTGCACTTTTT -GTAATTGGTTTAGTTATGAAAGGAACGTCAAACCAAATGGTTTTTCAGATAAGAAATTGA -CAGTATCTGAGAATTTGCTATCAAAGCTCAGAGGATTTACATATTTTAACGTAATTAAAA -CATTTTTATGTTCGATATATTAGCAAATAGCGTATTAATATACAGCTGTTGCGCTCATGG -TAAAATTTAGCGATATACTTTGCATCTTGGCTGCAAAGAAGAATGAATCGGATATACTAT -TTTTGATCATAATGACGGACATCATGATATAATAACGTTATACGGATAACTTTATTTCAA -AAGCACCATCATGTTATCTCTTGTAAAAAGAAGTATTCTTCATTCAATACCAATTACTCG -TCACATTCTTCCAATCCAATTAATATTGGTTAAAATGAACCATGTGCAAATCAGAAACAT -AAAATTATATCACTTTATTTCATATGGTTTCATGCTTACAAAGCTTACTGTCTTTCTCTT -TAACTTATTTTTCTACAGGCTACGAATTCTTTGCAGGCTTACTTTACTCATATTATCATT -ACCTGTACAAATATATATTAAAGAAATCCAAACAAAAATGCTTGAAAAGCATACAGCTTC -CGATACATCATGTATATAGAAAATCACAGTACAAAAATTTTGAATTTATGTATAACCGTT -TCGCCTGATATATGTAAGAGCTCTTGATTGTCGGAATAGTTCGGGAATTCTGGGTGGAAC -TAGTAGCTGGAGATGCGTTCTAAAGGATCTAAAATCAGACTCACCCCAAAAACCAAAATT -TTGATATTCAACTTTAGTATTAGCCAGTCTTAAAATGATTTTTTGCCAAGAAAGCCGAAG -TTTAACGAGCGTTTTAAAATATGCACAAGTCCATTAATTAAATTTGATCACAGTGATTAC -CAATTTTGTTGAAAGCAGTAATTTGTGACGTCCGTTTTTGGCACAAGTAAAAAATATTTG -TTTTGAAGTCTAGTTACAAGAAGCTACTGAAAACACAGGGCTGGATATAGATGTTTATAA -GCTCCTCCCATGGTCTAAGAGTTTCTCCAAACGCCTAATGTATGCAATTTGTTAAATAAA -AATGAAGAATAGATGCATAAACAAGCGTCATTAAAGTTCTTATCATTATTCCATGTAGAA -ATGACCTGCAAGTACGAGCTGGTTATGCGAAACTGAGCTTAACAACATAGTTTTCTTTTC -CATTGGCTTGGATATAAATTTTTCGCTGAGAAACTTCTCTGCATTTTTTAAGCATTAAGC -GTACATAACATAAAGTCACTGAGATATTAGAGGTTATAAAAAAAGACTACGTGGGTGTTT -ACCTAAGATTTTCACAACTTGTTTATTAATTGGATAAATAGTATTTTTCTTGGCATTTAC -AAACTTTATGTTTTTAGGTGTATTTGCAGTTCCATTAAGGGAAATAAGTCATAAGCTTTT -TTGGAAAACAGATTTTTTGCCCCGCTTAACCTGAAATTGATATTAAAAGAATGTGTGAAT -GGCCATTAACTAACAAGAGAATTAATAATGTTAAAACACAGATACCTCGAAACAAACTCT -ATGTAAACACTTATTTTATTGTGGTAATATTTTTTGATAACAACACATCTGAAACAAAAT -AATGCAAAGCCGAATAGTTAGGCTAAAAATGTACTCTTAGACATTTAAAAAGGTTTATGA -ATCCTATGGTATTTAATATATTAAAGAACGAAGTAAATGGGAAAAAATGTGTAAACACTA -TAAGCGTGATGATAGAATTATTAATATAAGATGATGCCGTGCGTTTACCATACGATTGCC -AGCAATACGGTGGAAATAAAAACACTTATGCCATTATTGGTCAACAGACCATTGGCAATA -CCAACGTAGGTTGAGATTTCTAAAGAGGCAGTACTAGATCCTATTATGCTACTTGCTGGT -GTGCTACGAGGCTGTTGCGACATAGTACTTAACCCGGAAGTTATTAGACTCTTGGTGTTG -CCAGTTTCGGATACAGAAACAACACTACTGCTGTGACCAATCACATCGGTCGCGGAAGCC -GTCTGTGTTTCAGCATGATTGAATCTTGAAATTGAAGAGGTGACTACTGTTTTCNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTGGTA -GCACTGTTCATTTTAGAGCTGACAGACTCTTCATTCGTAGTCTGTGGCCTCCATGTTGGA -TAGACCGTAACAACATCATTCACAGTAGCCGTGGCCGTCGAAACAATGGCAGGTGAAGCA -GTTTCGGAACACACACCAGATTCGCAGGAAGTAACAGTAACTAGCGTAGTTTGTTGCCTC -GATTCTGTGGTGGAAATAGGACACCATGTCGTGTATTCTGTGGTAACGCCGTTAATAGTA -GCAGTGCTTATAGATACAATGGCTGGAGAAGCAGTCTTAGAGCATACGTCAGATTCACAA -GAAGAAATTGTAACTACTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNAGAAATAGGGCACCATGTGGTATACTCTGTTGTG -GCACCGCTAACAGTAACGGTGGCCGTGGAAACAATTGCAGAGGAGATGGATTCAGTGCAC -ACATGAGATTCGCAGGATGTCACGGTAACCAAAGTGGTTTGTTCGCTCNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNAC -GAATATGTAGACTTTGGTGATTCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTAGCT -GAACTAGTTTCGCTCTCAGAAGAACCAGAGGTGGAACTACTGGTTGGAATGACGGATGAT -TTAAATGATTCAGAGAATATAGAAGTGGAGGTTGTTGTNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTTCCA -TTGCTAGGATAGAATGGGGTAATAATTGGATGCTAAGACGTGATAGAGCTGGTTATTTGT -TCTGAAGAAGATGATGACAAACTGGATGAGGTGGCAGTGGTTGGACTTTTAGCAACAATA -ACGGTTTCGTCAGTTGGTTGACCATTAGTGCCAGTGACAGTAGTCATCTCAGTAGAAGTC -GAAGTGGTAGTTGCGATGGTGCTAGTAGTATGTTTTGAAGGATCAGGGATAGTACAATTG -GGCTGTTAGGTCATCGTCAAAAGAGTAAACGTGCCCTGCAAAATCATCGCTAACAGTAGT -AACATCAGGCAATTCCACGCTAACTGGCAGTGTATGCCAAGAAACAGCGTTTGAGTAGAC -AATCTTCATTGGACAGTAGAATCCAGCATACATATACACAGTCCCTGCAATGTTATCGGG -CAATCTTCCTTGCCATGGCTTGATACCATTAATCGTAAAGTTTGTGGATGTAATTGGAGG -TTGCTCTTGTGCACAGCATCCGAATGCAACGTCGCCACCGACTGATAGAATTGCAGAGTC -ATCGACCTTAGCAAACCTGAACGTGTAAGAACTTGTTTGTGGTGGTAAAAAGTAACCTGT -CATTTCTAGAGTAGCGTTTTTTGGGATAGTATAGAAACCAAGTAAATCAGTACTCCAATA -GGTCTTTCCTGGCTATTTTGAACATTCACTATGACCTCTGCATCCCCAGTTTCCATAAGC -ATCTGATTGAGCACATTTAAAAGTTCCTGAAGAGATAACACAAGAAAGATCGTAGTCAAT -TGAGAAATCCGTCTGTCCGCCAACGGAACCTAATTCCAATTCGAGGCATATCCAGAAGTC -ATATATTGCGGGTAGGAATACGTTGTTGAATTCAGTAATGAGTACAAAAGTTGACATTCA -TCCCATTTTTCCTCGGGTCCGTTGGCAAGCATGCTTGTGTACTTCCTGAAACAACATTGG -ACGTGGCCAGGTAGGTGAAGAGTGCCAAAAATAAATAGTGATGAGGCATTTCTTGGTTCG -TCAATCAGGTATGGGTATATTAAACAATAACTTTAAGCCATGCTGTTAATGATGAAAATT -CTGATGCTGGTCTCTTCATATGTCATTGTTTTGGGAACTGTCTTTTTTCGATCAGATGTA -TGCGCAACGATTTGTTTAGCGTAGTGATGTTCCCGCGTAGTACTTAGGAAATTTTGGTAT -CGAAACGTCCCTACAACACTTTTTGTCGCTGATATCTGCACATGTGAGTAACGCAGATTC -CATTGCATTATTACCTTCCCCTTCCCAGAAACGATTTATTACGACTCAACAAGTTCAAGN -NNNNNNNNNNNNNGGTTACAACCGCATTTTGCGTTTAGGTGCAGCGAGACTTACCTTGAT -GCAGTCCTAAAGGGTCCTGCAGCGGTTGTAACGAATCCTATTTGCTTTTGTGCATTCCTA -AACGGGCTGAAGTAAAAGTCTTGAGGAACTCCAGGAGAAGATACGATAAGCTCCGAAGTG -CCAAATTTTATTATCNNNNNNNNNTATTTGTACGAGCGGAAAAGGATTATACTCTTCCTC -TTTTGCTTCATCACAAGAGGATTATTTTGACGTCGTCTGTTGTACTACTTCTTTATCGGT -GTGCGCAGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NTCTCGTGAGACCTCCGGAATTTTGACGCTGCAAGTCAATCTACGGGAAAGAAGAAATTT -TTTAAACCTAATGCAAAATAAGCTTTTCTTGGAAAATAAGATTTTCGGCAATAAAAGGTA -AATGCAGCCAAAAATCAAAATACTTCAGAAGAAGTCGTAGCGAGGACTGCTAAGGGGAAG -CGGATTTGAAGATCCTTTCCAGAACAAGAAGGAGCCGAAAGCTGTCAGGAACTGTTCCTG -ATTTTTTAGGAAAACAATTAATAGGTATCTCGTCTAGAGTAGTATCTCGAGCTTCCAGAA -GTTGCAGATAATCAAAATCATTGTTTTATCCCTTTTTTTAGATTACAGCTTAGAAGAGTA -GAGAGCAAGTTTACTGAAACGGTTCCTTGTTTACAATAATATTCCTAACAAACTTTACGA -ATTAGGATGCAGCATGATTTTTTATATTGCTTCACTTCCTAAAGTATGAATTTTTATCCG -TAGTCGCAAACAAAACAGCTACTGGAAATCTGCAGCTTGTTAAAAACCGGTAGTTTCCGA -ATACTCCTCGTCCTTGAGTTGTATACCGTTAAACTTCCTAGGGTGTCATGTGTCTGGCCC -AATTGGCCCACAAAATCTGGTCCTATTGACGGTTTTCTTTTGATTTTCAGCATCTTCCTC -TAAGAAGGACAGAAAATTATGTAATATATGGGAGAAACGGCCTCCCAACTGCTAAGTGTC -CCCGGCAGCACGAGTAAGCAAAATTCAGGCAAACTATTGCATTAAGAAGCCGTACATAAT -TCAGCGTGATATGATGAAATTTTGTTAATTGCAAATTTTAGTACGATTTGGTTGTTAGTG -TGTGTTTATGCAAGTAATTATTGAACCCTAAGTAGTTACTGTCTTCTTTTGCTGTAATTC -GTGGATTCACGGCCCTCCAGCAACATGGATTGAAAGGTTCTTTAAAGTTTTCAATCCGTA -AAGTTCTGAAATGTATTTTAATCATGTCAATAATTTTACTGGTGAGTAGCATTTATGACC -AAAAGCGTACTTAAATTAGCAGCAAAAAAATTTTTAATAACGAAACTATAAGGAAAATAC -GAGGTACTGATTATGAGAGTCCCCGTTTCTCATTTTTGAGACATGATCTGAACAAGGCTG -AAAACAGCAATCTTTTTCGATAACTTTTGCAAAAATTTCAAACATTGTTGTTTGAATGCA -GCCAATTTTTATAGGGTACAGAGCTTAATGCTTTACATGTGCTTTATTTTCGGTACTTTC -CTTAAAGTGTCTACATTATCTCTCAGGACTTGAATGTCTTCGGCTGAATTACTATAAAAT -CTTGAGTTTTCTCTGAAGTTTAATCCTAAGACAATAGTGGTGAGTGATGTAGTTCACGTG -TGTGCCACTGGTAATAATAGAGATAACTATCTCAGTTAAGTTTGAAAAGGTAAAAAATAG -TTTAAGTAGTCATTTTTTGCGACGGTCATTCTTCTCTGATGCACGTTCTTTAGACTACCT -ATAAACACCATTCTTACGGAATTATAATGGAAATAAAACATCAGTACGTGTTGCTGTCGG -TGATAGAGGGGTAACAGAACCTTAATTGAAAAATTAGCACAGTGCATAATTTATTAACAT -GATTGTTTTCTGTGGAAAATAAGAAATTCAGCACCAGTAAAAGACGAGAAATATAGGCAC -ATAAATGCGCTCTTACTCGTATGTTCCAGGATGAAAATGTTTAGGGCATCAAGTATTGCC -GAAAGGGCAATATGCTTTAACACCAGAAAATCCACTGTATACTCGTTACGGGTAAACAAA -GCAAAACGCAGTGCGTGATAATGTTTCTAAAATCTCTGCACACTGTTGAAATGCGGCTCT -GATACTTTAGCCCTTAGTACCTGACGGTGCCTAAAATGAGGATAAGTATATGAGTTTACA -ACGAATATAATGCTTTTTACCTCATCATATAAAGAATAATATTAATTTAAAAGTAAAAAT -TAGACCTAGGTGGTAATGAGGAATGTGTCCTAATGAATTTATGTAGTTGATGCTTTTGCA -GCGNNNNNNNNNNNNNGTATTAATCAAAGTGCACTACGTGNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTAACATGGTATTCTTAATCGTATATCGTA -ATGGATTGTCAAAAATAAAGAGAATATAGTCGGTTCAAACCACTTTGTACGTCTACAGAG -TATAGTGTAGAAATTATAGTTAGGATTGTGACATCCCTTTTTCTTTAACATAATAAGTTT -GCTTCAAATTAATTGATCAATTAGGATAATAACTCTCAACACCTTTATTATTTATGTTTA -GAGAGTTTATGGTCAGATGGTGATTGGTATTGATACTTATACTTTTTTTCTCATTAGTAT -AATACGCTATATTCCATGTTTGAATAGATCTTATTTTTTGGCTGTCTAGATAATAAACAT -ACCGTTTTTAACACACACACACCAATGAGTAGACGTTATTGCGACTGTATGCCCTTTAAG -ATATTCTGTTCAAAGAGATAAGGTATTTATTCGTTTTCTTGCAATTTCTTCTCATCTATC -ATTATCATACCAGATTGAATCTTATTTTTTAATTTTTAGTCTATTTGATGACGGCTACTG -AATCTTTACATTACTTGAGCTGAGAAGTAAAATTGCATTATTCATATTAAACAAAAAAAT -CAATTTCCCATAAAGACAATAGCTCAACTTCATCACGTCCTTGGTTTTTACCGAGTACAT -ATATTTGATGAATTCTGATTTGAAAATATCAATTTGTTCCTCTAGAATATTTCCACTCGC -ACATTCAAAAGCAGGTATTGGAACGCACAAGAAGCGATCGTCACCTTCCATTGGGGTTAG -TAGCAGGATATATATTTCCATTCTATATTCCAGGTTCTCTTTCACAATTTTATTGAATGA -AATACCTGAGCTACCAAATCAGTCTTAATAACACCATCTTTTACACCGGTACTACAACAA -ACCATACTGAGTCTGAAATTGGACTTCTGCAATGAAAAATTTAAGCCCTGATCTACGCAT -AATGCCCGCTATAAACCTTATTTTTTATATGGGGGTCTGGCGCTTCGGGAAAAGAGAGGA -AAACTTGTAACTCAATATATCTCGATACAACATTACGTTTTGTAAATTTATCACAAAAGC -CAAATGATGATATCTCTCTTGCAAGTTATCGAACATTGATTGGTAATTTGTTTGAAAATT -GTTAATTTATTGAATATTTCTTTTGCAAAAGAAATAGTCTCAGCGAAAGCTGGTTACAAA -ATTTACATCATGAGTTTACGGGATTTGTAAATACGCTTTTTGCATAAAAATACTTTGCCG -TTTCCCACCCTTGCATATTCACTTACTCCCCCCTTCATATACTCTATGTAATGATGATTA -AGCTTTGGCCGCTAAGTCTCTCAATTAGTGTTGATTTTGGTTTTATTCATATGATTCTTC -TTTAGTGAAGTATTGATCAATTACGTGAGTCAGCTTTTTGAAAACCCCATTTGGAAGGAA -TTAGGAAATTATTTTGCTTACTACGACCACTAATTTACCGCCATTTCTGGGCCTTTTTAT -TGACTATTTTGACCATGTGCTCGACTAGAAGAACGGCATCATAATCTGCTGGTAGAGTTA -GTCTATAATGATTGTTGAAAATAAAGGCATAAGAGATATTCCACCTAAAATTCAAGTTAT -TGACTTTATTATCAGGATCTTAGTATCCTTTTTTGGTAAGTCATATTCAATGAACTAGGT -CTCGCAAACTTTTTGTTCGAAAAGCGGTAGTGCATAGTTATGCTAACTCTGGATATATGG -CATAAACCGTACAACACTAGCCCATTTTTTTGGAAGTAGTGAGGGCAGCTAGACTGTATG -ATGAATATTCGCCTGCATACTGAGNNNNNNNNNNNNNNNNNNNATGTGGCTGGCCTTACG -ATATGATGCACAATTCATAATTTGGAAGAAGGGCAGAACAATTGCATCTGTGCTTGGCTC -TCAAGAACGGTGTTTGGTGCATCAAAAGTTTTCGACTGCTTATTTGGTCGGAAATATAAA -AACTCGATCCTCTTATCTAAGCAGTATACATTCTTCTTTTTGAAATGAATGTACTCCGTA -ATATCTTCTTATTTGGCATTTTCATCCTTAACTTTTGCATGGCTCTGAACTAGTCAGATA -GTTGCCCTTTTCAGCAAACCTCTTATTATTGAAAGCATGGTGTACATCCGTTATACTATT -ATATTATAAGAAATTGGGATGCCAANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NCGCAAAAGTAATTGCAGATTTAATAGCAGGATATTATACCGTTGGTAAAACTTAAGGAT -TTTATGAACAATAGCTTCAAGTACAGCATTCATAGAACCAACTACTAAGGATGAAACTAG -TATGTTTTTGTCAAAATATTTTCTTGACCTTGCTGTAACATCAAGATCTGTTTCTCTAAG -ATATTAAAGTTGAGTAAAAACAAAGCTGATATGAGAAAAATACGTAATTGCTCCACATAA -TACGTGGGTCAGACATAAAGGTAGAATACTTGATACAGAAGAGATTATTCGGTACTCTTG -ATGGCGTGCTTGAACTGGTGCCTCTTAACAACCGGTAATATAGTCAGATGAGTCACTACG -AGTGTGTGTAGTAGCAAGTGTTTTACCTACGTGGCAGTAAGAGTAGCTCTATGGTTGTGT -AATAGTGGTGCTTATTCCTAATGCTCTGAAGTCTGAAGCGGTACAGTTGGTCTGGTCTAT -ATCATGGTCAAAGGAGCAAACATATCTTCTGAAGTGACCGCAAATAGTACTATGATGTGG -TTGGCAATATAACTTAAAAGGAAATAACCACAAGGAATTGCACCCATGTACACAGTTTTT -CCCGGAAATTGGGAAACCAGTACGAACATATATCAATTACTTTTACATTATCTTGATTGG -AAAACTGGCACAATTGACTGTGACGTTAGTAGTATGTTGTTCTTCTCTACATCAGTTAAA -TATACGTGTCAACATCAACTAATCAACTTTCCCCCGTTTACCACATTGAAGCTGGGTGTG -GAAGATTTATTTGAAGAAACTAAAACGTACCCTGTCATTTCCTGAGTCCCCTTTCAACTT -AGTGTGAAAGCCGAACAATTATAATCCTCGGTAGACAACAGATTTATTGTACTAAAGTTA -CTCTTCCTGTTATCTTCCTTGATTTTACTGTTATAGCAATGACCCACCGCAATCAGGAGA -GCCGCCGTATGGAATAGCATACCAAGTCATAAAATCGTCAACCTATTAACGGGGTTCAGG -TTCTTTTTCAGCGTAGTAGCCCTTTAACAAGCGCTGACAAAGTTGACACTCAGAGAAAAT -TCAGGATTTATTGTAATCCAGCTACTCATCCTTAGATCCGCTTGCAGGCATGGTTTTTTT -CACCTTGAGAGGCTATTTTGGGTAAGCCAGGAAGGCTGAAAAATCCCAAAAGGACACAGT -AATAAGAAATTGTTGTTGTTGTATGATGCATTTAGAACTCAAAAGACGAGTTTCTGAAAA -TGCTTACAATACTCCATAGGTAACATGATTTTTTTATTAAAAAAGTATACTGTTCCTTTG -GGTAAAAATTATGCAACCCTTGAGTGTCCGATGAAGATAAGACTACGAAACAATTTGCGG -TAAATTTTTTCTGCTATTGACATTTACACATGCTCCAATCCATTACCCTTTCCATTCTCG -TAATAAAACCTCGAACTGTTATTTCATATTTACATCTAGACGGGTATCGGCCTCAACAAC -TCCAAACAAAAGTAAATAGAAAAGAGCCAGACCTATCGCACCGGGTAGAGCCAGAAAATA -TTTTAAACTATAGTTGACGTATTCTACGGCTGTTGTTTAGGACAATACTTTTTCCTTCAC -AGGCTTCGAATTACGCACATGCAGAACTCCTGTAGAAACCACGAAGAAAAGTTTAATTAA -CTTTCAAATGCCAGAACTAAAGATTGATGAAACAGTTATACGAATTTAAGGGGAACTTGC -TTTTTCCTTTTGCTTCATCATAAGCGCAATATTCGCAGCGGTGGCGTCGCGTCTTACCAT -TTATCGGCACATTTTTCCGAAAAGGAAGGAAAATGGCGGTGTCAAACGGTCTGGTGTGAC -ATCTAGAAGTTCGGCATTGCAAGTTAATCTACGGGAAAAAGAAAATTTTCTTATAACCCT -AATGTATAATAAGGTTTTCGGAGAAAGCAACTCACGGGGAACAATTGGTTAGAAGAGACC -GTAGAAGCGCCCCACTAACCTGGAGTTGATTATCGAGGATCTTTCTCAGAAAAGCAGCTA -ATAAATGAGCACAGTACTCAAAAATTACTCATAGTATTATAATTACTTACTTAGTCAATA -TGGCTGCGCTTTTAAAATGAGTATCTTTTATTTTTTGACAAGGAAGAAAAAGATGCAAGC -AAAGAGAAATTTACTAAGTACAAGCTCATTTCCAAAAATTCAGTTTGCCTGTAACAATGG -GTAGCGATCTTCAACATATGGGATTATGCCTTGAATGAGATTTTTGAACGTAGAGGAAAA -AATCGCAGACAGGCTTTATTGTGCTGTTTGACATAGTATACTCAGCCGTTGTGGTGTTAA -TGAATACTATCGATGTGTATACAAACGTACTTCAAATAAGCAATGCGAATATACTGCAAC -TTTTCGGCCTTTGCAACGATTTGTAATGAATCCTTTTGCATCGCTAGAAGGACAAGATAA -TATTTCTTCTGNNNNNNNNNNACATATGCAACAATTTGAAAGTCAGGTCAAAGACAGATT -CCGGTTCCCCATATTCAGATTGGAGAGAAAAACTTTTGGCAACTCATGTTACCAAGTCGA -GACGCTTAAAGTTAAGTGTCGGCCAAGACACGCAAAATCTTGTAATCTTTTAACGCTGCT -CTTCAAATCACGGACGCAATCAGTACTTGTACCTAATTTTGGTTTTCTAATATTGAATAG -CGAACCATAGGTCGAAAATTTAAGGCCACATAAATCCAGAGCCCGCAACTTGGATAGGTA -TTTACTTGATTTTTAGTTTGCTTTCAATAGTGTCGTGAAATTATAAAGTACGCCGCATAT -ATATCTTGATTAGTTAAAAATAGCAGTGTTCAATGATGATTTGATAGGGTTCATAACTGG -TACCAGCGTAGTACAATTACGATTATCCATGAACATAAAAGTGGTTTAAGTACTATATAT -CAGTGAAGCTTCAAAGTAAGCAAACGAGATACCAAGATCTTGTAGGACCACGATATATAA -GAAGCCTAGTTCCGTTGTAGCATCACATAGAAGAGAGCGACAATGCCTCAGAAATTCTAC -AGCAACAGAAAGCACAGTGAGTCATTAACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNAAAGCATTCGCCAAATTTTTA -TTAATAAAACAAATGTCAGAAATATGGCCGGAATCTAATCTGAAAGTTAAAATAATTCTT -ACGATATTCTTATCATAAAACCAATGATTAATGTTTATGATGAGCAAAACTGTGCGAGGG -CACATACATACAGTGGGACCTCATGAGATCCAGAAAAAAAGCAAAGGAAAGTTCGATCGA -AACATTAGCTCTTAGATATTACAGACGTGAGGTATCTCTTCCTTGAAGAGAATCTGGCCC -TGATCAAAAACTTTATTTTGATACTGTTCGAAAAGAGAAATAAGGACAACGTTCTAATTT -ATACAAATATAACCAGTAGGCTTTATCGTAAAATCCTCGAACTTGCTTCTCATCACAGAA -GTATAAAAAGTAAAGAGGTCAAGCAAGAAACGAATAACCACCAAATTTTTTTCAATTGAA -AAGCGAAACGTAATGGAAATTCACCTGCTTTGAATCGTTGTTGAATTCTTATCATCAGTC -ATTATTTTCCTCTTTTAAAGCTTAAGTCAACCGCATCTAAGTTTAACACTTCGTTCCCGT -TTTGAAGTTTATCAAAATTCCAAAATACAGTAGTTAGGTGCTCGTGACAAACCTTTTTCC -AAAGTGTCATTAGACTTCATGGAACTACTACACTTCTGGGGAACGAAAAGCTACCATTTG -CTCATCATTGGATAATTTCNNNNNNNNNNNNNGATGCATCCAAACTTGGACCCCTTTTGA -ATGTCGAGTATGAAGTATCAATTTTAGGGCAAGTAGTTTTACAATAATTTTGGTGCACTT -TTACGTCTCTGCTGATATTTTTAATACTAGTGCAAAAGAATTCGAAATAAATATAAAAGA -ACAAGGAGGATTAACATACTTTAAATAACTAATTATCACCATTATTTCAAGTTTCAAGTA -CTGCGTATGGCATGCACAGCAGATTTCTACTCAAAAACATCCTAAGCGAACCACACTAGA -TCTTACGTTAGTACTGCTGAAAATGGCAATAATTGTTAAAGCAAAAATTGGCGATGGTTC -ATTAATTGCTAAACAAAATAGGGCATTTTTCCTCGTTAATGATAAGTACTCATACTTCTG -TTTCTATAAGTGTTAGTTGTAACTTATGAAATATCGATTTAAATTCGAAGTGTTGTTTGC -AGGATNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -CAATGATATCGATAACGGTGAAATTCTTTTCATGGATTTTTGTTGCCCAAGAAAATAACA -ATAACGTTTTCTTTATGATACATATATCTACTTTTTCAAAAAAGGAAGCGCAAGAATTAT -CATTTAGTTCAATTTGAATATTTGAAAGTTTGGAGGAGAAACAGTTAAAAAATAATTCAT -GTCAGCGTATATTTAGCAAAGAAAAGATACACAGATACGTAAAAAGAACGCGAATTTTAT -TAAATAATTGCCAGCAATAAGGACGCAATGAAGACACTTAAACCACTACCGGCCAGTAAG -CTGTTGGCACTGCCAGCATACGTTGAAATTTCTAAAGAAGCTGTACTAGATCCTACCATG -CTACTTGCTGGTGTGCTACGAGGCTGTTGCGACATAGTACTCAACCCGGAACTTGTTAGA -CTCTTGGTGTTGCCAGTTTCGGATACAGAAACAACACTACTGCTGTGACCAATCACATCG -GTCGCGGAAGCCGTCTGTGTTTCAGCATGATTGAATCTTGAAATTGAAGAGGTGACTACT -GTTTTCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNCTGGTAGCACTGTTCATTTTAGAGCTGACAGACTGTTCATTCGTAGTCTGTGGC -CTCCATGTAGAATAGACCGTAACAACATCATTCACAGTAGCCGTGGCCGTCGAAACAATG -GCAGGTGAAGTAGTTTCGGAACACACACCAGATCCGCAGGAAGTAACAGTAACTAGCGTA -GTTTGTTGCTTCGATTCTGTGGTGGAAATAGGACACCATGTTGTGTATTCTGTGGTAACG -CCATTAATAGTAGCAGTGCTTGTAGATACAATGGCTGGAGAAGCAGTCTTAGAGCATACG -TCAGATTCACAAGAAGAAATTGTAACTANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNA -GAAATAGGGCACCATGTGGTATACTCTGTTGTGGCACCGCTAACAGTAACGGTGGCCGTG -GAAACAATCGCAGAGGAGATAGATTCAGTGCACACATGAGATTCGCAGGATGTCACGGTA -ACCAAAGTGGTTTGTTCGCTCGTTTTTGTAGTGGTAACAGGTGGTAATGAAGAAGTAATT -TCCTGACTTGTTGTTGCACTGGTAACAGGTGGTAATGATGAAGACGAATATGTAGACTTT -GGTGATTCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTAGCTGAACCCGTTTCGCTC -TCAGAAGAACCAGAGGTGGAACTACTGGTTGGAATGACGGATGATTTAGATGATTCAGAG -AGTATAGAAGCGGAGGTTGTTGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTTCCATTGCTAGGATAGAAT -GGGGTAATAATTGGACGCGCAGACGTGATAAAGCTGGTGATTTGTCCTGAAGAAGATGAC -AAACTGGATGAGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNCTGACAGTATAATTTGAAGGGTCTGGAATGGTA -CAGTTTGGCTGGCTTAGATTGTTGTCAAAAGTATATACGTACCCTTCAAAGTCATCACTA -ACGGTAGTGCCATCTGGTAGTGTCACACTAATTGGAAGTGTACCCCAGGCAACGGCATTT -GAGTAAACAATCTTCATTGGATAATAGAAACCAGCATACATGTAGACAGTCCCTGTAATA -TTATCAGGGGGACTTCCATTCCATGGCTTGATACCATTGATGGTGAAGTTAGTCGACGTG -ATGGGAGGTTGTTCTTGTGCACAACATTCGAACGCAATGCTACCACCGACTGATAGAATT -GCAGAGTCGTCAACTGTAGCAAACTTGAATGTGTAAGAACCCGTCTGTGGTGGTAAAAAA -TAACCTGTCATTTCTAGGGTTACGTTTGTTGGGGTAGTATAGAAACCAAATAAATCAGTA -CTCCAGTATGCAATTATTGGATTATTAGAACAAGCACCAATTCCTTTGCATCCCCAATTA -CCATATAAATCTTCTTGAGGACAAGGAAATGTGCCTGATGAACTAACACAAGGAATATTA -TAATCAATCGAGATATCAGTTTGTCCTCCGACAGAACCCAGTTTAGTTTTTGAGGCATAT -CCATAAGCCATATATGCTGCATTCGAATATGTGGAGGAATCTCTCAATGAATACTGGTAA -AAGTTTACATTCATACCATTCTTCCTTGAGTTTGCTGGCAGGCATGCCGCTGTAGTCGCA -GAGACAACATTAGTTAATCCCAGCAATGTGACGATGGCTAGTAGTAAACAATAATGTGCC -AGAGACATTTTTGGGGCTTTTATTGTACAATTGTTCTTTTTAAATTGCAATTTAAAGAGC -GTACCTGTAAATAAGAAGGAAGAACGTTATGTTATTAATGGACTTTTAGTGTCATCGAAT -TTTATGTAATATATAAGAAGGTAGAATAATTTGGCAGGATAATGTGTTAGCAAAGGAGGA -AATCGAATACCTTTAAAAGAGAAAAAATTTTTTAGCTGCTTAAATTTCTGTGTTATACCA -CCCGATAGATTTTGAGTTATGCTTTCTAATTGATCTGACTGCGAACGTTTTCTTTATGCC -ATCTGAATTGTCAGGAACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCTGTGGTCGTGT -GTGATGTACCTTTCCTTTACATGCATTAATGCGCTCTGAAATGTGGTACGATATCCTTAC -AGAGAATATATTTTCTGTATATCGTGCAATGTTGAATAACCTATGAAGGAAAGTACCCAT -CGCTCAAGGTAAGCATTCCAGGAGGGTCGCCAGAAACTTAAACTAGTTTTAGCGACAGAT -CCGAAAATTGATAGAGACATTGAAAAAATCACTACTCCGTCCTTTTTAGTGCTTTCTCAA -TGCATAATTTTGGTGCACGACTAAAAAATTCTAGAACACTATAGTTGCATTTTTTGGGCC -GGAAGAAGAAAAACGCATGTAACTTTAATGTCAAATAAAGTTTTCACCTAGTAAGCGCGA -TACNNNNNNNNCACAGAAATAGCCATAGGAAAGTGAATTTTGTCAGCCGACTAAAATTAA -GGTTAGCTTACAAAGCAGCAAAAAATTTGACATCGCACGGTATTCCCTGAAAAAGGAGCA -GGCAGGTGCTGTATATTTTTTTCGGTTCCTGCCTCTTACATGGCGTCGGTGTATCTTAAA -TACTAAAGTGAGCTGACTACCCTTTTGAGTGCCCTATGTGACCTCTGATCTCGAAAGTAA -ACAAGAGATACCTAATTTCACAGCCACTTTTTGTTGCGGACACTGACGGGATGTGTTGTG -AATATTTTAAACCTTAAAAGTATTTATTGGTTAGTTATACTTAATTCTTATACGTCCTTT -AAAACCAGTGTGCAGTAAGTCTGTCACACAAAAATATGATTGATGCATTTTCAAAAAATA -ATGGCTTTGAGGTAATTCGTTCCACTTTTGAGACTTATTCACATGTCCCAGCTGGGTGCA -ATCAAAATATACCGGCATTTCAGCAAGGTAACTATATACGCTTTTTTTCTCATGGTTTTT -GAAATCATACCTGCCAAGCTTGCTGCACTTGGAAGGCAACTCCGTTTTTCAGAGATTAGA -TCCNNNNNNNNNNGAAGAAAAGGCAGCCAAGTTACGTCATAGAGAAAACTCCCTAGAGCG -CTGCAAACACTTGTTAGTTTGCAGCTTACTTCACGTGTGGCTGGAAAATTGAAAAGTTAC -AATACGGTAAAAATACTTTGAAGACACTACACTATAACTGCTTGACCAAATTTTTACTCG -TGAAAAATTTGTTCCAGCCGGTCTGTTACTGATATTAAGTTAAGGAATAGTAAACCGTAT -ATTTTTCATCCACGTTTTTGTAGTTTATTTTCGGTTTACTAGCTATGCATTGATTGTCTA -TCAGAGCATATCAAGGTGGTTATGGAGGTGCTGATATTTAATCAATAAAATTATAGAAAT -TTTGAGAAAACAATAATGATTGTTTCTACAATGAAAATCAGTTCATGGAATAGTTGCCTT -CGCACTACTTTTTCACCAGATTAATGGTGCATCAGAGNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNCGATTGGTTTATCACGTAAGTTTCTTATGACATAAGAAGAGGCAAGAAA -CGAAAAGGGAAATATTGCCTACTTTTTTCTTTTCGAACGTAAATAATGACGGGATTTTGG -TGTCANNNNNNNNCGTCTGGATTTTCTCAGAGAAGTACGTTTCGTCGCACAAGCTAAAAT -CATTGACAGGGCATGAGTTACGTCAATCTCTGGTCAATCCATGTCCAAAAAAATTTCTTG -ATTTGTTCAAAGTTTTTGCATAGGCACATTAATTGGTTTAGCGAAGTATACATTCTGAAG -AACATTTTTGGGTGTATTTTCCACATAGAAAATTCGANNNNNNNNNNNCAATGCACCACT -TGTCGAGTATACGTTAACTTTAATGTATTGAAGATGCAAAAATGAAAAGCCTACTTGGCA -TATGGAATTACAATAAATGGTCAATTCCTGTTTAAGCTAGCAGCGGCACTGTCGGTGTAA -ATTTGGGTTTAAACTATTGTTTACTTACTTTGAGAAATTTATGTATCGCCTATATTTTTC -AATAAGTGCGATATCTTTAGCTTTCCACAGAACCCCCCCTCAGGCTATGGACGTGCGGTT -ATATGATCTTCTAATAAAAATCTCTTAGACTACGGTTCATGGAATACTTCTTGACTTCTT -GGCGAAGGAAAGGCGCATAAATGTTGTGATCGAATGACCAGTAATACGTCGTTTGTTCTC -TTGCTGAACAGCGAGGAAGAGATATTCATCCAAATGCATGAACGCAGAATCCTGTAAAAG -TCGTAAAAATGTTAATCGCAATGTTGTAAAAACCGTCAAGGCATTTATCGTTCAAAATGG -CGATCATTGTTACTACTAAACACTTACTGTTAAATTAAAAAGCTGATGTTGCGTAATCCA -TTGACCAATTCATAGGCAATGTATTTCAATGACGCACAAGATTCATAACAAATTTTTTAT -TTACGATGTACCTGTACATTGTGCAGAAGGTCTTCAGAGTGAGTTTAAGCTAGGCTGTAA -ATATTTTAATGTTAAGATGAAATTTAAGTGAGCTGGTAATATCAAGTGAGGCATAATTTG -TTATATGTAGCTGAACTTCAACTTTAAATAGAAAAATTACAACTAACAAGCACCGGATTG -TTTCAGAATTCAAAGTGTAGAAGCTATTATTCTTGCAAAATAAAACGCTTTCAAAGTTTT -CTTCTATAAACATACTTGTGGCAGCTTGNNNNNNNNNNNNNNNNNNNNNNNNNNGTTGGG -TCTCTGAGAACTTTCNNNNNNNNNNNNNGTAAAGTATGATAAAACGGAGCACTTGCCAAA -GTAATTAACGCCCATTAAAAAGAAGGCATAGGAGGCNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNGGCTGCTGACAGATATTCTGCACTTAAAAACTAAAAATATTATACCAACTTTTC -TTTTTCTTCCCGTTCAGTTTGCTTGATTGGCCCAGCTCTTTGAAGAAAGGAAAAAATGCG -GAGAGGGAGCCAATGAGATTTTAAAGGGTATATTACTTATCTTATCGATAAGCAGTATTG -ATATTAAAGGGACAGTTTTATCGTTGGTTAATATGGAAAAAGTGATGACCATGATGCCTT -TCTTAAAAAGAGTATTTCTTTTTATTTCACTTTCACATAAACAGTTAATGACTTCTGACT -TTGAGCCGTTCGAACTCAGTTATATAAAGGTACATACATAGGCNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNGGGAAGTAGCAACAGTCACCGNNNNNNNNNNNNNNNNNN -NNNNNNNTGACAAGCGAACCAGAGTTTCAGCAGGCTTACGATGAGATCGTTTCTTCTGTG -GAGGATTCCAAAATTTTTGAAAAATTCCCACAGTATAAAAAAGTGTTACCTATTGTTTCT -GTCCCGGAGAGGATCATTCAATTCAGGGTCACGTGGGAAAATGATAATGGCGAGCAAGAA -GTGGCTCAAGGATACAGGGTGCAGTTCAATTCAGCCAAGGGCCCTTACAAGGGTGGCCTA -CGCTTCCACCCATCAGTGAACCTGTCTATCCTAAAATTTTTGGGTTTTGAACAGATCTTC -AAGAATGCGCTCACTGGGCTAGATATGGGCGGTGGTAAGGGTGGCCTGTGTGTGGACTTG -AAAGGCAAGTCTGACAACGAGATCAGAAGGATTTGTTATGCGTTCATGAGAGAACTGAGC -AGGCATATTGGTAAGGACACAGACGTGCCCGCAGGAGATATTGGTGTCGGTGGCCGTGAA -ATTGGCTACCTATTCGGCGCTTACAGATCATACAAGAACTCCTGGGAAGGTGTGTTGACT -GGTAAGGGTTTAAACTGGGGTGGCTCACTTATCAGGCCGGAGGCCACCGGGTTCGGCTTA -GTTTACTATACGCAAGCAATGATCGATTATGCAACAAACGGCAAGGAGTCGTTTGAGGGC -AAACGTGTGACAATCTCCGGAAGTGGCAATGTTGCGCAATATGCAGCTTTGAAAGTGATC -GAGCTGGGTGGTATTGTGGTGTCTTTATCCGATTCGAAGGGGTGCATCATCTCTGAGACG -GGCATTACTTCTGAGCAAATTCACGATATCGCTTCCGCCAAGATCCGTTTCAAGTCGTTA -GAGGAAATCGTTGATGAATACTCTACTTTCAGCGAAAGTAAGATGAAGTACGTTGCAGGA -GCACGCCCATGGACGCATGTGAGCAACGTCGACATTGCCTTGCCCTGTGCCACCCAAAAC -GAGGTCAGTGGTGACGAAGCCAAGGCCCTAGTGGCATCTGGCGTTAAGTTCGTTGCCGAA -GGTGCTAACATGGGTTCTACACCCGAGGCTATTTCTGTTTTCGAAACAGCGCGTAGCACT -GCAACCAATGCAAAGGATGCAGTTTGGTTTGGGCCACCAAAGGCAGCTAACCTGGGCGGC -GTGGCAGTATCCGGTCTGGAAATGGCTCAGAATTCTCAAAAAGTAACTTGGACTGCCGAG -CGGGTCGATCAAGAACTAAAGAAGATAATGATCAACTGCTTCAACGACTGCATACAGGCC -GCACAAGAGTACTCTACGGAAAAAAATACAAACACCTTGCCATCATTGGTCAAGGGGGCC -AACATTGCCAGCTTCGTCATGGTGGCTGACGCAATGCTTGACCAGGGAGACGTTTTTTAG -CCGTAAGCGCTATTTTCTTTTTGTTCGTAACTATCTGTGTATGTAGTAGTGTAATCTACT -TTTAATTTACTATGCAAATAGGGTTCAGCATTACGGAAGAAACTGAAATCCCTTCCGCGG -AAGTTTCTTAGTAGTGGCCGTGCGGGGTGAGGAGATTACATGTCGGTAATTAGATGATTA -ACCTAGGCAATTTGAAGGGGGATAGTGGCATTGGTTAGCTCAGATATGATAAGGAGAACT -AAGCAAGGGGGTTAACCACCACGGCTGTAGCACAAGACCGGCAGATGCGATTATTAGCAA -CACATTAGTTAATGCTTTTGATAAAATGTATATAAAGGCTGTCGTAATGTGCAGTAGTAA -GGACCTGACTGTGTTTGTGGTTCTCTTCATTCTTGAACCTTGTCATTGGTAAAAGACCAT -CGTCAAGATATTTGAAAGTTAATAGACAGTTAACAATAATAACAACAGCAATAAGAATAA -CAATAAATTCATTGAACATATTTCAGAATGAGAGCCTTAGCGTATTTCGGTAAAGGTAAC -ATCAGATTCACCAACCATTTAAAGGAGCCACATATTGTGGCGCCCGATGAGCTTGTGATT -GATATCGAATGGTGTGGTATTTGCGGTACGGACCTGCATGAGTACACAGATGGTCCTATC -TTTTTCCCAGAAGATGGACACACACATGAGATTAGTCATAACCCATTGCCACAGGCGATG -GGCCACGAAATGGCTGGTACCGTTTTGGAGGTGGGCCCTGGTGTGAAAAACTTGAAAGTG -GGAGACAAGGTAGTTGTCGAGCCCACAGGTACATGCAGAGACCGGTATCGTTGGCCCCTG -TCGCCAAACGTTGACAAGGAATGGTGCGCTGCTTGCAAAAAGGGCTACTATAACATTTGT -TCATATTTGGGGCTTTGTGGTGCGGGTGTGCAGAGCGGTGGATTTGCAGAACGTGTTGTG -ATGAACGAATCTCACTGCTACAAAGTACCGGACTTCGTGCCCTTAGACGTTGCAGCTTTG -ATTCAACCGTTGGCTGTGTGCTGGCATGCAATTAGAGTCTGCGAGTTCAAAGCAGGCTCT -ACGGCTTTGATCATTGGTGCTGGCCCCATCGGACTGGGCACGATACTGGCGTTGAACGCT -GCAGGTTGCAAGGACATCGTCGTTTCAGAGCCTGCCAAGGTAAGAAGAGAACTGGCTGAA -AAAATGGGTGCCAGGGTTTACGACCCAACTGCGCACGCTGCCAAGGAGAGCATTGATTAT -CTGAGGTCGATTGCTGATGGTGGAGACGGCTTCGATTACACATTTGATTGCTCCGGGTTG -GAAGTCACATTGAATGCTGCTATTCAGTGTCTCACTTTCAGAGGCACCGCAGTGAACTTG -GCCATGTGGGGCCATCACAAGATACAGTTTTCTCCGATGGACATCACATTGCATGAAAGA -AAGTACACAGGGTCCATGTGCTACACACACCACGATTTTGAGGCAGTAATAGAAGCTTTG -GAAGAAGGCAGGATTGACATTGATAGAGCAAGACATATGATAACGGGCAGAGTCAACATT -GAGGACGGCCTTGATGGCGCCATCATGAAGCTGATAAACGAGAAGGAGTCTACAATCAAG -ATTATTCTGACTCCAAACAATCACGGAGAGTTGAACAGGGAAGCCGATAATGAGAAGAAA -GAAATTTCCGAGCTGAGCAGTCGGAAAGATCAAGAAAGACTACGAGAATCAATAAACGAG -GCTAAACTGCGTCACACATGATTGTGATTGAGTACTCACGTTCTCGTGTTAATCCCGCGG -TCTTCTTGTTTTACTAACTTTTCTTTCTCTCATAGCATTCTCTTGACAGTGTTTTATATA -CATCATATGTACATTTATCGAGCCAATCGAGGGCAGCAGTTTAACATCAAGCCGGATTTG -CTCACGCTACTTTGACCCCTTTTCGTTTCGACGGAGAGAAGAAACCGGTGTTTTCCTATC -CTTGCCTATTCTTTCCTCCTTACGGGGTCCTAGCCTGTTTCTCTTGATATGATAATAGGT -GGAAACGTAGNNNNNNNNNTCGACATATAAAAGTGGGGCAGATACTTCGTGTGACAATGG -CCAATTCAAGCCCTTTGGGCAGATGTTGCCCTTCTTCTTTCTTAAAAAGTCTTAGTACGA -TTGACCAAGTCAGNNNNNNNNNNNNNNNNNNNNNNNNNNNNGTTTTAATTAATTATGAGA -GCTTTGGCATATTTCAAGAAGGGTGATATTCACTTCACTAATGATATCCCTAGGCCAGAA -ATCCAAACCGACGATGAGGTTATTATCGACGTCTCTTGGTGTGGGATTTGTGGCTCGGAT -CTTCACGAGTACTTGGATGGTCCAATCTTCATGCCTAAAGATGGAGAGTGCCATAAATTA -TCCAACGCTGCTTTACCTCTGGCAATGGGCCATGAGATGTCAGGAATTGTTTCCAAGGTT -GGTCCTAAAGTGACAAAGGTGAAGGTTGGCGACCACGTGGTCGTTGATGCTGCCAGCAGT -TGTGCGGACCTGCATTGCTGGCCACACTCCAAATTTTACAATTCCAAACCATGTGATGCT -TGTCAGAGGGGCAGTGAAAATCTATGTACCCACGCCGGTTTTGTAGGACTAGGTGTGATC -AGTGGTGGCTTTGCTGAACAAGTCGTAGTCTCTCAACATCACATTATCCCGGTTCCAAAG -GAAATTCCTCTAGATGTGGCTGCTTTAGTTGAGCCTCTTTCTGTCACCTGGCATGCTGTT -AAGATTTCTGGTTTCAAAAAAGGCAGTTCAGCCTTGGTTCTTGGTGCAGGTCCCATTGGG -TTGTGTACCATTTTGGTACTTAAGGGAATGGGGGCTAGTAAAATTGTAGTGTCTGAAATT -GCAGAGAGAAGAATAGAAATGGCCAAGAAACTGGGCGTTGAGGTGTTCAATCCCTCCAAG -CACGGTCATAAATCTATAGAGATACTACGTGGTTTGACCAAGAGCCATGATGGGTTTGAT -TACAGTTATGATTGTTCTGGTATTCAAGTTACTTTCGAAACCTCTTTGAAGGCATTAACA -TTCAAGGGGACAGCCACCAACATTGCAGTTTGGGGTCCAAAACCTGTCCCATTCCAACCA -ATGGATGTGACTCTCCAAGAGAAAGTTATGACTGGTTCGATCGGCTATGTTGTCGAAGAC -TTCGAAGAAGTTGTTCGTGCCATCCACAACGGAGACATCGCCATGGAAGATTGTAAGCAA -CTAATCACTGGTAAGCAAAGGATTGAGGACGGTTGGGAAAAGGGATTCCAAGAGTTGATG -GATCACAAGGAATCCAACGTTAAGATTCTATTGACGCCTAACAATCACGGTGAAATGAAG -TAATGACAAAATAATATTTGGGGCCCCTCGCGGCTCATTTGTAGTATCTAAGATTATGTA -TTTTCTTTTATAATATTTGTTGTTATGAAACAGACAGAAGTAAGTTTCTGCGACTATATT -ANNNNNNNNNNNNNNNNNNNNNNNNCCTTTATTCAACTTGGCGATGAGCTGAAAATTTTT -TTGGTTAAGGACCCTTTAGAAGTATTGAATGTGGGAACAAAGACGACAAAAGGTAGTTTT -TTCCTTGACTATACTGGTAAGATATCGTCTAAAACAAAGCATGGCCAAGAAAATATCAAA -GAATTCAAGAGCTGCTAGACAATCGGATGCTCTTGAACCAGAGGTAAAGGATTTAAGTGA -ACTACCTAGAGCTGAAAAAACCGATTTGACTAATATTTTGATTAGAACAGCAGCCAAGAA -TGAGGCATTGCTGGAAGCAAAGATATCTAAGAAAGCCAATAAAAGTAAGAGGGGCAAGAA -GTTAAATAAAAAGGCTCTGGAAGACAAACTGGCCAACTCTATTTCATCCATGGACAGGGA -TCGTTTAGTGAAGGCCTTGAATTTTACCAATCGTCTGGACGGTAAAATTGCCAAGTCCAT -TTCTCGTGCCAAGTACATTCAAAATACAAGAAAGGCTGGCTGGGATAGCACCAATGAGAC -TATAAAAAAAGAGCTGGCTTTTTTGAACGGAGGGTTGTCTGTGCAGGCAAAAAGTGCTAG -TGAAGGTAATGCTGAAAAGGAAGATGAGGAGATCCCAGAAGTTTTTGACTCTTTAGCAGA -GGATAACACAGTGCAGAAGACTCCTACAAATAGATTCGGTGTCCTGCCAGACGATGTTGA -AGAATAGAAAATTTTCATATGAAAGGTCCTAGGAATACACGATTCTTGTACGCATTCTTC -TTTTTTCTATCTTCTTTCATTCTTTGTACATTAGATAACATGNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNTATATCTGGATGTATACTATTATTGAAAAACTTCATTAATAGTTACAAC -TTTTTCAATATCAAGTTGATTAAGAAAAAGAAAATTATTATGGGTTAGCTGAAAACCGTG -TGATGCATGTCGTTTAAGGATTGTGTAAAAAAGTGAACGGCAACGCATTTCTAATATAGA -TAACGGCCACACAAAGTAGTACTATGAAATTTTCTGCGTATTTATGGTGGCTGTTTTTGA -ATCTAGCGTTGGTGAAAGGCACTTCATTGCTATCCAACGTTACATTAGCGGAAGATTCTT -TCTGGGAGCATTTTCAGGCTTACACTAATACAAAGCATTTAAACCAAGAGTGGATCACAA -GTGAAGCCGTCAACAATGAAGGCTCTAAAATATATGGTGCACAATGGCGACTATCACAGG -GTCGATTGCAAGGATCCGCATGGGATAAAGGAATCGCAGTTCGAACAGGCAATGCCGCAG -CTATGATAGGACATCTCTTGGAGACACCTATTAATGTTTCAGAAACGGATACCTTGGTTG -TCCAGTACGAAATTAAGTTGGACAATTCTTTGACGTGCGGCGGTGCGTTTATTAAGTTAA -TGTCTGGTTTCATGAATGTTGAAGCATTAAAACACTATGCACCCGATACAGAGGGTGTCG -AGTTAGTTTTTGGTCCGGATTATTGTGCTCCTGAAATAAATGGCGTGCAATTTGCCATCA -ATAAGGTTGACAAGATCACACATGAATCTAAACTAAGATATTTGCAAGAGATGCCCCTGT -CAAAATTAACTGATACCTCGCAATCTCATCTGTATACGCTCATAATAGATGAATCAGCGC -AGTCTTTTCAAATTCTTATAGACGGTAAGACGGTTATGGTAAGAGAACATATCGAAGACA -AGAAAAAGGTCAATTTTGAGCCACCCATTACACCGCCTTTAATGATTCCTGATGTTTCAG -TAGCGAAACCGCATGATTGGGATGATCGCATCCGAATCCCAGATCCTGAGGCGGTGAAGC -TCAGTGATCGGGATGAACGAGACCCATTGATGATTCCACATCCAGATGGCACTGAACCAC -CAGAATGGAACAGCTCCATCCCCGAATACATTCTTGACCCAAATGCTCAAAAGCCCTCGT -GGTGGAAGGAACTTGAGCACGGGGAATGGATACCGCCCATGATTAAAAATCCTCTTTGCA -CTGCAGAACGTGGTTGTGGCCAGCAGATACCAGGGCTGATAAATAATGCCAAGTACAAAG -GTCCAGGCGAACTCAATGAAATCATAAATCCCAATTACATGGGGGAATGGCATCCACCGG -AAATTGAAAACCCGCTATACTACGAAGAGCAGCACCCATTGCGCATCGAAAACGTTATCA -GTGGTGTGATCCTCGAGTTTTGGAGTGGATCTCCAAACATGTTGATAAGCAACATTTATG -TTGGTAAAAATGTAACAGAGGCGCAAATTATTGGGAATAAGACTTGGCTGATGAGAGACC -GCGCGTTTAGAGGCTCCGATGGCCCCACAGAACGCAAATTCATGAATAGCAGACTAGGAA -ATCTACAAACAACTTTCCATAACGAAAGAGAATCCCCTAATCCATTTGACCGCATTATAG -ATCGCATATTAGAGCAACCTCTGAAATTTGTGCTTACTGCGGCCGTCGTGCTCTTGACGA -CGTCGGTTCTTTGTTGTGTAGTATTTACATAGTGGACAAGTGTTAGTTTATAACATGGTC -TCAATAATTGCACCACAACGGCTTCTCTTTTATAGATGGTTAACATTATAGTATCAATAT -TATCATCATGATTAAATGATGATGTATAATACTTACCCGATGTTAAATCTTATTTTTTCA -TGCAGTAAGTAATCATGCAACAAGAAAAACCCGTAATTAAGCGAACATAGAACAACTAGC -ATCCCCGATAAGACGGAATAGAATAGTAAAGATTGTGATTCATTGGCAGGTCCATTGTCG -CATTACTAAATCATAGGCATGGAAATTTCCAGTTCACCATGGAACGACGGTGGATACAGC -CCCTATGAGAGAAACAGAGTCGCTGTATCACCATTTTCATCAGCGTTGGAAGGCGAAGAA -CGAATAGAAACCTCTCGATCTTTGGGTGATCATTGCTTTGAACCTTTGCCATACGTGACG -AATTATCTTTCTATTTTCGCGCTTTTTGGTAAAGAGATATTTGGTGACAAGGGAAATGTG -AGCTCAAGAAATGAATATTTGCTAAAAAAATACTACTCTTTGAAAAAGCCATTTGTATTG -CGACATAATGGGCATGCGTTGAAGAATCCCGACATGCCACTCCAGAGGAATGACATATTG -CAAACCAATTTCATGGTTGACAAATTTCTGAATCGTACTGTGCGGTCAGTGAATTTTAAT -AATTTCAAGATAATATCAGATATGCAAAGTAAAAGCGGTCGAGGAACAAAGTCAGGCACA -AATCAGAATCAAAGTGCCGACGCTATTCAAAATATTTGTCTACCATCTATACCGTCGGCG -TTGCCTTATTTCCAGTATTATAGGAAGCTATTGACAGTTAATACCAAAGAATGGGATATT -TTAAAACTGCACAGTTTATGGGTACCAAAGCTAAGGAAGGATTTTAAAGATTTTTCGTTG -TATGGTGATAAAAACTCTTTAAAGCCGATCGATAGTCACTATGATGAGGATAATACCATG -AAGAAAAATTTATTTTTTGAAAGATCTCCAAGTCGACAGACTCTAGATGGTAAAGGGTGT -GCCTCTAAGGGGTATGACATTTCTTCCGGTAATATGATTATCCCATCCCTATTTTCTGAA -GATAAGCTGCCGGCTTTAACTTATCATTGTTCCGTAGAATTAAATGGAAACATTTACATA -TTTGGGGGATTGATGCCATGCTACAGCTATGAGGAGGATGCGCCGATGCTGAACGATTTT -TTTGTAGACGGAATAAAGAACTTACCTCCGCCTTTACTACCTCAAGTGATTAATAATCCA -TCAATGGTCAATAATCCTCATCTTTATGTCGCTTCTATACCATCATGCCGGTTTAGCAAA -CCTAAAATGGGGGGTTATATACCGCCTCCATTGCTATGTGTTCAAGGATCCAAATTAACG -GACCGACATATTTTCTTTTATGGCGGATTTGAAATCAGGACAGAAACCCGTGGTGATGAA -AATGGGAAGTATCATCTCAAGAAAAGATTATATGTGAATAACACTGGTTACATACTCGAT -ATTATGTCGTTCAAGTTCACTAAAATAGATATCATAGTACAACCTTCCAAATATAATGCA -TATCCGACAATGTCATCGAGGTTTGGTCACTTACAAATTTCTATTGATAATCCAAATAGG -AGAGCTAGCGTTCATTCTTCAAGCATGAACGAAATTCATAAAATGGGGAGTGCTTCCATG -AAACAAGGTAGCAGCATCACTTCCGGGCGGCTTGAAAAAGCAGCAGTACTTTCATCATTA -CCTCATAATACTGTGCACACGGTTATAATATTTGGTGGTTACAGACAAACCGGTGATGAT -CGTTACGAAGCAATGAATGATTTGTGGAAGATAGAGATACCCGTGATACGTCGCGGTAAA -AAAGGTTATTGTAAGTTTTCAGAGACAGCTAACGCGATACTACTGACGCCAAGCGAAAAG -GACAAATCGGATTGGCCCGAAGAAAGAGCCTTTTCTGCCTTTTCTGTTCATGGGACTTCG -TTAATGGATAGGAGTTCTCTTGACATGAGACTATTGAACAACTTAAAAAACCATTTTGTT -TTAAAACCGTCATATATATCACAGGATCGCGTTGTTAGTCCTAAACCGGTTTTCCCCATG -ATGGTTCATGGCACGCATCAAGATCTTTTCAATAGTGGCTCTGCGGCACAAGAATCGCCC -AAAGCTGGTGCCTCGGCCAGCAGCGCAAGTGCTGCGAGCTTTGATCCCGATATGGACGAT -AATTTGGAAAATTATATAGTCAATCCAGGGAGAAAATCGTCATCTATTCCAATGACTGCG -ATAGGGAGACAGAGATTAATTTTAAGCCAAGAGAAGCCAGTAGGTAAAACTGTTGTATTG -CATGGTGGGTCTAACGGTCTCAACGTTCTTGATGATATGTGGTTGATGGACTTAGAGTGT -GAGACATGGACTCCAATAGAGACATTTGCAAAGGCAGATTCGAGCGAAGACGGTGATGAA -AAATTGGATAGTGTGAACGTAGGTCTCGTTGGCCACAGAATGGAAAGTATTGGACGAATA -TGTGTATGTATAGGTGGTATGGTACAAGAGGATGTTGACCAATTTTACTCGGAGAATGAT -GATGAGCCTCCTCGAAAACGCAAGGTCGATACATTACCGTTGGGTGGTAATTTTTTGAAC -ACAATTGATTTAAGCACGCAGTGTTGGGAAGAACATAAAATTACTCTGTCCAAGAAGGAA -GACGATGAGGACAGACAAGATAGCGAAAATGAAGATACAAATTCAAATATAGTAGTTGGT -GTCGGTGGCACTTCTTTGCAATGTGACAAAAGTATTATTTTGATTGGCGGATTGATATCT -AGACGGAGCAATGTAAAAGAAATATATTTACATGGTACCATAACGAAAAGTATTTTTCCT -AGCGTAAATCCTAGTGCATAAAAAGGCAGTTTTCAATGCTTTCACTTTGTAAACTTTGTT -TAGTAGTAGAATATAATATATTCAGTTTTGTTTTATAGTCACATAACACTTTGTCTTTCA -AAGAATAATCTCCTTCGCAATACCAGCGAAATATTTTGGCAAAAAATTAACAATTAGGTT -CATAGTCCCCTAATTCAATTAATCGNNNNNNNNNNNNNNNNNTATAAGGGAAGATTGTGC -TGATGAAATAGACAATGAAACAATAATGAAGAATAAAGAAGAAGAAGATATAAAACATGC -CACCACCATCAAGAAGTAGAATAAACAAAACAAGAACATTAGGAATAGTGGGTACAGCTA -TAGCAGTGTTGGTCACGTCCTACTATATATATCAAAAGGTGACAAGTGCAAAGGAAGATA -ATGGGGCACGACCTCCAGAGGGTGATTCAGTAAAAGAGAACAAAAAGGCAAGGAAGAGCA -AATGTATTATAATGAGCAAGTCGATACAAGGACTGCCCATAAAGTGGGAGGAGTACGCCG -CTGATGAAGTGGTTTTGCTGGTACCTACGAGCCACACTGATGGATCAATGAAACAAGCCA -TTGGGGATGCCTTTCGCAAGACGAAAAACGAACACAAAATCATATATTGCGATAGCATGG -ATGGATTATGGTCATGTGTAAGACGGCTAGGTAAATTTCAGTGCATATTGAACTCCAGGG -ACTTCACAAGTAGTGGTGGTAGCGATGCAGCAGTCGTTCCTGAAGATATAGGCAGGTTTG -TCAAATTTGTTGTTGATAGCGATGTAGAGGATGTGCTGATTGACACTTTATGCAATTAAT -GTAGAAAAGAGTTTCTTGTAACANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNCAGCTCGGTTATAAGAGAACAAAAACACACGNN -NNNNNNNNNGTCGTCAATATAAAAAGGAAAGAAATCATCATTACAACTTGACCGAATCAA -TTAGATGTCTAACAATGCCAGGGTTTGACAATGTAGAAACGTCGCCTAGTTGGTCACTTT -CTCCTGCTAGGATTTTTCTTAAAATACGTCTCATAATTTTGCCGGATCTTGTCTTGGGCA -AGTCATCCACTAAAATGATCAATTTTGGTGCGGCAAATGGCCCGATGTCTTTTCTAACAG -TAAAGACCAAATGCTTCTTGATATCTTGTAATTCATCATCTGTTGCGGTGGACCAACTAG -ATTTGTTTTTCAACACCACAAATGCAGCAACTGCTTGACCAGTCAAGTCATCGTTGAATC -CGACAACAGCACACTCGGCCACAATTGGATCTTCGATAATAGCAGCCTCAATTTCAGCGG -TAGACAGACGGTGACCAGAGACGTTCACCACATCGTCTACACGACCCAAAATCCAGATAT -AACCATCCTTATCCTTTGCAGCACCATCACCAGTGAAATAGTAGCCAGGGTAAGGGTTCA -AATAAGTGTCTAGATACCTATCATGATTTTTCCAAATAGTTCTTGCAAATGATGGCCATG -CAGCTTTGACGGCAAGGACACCCTCTGCGTGGCTGGTGTTAAGTTCTTCACCAGTGTTAG -GGTCAAGAACAACTGCATCAATACCGAAGAAGGGGAATGAGGCAGAACCCGGTTTCATTG -GTGTAACACCACCAGCCAGCGGGGTGACCAGATGCGAACCAGATTCTGTTTGCCAGTAGG -TGTCTACAATGGGGATTTCATTTTTACCTATTTTTTCAGAGTACCACTCCCAAACTTCAG -CAGCAATTGGCTCACCGACCGAACCCAAGCAACGCAAAGATTTTAAGGAATGATTTTCGA -TGTAGGAATCACCAGCTCTTTTCAACAAACGCAAAGCAGTTGGCGCAACATAAAATTGGG -TGACTTTGTGTTCATCAATAATATCCCAATAACGGGAGTAATTTGGGTACGCAGGAGTCC -CTTCAAAGACCAAAGTGGCACAACCATATAGTAAGGGACCATAAACCACATAAGTGTGGC -CTGTAATCCAGCCAATGTCTCCAGCTGTGAAGAAAACGTCTTCTTGGTGAGTGTCAAAAG -TGTAGCGCATGGTCAACAAAGCTCCCAGCAAGTAACCTGCGGTAGAATGTTGAACACCCT -TGGGGGCACCAGTAGAACCAGACGTATACAACAAGAATAATGGATCCTCAGAATCAACGG -GTGTGCATGGATAGTAGGTCTTGTATTTCTTCTTTTCTGTTGCCCAATCCAAATCTCTGG -GGGCATGGAAAGCAACAGATGGATTGTTGGTCTTTCTATAAACCAAGACGTGTCTCACGC -CTGGGGTCTCTCTTAGCGCGTCATCAACAATTCTTTTAGTCTCAATGACTTTACCACCTC -TGTTGGATTCATCTGTAGTGATGACAACTTTAGAGTCCCCATCGTTGATACGATCTCTCA -AGGAGTTGGAAGAAAACCCGGCAAAGACTACGGAGTGAATGGCACCGATACGGGAAATGG -CCAACAAGGTTATGATTGCTTCTGGGACCATAGGCATGTACACGGCAACAGTATCGCCCT -TGCGAACGCCCATAGAGTAAGTCAGCACTTGTGCCACTTGACAAACTTCTTCAAGTAGTT -CCTTGTAGGTAATGGAATAGCCTTGGCCAGGCTCGTCACCTTCGAAAATAATGGCTTTCT -TGTTAGGAGTCTTCAAGGCATGTCTGTCAACACAGTTGTAACAGGCGTTTAATTGGCCGT -TGAGGAACCATGCATTGTTCTGGAAGGAGGGCCTGCCCGTTTTAGGGTCTGGGATGAACA -CCTTATCGAATGGCTTAGACCAGTTTAAAAATTGGGTAGCTTTAGAACCGAAGAACTTAG -CAGGGTCTTCAATAGACTCCTTGTGCAAGCGCTGATAGTCCTGCAACCCGTCCAAGTGTG -GAGAATAGTGGGTAGCAATTGCGGGCTGCAGTCTATCTGAGATGGGCCGTTGTGGCACGA -TCTTGACCGAAGTCAAATGTTCATACTCATGTTCCTTCTTCTGCTGCGCAGTGGCGGCAG -ACTGGGACATTTTTGCTTTCAACTTGTCAATTTCACTTGACTGTTCTTCTAGTTTTGATG -ATTGTACGGCAGAGGGCGACATAGCACAGTGGGCAATGTCTTTCTAGTAGTTTTGATATG -TTTGGTTTTGCTTATAGATAGAAAATATAAGAACAAGATATAACGTACTACCAGATAACC -TAAGGGAGAAATATGCTTAGAATAGCCGCCCAGTTTATATACAAAATGAAGGGAGAACTA -TTTGCCACCGAGGAACTGTACCCCAACTGCAATACCCATTGAATAATGGCATCGGAGGCT -CGGCGGCAATTCGTACCCCAACCNNNNNNNNNNACTTTTCTTTGGATCTTAGAGATAACA -GAAAAAAAGGATGACCCCAATCATTTGCCACGGCATGTCAACAGGTGAGTGCCTTTTGAN -NNNNNNNNNTCATCTCGACATCCGGCGAAATGGAGCAGTCACACGTGAACATTTTTAGGG -GATGGAGAGTGCTACGCCGTTCGTCCGAGATGATTATCATATTTACACAGCCGTACATAC -ACGTGCCATTTATCTTGATATCATTCTGGACGTATGTGCACATGTGATTTGCTTTTGTTT -TTTTAAGAATGTCGGGTAATAAACAGATTGTTTTTCTGGGAGGATAATCTTTTCTTTTTT -CCTGTTGGTATTCTAAAATTAACCTTGCTGTTTCNNNNNNNNNNNNNNNNCGCGCGACTA -CTCAGCCATCTTGCATTTTTAAAGAAAAAGATAATCATTAATGCCTTCACGGGAATACGT -ATAGAACATTATTAAAAGTATATGAATGGCATATATATATAGAACACCACCCTTGGAAAA -CATTTATACCCCTTAAACTAAAACAATTTGCTGCGCTATACCGTGTTTCAGTGTATTATA -ATACATTCATTTCTGTTTCATTACGATTATATTGACGTGATAAAAAGATTATATAGCCAT -GATCTTCCTAAACACCTTCGCAAGGTGCCTTTTAACGTGTTTCGTACTGTGCAGCGGTAC -AGCACGTTCCTCTGACACAAACGACACTACTCCGGCGTCTGCAAAGCATTTGCAGACCAC -TTCTTTATTGACGTGTATGGACAATTCGCAATTAACGGCATCATTCTTTGATGTGAAATT -TTACCCCGATAATAATACTGTTATCTTTGATATTGACGCTACGACGACGCTTAATGGGAA -CGTCACTGTGAAGGCTGAGCTGCTTACTTACGGACTGAAAGTCCTGGATAAGACTTTTGA -TTTATGTTCCTTGGGCCAAGTATCGCTTTGCCCCCTAAGTGCTGGGCGTATTGATGTCAT -GTCCACACAGGTGATCGAATCATCCATTACCAAGCAATTTCCCGGCATTGCTTACACCAT -TCCAGATTTGGACGCACAAGTACGTGTGGTGGCATACGCTCAGAATGACACGGAATTCGA -AACTCCGCTGGCTTGTGTCCAGGCTATCTTGAGTAACGGGAAGACAGTGCAAACAAAGTA -TGCGGCCTGGCCCATTGCCGCTATCTCAGGTGTCGGTGTACTTACCTCAGGGTTTGTGTC -TGTGATCGGTTACTCAGCCACTGCTGCTCACATTGCGTCCAACTCCATCTCATTGTTCAT -ATACTTCCAAAATCTAGCTATCACTGCAATGATGGGTGTCTCAAGGGTTCCACCCATTGC -TGCCGCGTGGACGCAGAATTTCCAATGGTCCATGGGTATCATCAATACAAACTTCATGCA -AAAGATTTTTGATTGGTACGTACAGGCCACTAATGGTGTCTCAAATGTTGTGGTAGCTAA -CAAGGACGTCTTGTCCATTAGTGTGCAAAAACGTGCTATCTCTATGGCATCGTCTAGTGA -TTACAATTTTGACACCATTTTAGACGATTCGAATCTGTACACCACTTCTGAGAAGGATCC -AAGCAATTACTCAGCCAAGATTCTCGTGTTAAGAGGTATAGAAAGAGTTGCTTATTTGGC -TAATATTGAGCTATCTAATTTCTTTTTGACCGGTATTGTGTTTTTTCTATTCTTCCTATT -TGTAGTTGTCGTCTCTTTGATTTTCTTTAAGGCGCTATTGGAAGTTCTTACAAGAGCAAG -AATATTGAAAGAGACTTCCAATTTCTTCCAATATAGGAAGAACTGGGGGAGTATTATCAA -AGGCACCCTTTTCAGATTATCTATCATCGCCTTCCCTCAAGTTTCTCTTCTGGCGATTTG -GGAATTTACTCAGGTCAACTCTCCAGCGATTGTTGTTGATGCGGTAGTAATATTACTGAT -CATCACGGGACTTCTGGTTTATGGAACTATAAGGGTTTTCATCAAGGGAAGAGAGTCTCT -CAGATTATACAAGAATCCTGCGTACCTACTTTACAGTGATACCTACTTCTTGAACAAGTT -TGGGTTCTTATACGTTCAATTCAAAGCAGATAAGTTTTGGTGGCTTTTACCCTTATTAAG -TTATGCGTTCTTAAGATCCCTGTTTGTTGCCGTTTTACAAAACCAAGGTAAGGCTCAAGC -AATGATCATCTTTGTCATTGAACTAGCTTACTTCGTTTGTCTCTGTTGGATAAGACCATA -TTTGGACAAGAGAACTAATGTTTTCAATATTGCTATTCATTTGGTGAATTTGATCAATGC -ANNNNNNNNNNNNNNNNNCAGTAATTTGTTCAAGCAACCAGCAGTGGTTTCGTCAGTGAT -GGCGGTTATTCTGTTCGTTTTGAACGCGGTGTTTGCTCTATTCCTATTATTGTTCACTAT -TGTCACCTGTACACTGGCATTACTACACAGAAACCCAGATGTCCGTTACCAACCAATGAA -AGATGACCGTGTGTCATTCATTCCTAAGATTCAAAATGATTTCGATGGCAAAAACAAAAA -TGATTCTGAACTGTTTGAATTGAGAAAAGCTGTTATGGACACCAATGAAAATGAGGAAGA -AAAAATGTTCCGTGACGACACTTTCGGCAAGAACCTGAATGCAAACACAAATACAGCAAG -ACTCTTTGATGATGAGACTAGTTCATCCTCTTTTAAGCAAAATTCCTCTCCCTTCGATGC -CTCGGAAGTAACGGAGCAACCTGTGCAACCAACCTCCGCTGTCATGGGTACGGGTGGCAG -CTTCTTGTCTCCACAGTACCAACGTGCGTCATCTGCTTCTCGTACTAATCTAGCGCCGAA -TAATACAAGCACCTCCAGTTTAATGAAGCCTGAATCAAGTCTCTACCTGGGGAATTCCAA -TAAATCATATTCGCATTTTAACAACAACGGCAGCAACGAAAACGCCCGCAACAACAACCC -ATATTTGTAATCCAATATATACTCACATGTAACAACTTATTATATAAATATTTAAGGGCA -AGGATATCCTACATTATATTTCATAGAAAACCGCTCAAAAAGGTGTATTATCTCCATTAC -ATCCCAACACCACACATATTTCAGCGATAAAAACCTTAAATGTGAAATTCGCTTTGGCTC -TGCTTCCTTAAATGTACGCAATTGCCGCTTTTTTCTGACATCTTTTTTGACGTGTAGAGA -AGGAAACAGATCCTCCAGAAGGGATTTACTGTTGGCTATTTTGTGTTAGAAGCAGGTTAA -TAATAGATTAGGTTGCGTAAGTCATGGTCGAAAATAGTACGCAGAAGGCCCCACATGCCG -GAAATGATGATAATAGCTCTACCAAGCCATATTCGGAGGCGTTTTTCTTAGGGTTCAATA -ACCCAACGCCTGGATTAGAAGCTGAGCACTCAAGCACATCGCCTGCCCCCGAGAACTCCG -AAACACATAATAGGAAAAGAAATAGAATATTGTTTGTCTGCCAGGCTTGTAGGAAGTCAA -AAACAAAGTGTGATAGAGAAAAACCTGAATGTGGTCGATGCGTCAAGCATGGGTTAAAAT -GTGTTTATGACGTATCAAAACAGCCAGCACCACGAATTCCGAGTAAAGACGCCATTATAT -CAAGGTTGGAAAAAGATATGTTTTATTGGAAAGATAAAGCTATGAAGCTACTAACAGAGA -GAGAGGTGAATGAATCAGGCAAGAGATCAGCAAGTCCGATCAATACAAACAATGCTAGCG -GGGACAGTCCTGATACCAAGAAGCAGCATAAAATGGAACCTATATATGAACAAAGTGGTA -ACGGGGATATAAACAATGGTACCAGAAATGATATTGAAATCAACTTGTATAGAAGTCATC -CAACCATGATCATGAGTAAAGTCATGAAAAGAGAAGTTAAGCCGTTATCTGAAAATTATA -TTATAATTCAGGACTGTTTTCTAAAAATCCTGGTCACTTCAGTGTTCCTTGACACTTCAA -AGAACACGATGATACCGGCATTGACGGCAAACGCGAATATTACAAGAGCCCAGCCTAGCG -TAGCAAATAACCTTTTGAAATTGAAGGAAATGCTAATCAGACAGTGTCAAACCGAAGATG -AAAAAAATCGTGTAAACGAATTCACTGATAGAATACTACAAAATACAAATTCAAATAGAA -ACTTGAAAATCGGTATGCTATTATCAATGCTTTACAATTCTGTCGGTTACCAATATCTGG -AGGATCATTGCCCTCAAGGTGGCGAATATTCGGATTTATTGAGAAATTTGATCAATGAAT -GTGAAGCTATTTTGCCATCTTACGAAATTATTGAACGCTACAAGAACCACTTTTATGAGT -ACGTTTATCCAAGTCTACCTTTCATCGAATTAGAAATTTTTGAAGAATCATTAAGTCAAA -CAATTTTTCCGGACCCAAACAACCCCTCCAAGGTGCAAATACGTATGGGTAGCACACATT -TGAGAGCTAAGGTGGAAAACTTGAGTCTTCTATTGGTTATCTTGAAACTCTCATACATGT -CAATAAGGTTTTTAGATCATAGTACAGCAGACTCGAGTTTTTATCTTTCAAAGGAAATAA -TTGATAAATACCCAATACCGAACGATTTTATTTTATTGAGTCAAAGATGTCTAGCATCGG -AAAATTGGTGTGCATGCGCTAATGAAAACATCATATCATGTTTACTATATATCTGGTCNN -NNNNNNNNNNNNCTCCTGAAGAGGGTGATTTCTTTCTCGAGCACCCCACCGATGTTATCA -GTAGTTTGATAATGATGCTTTCCACCTCGATTGGTCTCCACAGAGATCCTTCAGATTTCC -CTCAATTGATTTCCCCGTCCACCTCAGATAAAAGAACCTTGAATCACAGAAGAATACTCT -GGTTGAGTATCGTTACCGTTTGTTCGTTTGAAGCAAGTCTCAAAGGTAGACATTCTGTCT -CACCGATATCTTTAATGGCCTTATTCCTAAATATTAAGGATCCTGATTCTCTGACGGTAT -ATATGAACCGAGTTAGGGGCGATCTAAGCGATATCAATAATCACAAACTTTTGAGAATTC -ATAAATTTACATTCAAGAGAGCCCAGCTTGCGTTACTCCTGTCGGACTTAGATAACTTGA -CGATGACATACTATGGTAGTTTCCATTTGCATTCAATTGAATTCATAAGAGAAAAGATTG -AGATTTTTGTGGAGGAAAACTTTCCCATAGTACCATTAAAAAGTGTCGCACAGGATAAGT -CAGACCTTGATGACATGAATGTGATTTCAGAAATGAATATATTATCTTCAGAAAATTCTT -CTTCATTTCACAATCGAATAATGAATAAACTATTGATGTTGAGAACTTCAATGGCCGTAT -TCTTGCATTTTGAAACACTTATCACTAAGGATAAAAGTATCTTCCCATTCTACAAGAAAT -ACTTTATGGTTAGCTGTATGGATGCGTTGTCACTAATAAATTATTTCAATAAGTTTTTCA -ACGGAGAATATCGACACGCAATATCTTCTTTAACCAGTTTTAATGTTACAAAATTTATTC -AGTTAGCACTATCCAGCACAATCTTCAGCCTATTAGGGATTATACTAAGAATAGGTTTAG -CCATCCATATGTTATCTTCTGAAGTACAAAAGTTATCGGGAACGACAGATCCAAGAATAA -AGGAGTTAAATACCAAAGTCGAAAAATTTAGTACCCTGCAAAGAGATCTCGAGTCTGCTT -TAGAAGGTATATATTGCTCTGCTTCGGAACATTTAAGATTCACATACTTCCCCGTTTTTA -AGATGTTGGCTTTATTCGATGTCATTGTACAAAGGATGAGAAAGGGTGAATTATGGCACG -GCATATTTACGATGATTCAAATGGAACAAATGCATTCTAGGATAATCAAGACATTAAGCA -TTACCTTAGGAGTCAAACTGGACAAAAAGGATAGGCTATTAGAGGAATTGATGGCATGCA -ATCACGTTGCGAATTTTAGCGTTGAAGATATAGATGAGCTGAACCGTAATATCAAAAAAG -AGATTCAAATTTCTTCAGGATTGAAGCCGCCTGTAAACACAATTGACTTAACCAACGGCG -AACCATTCGGAAATGCTGTTCCTACCTTCACAAAGACATGGAGTTCATCCTTAGATAATT -TAGAAAAACTATCATCGGCCGCTGCAGTTGGTCAGAGCTTGGACTACAACAGTGGTTTAC -GTCAGGGTCCTTTGGCGGGTGGTGGTTCAAAAGAGCAAACGCCAATAGCCGGGATGAATA -ACTTGAACAATTCAATCAATGCTACACCAATTGTCGATAACTCATCTGGATCACAACTTC -CTAATGGTTTCGATAGAGGCCAAGCGAATAATACTCCTTTTCCAGGTTATTTTGGAGGTT -TGGATTTATTTGATTATGACTTTTTGTTTGGCAATGACTTTGCTTAAAAATTTTCTTTCC -AAACTCCTACCTATTCATTTCATCAATTAATTAATATTATATAGCCACGAATTTATGAAA -CTGACCGATAATATAAAGTGCTCANNNNNNNNNNNNNNNNNNNNNACGGTTAACGTAAGA -AGAGCTCTTCCCTCTTAAACATTCGAAAAATGATTGAACCAGTATATTTGGTCGAGCAAG -ACTTTCTCCTTCGCATATTTTACGGCAGGTATGGATATATCGCCTCTTGCTGCAAACCCG -TGAGCCACACCACTGAAGAGGTCTAACTGGTAAGTAGCGTGATTATCCTTTAATTTTTCC -TCCGTTAAGTGTCTTAAGTTTGCCGGAAAGATGTGATCCTCTTCCGCTGCTGAAATCAAT -ATTGGTTTCTTGCTATCAATTGCTTCAATTTCCTCGATGCTGACGAAAGATGGATGTGCA -ATGGCTGCAGCATTGGCAAGACCCCCGTCGCCACTAATGTGTTGGACGGCAAACTTTGCA -CCAAAACAGTAACCCACAACGCCAATAAACTTTGGGTCATATTCAAGTTTTAACAACTTC -ATGAATCCATCAACAATTTTCTTGGTGACTTCAGGAGAATGTCTTTGAAACCAGGCATCA -CGATCAATTGGTTTGTCCGATGAGATAGCATCGCCGAATAAAATATCGGGAACAAAGACC -ATGTACCCAGCACTAGCAAATTTGTCGGCCGTTAATAAAACATTGTTGAATTTATTGCCA -TACACATCTGTCAAGATAACTATAACTTTTTCCTTGGGAGATGTAGAGCCTGCTGCATAA -GTATCTAAACCGAAGATTTCTTCACGACGACCCTTGGGTGTTCCATCGTGACAAACTCCT -TCAAAGCAACACTTGCCAGGTTGATTAGATGCCATTTGATTGAAATAATTTTGTTCTGCT -GTAGTTAGACGTAGTGGAAAACTTTAAGTCTACTGAGTCTTGAGACCTTATCACCCTTTG -AAGGTTTCTTGCAAATGAGCGTGGTTTGGCATTTTTTATCGGAAAGAAAAAAAGGGCTCC -GCCTTAGGCCAGATATCATAGAAATGCAACACTTCCCTAATATAGAAATTTGGGCATTAA -TTATTTTGAGAATTTTGATGATTTGAATAATTTCATTAACGTAAAGGAACATAGTGCTAC -GAATCCAACAGTGGACCCAAAAATGAGAGCCGTTTGTCTGTAGTCGACATCTTTTGCTGC -TGTTTCTTCTGGCAATCCCGGAGTGTTTTTGCCAGGATCAAGAGCAGCTTCTGTGATTTT -AATAAACAATTCATTAAGGGAACTTAGCCATCTGGATGATATGTGCAGTGGGTGGTTCAC -AAATAGCTCGTCTGCCAGTTCATCTGGTTGGATTTGACACCTTTGTTGCTGCTTATCCAA -ATCTGCCTTAGAAGCTACAAATACCAACGGTAGATCTTGTAAATGTGTGAATTTGTCTAG -AAGCGAAACTAAGTAGGAGAATGATTCTGGGTCGCTGGAATCGTATGTTAGACAGATTAC -GTCACATTCTTTTAACTTATCCTTATTCTCTAGTATGGCGTATTCCTGTTCTCCAAGTTC -TTGCAAAATCAAATAGTACTGTTTCCCACCTTTGAGTTCTAAACTATTGACTGCAATTCT -TGGTTTGATTGTCGGAGAATACTCCTCCGAGAAAGATCTGCCCAAGAAGGCCTCTAGCAA -AGAGCTTTTGCCGCAACATGGCTTTCCAATGACAAAGCAATTGAACACTTTTCTGTCATT -GATATTGGATCTGTAAAGTTTCCCGGAACGGCGTCTCATTTTCCTTGGCTTGGTTACTTG -TAGGGCTAGTCTTGCATCTTCCTGAAAGCCAAAATACACCAAGTAAGCGGTAGTTGTGCT -ATAGTTCAAGAAAGTCGTCATACTCCATTGTGCTAGCCAGCCTTGTAAGGTGATGCAACC -CTTGTTGTTTACGACAGTGGAGAAGGGGAAATTCGTTGAGGTCCATAGTTTAGGCAGCCC -TGGTGTGCACTTAAATAGACGATGTAATTCTTGATTATTCAAACCACCATCATTGTCGAT -ATCAAACTTCAAAAAAATATCTACAAGAAATCTGTAGCCCTTGGGGCTCAATTCCACACT -GGAAGTGTCAGGGACAACCAACCTCGGATGGAGAATTTTGTCATTAATACACAAGGAATC -TGTGTAATGGAAAGTTCTTAGGATAGCCCATGTAGTTTCGTGTCTCCCCCTTTCAGCGTA -TATTTTGTTCAGTACAAGGAAACCATCTTTGGTGATGCCTTTTCCCGGTACGTATAGCTT -GCGGTTAATGTACTCTTGATCGTGCTTGGAAATATCCAAAAGCAAATCTTTAATAAAATT -CAGTTCGTTTACATCGATACTCTTATTGAAGCACTTTTTTTGTAAGCCCAAGATTTCGTT -GTCATCTAAATATGAGTCCTGGTTTAAATCGCTTAAAAGAAAAATTCTTTTTAAAGCCAT -GACAGCCAATGGCTTTAGTTCACCTACCATGGCATCAAATAAAGGTGATATTGGGTGTGT -TATAGCCCTTTGGCAAAGATAAAACGCTTGGTTAAGATCAAACTGTGTCTTGGCACTTGT -CTTAATGCAAGTGTCGATTTCTTTAAACTCCATTAATATTGGGATAAATTCTTCATCCTC -CACTTTGGTATCGATATCATCATCACTGTTCTCTGACACGACCATTGCATTGGCATTAAC -ATTCGATATGGAATCACATTTATTTTTGCAGAGAATGACAGGAATATTCAACCCCAGGGA -TCTGAAATGAGGCAACCAAAAGAGAGAAACATGGTCATACGATTCGTGATCGCAATACAC -AAGCCAAATTACGTCGGCGGACTTCAACTCATGGTCTAAAGCTATGAGGTCCGAATCTGA -AGTGTCTATAAGTACTGTATTCTTAGGAGAATATGTAGGTGATGATGAGAAATCTCTTGG -GATACTGATGGGTGGCAGCACGTCCTGTATGGTCGGTATGAATTCAGCTTTTGTTAATGA -TACAATCAGACTGGATTTACCAACCCCTTCATCACCGCAAATAACTACCCGAATCGTTTC -TTTAGTCATTGTGTTGTTCAACACATTAGTATTTAGAAGTCCGCTATTTTTGTTTTCAAT -TTTTATTTGTTTAATATACAAATTTCATTCTTGTTTTGAGGGTAAACCACTATACCAAAT -GTTGAAGATCTAAAGGTATCGATCAAATATGTTGCTAGAGAGTGACTGAGTGTTACATTA -AATATATTTATATATAAACGTATGATATTTAGGGATTGTTGATTGATAGGTTGAAAAGTT -TCGATCTCAATGACTCATTTTCCTGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNCGTCTTTCTCTTTCGGATATCCATCTTCTTTGTAACTCCTCTATTCGTA -AGGTCAGTTCTTTATTTGGAGTTGCCGTTAATTCATTGCCCTGTTGATGTGGCTGCTCTG -GGGTTTCCATGGAAATCAGTGAAGAGATATATGAGTTTATTATGGACTCTAATGCAGTCT -CTATAAAAGTGTAGAGCGATTCTAGTTTGGGCTGAATCAAATTCAAGTTTTTCAACGCAT -TTGGTACAGATTTTATGGATTTCATTTTCCTGTCAAATTGGGCAATAGAACTTTCTTGTA -AGATTTTCTGCAGAATATTGAAAATACTGTCAAGGTGTAGTAAAAGGTTCTGATTAAATT -TGATAAAATTGCTTTCATATTGGGATAGTATTAACTTTTGGTTGTCCAAAGTATTTAACT -GATTTTTTAATTGGTAATTCTCCAAGTCTAATTTGTCTAACTGATTTTGTATTACGTGGA -ATTCCTCTGATTTATCGATTTGAAGGTCATTGATTTGTTTTTCCAAGTCATTGATGTAGC -TGTCCCAATTATTTTCCTTTAGTTTATTGATTTTGGTCTGAGTTTCCAGTTCTTTGGTTA -AAACTTTTTCATTTTGTTTCATTTTAATGATGTCTTCCTTCAATTTTTCCAAATTGTTTA -TCAAGACAGATTGCGATTCGATCTTTTCCTTCAGTTGGGAAATCAAATGATCTTGTTTTT -CTATAACGGAACTAGAATTTTCTTCCAATTCTAAGGAATCTAGTAGATGAGACTGCTCAT -TTAGTTTGGACGCTATTATTTTTTCTAATTTTTGCGATTTCTCGAATTTCAATCTAATGG -AATTTATAAATTGATCATATTCTTTGTGCAAATTTTCTATGACAATCTCTAATTGAGTGT -CTAAGGTTTTCTCAAAACGAGACTCGACGGCTGAAATTGGTAAGGAAGTACTGTTTGCCA -TTACATTTTCTGTATCAATGTGGTTGTTACTGTCATGAATTTCGTCATTCTGGTATCCAC -CATCAGTATTCTCCTCTTTACTTGATGGTGAGTCCCTACTTTCTAACTGTGATCCTGCTG -GTGAGGACTGGGCCAGTGAAAGAAATTCTTCCTTATCCTGCTTTGATTCCGCTCGACTTT -TGGAATGCAAAAAGTCCTGCAAGAATTGGATGATGAACTTGGACAAAGTATCCATTTTTT -CAAGAACATAATCCGAGCTCAGCTCTAAAGTTTCCTCCAGGGTCTCCCTCTCTTCTTTAT -CAAGAAGATGGGCATTTTCATCTTGCTCATTAAAATGCGTCAATATAAAGGACAATAGGT -GATTGATCGTATTCACGATACTTTCCGAATTTTCTAAATTCTCTTGAACGAATTGTAGCG -TATCTTGGTACTCGACTTCCTTCGCCTTTAAATCCTGTTTCAATTTGTTTATTTCAAGAT -TTAGACCCTCGATAATCGAATTTCTAAAATCAGTGTCATTGCCCAGCGATGGTGCATTGC -CGTCTTTATTAGGGATTCTGCGAATGTATTCATAGAGTACTTGAATCTTGATTTTGGCAT -TAGTCAACTCCTTCTCCAAATTTTTGACTTTGTTGGAATCGTTCATCAGAGCAGGCTTGA -TGGGATCGTTATGAGATGACCTCGTGGTCATGGAGTCCCTGAGTGATGGTATGGACATCC -CAGAATCCATCGAGTTTGTGAACTCGCTGTCGTCATCATCACCAGTGTTGTCATTATTGC -GAAGATGCCTGCCACTAGGAATCCATCGACGTACCATGGCTATAACTTTCCTTATGTTGT -TTGCTTAGTTTTTTGATATTAGTGTTGCTTATGTGAAATTTCGCGATTTCAATTAAAATA -ATAAATACATATATAAAGAATATACACAGAGGGAAGCAAAAGTAAACTAAAAGTGATACT -TACACGAGCTTTTTTGGTTCCAAACTGTTCATGATGATGCCGGACCCTTCCCAGTTGACT -TCTTAGTGGTCAATTGTAGGCCATGCCATCTGGAAATATCGTCCCTCAAAATTCTGTTCA -CCAGCTGGTGCTGCTTGATGAGACTCAGTCCGTTGAACTTCTTGCTTGTTATGTTGATAG -CAAACATGGATCCGCAGCCACCGGAAACGTCTTGCACTTTACACACTTCAGGTTCCAGTT -CCTGTTGTAGTTTATCGGTGATCATCTTCTCCTCCGGAGTCATTGCCATCTGCGTTGAGT -ACCAAAGCTTTGAGCCCGTCAGAATCCTTGGCCACCGGACATGCTTCACAGATATAGAAC -GTAGCATGGTCTGTGGGAGCTTCATTTCTATGTTTTACCTTCTCTTTTCGCTTTTATGGT -TCTCAGTGACCAAATAAAGAAACTTATATATGTTCCGGAATGACGAATCAAAAAGAGAAT -AGCATCGTTAGCAGCAAACGAAAGTGGAAAGAGAATAATGTTCAAGAGAGCAATGAGCAC -AGATGGTCCCGTGGCACGTACCATCCTGAAGAGACTGGAATGCGGCTTTCCAGATTACAA -GAACTTTGCGTTTGGCCTCTACAACGATTCTCACAAGCATAAGGGCCATGCTGGTGTACA -GGGAAATGTCTCTGCTGAGACACATTTCCGGATTGAGATGGTCAGTAAAAAGTTCGAAGG -CCTGAAACTTCCACAACGCCATCGTATGGTTTATTCCCTCTTGCAAGACGAGATGGCTCA -GGCGAACGGTATCCATGCTTTACAATTGTCACTAAAGACCCCACAGGAGTATGAATCCAA -AGCGAAATAGAATGCATAAGCATAAGTGTACACGTTGAGTTTATTGTTTTATTTCCCCTA -CNNNNNNNNNNNNNNNNNNGAAATTACTTTACGTACGTATAAGCTTTGTTCAGTCATCAT -GAACCAGTGTCTTTTCGTACTGTTCTAAGGACATTAGACCCTCGACCTGTTCCACATTAA -CGCCCTCACCAAGCTTCATTTTGACTAGCCAGCCGTCACCCATAGGATCTTCGTTCACCA -CACCTGGATTTTCCTCAAGATTAGTGTTAATTTCCTCTACGGTACCATCGGCAGGCTGGT -AGATCTCGGAGGCTGACTTGACGGACTCAATGGACCCTAGCGACTCACCTTGGGCAATCT -CAGTGCCCACTTCTGGCAACTCAACATAGGTAGCGTCCCCTAAGGCATCAGTGGCGTATT -TTGTAATTCCGACAAAGGCAGTCTTGTCCTGATGCACAGCTATCCACTCATGTTGGGAAG -TGTACCTCACGGCTTGAGGTCCTTGGGATGAGTACAAAAATGGTAGTTTATTCTTGTTTA -GGGCATTGCCGGAGCTGTTTCTCAAAAACAATTTGCTCACAGTGGGCATGCGGGTGGTCC -ATAGTCTAGTAGTGCGTAACATTGTCGATGTGGTATGCTTCATGTGGAGATTCCCTTTCC -CATTAGATACTTGTTTGTTGGTCTGTATATATAGAAGAAAGAGTTAGCGAAAGTGACTCC -GCCGCTGAATGACTCCTTACGGAAGTGTCAAAATTGCGAGGTCCCTATAGCACAGAATGA -TAGATAAAACATTGATTTGCAAGTTGAAGGAAGACCCTACACATGCGTATATATGATGTA -TGTAATGGTTGTGATCATTTTAGCCTGTCAAGCAGTGAATCGCACTGCTTGTGTAAGCCT -TCATCTTCTTGCTTTAGCTGATGCAGCAGGTCGCGAACAGTGTCCTGCACTGGGGGTCTA -AACATAATGAGAAACTTTAGCGTTTGGAAACCAAGGGAACTTCTTGCCGGATCCAGGCAG -ATAGGCTTCAGTGCCTCAAGATGATCGCTTTGAAGACTGGGCAGTTCGCTCATAAGTCTG -ATGAAGAATCGTCTGTGTTTGTTTTCAAGGAATGGACCCAGAGACTCGAGAACTCTTAAG -GACCATTTTTTGTAGTTAGAGGGATCTTGATGCAGCGAGGTTTGGAAGAACCATTCTTCA -TTGAGCCATTCAATGATCAGACTGACACGTTGCTCGAAATCCTGGATGAAGAAGCCAAGC -AGTTCTTCACGAATCAGGTCACTGGCCTCTTGTGCTTCGATTCCTCTCGTAACCAATCTG -ATTAAGACGTGTAACCATGACGAGGAGTCGTCATCGTCCAGTAATATGGAGGAGGAAGAC -GAAGATTTGGCCCGGGTAGTATCCTGGCGACCGGATAATTCAAACAGTTTCTTGGTCAGC -TTTGAGAGGTACTTTAGTTTTTCATCCTGCGTCAATGAGTCAGGTTCAAAGGGGGGTGCG -ATCTCCTTAATGGCAGAAGTTGATTTGTTGGCATCTCCTGAGATTTCTTGGGCGCTTTCC -TCTTCTTGAAGCATCTTCTGCATTCGGTCATCGTCTTCGGGCTCCTCTGGTTCCTCCGCT -AGTGGTTCTGTTTCCATTTTGATTTTCTTGCTATTAGCCGTTGGGCCATCGTTTCCAACT -TCTTCATTGTCGTTGCCGTCGTCATCATCGTCGGATTTCCTCTTTGATGATGACGAGGAC -GGTACAGAATTGATGTACGTATTCATTAAATCCGTGTACCTCGAAGCAACGATAGACAAT -CCGGTGATCAGTTTCGTGCTGTCCATTTGCAAGATGGCCTCTGTGGACAGCTTGATAAGT -ATGTCATTGGGTAGCTGGGTCACATCCTGGTTGGAGTTCGAACTGTTCATCAATGAGTAC -ACAGATGAGTAGGTGTTGCTGATTGGTTTGGGTGAGTTGTTGAAAAAAGTATTGCCCTGG -TGTGAAGCCTTGTTGAGGGTGTATTTTTGCAATATCTTCAGTTGATCAAGCATGTTTTCG -GTTGAAGAGCCCGTTGCAGGTGCGGACACAGGCGTGGGGGTCTTTGTGGACACCCCTAGA -GTAGACAATAACGCGGATAATTGCCTTTTCCATAGTGAGATGTATTTTAGTTTGTCCTGC -CTGGACAACGTTTTCTTGCTATTGCCCTTGGAAGGGTCGAAGTTCAAAATTCCCTTGCTC -TTGGTCTCTTCGCCAATAACGTGTAAAGTTTGAGAAATCTTGGTCAGCTTGGAGTAGATC -GATGACCCTGATCCGGATGAGAGGGATTTTGTAATGATTTGATTTTTTAGCCCAAATTGC -ACAAAGTTCTTGTACGCCCTTTCAACAAATCTCTTGGATAGTTTGTAGTTCAAGTCAGAC -TTGCCCTCTAGGGGAAACTTGGCGTCGACGTTGAAACGCAACAGCCCGGAAAGAATTCTT -ATTGTTGTCTGCGGCCTTCTTTTGATGACGAAGGATAAAGAATTGATGATACCAATGAAA -ACGGACGAGACCATGTACTGTTCCTCAATTAGGTAGTTTAGCAACATATCAAGAAGCCTC -TTAGCCTCGCTCTCCAAAGCCGGTTTGTTCAACACAGGGTGGTTATCCGGGATGGTAGAT -GAATTAATCTCGTTGCCGCTGGGTGATTTAGTTTGCGACAGCACGACCTCAGATATGAAC -TTGATGGTCGCTAATTTCACGCCGATATTTTGGTCAATCTGCGCCAGCCATTGTTCGACA -TCCGTTTCATCGTCAACGGTGGCACGCAAAGGATATGCAGTTCTCCAGTGCGAGAGCACG -AACTTCTTCAGCATACACAACTGATCAAACATTTCCTGGTTTGATGTCTTAGCAACCAGA -TCCAACACCAGCGGGTATGAAGCGCACATAATAAGCACGATATTCTTGTACACTAGTACG -TCCGCGGTGGATTGCGCCATAGCAAGAAGTAGTGGCAGATATTGAGCAGCAATAAACGGT -CTCTCAGTATTCGCAATTGGAGAGTCCATCGACACCACGTCTAGAACTAACTGTGTAAAA -AACTTGGCCAAAGGCAACTTCAGCTTGCTGAGATTACCGTTGTGGTACATGGATGCCGTA -GTTTCGAGCACCTTGGGCAGCATCTCCGTTGGATTGTTGTGCATGGCCAGTGTCTTGGCC -TGTAACAATTGTTCCATCTCTGCAGATGACATTGCGCTGCTTAGTGGTAGTTATATGCTT -CTTGCCACGATTTAACCATTTGTTCAGTCAAGTACTAACGGTTAAAAGGTATCGAAATAT -GGCAACTTTTCACTTTTAGATCAAGTCACTATATACGACTTGAACATCAGAACGGCGATT -TTCCATCAAGATGGAGTGGAAACCACGCCATTATAAAGGAAAGCTAGTTTTATGTCTCGT -ATACATGCGGAGTAGGACAGTGATATAACACACATAGCTAGACACAATAGACATCATGAA -AAGGTCCACGTTGCTGTCGCTGGACGCATTCGCTAAGACCGAAGAGGACGTACGAGTCCG -CACCAGGGCCGGCGGGCTGATCACTTTATCGTGCATCTTGACCACGTTATTTCTGCTGGT -GAACGAGTGGGGACAGTTCAATTCTGTGGTAACAAGGCCACAATTGGTGGTGGACCGTGA -CCGACACGCAAAGCTGGAGCTTAATATGGATGTGACATTTCCATCGATGCCATGTGACCT -GGTGAATCTCGATATTATGGACGACTCTGGAGAGATGCAACTAGACATTCTTGACGCAGG -GTTCACGATGTCTAGGTTGAATAGCGAGGGTCGCCCCGTGGGAGATGCTACTGAGTTGCA -TGTGGGTGGGAACGGCGACGGAACCGCGCCGGTTAATAACGATCCTAACTATTGTGGGCC -ATGTTACGGTGCCAAAGATCAGTCGCAGAATGAGAATCTAGCACAGGAAGAGAAGGTTTG -CTGCCAAGACTGTGATGCAGTGAGATCAGCATACTTGGAGGCAGGCTGGGCTTTTTTCGA -CGGGAAGAATATCGAGCAGTGTGAAAGAGAGGGCTATGTCAGCAAGATTAACGAGCACTT -GAATGAAGGCTGCAGGATCAAAGGTTCTGCACAAATTAACAGAATTCAGGGGAATCTTCA -CTTTGCCCCTGGAAAACCCTACCAGAATGCATATGGACATTTTCATGATACTTCTTTGTA -CGACAAGACTTCGAATTTGAACTTCAACCACATCATCAATCATTTGAGCTTTGGGAAGCC -GATCCAGTCCCACAGTAAGTTGTTAGGAAACGATAAGCGCCACGGCGGCGCCGTAGTTGC -CACTTCTCCCTTGGACGGACGCCAGGTGTTCCCGGACAGGAACACACACTTTCACCAGTT -CTCGTATTTTGCCAAGATTGTCCCCACCAGATATGAGTACTTGGATAATGTTGTCATTGA -GACCGCGCAGTTCAGCGCCACTTTTCATTCCCGACCTCTTGCCGGTGGAAGGGACAAGGA -TCATCCAAACACACTTCACGTTAGGGGTGGTATCCCTGGTATGTTCGTCTTTTTCGAAAT -GTCTCCATTGAAAGTCATCAATAAGGAACAGCACGGGCAGACTTGGTCGGGCTTCATCTT -GAATTGTATCACCAGCATTGGTGGTGTCCTAGCTGTGGGCACTGTCATGGACAAGCTATT -CTACAAAGCACAGAGATCGATCTGGGGCAAGAAGAGCCAGTAGAGGAAGAGACTGTCATA -GGGAAGAGCCCTTTCTACATACTACTACNNNNNNNNNNNNNNNNNNNNNGAAATTGGTAT -ATCACTACTTGTACAAATATCATATTGTACGATAATCGCGAAGAACGACGCACTGGTGGG -AAGAAGTGGAAAACAGAAGCTTTAAGGTAGAAACAGAACAAGAATGTGGCTATGGTAGGA -TAGCAGAAGAGTACCATTGCTGTTATCATTTGTTGCCTAGCCCTATCAAGACCTGTCTGC -TAATCCAACCCGAGAGATCATGGCGATCCAAACCCGTTTTGCCTCGGGCACATCTTTATC -CGATTTGAAACCAAAACCAAGTGCAACTTCCATCTCCATACCCATGCAAAATGTCATGAA -CAAGCCTGTCACGGAACAGGACTCACTGTTCCATATATGCGCAAACATCCGGAAAAGACT -GGAGGTGTTACCTCAACTCAAACCTTTTTTACAATTGGCCTACCAATCGAGCGAGGTTTT -GAGTGAAAGGCAATCTCTTTTGCTATCCCAAAAGCAGCATCAGGAACTGCTCAAGTCCAA -TGGCGCTAACCGGGACAGTAGCGACTTGGCACCAACTTTAAGGTCTAGCTCTATCTCCAC -AGCTACCAGTCTCATGTCGATGGAAGGTATATCATACACGAATTCGAATCCCTCGGCCAC -CCCAAATATGGAGGACACTTTACTGACTTTTAGTATGGGTATTTTGCCCATTACCATGGA -TTGCGACCCTGTGACACAACTATCACAGCTGTTTCAACAAGGTGCGCCCCTCTGTATACT -TTTCAACTCTGTGAAGCCGCAATTTAAATTACCGGTAATAGCATCTGACGATTTGAAAGT -CTGTAAAAAATCCATTTATGACTTTATATTGGGCTGCAAGAAACACTTTGCATTTAACGA -TGAGGAGCTTTTCACTATATCCGACGTTTTTGCCAACTCTACTTCCCAGCTGGTCAAAGT -GCTAGAAGTAGTAGAAACGCTAATGAATTCCAGCCCTACTATTTTCCCCTCTAAGAGTAA -GACACAGCAAATCATGAACGCAGAAAACCAACACCGACATCAGCCTCAGCAGTCTTCGAA -GAAGCATAACGAGTATGTTAAAATTATCAAGGAATTCGTTGCAACGGAAAGAAAATATGT -TCACGATTTGGAAATTTTGGATAAATATAGACAGCAGTTATTAGACAGCAATCTAATAAC -GTCTGAAGAGTTGTACATGTTGTTCCCTAATTTGGGTGATGCTATAGATTTTCAAAGAAG -ATTTCTAATATCCTTGGAAATAAATGCTTTAGTAGAACCTTCCAAGCAAAGAATCGGGGC -TCTTTTCATGCATTCCAAACATTTTTTTAAGTTGTATGAGCCTTGGTCTATTGGCCAAAA -TGCAGCCATCGAATTTCTCTCTTCAACTTTGCACAAGATGAGGGTTGATGAATCGCAGCG -GTTCATAATTAACAATAAACTGGAATTGCAATCCTTCCTTTATAAACCCGTGCAAAGGCT -TTGTAGATATCCCCTGTTGGTCAAAGAATTGCTTGCTGAATCGAGTGACGATAATAATAC -GAAAGAACTTGAAGCTGCTTTAGATATTTCTAAAAATATTGCGAGAAGTATCAACGAAAA -TCAAAGAAGAACAGAAAATCATCAAGTGGTGAAGAAACTTTATGGTAGAGTGGTCAACTG -GAAGGGTTATAGAATTTCCAAGTTCGGTGAGTTATTATATTTCGATAAAGTGTTCATTTC -AACAACAAATAGCTCCTCGGAACCTGAAAGAGAATTTGAGGTTTATCTTTTTGAAAAAAT -CATCATCCTTTTTTCAGAGGTAGTGACTAAGAAATCTGCATCATCACTAATCCTTAAGAA -GAAATCCTCAACCTCAGCATCAATCTCCGCCTCGAACATAACGGACAACAATGGCAGCCC -TCACCACAGTTACCATAAGAGGCATAGCAATAGTAGTAGCAGTAATAATATCCATTTATC -TTCGTCTTCAGCAGCGGCGATAATACATTCCAGTACCAATAGTAGTGACAACAATTCCAA -CAATTCATCATCATCCTCATTATTCAAGCTGTCCGCTAACGAACCTAAGCTGGATCTAAG -AGGTCGAATTATGATAATGAATCTGAATCAAATCATACCGCAAAACAACCGGTCATTAAA -TATAACATGGGAATCCATAAAAGAGCAAGGTAATTTCCTTTTGAAATTCAAAAATGAGGA -AACAAGAGATAATTGGTCATCGTGTTTACAACAGTTGATTCATGATCTGAAAAATGAGCA -GTTTAAGGCAAGACATCACTCTTCAACATCGACGACTTCATCGACAGCCAAATCATCTTC -AATGATGTCACCCACCACAACTATGAATACACCGAATCATCACAACAGCCGCCAGACACA -CGATAGTATGGCTTCTTTCTCAAGTTCTCATATGAAAAGGGTTTCGGATGTCCTGCCTAA -ACGGAGGACCACTTCATCAAGTTTCGAAAGTGAAATTAAATCCATTTCAGAAAATTTCAA -GAACTCTATTCCAGAATCTTCCATACTCTTCAGGATATCATATAATAACAACTCTAATAA -TACCTCTAGTAGCGAGATCTTCACACTTTTGGTAGAAAAAGTTTGGAATTTTGACGACTT -GATAATGGCGATCAATTCTAAAATTTCGAATACACATAATAACAACATTTCACCAATCAC -CAAGATCAAATATCAGGACGAAGATGGGGATTTTGTTGTGTTAGGTAGCGATGAAGATTG -GAATGTTGCTAAAGAAATGTTGGCGGAAAACAATGAGAAATTCTTGAACATTCGTCTGTA -TTGATAAATAAAACTAGTATACAGCAAATACTAAATAATTCAAGAAAAAAACATTAGATA -GAGAGGGGCAGATGTTCAAGCTATACCCATTATATTGATCCACACTTAGTATTAAGATAC -GTCTGTGAAGGATGNNNNNNNNTGTATAATGTGACTAGAGGAAGTAAGGAGAAAAAACGA -TAGTAATCGTATTTTAGGTTGTGCGTTTTTATAANNNNNNNNNNNNNGTAATTCTATGCA -AATGTAATATAAGTATATTTAAAGAAATAATGAGTCCTGTGNNNNNNNNNNNNNNNNNNG -ATCATTAATGTATGTTAACGTATTTGCTTTGCAAATTTTAATTTATTTGTTGTTAAATGC -ANNNNNNNNNNGTCGTTTCAGCGAGTTTTCTTGAGGTTGCTACTATCATTAAAATCACAA -TCCACAGAGGAAGTTGATCTCTTTTTCAGTTGGGTGGGGGCAGAGCATGGGTGAGCAGTG -GCCATGGGTCTAACAGGAAATAATCTTTTTGAACGCACAGATAAATTTTGTAATAATTTT -CTATTTGACATTAGAGATGGGGTGGTGGGAGTTAGTGGGCTTGGCCAAAAGATGCTTGAA -TTTTGTGGGATGCTCAGTGACCTTTTAAAAGAATTTTGGGTAGAAGAGAACGAACCTGAA -TGTGAATGGTGTGATGCAGAGTCTGGGGTCGTCATTGAACTTGAAGTCTTGTAAGGGGAA -TTGAATGGAGATGGAGAGGATGAAGATGAGGTTGGAGTGAAGGCAAATGGTGGAGAAATG -CTATCTTTGGTCAACCTTCTTAAATGAGTGTGATCCGAGAAATAGTCTGTGGCCGCAGAT -GAAACCGTAGCGCTCTTTGGAGTAGTAGCATTTGAGTAAACACAAGTCAATGAATCGCTG -TCAAAGGACTGAGCAAAGATAGTATTGTACATGGTTTCCAATTCTTGTGAACGGTAGAAT -TCTTCCAGTTTCAATTGAATACAATAGTTTTGTAATGCGTCTAAGAGAGATTTTGCTAAA -GATGTCTTATTGCTATTCAAATATTTTGATTTGAAACTGGAGGGGAAAGAATTTTGGTCC -ATTGCTATATCCAATAAAGTATTAGAGATTTCTGACAATTTAATATCTAGGTCTTGGCAG -TTTTCCTCCAAAGCCAGATTGATATTTTCCCAAAGGTTTGAATTATAGTAGTTCAAAGAT -AATTTGATGAGGTTAATTGCACCCAGCGCAATTAGTGAACGATCATATTTAAATGATAAT -TCGAGATTGAAGGAAGCTAACTCGCACAACATAATGGCACCCAATTTGATCTCGTTGATG -TTCAAAGAGGGGCCTTGAGAAGAGGACGATTTATTAATAGCAGTACCAGCAGCGTTATTT -AATAAGGCCAGTTTCTGTTGAATGAAAGCTTCCAAAGGGGCAGAAAGGACAACGCCAGGC -GATAACGGGGACGTAGATTGGAACAAGAAGATGTCGATGTAGGAGTCGAATGTTGCCGAC -TGACAGATGGACCAATCGAGTGATTTGAAAAGATGCATTTCCATAGTCGTGAATTGCTTT -ATAGAATATTGATTGCAACACAAGTTTTGCAAGACTTTCAAAGTGGCCATTCTATTCTTG -GAGTCCCAAAATTTGGACGAAATCCAAAGCGCGGTCAAGGACAAGAGCTGGTAGTTGTAA -CTCTTGATAATGAACCGCGAGGAATACTTGTCCAAGATAGTGAAAGTAAGGAACAAAGTC -GAGGTCGATAGATTGAGTCTTGTGTGACAGTACATGATGAAGTCAAAGATCAAGAAACGC -ATCTTCGGATTAACTTGTGGCTGAGAGTTGAAGTTAGTCAGGTTGTACAGCGGCCTTTCT -GTGTGGGAAAGACGGAAATAGTGGTCCAATTGATCATTATTGTATTCGCTGATCGCTGAG -TGATGTGCTTGCAATTCTCTTTTAACGAGATTAGGGTTTTTAGACTTTGCACTAGCAATG -GCCCGCCTCTTTTGCAAGAGCAAGGGCAAATTAGGACATGAGGCAGCGCTGACAGAGGCG -GCAGTGGCGGTGGAAGTGCCACTAGCGGTAGCATACCTTGCATTAGCGTATCTAATTATG -GTATCCTTCAATATGGCCATCGTACAGAAAGCGTATCAAATCAGTGTCTTGAACGAGAGT -AAAAGGGAGATGCAATGGAATGTAAGAAATGCTATGGGTCAGAAAAGAAATGCAGAGGAG -TTAAACCGAATGAGGAAATGCAATGGATACGTTAAATTGGAGATGTGAGATTGCGACTGG -GACTCGGATGGATGCTTGCTTTTGGATGCTAGTACNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNGTTGGTTTAAGTCGGCAGAGGAGACTACTCGGGCAATTCGTTTC -CTAATGGGTATAGTCCTCTTTCCTCAGAAATCCATTTGACTGGCAGACTCAGTAGTAGAA -GAAAAAATCAAGAAAGAAATTGTGTGAAAGTATACTACACAAGAAAATGTTTAAGAAGAA -GATTAAAAGCTCGAGGAAAGTACAGATATACAAATTATAAATAGGTAGGAGGAAGNNNNN -NNNNNGATGAGGGCAAAAACCCAAGGCCAAATATGGAAATGTGGCAGAGGGACACACTAA -TCCGATAGTAAATTTATGTAACTTGATCATTACAGTGAGAGCAGGCTTGGTAATTTCTTT -TTCTTGCCTGATAANNNNNNNNNNNNNNNNNNNNNNNNNCTTGAAAGTTCACAATTTAGG -GTTTGAGCACAGCGTTTGGTTGCGACACTTCCCCAGAAGGAAAACCGGCCTCTTTGGCTG -GGGAGGGAAGAAGGGGGAGGAGAGCTCAGAAAGCCCTATCGCGATATGAGGGACCGATCT -GTATCAGCATACTTTCGGTATCATCACGGTCGCAGGATAGAGATAGTGAATGAGTTAGCT -GTTTTACAGGCCAAGCGTTCAAACGAGACGAATGGCGACATTTGCCCGTCAAGAAAACCC -GCCGAGTTTTTTCCTAAACGGGTAAAACAGCCATGCACCGCAGCACGTCGACGAGGTGAT -ATTTCCAATTTGGGAAATTTCCCAAATCAGTAATGTAGCCTCTACGGGTGTCTCTGTCAG -CCCCGTGGTCGCCAGCACAGAATGTATCGTACCCCTGAAGGTAGTTTTTTACCGCCGTGG -CACACGATAAAGGTGCACCTTGTGATAATAAGGTGGAAAAATATATATGAAAAAGTGAAA -TTGATTGTGGCTGCACTAGGACATCATTATTTCTTACTTGGCTATTTACACGTACTTACG -CTGGCTGTATATCATTTAAGGGGCGGAGGACGAAGAGGACGGACCCGAGATCATCCGGTC -CAAGAAACGGGTCATCCGGTCCTTAGCATTGTCTAGACTATCTAGGGCAGGACGGACATC -CACGTGGAAAGTAGGCATTCCGTTTTCGTCGTCGGGCCCTCCGTAGAAATCCAAGACGTA -TCTAACTTCCTTGAAGGTTGGAGGTTGTTGTTCCGCTTTGCGCTCGCCTCGGAGTACAAT -CCAGTCGTGCCTGTCGAATGGTAGTTCTTGGCTAAAATGGGACGGAAACAGTAGGCCGCA -CAGGTGCATCCAGCGAGCACGAGGGCTCAATACGCCCGGTTTCCCCATGAATTTCAGCAA -CTTAGGCTGCACGTGGCTTTCATCTGTGTGCGGTTTTTCCCATTCGAGCACTTCCTGCCA -GCACCCTTCATTTAGAAAGTTGTGGACCTGCACCATGGACTCCACTGCATCTTCGGCGAC -TTCGCCGCTACCGCCAATCTTGCCCTTTCTAACCATAGCATTGTACATCTGTTGTGGAGA -AGGATACTCCCAGAACTCGTTACTGTCTGGACTCTTGGGGATGCTGGAGATGGTCCGATC -AACGGGCAAGTCCATCTTTTGGCCAGGCTGTTTGGATGCTGCCAACTCCGGCATATTGTT -CAGCGGGTTTATTCTATCGTTATCTCCCTGCATAACGGGGCACTCAGAGGATGGTGGCGA -CGACGACGACGACTCGTGCATGACTGGGCACCCTGACATGGATGATACTGCTGCCCCACC -AATATCTTTGCCCGTAGTTTTTTGATCTGCCCAAAACCAACCCATTTTTTGTAGTTTCTG -TTGTATTTGCTCTGCTTTATTCGTGCTACTCGTATGTGTATGCTATCTTATTAGCTGCCT -ATTTCATTTCTCTTAGTATTCGCATTTAAAGCTGAGAAATTTTTTGATAATCATTTCCCG -ATNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNTTTGGGTNNNNNNNNCGGAAGATCCCACGCCGCGCAAGAGATATTTCAATATT -ACTACTACATAGTATATGCGGCGCTACCATACGTACAACNNNNNNNNNNNNNNNNNNNNN -NNNGCCTTCTAAATTTGTAATTCGGTCACACTTTTGTCGCAGTGTTGCAAACGTCTTGAA -AGAATTGTAGGTGTTGTAAACCACAACTTGCTCCCTTGAAAGCGTTGCTGATTATTTCCT -TTGAACCNNNNNNNNNNNNNNNNNNNNNNNNNNCTGCTGATGTTTTAGGCACTTAGTATT -AGATATTCCTAAGCCTCCCTCACCATAAATTACCTTTATTACTTGCATGACTATTATTAG -CAGAGCATGTAGTATGGGACTCAAGACCGATATGATACACACCAAAGACGTAGGCACCGG -CGATTAAATCAAAGGCTCCGATAGCCGAAAAGTGAGAAGNNNNNNNNNNNNNNNNNNNNN -NTTGTCCTAATGAGCGGTGTGGCCGACTTGCCATAATATCAGTTAGGGCTACTATCAATG -TTTTATCTACGTTGGAGTAAGATCGTTTATCACTTCCATATTTGGACCAAATGAAAAGTT -CAATCGGCCAAGTATTTCATGGATGGAATGACGTTTGGTAAGGAAGTGCTTTTTCTTTTT -CCACATATTTTCCCTTTCTCTCGGGGAAATTTTGTTTCTAAACATAAAAAATAAAGCAAC -AGCAAAAAAGAGGGTCTGTCCAGCGAATAAGAAGAAAACCTCCTTTTCGGCTTTTGAAGA -TAGGTTGCAGTTGTCTGCGGGCACAAAATGGGCANNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNCGCCAATTATATCGCATGAAGAATAACCAGAGTTTTTCTCCGAACG -TTAAGGGAGTTGAAGTAAAAATAAAGAAAGGACCAAATGAGAATGGGTATGCTTGGTCTT -AGTCTTCGAATCAAATTCTGCTTCCCTGTTCATGGCAACGTCACCTCAATTATTTGGAAA -GGGGGGGTTTTCCGACTTTATTTGAGATGACTTGAGATGTGTGTCAATGCTAGTATTTTG -GAGATTAATCTCAGTACAAAACAATATTAAAAAGAGGTGAATTATTTTTCCCCCCTTANN -NNNNNNNNGTTAGAATTGATCCAAATGTAAATAAACAATCACAAGGNNNNNNNNNNNNNN -NNNNNNNNTAGCCGCCATGACCCCGGATCGTCGGTTGTGATACGGTCAGGGTAGCGCCCT -GGTCAAACTTCAGAACTAAAAAAATAATAAGGAAGAAAAAAATAGCTAATTTTTCCGGCA -GAAAGATTTTCGCTACCCGAAAGTTTTTCCGGCAAGCTAAATGGAAAAAGGAAAGATTAT -TGAAAGAGAAAGAAAGNNNNNNNNNNNNTGTACACCCAGACATCGGGCTTCCACAATTTC -GGCTCTATTGTTTTCCATCTCTCGCAACGGCGGGATTCCTCTATGGCGTGTGATGTCTGT -ATCTGTTACTTAATCCAGAAACTGGCACTTGACCCAACTCTGCCACGTGGGTCGTTTTGC -CATCGACAGATTGGGAGATTTTCATAGTAGAATTCAGCATGATAGCTACGTAAATGTGTT -CCGCACCGTCACAAAGTGTTTTCTACTGTTCTTTCTTCTTTCGTTCATTCAGTTGAGTTG -AGTGAGTGCTTTGTTCAATGGATCTTAGCTAAAATGCATATTTTTTCTCTTGGTAAATGA -ATGCTTGTGATGTCTTCCAAGTGATTTCCTTTCCTTCCCATATGATGCTAGGTACCTTTA -GTGTCTTCCTNNNNNNNNNNNNNGGCTCGCCATCAAAACGATATTCGTTGGCNNNNNNNN -CTGAATTATAAATACTCTTTGGTAACTTTTCATTTCCAAGAACCTCTTTTTTCCAGTTAT -ATCATGGTCCCCTTTCAAAGTTATTCTCTACTCTTTTTCATATTCATTCTTTTTCATCCT -TTGGTTTTTTATTCTTAACTTGTTTATTATTCTCTCTTGTTTCTATTTACAAGACACCAA -TCAAAACAAATAAAACATCATCACAATGTCTAGATTAGAAAGATTGACCTCATTAAACGT -TGTTGCTGGTTCTGACTTGAGAAGAACCTCCATCATTGGTACCATCGGTCCAAAGACCAA -CAACCCAGAAACCTTGGTTGCTTTGAGAAAGGCTGGTTTGAACATTGTCCGTATGAACTT -CTCTCACGGTTCTTACGAATACCACAAGTCTGTCATTGACAACGCCAGAAAGTCCGAAGA -ATTGTACCCAGGTAGACCATTGGCCATTGCTTTGGACACCAAGGGTCCAGAAATCAGAAC -TGGTACCACCACCAACGATGTTGACTACCCAATCCCACCAAACCACGAAATGATCTTCAC -CACCGATGACAAGTACGCTAAGGCTTGTGACGACAAGATCATGTACGTTGACTACAAGAA -CATCACCAAGGTCATCTCCGCTGGTAGAATCATCTACGTTGATGATGGTGTTTTGTCTTT -CCAAGTTTTGGAAGTCGTTGACGACAAGACTTTGAAGGTCAAGGCTTTGAACGCCGGTAA -GATCTGTTCCCACAAGGGTGTCAACTTACCAGGTACCGATGTCGATTTGCCAGCTTTGTC -TGAAAAGGACAAGGAAGATTTGAGATTCGGTGTCAAGAACGGTGTCCACATGGTCTTCGC -TTCTTTCATCAGAACCGCCAACGATGTTTTGACCATCAGAGAAGTCTTGGGTGAACAAGG -TAAGGACGTCAAGATCATTGTCAAGATTGAAAACCAACAAGGTGTTAACAACTTCGACGA -AATCTTGAAGGTCACTGACGGTGTTATGGTTGCCAGAGGTGACTTGGGTATTGAAATCCC -AGCCCCAGAAGTCTTGGCTGTCCAAAAGAAATTGATTGCTAAGTCTAACTTGGCTGGTAA -GCCAGTTATCTGTGCTACCCAAATGTTGGAATCCATGACTTACAACCCAAGACCAACCAG -AGCTGAAGTTTCCGATGTCGGTAACGCTATCTTGGATGGTGCTGACTGTGTTATGTTGTC -TGGTGAAACCGCCAAGGGTAACTACCCAATCAACGCCGTTACCACTATGGCTGAAACCGC -TGTCATTGCTGAACAAGCTATCGCTTACTTGCCAAACTACGATGACATGAGAAACTGTAC -TCCAAAGCCAACCTCCACCACCGAAACCGTCGCTGCCTCCGCTGTCGCTGCTGTTTTCGA -ACAAAAGGCCAAGGCTATCATTGTCTTGTCCACTTCCGGTACCACCCCAAGATTGGTTTC -CAAGTACAGACCAAACTGTCCAATCATCTTGGTTACCAGATGCCCAAGAGCTGCTAGATT -CTCTCACTTGTACAGAGGTGTCTTCCCATTCGTTTTCGAAAAGGAACCTGTCTCTGACTG -GACTGATGATGTTGAAGCCCGTATCAACTTCGGTATTGAAAAGGCTAAGGAATTCGGTAT -CTTGAAGAAGGGTGACACTTACGTTTCCATCCAAGGTTTCAAGGCCGGTGCTGGTCACTC -CAACACTTTGCAAGTCTCTACCGTTTAAAAAAAGAATCATGATTGAATGAAGNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTTCAACTCAAAT -AAAGATTTATAAGTTACTTAAATAACATACATTTTATAAGGTATTCTATAAAAAGAGTAT -TATGTTATTGTTAACCTTTTTGTCTCCAATTGTCGTCATAACGATGAGGTGTTGCATTTT -TGGAAACGAGATTGACATAGAGTCAAAATTTGCTAAATTTGATCCCTCCCATCGCAAGAT -AATCTTCCCTCAAGGTTATCATGATTATCAGGATGGCGAAAGGATACGCTAAAAATTCAA -TAAAAAATTCAATATAATTTTCGTTTCCCAAGAACTAACTTGGAAGGTTATACATGGGTA -CATAAATGCAGATGCCAGTGAACTATGTTCAGCTTCTGGCCTTCGTTTGGTGGTTTAATC -TATTTTTTATAAAAAATGACGCGGGCAGATTCAATTAGTGTCCTAAATTTATTCGCGTTT -CAAGATTTCAAAGGATTGATCCTCTTATCAGAAACGATAAGTGCTACTCCGTCCTATTCT -TCTAGCCATCTAGTACGTATTCTTTTCATAACATAATCCCTTATTTACAGAATGTGTTTC -GAAGAAAAATTAATTAGATGGGAAGAAAACTGAAGTGGCTTATATAATCAGTGACATAGT -GCCAATAATTACGCAAAAAGCAAAGGAAATAACACTGCTATGGATATGGAAATCGAAGAT -TCAAGCCCCATAGATGACCTGAAGTTACAAAAACTGGATACCAATGTTTATTTTGGACCC -TGTGAGATATTGACACAACCTATTCTTTTGCAATATGAAAATATTAAGTTCATCATTGGT -GTCAATCTAAGTACTGAAAAGATAGCGTCGTTTTATACCCAGTATTTCAGGAACTCTAAT -TCGGTAGTCGTGAATCTTTGCTCACCAACTACAGCAGCAGTAGCAACAAAGAAGGCCGCA -ATTGATTTGTATATACGAAACAATACAATACTACTACAGAAATTCGTTGGACAGTACTTG -CAGATGGGCAAAAAGATAAAAACATCTTTAACACAGGCACAAACCGATACAATCCAATCA -CTGCCCCAGTTTTGTAATTCGAATGTCCTCAGTGGTGAGCCCTTGGTACAGTACCAGGCA -TTCAACGATCTGTTGGCACTCTTTAAGTCATTTAGTCATTTTGGAAATATCTTGGTTATA -TCATCACATTCCTATGATTGCGCACTTCTCAAATTTCTTATTTCCAGGGTGATGACCTAC -TATCCACTAGTGACCATCCAGGATTCTTTGCAATATATGAAAGCAACCCTGAACATATCC -ATCAGTACATCCGATGAGTTCGATATTCTGAATGATAAAGAACTGTGGGAGTTTGGCCAA -ACCCAGGAAATTCTAAAACGTAGGCAGACGAGCTCAGTCAAGAGGAGATGTGTCAATTTA -CCAGAAAACTCTACGATCGATAACAGAATGCTTATGGGTACCACAAAGCGAGGTCGCTTT -TGAAGAGCCCTCGGTAGCATAACATTTTTAATTATTACGACTGNNNNNNNNATTCATTAT -GTAGAGATAATTAAATGTTATAGATGCTCTATACTCAAACGGTGGAAGNNNNNNNNNNNN -NNNNNNTAACCGATACCCCCTTTTCGAATACAAATGCTTGTATATTCAATTATGAATTAN -NNNNNNNNNNNNNCATTTCTTATATTATTTTTTGTTCGAGAATCACTTTTTCAAGATGGT -AACAACATCTTCGTCTTCCAAAATGTGACTCAACCCCACGTATTGAGGTTGATGTTTGAC -ACTGCTACCGTAAACCAGAGCATTTCTAAAGTCGTCCACTAAAGATTTATGAATTTGGTT -ACAAAAATCCTTGACACTGCAACGGTCTGATCTTAGCACCACAGGGTCGGTAAAATCTGG -TATTTGGCCCTTTGGTTTAGTGTAAATACGGACTAGATTTAGTCTATCCCACATGACTTG -CAACAGCTCGTCCAAGTTCCAATCTTGACCAGACGAAATAGGCACGGCATTAGGAATTCG -GTAAAGTAATTCCAATTCCTCTATTGACAGAGAATCAATCTTGTTTAACACATAGATGGC -AGGCATGTATCTTCTTGACGAAGCTTCCAAAACATCAATCAAATCATCCACAGTGGCATC -ACACCTGAAGGCAATCTCAGCGCTATTTATTCTGTACTCGCTCATAACGGCTCTGATTTC -GTCATTCCCCAGATGGGTCAATGGGACTGTGTTTGTGATGGAAATACCACCTTTCTCNNN -NNNNNNGATCAAGATATCTGGCGGAGTTTTATTCAGACGAATCCCCACACCTTCCAGTTC -CTTCTCAATGATTTGCTTATGATGCAAGGGTTTGTTCACATCTAGGATGATAAATAACAG -GTTACAGGTTCTTGCCACGGCAATAACTTGCTTACCTCTACCTCTACCATCCTTAGCACC -ATCGATAATACCAGGTAAATCCAACATTTGGATCTTGGCACCTTTATAACGAATGACACC -GGGGACGGTAACCAGGGTGGTAAACTCGTACTCAGCTGCTTCAGACTCAGTACCAGTCAA -CTTGGACAGTAATGTAGATTTCCCCACCGACGGGAACCCGACAAACCCCACACTGGCCAC -ACCAGTTCTAGCCACATCAAAACCAATACCAGCACCACCACCGCTGCCGGATGAAGCACT -GGTCAACAATTCTCTTCTCAGTTTGGCCAGCTTGGCCTTCAGTTGACCCAAATGGAAAGA -TGTGGCCTTGTTCTTTTGGGTACGGGCCATTTCATCTTCGATAGCTTTGATTTTTTCAAC -TGTAGTAGACATTTTGCTCAATCAACAACTCTACGCTTGCACCTACTGCATCTAGCTTCA -AACACTTCCTATCATTGCGCCCTCATCACACCGTAATATCCCATCTTAAAAGTGGAAAAC -TCTTATAGCTCATCGATGAAAAAAACGGGCCCTCGTCGCTTGTGATGTGAAAAAATTTTT -CAAGCTTTAAGCCCATTGAAAGCAAGAGATCTTGCACTAGAATAAGTGGCAAAGGTGAAC -TTTGAGGGGATAAGAAGGGCAATCAGGAACATCAGATAAGTGAAAGATGGCGAAAAAGAG -TAAAAAGAACCAACAGAACTACTGGGATGAGGAATTCGAAGAAGACGCCGCCCAGAACGA -AGAAATCAGTGCCACGCCAACTCCAAATCCAGAAAGCAGCGCAGGTGCAGATGACACTTC -CAGAGAAGCAAGTGCAAGTGCTGAAGGTGCTGAGGCCATTGAAGGCGACTTCATGTCTAC -TTTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGATGGTAA -GCCTATACTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNGCCCAACAGCAAGCTCAAAAGGAGAAGAACAA -GGAGTTGAACAAGCAAAATGTTGAAAAAGCTGCTGCTGAGAAGGCTGCTGCTGAGAAATC -CCAAAAATCTAAAGGTGAAAGTGATAAACCAAGTGCTAGTGCTAAGAAGCCAGCCAAGAA -AGTACCTGCCGGTTTGGCTGCTTTGAGACGTCAATTAGAATTGAAGAAACAACTTNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNGAAGAAGCTAAAGCAGCTAAAAAGGAAAAGGAGAAGGC -AAAGCGTGAAAAACGAAAGGCTGAAGGTAAGCTATTGACCAGAAAGCAAAAAGAAGAAAA -GAAATTATTGGAAAGAAGACGTGCCGCTTTATTGTCTTCCGGTAACGTCAAAGTTGCCGG -TCTGGCCAAGAAGGATGGAGAAGAAAACAAACCAAAGAAGGTTGTTTACAGCAAGAAGAA -GAAGAGAACAACCCAGGAAAACGCCTCCGAAGCCATTAAATCTGACTCTAAGAAAGACTC -GGAAGTTGTACCTGATGACGAACTCAAAGAATCCGAAGATGTTTTGATTGATGATTGGGA -AAATTTGGCTCTTGGTGATGATGACGAGGAGGGAACCAACGAAGAAACGCAAGAATCCAC -CGCAAGCCATGAAAATGAAGACCAAAATCAAGGCNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNGCACATGTGCATGAAGTTGCCAAAAGCNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNACTCCATCCAGCGCTTCTCCAAACAAAAAAGATCTTCGTTC -CCCAATTTGTTGTATTTTGGGTCATGTCGATACCGGTAAGACTAAATTGTTAGACAAAAT -CAGACAAACCAACGTTCAAGGTGGTGAAGCTGGTGGCATCACCCAACAGATTGGTGCCAC -TTATTTCCCCATCGACGCTATTAAGGCAAAAACTAAAGTTATGGCTGAATATGAAAAACA -AACTTTTGATGTCCCAGGTCTTTTGGTTATTGATACCCCAGGTCACGAATCCTTCTCTAA -CTTACGTTCAAGAGGTTCTTCATTGTGTAACATCGCAATTTTGGTTATTGACATTATGCA -TGGTTTGGAACAACAGACTATTGAATCTATCAAACTGTTAAGAGATAGAAAGGCTCCATT -TGTCGTTGCCCTAAACAAAATTGATAGATTATATGACTGGAAAGCCATTCCAAACAATTC -ATTCAGAGACTCCTTTGCAAAGCAATCAAGAGCTGTTCAAGAGGAATTTCAATCTAGGTA -TTCTAAGATTCAATTGGAATTAGCTGAACAAGGTTTGAATTCGGAATTGTATTTCCAAAA -CAAAAATATGTCTAAGTATGTCTCCATTGTCCCAACATCTGCCGTCACCGGTGAGGGTGT -TCCAGATTTATTGTGGTTGCTATTAGAATTGACCCAAAAGAGGATGTCCAAACAATTGAT -GTACTTGTCTCACGTGGAAGCAACCATTTTGGAAGTGAAAGTCGTAGAAGGTTTTGGTAC -CACAATTGATGTTATCTTGTCCAACGGTTACTTGAGAGAAGGTGACCGTATTGTACTGTG -TGGTATGAATGGTCCAATTGTAACGAATATCAGAGCATTACTAACACCACAACCATTACG -TGAACTACGTTTGAAATCTGAATATGTCCACCACAAAGAAGTCAAGGCTGCTTTAGGTGT -CAAGATTGCCGCTAATGATTTAGAAAAAGCCGTTTCTGGTTCTAGGCTGCTAGTTGTCGG -TCCTGAAGATGACGAAGATGAATTGATGGACGACGTTATGGATGATTTGACTGGTTTGTT -GGACTCCGTTGACACAACTGGTAAAGGTGTTGTGGTCCAAGCATCCACCTTGGGTTCTTT -GGAAGCTTTGTTGGATTTCTTGAAAGACATGAAAATCCCTGTGATGTCTATCGGGTTAGG -TCCAGTGTACAAGCGTGATGTTATGAAAGCCTCCACTATGTTGGAAAAGGCTCCAGAGTA -TGCCGTGATGTTATGTTTTGATGTTAAAGTGGATAAGGAAGCTGAACAATACGCTGAACA -AGAAGGAATTAAGATCTTTAATGCAGACGTCATCTATCATTTATTTGATTCATTTACAGC -ATACCAAGAAAAGTTATTGGAAGAACGTCGTAAAGATTTCCTAGATTACGCTATTTTCCC -ATGTGTCTTACAAACCTTACAAATTATTAACAAACGTGGTCCAATGATTATTGGTGTAGA -CGTTCTGGAAGGTACTCTACGTGTGGGAACTCCTATTTGCGCTGTGAAAACCGACCCTAC -TACAAAGGAAAGACAAACTTTGATATTAGGTAAAGTCATCTCTTTAGAAATCAACCATCA -ACCTGTCCAAGAAGTAAAGAAGGGCCAAACCGCTGCTGGTGTTGCCGTCCGTCTAGAAGA -TCCCTCCGGTCAACAACCTATCTGGGGTCGTCATGTTGACGAGAATGATACATTATACTC -CTTGGTTTCAAGAAGATCTATTGACACTTTGAAGGATAAAGCTTTTAGGGACCAAGTTGC -TAGATCCGATTGGCTGCTATTGAAGAAGCTGAAGGTCGTTTTCGGCATCGAATGAGCATG -GCATACGCTGACTTGTCAACCCAATCACATTCTACAAAATTTAATGAATTAAATAGGTAA -TTGTATATAAAAATGTGAACCTTTGTGTATTAGTTTCAATTCTATCTTACTTTTCATTGC -CATTTTACTTCTTTCACCTTGCTGTCTTTCAACCTTGGAAATTTTTATAGTACGCGTAAA -CAAAAAAGGTAAATAAGAGGCATTGAATATAAGTTGGCATTTATTAGGAAGTTGAGTAAT -AACACGTTGAAACTGGGTTAAGACGATCAAAACAACCATGTCTGCTCCCACTATGAGATC -CACCTCAATATTGACAGAGCATTTGGGATATCCGCCCATCTCGCTTGTTGATGATATCAT -TAATGCTGTAAATGAAATTATGTACAAGTGCACTGCTGCCATGGAAAAATATCTGCTATC -CAAGAGCAAAATCGGCGAGGAAGATTATGGAGAAGAGATCAAAAGTGGAGTTGCTAAGTT -GGAATCACTTTTGGAAAACTCCGTGGATAAGAATTTTGACAAACTAGAACTATATGTTTT -GAGGAACGTCCTTCGAATCCCTGAAGAGTATTTGGACGCCAATGTTTTTAGATTGGAGAA -CCAAAAGGATCTGGTCATTGTAGATGAGAATGAGTTGAAGAAAAGTGAGGAGAAACTTCG -AGAGAAAGTGAACGACGTGGAGTTAGCGTTCAAAAAGAATGAAATGCTATTGAAAAGAGT -TACAAAAGTGAAAAGACTGTTGTTTACGATAAGAGGATTCAAACAAAAGCTAAACGAGTT -ACTGAAATGCAAAGACGATGTACAATTGCAGAAAATTTTGGAGTCGTTAAAACCTATAGA -TGACACAATGACTCTACTGACTGATTCATTACGTAAACTATATGTTGATAGTGAAAGTAC -CAGTTCAACAGAGGAGGTAGAGGCACTACTGCAGAGATTGAAGACCAACGGGAAGCAAAA -TAATAAGGATTTCAGAACACGATATATCGATATAAGGACGAATAATGTCCTACGAAAATT -GGGGCTACTAGGTGATAAAGAGGACGAAAAACAGTCTGCCAAGCCGGATGCGAGGACGCA -AGCAGGGGATATAGTTAGTATAGATATTGAAGAGCCTCAATTGGATTTACTTGATGATGT -GTTATAATATAAAGTGGGAAAAAGTATGTGCTATGATATGATGTATGTATTCACGAATGT -ATTATGTAGAAAAATGCTAAAAAATTGGATAAAAGAAAACCATGTTTAAAATGCATACCA -CCATGTGTATTATAAGTACTTCGTAAAATTCGAATCCTGTAGCCAGCCAACCTTCTCGAA -AGCTTGGAATAGTCTTGATGCTTTATTAACGTCGATCCTACAGGCTTTTTGGGCGTCGGT -CCTTCTAAACGGCAACCCTTTCTTTAGTCTATAAACTTTTTCCAAAAATAACCTTCTCTT -AGAATCCAGATACAAATCACAAGGTAACCTTAGAGTTTGAGCGAGAACTAGTTCAGCAGG -GTGTAGCTCGTTCCTCAGCGGGTCTGTGGACAGGTCCATTGGAGACCCCTTCCACTCGAT -CTTGAGTGACTTGTTACTGTCTGTAGGAAGCGTAGATAAGGGCGGAGAGTAATCTGGTAA -TTTTTTCCATGAGACGTTTGGTATATATTGAGGAGCATCATGAATCGCCTCAATGGATGC -AATGTTAGTGTGAGGAGTGGATGCAGAGGGTGAGAACTTCTTGGCGCGATGTGGACTGGT -AGTCATCGTTCTTCTTTGTGGTGAGTATACCTTGCGTTTCCGTGGTATCCATTCAGTGTC -GGATTCAAACTTTCCTAGATTGTTATTGTAGAGAGCCTGTTTCCTCATATTATATCTTGC -TTGTCTATTCAAATTCGGAGATGCTAACGGGGAAGGTAATCTAGAAGAAGAGGAAGGCAG -AGGAGGAGGAGTCATATCATCATTGTATTTGGAATATTTATGTCTAGCATTATAGGCCAG -ATTGTTGTACCGGTTGATAATGTTCTTAGAATATGGTTGGGCCAAATTGCTGAAAATTTT -GTATTGAGACAGAAACCCGTAGGTGGCGTAGCGGTACCTTTTTCTTGATAACCCATTGGG -CCATACAGGCTTCACGAACAGCACATTCTCTACAGCGCCTTTAGGCGTAGATCCCACTAG -CACTGAAGAGGCCATGCGGGGTGAGCCATTGTGGCTAATTTTCGACTCCAGCTTGGGCGA -CAAAGGTGGCGATGGTATTATATGTTCATCAACCAAGGAGTCAATGCTGCCAGAAAAGCA -TCCATTGCCATTATTTTGTGAGTTCTGGTTAATTCTTACGTCGTACGAGCGCCCATAGGG -TGAATTATTGCTATAATCACTCATGTTTAAACCGTTTTTATTACTATCGTTATTGTTGTT -ACTTGCTTTCAAATTCTGATTCAGACGTCTGAAAATGGACTGCGAATCATCCTTACCAAT -GTAATTCATATTTAATTGAGACTTTTCAGATTCAGGAGAATATAATCCCATGTTTCCCCT -ATAAATGTTACGATGCGCGAATATCCTGTTTATCGATGCCCAGTGTATGAGCCATAACGG -GGATGTTATGAACCATGTGGCTACTTTTATAAGCGGTTCTCTTAGGAAGAAGGGGGTTCT -TGATAGACCCCTGCACCTCATCTAGCGGAGGTGCACGGATGTACCAACAGTTTTAGTGAA -CATTATTCACTAAAGAAGCATTGGGCATACTCAGAGCCAATGGCAAGCTCGTTTACCAGT -TCAAATATGTCGTTTCATTATCTGTATGACTGTCGTAACTTTGAATCGATCTAATGTGTT -GACCCTGTCTCAGGCTCACCCATGGCGGCGCCTGCACCTGTGGGTGAAGGAAGAAAGACG -ATGTTTGTGAGGGAACTGAATTGGGTTGAAGTTCATATCCTAAACAAACACTTCACCAGC -CATGGATGCATGCCTTGTCTTTTCGCAGTTGGTGGCATGAAAATATATATCACCCACCAA -ACCCTCTTACTCTTTTCTTACCAAGTAACTCCAGTAAGTGCTCGTTTTTTTCTTCTTCCA -TTCAAACCTGCTTAAAAACCTCGACAAACGAGCCCCCAACGTACTACCACAGCAACCACT -CTGGTTTTTCTATCTTGTTGTCTTTAATTGCCTCCTGACTTTGTTTTGTTTTGTTCTTGC -TTAGCGCTCTTGAAAAATATTTTACTTTTCACTATCAGATTAATGTGATAGCAATAGTTA -GTGCAACAAAGAAACAAGTCGATAAATGGTACGTTTAAAAAGTAGATATATCCTTTTTGA -AATTATATTCCCACCTACAGACACCAACGTTGAGGAATCTGTGTCGAAAGCAGACATCTT -GCTTTCGCATCACAGAGCATCGCCTGCGGATGTGTCCATAAAGTCGATACTCCAAGAGAT -ACGACGCTCGCTGTCGTTGAATCTGGGCGACTATGGGTCTGCAAAATGTAACTCTCTCTT -GCAGTTGAAATACTTTTCAAATAAGACGTCTACGGGGATAATCCGATGCCATCGAGAGGA -TTGCGACCTTGTTATCATGGCATTGATGTTGATGTCGAAAATTGGCGACGTCGATGGACT -GATCGTGAACCCCGTCAAGGTAAGTGGGACCATCAAGAAAATAGAGCAGTTTGCTATGAG -AAGGAATTCTAAAATTCTGAACATAATCAAGTGTAGTCAATCATCACACCTCAGCGATAA -TGACTTTATTATCAATGATTTCAAGAAAATTGGAAGGNNNNNNNNNNNNNNNNNNNNGGA -CGATTAGAATATATTAATATATAGATGTACACGTATATGCAGTAGTTTTATTTTTTTATC -TATAATACAACTCAAGCACAAGAATGCTTTGTTTTCCTAGTGCTCATCCTGGGCCTAGGC -GCCATAGTTATCCGATTTATCATCGGATTCAGCTTTAGTAAACTGAATGGGGCCGTGAGA -ACCACTGGCACCTTCACTCTTAACATTGACCGCTTCGTCCAGCTTTTCGTAGTTGGTCTT -GTATATGCTTTCAATATCTTGTTGGACGAACAGTGGGTTGTCATAAACCTGGTCTTCATG -CCTTTTGGCGGAGGCATTTGCCCCTCTTGTGAAAAATCTTGAATCGTACTGCAGATCCGG -TTGTTCTGAACGCTTTGCTGCGCCCAGAATTATCTTTTCGGATACGTCTCTTCCTTGAGA -GTACGCCAGCTCTTTTAGTCTGGCCACTGTGCTCGTTTGCTTTTTGGGCTTAACTATTGC -TCCCGTCTGCGGAGTCCCGTTGTGGTATCTGGCTCGTTGGCTCAATTCTTTCAATTTAGA -TTCTTTAGCAAGCATTTCCTGTTCCATAGCAAGCCGCTTCAATTCCATTTTGGACCTGAT -CTCTTGTCTTGCCTTCTTGTCAGCGTTTTCTAACGCTTCGGAGAGCTTCATAAACCCATC -GTTGATGGTATTATTTTCGTTGTCAAGAGCTTTACCTACACGTCTTTCCAAGGCCACGGT -ATAACCATTTGGATTTTTCCAGTTTGACACAGCTGCAGGTATCTTCCACTCATTTGGATC -AGCTTCTCCCCTATCATTGCTGCCATCCATATGGAGAACAGGCACGACTTCGTCGTTTTC -TGTGGGTGCTACAACCTTTCTCGCCTTCTTCCCAACGAACCTTGGCAACAATGGATCCAT -TTGCTTGGACACTACCTCAATATGGTGGCTGTTGTTCAATAATAGATTCGCGGGTGCCTG -ATGTGTTTCGGTGACGTACCTTGATGATGCCCTGTTATTTGAGTTGGCTAGTTTCGCATT -CACAAGCCGCTGAATGTATGACTTGGTTCTTGCTGTACATTCTTGGATTTCTGCTTTCGT -TGGCAAAGGAACCGATAGTTCGAAATTAGACTGTCTCTTTGGAATAAAATCATCGAGCTT -AACGTTTTTAGCGATTTGGTCAGTCAATATTGCCGGCTCAACGCGATCTGAGCTCAAAGC -CGTCGAAACTCGTCCTTGAGAATGTTTTGGAGGTGGTAGTCTGTTACTAAACATATTTGG -TTGAGGTTGCTGATACGTCCTCTCGGCTCAGAGCTGCCATGTGTCAATAACCCCATAATT -TGAACTTCTTTCATCAACTTTTTAGCTGGGGAAAAATCAAATTCGTGAAGAATTACAATA -ATACGTTAAGGTAAAAGATTAAATATTAAAAAATAGTATGAGTACTTTTGAATCATCAGA -CAAGAACAATGAAGGATATGAATAGTATTAGATATGTATTCNNNNNNNNNNCCAGGGACA -TAAAGAGTTGTTTTTATAAGGTGCGGAGTTATCTCAATTTGCTTCTGATTTTAGAAGCTA -TTCTATGCCCGGTCGACTCTTTGATTTCGATCCCAAACGGCATCATGGTAGTTTCGGAGC -CAGATTCGCCATTTTCCCACTCTAATCCATCTCGAAGACTTTTTCGAAAGGTAAACCCTT -CTTCTTGTCTCAGCGTGTTATATTTGGACTTATGCTGTAGCGGCTTGATCATTGCCGAAG -CAGGTATTGGCGGATAATGTAGCACAGCCGGCTTCTTGTACCAACCCACCTTTGTTGGTT -TAGGATTTTCTGCCTCTGTCATTGGCGGTACACCAGCAAATCTCACCCTTTTGATGGACA -ATTCACTGGAGTTTGACTCCGGATCTAGAGTTAATGTCTCTATAGCCAAAGTATCACTAC -TATTGGCAATCAGGGTACTTGATGATTTTCCTGAGGAGGTGTTGTTTATACTGGATACTT -TTGGTGAAGGCGCTAACGATGAAGATGCAGAAGGATTGGGTGTAGATGCACTTTTGTTCA -TCAAATGCCGCACTGTATCTTGGACGATTTTTTGATTTAACGTCATGGTTGAGGACTGCA -AAGAATTGGACCTTTGATTGTTGAGCTTTGAAGGTGGAGCTATTGACGGATGTCTTGTAG -AATTCAAATATGAGGTTTGTTGTTTGTTTGTATAGGATTGCAAAGATGAGGATCTAGGCC -TTCTGCCGTTGATCAGTTTTCTTTTCTCCGGAGACACCACGCTTTTCTTCGTTTCTGCGT -TTTTATTGTTGAAAGTGGTCCTTACAGGCGATACTGAGGGAGACCTAGAAGAATTTGAGG -CTAAATGCGCCCTTGCCCTTGTTCTTATGCTCTCTAAAGAGGCCTGTCTTGATGGGCTTG -CTGAAGATGTGGGTGAGGGGGATGGAGAAGAAGAGGCTGGCAGCTTTGTTATTGACGGCT -TCTTCTTTAGCTTACTTTTCGCGTTTTTAACCTCTAAATACAGAGCCTTATCTCTTTCTA -GCTTTTCTTTCAAATTCTCCCGCAAGTCATTGGTTTCATCGAAGGTTTTATAATTTTTCT -CAATATATTTCCAGCAATCCATCCAATTGGATAATAATCCCATAATGGACCTCAATTTCG -GTATAATCTTGCAGATATGATTATTAAACAATTCCACAACTAAACCAGGTTGAAGGTGGA -AAATGGGAGTTCTTGAGGAATTGTTATCGGTACGCGCCGTTTGAGTCCAAAATTTTAAAT -TCTCCTGCAGTTCGAATAAAGCTGTGACATCATCACATTCTGGAGAGAGCAAAGCCATCA -GCTCACAAATTATCAAATCGTAATGGTACACGTTTTCGCTGGATAATCTTGTCTTGATGT -CCAAGAAATGTTGTTTATTCGGTAGGAAAATTTGCCTAGAGAAACTGATAATAACACACA -AGACAGAAAAAACCCGCAAGTGGAAAGTGTATATCCTGTGTAGAGTCCATTCCCAATGTG -GTAGATCCTTCTGTAAATTTGACAGTGAAGTAGGTCTTGTTTCCGAAAATTTCTGCAATT -GGTTGTAATATGTCCTTAGAATGGGGAAGATTTTCGAATGAACACAGGAGTTCAGTTTCT -CCATCACTTGCCATTGCAATTTGTAAAAGGAATGGGTGGACTTATCCCTTACTGGATCAT -TAATCAAAACGGCTAAATCTAGAATCAATGTCATTTCAACTGGATTTAACAAGTCTTCAA -TTATTGAAGTGTCAAATGGAAGTGACCGAGCTTTGTACGCATCCCTTTCCAATAAAATCT -GTCTCAACTTGGCATTATAAATTTTTATAGCATTTTGAGCAATGCAAGACAGCGAATTTA -AAATCTTCCATTGTAGAGAATTATTGTATATGCACGATTTATAGTGATCTAGGGGTACCT -CCTCGGGAAACATCCAGCCCTCTACATCAATAAAATTAGTTGATAATCTCTGCTGCACTT -CGCTTAGCTTTATCAGCTGGAATCGACAGAGCAAATGGTACCTCTTAGCCAATACGGGGC -TTACATTAAATATAGGACCCTCACAAAGTGATAAGATGAAATTAACGAGGGGAATAATTT -TGTAGGACTCGTCATTGTCTCTTTTCTTCTTCAAATGCGGTACCAGAACGTTTAGTAGCC -TATTCAGTTCATTCAGCTTGTAAAGAGCGTTCTTATATTGAATGATTTTTATATCATACG -AGTCCAACGGAACAGAACCTTTGATTGCCGGAATAGAAGCGCTGGCAGCAGCTTTGGCTA -GCAACTTTTTTCTCTTTTGCACATCTACCATGTTGTAATATAAAACTAGTCTAAATCCTC -AACCTTCAGCTTCCAATCACTCCTTTTATCATTGTTCATTCGCTAACAAACTTCAAACAT -ATGCCTTTATTATGCGTCTTCCTGCTGTTTCAACCATTGATTGCAGGGTAACAGACATTT -TTAAGGGTCTTTCCCACAGCATCTATAAGAAAGATCGTCAAAAGTATTAGTTAAACATTG -AAAATTTGCGCCAAAGACATAGCAAGCGCAACGTATTCATTGTCCATGTCGTCATCTACT -CCCTTTGACCCTTATGCTCTATCCGAGCACGATGAAGAACGACCCCAGAATGTACAGTCT -AAGTCAAGGACTGCGGAACTACAAGCTGTAAGTACAGAAAGCCACAGAGTACCATCTAGG -AAATTAACATTATACTAACTTTCTACATCGTTGATACTTATGCGTATACATTCATATACG -TTCTTCGTGTTTATTTTTAGGAAATTGATGATACCGTGGGAATAATGAGAGATAACATAA -ATAAAGTAGCAGAAAGAGGTGAAAGATTAACGTCCATTGAAGATAAAGCCGATAACCTAG -CGGTCTCAGCCCAAGGCTTTAAGAGGGGTGCCAATAGGGTCAGAAAAGCCATGTGGTACA -AGGATCTAAAAATGAAGATGTGTCTGGCTTTAGTAATCATCATATTGCTTGTTGTAATCA -TCGTCCCCATTGCTGTTCACTTTAGTCGATAGAAGTTCACTCGCAATGCNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNTTACTTTGTTCTTATTTTCTGTCTAATTTTATAATTTTACTGACAGTAGCTAAGCCC -TCTGTATTGCTGTTCTGTGTTATTGCACTAGTGTCATAACGCAGATGGTTTTTAGCAGAG -TCAAATTGGGCAGAAAGCATAATTTCCATCTTCCCTGGCAAAGACAGATTTTCTCTTTTG -ATCACGTTAGCTAAATAATTCAAGATTTCGTTCGGTACTCCAGCTTCGCCCTTGTTAGCA -GGCTTGTATTTCAACAGAATTGCTTGTATTTGGGCTGGATTCAAGGCATACCAGAAATCG -AATAGTAACTTGAACTCGTTCAAGTTGCTTATCTTCAACTGTAATATCTTGACAGCCTGA -ATTATTTGAATCAAATTGGGACGAACGTCTTCAATTCTTGGTTCAAACCAGCTCACCAAC -CGCTCGATATTTCTATCCACTTCGTACCCATACTTCCAATTTAACGCGGGACATTTGGTT -ATTAGGTCATTAAATAGCATTACGTTCAGATACTTCAGGGTGTCGTTAAAAATTTTTGTA -TGCATTGAGTCAACAACTTGAAATTTACACAAGACAGCATCAAATTCATTTAAGAATGTG -AATAATTTAGCGAACTTCTCATCACCAGAATTTTTAAATAGCTTCTCGTTTAAAACCATA -TCGAAGATCTCGATGTGGGCTGAAGCATGCTTCATGAATTTCACTAACCAAGTGGAATAA -ATCTTGTCGAATACTTTTAAAGTTTCATTCTCCAAATCATTCAAATATATCAGTGTTAAC -TTATCTTTTTCATCACCACCATTCGCTTCATATAATGTTTTTTGATTTGCAGCAAATGCG -GGAAGTCTGGAAAGATTACTTAACCAAAAGATACCACCAAGCATTGTTTCGTCCTTTGGT -AGACTCATAACAATGCTTTCTACAGTCAATAGGACTTTCGAGATGAATTTGCTACTTTGA -ATCAATAACCCATTTCTCACTAAGCTACTTACCACTGTAGTAATGACGTGTATAGGACCC -AGAACATTGTCTCCATTCACCTCAGTAACATTTACTTTTTTCAAGTAACCTTCTGTGACT -TCTAATGTGTAACAATTCAGGTCCATTAGTAATTCTAGAAGATCAGGATTTCCTGATTCT -CTACGAATTACATTGACTAGCTTCGGTTTTACTTGTTGTCCTGCGATTCCCAAACCTTTC -ACTTTATCATTCTTATTAGCAGAATATGTGGTGGTGAAATCTTGTGCTATTACGTTTTCA -ATAAACGCTAGTTCTTGCTTCATTGATTTGACTTCATCACTTAATCTTGAAGGTTTGTTA -CCTTTTATAGCAGCCAAACTTTGCATATGTGACTGTATTAAAGAAGATTGCTTCTTTTTT -CTCTCCTTCAAGGCATTCTTCTTGTTTAAAGTATTCATGATTTCAACTTGTAACGTCTTC -AGCTTGGAAATCTTATCATTATAACCATTTACTATCGTTTCGTACTCTTGCCTTTGCTTA -GATGGAATATTTGACAAATCTCCCTGCAACAACTGTGTTAATCTTGTATATGAGTCATTT -AACATCTCTAGATTCAAAATGAAAGAGTTCTTAAATTCGATAGCTTCCTCCAGTAATCCA -ATCCCGTAACTAGCCCTAATATTCCGTTCTTCAACTTCTTTTTGCAGAACTATATACCTT -CGTCTAGCTAACTGCATTCTCATGGCGCTTTGTACAAGAATGGAGCTCCTTTTCAATGTT -CTGTAATCTGTTTTGTGACCATATGATCTGATGTAGCTTTGGATAATTACTGCCGCCATG -AGCATGAATTTCCTGTTAACACTATCTAAAATCAATTTTCTTTTACAGGTACATTGTAGT -TTTATTATTTGCCCAATGGCAGCTCTATAGTATTCCCGTTTCCATAATGCTCTAATGTTC -GTTTGTAGTAATATGGCAGCTCTTGTCTTGAGCTCATGATCGACCCTTGTACGAACCAAC -AAACTTCTAATTTGGCTTTGGCACTTCTTTATTGATTCCATGGTCTGCAAATACTGAAGC -CTATAGTATCTTGCCCTTATCTTTTTCTGTATTATGATGCATATTTCATTCATTTTATTA -GTCCTTAGCTTTTCCAAAAATGCAAGCATTCCTGCTTTAAAGAAAATTTTGGTATTACCA -ATTTGGTATTTTGCTGAATCAGAGATAGTAGCATCTAGAATAGATTGACAGAAGTTGACG -ATTGCCTCTTTTGGGAGGTCTGGATTATAAAGAATTCCACTCCATAAGCTGTAGTCCGTC -AGGAGGAAATATCTTTGAACGAATTCGTCAAAAGTCCATCTTGATGGAAAGCCTGCACAT -GAAATCCTGATTGTTTCCAGCACACCACAAGCTCTTAATTGCGATAAGACCATCAAATTA -TCGAACTCCCATGGCTTTTTTTCAGAATTTGGTTTTATGCAACGAATATAATGAACATTA -GTAGAATTTATGATGGCCATCAATTCCCCGAGCGATTTTTTGAACATAGATCCCAGGGTT -GGTTTCTTTTGACTTAATCTTGCTGGGATCATTATCTTTTTTTCAGTATTTTGCTCTTCA -GGAGCATCGTCACTCCTAAGTTCTCTGTTGTCTAAAATTTGTTTGAAAATTGGATTTGTC -GTTGCTTTGAAAACATCCAGATGACCTAGGGAAACGCTGTCTCTATTCTTTTCAATAAAC -CCTTCAACTTCATATTCTACATCAACAGCATAATGGCTTACTATAAACTTCGTTTGTCCG -AATCTTGGCTTCGAAAAAACTTCATTTGAGGGCGGTTTATTAAAGGCAGAATATAGTTTT -GAGGCCCATGATTCATCTGAGCCTGATGGTAATCTACTTTCTTCATCTAATAGAGAAAGT -ATTCCAAGTTTATTCTCAATCAAGTCTATGCAAGGTTGGTTGTCGCTGAACTCAATGAAA -GACCACTCAATTTCCTCCTTTACATATTCTTCTTGCTCCAATTTGAAAACGTGCTGGTTG -AACTCTTGTTGTAATTTTTCATTCGCATAGTTTATACAGAATTGTTCGAATGAGTTTTTC -TCAAAATGCTCAAACCCGTAGATATCTAAAATACCAATAAAGGAAAAGACATGATCTTGT -TGATCCAGCTCAGGATCGTATAATGTCTTGTTAATGTTGTCTACTAGCCAATCAAAAAGC -GTGGAATAAATAAATTTCGCCACAGAGTCCCTAGCAATTAGCGCTTGATTGTAATTCAAA -TTAGTGACAATTTTTTCAGACCTTGTGACGATTTGTTTCTTGACAATCCATTTTGCAAAA -TTGAAGGGATCAATACCCAATAATTCACATGCGATTTGCAGGTTTTGCTCTTCCGATGAT -AGTGATGCGTCGTTTCTAGTCATTTTCATCTCGATATTACCTATATGTAGCAAGCCTGCA -AGAATTTTGAAAATTCCAAGCTGAGTCTCGTGGTTTATACCTACTAATGACAGGGCATCA -GTGGTTATCTTGTATTCTCGAGCTTCATCTATACCAGCTATGTTCGGCTGTCCACCTTGG -TTAGTATAATGGTAGTCCTTGGGAGATGACAAATGCAGTTCTTGTTTTACCGGTTCTGGC -AATCCTTCCAAAATTTGGTAAAAAATATGGTAATTTCTTTCTGTCTCTGGCTGATAAACT -AACCTGGATTTTTCCAAGAGATAGGTTCTAATTTTGGACCCCCTGATGGTAGTATTCTCA -TCAAATAAAATTTGCAGATATTTGCCGAAACGAGAGGAATTATCATTTCTGGTAGTTTTG -GCGTTACCAAAGGCTTCCATGATCGGGTTAGTAGCTAAAATTTGGCTCTCGATTTGAGAC -ATTTCCACTTCCCCTTCACGATTGTTGCTTTCTTGGACTGAGGCAAAGTATCTCATAATG -TATTTAGCAGAGACGGTCTTACCAGCACCGGATTCACCACTGACTACAACAGTCTGGTTA -GCCTTTTCATGGACCATGAACCTGTACGCCTCCTCTGCTATGGCAAAAAGGTGCGGCTCC -AGCTCATCTTTACGCTTACTAGAATAATTCTGTATCATCTCGCGAGAGTACAAATGGTCG -ACTTTATCAAAGGGATTAGCGGCAATAAGGACAATACCAGAGTAAGTATATATCTGTCCA -TTCATGTATCNNNNNNNNATGGCATGCAGCACTGCCGGTTCGTTCAGATATGATAGGGTG -GTTAAGTCATCAGTAGACTCTAAAATAGGTGGGTTTCGTAGTACAGGTAGCGTGGGATGA -TCATCATCATTTTCGAAGCTATTTGTTTCAATGGATACAGTTTCTCCATCCTCCAATTTC -AACTCTAAGTGGAACGTTCCTTCAAAGAAGTCATTCTTGGTGACTTCGCCGCCTATCCAG -CCTTGTTCTTTGTGAGGGTACCAACACTTAGTTCCTACTTCAAATGACATGCGGGAGAAC -TGGTTATAGGANNNNNNNNNNNNNNNNNNNNNNNAGAATTAGATTGAATTATAAAAAGAA -GAACAAAAGGGTATCGTATTGAAAATAAATTGTCTCGCCAAACTGGTAACAATGTTTTCA -GCTAGAACAATAAGAAAAGAAGAGAAGGTNNNNNNNNNGGTGATAACTCCGTAGGAATTG -AGGAATTGAGTATGCAGAATCAGAATAAAGGCTGACTTTCAAAAAAAGGTTGTATTACAA -TTGCAGGTTTTCGATAAAAGAGACCCTATTCTCATCTACTACTGCTAAACTTCGAGATNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCATTAGTTCAGAACCCTAAAGAAT -GGTAAACATTCTATGGATAACCCGGAGAGTGAGTTTCTTAAAGACCTAGTTTTATTTTAA -GGGTTTTAACTCAATCTTGATGTTTTCATTGTGTACCCTAAAGAAAGTTTAAGAATAGCC -CTAACTGTTACCTTTTGAAATAAAATAAGGGGAAGGTCAAAAAGCTATTGTTCTATTGTT -ATGAAACATTGTCTCAAAGAGTAAGAATAACACAAATTGATGGCAGTTTTTTACGTAGTC -CAGTAGTTGTCCAGGTACAATGCAAAATGCTCAAATAAAGAGCTCTTCTAAAGGCAGCGG -AATAGATGGTACAGATCGCAATAGCAAAGATGGTGTAGAAAAGAGACCCCTGGAAGATGT -AAAGCAAATGATTGACGCTGGAACACCAGATGTTGGCCACAAATCTACTGTTGAAACTAA -GCCAAACGTTGGATGGCAAGCCTCTCACAGTAATTTGGCTGCATTACACGAAAAAGAGCA -GAAATATGAAATGGAGCACCATCATGCTCGTCATAAACTGCATCGTCAAGTTATTCCGGA -TTACACGTCTGCCTCGACCGCAATGTTCAGCGATTGTATGTTCAACGCAGCACCAGATAA -AGTACGAAGTCTCAGTACGATGAAGTCTTCTGGACTCTCGCCAAAACACCCATTTAACGT -AGTCGCCACCTTTAAAGGACCATTCCCGCAGCATAGTGTAGAATCAAAGCCTCTCGATGG -TGGATACTCTGCCAAAGACCATTTTCCCTCATTTAAGATGTTGCAAGCCCAGCAGCACCC -AGCCCATCGCCATTACAAAGACAACGACAAGTACGGTCTTAAATCACCTTCCCGGTCCTT -CGTGAAGGACAAGAAAAGGTTGGTTCACCGGTTTTTGAAATCCATGGAGCCTTCTTCGTC -TGGGCAATCTAAGGATTCGTCTGCACTGGCGCCGGCTTTCGATCCAATATTGCCCAATGT -TATATCTAAGCCTTCCAAGCGACCCACACATCATTCGCATTCATCAGACGGGAGTTCTAG -CACGCAGACAGATATATCGTTACAGAGCTTGCTTTACCATGATCTTGAAAGCTCACCAAA -GAAACATGTTTCGCCCTCAAGACCGCCCTCTGTAGCTTCCGAATCCTCTCCTGCCGTTGC -TAATCCCATTGGGCTTTCGCCAAAAGACGCCTGCAATGCATCGTTTTCGCANNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNATTCTCACAGTCAGTGGC -TGTTGATCCTCTTGAACCTCCTGGAAATATCACATATAGTAGTTCGAATCTTTCGCTAAA -TTCAGATGAATTAGACTACTATCAGCGTCATATCGGATTGCAGTTACAGCAGACAGAAGC -TTTACTAAAGCACAGTTTGAAAGATGAGGTTCTGAAAGATGAAAATGACCTTGTTAAAAA -CATTGCAAATTTTGACAAGATCGTTAAAGAGCTAAGGGACTTAAGATCCAGGACCATTGG -ATGGAAAGAGCTTGTTGAAGAGGATTATTTAATGAATTTGAAACAGGATTTTGACAAGGA -AAACCCCGAATCATTTGAGGCACGTTTGAGTGATACAATAAATACAAACGTGGCAAAATT -ACAAGATTTAGAGAAAAGAATGGCTTCTTGCAAAGACAGGTTGGCCTCTAGGAAGGAAGT -AATGAGGAAAATGGAAAGTTTATTGTCTTTGGAGAATTCCTTAATGATATCCNNNNNNNN -TGTAACATTCGCATCTAAATACCGCAACGAGGCCCTTGATATTGTCTTTTTAATTATCAT -CATCGTCATATGCTATACCTTCAAGCATCTAGTATCGCATAAATAAAAAATAGTATTTGT -ATATCAAAAAATGATCCTGTGATTTTTTCATATGTAACGTATAAATGTAAAAATGTGCTT -CTTCTGGTATTTTTAATCAAGTGGAAAGATGAGTGGAAAAAAGGGCAATGAAATAGAAAA -GGACAGGCCTGAAAGGGAAGAATACAAGAAGATTGAGTATATTGGACTTCACAGTAACCG -TGAAAAATGGCACCAAGTATAGCAACGGTAAAGATAGCCAGGGACATGGTTTTGCCATTA -CGTATATTTGTCAATAGAAAGCAGATCCTTCAAACCAATGATAAGACTAGCAATAAGTCG -AATGCCACTATATTTGAAGCACCATTATTATCAAATAACTCCATAATCTGCTTAAAATCA -CCAAATACAAGAATATATTTATCGCAACAAGATAAGAAGAATCTTTGTGACGAGATCAAG -GAGGACCTGTTATTGATTGTTTACGAACTAGCGTCCCCGGAAATCATCAGTTCCGTACTC -AGCAAAATAAGAGTTGGTCATTCTACTGATTTCCAAATCAACGTTCTGCCCAAACTTTTT -GCAGGTGCCGATACGGATAATGCGGTAACTTCTCACATCCAGTCTGTGACAAGGCTGGCT -AAATTCAAATACAAGTTGCACTACAAACATAAGTGGGAGCTCGACATATTCATCAACAGC -ATTAAGAAGATCGCCAATTTAAGGCACTATTTGATGTTTCAAACATTAACATTAAACGGT -TTCTCATTAAATGCAGGACCCAAAACGTTATTAGCTAGGAAAATAGAAAAACAGCCCCAG -GTACCTAATTTGTTAATAGAAAATGGGGACGCTGATGCCCTGGATACACCGGTGGAAGAG -GATATAAAACCTGTAATAGAATTTATGTACAAGCCTGTTATTAATTTAGGTGAAATTATT -GATGTACATGTGTTGCATAGGCCTAGAAGACATAAGGTACGTACCCAGTCGAAGCAACCC -CAGGAGGAATGAAAAACCGATAACAAAGTGATGGCTTAATATTATAACTTCTATATAACG -GATATATTTTATGGTAAATGTACATATTTCAGTAATGGTAATAATGACNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNGTCTTCTGCTCTTTGTTTCTGTGCCTCATATATCAA -ATGAAATATCATCTCTCGAAGAACTGAATCTATTTGAATTTTGATTACCATCAGCAAATG -GATTTTCAATGAACGGTTCTGCACTTTCAAAGTCGTTACTTCCCAGTCCATTATTGTCAT -TAAAGGGGTTCGCCGAAGCATCTTGTAATTCACCGTACTTACCTCTCTTTTGAGTAGTAT -CATACATTCTGACAATTTTTTCTTGCCCACCCTCTTCAGCCTGTGAAAAGGCAAATCCTC -TTTGTTTTTTCATTCTTTGCACTTGCCTCACCTTCCTGATGGCATTTTGAAATTGCTGAA -CGTGCGGCCTAGAGTCGCTGATATTGTATTTCTGCATTTCTTGAATAACATGATACGTTT -CTGGTTCATACATTCTTTTATAGTACTTCCATAGAAAATCTCTTACCAGTGCAAAAATTG -GTAAAACGATCAAAGTTAACCAAAATACACCGGATCCATACGTGTGTTTAACCACACCAT -AATACTCTCTTGAGATGTTAGCATGAGGAAATATAGAAGCATAAATTGGGAAGAATATTA -ACCAAAATAAGAGGGAACCAGGAATGGCAATTAAGGTGAATTTCGTCCATTGATTAGTTA -CCAAAGCAGCCTTTCCCAAAACAATAATGACACTTGTAGTGTAGACAGTTACACCCCAAG -ACCAATGATCAGCTAGTTCGCCGTGCATATTTAAGGCAAACCCATATCTGTAAATCAATA -TGGTGCCAATAAATACTATTGCAGAATGGAAAAAGCCATTAATAATCCATCCCCAGAAGA -TGTAAACAGAGAAAAATTGACCCTTCTGTCCTAATTTGTACAATTGTGGGTACCGCTCAA -GTAATCTACTACTAACAAATTGATCAAATACACCAATGACAAAAGGGGGCCAAACAGTGA -AGAATAAGTTGTAGAAACTCATTGTCCATGATTCCATAATGGATTGACCTGAAAAGGCAT -TGGCAAAAACGTACCAAAACTGCGTCATGTATAATGCTGTATTCTTGTAAAAAGAGTACA -AAATTGCGACAGAAATTCTTTGATAAGACCAGGAGCCATGGACAAGTAATAGTTTTTTTA -AAAATTTAAATTGGCCAACAGCTATATCAGCTGAACGAGCCGCTTGCATACCTTCCATAC -CACTAATACCGACACCAACATGAGCTGCCTGTATCATACTAACATCGTTGGCACCATCGC -CAATGGCTAGCAGTAGTGAAGACGACTTTCTTTTTACCATTTTAACAACCAAGGCTTTCT -GTAGTGGAGATACACGGCAACATATAACCGCTTTACAAAGCTTCGCCACAGTTAGCAAAT -AATCTTCTAATTCTGGTTCCAAGGCAAAGCCTAATGACTTCCCATCAATGACGAGCGCTA -AGGTATTCATATCATGTGTTGACAATTGATGCTCGTTTAGAGCGTTAATCTTCTCTAACA -AATTTCTCTCAGTATCATCTCTGGTTTCCTCGTTGATGATCAACAAATTCATGTCTTCAC -TCAATAAACGGCAACTCATACCAATGTTAATAGCAGTTTCCTGTCTGTCACCAGTTAAAA -CCCAAATTTTAATACCCGCTTCTTGTAATGTGTGGATAGTTTCTGGAACACCGTCCTGTA -ACTTATCTTCAATAGCAGTTGCACCAATTAATATTAGATTTTTCTCGATTAGATTTGCGG -CTTCGTCTAGCTTCTCGGCTCTGTTATCTAATGTTGTGGCAGCCTCATTATAAATGCTAT -TCCATTCTTCATATTCTCCTTCAGAGATATCTCTCATCGCCAAACACAACGTCCGCAAAC -CCTCAGATGCATAATCTTCTAAATGTCTCATTGTAGCTTCTACATATTGATTAGCTTCAT -CATCCAATCTTTCCAGAATGACAGTATCAGCACCTTTACAGAATAACTTTATCGAACCAT -CCGGAAATCTAAATATAGCGCTCATTCTCTTCCTGGTGGAATTAAATTCACAAATGTTAA -GTAGTTGATACTCTTTTTCCTCGCCAGTTTCCTCCAATAAAACAGTTACAGAGTTTGGTT -TACGGATGATAAACTTATACCCTAAATCTGCACCACCTTGAACGAGGGCACCTTCATCTG -GAGAGGCTGCTTGATATTTAATAGATCCATCGCTTTGAAATTCTGGAATGACAGTATGAC -AGGTAGCCAGTAATGTTAAGAAGTCATTGATAATAGGTGAATCCTCATCAGAGGGATCAT -TTAACTTTTTCTTCAAATCGTCAAATTTTCTATAACCAACTTCAATCCCATCTTCAACAG -TGGCCGTTTTATCTTCAGGTATTTTATCAATATAGCAATGGCCTGCAATAGAGCAGGATT -TAAATTCCATAATATTTCTTGTTAAAGTTCCTGTCTTGTCACTGAATATATATTCTATTT -GACCAAGTTCTTCAACCAAAGAGGATGTACGAACCACAGTTGGGGTATCAGTTTTTTCGT -AGTACAAATCTAGATCTGAACCTATCATAAAAGCCTGATAATATTTGATTAATTCAACGG -TGACAAATAGAGAAATAGGAACTAGATTCGAAAATAGAATCCAAAATGTTAAAAAGTCTT -TGAAGAATAAGCCAGCCTTGTTGGTACCCTCCAGGTAAAGGTACGATAAATGTTTGGCAT -CTGCAGTAGACATAATAACATTACCAATTGAAGAAATTAAAATTAGCACGATTAAAACTG -TGAACAATGCAATAATCTGTCTGTTGATAATTTTCTCAACCGCGGTTCTTTTAATTGGGG -TTGCAGTAGCATTACGCAATAACTTAGTTTCATGACCAGTGAAGATAACTAAACCAAATA -TCCATGCAGTATTTCTTAAAGTTGCACCTCTTAAAATCATTTGGTCAGGAGATAACGGTA -TTTGACGATCATTTAAAGTCATTGTACCTTCATAAGTATACAAGCTAGAGTTCGGCTGTT -CGGAAACAACTTTTCCGTTCATGTTCTTCAAAGTTTTAACGTCTATAAATTTGGCAGTTT -CTACTCTCGACTGTTTGATTTTCAAATTTGTTTCACCATCCAAGTTGGCAGTTTCAATGT -AGCAAAGACCCTCCGGTTCCGAAGATGACAAAATTATGGTATCAGCAGGAATAGGTTCCT -CTGATTTTACTCTAATTATGTCACCTACACGAATATCAATCCATCGTTTCTCAACAAAGT -CATCATGTGCTTCTGAAAATATTTCTGCTGTCGAATTATTTAATTCTTTATCAGAATTAG -CTCTCTTGATATCTTCGATACATTCCTTCATGGCAGAAACAATCAAAACCACTAATAAAG -TACCAATTGTGGTGTATCTATTAGTTGGCGAGACGTGAGGCACCTGTTGAATGGCAGATG -TACATNNNNNNNNCAGATTAGCGTATTTGGAAAATTCTTGGAACAAAAATTTAGGCAGAA -AGGTCGCAAAATTATACTTGGTGGTAGATATATGGTTGTCACTATAACCGAAGGAGGAAT -TAGCGAGAGAATCGTTGATGTGGATGACTCTTGGTTCACCATTGCCCTCTGCGTCGCCAA -CGTTCTTTCTTAAAATGTACCGGTTGAAAAGAATTTTAATGTTGAACTTATTCCTCGAGT -CTAGATAATTATCGTCTAATTCGTTATTAGTCACCGCATTGTAATGATTCATTTCGAAAC -TTTCGGGCCCTTTCTTCCGTTTGAACGTAAAGGCATTTTTGAGACCATTACCAAACCTAG -CAAATAAACCGGGAGGCTTGACTGCTCGTAGGGATTGTGGTTGATATGCATCTGAGTCGA -ATCTATTGGCATTCCAAGACGTTTGGTCGTCATGGTTATTGCTCATAAATAGATTTTCAT -GGACATCATTTTCAATGTTATCATCATCAGCGTCTAAGTCGATAGTCTCTTCGGGAAGTA -CATGACTTGGTGGTATATAATTCGCGTTCGCATGTGAGTTGGTGACCTTTGAACGGGATC -CAGAATGAGAAGTCGTGTCGTCTAAGAAGTCAATATCGAAAAGCGTGTCGTCCTCCCCAG -GTTTCCTCTTTGGGGGGGTTTCTCTGTCGTCATTCATGGTAAAATCAGGGAATGAAAGAA -CCTACCAGTAAATTATTGCTTGGCGCTAACCTCTATTTGGCGTTACTGGCTTCTTGTTGC -ACTATTCCCCTTAGAATTGCCAACAATTGTTGATTATATGTTTCTTCAACTTAGTGGCAT -TAAACAGATTTGGGTTTTCTGGCAAAAAAAGCCAATCACGTGATCAGGAAGATTTCAGTG -ATTTACGCTTCAAATAACCTTTACCTCAATAATCCCGNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNTTGCAATGTTATTAGCCCAACAGCTACTAAAGGTATTANNNNNNNNNNNNN -NGATAAGAAATTTAAGTGTTACAGAATGGGCCATCTTACAAAAATAATAGTCTTTATGTA -TTTTTATATATGTAAAAGAATTGAAATATTTTATAACTGGTTGTTATTATGGTACAGTGC -GCTGCCCAATCCACGTGGAAAAATCCTGTTCATTCAATAATAGAAACTGAAATCATGTAA -TGTTGCGTAGTATAGTGCGTGAGCTTATTGTGCCACTTCTTGCTCAGCATTTTGAACTTC -GTGTTCCTCCTCGTATTCGATTTCGACTTTAGGACGTTTAGTTTTGGCACTAGTTCCCTT -CTTACGTCTCTTGGCTGAATTCTTATTTTCTTCATCACTATCGNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNGGAAGCTTCTCTGTCAGAGTCAGCTAACCACTT -TTCTAAGTCATCCACGTCAACGTATTCACCTTCGCCATCATCTGCAACGTATTCAACTTC -CCCATCATCACTTTCCTCTTCTTCATCCCAGTCTTCTTCCTCGTCCTGAGAATTCTCCTC -TTCCATTTGACCCATTATCTTCTTCCAGACCTTTTCGTCAACATTTAATGGTTTATCACC -GTAAGCACCACTCTTTAATCTGTCCATCAATTCTTTTTCGATGGCTTTTTCAATCTTGGC -AGCTACCAATGCCTTTCTCTCCCTGTTTTGTTCTCTTCTTTTGACCTTTGGTGCTACACC -AACGTAGTGTCTCTCCTCCTCCCTTAATGCTAAACGTCTCTCTGTTATCATGACCTGCGT -CAATTTTGTAAATCTCTGTTTACACTTATGACGGAAAAACTTGCTCCAATGTAGTAGGTG -TTCGTCGATCTGTTGTAAAGCCTTCGTGTAATTTTTGGATAGTTTGATTCTTTCCCATAA -CTTGGCAGGAGTGTGCGCTCTTTCAGGCGTCTTCATATACAAGTACAGTTTCCCATTGTC -ACACTTCACTGTTGCATACTTGGAGTTGGCAAGTGGGCATGATTGCCTTGTACACAACCC -AGTGACGTTATACTCATTTCTGCAAAAATTTTGACCATTAGGTGCCTTAATTCTATGAGA -GCAGAAACTTTGATTAATCACTTGCCAAACAATTTCGTCGGACATATCCTCGTTGTATTC -TAACCGTTGTAGTTATGTACTGAAGAGAACACTGTCAAAAGAAAGAACTAAGCAATGCAA -TATCTGCCTCTATACCAATCACNNNNNNNNNNNNNNNCAAAAGCTCATCGGAAAATTTTT -CNNNNNNNNNNNNNNNNNNNNNNNNGGTTTATTACCCTACTGCATTTTGATAATCTGAAC -ATAATGAGCTAATGAAAGCAATTCTCATTTAAAAACAAGTATTCTCTCTTATTGAAGTAT -GCATTATCTATCATTATAAATTCTTTTATTCTGTTCGAGTCCATGTTTTTNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTTTATATGCAAAGTTT -TTTACAAGAGGAATTTGGGAACTGGAGGAAAGTGGCACAATACCTCATGTGGATAGTTCA -TTAATCTCTTCTTGTGTTAATGTGCTAATATAAACACACTTACTCAGCAATTCGTGGTTA -ACTTTGAAAGTGTAAAACTTGGACCATTGAACCCTTTGAATGAAATTCTTGACTATTTGA -ACGTTCGTATCGAATTTATTGTAATTCACTACTTTATCTTCTAAGATCCAGTCTTTCTTC -TCTGCGTTTGCTGATAGGTCCGAAAGATATACGACGATGAAAGGGACGCAACCCACCAGT -GGATTCACAGAGTTAAGTAGATTTCTTATTGTAGAATAATTCCTGTCTAGCGAGGGAATC -TTCTTTAGCTCTTCCCAAGTCAGTAAGTCGCCTGGTTCAATCAGACGCCATGCATCAGTG -AATTTTTGAACAACTGAAGAACTTAAGGCTAGAATGATTTCCATCAATGTGTTAAAGTTC -TGAAATGTCCTGCAGTGGTCTGCAACGTGTATAAACCTTTGAATGACATTTCTTTTCATT -TTGCTGCTCTTGGTAAGAAGTATTTCTGATATAATCCAATCCACAGTTAAGTTAAATCTG -GATATAGCTAAATCAATGCCAGATAAGGTCTCGTTCCTTACTAGTAGTTGCAACCAACTT -ATAACTTGTGGGCCTTCATGCTTCATCTTTAAATCTAATAAATCTTTCCAGTCTATTTCT -CCTAAAATTTCCTTCTCTATCAAGGTCATTTGTTGCGCTACAGACAGGGAATCGTACATT -AGTATAAATGGAACGTGACTTTCATTATTAGAAATCATTAATCTCGAATCGTGAATCCTG -TATTGACCGATTAATTCCTGGATTTGCGCCGCTTGCACAGCAACATCAACATTAGCTGAC -ACGTCTATTTTTTCAGGAGAGGAGGAAGTAAAGCCTTCCTTCTCGGATTGATCTGGAGTA -AAGGGGATATTCATTATAGTTTGTCTCCTTCTTTCTATTAATAACGATTTTCTTTTTTCT -GCGGGGCTATTTTGGAATGACGGCAAGTTGTTAAGGTTTAGCATTTCCACTTCATCTGCT -AACTTGCTCGTTTTAATTCCAATAGCGTCACTACTCTTGGTGTTCTCTGGTTTTTCGGGA -ATTTTCTCGTATGTACCTTCCAGTTTCATTAATGCCACGGTTATTGGATCGTCATTAATT -GAATCATCGAGCATATTAGCAATTTCATTTAAATTTTTCTTATTCAAGGAGCCTGTAAAA -GCCGACTCAGAGTTTGCTCTCCGTGTGTTCCGGGCACTAGATGTGTCATTAATGTCGATA -TCGTCCATTGTCAATACACTTCCTGATATGTTACTATTAGTTTCACTCTCGTTCTTCAGA -AATTTACTTTTCAGCTCTTCAACGTTTTTCATTGGAGAAGCAACGTCAATGCTACCGTCA -TCTGGTGNNNNNNNNTACTTGTTGTTTTTCGCATGGGTACTTGGACTTTCTAGGTCATTA -TTGGAATCGCTTAAATCAATTGTTTTTAACTCATGCAATGAAGAAGTATTTGAGATTATA -TCTTGATTACCCCTTTGATATTCTTCTCTCAAATTTATTATCCTTTGGTGTGGCACTGGT -AAATCTCTGGACGTTTCGAAAGTTTCAACTGTGCTACCAGTGGTAATCGAATTCAAATCA -CTTACAACAGATTCTATTGTGGGTGCTATGGATAATCTGATTCTATTGGTTTCACTCACG -CTGGTCCCGTTGGGAAATTCTCTCTGTGGATTTTGAGTTTGTTTTAGAGGACTATTCTGA -GCAGATTCAAAAAGCTTGCTCGTTGAGATACTGATAACGGTGGACGATGTATCAGAGTAC -AACGCGCTTTTTTTATTATATTCCAGGTTGAGAGGTTCTATTTCACTTATTTCCTCTATA -ACTGAGTTTGACTTGTTTTGCTCAGGATCTACTATGGATAACTCTTTGGTTGGTGTTATG -GCAATGCTTTGAACTCTTGAAATGCTGATCCTTCCACTAGCCGGTCTTACAACTGCTTGT -TTGATCTTGTGATTGCAAGATGAATGTTTTTTTCTTGTAGTTATATCATAATTATTGGCT -TCTGATGATGCATCGAGTGAGTTGTCCAGCTTTTTTGTGCTCTCATATTCTGATTCCTGA -TTTTCTTTGTTATCATAATTCTTTTCAAGGCCATCTATAGTACTCTTTTTCTCATCTAAA -GACTTGGTATCTTCAAATGTAAACTCTCTTAGATTTAAAAATCCAGTTTTTGTTTTTAGA -GTTGGACTATCTGTATTATTCACGATGTTTCTGACTTTTCTTGACTTTTTCGTTACAGTA -TCTCTGGGTGGAGAGCTGGATGACAACTCGGAATCGTATGAGTATGTTATTGATTCTGTG -TCTTCCCTACTATCGTTTAAGGGAGACGATTCTTTAAGATCAGGTAGAACATTTTTCAGA -GGCGAAGAAGTCATGCTTTTTTGGGATTGGGAATGATTTTTCCTCCTTGGTGTCATATTT -GTAATCGCTTCTGAGTTGGTTTTATCAGTTTCATGGAATAACAATCTTTGAGGTCCATTC -TCGTCTGTACGTGAAGAACTATTATCTTTATCAAAGAGCCTCATACTTTCTGCTGAGTAG -CTACCGTGCATTTTATTGTAATATGCTGTCGTGAGACTTTTTACTTTCCTTCGTTGCAGT -GCATCATACGAGGGTGATGGCTGCATATTCGATTCATTGTTCTGCAGTTGCTTGTTTAAA -GTATTAGTTAAAGAGATGACTGACTGAGCAATTGAACTTACGGTTTGATACAGATCCAAA -TTGTCCATAGCGCTAAAATTATCATTACTCGGTTTAAAGCTATTTTGTTGTAAAATCTTT -ATATCATGTATGTGTTCCCGACGTTCACAATCAACATTAACTGTAGGACCTCGGTTGTTA -TTCGAATGTGTTTGAACTTTTTCTATCAGCTGGTTTTGTAAATGCAGTAGGGACTCCACT -TCATCTATGGTTCTTGCACTTAGGATGTCAAATTTAGAAGAATCAGAGTTAAGAAACTCT -TCCTCTTCTTCCTTGGAAGATTTTCTATTGAGAGATGATATTGATACAACGTATTTGACA -AACGCATCCATTTCAGGTTTCTGGTTTGCTGGTTTAATAGCACTCATAAATTTTTTATCA -TTACTGCTATCATGGCGATTATGGTTTTTCATCCACTTAGCTAAAAGACCAATAGCGCTG -CGATGTAACACAGACATTGAAGATGTATTAGATCTACTATTACTGTTGCTATTGTTATCT -AGAGATGATGTCGTCGATGTACCTTGAAGCGTTCCGCTTTGTTCATTTAAATCTTCAGGA -ATATATAAGGAATTCAGAATAAATTCAACTTTTTTAGCCGGTGTTGGAGGCATTATTTTA -TCGACTGCATATGATGACGGGTAGTCTACGCCTTTCATTAGTGTGGATACTAGAGTGACT -TTTGACAAGTGGCTGATCTTTTGTTTACTATCTGACATGTCCTCGCTTTCATTATCAACT -GAAGGTTCTTTCGCTATTCGGTGCTTCGAGTAAACATTTGATGTATTATCGGGAAATAAA -AGCATAGAAGGGCTTCTCTGGTTTTTGGAAGAATTTGAAGACTGTAGCTTCTCCGGCAGT -CTAAATACATCAGAAGTTTTATATAATGATAAAACGCTTTGGTTACGAAAATCAGGACTG -GCAAAACTTTGCCTGGCGTAAATGCTCAGTCGGCTTCCTCTTTTGTGTAGGCTTTCTAGT -TGCGTGAAATCCTTTAACGAATAATGCAGCCATGCATCAAAGTCTAATTTATCAGGTTCA -TTTAGTTCAATATTCTCCCAAACCAACTTAGAACAATGCACCCAGNNNNNNNNCAGATTG -ATTATACAGCTGGAAATTATTTTTGGGTACTGTTCAATGTGTTTGTCGTTTAGAAACTCG -ATCAACCGAAGTCTTAATGTTATGTTCGGTAAAAAATCTTGCACAAAATAATTCAGTATG -GAATGCCTCAACAACACAAACGTCCTCACGAGGGCAACTTCACCAATTCGCCTTCTCTTA -GCTTTTGCAGCATTTGTTGTGATCTCCCTAATACACCATCGAAATCTATAGATGAGTAAG -TCGTGTAAGTCTTGAGGCGTTATAAAATTCCTATAAATAAGGAAAAAATCTGCAGATGCG -TTGTAGTCTACACCTTCCAAAGGGGAAGAAAGGTGTACAATTAACGCGGGCAGGTCTGCA -CTATTCACTGGTTTGGATACACAATCGCTTTCATAGCTAATAACATTTGAGGATGGAGTC -GGGTAGTAATCTTTCTGGCTAAATATTTCCATGGTTCAGGGTAGCGAATCTTTGAATGGC -TAGAGGCTATGTAAAGCAAACAAAAAGGTTCGCGTAAATCAACGAGCGAATAACACGAGT -ACGGTTGGGGTGGGCTAAAGGGTTCAAGAAATTATCAGTTTCTGTTTACAGNNNNNNNNN -CATTGTTGATAAAAAGATCAAGAATTTCATTATTCGCGAAAATCAAAATGCAGAAAGGAA -AAAATAGAAGGGTAATAAAACAGCATCGGATCGCAAAGATGAGTAAGGAGAACAGCCTGG -TTAACAATTAAAGAGTGTTTATCGAAATTCATTATATAGTGGTTTATATAGACCACTTCT -TCTGCTGGTTGATATAGAAATTTTATTTAATTCTTGTTTTTTACTTATGTACTTACTACG -ATGATCTTAATTCATGCTTCTTGCTTGTCGGCAATGTCCCAAGTGGAAAACCAGTTTAAG -TAGCGGAAGTTACTACTTGGTCCCTCCATACCAAATGATATTGGGGAGAAGTACCAGAAG -CAACCAATTACAAGTGCCATGAATCCGGCGTATAGGACGAACCGCATGATACGGCCGCAC -TTAGATCTGGACCATTTTTGCAAACCGGCGTCGAAACAGTACGCCAAAATGATCAGTGCA -AAATACAAGGCAGGCAAGTAATGATGAACGTAGGTGACTCTAGACATGATAACGAATGGC -ATGTAGTGTAGGCCCCAAGCTAGTAGTGGGTAGAACCCGCCCATTAAGAAAACGTTCCAG -TTAGATGGATTTCTTAGGTCCACATATTGTCTTTGCCATCTGATCAGTAAGATAACGACC -GTGGCCATGAATGCGAGGACGGCAACACTAGAAGCCCACGTGGAAGCTGGGGTACCCAAT -AGGAAGTATTTTGGATTATCATCACCCCAGCCACATAGTCTCAAACCCACATTCAAAGTT -GGCCATTGCCATGCTGAGGAAGCTAAGTAATCAAATTTGTCTGGATCTGGCACCAAAGCG -TTATTAGTGGCCATCATGGCTAGATTTAAATGAATGAAGTCTTTTAAGAAGTTGGTCTTT -GGGTATTGAAAATCTTCGGGTCTTGGTGGCAACCTTTCATTTTCGTGGGTCTCGATGTTC -CACCAGGTCCTCTTGTCCCTCTTGAATGGGTTTTTCATGCAGACAACCTCTTGTTGTCTG -AAACCCCATTCGGGCAAACTGTTACCGGTTTGAGCCAAGTAACAGCCCATCTCCAAGTTC -TTGATACGGAAAGAGGTGGTCAATGTGTGCAACTTCTCAGGGTCTTCATCTCCTCTTTGG -TCCATGATCTCAATAACCCAATTGTCTTTGTTGTCACCAACAACATTGTCACCGTAACCA -GAAACCTCCCATTGTGTCTTTGACACTGGTGCAGCAACTGGGTGGGTGTGCAAGTTTCTG -CCCGTGCTTTTGTGTACCAATCTATAGGAGGTACCTGGCTTCAAATACTCGATGTCAGTT -TCGTTTTCTGACCATGATGGTAAGCCTCTTTCTCTGTTGAAAAACCATTCGTTGTTAGCA -TCTTTGTAACCATAACAGGTTACTTGTTGTTGGTTGGACCCATCTGGATAAGTTTGTATA -TGTGAGTGCAATAGAGATCCTCCAAGAGCTTGGTTTTTGATGGAAACAACGGAGGAACCT -AGAGCAATGTCACGGGGGCCTTGTCCGACGTCAGAACCCACTAATCTTGCTTGGAAAAGA -GATGGCATGTTAGCATCACCTGTACCAGAATGCGATAATAGGTCAAAATGTATTTTGAAG -CACAATAGGAAAATGCAGAAGGGGACGATAATAAGACCAAATATTCTTGCCAACCAGTGG -TTAATATAGGTTTTCCATGACATGGATTTATCTGCCAAAAAGGTCCATAAGTCAATCACA -GTATAGATACCGACCATAGTGATGATAAATAGACCCACCATTTTGACGGAAATAGTGCAA -CCCAAAGAAATACCAGTGATCAACAGCCATTTCCACCACTTTCTAGAGAACGGCTTGGAC -CTCTGGTTGTGGAACATAACAAAACTAAAGAACGATGCGACAGTGAAGAAAAGTAGCATG -GAGTCCAAAAGAATGAACCTGCCCAAAGTACTATACGAGTTTTCAAACAAAACCAACACG -GTCATCAGCCAAACTGTTGGTAAAGAAAATCCAATAGCTTTGGCAGTGAAGTAGGCCAAT -GGCACACAGAGCGCGGAAAATGACGCGTTGAACAGTCTCATTTTAACATAATCCAAATAG -TCTGGGTAAATTTCCCCAGAAGGGAAGTCCCAAGAACCGTTGTAGCCTGCCAAATAACCA -GACAACCCGACCAGCATTTTTCCTAGGGGAGGATGGACATCGTGGTAAAATTCGTGTCTC -AAGTAATAAGAACCAAATTTACCAAAGTGCGCCTCATCCCAAACAACATGGTTGTTGATG -CCGATTTTGTACATCCTGGTAAACAACGCCAATGCAGTAAAGATCACCGGCATTACAACG -GATTCCAGGCGTAACAGTGAGCTTTGTGCAGCGGGCTTTTCCTTCGAGAAATCTTCCGCG -TCTCTCTCATCAGCGCTCGAAAGTTCCTCACTGACGCTGATGGAAGACGATTCTCTTTGT -CTCAGTGTATTCTCTTGCTTAATGTGGGCGGCATTGTTTTTGCTGTACCCGGTAGACGAA -GACGAGGACATGATTGCTGGACCACGGTTCGAAACAGAATGACAGTAGCGATGTGGACTA -AGCCGGTTCTCCTTGGTAATGTTGTTAGTCTCGAGAAATGACCNNNNNNNNACCCTCAAA -AAGAATGCAACACTATTAATAAACAGTACACGAAACGGNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAGGGCGACGTGTCCAATAATA -TGTATGTTTGTCGCTATGTACGAGATATTATTGCTAAGTGACAGTAAATCGTATCACGAC -TGTAAATGATGGCGTTTCGGTATGTACAGTATCTATCTACCTGATAATAAAGTCAATTAT -GAAGACGAATACGTAGCTTATGATGCTGCCCAGAGCTAGTCCTGTAGAAACGAAAATATT -AGTGAATCCACCGGCCGCTTCCTTCTCGTCGTCGTTGTCCAGTTGCTCTGGCACCTTCAT -GAAACTCATAGAGATGACGTGCCCGTTGGTTACGCCGAAAAGGAACTGCAGTAGCATGTA -ACACAAGTCAACGATTACGGAGCCATTGTGCTCTTCATCGCCGCTTGAAGAGGAGGTGAT -GGCTGTGAACATCAAGAACAGTGGTATTGCGGCCACCCGCAACAATGAGTAGATGAAGGT -TTTGCGTGGCGTAAATTTCTGGTCACGGAACATGGGCCAGTCGGCAATGACTCTTCCGTA -AAGGTCGCCTAGGTTCCACAGCGTGAATATGAGAGGTATGTACTGTGCGTTGCTTAAAGG -AAGCCCTGTCACGTAGGTGGCAGACGCAAATACAGGAAAAACAAGAGTTACGACAAACGT -GGTGAATATGGAAAGAACCAGGTACTTTAGTTTGGCAAATAAGACCTCGAAAGGCACTTT -TAGTTGGAGTTCCTCACCTTCGTCGTTGTCGTCGCGAGTGCCGTTGGTGCGGCGGTGGTC -TTCATCCTCCATTTGGTCAATGCGGCCAACAATACGGATTTCCTCCTCATTGGAGCGCAG -AGACCCTAACAACACATCAGTGATATGTCCGTCTTCCACATTCCAATTCTCGTTCACTTT -CCGACTGATTTTGCTCACGCTGAACATGACCACACAAATGGTGACCACGAGTGTTGTGGT -AAAAAAGTATAGAAGAATCCCGCCCGTAGTAGACACAGAAGAGTTCTCGATGAAAGCTAG -GGCAAAAAGCACTAGGGAGGGCAGGACACCAGCAACGGCTTGCCCCACCATGACACCTTG -ACTGTACTCGGAACCGAAGACGTTGGCTATGGCCATGATACCATTCTGTGTCATGGCTGT -CCCCATGGAACTGATCACTACAAGCATCATTATAAACATGAAATTGAACCATTTAGGTAA -AAGGAAATGCAAAATTGTAAAGAAGCACATGACAGTAAAGACAATAATCTCCCACACAAG -CCCGTTTATGACCCTTCTCGAGTATTTGTACTGTCTTTTGGCCAAGTAGATGTTGAACAG -CATTGACGATATGGTAGAAAAGGACATCATAGAGCTTGTGAAGATCTTTGCCCAAATGGA -GGTGTCTTTGAAAATATCGTGCTTAAAATATTGCGAGGCACTGAGGATACAGTTCCACGG -CCATAAAAGACCTATTCCTATGGCGAAAAATGTAATATATGAAAGATTTTTCAACTTTTT -TCTTAACGGCAATGTATCCAGTGGTTCGGTTGACACAGATTGCTCTCTTTCAGAATAATT -ATCGCCTTCTTCATCTGAGTGCTCGTTGTTCTCTGATTCATGTTCTTCTCCAGAGCGTGA -TATCTCCTCTGAATGCGTATCGGCCAGTGCAGGCTCTGGCACCGCAAGGATTGGCTTCTT -GATGGTATCAGTGTCCGCACTAGTACTCATTTTTGCAATCTGGTATGCTTTCTTGCGTTT -GATGATAAGCTGTCGCCGTAACGTAAATCATTCATCCTTTCCTATGANNNNNNNNNNNNN -NNNNNNNNNNNNNNNCGGGAAATTAATTCTGTTTTTGGCATTAATAACAACAAGAAGAAT -TAAGGATTCGTTATAGAATACAAGATTCTTGGTTTGGTTAAATAATTTTGGCTCTCTTAA -ATATTATAAAAAGATACTTAAGTAAGAAAGAAACAGGACGAAAAAGATACGCAAANNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGTATAACGTGAAGGCTTTATGGG -AAGTGCGGTGAGATTGGGATCGTTTCAATTTTATAATGAGGTAGTGTACAGAGAGGAGGG -AGGGAGTGGGATGAAAGTGTGCGGTTTATACTTTCTTACTGCCTGTGTTTGTCTTCATAA -ATTCAAATCTTGCTAACAATGGTATATGGTCACTGGGGAATTTGTCGTTGGGGAACCCGA -TAAACTTACTCACGTATTCAGGGTCCACTTCACCCAATAGCCCACGCACCCTTAGAGCAT -GTGTAGAAAACCATATATAGTCGATAACATCTGTGAATGACGGTGTGAAATTGGTGAATG -GTAGTTCTCCGATACAATTATAACTTGATTTGAGAGCCAAGTTATGTGAGAAATTTTTCT -CCGACATGTAACCGAAATCTCTACCATTTCCCTCTTGATGTATTTGGACACGGCCTGTAT -TTATCAATTCGTATACGGCGGAGTTGATGTATGAATTGAAGTCACCACAAATGAGCACAG -GAAATTTCTTAATGTCCTGTCTAAAATTGTGCGATGTCTCCTCCTTTAGCAGCGTTTCCA -GATGATCTAACAGGACACCTACTTGGAATGTCTTGACATCATTAAATTTTGGATCCCAGT -GCAAATGCGTGGTGACCGCCCATATGGTGTCGCCACTAGGAATGTGTTGTAGCTTTAAGA -ACAGTGCAACGTTGTCTTTGTTCATTGCACGGTTTAAATAATCTTCAGTTCTTTGGAACT -TCTTGTGTTTCATCCAAGCACCGCTGAAATCCATGGCGTCTTTGGTGATCAACTTGAATT -GGTCCCTTTTGAAAAAAATGCAACACCCGTCCACTTTCTTGGAGTCCTTGGAATGCATGG -TCTTGGCTCTTGCCTTTGCATGGAAGATGCCTGTATAACCGTGCTTGTCCAATAGGGGCA -CCCAATACTCTTCAAAAGTCTTAGACTCCACTTCTTGTAAACACAACAGATCACTGTCGT -ACGAGAGAATCTGCTCCTTTAATTTATTGCGCCTGTAATCCCAACTTAACGCCCACGACG -GTGTGTAACGGTACATTTTTGGGGTGGCATAGTGTTGACATAAGGTGTTGTAGGATAAGA -CGGTGAACGTCCTCTTGGCTAAATCGGTGGCCAGATGCTCAGTGGATTGCTGCAAAGAAT -CGTACTCCCTCTGTGGTTCCCCATCGGTATTGATTTCGATGAACCTACGTTCATGCGGTA -AGGGAATCTCTGGTCTGTTGTCCCTTAGGTAGAAAATCAATCCCGTGACAGATTTTTCTG -TAAGGATCTTTAAAAACTGTTTTTCTAAGGGGTTTCCTTCTACACCAAGAAACTGAAGGT -TACACAGGTTCCCAAACTCCCATGGTAATGTGGTGACCATGTTATCAAAAAAGTAGAAGT -ATTTCAATTGGAAACATGAGCCTAGTTCCGCTGGTAGAGATGTTAACCTATTATGCGACA -GGTCCAAAACGCGTAGGTTGCTTAGGTTCTTGATCTCCGCTGGCAGTTCCGTGAGGCTAT -TGCCATTCAAATATAGTCTCGTTAGAAAATCGTACTTGAAGATGTTGGCGCTGATATTGA -AGATTTGCAAGTTGGACAAATCTAGCGCGTGCCATAATTGGTCGTCGTATTTCGAGTCCT -TGGGCATGACCATTCTGTTTTCAATGTCGTCATCTTCGTCGATGCTGTACTGAGACAGTT -TCTTGTGTTGTAAGAGCGCCTGGTTGGCTTCGTCCTTGCCATTAGCAAACAGCTCTATCT -TGGGAGTCAATGGTGTAGAAACTGCACTGTTAGTTGCCGTGCCTGAGGGAGTGCTATCTC -CCGTAGGTTGTTGTTTCTTTGCTGTCTTGCTGTCGGTGAGAGTGTCGGCCATTTCCATCA -AGGCTTGCTTTGTGCAGTCTACCAGTGATTTGGAGGCTTCTGCAATGTGAGATTGCTGGA -AATCGGTGGGCTGCAAAGCTGGTGGTGCAGCCTGAGGTCCGGGGCCAAATGGGCCCGGGA -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTGTAGCCA -AATACTTCTTCATAGCGTTTTGTCTAGCATAAATGTTGGGTTGCCCCAGAGATTGTGCGG -ACACTGCAGCCAGATGCAATTGAAGCTTCCAGATCGGATTGTTTAGTAAAGAAGGGTCAT -CCAAGTGCGGGTGTAATAAAGGGTTACTGGCGTTCACATTGATGTTCACAGGCGTACCAA -CGGTAGGAACCATCCCTATAGAATTTACTGCGGCTGTGGAGGCATTCATCATCACCCCGC -TTCCACCGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNCATATTGAGCATGTTCGCGTTCCCATTAGCCAATTGGTCGAGCAACTGGCGCGAGT -TGTTGTTGCTGGAAGTGTGTACATCGCTGTTGTTCATGAGTCCCGGTGGAGGTATCCCGG -TGAGCTGGTTCATGTGTAGCTGCTGCTGTAGAGCGTTTGGTGTACCCTTTCCTAGTAGCC -CGGCANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGGGCCCACATTAGGGTAGCCTA -GTAAAGAAGGGTCGTTCATTAGCGGTAGTTTGCAGGGATAACGTCAGTCGGAGTTCCCTT -GCTGGTGTCCCTTATGCTGTGCCCTTGTGCTTGAGAACCTTCTCTAAGGTGGAAACTTTT -TCAAATTTTTTCGTTGTTGGCCCGTTTTTCGCAAGTACGGGCGATAACAAAAGGCCTAAA -CGGCTACTTTACCTTTGAGATCTACCACGATGAGAATTAATGCTGAATGGACATCTATGT -ATATGATAGTGGGTATATAGTTACTTATCAGTGCTAGAGCACGATCCACGTGGTGGCACA -TCCGCCAAACACGCGAGGTTTTCCAGAGTATTGGCCCACGAGCTGCAGTCCAGGCTGGGA -GCCCTTTTGCGGGCCGCAGTTGCCATGCTCTCCCCAGCCCCAGCAGTATACATTGTAACA -GTGAGACTTGCCTTCTTGATTAGCAGTAGTTAGAATACCGTGCTCACTCCCGGTTGCAAC -ACCGACAATAGGGAAGTCTAGGCGCTCTTGCGGGAAGAGTTGGGAATGTGTGCCCCTACC -AAACGACTCTACCGTATTGAGGCGCGCATTCCACAGGTGGATCGAGGTCCACATGCACAG -TACCACTAGATTGTGTCTTTTTTGCTGTTGTTTGAGCTCGAACCCAGTGGGCAGGCGACC -GGATGCGTGCACTATGCGGCCGCCCTCGTCCACTATGACCATGAAGTCCTTGCCCATGGC -CACGTAGTCTACGGCCACAGACCCGGTATCGTACACCAATACGGGCTCTTTCAGTGATCG -GGATTTGGGCTCTTGCAATTGACACTTTGTGTTGCTGCCCCAGCCGTATACTCGGGTGCC -TTGCACCACCACAAAGTTCTGGAAACATCCGTATACTGCGATGCGCTCATCGTTGGAATT -CAATGGCACATGTTGCTGAGTGAACTCGTAGCAACCGCCTCCTCTCTGCCATACACGGCC -ATCAGCATCCACAATAACTGTCGTGTCCCAGCCGCACGCCACATCCACCACGGGTGCCGG -TACTTCCACGGGCCTCCAGTCATGCACCTGCCGCAGTGCTTGCGCACTATCCAGTTCTCC -CCGTCTGTTATCTCCACATCCTACCAGATTCCCGTCATTTGTCAGCATCACGCTGTGGTT -CCCACCGCACGCTATCTTCCTGACTATTGCTCCATCATCTCCTGGCACAGACCTCTGTGG -GGTATCCATATCCTCATCGTGCCCCAGTCCCAGTTGCCTTTGCCCATTAGACCCAAACGC -ATACACACAACTCATCGATACAAGCCTGTTATAGCCTTTAATGATCACATTCCATCACTT -GCGCTTTGGATCTGCCTGCATTATCAAGGCTCAAACGGCTGCGTTACCCCCGTCGCCGCG -AAATTTTTCATAATTTTTCACTTTGTAGGATTAAAAGAGATCATGAGCCCATCTCGCAAT -GCAACACGTAACTTAAATCAGTACTGGCGTGTGCTATAGTGCTCTATATTCGAGTTTGTT -GCTACTGGTGGACACCCGACTATCTACAGTAAGGAACGTAAACAAGAAAAAGAGAGAAAA -TACGCTATAGTTGAAAACATGAGTGGTTCGCATTCAAATGATGAGGATGACGTAGTGCAA -GTGCCCGAGACGTCCTCTCCCACCAAGGTAGCATCGTCGTCTCCCTTAAAGCCTACTTCG -CCAACAGTTCCGGATGCAAGTGTGGCGTCTTTGAGAAGCAGGTTTACTTTCAAGCCTTCA -GATCCCAGCGAAGGAGCTCATACTTCGAAGCCGCTCCCATCTGGGAGTCCTGAGGTAGCA -CTGGTTAACCTTGCGAGAGAGTTCCCCGATTTCTCTCAAACTCTGGTGCAGGCTGTTTTC -AAATCTAACTCTTTTAACTTACAGTCTGCCAGGGAACGTCTTACAAGATTGAGGCAGCAA -AGACAAAATTGGACATGGAACAAGAACGCATCTCCCAAGAAGTCAGAAACCCCGCCACCT -GTCAAGAAGTCATTACCACTGGCAAACACAGGCCGTTTATCATCTATCCATGGCAATATC -AACAACAAATCCTCCAAGATTACCGTGGCCAAACAGAAAACGTCCATTTTTGACCGTTAC -TCAAACGTCATCAACCAGAAACAATACACTTTTGAGCTGCCAACTAACTTGAATATAGAC -TCGGAGGCACTGAGCAAGTTGCCCGTGAACTACAACAAAAAGAGAAGGCTGGTAAGGGCA -GATCAGCATCCAATTGGCAAGTCTTATGAGTCATCCGCTACACAATTAGGTTCTGCAAGA -GAGAAACTACTGGCGAACCGCAAATACGGTCGTCATGCAAACGACAACGATGAAGAGGAG -GAAGAGAGTATGATGACGGACGATGACGATGCAAGTGGCGACGACTACACAGAATCCACG -CCGCAGATAAATCTGGATGAACAAGTTTTACAGTTTATTAATGACTCTGATATTGTCGAT -CTCTCGGACCTCTCAGATACCACGATGCATAAGGCTCAACTCATAGCCTCACATAGGCCA -TATTCTTCTTTAAATGCCTTTGTAAACACAAATTTCAATGATAAGGACACTGAGGAGAAC -GCATCGAACAAGAGAAAAAGACGTGCGGCTGCATCCGCCAATGAGAGTGAGAGGCTGCTC -GATAAAATCACCCAAAGTATAAGAGGTTACAATGCAATTGAGTCTGTGATCAAGAAATGT -TCTTCCTACGGTGATTTGGTCACTTCGCAAATGAAGAAATGGGGTGTGCAAGTGGAAGGC -GATAACTCTGAGTTGGACCTGATGAACCTTGGGGAAGACGATGACGNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCCGCTGGCGCAGACGCCACTAGC -AAGGAAAAAGAAGATACAAAGGCCGTAGTGGAAGGTTTTGATGAAACTAGCGCAGAACCT -ACTNNNNNNNNNNNNNNNNNNNNNNTGGAAAGAGAAACAAAACGAATTAGAAACACAACT -AAGCCAAAAGTGGTCGAAGATGAAGATGACGATGTAGATTTGGAGGCAATCGATGACGAA -TTGCCGCAGTCTGAGCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNATTT -GTCGCTACCAGAAAAAACACACACGTGATCTCCACCACGAGCAGAAATGGCCGTAAACCT -ATTGTCAAGTTCTTCAAGGGCAAACCCAGACTGTTAAGCCCGGAAATTTCACTAAAAGAC -TACCAACAAACGGGTATAAACTGGTTGAATCTGCTATACCAAAACAAGATGTCATGTATC -CTTGCAGACGACATGGGTCTAGGTAAAACATGTCAAGTCATTTCATTTTTCGCATATTTG -AAACAAATAAACGAACCGGGTCCTCACTTGGTTGTTGTGCCATCATCGACGCTAGAAAAT -TGGTTAAGGGAGTTCCAGAAATTCGCACCTGCTTTGAAGATTGAACCCTACTATGGCTCT -TTACAAGAAAGGGAAGAATTGCGTGATATCCTGGAAAGGAACGCTGGGAAATATGATGTT -ATCGTGACCACGTATAACTTGGCTGCAGGTAATAAATACGACGTTTCGTTTTTGAAAAAT -AGAAACTTCAATGTTGTGGTTTATGATGAAGGTCATATGTTGAAAAATTCCACTTCAGAG -AGATTTGCCAAACTGATGAAAATTCGTGCCAATTTCCGCCTTTTATTAACTGGTACGCCA -TTACAAAATAACTTGAAGGAACTAATGTCGCTGTTGGAATTTATCATGCCAAATCTTTTC -ATTTCCAAAAAGGAATCATTTGACGCAATCTTCAAACAACGTGCCAAGACCACAGACGAT -AACAAAAATCACAACCCGCTATTAGCGCAAGAAGCCATTACAAGAGCTAAAACGATGATG -AAGCCATTTATTTTGAGAAGACGTAAGGATCAAGTGTTGAAACATTTGCCACCAAAGCAC -ACGCATATTCAGTATTGTGAATTGAACGCAATACNNNNNNNNNTATATGATAAGGAAATA -CAAATCGTGTTAGAACATAAGAGAATGATTAAAGATGGCGAATTGCCAAAAGATGCAAAA -GAAAAGTCTAAATTACAATCTTCAAGTTCCAAAAATTTAATAATGGCATTGCGAAAGGCC -TCTCTGCATCCACTTTTGTTCAGAAATATCTATAATGATAAAATCATCACTAAAATGAGT -GATGCCATATTGGATGAACCTGCTTATGCTGAAAACGGTAACAAAGAGTATATTAAGGAA -GATATGAGCTATATGACGGATTTTGAGTTGCACAAACTATGCTGCAATTTCCCGAACACG -TTATCCAAATACCAACTTCATAATGACGAGTGGATGCAATCTGGGAAGATAGACGCTTTG -AAAAAATTGCTGAAAACAATCATTGTTGACAAACAGGAAAAGGTGCTGATATTTTCCTTA -TTCACTCAAGTCCTGGATATTCTAGAGATGGTTTTGTCCACCTTAGATTATAAATTTTTA -AGATTAGATGGTTCCACGCAAGTGAATGATAGACAACTACTAATAGATAAGTTTTATGAA -GATAAGGATATTCCCATTTTCATCTTATCAACAAAGGCAGGTGGATTCGGTATTAATTTG -GTGTGCGCAAATAATGTTATTATATTCGATCAAAGTTTTAACCCACATGATGACAGACAA -GCTGCTGATAGGGCACATCGTGTGGGACAAACAAAGGAAGTTAATATAACCACTTTAATT -ACTAAGGATTCCATAGAGGAAAAGATTCATCAACTGGCCAAAAATAAACTAGCTTTAGAT -TCGTATATCAGTGAAGATAAAAAATCTCAAGATGTGTTGGAAAGTAAAGTTAGTGATATG -TTGGAGGATATAATTTATGATGAAAACTCGAAACCGAAGGGAACNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTAACATATTT -ATTTTCTTCTGCGTGAACGCACCATGTGGAAAAAGAGAGTTGATAGAACAAAGGACAAAG -AAATTTAGAACGGTAAAAATATTTTCTANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNGCTAGGTAATTTTAATCTGGGGAGAGAAATGGTGAACTTTTTTC -AATTTATTGATTCGGTTGTTGATTGATATCTTGTGGTGCTGCTTCAATTTCAGCTTGAGT -TTCTACTAAATTTTCAGGGACCATTGGATGATCAAGGTTAAATAAAACGCTACCAATAGT -ATTTGTAGAAATGGCAAAGCCCGCTAAAATGGGCACGGACTCAATCAAACCGGCCAAGAA -ACCAAATGAGGCATATTGGCCAGCGTGGAGATAAATATTTTCACGTCTTTGTATGTTGTC -GAAATTTTGTAAACGTAAAACTTTCGTGAAGTAAATTTGAGTGATGAAAGGAGAAATTAA -AATATGAAAAAGGATTGGTCCAATAAGTGGGAAAAAAGATATAACCAACAGCACAAAAAG -AACCGACAGGCCTAACATGTACTTGACCAACTTGAATGGGAAATAGTAAGCCCAGAAATA -TATCGAGTTAATAGGTGCATAGTACTTGATTGGTTTGACTTCACTCAAATTCTCCTCTAA -ACCATTCTTCTCTAAGCACACCTCCACTAAATGATTATTAAAATGACTGAGTCTCATAAA -CAATAAAGTGAAAACATTTGCTTGCAAAAAGGAATGAAAAATGGCAATGAAAAGCCCAAT -AGGGCCCAGCACAATCAAAAAAGCTGTGTACATTGGCGTAATTGTAGCCCAATACACAAA -GCTTACCAGGGCAAACATTATCAAGTAACTCGATAATATACCTAACATAGTCGTTGAGTA -ACTGCTCTTATTGGTGTTGAACTCTAAAAACCCTTTGAACGGGTACATGAATGCACCTCC -TGTGAATGCATCTTTGAAAAAGTTCATTAGCACGTATCTGGTACGGCTCATAACTTTGCT -GAAGTGCTTCTTGTAAACTTTATCCAAGTACTGATTGAAGGGGATGTTGACATATGGCAG -TTTTTCATACGATTGGCCTCCGCCAAACTTGTACACCAAACCACCAATACCTGCCAGCGC -TAATGAACCTGTAAAACTCATTTCCTGTTGTTGTTATTGTTTGTATAATGTACCTTTGTT -CCCTACACTATAACAACACTTATTCGTGGCAAGAACGAAAATAAAAAATGATTTGAAACT -TCCTTTTCCACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNTCCATGTGTCACAAAACCAGAAAGATCCCGTCGTATTATTGAGTCACGTGCTTTAT -TCCATGGCGGGTAATAAATATTAAAACAAGGGTTTTTTAAGTAAATGATTACATGCTAAG -GAAGTGGTGAATAAGATTTGGCAAGGGGCAGGTCGCTAACCACAACATAGCATTCGTTGA -AAAGGAAATCAACGTTACAAAGTGCAGTTTTTTGTATTATTTTCCTATTATCCTCTTCTT -TTCCTTTGTTTCAGGCGTCGTTGCACCTTTTTGCTATACAAAAGCTCATAAAAGATTAGA -AACCCCGGATATCGTCACAACAGCGGTATATTATAGTTATTTTGCATCTTTTTGGTAAGT -CAGAAATTAGAAACAGTAGCTTACCAATTGAGTGAAAGTTTCCGTTCGTCATCTCCCTCN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNCTCTCCCTAATTTGCATATAGGTAAACATCAAAGAAGTAATGCCCTACATCGGTG -CTTCCAACCTCTCAGAACATTCATTTGTTAATTTGAAGGAAAAACATGCGATTACACATA -AAGGTACGAGCAGTTCTGTAGCATCTTTGCAGACACCACCGAGCCCCGATCAAGAGAACC -ATATTGACAATGAATTAGAAAATTACGATACGTCTTTAAGTGACGTTTCAACCCCGAATA -AAAAGGAAGGTGATGAGTTCGAGCAAAGTTTAAGAGATACATTTGCGAGCTTTCGGAAGA -CTAAACCCCCACCTCCTTTAGATTTTGAACAACCAAGACTTCCTTCGACAGCTTCTTCAT -CCGTTGATTCAACCGTATCATCGCCCTTAACGGATGAAGACATAAAGGAGTTAGAGTTTC -TTCCGAATGAATCAACTCATTCTTATTCGTACAATCCACTTTCGCCAAATTCCCTGGCAG -TCAGATTGAGGATTTTGAAGAGATCATTGGAAATCATAATACAAAACCCAAGTATGCTAC -TGGAGCCTACTCCAGATGATTTGCCTCCTTTGAAAGAGTTTGCGGGCCGTAGGAGCAGTT -TACCAAGGACATCGGCTTCTGCAAACCATTTAATGAACAGAAATAAGAGCCAGATTTGGA -ACACTACTTCCGCTACTTTAAATGCATTTGTAAATAATACCTCTTCCTCCTCAGCAGCAT -CTTCTGCTTTATCTAACAAAAAACCGGGCACCCCAGTTTTCCCTAATTTGGATCCAACAC -ATTCTCAAACATTCCATAGAGCCAACTCGTTGGCTTATTTACCTTCCATCTTACCTGAGC -AAGATCCGCTGCTCAAACATAATAATTCTTTATTTCGTGGCGACTATGGAAACAACATAA -GTCCTGAAAGGCCAAGTTTTAGACAACCCTTCAAGGATCAAACTAGCAATCTCCGCAATA -GCAGTTTACTCAATGAGAGGGCATATCAGGAAGATGAAACTTTTTTACCGCACCATGGAC -CCTCTATGGATCTATTGAATGAACAAAGAGCGAACTTGAAAAGTCTTCTGAATTTATTAA -ACGAAACACTGGAGAAAAATACTTCCGAGAGAGCTTCGGATCTTCATATGATATCGTTGT -TCAATTTGAATAAACTAATGCTTGGAGATCCCAAGAAAAATAATTCAGAACGCGATAAAA -GAACTGAAAAGCTTAAAAAGATTTTGCTGGATAGTCTTGCAGAACCATTCTTTGAGCACT -ATAATTTTATTGGAGATAATCCGATCGCAGATACAGATGAACTAAAGGAGGAAATTGATG -AATTTACAGGTTCTGGAGATACGACAGCGATAACAGATATACGGCCCCAACAGGACTATG -GCCGCATATTGAGGACATTCACTTCTACCAAAAATTCCGCCCCACAGGCAATTTTTACAT -GTAGTCAGGAAGACCCTTGGCAATTCAGAGCTGCGAATGATCTAGCGTGCTTAGTATTCG -GTATCTCACAGAATGCCATTCGCGCTTTAACCTTGATGGATTTAATTCACACCGATAGCA -GAAATTTTGTTTTACACAAATTACTTTCTACGGAGGGTCAAGAAATGGTTTTCACAGGCG -AAATCATTGGTATAGTTCAACCAGAAACACTCAGCTCATCCAAAGTAGTATGGGCATCGT -TTTGGGCAAAAAGGAAAAACGGCTTATTAGTTTGTGTTTTCGAAAAGGTTCCTTGCGATT -ATGTTGATGTACTTTTGAACCTGGATGATTTTGGGGCCGAGAATATTGTAGACAAATGTG -AGTTATTATCAGATGGACCCACATTGTCTTCCTCTTCTACATTATCGCTACCTAAGATGG -CTTCTTCACCAACTGGTAGTAAATTAGAGTATTCGTTGGAGAGGAAAATCCTGGAAAAGA -GTTATACTAAGCCTACTTCAACAGAGAATCGCAACGGCGATGAAAACCAACTTGATGGAG -ATAGTCATTCTGAACCATCGCTGTCATCATCGCCAGTAAGGTCGAAGAAAAGTGTAAAGT -TCGCAAATGATATTAAAGACGTCAAGAGTATAAGCCAATCGTTAGCCAAATTAATGGATG -ATGTGAGGAATGGGGTTGTATTTGATCCCGATGACGACCTTTTGCCTATGCCCATCAAAG -TTTGCAACCACATTAATGAAACAAGATATTTTACTCTAAATCATCTATCTTATAATATCC -CATGCGCGGTTTCCTCCACTGTGTTGGAGGATGAGCTGAAATTAAAGATTCACAGTTTAC -CTTACCAGGCGGGTTTGTTTATTGTGGATTCGCATACTTTAGATATTGTAAGTTCCAATA -AATCTATTTTAAAAAACATGTTTGGTTATCATTTTGCTGAGCTGGTGGGAAAATCCATTA -CTGAAATAATTCCTTCTTTCCCAAAATTCCTCCAATTTATAAATGACAAATATCCTGCGT -TGGATATCACACTCCATAAAAATAAAGGTTTGGTATTAACAGAACATTTTTTTAGGAAAA -TTCAGGCAGAGATTATGGGTGATCGTAAAAGCTTTTATACGTCGGTGGGTATTGATGGCC -TTCATAGGGATGGCTGTGAAATCAAAATTGATTTCCAGCTGCGTGTCATGAATTCTAAAG -TGATTTTGCTTTGGGTTACACATTCGAGAGACGTGGTATTTGAAGAATATAATACAAATC -CATCTCAATTGAAGATGCTGAAGGAGAGTGAATTAAGTTTAATGAGCAGTGCAAGTAGTT -CTGCCAGCTCTTCCAAAAAATCTTCGTCTAGGATATCCACCGGGACATTAAAGGACATGA -GTAATCTGTCAACATATGAGGATTTGGCCCACCGAACGAATAAGCTTAAGTATGAAATCG -GAGATGATTCTAGAGCACATTCTCAATCTACTTTGTCCGAGCAGGAACAAGTTCCCCTGG -AAAACGATAAGGACAGTGGCGAGATGATGCTTGCAGACCCCGAAATGAAGCACAAGTTAG -AATTGGCCAGAATTTACTCAAGAGATAAATCTCAATTTGTGAAAGAAGGAAATTTTAAAG -TTGACGAAAATTTGATTATTAGCAAAATTTCACTTTCCCCAAGCACTGAATCCTTAGCAG -ATTCTAAAAGTTCTGGGAAAGGGCTTTCTCCACTTGAAGAGGAAAAGCTAATTGACGAAA -ACGCTACAGAAAACGGATTAGCGGGATCACCTAAAGACGAAGACGGAATCATAATGACTA -ACAAGCGAGGAAACCAACCTGTTAGTACTTTCCTACGCACCCCCGAAAAGAACATCGGTG -CTCAAAAGCATGTTAAGAAGTTTTCGGACTTCGTAAGTCTGCAAAAAATGGGTGAAGGTG -CATATGGTAAGGTCAACCTATGTATTCATAAGAAGAATAGGTATATTGTGGTGATTAAGA -TGATTTTTAAAGAAAGAATCCTTGTAGATACATGGGTTAGAGATAGGAAATTAGGCACTA -TACCTTCTGAGATCCAAATTATGGCCACGTTGAACAAAAAACCACATGAGAATATTTTAC -GGTTACTGGATTTTTTTGAAGACGACGATTACTATTATATCGAAACTCCCGTACATGGTG -AAACAGGATGTATAGATCTTTTCGATCTAATTGAATTTAAAACCAACATGACCGAATTTG -AAGCAAAATTGATATTCAAGCAGGTTGTAGCGGGAATAAAACATCTACACGACCAGGGTA -TTGTTCACAGAGATATCAAGGATGAGAATGTTATCGTAGATTCTAAAGGCTTTGTTAAGA -TTATTGATTTTGGATCTGCTGCGTATGTCAAAAGCGGACCATTTGATGTTTTTGTTGGGA -CAATAGATTATGCTGCCCCTGAAGTCTTAGGAGGAAACCCTTATGAGGGCCAACCACAGG -ATATTTGGGCTATTGGTATTCTATTGTATACGGTGGTCTTCAAAGAAAACCCCTTCTACA -ATATAGATGAAATATTAGAAGGCGACCTGAAATTCAATAATGCAGAGGAAGTTAGTGAAG -ATTGCATTGAGTTAATCAAGAGTATTTTGAACCGTTGCGTACCGAAGAGACCCACCATTG -ACGACATAAATAACGACAAATGGTTGGTTATTTGAAGGATTAATGATCATTCTAGGACAT -TAGTAATTGGAAAAGAAAATGCAAAAAAATATCCAGTAGAAACAATGCTTGGTATGTCGT -TCTTCTTACTTTCTTCAGTAATGAGTTGGTAGTTTTCTCTATTTAAATATGAATAAATCA -ATATGTACTTTCTTTCTTTAATCAAAATGTTAATATGATAAAAATACAGCATCCAAAGCA -GTTAATCAAGACTTAAATATAAAAAATTTACATATTTAGAAAACAAAGATAGGGTAAATA -TTGAAATTACATAGTAAACCATACCTTAAAAGCAGAAATACTGATACCACATGAACTATT -GATCAATACTACTGCTATTCTCTTCCTAATGCAAAGAGCTTATTACCATTATTAAATCAC -TACAGACGATAATACCCGGAATGCCCTTTTTGCAGGGAAAGCGAAAAAGGTGAAAGAGTT -AACAGGAGAAAGTGTTAGGGAACTAAGTTACGAAGGAAGGCAGATAGCAACAATACTAAC -GTGGAACTTATTTCGACGACTATAACAACTGGTATCTGATTATCGAAGAATAATTGAGTG -GTCAGAAAGGAGCGAAATATGTCTGGAGCAAGATCAACAACGGCAGGTGCCGTGCCCTCG -GCAGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNACTCTAAGGACTCAGACTCTAACGAG -TCATTATATCCCTTGGCTCTGCTTATGGATGAGTTAAAACATGATGATATTGCTAATAGG -GTAGAAGCCATGAAAAAACTAGATACCATCGCGTTGGCACTCGGTCCCGAAAGAACAAGA -AACGAGTTGATTCCCTTTTTAACGGAAGTTGCACAAGATGATGAAGATGAGGTGTTTGCC -GTTTTAGCCGAACAGTTAGGAAAATTTGTCCCCTACATTGGCGGTCCTCAATACGCCACA -ATCCTATTACCAGTTTTGGAAATTTTGGCATCTGCAGAAGAAACTTTGGTTAGAGAAAAG -GCCGTAGATTCTCTGAATAACGTGGCCCAAGAACTTTCTCAAGAACAATTATTTAGTGAC -TTCGTCCCTTTAATTGAACATTTAGCTACTGCAGATTGGTTTTCTTCAAAAGTTTCTGCT -TGTGGTCTTTTCAAGTCTGTTATTGTTAGAATCAAAGATGATTCATTGAGAAAGAATATC -CTGGCTTTATACTTACAACTCGCTCAAGATGATACTCCAATGGTGAAAAGGGCCGTCGGT -AAAAACCTGCCCATCTTGATCGATCTGTTGACTCAAAATTTGGGATTATCTACAGACGAA -GATTGGGATTACATTTCTAACATTTTCCAGAAAATCATTAACGATAATCAAGATTCTGTC -AAGTTTCTGGCAGTTGATTGTTTAATTTCCATCTTGAAATTTTTTAACGCTAAAGGTGAT -GAGTCTCACACTCAAGATTTATTGAACTCTGCTGTCAAATTAATTGGTGACGAAGCGTGG -AGGGTACGTTACATGGCTGCCGATAGATTTTCAGATTTAGCCTCGCAATTCAGTTCCAAC -CAAGCATATATCGATGAATTAGTACAACCATTTTTGAACCTTTGTGAGGACAACGAGGGA -GATGTTAGGGAAGCTGTGGCTAAACAAGTTTCTGGGTTTGCCAAGTTCCTAAATGATCCT -TCAATTATATTGAATAAGATCTTACCTGCTGTGCAGAATTTGAGTATGGACGAAAGTGAA -ACAGTGAGATCTGCTTTGGCTTCTAAGATTACAAATATTGTATTACTGTTGAATAAAGAT -CAAGTCATTAACAATTTTCTTCCGATTTTACTGAATATGCTAAGAGATGAGTTCCCTGAC -GTTCGTTTAAATATCATTGCCAGCTTGAAGGTTGTCAATGACGTAATAGGAATTGAGCTG -CTATCAGACTCTTTGTTACCTGCCATAACAGAATTAGCCAAGGACGTGAATTGGAGAGTT -AGAATGGCTATAATTGAGTACATACCTATCTTGGCAGAACAATTAGGTATGCAATTTTTT -GACCAACAGTTAAGCGATTTATGTCTTTCATGGTTGTGGGATACTGTTTATTCTATCAGA -GAAGCCGCAGTGAATAATTTAAAAAGGTTAACGGAAATATTTGGCTCTGATTGGTGTCGT -GATGAAATTATTTCAAGACTGCTCAAATTTGATCTACAATTACTGGAAAATTTTGTCTCG -AGGTTCACAATACTCTCTGCTCTAACCACTTTGGTGCCCGTGGTATCGTTAGATGTCGTT -ACTGAGCAACTATTACCATTCATTTCTCACTTGGCTGATGACGGTGTTCCAAATATTAGG -TTTAATGTGGCCAAATCCTACGCTGTGATAGTGAAGGTTTTAATTAAGGACGAGGCCAAA -TATGATGCATTAATTAAGAACACAATTTTACCCTCATTGCAAACGCTGTGTCAAGACGAA -GATGTTGATGTAAAATACTTCGCTAAGAAAAGTTTGGCAGAATGTCAAGAACTTTTAAAA -AATTGATACTAGTTCAAATATATACATACATACACATATGTACACTTGAATGAATAAAAA -GTATACATATTAACAACTAGGCCTGCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNACCAC -ACTTAGTCCTCTACTTTAACAGAAATATCATTTTCCAGTTTGACCATAGTTTCTTCAACT -GTTTTCTCCTCGTGTTTAACATTGATTTCCGCCTCCACGTTCAGTTCACGTTTTCCTTCC -AGGTATTTCACCCACTTTGGATAACTCATGATATTTTGCTGGATTTCCTTGTACAATTGA -GACTGCAAATCCCAATCTAAGGAGCTTCTGGGATCATCCGGTGGCAAGAATTGTAACATG -TCACCAAGGTTCCTCGATTTAGTGATTATTTGTCCAAATCCAACCAGCAACCCATTTATT -TCTGTCCAAAGCCCCTTAGGCAGCCAATTTTGTAATTGAGTTCTTGTCTGATCTGGAGTC -TTGCATTTCTGCGCATCTACCCATTTCCAAAGCTTGGTCAATCTATCCACGTGAACGTCA -ACGCAGATACCTTCAATCTTGCCCCATGCCTTTTGTAATGTTAGATAAGCCATTTTGGGC -CCTACACCGGGCAGGCCCAATAGCTCATTAATCGTAGCTGGAACATCACTCGAAAACTGA -TCTTGAAGGATTTTGCAGGTTGACAAAATATACTTGGCCTTCCTTGTGTGGAACCCAACT -GAATGAATCAATTCGTCTAATTTGGTCTCATTGATTTGTAAAACGGCCTCTAATGTCATA -CCTTCTTCGCTGTGCAGTTCGTCTATACAATACCGCATTATGTTAAGCATTGCCATTGCG -GTAACTTCATCTTTTGTTTGCGATGATAGCATCACCCCAAGAAGGACCTGTAATCTGTAG -TCCCTCGGTGATATCTGCTCTTTCGAGATACCACACTTAGAGGCAACCGTTACAGGAATG -GATGATCCACCAATTATATCGACGGGGGCTAGAATCTTAGATCTCAGTACTCGCATTCTA -GCGTATGTTTCTTGAAACTTGTAAGGGACTTTCGTCGAGGCCGGAGTGACAAGGATCGAG -GGGTCCAATGGTGTGGCCCACCTGTTGGGCACATTGCCGTTTCTAACCACAATCCATTCG -AAGTACTGCTTATTTGGCAGCGATTTAACCCAGTCGATATCCACGGGTTGAGGGACAACC -TCTTCTTGTTTGATTTTGGTCCTTTTCTCCGGTAGGAGTTCTGATTCTGGCCCAGTTTCA -GTCTTTACCAGCGGTCTTTTCCTCAGAATTGCCATAGATGAGTATTTACTGATCTTTTGC -ATANNNNNNNNNNNNNNGGGCTATAAAGTATATATAGATACAAATATATGATGAATCATT -AAAGAGGAGGTTATTACTAAGTGAAAGNNNNNNNNNNNNNNNNNGATCAAAACCAAACTT -CGTATTCGAGCCTAAAAAACAGAATATAATGTTATAATACTAATAGAAGCAACAGGAGCA -CCACTATCAGCACAAGAATAATCACGCAGTTGCCGTTATCCTTGAACCTAGAATTGTTAA -AGCCATGCATGGACCGAGAGGCCCTGTTCAAATTCCTACCATTATTATCAATCAGGTTTT -CTAAATCAACCAGCAGCGAGTCGTTCTGAGAAACGATCTCATTATTAAGGTCCAGCGAAA -TGTCATGAGTCCTCCCAATAGACTGAGACAGTGCGCCCAAGTGGGAATCTTGCTCTAACA -ACTGCTGTTGCTGGTTAATAAATAGTTCTTGGTTGGAAACCATGGGTTGTGNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNCGATTGCAATGGTTCATCCTTGTATGGAGTATGCGTCG -AAGGCAGCGGCGACTCCTCGTCTTGTTCATCGTCATCCTTATACATGACCGTAAGCTCGT -CATCATTCTTGAACCGCACTTTTTTCAAAGACTCTTTGGACACCTCATCAGTATTTCTTG -CCACCTGCTGTTGGAACCTATACAACTCCTTGTCAACCGCCGTATCAGGAATTTTGTCCA -GTATGGTATTGTATCGGGATATTAGTTCATCATTGGGCGCACACTTCTGCAATAACTCCA -ATATTGAGCCCAATTGCCGTTTCAAAGTAACGTTATCGTTTGAGGTCGGGGCGAGCTTCA -ACACCGACACTAGCCTTGTTCTTTCTTCGACCAGATCAGAGAGCTGGTCCAGTTCATAAC -CCAGCTTCAACACATCCATACCGTGTGTGCTTACGCATCTATTTGCTGTCGTGAGATCTG -TCTCTATGCTTTATTCGTTTTCCATTGTAAAGTCTCAGCATTTATTTCTTGTTCTTTACT -TGTTTTTGCCCTTTCGGGTGATCAAAGTCGTGCTGGGAAATTTTATTCTTATAAAATGAT -TTTTAGAAATAATAAACTCATAACAGTGCAACGGCAAAGTACAAGGGAAGGAAGCACAGA -AGCAAGAGGAGGCGCATCGATCGTGGCAGATGAGTCAGCAAACACCACAGGAAAGTGAAC -AGACCACAGCGAAAGAACAGGACCTTGATCAAGAGAGCGTGTTGAGCAACATTGACTTCA -ATACGGATTTGAATCACAATTTGAATTTATCGGAATACTGTATATCCAGTGACGCAGGAA -CAGAGAAGATGGATAGCGACGAGGAGAAGTCGTTGGCCAATCTGCCGGAGTTGAAATACG -CTCCCAAGCTATCCAGCCTGGTGAAGCAAGAGACGCTCACCGAGAGCTTGAAAAGACCAC -ACGAAGATGAGAAAGAGGCGATAGATGAGGCCAAGAAGATGAAAGTGCCGGGAGAGAACG -AGGACGAAAGCAAGGAAGAGGAAAAGAGTCAAGAACTGGAAGAGGCAATTGACAGCAAGG -AGAAGAGCACCGACGCCAGGGACGAGCAAGGGGACGAAGGTGATAATGAGGAGGAAAACA -ACGAGGAGGATAATGAAAACGAAAACGAGCATACAGCACCGCCTGCGCTGGTGATGCCCT -CCCCCATCGAAATGGAGGAACAGAGGATGACTGCGCTGAAGGAAATCACCGACATCGAGT -ACAAGTTCGCGCAATTGCGCCAAAAACTATATGACAATCAATTGGTGCGGTTGCAAACGG -AGCTGCAGATGTGTCTGGAAGGGTCACACCCGGAATTGCAGGTCTACTACTCGAAGATTG -CCGCGATCCGTGACTACAAGCTACACCGAGCGTACCAGCGACAGAAGTACGAGCTTTCAT -GCATCAACACAGAAACAATCGCTACCAGGACATTCATTCACCAGGACTTCCACAAGAAGG -TCACCGACCTGCGAGCCAGGCTGCTGAACAGAACCACGCAGACCTGGTACGATATCAACA -AGGAGCGCCGCGATATGGATATAGTCATCCCAGATGTCAATTACCACGTCCCCATCAAAC -TTGATAACAAGACGCTGAGCTGTATCACGGGCTACGCCAGCGCAGCACAGCTGTGCTATC -CCGGCGAGCCCGTGGCAGAGGACCTCGCTTGCGAAAGCATCGAGTACCGCTACAGAGCCA -ACCCGGTGGACAAACTCGAAGTCATTGTGGACCGAATGAGGCTCAATAACGAGATTAGCG -ACCTCGAAGGCCTGCGCAAATATTTCCACTCCTTCCCGGGTGCTCCTGAGTTGAACCCGC -TTAGAGACTCCGAAATCAACGACGACTTCCACCAGTGGGCCCAGTGACCGCCACACTGGA -CCCCATACCACTTCTTTTTGTTATTCTTAAATATGTTGTAACGCTATGTAATTCCACCCT -TCATTACTAATAATTAGCCATTCACGTGATCTCAGCCAGTTGTGGCGCCACACNNNNNNN -NCCATAAAAATCCTCGAGNNNNNNNNNNNNNNNNNNTATTTCAGTTATTTAAAGCATAAG -ATGCCAGGTAGATGGAACTTGTGCCGTGCCAGATTGAATTTTGAAAGTACAATTGAGGCC -TATACACATAGACATTTGCACCTTATACATATACACACAAGACNNNNNNNNNNNNNNTAT -GACTCTACAAGAATCTGATAAATTTGCTACCAAGGCCATTCATGCCGGTGAACATGTGGA -CGTTCACGGTTCCGTGATCGAACCCATTTCTTTGTCCACCACTTTCAAACAATCTTCTCC -AGCTAACCCTATCGGTACTTACGAATACTCCAGATCTCAAAATCCTAACAGAGAGAACTT -GGAAAGAGCAGTTGCCGCTTTAGAGAACGCTCAATACGGGTTGGCTTTCTCCTCTGGTTC -TGCCACCACCGCCACAATCTTGCAATCGCTTCCTCAGGGCTCCCATGCGGTCTCTATCGG -TGATGTGTACGGTGGTACCCACAGATACTTCACCAAAGTCGCCAACGCTCACGGTGTGGA -AACCTCCTTCACTAACGATTTGTTGAACGATCTACCTCAATTGATAAAGGAAAACACCAA -ATTGGTCTGGATCGAAACCCCAACCAACCCAACTTTGAAGGTCACCGACATCCAAAAGGT -GGCAGACCTTATCAAGAAGCACGCTGCCGGCCAAGACGTGATCTTGGTTGTCGACAACAC -CTTCTTGTCCCCATATATCTCCAATCCATTGAACTTCGGTGCAGACATCGTTGTCCACTC -CGCTACAAAGTACATCAACGGTCACTCAGACGTTGTGCTCGGTGTCCTGGCCACTAATAA -CAAGCCATTGTACGAGCGTCTGCAGTTCTTACAAAACGCCATTGGTGCTATCCCATCTCC -TTTCGATGCTTGGTTGACCCACAGAGGTTTGAAGACTTTGCATCTACGTGTCAGACAAGC -TGCCCTCAGCGCCAACAAAATCGCTGAATTCTTGGCAGCAGACAAGGAAAACGTTGTCGC -AGTCAACTACCCAGGTTTGAAGACACACCCTAACTACGACGTAGTGTTAAAGCAACACCG -TGATGCCCTTGGTGGTGGTATGATCTCCTTCAGAATCAAGGGTGGTGCTGAAGCTGCTTC -CAAGTTCGCCTCCTCCACAAGACTGTTCACATTGGCCGAATCCCTTGGTGGTATCGAATC -TCTATTGGAAGTGCCCGCTGTGATGACCCACGGTGGTATCCCAAAGGAGGCCAGAGAGGC -CTCTGGTGTTTTTGACGACTTGGTTAGAATCTCTGTCGGTATTGAAGACACTGACGATCT -TTTGGAAGACATCAAGCAAGCCTTGAAACAAGCCACCAACTAATCGCCAGTGCCACGTCT -CTGCCTTCGACCGGACCTTTTTAAGTACGATAAATATCCTTTTATAAATATATAGTCTAA -AATATCCATTAATACTGTGCTCAATCAATCGTGTTAGATGATTTAGTTTTTTCCAAATCG -TTATTATAGTGCAGAAGTAGTATACATAAAGGCATATGCATGCGATTTGGAAGTAACGCT -CGCCGTAGACAAGTAAGAATGCCTGCTGTCTTGAGAACCAGGTCCAAAGAATCCTCTATA -GAGCAGAAGCCTGCTTCCAGAACTAGAACGAGATCAAGAAGGGGCAAGCGTGGTCGTGAC -GATGATGATGATGACGACGATGAGGAAAGCGATGATGCATACGATGAAGTAGGTAATGAC -TATGACGAGTATGCTTCAAGAGCGAAGCTGGCCACCAATAGGCCCTTCGAAATAGTCGCG -GGACTGCCTGCTAGTGTGGAGCTGCCCAACTATAACTCTTCGCTTACTCATCCGCAATCA -ATTAAAAATTCTGGGGTGCTTTACGACTCTCTGGTCAGTTCCAGAAGAACCTGGGTTCAG -GGTGAGATGTTTGAACTGTATTGGCGAAGACCTAAGAAAATTGTTAGTGAATCTACCCCA -GCAGCGACGGAGAGTCCAACATCTGGAACGATTCCTTTGATTCGAGATAAGATGCAGAAA -ATGTGCGATTGTGTAATGAGTGGAGGTCCTCACACGTTCAAAGTTAGACTTTTCATACTG -AAGAATGACAAAATCGAACAGAAATGGCAAGATGAGCAAGAGTTGAAGAAAAAGGAAAAG -GAACTGAAACGAAAGAACGATGCAGAGGCCAAAAGATTGAGGATGGAGGAAAGGAAAAGG -CAGCAGATGCAAAAGAAAATAGCCAAGGAACAAAAACTTCAATTGCAGAAGGAAAATAAA -GCCAAGCAGAAGTTGGAACAGGAGGCGCTGAAGNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNCAGGGTTCACCTTCTTCCTCCATGCATGACCCAAGA -ATGATAATGAATTTGAATTTGATGGCACAAGAAGATCCAAAACTAAACACTTTAATGGAA -ACCGTCGCAAAGGGTCTTGCCAATAATAGTCAACTGGAGGAATTTAAAAAGTTCATTGAA -ATTGCCAAAAAAAGGTCACTAGAGGAGAACCCAGTTAATAAGCGTCCATCTGTCACAACA -ACGCGACCTGCACCTCCCTCTAAAGCTAAAGACGTAGCCGAAGATCACCGGTTAAACTCG -ATAACCTTGGTGAAAAGTTCCAAAACCGCTGCCACGGAACCTGAACCAAAAAAAGCTGAT -GACGAGAATGCAGAGAAGCAACAGTCCAAAGAGGCAAAGACAACTGCCGAATCGACTCAA -GTAGATGTCAAGAAAGAAGAAGAAGATGTGAAGGAAAAGGGTGTGAAATCAGAGGATACA -CAAAAGAAAGAAGATAATCAAGTGGTACCGAAAAGGAAAAGAAGAAAGAACGCAATAAAG -GAAGATAAAGATATGCAATTGACCGCGTTCCAACAGAAATACGTTCAAGGTGCGGAGATC -ATCCTGGAGTATTTAGAATTCACCCATTCGAGGTATTACCTGCCTAAGAAATCAGTAGTA -GAATTTTTGGAGGATACGGATGAGATTATAATATCTTGGATTGTTATACACAATTCTAAA -GAAATTGAGAAGTTCAAAACCAAGAAAATAAAAGCTAAACTGAAAGCCGACCAAAAACTA -AACAAGGAGGATGCCAAGCCAGGCTCTGATGTGGAGAAGGAAGTCAGCTTTAATCCTCTT -TTTGAAGCCGATTGCCCTACCCCTCTCTACACCCCAATGACAATGAAGTTATCGGGGATT -CACAAAAGATTTAACCAAATCATCCGAAATAGCGTTTCTCCAATGGAAGAAGTTGTTAAA -GAAATGGAAAAAATTCTGCAAATTGGTACTAGATTGTCTGGCTATAATCTGTGGTACCAA -TTGGATGGATACGATGATGAAGCTTTGAGCGAAAGTTTGCGGTTCGAACTAAATGAGTGG -GAGCACGCCATGAGAAGCAGAAGACACAAAAGATAAGGTGTTCGGTTACTTTATTCTGCT -TTAACGCCATTATGATTATACACATTGTATTACTTATTTTTTAACCTGTATATTAAAACC -TTTATTTTATTTCACATTACTCATCATGTGGAGTACTGGAATTGTATGCCAAACTTTGCC -GGGAAAACTGGTATATTGCCGTTTTCTGTATCAGTTGCTGATATAGATATTGCATTATCA -TTCTTTTCATCATCGGATAAACTTTCTTGAAAGCCTCTAGTGAATACCAGCTCTGTCCCG -GCAGATATTAAAAATCCCCTCCATTTGCCTTCCCATAATAGTTTTAAAGTCTTGTCACGT -AATGACGTGCTTAATTTCCAAACACTGGTAAAAATGGAACTATTTATTTTGTTATCAAAT -TTTTCGATGGTAGATCTTTCTTCATCGATTTTTCTTAATGACGACGAGAATGCATAAGTT -AAATCATTTAATAGCTTTTGTTTGTGAACAGGTATATCTAGTGTAGAAGGAATATCGTTA -ACAGCTGAATTCAGATCCGGTACATTTTCGTGCAGTAGTTTAGTCGCTCTGCTGTTTGGA -TTTATATCAACCAATTCGTCGGAGATTGGTTCTAATTTATCATTATTGTTTTTATTGGTT -TCAAGCAAATGATGCTTTTTTTGCCAAAATTCGCACCCAAATGAAAGATTTGATTCAATC -GAATAAAGATTAAAATCATACTTCGCGCAAAAAGTAGAATTTGTCCCTGTCTTGGCCGAA -TATGTGGAGGATATATGGCCGAATAATGGATTCCAAGATAATGTCAAAGTTAGTGGTCGT -CCTGTGTTTGTAGAATGTGTGTAATATCTTAAAGTTGTCGAACAACCGGGGCTTAAACTT -ACTAACCCTAACCAAAATTCAGCACCAAGCGACAACGAAGAATTATTGTACAGTGAGGTG -TTAAACTTGGAAGGCGTGGTAAGGAAATTGTGTAATACTCTATAACCACATAATAGATCA -CTGGTGGAAAATATCCACTCCTGTAAATTGCGGTGAGAATCTCTTTGAAAATAGCACGTT -AAAACGTTTAAGCTTTCTTTGAAACTACTGACACCCTTAAGCATAAATTGGGTTTGTGGA -CTTAGTCGTTTTATTATCATTGCTTCTAAATCAGAGCTGGGGTAGTACATTCTACCATAA -TAAAGGGATTTTTTAACAAATTTCGAGTCATGTAGTAATTTCTTGTCATTGTCGACTGTG -GTGTTGTCACTACTCAACGTATTCGCACTACTAACACTGAAATTGAGGTTTGGTTGCAAT -TGTCTGTATGTTTCGGTGGCATCTTGTAATGGGATATCAGTAGAGTTGCGCATGAATTTC -TCCAATTGCTGTGCATCGGAGTATAAATAACTCAGAGAACCATTTATCCTGGACCTCGTA -GAAAAATCTAAAGAATTGAATGTATTGGGAGTAGATTTGTTGGAAATTTGCAGGTGTATT -GCTGAGGGAATTCGGAAATCTAATAATGTTCTCGATGTGGCCGTTATATCCTCGTAGCTA -TTTTGCGTACTCCAATGGGTGCTCTGATAAAATGCCCTTAGTACTTGGTCCATATAGGGT -AGCATCAAGATCGGTCTTCTCTGTTCGTGTCTTTTTCCTAACGTATATTTGCTTTGTTTC -TTCACTCAACAATAAAGTCAAAGTAAAATTAAATACTAATTATTCTTAAAAGGGAAGATG -CGAAATTTAGCGAAAATCTATTGATTATACACACAAAGGAAGAAAGGTAGTGGAAAGCTA -AATAAAGGAGGTCATGGAGCCAGAGAGCATAGGCGATGTGGGGAACCATGCCCAGGATGA -TAGTGCCAGTATAGTGTCCGGGCCTCGCAGGCGTTCTACTAGCAAGACATCCAGTGCGAA -GAATATACGGAACTCCAGTAATATCTCTCCAGCATCGATGATTTTCAGGAATTTGTTGAT -ACTGGAGGATGATTTAAGACGCCAAGCTCACGAACAAAAGATACTGAAGTGGCAATTCAC -TTTGTTCTTAGCGTCTATGGCCGGTGTAGGCGCATTTACCTTCTACGAACTTTATTTCAC -TTCAGATTATGTCAAGGGCCTCCATAGGGTTATTTTGCAATTCACTCTTTCTTTCATTTC -CATTACTGTAGTTCTTTTTCATATCAGTGGACAATATAGAAGAACTATCGTCATTCCAAG -AAGATTTTTTACCTCTACTAATAAAGGGATTAGGCAGTTTAATGTGAAGCTAGTTAAAGT -ACAGTCTACGTGGGACGAGAAATACACAGATTCAGTAAGATTTGTGAGTCGAACAATTGC -TTATTGTAATATTTATTGTTTGAAAAAATTTCTGTGGCTTAAAGACGATAATGCCATTGT -GAAATTTTGGAAAAGTGTCACGATACAATCCCAACCGAGGATCGGAGCTGTGGATGTGAA -ATTAGTCCTCAACCCCAGAGCATTTAGTGCAGAGATTAGAGAAGGATGGGAGATTTATAG -AGACGAGTTTTGGGCCAGGGAAGGTGCTAGAAGACGCAAACAAGCGCACGAACTCCGACC -TAAATCAGAATGAAAGAGTTGGAGGGCTTCTTCCTTCGAATAAGAGGTCATATTTACCTA -TGTAAAATTGTAACCATCTATGTTCACACATAAATTATATTTTATACATTATTAGAAGTG -AAGCTGTTGTGTCGTGAAAATTTTACAAATCCGTCATTTCATATTTAAGTTTTCCAACAA -GTGCTAGAAAACCTAGGGGTTGTTGAAATTGGTTAAACAAGGCATCTTATTATACATACA -ACAGCATAACGCTAGAGGGGCAAGAAGGAAGAACTTAAAATAATAGGTGTAAAATGACTT -TGGCTTTTAATATGCAACGGTTGGTGTTTCGTAATTTGAATGTTGGGAAGCGCATGTTCA -AGAACGTCCCCTTATGGAGGTTTAATGTCGCCAATAAATTAGGAAAGCCCTTAACTCGCT -CTGTAGGGTTAGGCGGTGCTGGCATAGTTGCTGGTGGCTTTTACTTGATGAATCGCCAGC -CTTCTAAGTTGATATTCAATGATTCTTTAGGGGCAGCTGTCAAACAACAGGGTCCCTTGG -AACCAACTGTGGGCAACAGTACGGCAATTACCGAGGAAAGGAGGAACAAAATAAGTAGTC -ACAAGCAGATGTTTTTGGGATCATTATTCGGTGTTGTTTTAGGAGTTACGGTGGCTAAGA -TATCAATTTTGTTTATGTATGTCGGTATTACAAGCATGCTTCTTTGTGAATGGTTACGGT -ACAAGGGATGGATTCGCATTAATTTGAAAAATATCAAATCTGTAATTGTTTTGAAAGATG -TAGACTTGAAGAAACTGCTTATTGATGGGTTATTGGGTACAGAATACATGGGTTTTAAAG -TATTCTTTACATTGAGTTTCGTATTAGCAAGTTTAAATGCTAACAAATGAGCAAGACAAA -TGACCAGATATAAACGAGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNCCTATACAGTAAATATACATAGGGCTAAGGAAGNNNNNNNNNTCACGTCGAAT -ATAAACCTAATTGTGTTCTATATTGCGGACATATATTTTTCGTAGATTGAAAAGTTCTTA -AACGTAATTTTTTTGACGACCAGTGAAGAGGAATTGAATAAGTAGAACTTGGGCAATACT -TATAACGGCAATGATAATGATAATCAATATAGATAACCAAGTCAACCTTGATTCGGTGGA -ATTGACGGTAGACATGTTTCTCCATTCTCTGGCTCTCAAATAGTTCAAAGTCTTCGTGAT -TTTGTTCAAGTTTCTATCTATTTCCTCCACGGCGTTATTGGCAATAATGTCATCGTTATT -GACATCAGCTTCATGCTCGTCAGTCAAAGTTTTTTCCTTTTCTAGTGTAATTTCTACCTT -TTTCAACGCTGTACCATAGTTATTGGAAAAACAAAAGGTATACTTCCCCACTCCAAACGA -TTTTAATAAAAAGTCTGAGTACTTCTTTTGTTTCTCACTAGTAATCACAGATCCATCAGG -AGCAGTAATATCAAAATCAATCTCAAAATTACCACCGGTTAGAACTTGGTAACCCACAGC -CAGGGAATCATCCTCAGTAACCATATCGTAGTACAGGCATTCTTTGCTGAATGCTGGTAA -ACTGATAGCAACTGGTGCATAACTGGAAGATGCAGCCACTGAATTGACCAACGCCAAAAT -TAAAACAATGAAGAAAGAGGGTAGAGCAATTGTAGATTTGATCATGGTTTTCCTTTACAA -TGAGTGTACTCCACTGTTTATCTTATTCTAGTTTGGGTCACCTGATGCAGAATTGGCGGT -GTCGATCCCTAAGGTTAATGAATCGAAATCACTGGAGATTTTGTTAGTTTTTCATTTTAA -CTAGTTCAAGTTTTGGCAGAATGTACTTTTTCGTGTTTCGGGACACGTCGCTGAAAAGGA -TTGAAATATAACCAAACGCCATCATGTAAGGTGCAGTGAACATTAGCGCTAAGAGGATTG -AGGATTGCTTTATGAAAGTTTATGAACATTTTCTTGAATTAAATAAATAAGTCTGAAAAC -ACTTGAATTCGAGATGCTGTAGCAATTTGTAATATTATTTAAAGTTCACAGAGTGGCTTC -CTTGGCGGATCTGAAAAATAGGTAGTGATTTNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNTGAAATAGAATCTTTAATGATCACAGTGGATC -TTTTAAAAACTTGGTGAGATAGTGCTAGTGATCCGTAGTCTAAATGAGTTACGTACGAAA -GGGAGCCAAAAGCAATCTGACCAATTTGTATATATATACATCTATCCGAAAAGGAAGACA -TCAATTAGTACGGGCGTGTGGTCTAGTGGTATGATTCTCGCTTTGGGCGACTTCCTGATT -AAACAGGAAGACAAAGCATGCGAGAGGCCCTGGGTTCAATTCCCAGCTCGCCCCGAATAA -NNNNNNNNNGCCTATCTATAAAATTAAAGTAGCAGTACTTCAACCATTAGTGTTAGCGAT -AATCAAGAAGTGAAACTCTTTCTCTANNNNNNNNNNAATTGAAAAATTTCCTTTCTCTAT -AGCGTATAGAATATATGTTACATGNNNNNNNNNNNNNNAAGTAAAAACGTTCGGAAAATT -CCTCATTATACCCAGATCATTAAAAGACATTTTCGTTATTATCAATTGCCGCACCAATTG -GCTTAATCAACTTCTTCAACGGTTGGACCTTCAGCCTCTGGAGCTGGANNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNAGCTTGGTACAAC -TTAGACATGATTGGGTTGGCAATGTCTTGCAACTCCTTCAACTTGTCATCGAATTCTTCC -TTGCTGGCAGTGGTGTTGCTGTCTAACCAAGAAATAGTCTCTTCAGCCTTCTTGGTGACG -GTGTCCTTGTCAGCTTGTTCCAATTTGTCACCAGCTTCAGAAATGGTGTTCTTCAAAGAG -TAAGCAATGGATTCCAATTGGTTCTTGGAAGCAATTCTTTGAGATTCCTTTTCATCTTCT -TCCTTGAATTTTTCGGCTTCAGCAACCATCTTTTCGATATCTTCCTTGGACAATCTACCC -TTGTCGTTGGTAATAGTGATCTTGTTAGACTTACCAGTACCCTTTTCGACGGCGGAAACA -TTCAAAATACCGTTAGAGTCGACATCGAAAGTGACTTCAATTTGTGGGACACCTCTTGGA -GCTGGTGGAATACCACTCAATTCGAACTTACCCAACAAGTTGTTGTCCTTAGTCTTGGCT -CTTTCACCTTCAAAGACTTGAATCAAGACACCTGGTTGGTTATCAGCATAAGTGGAAAAG -ATCTCGGACTTCTTTGTTGGAATGGTAGAGTTTCTTGGAATCAACTTGGTCATGACACCA -CCAGCAGTTTCAATACCCAAGGATAATGGAGCGACATCCAACAACAATAGATCTTGAGTC -TTGGAAGATTCGTCACCAGTCAAAATAGCAGCTTGAACAGCAGCACCGTAAGCAACAGCT -TCATCTGGGTTGATAGATCTGTTTGGTTCCTTACCGTTGAAGTAGTCAGTGACCAATTTT -TGGACCTTTGGAATTCTGGTAGAACCACCGACCAAGACAATTTCATCGACTTGAGATTTG -TCCAATTTAGCATCTCTCAAGACCTTTTCAACTGGGTCCAAAGTAGATCTGAACAAGTCA -GCACACAATTCTTCGAATCTGGCTCTGGTGATGGAAGTGTAGAAATCGATACCTTCGAAC -AAAGAGTCAATTTCAACGGAAGTTTGAGCGGAGGAAGACAAAGTTCTCTTGGCTCTTTCA -CAAGCGGTTCTTAATCTTCTCAAAGCTCTTTGGTTGGTAGACAAGTCCTTCTTGTTCTTT -CTCTTGAATTCTTGGATGAAGTGGTTGACCAATCTGTTGTCAAAATCTTCACCACCCAAA -TGGGTGTCACCAGCGGTGGCCTTAACTTCAAAGATACCGTCTTCAATGGACAACAAAGAG -ACATCGAAAGTACCACCACCCAAGTCGAAAATCAAGACGTGTTCTTCCTTACCCTTCTTG -TCCAAACCGTAAGCAATGGCAGCGGCGGTAGGTTCGTTAATAATACGCAAGACATTCAAA -CCAGCAATGGTACCAGCATCCTTGGTAGCTTGTCTTTGAGAATCGTTGAAGTAAGCTGGG -ACAGTGACGACAGCGTCATTGACCTTGGCTCCCAAGTAAGATTCGGCAGTTTCCTTCATC -TTACCCAAGACCATGGAGGAGATTTGTTCTGGGGTAAAGTTCTTGGTTTCACCCTTAAAT -TCAACTTGAATTTGAGGCTTACCGTCAACATCGATCAACTTGAATGGGAAGTGCTTCATG -TCAGCCTGCACTTCTGGGTCGTTGAAGTTTCTACCGATCAAACGCTTAGCGTCGAAAACG -GTATTCGAAGGATTCATAGCAGCTTGATTCTTAGCAGCATCACCAATCAATCTTTCAGTG -TCAGTGAAAGCGACAAAAGATGGAGTGGTTCTGTTACCTTGATCGTTGGCAATAATGTCC -ACACGATCATTAGCAAAGTGAGCAACACACGAGTATGTTGTACCTAAATCAATACCGACA -GCTTTTGACATATTATCTGTTATTTACTTGAATTTTTGTTTCTTGTAATACTTGATTACT -TTTCTTTTGATGTGCTTATCTTACAAATAGAGAAAATAAAACAACTTAAGTAAGAATTGG -GAAACGAAACTACAACTCAATCCCTTCTCGAAGATACATCAATCCACCCCTTATATAACC -TTGAAGTCCTCGAAACGATCAGCTAATCTAAATGGCCCCCCTTCTTTTTGGGTTCTTTCT -CTCCCTTTTGCCGCCGATGGAACGTTCTGGAAAAAGAAGAATAATTTAATTACTTTCTCA -ACTAAAATCTGGAGAAAAAACGCAAATGACAGCTTCTAAACGTTCCGTGTGCTTTCTTTC -TAGAATGTTCTGGAAAGTTTACAACAATCCACAAGAACGAAAATGCCGTTGACAATGATG -AAACCATCATCCACACACCGCGCACACGTGCTTTATTTCTTTTTCTGAANNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTAGGGCTCAGAACCTGCAGGTGAAGAAGC -GCTTTAGAAATCAAAGCACAACGTAACAATTTGTCGACAACCGAGCCTTTGAAGAAAAAA -TTTTTCACATTGTCGCCTCTAAATAAATAGTTTAAGGTTATCTACCCACTATATTTAGTT -GGTTCNNNNNNNNNNCCTTCTACTCTTTATCTTTTTACCTCATGCTTTCTACCTTTCAGC -ACTGAAGAGTCCAACCGAATATATACACACATAATGGCATCCACCGATTTCTCCAAGATT -GAAACTTTGAAACAATTAAACGCTTCTTTGGCTGACAAGTCATACATTGAAGGGTATGTT -CCGATTTAGTTTACTTTATAGATCGTTGNNNNNNNNNNNNNNNNNNNNNNCCTATGGTTA -CATGTAAAGGGAAGTTAACTAATAATGATTACTTTTTTTCGCTTATGTGAATGATGAATT -TAATTCTTTGGTCCGTGTTTATGATGGGAAGTAAGACCCCCGATATGAGTGACAAAAGAG -ATGTGGTTGACTATCACAGTATCTGACGATAGCACAGAGCAGAGTATCATTATTAGTTAT -CTGTTANNNNNNNNNNNNNNNNNGTTCAAAAAAAGAAAGACAGAGTCTAAAGATTGCATT -ACAAGAAAAAAGTTCTCATTACTAACAAGCAAAATGTTTTGTTTCTCCTTTTAAAATAGT -ACTGCTGTTTCTCAAGCTGACGTCACTGTCTTCAAGGCTTTCCAATCTGCTTACCCAGAA -TTCTCCAGATGGTTCAACCACATCGCTTCCAAGGCCGATGAATTCGACTCTTTCCCAGCT -GCCTCTGCTGCCGCTGCCGAAGAAGAAGAAGATGACGATGTCGATTTATTCGGTTCCGAC -GATGAAGAAGCTGACGCTGAAGCTGAAAAGTTGAAGGCTGAAAGAATTGCCGCATACAAC -GCTAAGAAGGCTNNNNNNNNNNNNNNNNNNNNNGCTAAGTCCATTGTCACTCTAGATGTC -AAGCCATGGGATGATGAAACCAATTTGGAAGAAATGGTTGCTAACGTCAAGGCCATCGAA -ATGGAAGGTTTGACCTGGGGTGCTCACCAATTTATCCCAATTGGTTTCGGTATCAAGAAG -TTGCAAATTAACTGTGTTGTCGAAGATGACAAGGTTTCCTTGGATGACTTGCAACAAAGC -ATTGAAGAAGACGAAGACCACGTCCAATCTACCGATATTGCTGCTATGCAAAAATTATAA -AAGGCTTTTTTATAAACTTTTTATAATTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAGAAGG -AATTTTGAACGATAAACTTTTCGACTGCACACGAAACATTATTACTAATTTGTGTAACCA -CTATATAAGGAATCGTGTTTATTAATTGAATTTATTCCGGGAATATTCAAGTTATGTATA -TCTCTTTTCATATTCTTAAATACACATACTCATAATATCTTGTCGAAAATACGCGGTGTA -GGGAGTTATGGTGGATAACTTTTTCACGATTAGAAGAAAAGGAAAATTTCATTATTCGTA -GCTTAACATGGCAAAAACGAGAAAGACATATAATCAAAACGTGAGTTTCCTGTGGNNNNN -NNNNNNNGGGAACCTCTGGTTACGATGATATACCTGCGTGAAAAAGGACAGTTATTACCA -ATACATACAAAGGCTTAATAAGTGTAAAATATATATCTGCCGAGACCATTACTCATTACA -CCTAGAATGGAGCAAAATGGCCTTGACCACGACAGCAGATCTAGCATCGATACGACTATT -AATGACACTCAAAAGACTTTCCTAGAATTTAGATCGTATACCCAATTAAGTGAAAAACTG -GCATCTAGTTCTTCATATACGGCACCTCCCCTGAACGAAGATGGTCCTAAAGGGGTAGCT -TCTGCAGTGTCACAAGGCTCCGAATCCGTAGTCTCATGGACAACTTTAACACACGTATAT -TCCATCCTGGGTGCTTATGGAGGGCCCACGTGCTTGTATCCGACAGCCACGTATTTTTTG -ATGGGCACTTCTAAAGGATGCGTACTCATTTTTAATTATAATGAACATTTGCAGACAATC -CTAGTGCCGACCTTATCTGAGGACCCTTCTATTCACTCAATAAGAAGTCCAGTGAAATCA -ATTGTCATATGTTCCGATGGTACTCATGTAGCTGCCTCATACGAGACCGGAAATATATGC -ATTTGGAACTTGAACGTAGGGTATAGAGTGAAACCCACTTCTGAACCAACAAATGGTATG -ACCCCAACGCCTGCCTTACCGGCAGTCTTACACATCGATGACCATGTGAACAAGGAAATC -ACAGGGTTAGACTTTTTTGGTGCTCGGCATACAGCCCTGATTGTTAGTGATAGGACAGGT -AAAGTATCACTCTATAACGGTTACAGAAGAGGCTTTTGGCAGTTGGTGTATAATTCNNNN -NNNNTTTTAGATGTGAACTCTTCCAAGGAGAAATTAATAAGGTCAAAGTTGTCTCCACTA -ATATCACGGGAGAAAATTTCCACTAATTTGTTGAGTGTACTCACAACTACACATTTTGCC -CTTATTTTATTATCGCCACACGTTTCTTTGATGTTTCAAGAAACTGTTGAACCCTCAGTA -CAAAATTCTCTAGTCGTGAATAGCTCTATTTCATGGACTCAAAACTGTTCCAGGGTTGCT -TATTCCGTAAATAATAAAATTTCTGTTATTTCCATATCTTCATCAGACTTCAATGTTCAG -TCCGCTAGCCATTCTCCTGAATTTGCAGAATCTATATTATCCATTCAATGGATTGACCAG -CTCCTACTTGGTGTTTTAACCATATCGCACCAATTTTTGGTATTGCACCCCCAACATGAC -TTCAAGATCCTGTTAAGATTGGATTTTCTGATTCACGATTTGATGATCCCACCTAATAAA -TATTTTGTAATAAGTAGAAGAAGTTTCTACCTGTTAACAAACTACTCATTTAAAATTGGC -AAATTTGTGTCTTGGTCAGATATTACTTTAAGACATATTTTGAAAGGCGACTACTTGGGT -GCATTGGAGTTCATAGAATCACTTTTGCAACCTTACTGTCCACTGGCAAACTTGTTGAAG -CTAGATAATAATACGGAAGAGAGGACTAAGCAACTTATGGAACCATTTTACAATCTGTCC -TTGGCTGCCCTAAGGTTTCTTATAAAAAAAGATAATGCCGACTACAATAGGGTTTACCAA -TTATTAATGGTAGTTGTTCGTGTTTTGCAGCAATCTTCCAAAAAACTAGACTCAATTCCT -TCTCTAGACGTCTTTTTGGAACAGGGTCTGGAGTTCTTTGAATTGAAGGACAACGCGGTA -TATTTTGAAGTTGTAGCAAATATTGTTGCCCAAGGATCAGTTACGTCAATTTCCCCAGTT -CTTTTCAGGTCCATAATTGATTACTATGCTAAGGAGGAGAATTTAAAAGTAATTGAAGAC -TTAATCATCATGTTAAATCCTACTACGCTTGATGTTGATCTTGCCGTCAAACTATGCCAA -AAGTATAATTTGTTCGATTTATTAATATATATTTGGAACAAGATCTTTGATGATTATCAA -ACCCCAGTGGTGGACTTGATATACAGGATTTCTAACCAAAGTGAAAAATGTGTGATCTTC -AATGGTCCTCAAGTACCTCCTGAAACGACTATATTTGATTACGTAACGTATATCCTTACT -GGCAGGCAATATCCACAAAACTTGTCTATATCACCAAGTGATAAATGCTCCAAAATACAA -AGGGAACTTTCAGCATTTATTTTTAGTGGCTTCTCCATAAAATGGCCGTCGAACAGCAAT -CATAAACTTTACATATGCGAAAATCCAGAAGAAGAGCCAGCATTTCCTTACTTTCACCTT -TTATTGAAATCGAATCCGAGTAGGTTCTTAGCAATGCTCAATGAAGTGTTTGAAGCGTCC -TTGTTTAACGATGACAATGACATGGTTGCATCAGTTGGAGAAGCAGAATTGGTAAGTAGG -CAATATGTTATTGATCTACTATTGGATGCTATGAAAGATACGGGAAATTCAGACAACATC -AGGGTACTTGTTGCAATTTTCATTGCAACTAGTATATCAAAATATCCTCAATTTATTAAA -GTGTCTAACCAAGCCCTCGACTGCGTTGTTAATACCATATGCTCCTCTAGGGTTCAAGGT -ATATATGAAATTTCTCAAATAGCTCTGGAGTCGCTTTTACCCTATTATCATTCAAGAACA -ACAGAAAATTTTATACTGGAACTAAAAGAAAAAAATTTCAATAAAGTTCTTTTCCATATC -TATAAAAGTGAAAATAAGTACGCCAGTGCGCTTTCACTTATTTTAGAAACTAAGGACATC -GAAAAAGAATATAACACGGACATTGTATCCATAACCGACTACATACTCAAAAAATGCCCA -CCTGGAAGTTTAGAATGTGGCAAAGTTACTGAAGTTATCGAGACGAACTTTGATCTTCTT -CTCTCAAGGATCGGTATCGAAAAATGCGTCACAATTTTTTCTGACTTTGACTATAATCTT -CATCAAGAAATCCTGGAAGTAAAGAATGAGGAGACTCAGCAAAAGTATTTGGATAAGCTT -TTTTCTACGCCAAATATCAACAATAAGGTCGATAAGCGTTTAAGAAATTTACACATCGAA -TTGAACTGTAAATACAAGAGCAAAAGGGAAATGATTCTTTGGCTTAATGGTACAGTTCTC -AGCAACGCTGAGAGCTTACAAATTCTGGACTTATTGAATCAAGACTCTAATTTTGAAGCT -GCAGCTATAATTCACGAACGCTTGGAAAGTTTTAACCTAGCAGTCAGGGATTTATTAAGT -TTTATTGAACAATGTCTAAATGAAGGGAAAACAAATATATCTACTTTATTGGAATCTTTG -AGGAGGGCCTTTGATGATTGTAATTCTGCTGGTACCGAGAAAAAATCGTGTTGGATATTA -TTGATTACATTCCTGATCACTCTATATGGGAAATATCCTTCACACGATGAAAGGAAAGAT -TTATGTAATAAACTACTTCAAGAAGCATTTTTGGGATTGGTTAGGTCCAAGAGTTCCTCT -CAGAAGGATTCAGGTGGGGAATTCTGGGAAATAATGTCTTCTGTTCTTGAGCACCAAGAC -GTTATTTTAATGAAAGTTCAGGATTTAAAGCAACTGCTACTGAATGTTTTTAATACTTAT -AAATTGGAAAGATCTCTTTCTGAGTTGATTCAAAAGATTATAGAGGATTCTTCGCAAGAT -CTTGTTCAACAGTATAGAAAATTTCTGAGTGAAGGGTGGTCTATACACACCGACGACTGC -GAAATCTGCGGGAAAAAAATATGGGGAGCTGGTCTGGACCCATTACTTTTTCTAGCTTGG -GAAAATGTACAGCGCCACCAAGATATGATTAGTGTAGATCTCAAAACTCCCCTTGTCATA -TTCAAATGTCACCATGGCTTTCACCAGACTTGCCTCGAAAACTTGGCCCAGAAACCCGAT -GAATATTCTTGTTTAATTTGCCAGACGGAATCTAACCCAAAAATAGTATAACATTTCTAA -ATATTTAATACAACTTTGGTTACATAAAAGTAAAATTTATACACCTCATTTCATTATGTA -GATTCATATATAGAATACCAATTATGATTGACCCAATAGCCATCAAAATCAGTAGTTATT -AATACTTGTCTTTCTAGGAGCCATTTGCATATTTCTGATATTTCATGAAGCGAAAGTACT -TCACGACACCTAGATTGCAATCTACTCAATGTTATCCCTGGATGAAATATTATTTCGTTA -ACGACCATAGTAACTACCTGCTTCCATATGTTTGGCCTAATGGAACCAGATCCATTCACC -CATAAACGAGAAAATGGTTTGCCCAGTGGAACTTTGACAGCAGACTTCCTTGCTGTATTC -AATTTTGTCTGAGAATTGGCATATATAATCAGAGGGGGAGTTAATGTTCGTATTTCAAAT -CTCCTTGAAGTATACGTTAAAGGTCGAACATTTCTCACCATTGGAATTACATCCATATTC -AATAGCTCTCCCGAAATCAAATCAATTAAAACCCAAGAGGATATATCGGACGGCTCTTGA -TTGATAACAATAGCGTTTCCGGCCTCCAATAATTCATTAACCTTACATCTATACTGAAAA -GCTACACCAAAATCTTTATAATTTCCTCTATTTTCCAAAATGTCTGGTAAAGTATCAGTA -CATTCAAGTTTTGAGCCATGGAGATAAATTTGCTTTTCCTTAGCCATATCCATGATGACG -TTATCTATTGATTCGTTTCCAACGTTCTTCAACGCCTCTATTTCATTTCTAGTGGTCGAA -GGACTTTCTATTAATATGGACCGGATCACTGTGCGAATATAATCGTCGCTTTGACTCTTC -GATAAGTCCTTAGTAGAAGCGGAAATCTTTCTAGTGTAAGNNNNNNNNAAAGAAGAGATC -TCTCTTTGAATCATAGAAGACATGGCCAGATCGTTGCCAGAATGTGTAAGTGTGTCATCA -CGTACCAGAGTAAATTTTTTTCTATTCTCTTCGTAGTTCTTATAAAGAAAGAGCGGCCTT -TTTATTTCCTTTTCATCAAAAGAGGTCCAAATATCAAGCAATTTGATAAGATCTAGTTCT -TCAACATCCCTCAGTGAAATCTTTTCACTTTTAATGGCTAGAACGAGCATTTTTTTCCAC -TTATCGACATATGCCCTCCAACCACTATGACCCATTCTTACTCGCCGTGCCGTCCATTTC -TTTTTTAGGTTATCTAAAGAATTATTAGGAAATAATTTTGTTATTTTGTCCCACATTATT -TCATTTTTAATACTTTTAGTAACTACAACAGCTCTGATTAAAGCCTGAACACCATCTTTA -GTGCCTGCATGATAGACAGTTTTGTCTTCTTTAGTATTTTCCACGACCACCGTTGTCCTA -CCAGCAGACACTTTTTTGTCTCTCCTTTTGATCTTTCCATCTGATACGTTGACCGACGTA -CTCTTCTTAGAGATAGCGTCATCTGAAGCTTTGATCTTAGCATTCTTTTGGCGGTTCTGA -AACTTACGAATTCTTTCAACTGATTTCTTTCCTCTGTGAAACCTATTTTTTTCCGTTTGG -TCAAAGAAGTATATTTCCGTATCATGTATAACATCAGTAAAGGTTGCTTTTTTACTATCT -TTTTCTTTCAGGATGTACCTTTGGATAGCGTCCTCTCCAACAGTGGGCAAAAAAATAATT -TTTCTTCCTGATACAGGCTCTGTTCTGGCTCCTAATTTTTCGCTTTCTACCATCAAATCA -ACATCACCACGGACAGTCTTTTTATCTAATGTCGTTGTGGAGCCCATATATTTAGAAACG -CTTTCGTAAAATTGTTCTCTCAGGTATGCTACCCCACCAATCGTATTCATAACTTTCAAA -ATGGCTCTCTGTCTCTGTAGTGAACGCAAAGAGCGGGCAGAAAAGCCGCCGAAGTTAACC -ACCTTGCCTTTGACAACAGTGCCTCCGTTTGAACTTGGACTATCTTCAGCAGATTTCGGC -TCCTGTGCAGTGCTGACATGCTGCTCTAGCTTAATCCTTTTGGGATTCGAAATGTTTCCT -GCAACAGAAGCATTAGTACTGTTTTTAACCTGCCTCTTCNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNAATTCACCGTGCCAGAAGAATATATCCTGTCCATCG -CTGTCCGTTGTAAATCTAACAGTGTTGTTGAGTGCGACGAAATTATCCTCGTTGAGAGTT -TTCAAATCGGTACGAGATTTGCCTAGCTCATCAAACCCTTTTGGAACGGATATTTCGTCT -TCCGCATTTGTTAACTTTTGAAAGTTCTGAGCTGTGAACAGCCTAAAAAACTTCTTCTTT -CCCTCAAAATCGTATATGCGAAAAAGCCTATACCCCCCTGTATTTTCTTTTTGCTTATCC -ACACTTTCTAAATAATATTCGCTTGATTTGGTAAAAGCTCGCTGAAATTCTTTTCCGGTA -ATTCGATTTACAACATCCATAGTTGAAATTCCTTTAAGGCCAGACTTATCTGCAATGTCA -TAAGTCTGATTTTGAAGTGGATAAAATCGATTAAGAAGAACTTCATTCTTTACAGCATCC -TCTTTCTCTTCCATAACAAGGCCTTGATTTTGTAATAAATCAGTCGCATTGAAATTATCT -AAACCTTCGACTAAGTCTTCATCTTCGAAAGCTGCCTTGCTATCTGATACAGAATCTTCA -TCCGCGCTATTGCTATCATACTCAAATGAAGGCGAGCCTTTAGAGTCTGGAATATCTTTC -ACGTATTTTACACATCTGATTTTAATGGCAGGATTCTTGGGTGATACTACAAGCACTTTC -TTTAAGTACTCCTTTTCATCTAACCATGCAATAGCTGCAATAAAAGCTTTAGAAAGTCTT -TTCTCTTTGTCAAATTTCAATTCACGCTTTAAATCAATTATCTGGCGAATACCATTTTTT -GATCGTTTTACCACCTCAACTATTGTTGCTAAATGATCCCTAATATTAATATAGGGATTA -CTATCCACCCCGTCATGGCTGAATTTTTTTAGCTTCAATTGCTTCACGACGTGTCCCTTA -TAAATCAGTTGTGAACTTGTTAACAGGTGGTTTATTTTCTTGATACGTCCAGTCACACTT -CTAGGATCTTGCCCAGTTACCTGCGCCAAATCCATAGTATTGATCCCTTTTTCTCCTGAT -TTGGCAACTTCGAGAAGTAGTTCAAATGCAGAATTTCCAATAGTTGACTCCTTTTTTGTG -TATCCCGTTAATAATGTCCATAGGCTGTCCTCAGTAATCCCAACCGAGTATGAATGATTA -GCGTCGCCTATAATATCAGTCACATTTTTAGTTGTTATAGCACCATCACAATACACCTCA -ATGTCCTTTTTCAATATCACGCATGAAAGCACGAACTGTTTAACTTTTTTATCAGACAAA -TCAAAATATTTACCAGATATATCCCACAGCTGATTCAAAGTGATTTCTTCAATGTGTCGT -TAGTAAATAATCTTTCACAATATAGTACGTTTATCACCTAAACGGAGCCGAAAAGGAGAA -TGAGACATGAACATACTTCCCTTATTTGAAGCAATTTTATCAGACACTATTTGTACGAGT -TCGTCAGGATAAATCGTCAGTACCATTTTTCTTGTGGCTAGTTGGCTTCAACCAAACGTC -CTCTTCTCTCTTATGGCAAGAAGAAAGTTATATGTGTGACTGGTTGTTTATTTCACTTTC -GCGACTGAAAGCGCCGCCCTTTATGATGCAAAAAACCAAGCGGTATTTGAAAATGCAGAT -TTGCANNNNNNNNNNNNNNNNNNNNNNNNNNCTTATAATTTTACCAGCTTCAATAACTCG -ATTTGCATAAGTGTGCCTTAGTATGCTTATTATATTGACTTTGACATTGAACTTCAAAAC -CTTTTATGTAATGATTTAAGTCTTGTCACATGANNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNCCGAAGCAGTCAAAGTATTTTAATTTTCGGAGCTTTCATTTCAAGCGCCNN -NNNNNNACACATAATACGATCAAGATAAATTATTATAGTGGTACAGAACTCTTAAGCACT -AGGCGGTGGACCTTATTAGCTCAATCTTGAGTCAGTCCATGTATCGTTTTATAATACTTT -TTTAAGCACTTTCTTTAATAAATATTCCATTGAAGTACTGTTACTGAAATGAGATGAACT -GTTCAGAATGTAGAAATGGCGCCAGAAATCAATCATTGTTTAGCAAAAACACCTTTCGTC -TGCTGCCTCGGGTGTTTTTTCAAATTATTTCAGCAGGTAAATTAAGATAGTTATTCGAGT -GATTGCCAAATATCATGTTCTACTTCGAAGACTTATAGCTAATTAATTTTTTCATAATGA -AGGTGTCGTTAATTGTTCTGATTAGTAACATGNNNNNNNNNNNNNNNNNNNNNNNNNNNN -GCTAAATGTATACTTTTTTGTCTACATTAGTTACCTTTTATTACATGAGAAAGTTANNNN -NNNNNNNNNNNNNNNNNNNNNNNNGAAACTTTTTCCTCTCGGAAAATAAAAGATATATTT -ACAAGTGAAAGCTTATTGTAATGTGTACTTTTAAACATCAAATAACAGACCTTTACATCA -AATAAGCACCGCAAGATATCCTAAAATCGACATCCAATGCATCGTAAATCATTGAGGAGG -GCTAGCGCTACTGTGCCTTCCGCTCCCTATCGAAAGCAGATTATTAGCAATGCACACAAT -AAACCAAGCCTTTTCTCTAAAATTAAAACTTTCTTTACCCAAAAAGATTCAGCCAGAGTG -AGTCCAAGGAATAATGTTGCTAATAAACAACCACGCAATGAGTCTTTTAACAGAAGAATC -TCAAGTATGCCTGGAGGTTATTTCCATTCTGAGATATCCCCAGATTCTACTGTAAACCGT -TCCGTAGTTGTTTCTGCAGTGGGTGAAGCCAGAAACGACATTGAGAATAAAGAAGAGGAG -TATGATGAAACACATGAAACTAACATCTCCAATGCAAAGCTTGCAAACTTTTTTAGTAAA -AAAGGTAATGAGCCTTTATCAGAAATTGAAATAGAGGGTGTGATGTCATTGTTACAAAAA -TCAAGCAAATCCATGATAACTTCGGAAGGAGAACAAAAATCAGCCGAAGGTAATAATATC -GACCAGTCGCTTATCTTGAAGGAGTCAGGAAGTACACCAATCAGCATATCTAATGCGCCG -ACCTTCAACCCAAAATATGATACTTCAAATGCGTCAATGAATACGACTTTGGGAAGCATT -GGTTCAAGAAAATACAGTTTCAATTATTCTAGCCTGCCCTCACCATACAAAACAACCGTT -TATAGATATAGTGCAGCGAAAAAGATCCCCGATACATACACAGCCAACACATCTGCTCAA -AGTATAGCATCTGCTAAATCGGTAAGAAGTGGTGTTTCAAAGTCAGCTCCTAGTAAGAAA -ATAAGTAATACAGCTGCGGCATTGGTCTCACTATTAGATGAAAATGACAGTAAGAAGAAT -AATGCAGCTTCAGAACTTGCTAATCCATACTCCTCATATGTAAGCCAAATACGCAAACAT -AAGAGAGTTTCTCCAAATGCTGCACCAAGGCAAGAGATCAGTGAAGAAGAAACTACTGTT -AAGCCATTATTTCAAAACGTTCCTGAACAAGGCGAAGAACCAATGAAACAACTGAACGCC -ACCAAAATTTCACCATCTGCGCCAAGCAAAGATTCTTTTACTAAATACAAACCTGCAAGG -TCCTCATCCTTACGCTCAAATGTCGTCGTAGCTGAAACCTCACCTGAAAAGAAGGATGGT -GGAGATAAACCTCCATCCTCTGCTTTTAACTTCTCGTTTAATACTTCAAGAAACGTTGAA -CCTACTGAGAATGCTTATAAGAGCGAGAACGCACCATCTGCATCATCAAAGGAATTCAAT -TTTACCAACCTACAGGCGAAGCCGTTAGTTGGAAAGCCAAAAACCGAACTTACAAAGGGC -GATTCTACTCCCGTCCAACCAGATCTTTCGGTTACTCCTCAAAAAAGTTCATCGAAAGGC -TTTGTTTTTAATAGTGTTCAAAAGAAATCACGGTCCAATCTTTCACAAGAAAACGATAAT -GAAGGTAAACATATCAGCGCCTCAATTGATAACGACTTTTCAGAGGAAAAGGCGGAAGAG -TTTGATTTCAATGTTCCCGTGGTGTCTAAGCAGCTAGGAAATGGCTTGGTTGATGAAAAT -AAAGTTGAGGCTTTCAAGTCCCTATATACCTTTTGATAATGAAAATTTTAGCCGTGACAT -AATTACCGTATAGCCCAACTCAATACGTAAGTTTGTGTAAAATACCATTCCAAGATGATA -TTATTTAGTCANNNNNNNNCCACTTTCTCAAAAAGAAGGAATACCTTTAGCGGCTCTTAT -AAACTATAAATTTCTAGAAGATACATAAAAGGTTTTTAGTCTGATCATAAAATTTTTTGC -TTAACAAAAAATTTGCCCAGGTGTTTCATTTGCCAGCCACAAGTAACAGCGAGAACAATT -AATTGAATGACAATCCACCACATAGCACGAGAATTAACAGCTTCAGAGGCGTCTCTAAAG -GTAGCTTCACGATCTCTCATCAATTTTTGCTCTCTTCTAATTTCGCCGATCTTGGAGTTT -AGGACGTTAACCTTGGCATGTAGAATGTCAATAGTGGCTTTACCCTTAGAATCTAACTTT -TCATCAGAGCCCACTTGGAATTCAACGTCAATCTTCGTTTTAGCCTTAATCAACCAGCCA -CCAGCTTCGGGCTGAATACAGATTTTATGTTCACCCGAATCAGACGCAAGGAAAGTTAAA -TCACCACTTGCTGAACCTTTCTGATGAACAACCAGGTGGTTATCATCAAAAGTTTCCTCA -ATATCAATCAAGACACCAAAATCTTGCGCACCAGCGTCTCTGTAATTTTGTAATTGGTCA -TCGTAAATTTGTGCCTTGTAAGTTGCTTGGAACAAAGTACCTTTAGACAATTCCTTGTGG -AAGCACTTACGTTCAGCACCAGAAGTATAATAATAGAACGCAGTAACTTGAGCTGGTAAA -ACTAGACAGCAGGCAAAAACCTGTAAAAGAGAGGTTAAAAGCATGATTAGTAGAGAGATT -GGTTACCTTTAAATACTTTTCCAAACTACAGAGGGAAGATAGAGTAAGTTTTGTATGTAC -ACATTTCTGCTGATGTGNNNNNNNNNNNCAACTTATTACGCGATTCGNNNNNNNNNNACG -GTAACAGAATACAGAATAAATTCACGTACAAAAATAGAGAATATATAAAATAATAGGTTG -ACGATTATATTGGATCTTCCCCTGGGGTTCAAGAGTCGAGACCGAGTCCTTTTAGTTTGT -GTATATCAGCTGGTTCTTTTCGTTATGAACATCCTTTTACAGGATCCATTCGCTGTTCTT -AAGGAACATCCTGAGAAGCTCACACATACGATTGAGAACCCTTTACGCACTGAATGTCTC -CAGTTCAGTCCTTGCGGTGATTACCTGGCTCTTGGGTGTGCCAATGGAGCACTTGTTATT -TACGATATGGATACGTTCAGGCCTATTTGTGTCCCAGGAAATATGTTGGGAGCACATGTT -CGACCCATTACATCTATCGCATGGTCTCCAGATGGTAGATTGTTGCTTACAAGCTCTAGA -GACTGGTCAATAAAACTGTGGGATCTTTCAAAGCCAAGTAAGCCTTTGAAAGAAATACGA -TTCGATTCTCCAATTTGGGGTTGCCAATGGCTGGATGCTAAAAGGCGGCTTTGTGTAGCT -ACGATATTTGAGGAAAGTGACGCATATGTTATTGACTTCAGCAATGATCCGGTCGCAAGC -CTTCTCAGTAAATCAGACGAAAAACAATTGAGTTCGACACCTGATCATGGATATGTTCTT -GTTTGTACAGTACATACCAAACATCCAAATATTATTATTGTTGGAACTTCAAAAGGTTGG -CTAGACTTCTATAAATTCCATTCTCTATATCAAACAGAATGTATTCATTCCCTTAAAATC -ACGAGTTCTAATATCAAACATTTAATTGTCTCGCAAAATGGTGAAAGATTAGCTATTAAC -TGCTCCGATAGAACAATAAGACAATACGAAATAAGTATTGATGATGAAAACTCTGCGGTT -GAGTTGACCTTAGAGCATAAGTACCAGGATGTGATTAATAAATTACAGTGGAACTGTATC -CTCTTTAGTAATAATACTGCCGAATACTTAGTCGCTTCTACACATGGTTCTTCTGCACAT -GAACTATACATCTGGGAAACGACTAGTGGAACGTTGGTGAGAGTCCTGGAAGGGGCTGAA -GAGGAGTTGATAGATATAAATTGGGACTTCTATAGTATGAGTATAGTGAGTAATGGTTTT -GAATCTGGGAACGTGTATGTGTGGTCTGTTGTTATTCCGCCAAAGTGGAGTGCTTTGGCG -CCAGATTTTGAAGAAGTAGAAGAGAATGTCGACTATTTGGAGAAGGAAGATGAATTTGAT -GAGGTCGATGAGGCAGAACAGCAGCAAGGACTAGAACAAGAGGAAGAAATAGCTATCGAT -CTTCGGACGAGAGAGCAATATGATGTTAGAGGTAATAACTTGCTTGTAGAACGGTTCACA -ATCCCTACAGATTATACGAGGATAATTAAGATGCAGTCATCATAGGTTTCTCTTCAAAAG -GAGAAAGTTTAAATAGGCAACTGACACTGAAGAGGTATAGTCATGCCTACCGCGATTTCT -TTGACACAGAATTGAAAAATTTTGCATTTTTTGGTAATTTCCTAATAATACGAAGTGCAA -TAATCTCACTTTGATAGGAGCACGTCATGATGGTAATTTCATACTACTGAACGTAAATGT -TGAAGGTGAATTTGTAAAGCTTTGTTATTTGAAGCTGTACACCTAAAGGGCGGTAAATTG -TTGGGTGTTAGTACCATGCCATTAATTAGAATTTGTTAGCATTTTTATTCATTTGTGCAT -TATGGGTTCAAATTCATATGACTGAACGTGTAGTTTCATATCCAGTCATCAAGAGATGCT -GAACCGCCCTTCAAAAACTTGACGAAATAGAAGNNNNNNNNNNACATTTCTCATATGTTA -CATAGATTAAATAGTACTTGATTATTTGATACATTAAGCTAACAAAGCCTTGGATAACTC -ATCGGCAAGATAGTCGGCTTCAGCCCTGTAATTCAAGCTGTGTAGGTTAGCAACGGTATA -TCTAATTCTGCTTTGATCATTGTATGTATCCTCACGCGCTCTAATCCTAAAGTCATATTC -GTTCATTTGGATACTTTGAGTAATTTTTGTGAATTCGTTGGGGTCTTCTTCCTTCAAAGA -CATTAATGTATTAGCATCAACACCCAATAATTGTTTAGCTTGGTCGTCAAATAAAGTGAG -CCATAGTTGATTGGTTTCGTCAATAATTGATATTGTCAAGATGTATCTCCAATTTGGCCT -TGCATTATTGGTGTCGCACTTCTCACATCTCCAAGTACCATCAGGCTGTTCCAGAACTTT -CTTATTACAATTCTCATTAGAACAGGCAGGATATGCAAAATTATCAACTTTTAAGAAACT -TATAGCAGCTTTAACACTAAAAAAGTCACCTTTCTCGCTTCTTCCTAGATTTTCAGCTTG -AGCTCTAGCAATAGTAATACGCTGAGCAATGAATTTTGTTAAGCTAGCAGCCGATTGACC -ACCCATACCGGGTTCTTGCTTTAAAGTGATGAAGTTTGCGTTGCGGCCCTTGGAATCATA -CCAACCCTTTAAGGCATATGCCTCAGGAATTTCTGGATTCGGAATCAGGGTACTAGAAAA -TCCCATAGACAAAGATTTGCCACCAAAATCCGTCACACGAACACCTTTAATGGCAGCAAC -AGAACCTTCAGGAAGGTTGAAATCAAGGGCTTGCTGATTCCATAGGCCAACAGAGATAGA -AAACCCAGAGTCGTCAACAATTGTGATGTCACGACGATCGAATTTCTTCCCAGCCCTTGA -AGTTAGCTCAAAATGTGGGTTTATAGTTTGGATAATACCGAGGACGTCTACGTTGGAATT -TACTTCCTGGTTCTGAATAGCATCTAGTTTGATGAAATTGAAATGGGTTTTCGGAACATT -ACTTTCATCGAAACATTCTTCTATAACAGTGTCTCTATCCAAATTCAGTTCATAAGGGTG -TGTTAGATTAGTAAATTGGGGCTTAGCTGGTTGGAGTTTTGCCTTTGATACATAGTATAC -TTTGCCTTCTTGTAAAATTTCGTTAAATTTTGTAGCAAAATCATTAAACGCCGTGGCTCG -GATTTCTCCAGAGGTATCCAAGAAGTTGACATTGAATAGTTTACCATCACCTCTTTGATT -GTGCCACGTTTTAATTTCTCCCTTGTAGGAAACTCTTGCTTTGATAGTCCAAACGTTTTG -GTATGGAGACAGTTGTTCGATGGCAAAAATTGGTCTGGTTTTTTGCGAATTAGGGTTTTC -ATTGGCGAATTTTCTCTCATTTGCATTCAAGTTTGAGTTTGAATGCAGCATATCAGGGAC -ACCAGCATTGCTGGCGTTTGTTTGATTGGCAACATTACCACTGTCAGTTATATCTTCGTC -TTTTAAGGTTTCATTTGGATGCTCTGAGAAATAGTTATCCAAAAAAGTACTAGTTTGGTT -GACCATATCAGCACGCGACTGGACCAACTCAAAGTCATCTACTAAAAGAACGTATTTCTT -TCTTTCCCTGACAATAGCAGGTTCTGCAATTATCACGCGAATGATATCACCCCTTTGTAG -TTCCATTGACTGGAACTTGGATGCAGCTTGGTTTCTCAACAGAGCCTTCATATGGTAAAT -ACCATCGGAAATCATGATCAAATTCTTTCTGTTGCTGTTAGCCCCATCAGATTTCCTGGT -GTTATAAACTTGATAAACGCCACCGGTGGGATTATCGTACCTTTGCTTATTGGTGAAGAT -GCTATGAAAATCGCCCCTCGAAAGTTGAACACTGCTCATCTCTTGTAAGTATAATCTGGT -CTTCTTGCTGGTTTCGCCTTTACCGTAATAAGAAGAGTGAATAGTTTTTGTTTTACGTGT -AGAACTTAAAGTGATAACATTTGTTCAAGTAAACCTTTATGTTAGTTCACGCGTCTTTTG -TCGCCTCGTCTAATTTTTACGCGTGACATTTTTCCAAGCAGAGATATTTTATTGAGCAGC -GAAGAAGAGTTAGAGAATAAGAAAGTGATGCGATAAGAAATCCACCCAATTAGCATAGAT -CCTTTCGTATATGGCTGAAGAAGGTGGTACGCGCATAGCTATTAACATATATGCAAAAAG -AACGGCAAAAGGCGAGGAGGTTTTTATGCCACCGCTAGTATTTGACATAGATCACATCAA -ACTTCTAAGGAAATGGGGTATTTGTGGTGTGTTATCTGGAACTTTGCCTACTGCAGCACA -GCAAAATGTATTTTTGTCGGTACCTTTGAGGCTTATGTTAGAAGATGTGCTGTGGCTGCA -TTTGAACAATCTTGCCGATGTGAAATTAATAAGACAAGAGGGAGATGAGATTATGGAGGG -AATAACATTAGAGCGGGGCGCCAAACTATCTAAAATTGTCAACGATCGTTTGAACAAGTC -ATTTGAATATCAGAGAAAGTTCAAAAAGGATGAACACATTGCAAAATTAAAGAAAATCGG -TAGAATCAATGATAAAACCACAGCTGAAGAATTGCAACGGCTTGATAAATCTAGCAATAA -TGACCAGCTAATTGAATCTTCTTTGTTCATTGACATTGCTAATACCTCTATGATTTTAAG -AGACATACGGAGTGATTCAGACAGCTTATCCCGCGATGATATCAGTGATTTGTTATTTAA -GCAGTACAGACAGGCAGGAAAAATGCAGACCTATTTCTTATACAAGGCATTGAGAGATCA -AGGGTACGTTTTGTCCCCAGGTGGACGTTTTGGTGGGAAGTTTATAGCATACCCTGGTGA -TCCTCTTCGTTTCCATTCACATCTGACGATACAAGATGCGATTGATTATCATAATGAGCC -GATTGACCTAATATCCATGATAAGTGGTGCAAGACTAGGAACGACTGTGAAAAAACTTTG -GGTCATAGGCGGTGTTGCGGAAGAGACAAAGGAAACTCATTTCTTCTCAATAGAATGGGC -TGGATTTGGTTAAGCTGGGAATCAGTCATGTATAATTATTTTCTCAGAATTTATGTATTT -ATAAGGTTTTTCAGAAGCATACATATGTGTAATACAATTTTTAAATTTGCATTGATATTT -TGATGCATTCAGCGGGAAAGTAGTTGTTTATCACTAGACATATAATTATGTTTATTTATA -TTTAGTGGGAGCAAAACAGTTTATTGAATGTTTACCAGAACCGNNNNNNNNGCTCTTCTA -AACTGTTGACATCCAGTTCATTTACTTCCACGTGTAGATGTGAAGGAACAAATATTTTAG -CATCGTTCATACAAGTAATTATGCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNGGTTCTTATTTTCAACAATGTAATTGATGGCCTTAAAT -CTCTACTACATCATAAAGCTTCTAAGCACTTACCATTCCTTCATAAGTCTAGTATTGTAA -TGAGTTGGGCACATGGCGCAGTTGGTAGCGCGCTTCCCTTGCAAGGAAGAGGTCATCGGT -TCGATTCCGGTTGCGTCCAAATTTTTTTGTTAATCCAACACAATTGAATTCGTGAATAGC -TGACTGTCATCAGTAATGTTCGTGGAAAGTACCTATCCATACTGTTGTATCACGACTAAG -TAGTTGTCGACTACTACCTCCTCAACCCCAGTTATATCCCTATGACACATTGGAGGATGC -TGAATAATGACAGAATTTTATTCCTCCTTTTCATTATCATAATCTGAAGCAAAGTTAAAA -AATAGAAGAAGTAAGATAAACTTTGTAGATACGATATATAGTTGTTTGTTTTAGCTATCA -TATATGCTGAACTGTTACTACCTTATTTTTTCCGAAATGTTTCTAAAACAAATAAATATT -CATGAATATGATGCAAGTTCGTTGGATGAGAAAAAGACCAGGCTTTATTGTAAGGACAAT -ATCATTTACGAATAATTTCATCCAATTGTTTCATCAACACATCCATTCTGTCAAAAACTG -GAGCATAGAGATGTTGAACCAAAGAATTGGGCTTCGAAGCCGGATCGGACATATTGGTAT -TAGACAATGCCCTTGATCCGGAAAGTGAACTATTTATGCTTGCTGATGATACCGCCCTTT -GTTCATCCATATAAAAATCTTCTTCAGATGATGAGTGTAACGATAAGGTTGATTGCTTTT -CTTCTTCGGGGGTACTGTGATGTTTTTCTAGCTCCTCTTTAGGTTGTTCTGCGTCAGTTT -GATTTGCCATTCCTCCACTAGACCCCAAGCTGGCTTGAATTTGCCCCTCTGTGTTTTCCA -CGTTTGTTGTCTCTTCAATTTTCGATTTTGCATGAATATATTGTGAAATGTCCTTTATTG -CTCTAGATGATGGAATACTGCTGCTTTCTTCAACTATTGGAGTGGATGGTGATTCGTTTG -TCCATTCTGACGACGACGGTGAAAACTCGCCAATTGTTGAAAGGGAATTTTGAGAGTCTG -ATTTTGCCATACCATTCGCAAATGGCATACGAGGCGCTTCAAATACTTTTTTCAGATCGG -TATCGTAATCACTGTCAACCGGTTCAGACTTTTCTTGCCCCACATACCGATTTGCATTAT -AATCATCTTCTCTGTCTTTACTCGATGATGTCTTAGGCTCACTTTCGTTTTTGTTGTCTT -GTCTCCGAACTTTTTTCACATTTAGTGGTGTATTCAAAGATGTACTAAAGGAGACGTCGC -TCACTACATCGCTCGTATCATCATCCTGGAATTTGCCAAAATTTAACTTCGCTTCAGTGT -ATTCGTCCCGGTGCGTTACTTTTGTTTCCTTGTCGTTATCAACATCATCGTCGTACGACT -GTCCATTGCCTTCACCGCCATCATCGTTACTATCTAACGAGGTATCTTCAATTGCATCAT -CTATAAACCTGTCTGCATAACCGACAACATCATTGAAACTAACAGATTTGTTCCCCTTAC -CATATCCATTCAGTGCAGGTGTCGGAATTATACTCTCTGCATCACTTTGATTCTTGTTAC -CAGAGCTGATGGAATCATCTTTCGAATCGGAGGAAGCAACCGATTGAGAAGACATGTTTT -CATTTTTCCAGCAATTCAATCGAGCTAGTCTTTCTGGAAAGGTTTCTAGAATTTCCGCTG -GCGCAAACCCGATTTTACCATCAGTGATCCTCTTAACCAGCCACCAATAGGCATCCTGGT -CATTCAAAAGTATACAAGGTTCGTCTTGCCCTAATTGACAATGTGAAGAATCATGGCCAT -TGAACGCATATAAAGCATATAGTTTATCAGGGTCCAGTTCTCTTGGCGGCGATAAGGGTT -GGTAATCGTCGTTTTCCTCCTCCAAATCGTCTTTCTCCCCTTGAAACCCTGAATCTTGAA -ATTTTCTGTCAAAGTCATCGTCATCAGAGTAGTTTTCCTCTTCATCCTCGTCCTCCGAGA -TGGCGTATTTCAAGCCATCACTAAAATCGTCAACGTCAGGGTTCATTGTATTATTCACTG -AAAAATGCACCTCATCCTTATCGGCGCTATCCACGGAATCAGTTTCGATCTCTTGTAGCC -TTCTTTCCAAATTGTCCTCAAATTCAGAATCCGAATAATCATATGAGTCGGGCAATTCCG -AAGAATTTTCTTTGTAATGTCGCTGATCCCTTTTACTGTTGCTATGCATATGTTTTTCCA -CGTTCTCCTCCTCTAACTCTTTGTCATCATCTCTATTTCGCAGAACATCATGGCCCTTTT -CTGCCGCATTACTCAGTATATTAAGTTTCGAATTGAAGGGCGAACTCTTATTCGAAGTCG -GAGTCACCACAACACTTCCGCCCATACTCTCCGAATCCTCGTTTCCTAAAGTAAGTTTAC -TTCCACTTGTAGGCCTATTATTAATGATATCTGAATAATCCTCTATTAGGGTTGGATCAT -TCAGTAGCGCGTGCGATTGAAAGGAGTCCATGCCCGACGTCGACGTGATTAGCGAAGGCG -CGTAACCATTGTCATGTCTAGCAGCTATAGAACTAACCTCCTTGACACCACTTGCGGAAG -TCTCATCAACATGCTCTTCCTTATTACTCATTCTCTTACCAAGCAGAGAATGTTATCTAA -AAACTACGTGTATTTCACCTCTTTCTCGACTTGAACACGTCCAACTCCTTAAGTACTACC -ACAGCCAGGAAAGAATGGATCCAGTTCTACACGATAGCAAAGCAGAAAACACAACCAGCG -TACCCCTGTAGAAGCTTCTTTGTTTACAGCACTTGATCCATGTAGCCATACTCGAAATTT -CAACTCATCTGAAACTTTTCCTGAAGGTTGAAAAAGAATGCCATAAGGGTCACCCGAAGC -TTATTCACGAGTCAGTCTGACTCTTGCGAGAGATGAGGATGTAATAATACTAATCTCGAA -GATGCCATCTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCTTAC -CCAGATTCTTTGAGGTAAGACGGTTGGGTTTTATCTTTTGCAGTTGGTACTATTAAGAAC -AATCGAATCATAAGCATTGCTTACAAAGAATACACATACGAAATATTAACGATAATGTCA -ATTACGAAGACTGAACTGGACGGTATATTGCCATTGGTGGCCAGAGGTAAAGTTAGAGAC -ATATATGAGGTAGACGCTGGTACGTTGCTGTTTGTTGCTACGGATCGTATCTCTGCATAT -GACGTTATTATGGAAAACAGCATTCCTGAAAAGGGGATCCTATTGACCAAACTGTCAGAG -TTCTGGTTCAAGTTCCTGTCCAACGATGTTCGTAATCATTTGGTCGACATCGCCCCAGGT -AAGACTATTTTCGATTATCTACCTGCAAAATTGAGCGAACCAAAGTACAAAACGCAACTA -GAAGACCGCTCTCTATTGGTTCACAAACATAAACTAATTCCATTGGAAGTAATTGTCAGA -GGCTACATCACCGGATCTGCTTGGAAAGAGTACGTAAAAACAGGTACTGTGCATGGTTTG -AAACAACCTCAAGGACTTAAAGAATCTCAAGAGTTCCCAGAACCAATCTTCACCCCATCG -ACCAAGGCTGAACAAGGTGAACATGACGAAAACATCTCTCCTGCCCAGGCCGCTGAGCTG -GTGGGTGAAGATTTGTCACGTAGAGTGGCAGAACTGGCTGTAAAACTGTACTCCAAGTGC -AAAGATTATGCTAAGGAGAAGGGCATCATCATCGCAGACACTAAATTCGAATTCGGTATT -GACGAAAAGACCAATGAAATTATTCTAGTGGACGAGGTGCTAACGCCAGACTCCTCTAGA -TTCTGGAACGGTGCCTCTTATAAGGTAGGAGAATCCCAAGATTCTTACGATAAGCAATTT -TTAAGAGACTGGCTTACTGCTAATAAGTTGAACGGTGTTAACGGCGTCAAAATGCCCCAA -GACATTGTCGACAGGACAAGGGCCAAATATATAGAGGCTTATGAAACATTGACAGGGTCT -AAATGGTCTCACTAACGTGATTTACATATACTACAAGTCGCCAGTGTAACTCCTCACTGA -ATATGATTCATACATACCCGTATGTATTAATGTATAAATGTTCTCAGAGCAAATTTTATC -GATATCTTGTTTGCCAGTGGTATGCAGGTTTGGCAAATTTTTTACCATAATATCCGTTTA -TAGATTCTGGAACCTTACCAACTTTCTTACCGCTAATTACTTCCCTGGCTCGCTCCTCCA -CTGCCTGGGTAAATTGTTCCTTCAACTGACTCAGTTCTCTTTCGTATTCAATAGCTTGCT -TCTCGAGGATTTTTTCAATGTTTGTCAGCTCATTTTCATAGTCCAGTAACTTCCTTTCAA -ATCTCTCTAATTGCAACGACTTTCTTGCAGTTCGTATCTGAATATCTTGCAGTAATTCAA -AAGTGGAAGGCCTGGTTCTTAAGTTCACATCTATCATTGAATGTATTATGGCATTAAGCC -CTCTAGAGTAATACTCAGGGACGGTGTCACATTTCCCGTTTTTAATCTTAGTTTGTAGCT -CGAGATAATTTTTTGCCTGAAATGGGGGGTGCAACGAACACATCTCAAAAATAACACAAC -CTAGTGACCAGATGTCGGATAGTGGGGAGTATGGTTGGTCCATCAACACTTCAGGCGACA -TGTAATATGGTGTACCGACGTATGTTGTGGCAAATTGAATACTAGTTTCCAGAGATTTGG -CTAACCCAAAATCACCTAACTTTACCACAACTTGACTATAGTCCATAGGGCTCCCCCTTT -TCCCTGAATTCACTCTATGGTCTCTGTAATAATTACTATTCACTTCCTCGTGACCGTCTA -CTTGTTCATTAATATTGTAATCGCTATCATCATAGCTTAAGAATATATTTCCTGGTTTCA -GATCACGATGGATAACGATGTTTTTGCCTTTTACCGGTGGTTTCATCCGGTCATATATTG -TGGTCAAAGTTGGCAATTCAACACCATAATGACATTTATAGAGCGCAGTCAATAATTGGG -CCAGGATACCCCACACAATTTTTTCTGGTATATATTTATGCTCCTGTTTGTAGTGCTTAA -TCATCTGGGATAAATCACCCCTGGAACAATATTCCATATAAAGGTATAACACTTCTTTTT -GTTCATCGAAGTCCCAGTTATAAAATTCTACAATATTTTCATGCTTCAACTGCGATAGAA -TGCTACATTCAGCGATCAGCTGTTGTCTCTCTTTGCTATTCATATGGCCATATTTGATAT -CCTTTCTAACCAAAAGTTTCTTGGTAGGTATATGGATGACTTTTCGTACAGACCCAAATG -AACCTCTCCCAATTTCTTCGAGAACTTGGTATTCTGACCTTGGTGGGTGTCCCTGCTGCT -GCTGAGGACTACGGTATTCTTGGAAAAACTGTCGTCTATGCATACTCACACAGAGAATTG -ATTCAATTATCAAATAGCACTCTCATTGAAATTAGTATTGTGAATCTTGCTCTTTTCATG -TTATATGATTTGATATTCTTTTGAAAAGTCGCTTTTATTTACGTTTAACCTAATTAGGAA -ACGTAATGAAAAAATTCAGAAACCTTNNNNNNNNNNCTTGGCTGTAACCTATCGGAAGAC -TGTGCCACTGCAATCATGTCAGATATCGTATTTCAGATTTATTGATCTATAGCTAGAAAC -ATTTAACAAAATGCACTTTGAGTCGTTCATACATTTAATCCCCAATTGNNNNNNNNNNNN -NNNNNNNNNNNGCATATATATGTATATGCTTTTTTATCATTACTGGCCTCTTTAAATTCA -AAAACTTTTCTGATCTCTTTTCCAAACAGATGCGTTTTCAGTATTGGAAGGTTCACAATT -CTATATATAGTGTTAATGTAATGCTGTATTATTTCTCTATATATGTATGTATGCACATGC -AATTCCTACATTATGTTTGAAATGTTGTAATGGGGACGGAAAAGCCGTCACTTTTATCTT -TGGAGGATCGCAAATTACTACGCTCATCTTTTGTTGGAGAACTACCAATTGCTGCAGTGA -CGCTTGAAACTTTTTGCAGGCTTCCTTTTTTTGATAATGAACGGATATCCTCACATAGCT -GACAGATCAAAACTGAGTCCCCCCCAACTTGATTTGAATTCCTTTTTGGGACATCCTTGT -TCCAGTTGTTGTTTAAAAACTCCGTTATTTGTACTAAAATGGCACGAAGTTTGAAAACAG -TGGCCTTATTACGACGATTTGGTTCGGTTTGCTTTATAGGATCCGGCTGTCCTGTGTAGT -CATATAGCTTCAATAACGATTTTGAGAATATTAGCTTTATGAATTTCAATAGATCGATTT -GAATAAGTAAACTGTTGAAATAGGTATCAAAGAAAGAAACAATCTTTTCATAAAAGTTCG -GGTGAAATATGATATTAATTGTAAGGTTTTCAAAACCGGGCAATGAGCATATCTTCGTGA -AAATGCTAATTAGTTTACTGAGGTTAACGTCATCGTCATTCAATGCATAAAACAGGTCAA -CTAATTGATCAATCGGTAATTCAATAGCAGCGTCATTGTTGACCTTTATGAGGAAAACAC -TATGAGACTCTGATGAGCCCACTGTAGGAGCCACATCATCATTTACATTGCGTAACGTAA -AATGCAAGCAGTTCAGTATGATCTCCAGTCCACTTATGGAGGTGTTATTCTTTTTTCTGA -TGAAATTCATAGCTGTAGAAAATAAAGAAGCACTCATTTGGTCCATATCCAAACTCATTT -CAACGCATATAGCAGTGATTTGTTTCCAAATGAAAGCTGCTGTCTTTGCGTCGTCGATAA -AGGGAATGATGGTATCAATATTCCGGATAAAAGCAAAAAAAGCATCGTTGTCAAGCAGAT -CATTTAAAAAAGTGCTGTTTATATGTACTGTAAGGTAACAAAGCTTGGTGAAGTACTTTA -AAACAGATAAATCTTTGATTTGGGCCATGTCAACAAAAAAAGATGTTAGCCAGGTAAAGA -AACCCTCCGGTAATTCAATTAGTAGTCTTGATTTTGAAGATATGGTCAGATGGGGAAAGT -TTGAAATGCTCTTGTGTCGCATTGGAGAAGAGGGACGCGTTGCCATCAAAGAATGAACAG -GGGACCTTGATGGAGACTGTACCGAATTCACTGGTGAGTTCCTCGTGGGTGAGGAGGATA -ACGGTAGAGAGGAAGAAGAAGGAATAGCGGACTTGTGTATTTTATCGTCATTCGTGGTTA -TCATATAGTTTATTGATTTGAAGACTACGTAAGTAATTTGAGGACTGATTAAAATTTTCT -TTTTTAGCTTAGAGTCAATTAAAGAGGGCAAAATTTTCTCAAAAGACCATGGTGCATATG -ACGATAGCTTTAGTAGTATGGATTGGGCTCTTCTTTCATGGATGTTATTCAGAAGGAGTG -ATATATCGAGGTGTTTGAAACACCAGCGACACCAGAAGGCTGTGGATGTTAAATCGTAGA -ACCTATAGACGAGTTCTAAAATATACTTTGGGGTTTTCAGCGATGCAAAATTCGGAGGAT -ACATTATTCCACATTCAATTAAAGTCTGAGGGTAGTCGATGACGAACTCTTTGGCTAAAT -GTTCGAATTTAATGATCAGTGGAATTCCTCCCATAGCGATGAATTTCAGTCGCAACCTAG -AGTGGTTATGCTGGGTATCGTAAACAAAAATGGAGCCAAATGCAGTTATTAATCGTTTAT -CAACAGTTGTGCGCGACAGACACTCGATAATTGTATCAGCGATGTTCTCGAGGGAGCAAA -CACTGAAAAGCACATGCAAGTCCGTCAAAGGCTTAGATGAACTCTTCAATTGGCTCAGCA -ATTGACTTTCAGTGGGGGGCATTAAATCTAGTTCTTGATTGTTTTCTGCCCAGGCAGCGG -GAGCCGCTGCAAGACTGAATTTAGAGGGTGATATATTTAGTTTCTCTTCTTGAAAATCGG -CATCCCAATGATAATCAGCGTCGGTAAAGTCCTCCTTGAACTTGTTGAGCTTGTCGACCT -TCACATTTTCGGTAGAGTTGATCCACACATGCTTGAGTAACTGGTCGGCTGTCGGCCTCT -TGTACATGTTTTTCACAAAGCATTTAGATAAGAAATCCTTTAGTGGCTCAGAGAAAGAGC -TAGGTGGGTAGTAGGTATCATTTTCAACAGCGTAGTAGATATTGGCGTCTGTCAAATTGT -GGTAGGGTGGATTCTTTGTGAGCATTTCAACTACAGTGGCACCTAGAGACCAAATGTCGC -TGAGCGTAGAAGCTCCCCTGTTGCCCAGGATCTCTGGAGCCATCCAATTGAGTGTGCCCG -CTAGCGTTAAGGCGCTGGAGTTCACAATAGTGGAAACGCCAAAATCAGCAAGTTTGACAG -TGTTATCAGCACTCAGCAGGATGTTAGCCGCCTTGATGTCCCTGTGGATGACTCCTTCAC -CGTGTAAATATTTCAGCCCCAATAGTGTCTGTGTCACATAGGTTTTCGATTCATTTTCAC -TTAATCCGGTAGAGCTCCTTGAAATGAGCCTCCTCAAAGAACCATTAGCGCAGTATTCGA -GGAGGATATACAATTCATAGCTTTTTCGTATGAAGCCGTGGTATTTAACAATATTGTTAT -GGTTTAAATTTTTTAACAAGCTAATTTCTGCCATAATGTCATTAAGTTCCTCATCATTTT -CGTACACGACCTCCTTTATTGCCACGACTTGGTCAGTATGTTTATTAATGGCTTTGTAAA -CTACCCCGTAAGAACCCCTCCCAATGACCTGCTTCAAGTGGTATTGCACGGATTTCTCAG -ATGCCCTCTGGATGGGAGTCAAGTTGACTCTATCGGTATCGGCCATACTGTTCATGGTAT -AGTCTTACCAGGAAAATGGGTAGTGCTTATGTGTGTTTTGTCCTTCCTCGAGCCTCCAAG -TAGAAGATATACCTTTTGTGAGGCAGATCTCCCGTATACAAAAATAACAGCAAGAAAAGC -GGAAAGACCATCGCAAGGTGGAAAGGATTATAATGGCACAGCAAAGTCCGCACAGAGCAC -TACAGTATAGCATAGAGTGCTAATGAGTTGATAGGCCCAATTTTGATTATGCCTCTTTTC -CATACACGACGCCAGAGGACATTATTACATTACAGTAGTTCGCCGCTAGATGACAAACGA -CATCCTTACCGATATGAGATGTGCAAAGCTACATAATGGCAACAAGCGTTATGAACAGCC -TTGTCTTTACGACCACAGAAAAGCCGTATTAGAGCTCTTCAGCTGCAAAATTTTCTTCTA -ATATGATGCAAAGCCATCAAAAATCATGCATAGTTATGAAATACCTGATGAAACGCTTCG -AGTTCGTGCTCAAGAAATTACTGAAAGGTTACCGAGAAGAAAAATATCTATGAGACACGA -TAAGGCCCCTTCTGAATCCATTGTCCTGGGCTTGTTCATTCTATTTACCACTTAAAATTG -ATCCTTTCAAAGGAATTTTTTTCTATTTCCAATAGTATATTTGTACAAAAACTACAAAAA -TGGATAAAAAATAACAGTAATTTGTGACTACTGTAAATATCACTGATTTGGATTTTGTAA -TGAGTACTGCTCATGCCCATGCCGATGCAAGTGGATCATAAATTTTACTAAACGATATTC -GATAATGCGCCAAGCCTTTATAAGGAACTCAAAATAACCCATATGGACAGTTTCAGAAGG -CCAAATAACGATCAAGGACATTCACTCATGTTTTTCAAAGGCGAAGAGTGTAAAATTTTC -TTCTATATAGTTCGAATATTTTATCTTATAAATTTCAGTCGTCATTTTCCACATTCGAAC -TCAAATAATGATAAAGAACGCTGCAGTAATGGCTTAAAAAAACATACTTTATAACCCATT -ATCTCTTACGTGTAATTTAAAATTGTTTATAGTACTATTTGGTTATGCTTGTATGCCTCT -ATTATTTACTTGATCTTTTTATGTTTTCTTATGATTGAATTATTTATATTCTAAATTCCT -CACGAATTTATACTGAAGATTTCCTTCCAGGCGAGAATAATAAACACATATTTATGATGA -TAACAAGACGAACGTGTATTAAGCTCCCAGTACGAGGGAAGCAGTAAAAATTATCCCAAG -ATCCATTTAAAATGGATAACTCCACGAGCTACAACAAAATACTAAGGGAATAGGCCGTTA -TTTCCGTAAAGGATGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNACATGCGCCTAACTATTCATACTATTAATTTCATATTATTAAGC -NNNNNNNNNNNNNNNNNNNNNNNNNNNNCGTAACCTCTCATACCTGTACAGGTTTCATTC -GTAAAGCAGGGACTCTAGTTTGCGATAGTGTAGATACCGTCTACGGATAGAGCACTAGAG -ATAGCTGGCTTTAATCTGCTGGAGTACCATGGAACACCAGTGATAACTCTGGTAACTTGG -TCGGCGGGAATACCAGTCAACATGGTGGTGAAATCACCGTAGTTGAAAACAGCTTCTGCA -ATTTCAACTGGATAAGTTTCAGTTGGGTGAGCAGCTTAGAAAGAGTAGTATTCAGCCAAA -TGAGCTCTGATATCGGAAACATAAACACCTAATTCAACCAAATTAACTCTTTCGTCAGAT -TGAGATAATGTAGTGGTTGCTGCGGCGGAGGCACCAGCAGCAATGGCGGCGACACCGGCA -GCGATTGAAGTTAATTTGACCATTGTATTTGTTGTTTTTTGGGTTATTGCTTAGTGATGA -TATAGGCTTAACTGGAAGGAAAAGAACAGAGAAATGTCTCAAACAAAGCTGATCAAGCCG -CTGTATTTATATGAAACTTTGAACAACTACATCTGCACACATGGGCTCTTACTGGTCGCC -CATCTCACACTCATGCCTTCCACATTCCACTTAGCGACTAAGTCATTATTACTATGGGGA -CGGGTTGTTCTTGAACGATGCTATACTTCGTATAGGAAGCCGTTTTTTTATGCCCCATCC -TTTCATATGTTCCATAGCACAAGAATGTTCTCTACAGGAAAAGTGCCTATAGGGCTGCAG -CTGCAGTTTTGGCCAAGAAATAGAACCAAAGCCAAATTTATTTTGGGCCCTCGTTCAAGG -GCCATCTCACCCTTGGCACTAAACGGTTAGTAGGAGGGAAATCGGACTTTTCCCAAATTA -GAAACAATGAAAAATTAAGTGTGAGCTCTTAGAGTCGCATCTGCAGGAATATGCACACAA -AAAGGGGAGCTGTACGTAAATAATCAGACCACACAAACTATTGCCAACCATTTGATACTC -ACGCTAGATATGATGGGGGTTCTTGTTTGGACAACACAAGTCTCAGAGCCAGCGTAGATA -TGCTTGTACATAAATGACGACTGGGGCATCAATTGAATCGGGTTACATTGTGCGAGCTAT -TACATGAAGAGAATATGCCTTTAGGGTAATTTCCAAATGTAGGAAGTCTCGCTAAGTAGG -GCGCCCAAATCTGTATAGCGATGTTGTTGAGGCCATATAGTAAAATGACGTGCCAATTAC -CGAGCTTTTGATGGAGGTAAAATCTAAGATTAATCTTGCGCCTTGAAACCACTAGAAATG -AAAGGAATTGGTGAAAAAATAATCGCGCAATAGATGACATGGAACGACAGAAGTCTTGTA -TTGTGCACGAATCCGCAATATTCAAAGCCGAAGTTCATATACGAATGCGAACTATTTCTT -AGGGTAGCTCTCTGTATGGGCCGCCATAAATTAGTACCAAAAGATAGGTTTTTGAAAAGG -CTACAATGTGCTTTTTTCCTTCTTGCTTTCGAGTCCGGTGAACAGAATATTACGACGTCC -TTGTATTAAGAGCCAGACCTCCTGTTAGCGTCACTATAAGAGTAAGTCTGAAATACGCAA -CAACTACAGTGCAATGAAAAAGTGCTCAACTCAATGACAATAAACAATTTAACCATGGCA -GGTTAAAATATTACTGCGATCAGTAAAAATGGGGATATCACCTTTTGACACATAACATAG -CAATAAAGTAACAGATCATTAGTGATCGGACAACCTGAACCAACGATATAATGTCGAAGC -CACCACTACCTTTAAGATTAGTAGCGCTGCAGGGGGAGACAATGAGAGAAATTTCCCGCC -ACATGAACTGAGTCAGGAGNNNNNNNNNNCTTGCTGGAGAATCATTTAATTTCATGGTTA -AACTCCTCTATAAGCATCCCATTCTCCCATGCCTGAAAACACTTTTGTCCATTCGATCCT -CATGCAGCCCTCGTTAATATGCTAAAATGGCTCATTAAATTGTAGATTGTATCGTTCGAG -AAACGTCAGGCATGATAGATGTTGCAATCACAGGACATTGATTATTTAATCCTGCTCTCA -ACATGTTCAATAAGTTGAAGAGTTGCTGATCTCCCCGTATATCTTATGAACCAAAGCATG -GTGGGTGAATGTTATGGTTATCCTTGTTGAAAAATGATTGATAGACTGGATTGAGCGGAA -AAACATGGGTCAATATGCTGATCTTGACATTTTTCAAAATCCACGGGGGATCAAATCAAC -TTCTTATAGCGTATGACCTCTTTTACATTGTTTAATGATGTTAAGATTGCGATATTATAG -TCAGTTAAGTTACTCAAACGCACAGATTTAATAGAAAACTGCGTCTTCGTTGCCTAGTCG -ATCATAATAAATTCGCAGATTATTTCGAATTTGATCTCCTTCGAAATCAAGTTTATTCTC -TTCACAACAAAAAATGCTTTTAACTTGAACAAAACTCGTAAACTATTTCCCCACTGTTGC -TTCGGGACGACCCAGTTATTCAATATCTTGCAATGCTAANNNNNNNNGGGAGAGCAGTTG -CAAATATTGCAAACACATCTAAAGCGTACCCACAATTTATGACTTCCTGGAGCCCAGAAC -AGCCCNNNNNNNNNNNGATGCGTTCTTTTTATACCAATATATTAGATACGTAAACTCTAC -TCATATTGCAGGTATGCCCACATCTGGATATTGACTTTGCCAATATTCCCGCACAGCATG -GGCTTGAATTTCGGCTGCTTTAAAGAGGCACCACTTTACGGTTGGTTCAACATCAGAATT -TTGAGTTGCAGCCTGATTTTCTGGAACACTGATGAACGGCTGTGTATTCGCTGTATCCCA -CTGTACATCAGGATATTTTCCCTTTATGAGATCCTTGAAAAATTCATAGCACTGGTGTTC -ACAAAAAAAGTGGTATGGTGTTTTCCATAAGCCAGCCTTGAACAAATATTGATTCATGTT -ATACGTTATGGTTTTCCATTCTTTCCCAGCTATCGATGGTCTATGAGTTATTACCTCTAG -TAGAAGTTTTGTACGGAATGTTTCATTACTTATTGGTCTACTGAATGACCATATCTGAAG -GACTACCATAGAGCCACCTAAACATATCCGGATCACCATGGCAGGGGAGAGAACACCAGA -AAACCAAATGTTTGTTAAAGTCGCCAAAATCGTCAAGACAAAAAGGAGGAAATTGATCAT -TATATACTTGGCGCGTACAATTTCGTAAAGCAAATAACTCTGGTATGATGCAAACTCATC -CTCTGGAAGGACGATATCAGCTGAGATTAAAGGACTTTCAGGGTTGTCAGGAGATCCTTC -CCTCAATGGGATTGCTTTAGGATCGTCCGTGACATGAGTGNNNNNNNNAAATAAGATTGC -ATGTTTAACAAACGATTTAACTTGCTTTTGCTTACAAGTCAAGTAAACCTTATCCTGATA -GCTTAGGAAAAATAGACTTGAATGTGTCGAACATTTCAAACCTCAATTGGTATTTTCCTT -TTTTTCAACTGTACGTACATAGCTTTTCGCTTTCTTTAGCGCCCCCAGATGAAAGTATAT -ATCGTAACAAGGATGGGAACATGAAAGGTACTGAAAAAACATCTGTATTTATTAAAAGTA -AATCAAAAGCAGACTGGGAAGTTCTGTCGTAGGGANNNNNNNNNNAATGTTATGTGTGTA -GGATTATTCTATTTCCTTGAATTTCTCGATCGAGATTTTTCGTACCTGTGTATTTTTGGA -TATAAGAGTGTTTCTGATCTATTGAGTGAGCAGGTCTCCAGCGGAATATAGAGTAGATTG -AATATGGAAGAGGACTACATTAAGGCTTATTGTTAGTTAGTTACTGTTAGGACGCTTCGG -CGAGCTGATGTCTGACTTCTCGTTGTATCAAAGAGCTCCCAATACGCCAGCGCATTTAAA -CTATGATCACGGAATGCTGGATTAGTAGTATAGCAAAAGTAACACTTGTCCACCGCAGAC -TCCATCACTTAGTCAACACCTTGGGTGTTTTACCGCTGATAATGGCCGTAAAATCGCCAG -ATATATATCATCATTGTTCTTCGCGAATAATACGTAACACAGTCTCTTTTCGAAATTTAG -ATGAGGACCATAGGCATGACTTATTTACTGAGATGTCCCTGCGTTAAAACTTTTACTGGC -CGATTGCTAACTTTATATTTGTTAATAAAACTATTCACGCCTGTGTCCTAATTGTTGGAT -AATACCTAAACAATAACGATGTTGTATAGCTAAGAGGACGACCAGACAAAAAGTTATAAA -CTTTACCCTCGTTGAAAATGGGGCAGCCACCTATGAATCACTTCCCATTACAATGCCGAA -TAGCAAAATATGTAGTAGAACACGTACACGCATGATAATTACTTCCATGCTGTACTTATT -TTTTGGGTGTCTCTTCAGAAAGAATGCTTTATATAACCATGTGTTTGAATTAGCGATCAG -CTAATAACAAGTCAGTGTCCAAATAGTTAAAACATTGTGACCCAAATATCACAAATAAGT -GGTTGTTTGGCCGAGCGGTCTAAGGCGCCTGATTCAAGAAATATCTTGACCGCAGTGAAC -TGTGGGAATACTCAGGTATCGTAAGATGCAAGAGTTCGAATCTCTTAGCAACCATTATTT -TTTCTTTTTCCTCCTATACTTCATAATCTACGTAGGAATGAAAGTACCAACATTATACCA -ATGAGGGTGTGTTTCGTGGATGCATATACTCTGAAGATAAAAACAAACTCAAGTCCGCTT -CCTACGGTTTGAGTATTTCTTACCACTACATAATAAAGAATATTACGTTAACTGTAAAAT -CAAGTAGACTTGGAAAATACAACGAGAACACTTTCCTGATTCTGCATCAGCGTTTTCTTA -TCACCAGCTGTACTTCTACATTAGCTAACTCTCCTTTCTATAAAGGGCGTCTTTCACTTC -ACTTGTGCCATGTTACAAAGCTCCAAACGCACTTCTAACTGAGTACAATGCACGATCCCA -CTGACAGACAAAACAGCTTCACAGAATTTGATCATGCCATCGTAAAAACCACGTAGTAAG -GAATAAAAAATCCCGAAGTCGATCATACTATGTAGAGATGTACATGAATAGTCTAGGAAT -CTGGTCTTCCAGCATGTTGCTTTGGTCTGCTTCAAGCGCTATGGAAGCGCTCGCCATGAG -ATATGCTGTTTCAAGGCAAAATAGCAAAGCTCTTTGTAAAGAAATACAATTCAGAGAAGA -AGCTACAGCATTTTGTTTCTGGATGATCCCTGCAGGTTCATACTACTAAGTAAATCTTGA -ACAGTTCAAATTTCAACAATTCAGAAACCGCTCTTTTTATATATACTCTACCAAACGAGA -TGAAACAGCATTTTTTTACTCTTATAAGGTACCAATATTTTGACGTATGCTTTCTTTAAC -GTTCACGATCGGGCTGGGCCATTAAACTTACCTTAGATATTATTTGGAACAGCACCGCAA -GTGCTGATGTCCCAGAAATGGGCGCCGGTTCAATTAGGTCGTGAAGTCAGACATATGGAG -ACTCTCGGACTGAAAGCACTAAGGGATGATAGCTGGCATGCCAATTCCATTTTAAATTTA -CACATCAAGTTACAGGGTTTGGGAAAATCACGTTCAAAGCCTGAAAATTTGAGGTTGTTC -ACGGAAATCATTTGGTTATGTCTGTCGGCCTGCTATTTAGAGACATTTTTTATTGCAACA -ACCTACTCTATGCACTTACACGGAATCGCAGAATAACGCGCGCACAACACAATTGGGAAA -CGATAGGATTTTGAATAGTGTATTGCTTTGTACCGATTTAAATAATTCTTTCTCGTGTTG -AATCCGAGTTGAAGATGAGTATGCTTTGAAGAGGTGAAATATCATCAGTNNNNNNNNNTA -ACGACAACTGCAGGACTCGAACCTGCGCGGGCAAAGCCCAAAAGATTTCTAATCTTTCGC -CTTAACCACTCGGCCAAGTTGCCAAAATTGTATGTTATTNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNTTATTTTCAGTGATAAAATATGTAAACCAATTATAAGAAAA -AGGATTGCGTTGCATCACAACTGTAAACCATTAATTAAAAAGAGCAATTGCTATTTAGAT -TTGTTGCTGAGAATTGGCTAAAAAATCTGATAATTGTAGGACTTCTATTATTGCTAGGGG -CAATGTGTTGGAATGCAATTCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAATTCTCAACATCC -GACTGCCATGCAATGTGCTTTTCTGGATCTCACTCATGATCATAATGGCCCTGTAAAAGG -CTCGCACTATTATTATTATATCTTCACTATATATTATTTCGGAGGCTGTACCTATCAGTG -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGAATATGAAAGGGGTTCTGAATTGCTAAA -ATATTTCGTCAAAGCTCAATTAGTATCATGATCAAGTCGTAATTCGAATCAGCATAACAA -CCTCCAAAACCATATAATAACCTTACACAAGACAAGATATCAATTCAACATGCAAACCCC -TTCAGAAAATACCGACGTCAAGTTGGATACTCTCGACGAACCCAGTGCACATTTAATCGA -GGAAAATGTGGCTCTTCCAGAGGATACATTCAATTCGTACTGGAGTTATATACTTAATGA -AATCGCTCGTTGTAAACCGCTAATGATTATGTTCCTAATACCTGTGTGTTTGGTTTTATT -GATTACGTTTTTTCATGATATCAAAGGTATCCTTGTGTTTTTAGTGATTTCTCTTATCCT -CTCTATTATCATTTTATTGATCGGTATAACTGCCTTCGTGTCTGAGACCTTGAATAAGGG -TTTCATAATTAAGCTTTTAGTAGAAGTCATTACACGTAAACCAGCAGTAGGGGGGAAGGA -ATGGAGAATAATCGCATATAATATGAACCAGTATCTGTTTGACCATGGGATATGGCATAC -TCCGTATTACTTTTTTTGTGAACATAGGTGCCATAAATTTTTCAAAAGCCTTATCAAACA -GACAAGGTCGAATGCACATTTGAGTTCACCAACGAACGGTGCAGAGAATACGCAGTCAAA -CACACCAGCAAAAGAGGTTTCAAATGAGATGGTAAAACCTTATATCTTTAGTTCTGATCC -AGTTTTAGAAGCTTACCTTATTAAAGCTGCGGAAATTCACAAAGAAGCTGAATTTGAGTA -TTGGAGAAAGCAATACCCAGAGGTTGATTTGCCTTAGGGCCGAATTTTTGGTATTTATCT -AGTATATTCTAATATAAAATGTACGAGCATCATTAACTTCAAGAACATTACGAAGCCCGC -AATTAAGTGTCAGTCCATCTGGGTGTAAAAGTTATGTACGCTCGAAACAAATTTTATGTA -GTTTACTTTAGATGCAAATGCTATTATATATTTTGCTTTATGATCCTCGGCTTGATGCTC -GCCAACGTGAGATAGCTGGTCATCACAATAGATCAGCCGGGACGCTTTTCGATCACATCG -AATCCCTTCGGGACGTTGCAACAATACGTGAAAAATGCCTCAAAAATAATAAATACAATG -GTGAACAACGTTAAAAAAGCATAAAACAGCTGGCTATTTTGATCAGGATAACATCTATAA -GTGCCATATTAAGGCAAGATATCAATTGACCATGCAAACACCTTCAGAAAATACCGACGT -AAAGATGGATACTCTCGACGAACCCAGTGCACATTTAATCGAAGAGAATGTAGCTCTTCC -CGAAGACACATTCAGTTCACATCTGAGTTATGTACTTTATGAAATTGCTCATTGTAAACC -GATCATGTTTATGATCATCATAATCGTGAGTTTGATCTCATTGATTGTGCTTTTTCATGA -TAACGACGGGTGCACTGTGATCTTAGTGATGTCCCTTATAGTAGCCTCCATGGCTTTAAT -GGTGGTTGCAGCATTCACATTCGGGAAAGCGATCACTGAACAGGAGTTCATGATAAAGCT -TTTAGTGGAGGTGATCGCACGCAAGCCTGCGGGGAAGGAATGGGGTACTGTCGCATATAA -TATGAACCAATATCTATTCATGAAGAGACTATGGTATACCCCGTACTATTTCTATAGCGG -CAAGAAGTGCCATGAGTTCTTCACCACTCTTATCAAGGAAGTGAATTCTGGTTCGCACTC -GGATTCCTCATCGAATAGTGCCGAGGATACACAATCACCTGTCTCAGCAGGGAAGACTTC -AAATGGTCTAAACAACTTTTATAGTATTAGATCAGACCCTATTTTGATGGCATATGTTTT -GAAGGCAACACAAATAGAAAAGGAGGCTCAAAGTGAATACTGGAGAAAGCAATATCCTGA -CGCTGATTTACCTTGAAGCGGAAGCATTTTATTCACCAAGTATACTTACTTTTCTTTAAA -ACGAGAACAAGAATCGAATTCAAGAACATCTCGAAGCCAGAATTGAGCATCATATATTCG -AGCTGTACAAACATCATGGCCTACAACTATCGTATTTGTAAGTTTTTTTAGAGGTTTTCA -TATTTGTTTAATAAGGGTTCTGTCAGTTTTTGTCACATTCTATTGTTGCGCTTCGCATAA -TGCAGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGGATCTCAAAAAGGGTTTGGT -GTTGTAGTTATAAGAATAACTAGTGAATAAAAAAGCTGTTGTTTGGTCCGTATTACATTC -GTCAAAAATTTAGTACTCAAATCGTGTATGCAATCGCAACCACAAAATAAAAATATTAGA -CTGGATGTGTTGAGTGGAGATGGTGCCAATTTAGTTGAGGGAAATGTGGTCCTTCCCAAA -GACATGTTCAATTCGTACTTAAGTTATTCACTTTACGTGTTACGAGGGGGCTCATTGTAA -GCCGATAATGATTATGTTCCTGGCATCTGTAATTTTGATTTCACTGACTAATTTCCGAGT -ATACCATCTCATGTCCCTTCTATCCTCTTTTTTCATCTCCGGGACAGACCGACAATAAAG -CATCTAATATTAGGCTTTCGTTAGAGGTAAGCACACGCCAGCGTTCGGTGAAAGGGGAAT -GAAACATTATCACGTACAAGATGAATAAATATCTATTTGACCATAAAATATGGAGTACTC -CTTACTACTTTTATTGCGAAGAAGATTGCCACCGTCTTTTTCTAAGTTTTATTGAGGGAA -GAACTTTCGAGAAGCCAACAAGCAACGCTGAGGAAAATGTACAGGAGACTGAAGCTGGCG -AATCTTTCACATTAAATCCCGGAGAAGATTTTCAAAATTGCTTTCCAAGACAGCGGATAT -TGTAGAACAATCTCAAGTGAAGTATTGGCAAGATATTGGTGCAATTATTTGAAAGGAAGG -AGAAATATTCTGACAGTACCTTGCTAGCAAAGGGATTTACCAATCCACTGACGCTAAAAT -GGGGTAGTAAATTAGATAAATTGCATTCTAACGTGACTTTATATAGTGGGAAACAGATAT -GTAGCACACAAAACGGCATGATTATGCTTAATTGATTCCTATTTTTTAACGTAAATACTC -TCCCAGAACGATCAGAAAACTTAACCCGCAACCATCTTTGCTGTGCTAACAACTTATGTC -GCCTCAATACCATTTTTATTTTGTATCATTCCGGAACTTAGTATTGAATGAAAAATGCCT -CCGAAGTAAAAAGCAGGTGATGAAAAGTTTCAATTGGTATAAGACAGATCGCTATTTTGA -TCCGCATAACATCCTTCAACACCATAGCAGAGCTATAGAGAAGACAAGATATAAACTGGG -CATGCAAACATCTTCAGAAAGTACCGACGCCAAGTCGGATTTTCTCGACGAACCCAGTGC -ATATTTAATTGAGAAAAATGTGGCTCTTCCCAAGGACATATTCGGTTCGTACTTAAGTTA -TTGGATATATGAAGTTACTCGTCATAAAGCGGCAGTAATTTTGCTCGTACTTATTGTGAC -TTCAATTTTATTATTAGTGTTTTTTTATAATACGGAATTTTGCGTTGCCTTTGAGATACT -ATTGTTTTCCTTTTGCTTTCCAGGAACATGCATGGTTGTAATTGCATTTAGTGAACCGAT -CGGTGATCGGGAATTTAAAGTTAAGCTTCTGATGGAAATTATCACACGTAAACCGGCGGT -AAAGGGGAAAGAATGGAGGACAATTACATACAAGATGAACCAGTATTTATTTGATCATGG -GCTATGGGATACTCCCTACTACTTTTACCGTGATGAAGATTGCCACCGTTATTTTCTAAG -TCTTATTAAGGGAAGAACTTTCAAGAAGCAAAAGGAATCGTCAGCCAGCAATGTTAAAGA -CGCACAATCAAATGACGAAACCGCTGGCACACCAAACGAAGCCGCTGAGTCTTCTAGTTT -TAGTGCCGGACCGAACTTTATAAAGCTCCTCACCAAGGCAGCCGAAATCGAACAACAATT -TCAAAAGGAATATTGGCGACAAGAGTATCCTGGTGTCGATGAGTTTTTTTAGACAGAAGA -CGGGAGACACTAGCACACAACTTTACCAGGCAAGGTATTTGACGCTAGCATGTGTCCAAT -TCAGTGTCATTTATGATTTTTTGTAGTAGGATATAAATATATACAGCGCTCCAAATAGTG -CGGTTGCCCCAAAAACACCACGGAACCTCATCTGTTCTCGTACTTTGTTGTGACAAAGTA -GCTCACTGCCTTATTATCACATTTTCATTATGCAACGCTTCGGAAAATACGATGTTGAAA -ATGCCTCTAGAGATGAAAAACAATCGTAAAAGGGTCCTGCGTAATTGAAACATTTGATCA -GTATGCAGTGGCACAGAAACAACCAGGAATACTATAGTCATAGGCAATACAAGGTATATA -TTGGCTATGCAGACCCCTCCAGAAAGTACCGACGTCAAGTTAGATACACTTAACGAACCT -AGTGCACATTTAATTGAGAAAAATGTGGCTCTTCCTAAGGACATATTCCGTTCGTACTTG -AGTTATTGGATCTATGAAATCGCTCGCTATACACCAGTCATGATTTTGTCCCTGGTAATA -GGGGTTTTGGTTTTATTAATTATATTTTTTAATGACAACGAAGCTTGTGTTTTCAATTCT -GCAATATTTGCTTTTACTTCTCTTGTAGGTTTGTTAATAATATTAAGTGATGGTAATCCA -AAGCTAGTCAGTCGTCGAAATTTTAGGACCGAGCTTTTAGTGGATGTCATCACACGTAAA -CCGGCGGTAGAAGGGAAAGAATGGAGGATCATCACATACAACATGAACCAATATTTGTTT -AATCATGGGCAATGGCATACTCCGTATTACTTTTACAGCGATGAGGATTGCTACCGTTAT -TTTCTACGCCTTGTTGAGGGAGTAACCCCCAAGAAGCAAACAGCCACGTCAATTGGCAAT -TCTCCGGTCACCGCTAAGCCTGAAGATGCCATCGAGTCAGCTTCTCCTAGTTCCAGACTG -AATTATCAAAACTTTTTGCTCAAGGCAGCGGAGATCGAACGACAAGCTCAGGAAAATTAC -TGGCGAAGGCGGCATCCCAATATCGATGCGCTTCTTAAAAAGACGGAATAGCTTAGAGAC -ACTACCATACGTAAAGCGAACATAAACTAGAGTATGATATATAATCAGCACTAACTGGCC -GGAAAACGGCCGAAGGAAGCCTCGAAAAGTCGATTCGTGTTGGACCCATTTGCTGAACAA -AGTGGTTCATTGCCTACCTATTATGGTAGTAGTCGTGATAATCGTGTGGTTGGTTTTGTC -AACGGTGCATTTGCATTTTCATGACAATAAACCTTGCGTTTTCGTTCTCGGGATATTACT -TTCCCTCCACTTCTTTCGCCTCAATAGCTCCTATAAGCATTCTCAGGGCGTATGTCGGTG -ATCGAGATTTCCAAGCAAGCTTTTAGTGGAAATCATCGCGCGCAAGCCAGCGGTAAAGGG -AAAAGAACGGAGGACGATTACATACAAGATGAACGNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNAGTACAGTAGCATTAAATATTATTAAGTTTAATGATTAAAAATTGGTTAATTG -TCAAGAAAATCTAAGGTATTAATAAATAAATAATACTATGACAACTTGCAGCGAAAGCAT -CAGCCCCAATGAAAATTAATCAGAATTGAATCTGAGCGTATTTATTTGATAACGGTTTAC -GTAACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGTAACACCCCACCCCGTATT -ACTTTTACCGTGATGAAGATTGGCATCGTTACTTTCTAAACGTAGGACGTGCGGAATGAC -AAAACCATCAGCAGTGTCACGATCTCTCCAGTCACAATGGCAATCATGAGTGCATAGTCC -AAAGTAAAGGGGCAAGGAAAAGCATGATTGAAAGGACTCCCCATCTGGACTCTATATGTC -ATCAGCGGCTNNNNNNNNGCATATAGCACAANNNNNNNNNNNNNNNNNNNNCTAGAGTCA -TCGGCCCGGCGGTCCGCGGTCATCCCCGCGGACTTTCCGTCCGCCCGGCGGGCTGTATCA -GCGTCAACTGGAACGCGCATATATATACAAGACACACATAACATAGAAGCACACCNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNCCGCCCACCCCTCCTTTCCGTATACAATGCCAAA -CTTAAAGAGACTACCCATCCCGCCACTGCAGGACACGCTCAACCGCTACCTGGCACGCGT -GGAACCCCTGCAGGACGAGCGCCAAAACCGCCGTACGCGCCGCACTGTGCTCTCCGCAGA -AAACCTGGACGCATTGAACACGCTGCACGAGCGGCTGCTAGAATACGACGCACGGCTCGC -GGAAAGCAACCCAGAGTCCTCATACATCGAGCAGTTCTGGTATGACGCGTACTTGCTATA -TGATGCAACTGTCGTTCTCAACGTCAACCCGTACTTCCAACTGCAGGACGACCCAACCAT -CAAAGACACACCAGAGACGGCGGCACAGGGCCCCTATGGCGCACACACGGTGCAGGTTCG -TCGTGCCGCACGACTCACCACCTCTATTCTCAAGTTCATCCGCCAGATTCGCCACGGCAC -ACTCCGCACAGACACTGTGCGCGGCAAAACGCCGCTGTCGATGGACCAGTATGAGCGGCT -ATTCGGCTCCAGTAGAATCCCTCCGGGTCCCGGCGAGCCCTCTTGCCACTTGCAAACAGA -CGCCACGTCGCATCACGTGGTGGCGATGTATCGTGGCCAGTTCTACTGGTTCGACGTGCT -GGACACACGCAACGAGCCCATCTTCGCCACCCCAGAACAACTGGAGTGGAACCTCTACTC -GATCATCATGGACGCGGAATCCGCCGGAAGCGGATCCGCGCCCTTTGGCGTGTTCACCAC -AGAGTCGCGCCGGGTGTGGTCCAACATCAGGGACTATCTGTTCCATGCGGACGACTGCAC -CAACTGGCGCAATCTCAAGCTGATCGACTCCGCGCTGTTCGTGGTCTGTCTCGACGACGT -GGCGTTTGCCGCCGATCAGCAGGACGAGCTCACGCGTTCGATGCTGTGCGGGACTTCTAC -CATCAATCTCGACCCGCACCAACACCAGCCGCCATTGAACGTGCAGACAGGCACCTGTCT -CAACCGCTGGTACGACAAGTTACAACTGATCGTGACCAAGAACGGTAAGGCGGGCATCAA -CTTCGAACACACCGGTGTGGACGGCCACACTGTGCTGCGGCTCGCCACAGACATCTACAC -AGACTCGATCCTGAGCTTCGCACGCGGTGTCACCAAGAACGTCGTCGACATCTTTAGCGA -CGACGATGGAAAACCATCGTCGTCGTCGTTGGCCTCGGCGGCTCACTCCGCCAACTTGAT -CACCATCCCTCGTAAACTGGAATGGCGCACTGACAATTTCCTGCAATCGTCGCTGCACTT -TGCCGAGACGCGCATCTCGGACTTGATCTCGCAATACGAGTTTGTTAATCTTGACTTCTC -CAACTACGGCGCGTCCCATATCAAGACAGTGTTCAAGTGCTCGCCAGACGCCTTCGTGCA -GCAGGTGTTCCAGGTCGCATACTTCGCGTTGTACGGTCGCTTCGAGACCGTGTACGAGCC -TGCCATGACCAAGGCGTTCCAAAACGGCCGCACAGAGGCCATCCGCTCCGTCACGGGCCA -ATCGAAGCTCTTTGTCAAGTCACTACTGGACCAGGATGCCTCGGACGCCACCAAAATTCA -GCTCTTGCACGACGCCTGTACGGCGCACTCGCAAATCACAAGGGAATGCTCCCAGGGGCT -CGGCCAGGACCGTCACTTGTATGCGCTCTACTGCCTCTGGAACCAATGGTACAAGGACAA -GTTGGAGCTCCCACCCATCTTCCGCGACAAGTCCTGGACTACCATGCAGAACAACGTCTT -GAGCACCTCCAACTGCGGTAACCCCTGCCTCAAGAGCTTCGGGTTCGGGCCTGTCACCGC -CAACGGCTTCGGCATCGGCTACATCATCAGAGACCACTCCGTCTCTGTGGTGGTGTCCTC -AAGGCATCGCCAGACTGCTCGGTTTGCGTCGCTCATGGAAAAGTCGCTGCTGGAGATCGA -CCGCATCTTCAAACGGCAGCAAGCTCGCGCAGCAAAACCCGCTGCCAGGACCACTGCTAG -CGCCAACACCAAATCAGAAGACATGAAATACCTGTTGTCCGGCTACGATTACTTCGACGT -GAGCGTGTCCGGTTGAGTTTATGCTGAGTTTTTGCGCATCAATATTATTTTNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNAGAGGAAAACGCTTTGG -AAGTGACTGGCGCCGCCGCTGGCTACTATAATAGCAGCGACTGTAATTTAATCTCATCCC -GTCGTTTGGATTACCTCTTTTACTCGCCGAGCGAACGTGCACCNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTGGATAAATAGAAGCACTCAAACTAA -ATTAAACTGCCNNNNNNNNNNNNNNNNNNNNGGGAAAAGTTTAAACATCAAAGTACACCT -TTCACCCCTCCACACACCATGGAACAACCTGATCTATCGTCTGTGGCCATCAGTAAGCCG -CTGCTGAAGTTGAAACTTCTCGACGCCCTTCGCCAGGGAAGTTTCCCCAACCTACAAGAT -CTCCTAAAGAAACAATTCCAGCCGCTAGACGACCCAAACGTCCAACAAGTGCTCCATCTC -ATGCTCCACTATGCCGTGCAAGTCGCCCCCATGGCTGTCATAAAGGAAATCGTCCATCAT -TGGGTCTCAACTACAAACACCACTTTTCTAAACATCCATCTTGATCTAAACGAACGGGAC -TCCAACGGCAACACCCCATTGCACATCGCCGCCTACCAGTCCCGCGGTGATATCGTAGCC -TTCCTCCTGGACCAACCAACCATCAACGACTGCGTGCTCAACAACTCCCACTTGCAGGCC -ATCGAAATGTGCAAGAACCTAAACATCGCGCAGATGATGCAGGTGAAACGCTCCACATAC -GTTGCAGAGACCGCCCAGGAATTCAGAACAGCTTTTAACAACAGGGACTTCGGCCACCTA -GAATCTATCCTCTCCAGCCCTCGAAACGCAGAACTGCTCGACATCAACGGTATGGACCCG -GAGACTGGCGATACCGTTCTGCACGAATTCGTCAAGAAAAGAGACGTCATCATGTGCCGT -TGGTTGCTTGAACACGGTGCTGACCCCTTCAAGAGAGACCGCAAGGGCAAACTGCCCATC -GAGCTCGTTAGGAAAGTCAATGAAAACGACACCGCCACCAACACCAAGATCGCCATCGAC -ATCGAACTGAAAAAACTATTGGAAAGGGCCACCAGGGAGCAAAGTGTCATCGACGTCACA -AACAACAACTTGCACGAGGCCCCCACTTACAAAGGCTACCTGAAAAAATGGACCAACTTC -GCTCAAGGCTACAAATTGCGTTGGTTCATCCTTAGTAGCGATGGGAAACTATCCTACTAC -ATCGATCAGGCCGACACTAAGAATGCCTGCAGGGGCTCCCTAAACATGTCTTCGTGCTCT -CTGCATTTGGATTCGTCTGAAAAGTTGAAATTCGAAATTATCGGCGGTAACAACGGTGTT -ATCAGGTGGCATTTAAAGGGGAACCACCCCATCGAGACAAATAGATGGGTTTGGGCCATC -CAGGGCGCCATAAGATACGCAAAGGACAGAGAAATTTTGCTGCACAATGGCCCCTATTCG -CCTTCTCTGGCCTTAAGCCATGGCTTGTCATCCAAAGTGTCCAATAAAGAAAACTTGCAT -GCAACTTCAAAACGGTTGACCAAGAGCCCGCATCTGTCCAAATCCACACTGACACAAAAC -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNAAGT -AGACCCCTCATAGAACCATTACCGTTGATTTCATCCAGAAGCCAAAGCTTAAGCGAAATC -ACTCCCGGTCCACATTCTAGGAAGTCTACAGTCTCGTCTACAAGGGCAGCCGATATACCA -TCAGATGATGAGGGTTACTCTGAGGACGATTCTGATGACGACGGTAACTCCTCTTACACA -ATGGAAAACGGCGGTGAAAACGATGGCGACGAAGATCTAAATGCCATTTATGGTCCCTAT -ATTCAAAAACTACACATGCTACAAAGATCCATTTCCATCGAGTTGGCATCTTTGAACGAA -TTGCTGCAAGATAAACAACAACACGATGAGTACTGGAACACCGTCAACACTTCTATTGAA -ACCGTCAGCGAATTTTTCGACAAATTAAATCGGTTGACCTCTCAAAGGGAAAAAAGAATG -ATTGCCCAAATGACCAAGCAACGGGATGTTAACAATGTTTGGATTCAATCGGTAAAAGAT -CTGGAAATGGAACTGGTTGATAAAGACGAAAAATTGGTTGCCTTGGATAAAGAACGNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNTTGAACAATCAACCACAGGTTGAAACTGAGGCT -AATGAAGAATCCGATGATGCAAATTCAATGATAAAAGGATCCCAAGAATCAACAAATACC -CTTGAGGAAATCGTAAAATTTATCGAAGCAACAAAGGAAAGTGATGAGGATTCTGACGCC -GACGAATTTTTCGACGCAGAAGAAGCTGCTTCCGACAAAAAAGCCAATGATTCGGAAGAC -TTAACCACAAACAAGGAGACTCCAGCTAATGCGAAACCACAAGAAGAAGCTCCTGAAGAC -GAGAGCCTTATTGTGATCAGTTCTCCACAGGTGGAAAAGAAGAACCAACTATTAAAAGAG -GGATCATTCGTCGGATATGAAGACCCAGTGAGAACCAAACTGGCTTTAGACGAAGATAAT -CGTCCCAAGATTGGTCTCTGGTCTGTTTTAAAGTCTATGGTCGGTCAAGACTTAACCAAA -CTAACTCTACCGGTATCGTTCAATGAGCCAACATCCTTACTACAGAGAGTATCTGAAGAT -ATTGAGTATTCTCATATTCTTGACCAAGCTGCCACTTTTGAAGACTCCTCTTTAAGAATG -CTATATGTAGCTGCCTTTACTGCATCAATGTACGCATCTACCACTAACAGAGTGTCTAAA -CCATTCAACCCCTTACTCGGTGAAACTTTTGAATATGCCAGAACTGATGGTCAGTACCGA -TTCTTCACCGAACAAGTCTCTCACCACCCACCTATCTCTGCTACTTGGACAGAATCGCCC -AAATGGGATTTTTACGGTGAATGTAATGTTGATTCGTCATTCAATGGGCGCACGTTCGCC -GTGCAACATTTAGGATTATGGTACATTACTATCCGGCCTGATCATAATATTAGTGTTCCC -GAGGAAACTTATTCCTGGAAAAAACCAAATAACACTGTTATCGGTATTTTAATGGGGAAA -CCACAAGTAGACAACAGTGGGGACGTCAAAGTCACAAACCATACCACAGGCGACTATTGT -ATGCTGCATTACAAAGCCCATGGCTGGACCTCAGCCGGTGCATATGAAGTCAGAGGTGAA -GTATTCAACAAGGACGATAAAAAATTATGGGTTCTTGGTGGGCATTGGAATGATTCCATT -TACGGGAAAAAAGTAACTGCTAGAGGCGGAGAACTGACATTAGACAGAATAAAAACGGCA -AATTCTGCCACGGGAGGACCAAAACTAGATGGGTCTAAGTTTCTGATATGGAAAGCAAAT -GAAAGGCCTTCAGTGCCATTTAATTTAACGTCGTTTGCATTGACTTTGAATGCTTTGCCA -CCCCACTTGATACCATATTTAGCACCCACAGATAGTCGTTTAAGGCCCGATCAAAGGGCT -ATGGAAAATGGTGAATACGATAAAGCTGCCGCGGAAAAGCATCGTGTTNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTACAGACCTAAGTGGTTTGTC -CAGGAGGAGCACCCCGTTACCAAAAGTCTATACTGGAAATTTAATGGAGAGTATTGGAAC -AAAAGAAAAAATCATGACTTTAAAGATTGTGCTGATATTTTCTAAGCTGTGCAATGTAGT -CACAATAACACTCGTTCATTTGTATCCATTGCGAATGCCGGTACATCGGAAAACAGGATA -GGACCTATTTAATTATATAGTATGAAGTATTCATAACTTCTTGAGGCATCAATACATCAT -ATTCCATGAGCTGCGTGGCATTCATACTCATTGATTTAAAGGTTTTTTATTTTCATGGAA -AAGATTAACCGGGCTGAACGAAATATATTAAAGATGCTAAAACTTATGCTTTCATTGACT -TTCAATAGTGTCCACTAACCNNNNNNNNNNNCTACTCTAACAAGGGATCCCCATGGATTC -AAAGCCGATACCAAACAGATATTACTCTGCATAGAATTCAAAATATTATCCATATAAAGA -TGGGAAAGAATTCCAAAAGGAAAATTCTGCTCTAGAAGGTCACAAAACTAGTAAGAAGTT -GACCCCCCTGCCATTAAAAAACGTTTTTAACAGCTCTAGCAATATTCTAATTTCGAAAGT -GCTCTCAAAAGAATTTATTCATTTGCGAAAAAAAGAATATCTCAAAATTTTCTCGATCAC -GTACAACATCGTAGTATTTAAAGGATTATTAAGTCAACGAATAATTTCCACAAGAAAGGT -ACCTCTAGTTTTGGTGATGAAGCAAGACAATAACTGGCAAGGGCTCTCACTAAATATCAA -CCCCTTTCAAATAAAAAAAGGATCATGGCTGGCAGCGCCCACAACAATTAAACTCTGTTA -CTATCAAAAAACATTGAGCCCAAGAATGGAATAAAATTTTCACTACACCTCGGACATGGA -TTTGTACATGTCCTATTATCCTGTAATTTTGACATATACTGATATGGACCTCTTGTTTCG -TATAAATCGCTATTTATTTCCCCAGATAACTAAAGAAAATCCTTCAACCCAGCGTTCTAT -ATTACTATATTCTCAACCCGCCGTTTTCCTGCTGTGCGATAATTCTCATTCAATACTACC -ATTTCAAACCTAGAAAAGGGTGTCTTTATTAAAACTGTAAGAAAATTTTATCATGAACTC -TGATGAAAAGTCTTCGGAAGATCAACTTTTTGATTTTTCAAAAATGAAAGAAACTGTTGT -CTCCATTTATGGCCTCATATCTGAAGGAAATTCGTCTGCTATTAGTCATACCACTATCTT -CTTCTTGAAGCTGCATTTCAAGGTTGATTAGGAAGCATCTAACAATCATTCGATAGGGAA -AACAGAAAGGCCGTTACAGTTTTTTAAAAATATCAATATCAAGAGAAAGAACTAGGGATA -TTGCAAAATCAAAACTTCTGATATTTGGTTTTACGTGAAAATTACCAACACTTAAACGTT -AAAATTTCAAACTATCTACTGAAATATAAATTTTCAGTCAAAGAGATGAAACGATTATTT -TCTTGAGTAATTCGTTGTCACAATTTAACAGAAAATTACTGTTTTTTTCAAGTAGTTCAC -AAAGATACTCAAACTAAGATCATGGAGACGTCGGCAAGCAATTGATTGTTAGTGATTATC -AAAACTCATTAGCTTCGGTAAAACTACATAGATTGAAAATCAGTAGTAACATACAACATG -GTTTCCATGAGATTACAAACCGGCCAACCTAATGCTTTCAAAAATTCTTTGCTTACTGAT -TCACGGTGGCCAAGAAGCATATAAATCTGTACTTTGCAGTAAAAAACAGATGGTATTGCT -CATTCCCAGCGATTGCCAAATACGATTCATAACAGATTGACTTATCTTTTTCGAAAGCTC -TATCATATGGCTTTGAGTAATAAGGTGAGATTTTTTTGGTGATGAAAATAAATACGGTGC -CTTGATGCAAAATTTTTAGCCACAAACCTCTCTTCAGTCCCACATGATTCACCTGATTAC -GACTCACTATTTCATCTGTTCCATAAATCTCGGCTTTTTATATACAGAACATTAGACGAC -GGGAAGAGAAAAACGTCAGTATAACCCACTTTTGTTCGTAAAAAAAGGTTATTCACTTCT -ACTCCGTACTAATCAATGACTTTAATGGTGAAACCATGATGAGGAGAGTAACACGATGTA -ATTGTCATAAACTAATATTATCCCATATTAGTTTACTGACGGCTACAAGTGAGAATATAT -ACTTTAAGAGTGTAACCATACCAGTAATTGGGTTCCAAACAAGTTTGTGAGGCGCGTGTG -CTGAAAGTNNNNNNNNCTTACCTTAATAACGCAATTTCTGGCGAGGTTAAAATATTAAAT -ATAAAAAGCCTTCCAAGTAATTTTGCCCACTAAAATGTAACACAAAGCTCCACTGGTTCT -CGGCTTCTTGTTCTTTCAAAAGGATCTTCAAATCCGCTTCCACTTAAGCAGCCTTCTGCT -ACGACTTCTTCTGAGACACTCGGTTTCGCGCGGGCACTTCTGCCCACCAAAAAAGTTTAT -TTTCCGGAAAGCTTATTTCTAAATAAACTTCTGAGGAANNNNNNNNCCGCAAATTTCCAT -GCAACGTCGAACTCTCAAATTCTCACGAGATTATTTGACTTGCTTTCCTTTCCCCCTTTT -TCCACGCACTACGTCAATGCAAGTGATCCGCTTTTGAAGAAGCAAAAAATACTTCTTTCA -GCTCGTACCGGCATTTTTATTATTTGTCAAAACTGGCGTTTGGAAACCAGCTCTTCACTT -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNAGAGTTTTGTTTAAGCCCCTTTTATGGATG -CATGAGNNNNNNNNNNNGGTTTGCTACAACCATCTCAGGTCTCTTGAAGGATAGTTCGAA -GCTCGCCTGACCGTCTTTGGGTGACCAGGCTTGGTTTTCAGNNNNNNNNAGCTCATTGAG -ATATGTGATCCCGTTCCTAGATATTATGAGGGAATTTTATATATCAAATTGATTTTCACC -GCGAATTCCAGAAGGATGGGCAAAAGAGGGCTTGTTGGCGTGGGAGGATGGTCGCGGCTG -AAAATTTTCACCACGAGCAGTTTCTTGTGAGACATCCTAATACTTTTGCATTTTTACCAA -GCAGTCGTCCGTAGCAAAGCATAGGTTAGTAATAACAATGTGCAAATAAAAAACTATCTT -ACAGGCAATTATTTTGTGGCAAAGCAAGGTCCATGTTTTCTTGAAAGGTAAGAAGTGGCT -TTGGGACAGCTCATATAGACAGATTTAAGTTTTTGATCTGAGAAGCGAATGAAATGTCTT -CAGTATCATTCAATTTAGCATCCTTTTCATTGACTTTGAATGTTTTACCGCCCCAATCAA -TGCCATAATTAGCACCCCATGGATGGTCGTTTAAGGCCTGAAGAGTTATGGAGCATTGTG -AATAAAATAAAAAATTACTTAGGAAAAGCATCGTGTTGAAGTAAAGCAAAGAGCAGCAAA -AAATAAATGGAGTAAATATGAGAGAAATACAGATCAGAATGGTTCGTTCAAGAGTCCATA -CTATAAACCCGATGGTGACTTTTGCACAAAAAAACAATGGTTTCGAAGATTGTGCTCATA -TTTTCTGAGCTCAACATATGCTCGCAAAAACACCTACTAATTGATGTTTACCAAGAACGC -GAGTACAGTCATATATAGATGTAGTAGAGTTGAGATATTCTGAATCGGAAGTACGATATT -TCAATTCCTATATTGCAAAAATTTATATATTTGGAGCTTCTTGAAAGAAAAAGTGTCCAA -CATCCTGCATGAAGTTTGATCACTTTAGCTGGTCCCATTCGAAGAACCNNNNNNNNNNNN -NNNNNNNNNGAGATTCTTCATATTCTGTTATTAAATTTTTAGACTTTAATTTTTACTTTC -TATGTAACGTTCACTCTTACCCTAAATATTAAACTATTTGATAAAATATTACACTGAAAG -GTGTTACAACTTTTCCTAGACCAACCTTAATATAAACGTTACGATATAAAATAAACAGTA -ATTTTAAGATTCCATTGTTGAATGTGACACGTAACTCTAGGCCATACCTGGTTTAGTATT -TTTTAAAAGAACTCTTGCTACAGCATATTTTACGTTTGCATAAAAATAAAAGAAAAGCTT -CCTTATGAAACACTGGTTAAGAAAAGAAAATGGAGTGGTTACATACTCCAAAATAAATTA -CTCTTAATATCTGTTTATCCAATGAGGAGCAGATCTCAAAGATAATCAGACTTGTTATTG -AAGCAATTGAAGTAAGTCTTCCATTGAAATCACGCTAATTATTAAGCAATATGGTGGATT -AAACAACTCTGACGGGACCGTACTACTTGATGAAAAGTTATATACAATATTGAATAACAG -CATAATGCTGTATGATGTTGAGCGGAAGATTGTATAAAAATGTCCTTTTCTAAAATCATG -AAAAACGAACCCTTTAAAGTAATTTTGTAGCGAAATTTAACCTCACGAGTTCATGATCAT -AACTCGTTATCATTTTTGTAATATTGAATCGGTCTCTATAGAGCCTCATGAGAAGATAGA -GGACCCGAAATAATTCTCCCTTCAAACATTATGGCCAATAAGTGTCAGGAAGTGAAGCAT -TGACATGACAGCAGCACATTAAAACTCTATTGAATATAAATACGATCCACGACATGTCGT -TTACAAAGCGCTAAAAACTCATGAGCCAACTATTCCCTAAATTTCCAAGATCTATCATAT -ATTTTTCCCTAATTTTCCAAGAGGAACCTCCATAAAATAATGCAGAAAAACATTTGTTTG -ATCTATTTTAAAAGGCATATCGCATGTTATAGTGAATCTGAAGATTGCTTCTCTCGTCAG -TATTAATGCACTATATTACGTTTCAAATAATTCGTAGATTGTCTCAAGTTTTCAGTATAT -TTGCCTTCATGACCCACCGGTCCTCTTCCCTCAAGTGCTCAACGATGGGAGCTTCAGAAA -AATCCAGCAGCATAGTTGAGTTCTGATTCTCTCCTTGGTAGTTTTTTCCTTTGGTGATTT -CGGATTCATAATGAAAATGTTTCGTATATTCTATGACTAAAGTTGTTATTGTTGTAAGTA -TTTCTGCTTCCTCTTGCAACAATTCCGCTCCCACTTATAATGCACCGAGGTGAATTGGTC -ATCCTTACGAAAATACCCAGATAGAAATGGAGTAGTTGCGTGATCGTTTACTGCATCTTT -TGCGCCTTTTAATCAATCTTGACGTGGATATCTTGTTTTGCTTGAACCACCACCTGTATT -GCTGGTATAAATCACCATATTAACCATCGTTTTCAATCAACGCAACTTTTAGTGTATTGT -CTGCAACATCTGATTTCCCTCTGGTAAGTCACCTAATCTAAAATCTCTATTTTGAATCCA -CGGAGACATACGTTTGAAAGATATAAAAGAGTTCATTGAAAAGTCTAGCGTCACAACTGA -CATTAAAATACTTAAATATGAACCAAAATTTTTTGGCTTTTATTTTCAATGCAATCATTA -TCTGCCTATACAGGAAACGCTTTATTTGGCTCAATAATATGATCATGTTTGTCTGAAGTT -GGCAATAAAAGAAACTAAGAAGAGCCACTAAACTTATTTTATGATATGGGAAACACAGAA -AACACTCCAAAAATTTTGGTACAAGAACCTGAAAATAGAACAAAGAAAGAGGCGAGGTTT -GGTACATCTAATTTACGTGACCTAGACGTTGCTCACCTTATGTTAATAGCTTATCAGAAT -TACAAGTAATTACTTGTAGGAACATCCTCTACTAGTGAATATGAAAGAGCAGAGGTTAGC -TCCGTCTCAACCAATTTTGTACAAGTCGTTGAAAAGGACGGCTCTACTGTAGACAGGTCG -ATTCAAAGTCTGGTCTCAAAATAGAAGGTAAAATATTATTGAACAAAAGACCACTAAAAG -GCTATGGTATGTCCAATAAGATGCAAAATAGACATTTCACTCGCTAATCGTTAGTGGGAT -TATATCTTACTATACTCCTTATCTCATTGAATGGCACTAGTCGATCGAGGAACAAAAAAG -GATCGAACCGATTAGCACGGATTTCCTTAAGTAATTTAAATTACCAAAGAAGATCCACAT -CAGCAGTCGAATGTTCAAGATGCCGTAAGTTTAAAATCTTTCGTATCTTTCCCCGATCCT -GTCTTTCATCAATGAACTTGAATATCAAGAGTGAAAAAAACTCATATGGCTTCTCTTGAA -GAGTTAGAAAGATAGGCACATGCCAATTGTGTGCATAGCACTTACTACTCAACGATTTCA -CAACCTAGCATAATACGCGNNNNNNNNNGTGCATTTATTTAGGTAAGTCTCATTACCTAA -ACGCCAGTTTGTTTCACGTAATTGGTAACGATGAGGGAACCGCAGTAGAAAAAACTTTCA -TTCACAAACGATTAAAGTGTTATGCTAGCCAGTTTCAGGCTTTTTGTTTTATGCAAGAGA -ACATTCGACTAGATGTCCAGTTAAGTGTGCGTCACTTTTCCTACGGTGCCTCGCACATGA -ATGTTATCCGGCGCACGATACTTATCACCGAAAAACCTTATTCTACGGAAAACCTTATTT -ACATTAAAGTTGGAAAAATTTCCTCTTTTTCCTAATAAGGTGGAGCTTTTGGCTTCCAGT -ATGCTTTCACGGAATTATTTCTCATGTACATTTAGCTCCATTTCCAGTGCCTCCGATAGG -GAGGCATCATGGTACTACCGTGACGGAGAATACGTAGGCTGACTTTTTCGTCAGTTTGTT -GTCCGTTTACAAAATTGGTGAATGAATTCTAGCCTTCCTCTGCTCATTAATTGCCCTCAC -AAGAATTTGGAAGTGCGTAGAACAGGTAAAAGATTGTACTACAGAGGTATTGTGGAACCT -TCTACAGTACTTCGGAATACACCTAAAAGGTTGTTGGATGCTAAATTTAGCAAAAGTCTT -TTTTAGCTCACTATTAGGCTTGTTAAAGTCTGAAATTGTTGAAAGGCACTCAAAAAGATA -AATCAACAATCAGCATTAACGGCACAGTTGAAAGAGTCACCCACTTGAAATTAGCTCGGT -TATCAAATATAATTATCTCTGGTAAAGAGCTCTGCAGCAGGGTTAATCTATTCGCATACT -TACGCTGTAGGAACATTTTATTATTAGGATCCGACTACTGCCTACATATTTATTCGGAAG -GCATGATGTCGAAAATTTTTGAGCTTATAAAAGGAACATATTTCACTCTTGCTCGTTTGA -TGTAAGCTCTCTTCCGGGTTCTTATTTTTAATTCTTGTCACCAGTAAACAGAACATCCAA -AAATGACAATGCCTCATCGCTATATGTTTTTGGCAGTCTTTACACTTCTGGCACTAACTA -GTGTGGCCTCAGGAGCCACAGAGGCGTGCTTACCAGCAGGCCAGAGGAAAAGTGGGATGA -ATATAAATTTTTACCAGTATTCATTGAAAGATTCCTCCACATATTCGAATGCAGCATATA -TGGCTTATGGATATGCCTCAAAAACCAAACTAGGTTCTGTCGGAGGACAAACTGATATCT -CGATTGATTATAATATTCCCTGTGTTAGTTCATCAGGCACATTTCCTTGTCCTCAAGAAG -ATTCCTATGGAAACTGGGGATGCAAAGGAATGGGTGCTTGTTCTAATAGTCAAGGAATTG -CATACTGGAGTACTGATTTATTTGGTTTCTATACTACCCCAACAAACGTAACCCTAGAAA -TGACAGGTTATTTTTTACCACCACAGACGGGTTCTTACACATTCAAGTTTGCTACAGTTG -ACGACTCTGCAATTCTATCAGTAGGTGGTGCAACCGCGTTCAACTGTTGTGCTCAACAGC -AACCGCCGATCACATCAACGAACTTTACCATTGACGGTATCAAGCCATGGGGTGGAAGTT -TGCCACCTAATATCGAAGGAACCGTCTATATGTACGCTGGCTACTATTATCCAATGAAGG -TTGTTTACTCGAACGCTGTTTCTTGGGGTACACTTCCAATTAGTGTGACACTTCCAGATG -GTACCACTGTAAGTGATGACTTCGAAGGGTACGTCTATTCCTTTGACGATGACCTAAGTC -AATCTAACTGTACTGTCCCTGACCCTTCAAATTATGCTGTCAGTACCACTACNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNTCTCATCCAGTTTGTCATCATCATCTTCAGGACAAATCACCAGCTCTA -TCACGTCTTCGCGTCCAATTATTACCCCATTCTATCCTAGCAATGGAACTTCTGTGNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNTTCTACAACAACCTCCACTTCTATATTTTCTGAATCATCTA -AATCATCCGTCATTCCAACCAGTAGTTCCACCTCTGGTTCTTCTGAGAGCGAAACGAGTT -CAGCTGGTTCTGTCTCTTCTTCCTCTTTTATCTCTTCTGAATCATCAAAATCTCCTACAT -ATTCTTCTTCATCATTACCACTTGTTACCAGTGCGACAACAAGCCAGGAAACTGCTTCTT -CATTACCACCTGCTACCACTACAAAAACGAGCGAACAAACCACTTTGGTTACCGTGACAT -CCTGCGAGTCTCATGTGTGCACTGAATCCATCTCCCCTGCGATTGTTTCCACAGCTACTG -TTACTGTTAGCGGCGTCACAACAGAGTATACCACATGGTGCCCTATTTCTACTNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGG -TAGTTACAATTTCTTCTTGTGAATCTGACGTATGCTCTAAGACTGCTTCTCCAGCCATTG -TATCTACAAGCACTGCTACTATTAACGGCGTTACTACAGAATACACAACATGGTGTCCTA -TTTCCACCACAGAATCGAGGCAACAAACAACGCTAGTTACTGTTACTTCCTGCGAATCTG -GTGTGTGTTCCGAAACTGCTTCACCTGCCATTGTTTCGACGGCCACGGCTACTGTGAATG -ATGTTGTTACGGTCTATCCTACATGGAGGCCACAGACTGCGAATGAAGAGTCTGTCAGCT -CTAAAATGAACAGTGCTACCGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNAAACAGTAG -TCACCTCTTCGCTTTCAAGATCTAATCACGCTGAAACACAGACGGCTTCCGCGACCGATG -TGATTGGTCACAGCAGTAGTGTTGTTTCTGTATCCGAAACTGGCAACACCAAGAGTCTAA -CAAGTTCCGGGTTGAGTACTATGTCGCAACAGCCTCGTAGCACACCAGCAAGCAGCATGG -TAGGATATAGTACAGCTTCTTTAGAAATTTCAACGTATGCTGGCAGTGCCAACAGCTTAC -TGGCCGGTAGTGGTTTAAGTGTCTTCATTGCGTCCTTATTGCTGGCAATTATTTAATAAA -ATTCGCGTTCTTTTTACGTATCTGTGTATCTTTTCTTTGCTAATTATACGCTGACATGAA -TTATTTTTTAACTGTTTCTCCTCCATACTTTCAAATATTCAAATTGACTAAATGATAATT -CTTGCGCTTCTTATTTTGAAAAAGTAGATATGTGTATCATAAAGAAAACGTTATTATTAT -TGTCTTAGGCAACAAAAATCCATGAAAAGAATTTTACCGTTATCGATATCATTGTATTTA -TTTTATTTATTTATTCAANNNNNNNNNNNNNGGTTTATATCCTGCAAACAACACTTCGAA -TTCAATTCGATATTTCATAAGTTACAACTAACACTTATAGAAACCGATGTATGAGTACTT -ATTATTAACGAGGAAAAATGCCCTATTTTCTTTAGCAATTAATGAACCATCGCCAACTTT -TGCTTTAACAATTATTGCCATTTTCAGCAGTACTAACGTAAGATCTAGTGTGGTTCGCTT -AGGATGTTTTCGAGTAGAAATCTGCTGCACATGCCACACGCAGTACTTGAAACTTGAAAT -AATGGTGATAATTAGTTATTTAAAGTATGTTAATCTTCCTTGTTCTTTTATATTTATTTC -GAATTCTTTTGCACTAGTATTTAAAATATCAGCAGAGGTGTAAAAGTGCACCAAAATTAT -TGTAAAACTACTTGCCCTAAAATTGATACTTCATACTTGACATATTCAAAAGGGGTCCAA -GTATAGATGCATCNNNNNNNNNNNTTATCCGATGATGAGCAAATGGTAGCTTTTCGTTCC -CAGGAAGTGTAGTAGTTCCATGAAGTCTAATGAGACTTTGGAAAAAGGTTTGTCACGAGC -ACCTAACTATTGTATTTTGGAATTTTGATAAACTTCAAAACGGGAACGAAGTGTTAAACT -TAGATGCGGTTGATTTAAGCTTTAAAAGAGGAAAATAATGACTGATGATAAGAAGTCAAC -AACGATTCAAAGCAGGTGAATTTCCATTACGTTTCGCTTTTCAATTGAAAAAAATTTGGT -GGTTATTCATTTCTTGCTTGACCTCTTTACTTTTTATACTTCTGTGATGAGAAGCAAGTT -CGAGGATTTTACGATAAAGCCTACTGGTTATATTTGTATAAATTAGAACGTTGTCCTTAT -TTCTCTTTTCGAACAGTATCAAAATAAAGTTTTTGATTAGGGCCAGATTCTCTTCAAGGA -AGAGATACCTCACGTCTGTAATATCTAAGAGCTAATGTTTCGATCGAACTTTCCTTTGCT -TTTTTTCTGGATCTCATAATGTCCCACTGTATGTATGTGCCCTCGCACAGCTTTGCTCAT -CATAGACATTAATCATTGGTTGTACGATAAAAATATCGCAAAAATTATTCTAACGTTCAG -ATTAGATTCCGGCCATATTTCTGACATTTGTTTTATTAATAAAAATTTGGCGAATGTTTT -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNGTTAATGATTCACTGTGCTTTCTGTTGCTGTAGAATTTCTGA -GGCATTGTCGCTCTCTTCTATGTGATGCTACAACGGAACTAGGCTTCTTATATATCGTGG -TCCTACAAGATCTTGGTATCTCGTTTGCTTACTTTGAAGCTTCACTGATATATAGTATTT -AAGCCACTTTCATGTTCATGGATAATCGTAATTGTACTACGCTGGTACCAGTTATGAACC -CTATCAAATCATCATTGAACACTGCTATTTTTAACTAATCAAGATGTGTATGCGGCGTAC -TTTATAATTTCACGACACTATTGAAAGCAAACTAAAAATCAAGTAAATACCTATCCAAGT -TGCGGGCTCTGGATTTATGTGGCCTTAAATTTTCGACCTATGGTTCGCTATTCAATATGA -GAAAACCAAAATTAGGTACAAGTACTGATTACGTCCGTGATTCGAAAAGCAGCGTTGAAA -GATTACAAGATTTTGCGTGTCCAGGCCGACACTTAACTTTAAGGTCTCGACTTAGTAACA -TGAGTTGCCAAAAGTTTTTTTCTCCTATCTGAATATGGGGAACCGGAATTTGTCTTTGAC -CTGACTTTCAAATTGTTGCATATGTNNNNNNNNNCAGAAGAAATATGATCTTCTTCTTCT -AGCGATGCAAAAGGATTCATTACAAATCGTCGCAAAGGCCGACAAGTTGCAGTATATTCA -CATTGCTTATTTGAAGTATGTTTGTATACACATCGATAGTATTCATTAACACCACAACTG -CTGTGTATACTATGTCAAACAGCATAATAAAGCCCGTCATTTTTGTACCCGCTCATTTCC -AATAGGCATCTAAACTTACAAATGTGGTACACTACTTCGAATTCATTAATCGATATTGAA -TGCTAAAAGTCTGCGATTTCTTCCTCAACGTTCAAAAATCTCATCCAAGGCATAATCCCA -CATATTGAAGATCGCTACCAATTGTTACGGGCGAACTGAGGTTTTGGAAATGAGCTTGTA -CTTAGTAAATTTCTCTTTGCTTGCATCTTTTTCTTCCATGCCAAAAAATAAAAGATACTC -ATTTTAAAAGCGCAGCCATATTGACTAAGTAAGTAATCATAATACTATGAGTAATTTTTG -AGTACTGTGCTCATTTACTAGCTGCTTTTCTGAGAAAGATCCTCGATAATCAATTCCAGG -TTAGTGGGGCCCTTCTACGGCTTCTTCTAACCAATTGTTCCCCGTGAGTTGCTTTCTCTG -AAAACCTTATTATACATTAGAGTTATAAGAAAATTTTCTTTTTCCCGTAGATTAACCTGC -AGTGCCGAACTTCTAGATGTCACACCAGACCGTTTGACACCGCCATTTTCCTTCCTTTTC -GGAAAAATGTGCCGATAAATGGTAAGACGCGACGCCACTGCTACGAATATTACGCTTATG -ATGAAGCAAAAGGAAAAAGCAAGTTCCCCTTAAATTCGTATAACTGTTTCATCAATCTTT -AGTTCTGGCATTTGAAAGTTAATTAAACTTTTCTTCGTGGTTTCTACAGGAGTTCTGCAT -GTGCGTAATTCAAAGCCTGTGAAGGAAAAAGTATTGTCCTAAACAACGGTCGTAGAATAC -GTCAACTGTAGTTTAAAATATTTTCTGGCTCTACTCGGTGCGATAGGTCTGGCTCTTTTC -TATTTACTTTTGTTTGGAGTTGTTGAGGCCGATACCCGTCTAGATGTAAATATGAAATAA -CAGTTCGAGGTTTTATTACGAGAATGAAAAGGGTAATGGATTGGAGCATGTGTAAATGTC -AATAGCAGAAAAAATTTACCGCAAATTGTTTCGTAGTCTTATCTTCATCGGACACTCAAG -GGTTGCATAATTTTTACCCAAAGGAACAGTATACTTTTTTGATAAAAAAATCTTGTTACC -TATACAGTATTGCAAGCATTTTCAGAAACTCGTCTTTTGAGTTCTAAATGCATCATACAA -CAACAACAACAATTTCTTATTACTGTGTCCTTTTGGGATTTTTCAGCCTTCCTAGCTTAC -CCAAAATAGCCTCTCAAGGTGAAAAAACCATGCCTGCAAGCGGATCTAAGGATGAGTAGC -TAGATTACAATAAATCCTGAATTTTCTCTGAGTGTCAACTTTGTCATCGCTTGTTAAAGG -GCTACTACGCTGAAAAAGAACCTGAACTCTGTTAATAGGTTGAAGATTTTATGACTTGGT -ATACTATTCCATACGGCTGCTCTCCTGATTGCGGTGGGTCATTGCTATAACAGTAAAATC -AAGGAAGATAACAGGAAGAGTAACTTTAGTACAATAAATCTGTTGTCTTCCCGAGGATTA -TAATTGTTCGGCTTTCACACTAAGTTGAAAAGGGGGACTCAGGAAATGACAGGGTACGTT -TTAGTTTCTCCAAATAAATCTTCCACACCCAGCTTCAATGTGGTAAACGGGGGAAAGTTG -ATTAATTGATGTTGGCACTTATATTTAACTGATGTAGAGAAGAACAACATACTACTAACG -TCACAGTCAATTGTGCCAGTTTTCCAATCAAGTATTTCGAGATAATGTAAAAGTAATTGA -TATATGTTCGTACTGGTTTCCCAATTTCCGGGAAAAACTATGTACATGGGTGCAATTCCT -TGTGGTTATTTCCTTTTAGGTTATATTGCCAACCACATCATAGTACTATTTGCGGTCACT -TCAGAAGATATGTTTGCTCCTTTGATCATGATATAGACCAGGCCAACTGTACCGCTTCAG -GCTTCAAAGCATTAGGAATAAGCACCACTATTACACAACCATAGAGCTACTCTTACTGTC -ACGTAGGTAAAACACTTGCTACTACACACACTCGTAGTGACTCATCTGACTATATTGCCG -GTTGTTAAGAGGCACCAGTTAAGCACGCCATCAAGGGTACCGAATAATCTCTTCTGTATC -AAGTATTCTACCTTTATGTCTGACCCACGTATTATGTGGAGCAATTACGTATTTTTCTCA -TATCAGCTTTGTTTTTACTCAACTTTGATATCTTAGAGAAACAGATCTTGATGTTACAGC -AAGGTCAGGAAAATATTTTGACAAAAACATACTAGTTTCATCCTTAGTAGTTGATTCTAT -GAATGCTGTACTTGAAAATATTGTTCATAAAATCCATAAGTTTTACCAACGGTATAATAT -CCTGCTATTAAATCTGCAATTGCTTTTGCGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNTTGGCACCCCAATTTCTTATAATATAATAATATAACGGAAGTACACCATGCT -TTCAATAATAAGATGTTTCCTGAAAAGGGCAACTATCTGACTAGTTCAGAGCCATGCAAA -AGTTAAGGATGAAAATGCCAAATAAGAAGATATTACGGAGTACATTCATTTCAAAAAGAA -GAATGTATACTGCTTAGATAAGAAGATCAAGTTTTTATATTTCCGACCAAATAAGCCATC -GAAAACTTTTGATGCACCAAACACCGTTCTTGAGAGCCAAGCACAGATGCAATTGTTCTG -CCCTTCTTCCAAATTATGAATTGTGCATCATATCGTAAGGCCAGCCACATNNNNNNNNNN -NNNNNNNNNCTCAGTATACAGGCGAATATCCATCATACAGTCTAGCTGCCCTCACTACTT -CCAAAAAAATGGGCTAGTGTTGTACGGTTTATGCCATATATCTAGAGTTAGCATAACTAT -GCACTACCGCTTTTCGAACAAAAAGTTTGCGAAACCTAGTTCATTGAATATGACTTACCC -AAAATGGATACCAAGATCCTAATAATAAAGTCAATAACTTGAATTTTAGGTGCCATTATT -TCCAACAATCATTATAGGCTAACTCTACCAGCAGACAAGAATACCGTTCTTCTAGTTGAG -CACATGGTCAAAATAGTCAATAAAAAACGCCCAGAAATGGCTGTAAATTAGTGTTTGTAG -TACACAAAATAATTTCCTAATTCCTTCCAAATGGGGTTTTCAAAAAGCTGACTCACGTAA -TTGATCAATACTTCACTAAAGAAGAATCATATGAATAAAACTAAAATCAACACTAACTGA -GAGACTTAGCGGCCAAAGCTTAATCATCATTACATAGAGTATATGAAGGGAGTAAGTGAA -TATGCAAGGGTGGGAAACGGCAAAGCATTTTTATGCAAAAAGCGTATTTACAAATCCCGT -AAACTCATGATGTGAATTTTGTAACCAGCTTTAGCTGAGATTATTTCTTTTGCAAAAGAA -ATATTCAATAAATTAACAATTTTCAAATAAATTACCCATCCATGGTCGATAACTTGCAAG -AGAGATATCATCATTTGGCTTTTGTGATAAATTTACAAAACGTAATGTTGTATCGAGATA -TATTGAGTTACAAGTTTTCGTCTCTTTTTCCGAAGCGCCAGACTCCCGTATAAAAAATAA -GGTTTATAGCGGGCATTATGCGTAGATCAGGACTTAAATTTTTCATTGCAGAAGTCCAAT -TTCAGACTCAGTATGGTTTGTTGTAGTGCTGGTGTAAAAGATGGTGTTATTACTTAAGAC -TGATTTGGTTGCTCAGGTATTTCATTCAATAAAATTGTGAAAGAGAACCTGGAATATAGA -ATGGAAATATATATCCTGCTACTAACCCCAATGGAAGGTGACGATCACTTCTTGTGCGTT -CCAATCCCAGTTTTTGAATGTGCGAGTGGAAAAATTCTAGAGGAACAAATTGATATTTTC -AAATCAGAATTCATCAAATATATGTACTCTGTAAAAACCAAGGATGTGATGAAGTTGAGA -TATTGTCTTTATGGGAAATTGACTTCTTTGTTTAATATGAATAATGCAATTTTACTCCTC -AGCTCAAGTAGTGTAAAGATTCAGTAGCCGTCATCAAATAGACTAAAAATTAAAAAATAA -GATTCAATGTGGTATGATAATGATAGATGAGAAGAAATTGCAAGAAAACGAATAAATACC -TTGTCTCTTTGCACTGAATATCTTAAAGGACATACAGTCGCAATAACGTCTACTCATTGG -TGTGTGTCAAAAACAGTACGTTTATTATCTGGACAGCCAAAAAATAAGATCTATTCAAAC -ATGGAATATAGCGTATTTTTATTTAATCACGGTACAATGGAGATATTTGCATGCCTATAG -AAACAAGTAATAGTTATCATATTATTTTCTAGATTTTGTCACTGAACTTTTCCACTAATG -AATCCTATCAAAATTATATATCCAATATGGCTGCATTCCCAACTAAATATTAAAATGCCG -CTAAGTATAAAATGTCTCCGCATCGGTAAAAAGCATTACAAATGCGTATTATACTAGCGA -GAAAAAAGTATAAGTATCAATGCCAATCACCCTCTGACCATAAACTTTCTAAACATGAAT -AATAAAGGTGTTGAGAGTTATTATCCTAATTGATCAATTAATTTGAAGCAAAGTTATTAT -GTTAAAGAAAAAGGGATGTCACAATCCTAACTATAATTTTTGCACTATACTCTGTAGGCG -TACAAAATGGTTTGTACCGACTATATTCTCTTTATTTTTGACAATCCTTTACGATATATG -ATTAAGAATACCATGTTATTTTTATGAAAATCTGTGNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNGTCACGTAGTGCACTTTGATTAATACNNNNNNNNNTGCTGCAAAAGCATCGAC -TACATAAATTCATTAGGACGCATTCCTCATTACCACCTGGGTCTAATTTTTATTTTGAAA -TTGATATTATTCTTTATATGATGAGGTAAAAAGCATTATATTCGTTGTAAACTCATATAC -TTATCCTCATTTTAGGCACCATCAGGGACTAAGGGCTAAAGTATCAGAGCCGCATTTCAA -CAGTGTACAGAGATTTTAGAAACATTATCACGCACTGCCTTTTGCTTTGTTTACCCGTAA -TGAGTATACAGTGGATTTTCTGGTGCTAAAGCATATTGCCCTTTCGGCAATACTTGATGC -CCTAAACATTTTCATCCTGGAACATACGAGTAAGAGCACATTTATGTGCCTATATTCCTC -GTTTTTTACTGGTGCTGAATTTCTTATTTTCCACAGATAACAATCATGTTAATAAATTAT -GCACTGTGCTAATTTTTCAATTAAGGTTCTATTACCCCTCTATCACCGACAGAAACACGT -AATGATGTGTTATTTCCATTATAATTCCGTAAGAATGGTGTTTATAGGTAGTCTAAAGAA -CGTGCATCAGAGAAGAATAACTGTCGCAAAAAATGACTATTCTTTACCTTTTCAAACTTA -ACTGAGATAGTTATCTCTATTATTACCAGTGGCACACACGCGAACTACATCACTCACCAC -TATCGTCTTAGGAACTCAAGATTTTATAGTAATGCAGCCGAAGACATTCAAGTCCTGAGA -GAAAATGTAGACATTTTAAGAAAAGTACCGGAAATAAAGCACATGTAAAGCATTGAGCTC -TGTACTCTATAAAAATTAGCTGCATTCAAACAACAATGTTTGAAATTTTTGCAAAAGTTA -TTGAAAAAGATTGCTGTTTTCAGCCTTGTTCAGATCATGTCTCAAAAATGAGAAACTGGA -ACTCTCATAATCAGTACCTCGTANNNNNNNNNCCTTATAGTTTCGTTATTAAAAATTTTT -TTGCTGCTAATTTAAGTACGCTTTTGGTCATAAATGCTACCCACCAGTTGAATTATTGAC -ATGATTAAAATACATTTCAGAACTTTACGGATTAAAAACTTTAAAGAACCTTTCAATCCA -TGTTGCTGGAGGGCCATGAATCCACGAATTACAGCAAAAGAAGACAGTAACTACTTAGGG -TTCAATAATTACTTGCATAAACACACACTAACAACCAAATCGTACTAAAATTTGCAATTA -ACAAAACTCCATCATATCACGCTGAATTATGTAGGGCTTCTTAATGCAATAGGTTGCCTG -AATTTTGCTTACTCGTGCTGCCGGGAACACTTAGCAGTTGGGAGGCCGTTTCTCCCATAT -ATTTCATAATTTTCTGTCCTTCTTAGAGTAGGATGCTGAAAATCAAAAGAAGACCGTCAA -TAGGACCAGATTTTGTGGGTCAATTTTGGGCCAGACACATGATACCCTAGGAAGTTTAAC -GGTATACAACTCAAGGACGAGGAGTATTCGGAAACTACCGGTTTTTAACAAGCTGCAAAT -TTCCAGTAGCTGTTTTGGTTGCGACTACGGATAAAAATTCATACTTTAGGAAGTGAAGCA -AGATAAAAAATCATGCTGCATCCTAATTCGTGAAGTTTGTTAGGAATATTATTGTAAACA -AGGAACCGTTTCAGTAAACTTGCTCTCTACTCTTCTAAGCTGTAATTTAAAAAAAGCGAT -AAAACAATGATTTTGATTATCTGCAACTTCTGGAAACTCGAGATACTACGCTAGACGAGA -TACCTATTAATTGTTTTCCTAAAAAATCAGGAACAGTTCCTGGCAGCTTTCGGCTCCTTC -TTGTTCTGGAAAGGATCTTCAAATCCGCTTCCACGTAGCAGTCCTCGCTACGACTTCTTC -TGAAGTATTTTGATTTTTGGCTGCATTTACCTTTTATTGCCGAAAATCTTATTTTCCAAG -AAAAAAGCTTATTTTGCATTAAGTTTAAAAAATTTCTTCTTTCCCGTAGATTGACTTGCA -GCGTCAAAATTCCGGAGGCCTCACGAGATTTTTTGACATCGNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNCTGCGCACGCCGATAAAGAAGTAGTACAACAGACAACGT -CAAAATGATCCTCTTGTGATGAAGCAAAAGAGGAAGAGTATACTCCTTTTCCGCTTGTAC -AAATANNNNNNNNGATAATAAAATTTGGCACTTCAGAGCTTATCGTATCTTCTCCCGGAG -TTCCTCAAGACTTATACTTCAGCCCGTTTAGGAATGCATAAAAGCAAATAGGATTCGTTA -CAACTGCTGCAGGACTCTTTAGGACTGCATCAAGGTAAGCCTCGCTGCACCTAAACGCAA -AATGTGGTTGTAACCNNNNNNNNNNNNNNCTTGAACTTGTTGAGTCGTAATAAATCGTTT -CTGGGAAGTGGAAGGTAATAATGTAATGGAATCGGCGTTACTCGCATGTGCAGATATCAG -CGACAAAAAGTGTTGTAGGGACGTTTCGATACCAAAATTTCCTAAATACAGCGCAGGAAC -ATCACTACGCTAAACAAATCGTAGCGCATACATCTGATCGAAAAAAGACAGTTCCCAAAA -CAATGACATATGAAGAGACCAGCATCAAAATTTTCATCATTAACAGCATGGCTAAAAGTT -ATTGTTTAATATACCCATACCTGATTGACGAACCAAGAAATGCCTTATCACTATTTATTT -TTGGCACTCTTCACCTACCTGGCCACGTCCAATGTTGTTTCAGGAAGTACACAAGCATGC -CTGCCAGTGGGCCCGAGGAAAAATGGGATGAATGTCAACTTTTATAAATACTCATTACTG -GATTCAACAACGTATTCCTACCCGCAATATATGACTTCTGGATATGCCTCGAATTGGAAT -TAGGTTCCGTTGGCGGACAGACGGATTTCTCAATTGACTACGATCTTTCTTGTGTTATCT -CTTCAGGAACTTTTAAATGTGCTCAATCAGATGCTTATGGAAACTGGGGATGCAGAGGTC -ATAGTGAATGTTCAAAATAGCCAAGAAAGACCTATTGGAGTACTGATTTACTTGGTTTCT -TACTATCCCAAAAAACGCTACTCTAGAAATGACAGGTTACTTTTTACCACCACAAACAAG -TTCTTACACGTTCAGGTTTGCTAAGGTCGATGACTCTGCAATTCTATCAGTCGGTGGTAA -CGTTGCGTTCGAATGTTGTGCACAAGAACAACCTCCAATTACATCGACGGATTTTACAAT -CAATGGTATTAAGCCATGGCAAGGAAGTTTGCCTGATAACATCGGAGGGACTGTCTACAT -GTATGCAGGCTACTATTATCCGCTGAAGGTTGTTTACTCCAATGCCGTTTCCTGGGGCAC -GCTTCCAATTAGCGTGGAATTGCCTGATGGTACTACTGTTAGTGATGACTTTGAAGGGTA -CGTTTACTCTTTTGACGATGATTTAAGTCAGTCAAATTGTACTATCCCTGATCCTTCAAA -ACATACTACTAGCATCGTCACAACTACTACCGAACTGTGGACTGGTACTTTTACTTCTAC -ATCTACTGAAATGACCACCGTCACCGGTACTAATGGTCAACCAACTGACGAAACCGTTAT -TGTTGCCAAAGCTCCAACCACTGCCACCTCATCCAGTTTGTCATCATCTTCTTCAGAACA -AATCACCAGCTCTATCACGTCTTAGCATCCAATTATTACTCCATTCTATCGCAGCAATGG -AACTTCTGTAGTTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTTCTGCAACGAC -CTCCACTTCTATATTCTCTGAATCATCTAAATCATCCGTCATTCAAACCAGTAGTTCCAC -CTCTGGTTCTTCTGAGAGCGAAACAATCTTAGTGATTGCTGGCATGTCATTAGCGACAAG -ACGCTTATTACCGTAGTAGCCCCCCAAGGCAAACATCTCTTTATCAGTAATATCCAAAGC -TGTTCAACTTCTCGAATTGGCCCAGGAAAAGAGCATTGGGGCGGCAACTAACTCTGGCAT -ACTTACAGTTTCTGCTCTTGACAGCGCTAAAAAAGGGCTTGTTTTGTAATGCCCGGTTCG -CAATTCTACAAGTACCACGCACTAGCTGCTAAAAGTGTCTAACCTTGCGAACAAATCTGG -ACTTTCTTATGAGAATCCCATCGTCAAGAAACAAAATTATACAGACAGGCGTAAATGTAG -CTCGTAAGCGCCTGATCAAGTAAGCCAAATGCGCTAACTTGAGGAAATATAGCCATCTAA -ATCTCTGCAACATGCCAATTCGCACGTGACTTGAAACTATGGAAAGTGTCTAGAAGATTA -CCAAGAACCACGTTATTTGAGAGAGGATGGCAAGGTGACGACAATCACACCAAGACCACA -TTTTGGGTGCGCCTGGAAGCAAGACCTGAGAAACTGGGCCAAAATATTCAAACCAAGCAT -AAGATAGTTGGAGGTAGGAATACACTATCTAATCTGTGCTGATGAAATGCTGGCGAAAAC -GGGCGATGTAGTGGTACAGAAGGTGCCGGTTATCCGTTTGTCCGNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNGCACCGCTTATATATGGGTATGAAACAAGTTCAAGA -ATTTATAATGGAACCCAAAGGTTCAGTCTTTGTAGTTCGAGCGACATTGCGCGTTTCCTT -AGAAAACGCTGGAAAGATATTCTTTAACGAGACGGAGTAATTCTCGTCAGGAATAGGATG -TTGATTGATTTTTGCTGTAGTTATATAGCAGGGACCCACGGAAGAGAGCGAGCGCCTTCT -TTCACAGGGACTTTTGTCAGCCACGTCTCCGGGGAAAACAATTGCCGTCCGCGTCGCAGT -GAGATTACGCAGCCGTGCGCTTCAGGGACAGAAAAGAAGCATTTCGCGGCTACGGAGAAA -CCGTGCACTAACTCTCTCGAGGGTAGCCGCAAAGATTTCTTGTCTCTTCCATTAGGACAT -AGCTATCTTTTTCTTTTCTGTTTTTGGCGTATGATCTGTTCTGAGCCAAAGTTATAGATC -ATTGCTTGAATAAGCACCTCACAGAGTAGGGATTGTATAGAAAGTAGCTGAGCGTCTGCC -CACGTAACAAACAATCTTGCCCCTTCCCCGCTCTTGTTTTCGCGTGCCTCTTCTACAATA -ATCTGGCCAGGCTGAATCGCGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNGTCTGCAAATTAGCACCTCGTTCCCTGTTGGCAA -ACGCGCGCGTACAAGCCTTACAGGGCTTGAGAATGTTCTTCGTAGAAATGCATGCACAAA -AATTCTGATCTAGCACACCATCGGTCTCTGTAGCTTCGGGCTCTATAGCTATGGGTTAGG -AGTCCGTGAGTAGTAACAAGAAGAAGTATATAAAAAGCAGGTAAATCGTACTTCAATATG -CTTCATTGTCACTGGATCGTCATATTCACTCTTGTTCTCATAATAGCAGTCCAAGTTTTC -ATCTTTGCAAGCTTTACTATTTCTTTCTTTTTATTGGTAAACTCTCGCCCATTACNNNNN -NNNNNGAGATGTTCAATCGTTTTAACAAATTCCAAGCTGCTGTCGCTTTGGCCCTACTCT -CTCGCGGCGCTCTCGGTGACTCTTACACCAATAGCACCTCCTCCGCAGACTTGAGTTCTA -TCACTTCCGTCTCGTCAGCTAGTGCAAGTGCCACCGCTTCCGACTCACTTTCTTCCAGTG -ACGGTACCGTTTATTTGCCATCCACAACAATTAGCGGTGATCTCACAGTTACTGGTAAAG -TAATTGCAACCGAGGCCGTGGAAGTCGCTGCCGGTGGTAAGTTGACTTTACTTGACGGTG -AAAAATACGTCTTCTCATCTGATCTAAAAGTTCACGGTGATTTGGTTGTCGAAAAGTCTG -AAGCAAGCTACGAAGGTACCGCGTTCGACGTTTCTGGTGAGACTTTTGAAGTTTCCGGTA -ACTTCAGTGCTGAAGAAACTGGCGCTGTCTCCGCATCTATCTATTCATTCACACCTAGCT -CGTTCAAGAGCAGCGGTGACATTTCTTTGAGTTTGTCAAAGGCCAAGAAGGGTGAAGTCA -CCTTTTCTCCATACTCTAACGCTGGTACCTTTTCTTTGTCAAATGCTATTCTCAACGGTG -GTTCTGTTTCCGGTTTGTAACGTAGAGACGACGATGAAGGCTCTGTAAATAACGGTGAAA -TCAACCTAGACAATGGAAGTACCTATGTTATCGTTGAACCAGTTTCTGGAAACGGTACAA -TCAACATCGTCTCTGGTAACCTATACTTGCACTACCCTGACACCTTTACTGGCCAAACTG -TTGTATTCAAGGGTGAAGGTGTTCTTGCCGTTGACCCAACCGAAACCAACGCCACTCCTA -TTCCTGTTGTTGGCTACACCGGTAAGAACCAAATTGCCATTACCGCCGACATCACTGCTC -TTTCTTACGACGGTACTACTGGTGTCTTAACTGCAACCCAAGGTAACAGACAATTCTCTT -TTGAAATTGGTACTGGATTCTCTAGTTCTGGCTTCAGTGTCTCCGAAGGAATCTTCGCAG -GCGCCTACTCATATTACCTAAACTATGACGGTGTCATCGCTACAAGCGCCGCATCCACAT -CCGCATCCACTACCTCTGGTGTTGTCTCTACTGCCACTGGTTCAGTCACTTTATCCTCTA -ACGCTTCTACCACCGTCTCTTCTACGATCTCTTCTAGCGCCCCAGACTCAATAATTCCTT -CATCTAGCGCCTCTATCTCTGGTGTCTCAAACTCCACTACAGCATCTGGTTCAATCNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGCCACCAGCTTCA -CCTCAGGTTCCGCTTCTGTCTACACTACTACATTAACTTACTTGAATGCCACAAGTACAG -TCGTGGTTTCCTGTTCAGAAACAACCGACGCTAGCGGTAACATTTACACCATTACCACAA -CTGTCCCATGCTCATCTACCACTGCCACCATCACATCTTGTGACGAAAACGGATGCCATG -TTCCAGCACCAACTGCTACCGACGCAACTGCAACCGTTTCCTCCAAGTCATACACCACTG -TTACTGTTACTCACTGTGACAACAATGGCTGTAACACCAAGACTGTCACTTCTGAATGTT -CTAAAGAAACTGCAGCAACCACCATTTCTCCAAAATCATACACTACTGTTACCGTTACTC -ACTGTGACGACAACGGCTGTAACACCAAGACTGTCACTTCCGAGGCTTCCAAACAAACAT -CATTGGCCACTAGCACAGTCACCAAGTCTGCTGCTCCAACTTCTCATACTGCTGCTTCCA -GCACCTTCACTGGTATTGTCGTTCAATCCGAAGGTATGGCTGCTGGTTTGAGAACCAATG -CTTTAAGTACTTTGGCAGGTATTTTCATCCTTGCNNNNNNNNAAAATGAGTGCGTAACCG -TACTTTCCTAAAAATAACTAAGTAGAAAGTATTTTAATATATAAACGTCAGTGTAAACAT -TCAAGTGATTTTAACTTTACGCGGTTGAAGAATGCTGTGTTCGAACTATAAAGCGTCAGA -AAAGATGGTTTAGCGAAGGCACCATTATGAAGATAGACACATTCTTCNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNCATTTACTTTTATTTCGCGCGGTCGGTAAATTTTTCG -TGGGTTTCTTTGAATCTATTAGCCGACATAAGAATAATGCATAAATAATATTTTTAATGT -CTTCCTATGCCCAAAAGAAGAAGTCTTGAAGTTGCCGCACATGGAAATCACATGACCATG -GCTTGGCCCTTCGTTTTAAATGCAACATGCAATATGGAATGTGTCATGAATACTATCAGC -AGGAACAGAAAGCGTCGTTTTGTTTCTGCAAATGCTGTAGTTTTGGGCCGAAAATAGATG -TAGTAGAATATATAGTGAAACGTGATGTACNNNNNNNNNNNNNNNNNNNNNNNNNNTTAG -ATAACTTGGATTTTTACCCTGAATATTGCATGTGATTCGTAAAGAACTGAGTTACCTCAA -ACGGACCTCCCTTTTCATTTCGTATTCCGCGAATCATGAAGTCATGCAATTACCTCTGAA -GAGCTGACTGTCCCAAAAGAAGCTATCGAATCTGTCCTTGATTTATTTAAGCCTTGCGTT -TCGAGAAAGTGAAAACCAATTGAATACNNNNNNNNNNNNNNGAAGAAAGAAATAGCAGGT -CTAAGATATATAAGAAAGTTAATATCATTTTTGAACATTTTATTTTAGACGCCTTCAGCC -GCGCGACGCCCGGAGTAATCATATGCCCATGACTTTACCAAAAGGCAACAGGGAGGAACA -TGCATTAATGTGAAGCATCACTGCTGCAATTCTCGGTGTTGCTAATAATTCATGGATCGA -GAAAGAGACATAACATTTAGGCCAATTTTTTGAATAAATATGAACTCAGCTAAGACTCGA -CAATACAATTTTCTTATACTAAACGTAGATTTATAAAATAAACACAACTGTAAGGGCAAT -GCAACCGTAGATGCATATATCATTTATAGAAATTATATCCAACAGAAAGCTCAGACTTAT -ATCCGGTTTAAGAGAGAAATTCTTGCTCATATTACCCCAAGACCAGGTGGCGTGTTGAAG -TTTATAACATATAAGAACTACTACCTCATGAATTCTAGTGGATGAAAGAAGCAGCACGAA -CACCATTTCTACAGACAACGACACATGGAAAGGTTCACCATTCCCAAAGAAAACAACGAT -GGCCACAAGGGTGTGGTCCTCCATTCTCCTACTGTTGGAAGGAGATATTATCCGACCGAC -TGTTTTGTGATATGGCAAACTATTTTTTTAAATGAGCAAAATTACTTCTTTTGGCTGGAA -ATGTCATTAGAAAGTGCCCAAGTGACATTTAGCTAAACTCGGGTATTGTCTACAAGACCG -GTGCTGTGACCGTTTCCAATACGGAAAGAAACGGTACTGGGAGCAGGAGTTGCTTTTACA -GATATGAACAATGCCAATAGAGCCGCACATGTAATTACTGGTTCACACTCGTGGGGCCCA -CACGATTCCTGTGCAAAGTTTGACAAGAGGATGGAGTTTCACGTAAATGCTGCCAAAGGT -GATGCGGTTTTGTTTTTGGGCAGCCTCTACCATGTTGCAAGTGCGAACCATACTGTGGCC -ACATAGATTACAAAAAAAGTCCAGGATATCTTGCAAACCTAGCTTGTTTTGTAAACGACA -TTGAAAAAAGCGTATTAAGGTGAAACAATCAAGATTATCTATGCCGATGAAAAATGAAAG -GTATGATTTCTGCCACAAATATATAGTAGTTATTTTATACATCAAGATGAGAAAATAAAG -GGATTTTTTCGTTCTTTTATCATTTTCTCTTTCTCACTTCCGACTACTTCTTATATCTAC -TTTCATCGTTTCATTCATCGTGGGTGTCTAATAAAGTTTTAATGACAGAGATAACCTTGA -TAAGCTTTTTCTTATACGCTGTGTCACGTATTTATTAAATTACCACGTTTTCGCATAACA -TTCTGTAGTTCATGTGTACTNNNNNNNNNNNNNNNNNNGAAATAGGAAGGAAAGAGTAAA -AAGTTAATAGAAAACAGAACACATCCCTAAACGAAGCCGCACAATCTTGGCGTTCACACG -TGGGTTTAAAAAGGCAAATTACACAGAATTTCAGACCCTGTTTACCGGAGAGATTCCATA -TTCCGCACGTCACATTGCCAAATTGGTCATCTCACCAGATATGTTATACCCGTTTTGGAA -TGAGCATAAACAGCGTCGAATTGCCAAGTAAAACGTATATAAGCTCTTACATTTCGATAG -ATTCAAGCTCAGTTTCGCCTTGGTTGTAAAGTAGNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNATCATCAGAAATACCAATGTTGAAGTCAGCCGTTTAT -TCAATTTTAGCCGCTTCTTTGGTTAATGCAGGTACCATACCCCTCGGAAAGTTATCTGAC -ATTGACAAAATCGGAACTCAAACGGAAATTTTCCCATTTTTGGGTGGTTCTGGGCCATAC -TACTCTTTCCCTGGTGATTATGGTATTTCTCGTGATTTGCCGGAAAGTTGTGAAATGAAG -CAAGTGCAAATGGTTGGTAGACACGGTGAAAGATACCCCACTGTCAGCAAAGCCAAAAGT -ATCATGACAACATGGTACAAATTGAGTAACTATACCGGTCAATTCAGCGGAGCATTGTCT -TTCTTGAACGATGACTACGAATTTTTCATTCGTGACACCAAAAACCTAGAAATGGAAACC -ACACTTGCCAATTCGGTCAATGTTTTGAACCCATATACCGGTGAGATGAATGCTAAGAGA -CACGCTCGTGATTTCTTGGCGCAATATGGCTACATGGTCGAAAACCAAACCAGTTTTGCC -GTTTTTACGTCTAACTCGAACAGATGTCATGATACTGCCCAGTATTTCATTGACGGTTTG -GGTGATAAATTCAACATATCCTTGCAAACCATCAGTGAAGCCGAGTCTGCTGGTGCCAAT -ACTCTGAGTGCCCACCATTCGTGTCCTGCTTGGGACGATGATGTCAACGATGACATTTTG -AAAAAATATGATACCAAATATTTGAGTGGTATTGCCAAGAGATTAAACAAGGAAAACAAG -GGTTTGAATCTGACTTCAAGTGATGCAAACACTTTTTTTGCATGGTGTGCATATGAAATA -AACGCTAGAGGTTACAGTGACATCTGTAACATCTTCACCAAAGATGAATTGGTCCGTTTC -TCCTACGGCCAAGACTTGGAAACTTATTATCAAACGGGACCAGGCTATGACGTCGTCAGA -TCCGTCGGTGCCAACTTGTTCAACGCTTCAGTGAAACTACTAAAGGAAAGTGAGGTCCAG -GACCAAAAGGTTTGGTTGAGTTTCACCCACGATACCGATATTCTGAACTATTTGACCACT -ATCGGCATAATCGATGACAAAAATAACTTGACCGCCGAACATGTTCCATTCATGGAAAAC -ACTTTCCACAGATCCTGGTACGTTCCACAAGGTGCTCGTGTTTACACTGAAAAGTTCCAG -TGTTCCAATGACACCTATGTTAGATACGTCATCAACGATGCTGTCGTTCCAATTGAAACC -TGTTCTACTGGTCCAGGGTTCTCCTGTGAAATAAATGACTTCTACGACTATGCTGAAAAG -AGAGTAGCCGGTACTGACTTCCTAAAGGTCTGTAACGTCAGCAGCGTCAGTAACTCTACT -GAATTGACCTTTTTCTGGGACTGGAATACCAAGCACTACAACGACACTTTATTAAAACAG -TAAATAGATAATATGATTATGTAATTTTAGAAACTAATTATGAATACCGATTTANNNNNN -NNNNNNNNNNNCACTTTTGCTGGCAAGAAATACGAAATTGCAATGACGATCACAGTCCAA -AGAGGTAAGCACAAAGGCGCAGTATGTGATTACTCTATCATTCTTTAGCAAAACCAGGAT -AGGAGTATATGTATAAGAAATATGCAACGCCATCATTTAATGCAATAGACACGACATGCC -CTTTACATGAGGTGGTACAATGTTTTAATATTGTGTCAGGGCAAGTACATGATAATATCG -TTTAAAGATGATGCTAGAGTAAAAGTATGAAGTGAAAGAAAAGGGCAATTGATTGACTAA -GCGGATGTTGTAGGATGATATAGTGGCTCATGATCTGTAAATGATCGGTTGACCGCAGTA -TTATATAATAACATCCGTATAAGTACATATACTACCATGTCTGTTCTCTACATTGCTTTT -TATTCAAGATTATTGGTTTTCCTAACCGCCGCGCCGCGCAGGTACCCCGCGCATCTCTTC -TTCTCGAAGAAAGCGGNNNNNNNNNNNNNNNNNGTATAAATAGTGGAGTCTTTTCCCATT -TAACATTTAGAAAAAAATTCGAATGGAAATTTCTTGCCGAACATTTAACCGGAGACCCTT -GGCGGCTTTTTCTCAGTTTCGTGGGCTAGTACATTTTACCTAGTATGCTGGGAACTTTTT -TTCCGTATTCTATTCTATTCCTTGCCTTACTTTTCTTATCATTTTTTATATAACCAATTT -CAAAAATACTTTTTAACTGTCATAGACGCATTTTGTTTATTACAAATTAAAAGAATCAAA -TATAATATGTGCAATTAATAACTCCACAAGTAGCGAAAGCAATGGCCGCCATTAGAGACT -ACAAGACCGCACTAGATCTTACCAAGAGCCTACCAAGACCGGATGGTTTGTCAGTGCAGG -AACTGATGGACTCCAAGATCAGAGGTGGGTTGGCTTATAACGATTTTTTAATCTTACCAG -GTTTAGTCGATTTTGCGTCCTCTGAAGTTAGCCTACAGACCAAGCTAACCAGGAATATTA -CTTTAAACATTCCATTAGTATCCTCTCCAATGGACACTGTGACGGAATCTGAAATGGCCA -CTTTTATGGCTCTGTTGGATGGTATCGGTTTCATTCACCATAACTGTACTCCAGAGGACC -AAGCTGACATGGTCAGAAGAGTCAAGAACTATGAAAATGGGTTTATTAACAACCCTATAG -TGATTTCTCCAACTACGACCGTTGGTGAAGCTAAGAGCATGAAGGAAAAGTATGGATTTG -CAGGCTTCCCTGTCACGGCAGATGGAAAGAGAAATGCAAAGTTGGTGGGTGCCATCACCT -CTCGTGATATACAATTCGTTGAGGACAACTCTTTACTCGTTCAGGATGTCATGACCAAAA -ACCCTGTTACCGGCGCACAAGGTATCACATTATCAGAAGGTAACGAAATTCTAAAGAAAA -TCAAAAAGGGTAGGCTACTGGTTGTTGATGAAAAGGGTAACTTAGTTTCTATGCTTTCCC -GAACTGATTTAATGAAAAATCAGAAGTACCCATTAGCGTCCAAATCTGCCAACACCAAGC -AACTGTTATGGGGTGCTTCTATTGGGACTATGGACGCTGATAAAGAAAGACTAAGATTAT -TGGTAAAAGCTGGCTTGGATGTCGTCATATTGGATTCCTCTCAAGGTAACTCTATTTTCC -AATTGAACATGATCAAATGGATTAAAGAAACTTTCCCAGATTTGGAAATCATTGCTGGTA -ACGTTGTCACCAAGGAACAAGCTGCCAATTTGATTGCTGCCGGTGCGGACGGTTTGAGAA -TTGGTATGGGAACTGGCTCTATTTGTATTACCCAAAAAGTTATGGCTTGTGGTAGGCCAC -AAGGTACAGCCGTCTACAACGTGTGTGAATTTGCTAACCAATTCGGTGTTCCATGTATGG -CTGATGGTGGTGTTCAAAAACATTGGTCATATTATTACCAAAGCTTTGGCTCTTGGTTCT -TCTACTGTTATGATGGGTGGTATGTTGGCCGGTACTACCGAATCACCAGGTGAATATCTC -TATCAAGATGGTAAAAGATTGAAGGCGTATCGTGGTATGGGCTCCATTGACGCCATGCAA -AAGACTGGTACCAAAGGTAATGCATCTACCTCCCGTTACTTTTCCGAATCAGACAGTGTT -TTGGTCGCACAAGGTGTCTCTGGCGCTGTCGTTGACAAAGGATCCATTAAGAAATTTATT -CCGTACTTGTACAATGGATTACAACATTCTTGTCAAGACATCGGCTGTAGGTCGTTAACT -TTACTAAAGGAAAATGTCCAAAGCGGTAAAGTTAGATTTGAATTCAGAACCGCTTCTGCT -CAACTAGAAGGTGGTGTTAATAACTTACATTCCTACGAAAAACGTTTACATAACTGAATG -TTAAATGGGATCATTAATACAATAGTACTGTACGTATGGCACCTGTACATACTGCGTTAT -AAATGTACTAATGGAATGATATATTAATATATAGTGTGTTTATACCTTATTATTGATGAT -TAGTATATATTTTTATATTTAGGTGATTTTAGTGGAGATTATTTGGTGGTAATTACACTA -GTATACATAAAATGGGTAGTGGATATTTGTATAGAAAGGGCATTACGCATGGAGTTAAGA -GTATTTACATGATAATTGGGGTTCCGTGATTCATTATAGATAATAAAACGTGGATAATAT -TGGGTGTTATAGGTAAATGGGACAGGGTATAGACCGCTGAGGCAAGTGCCGTGTATGGTG -ATGTGGTATGGTATCGAGTACCGATGGAGTGAGAGATGGCCTTGGTGTAGAGTATTATGG -CGGGTAAGTTAGATGATGTANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNTCAATATATCAATGGAGGGTATGTAGCATTATGGTAAGTAGCAC -GTGGTAGATGGGGATTGTAGGTGGATGGTAGGATGAGTGGTAGTGAGAGTTGGATAAGAT -ATATTGGGCAGGGGATAGATGGTTGTTGGGGTGTGNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNGGATGGTGGAGTGGGGGAATGAGACAGGGCATGGGGTGGTGAGGTAAGTGCCGT -GGATTGTGATGATGGAGAGGGAGGGTAGTTGACATGGAGTTAGAATTGGGTCNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGG diff --git a/latch_cli/services/init/example_snakemake/data/genome.fa.amb b/latch_cli/services/init/example_snakemake/data/genome.fa.amb deleted file mode 100644 index ec9ab33f..00000000 --- a/latch_cli/services/init/example_snakemake/data/genome.fa.amb +++ /dev/null @@ -1,228 +0,0 @@ -230218 1 227 -0 62 N -1723 8 N -1735 17 N -4617 29 N -5068 13 N -5624 8 N -6077 25 N -6736 19 N -6947 10 N -8626 8 N -9052 8 N -9223 43 N -11874 60 N -12258 68 N -12468 370 N -12863 31 N -12998 137 N -14459 14 N -14655 9 N -14768 53 N -16863 13 N -16900 51 N -18744 19 N -19105 36 N -21611 10 N -22229 310 N -23239 13 N -23705 55 N -24306 60 N -24688 91 N -25028 31 N -25163 137 N -25393 1754 N -28278 29 N -28683 8 N -29283 10 N -29737 34 N -29885 8 N -30097 11 N -30988 26 N -31035 13 N -31116 30 N -31483 38 N -31542 25 N -34990 9 N -35113 28 N -36421 24 N -37242 29 N -42085 17 N -42743 64 N -42838 11 N -45263 10 N -45359 10 N -45634 16 N -47581 17 N -49978 14 N -51804 21 N -55045 46 N -57901 18 N -62608 21 N -65534 8 N -65614 13 N -65681 18 N -65761 10 N -67715 41 N -67975 10 N -68114 25 N -69662 65 N -69734 8 N -69819 24 N -69967 26 N -70179 22 N -70534 40 N -70858 10 N -70906 22 N -71116 12 N -71530 13 N -71572 8 N -73312 53 N -74863 8 N -74928 18 N -74999 14 N -75597 9 N -76623 49 N -76689 79 N -76975 87 N -77494 48 N -77569 30 N -83197 20 N -84701 10 N -87769 74 N -91990 8 N -92291 23 N -92429 9 N -92578 36 N -93831 51 N -94372 8 N -95568 36 N -99005 8 N -99937 32 N -100007 14 N -100363 44 N -101242 15 N -101281 24 N -101450 54 N -102967 8 N -105405 8 N -106011 9 N -108643 8 N -108698 60 N -110507 28 N -110695 42 N -112740 52 N -113050 54 N -113285 33 N -116146 51 N -116283 22 N -116416 100 N -117394 9 N -118304 66 N -118468 48 N -119651 53 N -120119 66 N -124924 30 N -126866 29 N -128103 14 N -128187 17 N -128571 31 N -130613 8 N -130638 18 N -130783 14 N -132933 51 N -137539 48 N -137620 9 N -138751 237 N -139260 9 N -139346 10 N -139404 14 N -139548 59 N -141889 40 N -142085 10 N -142288 22 N -142506 17 N -142872 21 N -143188 85 N -143575 12 N -144416 8 N -148420 8 N -149619 45 N -151325 26 N -151473 96 N -151618 8 N -152012 28 N -152096 28 N -153971 8 N -154817 11 N -154847 10 N -156693 10 N -160003 8 N -160104 132 N -160237 5925 N -169210 44 N -171866 10 N -172008 23 N -176476 60 N -176580 28 N -178459 10 N -179139 8 N -179225 11 N -179980 8 N -180275 10 N -182509 9 N -182619 340 N -183141 324 N -183600 31 N -185825 34 N -189215 32 N -189425 335 N -189970 8 N -189991 20 N -190135 31 N -192291 52 N -192463 49 N -192551 20 N -193920 116 N -194576 31 N -196008 51 N -196460 11 N -198368 8 N -198638 8 N -198840 30 N -198906 11 N -199001 8 N -199908 21 N -202399 9 N -204232 2420 N -206756 83 N -207233 65 N -207622 89 N -208278 13 N -208753 11 N -209460 318 N -210385 9 N -212970 38 N -213350 19 N -215376 31 N -215433 9 N -216383 9 N -217481 40 N -217625 8 N -217815 14 N -219193 35 N -220004 40 N -220642 64 N -221035 10 N -222296 51 N -222934 8 N -223127 36 N -223470 26 N -223707 14 N -225080 18 N -225394 49 N -226914 17 N -227416 17 N -229760 56 N -229955 31 N -230092 124 N diff --git a/latch_cli/services/init/example_snakemake/data/genome.fa.ann b/latch_cli/services/init/example_snakemake/data/genome.fa.ann deleted file mode 100644 index ef6c0b1a..00000000 --- a/latch_cli/services/init/example_snakemake/data/genome.fa.ann +++ /dev/null @@ -1,3 +0,0 @@ -230218 1 11 -0 I dna_rm:chromosome chromosome:R64-1-1:I:1:230218:1 REF -0 230218 227 diff --git a/latch_cli/services/init/example_snakemake/data/genome.fa.bwt b/latch_cli/services/init/example_snakemake/data/genome.fa.bwt deleted file mode 100644 index 9c42a579cb7eb2df36c3de6674c8300be20a41af..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 230320 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 z -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

  • Rdy?r-DxfUko0tN%CwY zP$NS&9^ZOlj_XH4RikKr_xqY$7o2ir?ZTV^e;s@-_|8A^m6Bdfc%*4{4yp!_pT*f5 z>M>_&cIj{2-^C9Ik@SXg@TK7IgP#SzrMp0%Z2aBv_iJG4>r%%k@wb_R_IveFPLWg} zp4$4q+2C2=E5Tb-$@5YY_96zMdKxOD5k!^$`xyoXAA-fJ{Ro=GIIqb*Qkn$(F!*Nh zfA)3c-Ct&_S~XL zHMiPPdtSwdE`D3I%Jns(c>F&ajT^N*9Nw3Cf;VuGkE1}4e?9=8nRJ^c(j!NOBBu)@ zFo$JE1g{?>^Ni*c_4ZOS3S8#z1MdiaG5A*Sj3OH~6obL<{kiBnK~*m%?IOAJUrEp922Rz77qWZmK;Yy(IFrM%_}+ z_B719IcKy>q;U{S-?aKiWq=F#eDK%7=R*8Mx0%~95|U0`j5vr8eArNI%P?rYEo9Q; zmePBA$?1E*zXbmTJQchQ&5<;R;sgjK08eY~7M4a75}c{Tfp#tPAo7mD_2S%t|NapCdLdOfhhY;?WA5R7F*|8pC4|t9{}6^GT_Ysei>S5^yeD`I z@E^cqS2$>4OoV=6(?rL$!s*M^sU4;(EpZFHLI%8SaAydy;CF&|0Y3%4H`2R9ll#H8 zEr5XSta;Yd;1+ZhU+phj6y{??U-RzvRq$!x{lObUU;cB-w+H5K4TwY*NhT##CrZwJ z)zv|r<-8C)Q2zbDs<##3Z-S2k9{_&qP}X#?dtA%3ABNLLQR0lOsFP&7@un!F_QwqB zYzjVsuLPd}J{f%ELiL)My)i+*cN~(Hx-oe7mDHy`Ik(llR6=i)ZZGbWf&UEt0{FY& zf9}$sLKYUZXXuvouN^_q3NahqUG&TLXfRHEwAE)dn!T4_FERLh@C@+0q@7=nQH5hJ zYCMY#*Ilpo=sOF9sgx#>cfo^4TzhR#@Qc>S$9V&u3%)6*w~k~^rBjAkbdA6gUhZ85 zCJ8~&*WD3~E&XzR@_*o0foFkV4t;gpRI4wFnU!(Mp;T(sk%Ah?x^^hsXGQ+37dkwp zd-I<2;Df*qgI@=JhG@y*Qd{=c?~7%bXw3cM1@8Oh9v-XcTu->1=tDpM6#NnJGvH&v z^AZ-Ncl#&Vl)RhQy=j~wI6G{udWn3yt-@JI&anDPVuHT_UdK(IhnwJ^aA?Qwk~p68 zEa&!r_G#+Umh8MXYuYfz=$Vgm`a8D!7x<^(SA(a5AJkJ7i!da%N&WE@Rz7x$6|QxW zMR&5zB8<)>&ZDyye2~YZgLeim1fR&QOQyV6km*Ys%b2$01m)f%yAYl!CW|wy-8%Ax zXb*k>{08uU_7$)`d2LqSznNq-yncu?x}zrk(f@c{hCpy6zD4;!6UE&RJlaVM7w1|Vs34iXM?iCkDz6TJUkd&t_|xD!_w2$tb;(|M z|G3__2DSLEEcr(E1TEq15qi!e3Gna0i@^s=vI3npF%Oha;+rxWyHCve<-V~Kb-yhc6!st7x%NK}_-o+5f?o-J z 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

    p^IBb5`}zL)%PBJ7e58JJSWUjpKZworh%>R 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 QWcyk9or>KL|0;t1A3WpVdjJ3c diff --git a/latch_cli/services/init/example_snakemake/data/genome.fa.sa b/latch_cli/services/init/example_snakemake/data/genome.fa.sa deleted file mode 100644 index b0d66d28356e837e97b6a3789603cae9c92c8b35..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 115160 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 z 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

    J3m=v7IF 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 diff --git a/latch_cli/services/init/example_snakemake/data/samples/A.fastq b/latch_cli/services/init/example_snakemake/data/samples/A.fastq deleted file mode 100644 index 4686190e..00000000 --- a/latch_cli/services/init/example_snakemake/data/samples/A.fastq +++ /dev/null @@ -1,1000 +0,0 @@ -@SRR800764.1 1/2 -CATCTTTGGAGTAACTATTATTTCGCCCCTTTTGTTTGCTGCATATCGCCCCGCTCTCTGCATACACGATTGGATAATGACCAAAGCAAGGTTTAATACGC -+ -;:8:DDDDH>F+AEHHGIGECHJGIEHDGHGIHIGIIJJDHGJJGGGEBEFFHG>H?HEFBDBCCCCBDDDDDCD>CACC@CCD@??CC??((49CA:@FF?AABDEF9AEFHHB:CD<BDFFFG)=CHHECA;CE5;B;DE<@;@;;=;?B=9AC(:@> -@SRR800764.3 3/2 -ATTACTCATCAAATCATGTACGAACTTCGATGGCAGTGAACCAGTTGGAGGGCCATTGCTGGTTTCAGGGCCGGAAAAAGTTGAAGGGGGGCGTCCGGTTA -+ -@@CFFFFDHHHHHIIIJJIAIHIJJJGJGFAHIIIJJJFEAH8BF@GGEHGGGGCHJJCHIIIBEE>?CHFFDD;=B?98:>C>CDC@05<&959@9>059 -@SRR800764.4 4/2 -TATAATATTTTTTATTTTTAATTTATAATATATAATAATAAATTATAAATAAATTTTAATTAAAAGTAGTATTAACATATTATAAATAGACAAAAGAGTCT -+ -<:+A:DADDAABH;CFEGH@BC,ABH>@HHCBBF9BFHI>CD@4CGCGGGH<4DBFG49BF??DGC3==FGGGA4CGCE4CG>DGCD>??EF>@BDB#### -@SRR800764.5 5/2 -TATATATAAGTATCCATTTCCATATAATCTTTTAATAAATATTAATAAATATTAAAAAAATAATATTATAATATTTTAGTATATAATTCAATAAAATTCAT -+ -@C@FFFFFHHFHHIJJJJJJJJJJJJIJJIIIIIJJJIIJIJJIJJJJJIIJJJJJJJJJJGJJIIJIIGIJIJJJIIJHIIGHHGHHFBDDFFFDFEEEC -@SRR800764.6 6/2 -AAATTGAAAAATCATAAATTAAAAAAAAAAATCAATTGAATTTTTTTTTTTCATGATTACGTTTTGACATTTTTCCTTTTTTTTTCTCTTATTACGATTTC -+ -CCCFFFFFHHHHFGHGIIJIJFIJJJJJGG<2)=3B@9C)=DGGIHDDDD@((9:(::(3(8??<8+44>ADDA9(:>CCDDDD################# -@SRR800764.7 7/2 -TCATGCGAAAAATGGATTGTACACAGATATTAGTCCCACCAGCTCCAACGGAAGAAGATGTTATGAAGCTCGTAAGCGGCGTTACCCAATTCCTTACTTTA -+ -@;@DF+0+@@?C:AB<++2222A+<3*11?C**1:???D:BG2DHC9B;(77;ACF############################################# -@SRR800764.8 8/2 -TACTCATTCCTAGCCTGAAAATCAAAAAGCTTGGCATAAGGGGTATGTACATAGTCTTCATGAAAGAAATGGAAAATTTTTTCAAGGGATGGCTTCACGGT -+ -@@@FFDDDHHAFDEHEECGEFHGHHGGIGGHBHFBGHHIIIHD)?BDDFB9B@CHGIGGIIJBFHFH;@CGEEE;=AA:@CCEEC;A@BC=??CD?:((9B -@SRR800764.9 9/2 -GTTGTCATTGGAGTTGTAATAGTAATTTTTATCGGATTCATAATTATTAGAAACAGACGAAACGTGAAAAATCACAGCAAAAAGGGCTTTAGCCATGATAT -+ -??@DADBDHFHHFIJJGEJ9J?3CDECBEHGDBBF7)?E6ACFCCFFCE9A8?=1?5>>@@@55>C3@@ -@SRR800764.10 10/2 -ATTACGACAATTTCAGTTCGAAGTTGGAAGAGAGAATTTCGCCCTGATCCATGTTTCACTTGTGCCCGTCATTCATGGTGAACAGAAGACGAAACCCACCC -+ -@CCFFFDDHHFHGJGIHIGIDDHEHGHIJIJIJIJJIIJJJJJJHIBHHHHIJJJIGIJJJJEGHHGGDEDEDDEDC@>@CCDDDDCCCDDD9<@BBDDD5 -@SRR800764.11 11/2 -ACATACCTATCTTGGCAGAACAATTAGGTATGCAATTTTTTGACCAACAGTTAAGCGATTTATGTNTTTCATGGTTGTGGGATACTGTTTATTCTATCAGA -+ -CCCFFFFFHHHHGJJHGHHIJIJJJIIIBHHIIGIJJJJJJIJJJFIJIIJHIJJJJGIIJJJJE#-;BEDDEECCDDDDDGG?F>;;B>D8*9==>*9BGIJI*?F@GEBBB=CFGICGGG>;EGE>AECCHDD?DDFE@@CEE;>@CD -@SRR800764.17 17/2 -ATAATCGTTCGTTCTGTTGATTTGGCTACTTCTGGGGAAGTCTAAGGGGTGTTTCTGAACTCTTTTATTTTTCGTCACTTTGTAGTTATGTGCGCTAAATG -+ -??@DDD722+@?A:E+CB@,,<:+<+2A?19?FHGGB1?F9DF*BF?BD(-;().=@AHI).7=EE################################### -@SRR800764.18 18/2 -TAAACAAGCTGAGCATCTTGGATTTAGAGGATAATAAAATACCCAAAGAAGAGCTTGACCAAGTACAGAGTTATACTCCATTTCATACGGGCATCCCCAAA -+ -@@@DDDFDFHHHGHIEICGHID@HGIGIJJAHIJJGGCHEGIJJJJIJHJFFGIIIJJJJJJJGHGGIIGDHDHGHGHHFEFFBCF>CABDDDDDDDD9?< -@SRR800764.19 19/2 -AAATTTTCTATACTGTTGAACAAGATCTTGCGAAGAATCCTCTATAATCTTTTGAATCAACTCAGAAAGAGATCTTTCCAATTTATAAGTATTAAAAACAT -+ -@@@DFFDDHGHFDHHDGECCGGGCGADGHABF?FHEGGHACA<@9??BGE>>ACD?B@ -@SRR800764.20 20/2 -CGATGCTTGTTCATCATATTTTGTCAGACATTCTTCTTTTAGCTTCACTAGCTGAGATGTTAAAGATCCCAAGTTACCCTTTAAAGGAGCAATCGATTCAT -+ -@@;:??ADD:DCDDGHJIIAGICGGIGG=C@AHGAEE>;?E;B;?=>A@;;ACCDC -@SRR800764.21 21/2 -CTTGTCAATTTCACTTGACTGTTCTTCTAGTTTTGATGATTGTACGGCAGAGGGCGACATAACACNGTGGGGCAATGTCTTTCTAGTAGTTTTGATATGTT -+ -@B@FDDD?DBFBDBHHEGIGE?FFEEH@EE?AEBGBHGHGGGCIIHGJHHG=1?AFE>AECEHDF#,,(5=@B@?CD@D>@>@@CCD>C>@DABDCCDC@@ -@SRR800764.22 22/2 -AAAATACATATTTCATAGTCTTAACGCAAGCGATGAATTAACCCAAGTTAAACTTTTACGTTTAAGTGGTCCAATTGGGCCTTTCGCTCCTTTGGTTACTC -+ -@@@FFDDDHHHDDGIJJJCJHCHHFGIIIEGGIGIGIJJ############################################################## -@SRR800764.23 23/2 -TCCTTGTTATGATGGGTGAAAACGGTACCGGTAAGACCACTTTGATCAAATTACTAGCTGGTGCTTTGAAGCCAGATGAAGGACAAGATATTCCAAAATTG -+ -CCCFFFFFHHHHHJJJFHIHJJIJJHHJJJJGIJJJJJIJIJJJHIJJJJHIJJJJJJIJJHIFIHHHHHHHFFFBCECCEDBBDDDDDDEEEEECDDDD@ -@SRR800764.24 24/2 -AATCATATTGTTTGCCCATGGATACCAATCTTTTTAAAATTAACTCAATTGACGTACCCATCAGAATAAACTCAACTGAAGAGATTGAATATATCGAGTTG -+ -@CCFFFFFGGHGFIJIJGIJJIJJJIGIJJJIJJJGIIJHIIJJJIIGJIEHHGEFHIIGJJFGIJGIIGIIJIJHFH>ABDFBBBCEEDEEEE@@B?>CDCEDE@CDDDDBDCCDECDDC# -@SRR800764.28 28/2 -CTTGTTTATCCTAGTTTGGATGAGGATCCCTTTCTTGCTACGTTGTTTCACAAAAAAAAAAATAACAAAAAAAGACGGCTACGAATAGTAGGGTAAAGGAG -+ -@C@DDFFFHHHHFIICHIIGGJIEGGGECH@HCHIIEIJHCDBFFHHGHIIJJG@@@EEFCB;ADCD@ABDDD@?C9>B@030-+:>@?9>?C>C<8 -@SRR800764.29 29/2 -ACCAACGATATCTTGGAGTATATCAGAGAATTCCGTTTGATTATGGATGATATTTCTCAGAATTACAATGTCAACTTTCAAGATGCAGGGGTCAAAAGTGC -+ -@<=ADDBD+<<CCCH=D;)7)=>CAACE>BD);'9'9;>(;CCAC -@SRR800764.30 30/2 -TGAACGGTCAAAAGATTGTCGTTGTCAGAGCTGAAGCTTTGAACATTTCTGGTGAATTCTTCAGAAACAAGTTGAAGTACCACGACTTTTTGAGAAAGGCT -+ -?@B7DDF+BHGIHIIJJFEHIJEHECEC.;?7;?;3A9=ACDB??B>C#### -@SRR800764.31 31/2 -TGCTTTTGTTCTCGCTAGGCGAAAGCTCCCTAAAAATATCCGTAGAATTTCATATGACACAACCAGGCCTTGATGTAGACGTCAAACTACACATTTCTCAA -+ -CCCFFFFFHHHHFIJGIIIJJJJJ>DHGIJJJJJJJJJJJJIFCGHG>DHGGIIIJIJIJJHHHFFFFDECEEDDFCDEDDBBDBCCDDDDCCCA>CCDEC -@SRR800764.32 32/2 -ACCTCTCTTATATAGAATAAGAAGATCTGCATTTATTCTTGATTGACACTACAGTTCAACAATTAATTATCAACAGAATTAATTACCACCTATCGTTCACA -+ -@C@DFFFFHHHDHJIIJIIEHGIIIJICHHCHEHIGGIJIIIGHHIIGCFHHGIFEHIGIJIIIJJJGIIIGIIIGIIJIIIGHHEEAEEDEFFD@BCCCD -@SRR800764.33 33/2 -GTTGCAAATACAGCTATAATGGTTTGCTTCTGGTCCTCCAAGCAGGACATATGTTTCCTTGAAGTTCAGTTGCAGTAGTTGTGCACATGCAGTTTTTGTTT -+ -@BCFFFDDFHHFHIJJICCHJIBEHGIHHIIJJDFGHGGEHIJIIIJIJIIJIGIHHIIJIGHIFHGII@FHJEDC@D=CHEHECDFFFFED@CECDD;A5 -@SRR800764.34 34/2 -AAGAATCATTCCACGAGAAATTCGGTGACTCTAAGGCTCTTCAGCTATCACAAGTCATTAGATTCTGTAAATTAAATGCGTCATCGAATTCATCATCTTCG -+ -CCCFFFFFHHHGHJJIJIIJIIJJJAGEHGIJJJJIIJJJJJJJFHJJJJJIGIGHHIJJJGIIIJJJIIJJIGEFHGGFDFDDEEDDDDCCEECCDDDED -@SRR800764.35 35/2 -TTAAGAAGTTGATAATTTCCCGAATTTTGCATAATTTCTGTCACGTTAGCAAATAAATTTTCGACNTTTTCAGAATGAGGCAAAATAGATATGGAAATGTT -+ -;B?:?DEBHD,:A,<<2,,,>7)5AAE@;(5>@########### -@SRR800764.36 36/2 -GAGCAAGTGTGTTGATGTAGTATAGTAAGTCAAATCTAAATTTATATCCAACATATGACGCTAGANCAATCAACTTTTGCATTTAATGCACTTTCTCTTTG -+ -?BBAAAD=C=:DDFH@E:ID:@=?E)?=E;BD)7?C>C;;;ACDC;;A> -@SRR800764.37 37/2 -AAAAGAAGTAACGATTTACATATCCTCTATTCCCTTGCATTTACTCCGGGTCTTCGTCTTTACTGNTTGGTCTGGGTATTTCTAACATTCTAGTCCGAAGA -+ -@@@FFFFFDFFHHIJGIJIIHIIIJGIEIJJJJIJIJIHIJIIJGGFEGIFHCHII@CFHHGIGG#-;?H=@@>DE(6;@BDDDDCC@@C>ACCCDB@?B@ -@SRR800764.38 38/2 -GGAAATATGACCATAAAGAGGTCCTGGTATTGGTTGAATTTAATAATTTTGCGGAATGTTTCACTTGTGAACTTTAGATCATCAACAATTGGTAACGGAAT -+ -@CCFFFFFHHHHHJJJJJJJJ?FHIJJGIJJJIGHGIICFHIJJIJIJJJIIIIIJJJFHJJJIIIJGIIIHHHHGHFFFFFFFECEDEDDDDCDCDDDDD -@SRR800764.39 39/2 -ATAACAAGGGTCTGCAATGATCTTGGACTAAATAAAGGTGTCTTACAATCCCAAAGAGCTTGAATCATTCCTTTTATGAGCTAAATAGCACCGTTTGCACT -+ -@@?>C########## -@SRR800764.40 40/2 -TTTAATATAATAATAATAAGATAATTATCAATAAAAATTACATTTTGTAATTTTTACGTTATATANATAAATTAAGTATATATATAATTATAATATATAAA -+ -CCCFFFDFHHHHFJJJJJJJHJJJJJIJHJIJJJJJJJJGFHIIJJJHJJGIJJJJHIHIJJIJG#-BD99 -@SRR800764.42 42/2 -TTTCTTCCCCATGTTTTCCTAGCCTTCTATGCTCAACACTAGCAGATCAAGTTTCTCGATTACAAACTTGTTTCTCTGATACTCTACCTCTCTATGCTAAT -+ -CCCFFFFFHHHHHJIJJJJJIJJIJJJIJJJIJJJIJIIHIIIIGIJJFIFFHIJJJJGIIJIIIJIIEHDHIGIGHEHHGHDDFEDFEEEDEEDDDDACC -@SRR800764.43 43/2 -TGTTGCTGTCTCCTTAGAATGTGGAATAAATTAGCAGGCGTAGTTGGATAAACAACCTGGAAATTACAATCCTGATGTTGTCTCTGTAGCTTTTCTTCAGA -+ -@@?DDDFDHFFFBFH@GGGHGHGEDGHFGHII>HIC>FH2C;;CGAHHGCCEE=BDCC>DACCCA>@@@C>CC@CCC@@3 -@SRR800764.44 44/2 -TCCATGTCCATAAGGTCGAGTGCGTTAGATGCCGGTTGAGGTGGTGGAGGGGGAGGCAATGGCGGTTTTAGGTGTGGAGACTTGGGCTTTGGGGGCAGTGG -+ -@@@DDBDDFBFHHEH?B@)@3ACFAFCGDH?AFHGDGH>BB9?C-;5CFE'5=3;>??>3@:@>8?@<(2+:@>?((+94?9@@@##### -@SRR800764.45 45/2 -GAGAAGTAAGTGGGTAATGAAAATACTTCTGGAACGACAAAGTCATAACGTTACCAGATATGAGGCCTTGGTCCAACCCTGACAGCGAGGAAACTAGCACC -+ -?B@FFF=BFF=CDEFHGEIEIGFHHHJGHIJJJJJJGHGGEIFGGHEIIHGGIJJJJJIJJIGIJJGHEHHGFFFEFDDACCCDDDBBDDD@CCDDDDDDB -@SRR800764.46 46/2 -TTAATGTTCTTTCAAGTGATCTCCTCGCTTGATCAATCCTTCCTTTTTTAACCAGCCACCATGGAGACTCTGGTGCAAAAAAAATACCTACCGCCAAAGGA -+ -BCCFFFFFFDHGHJIJHIIGGGHIJJIJIIJIJJJIJJIJJFIIJIIJJIFGGGGIIJIJJIIFGIGHGHHFF@CEFEDEDDBD?CDDDDDBDBDBBCDC? -@SRR800764.47 47/2 -CAAATGGCTTAAGAGAAGAAAAATCGAGAAGTGCCTTAGAAAAAGAATTCGGTAAAGATATGAGGATAACAGCTGCAGACCATTTTGCCGTCGTCGACTTT -+ -B8@:+A;:+A++AA -@SRR800764.50 50/2 -TACTTATTATAGGCGGTTGTTATTAACAGCCAATCCAGACGCAGATATTTTTATACTAGGAGAAGATACAGCCATAATAAAGGTAAATATACAAAAAATAA -+ -C@CFFFFFHHHHHIJJGIIGIGJJJJJJJJJGJJJJIJJJIIJJIIIIIIHIHHHHHGEHFFFFEDEDEEDDDBDDDDEDCDD:@CCADFEDDDDD?@ACC -@SRR800764.51 51/2 -CAAGTCAGGAGTCGGCTCCGGCTATTCTGGGTTAGAATTTGACGATGAGGATAACAAATCTATCGACTCTGAATTCAGTGGAAGCGCTAGTCTTTCTCAAA -+ -##################################################################################################### -@SRR800764.52 52/2 -GAGTAATGTTCTTTGGCAAATTATGTATCATTGCAGAAGACATCCGCTTGCATTAGGCTTCAAATATGTCGAGAACTCCTCCCAATCGCACGAAAATGAAA -+ -?@@+BDADFAFHGIDGHEIFFHH@AFIGDADE>AHGH>>AAHCEB:BHIB=9?DFAGBGDEE@=BG@@CEH?G@:CAAABDCD9>@>A?=@D@B8@>44@: -@SRR800764.53 53/2 -ACCTCAGCTTTCTGTTGGGCAAAAGACCATTTAAGAATAAATCCTTCAAAGCGTTTAAACTCTGTAAAGCAGAGTTTCTCGATTTTTTGCCACAATATGAA -+ -@?BFBD>DHHHDH>HCBC@ -@SRR800764.54 54/2 -TATGCCATGTCCCGGGGACAGACGCTAACAATGAGGGTATGATCGCGGAAATAGATTGAACTGAAGTATTAGATGGCGCATCCTGCAATACAACAATATTT -+ -@BCFDFFDHHHHGIIJJBHAABDCCC>@ -@SRR800764.55 55/2 -ACTCCACCGAGCCGCAGTTCGATGGTCAAGGAAGCGCTGAACGTACTAGAACACTAACCAAGAGGNATAGCTTCAAGAGGACTAGAATACTGAAGGCTCGA -+ -CCCFFFFFHHHGHJJIIHIIJJIIJHIJJJJHIJJJJJJJJJJ@=CGGFHEHHFFFFFEEDEED?#,;?BDCDDACCCDDBBCCDCACDCDDC@C>ACBD5 -@SRR800764.56 56/2 -ATCCTGGTGGGCTTCAAAATATTGTGGCAGATTTGACCTTTATGCTTTTGGGCTGGCTTTTCAGGCTATTATGTTCTTCATTATCGGTGGTTTAGGATGTT -+ -CCCFFFFDHHHGGJJJJJJJIJJJIIJJIIAHIIIGHIIFIGGIIIJJIFGHGGEIIDIJIGGIIHFHHHGFF@DFFFCEDEDDCDD5?@88?CDD:AC:A -@SRR800764.57 57/2 -CATGCAAACATCTCGACTATTCTGGCGATAGCAGTACCAACAATCACCAGCACAAATTTTGTCACNTGTGCTTTGCTAGAGTTACTTCAGTACTAATTAGA -+ -CCCFFFFFHHHHHIJBHHJJIJJIIIIJIIJJGGHIJJJGGIJIIJIJIFBFHHJJJJIIJGIHH#-;@DFEDEEEEEDDD>ACDDCDBDCDDEEDCDEDC -@SRR800764.58 58/2 -TTTTTTTCCCTTCTGTTTGGTATCTGATAGCTCTAAACCAGATACAATCCTAATGAGAGGAGGGACTTTAGCCTTATCATCGCTATCGACACTATTTTCTT -+ -@<@DAADDHBHFBHEEDH@EGGIJEEBGHJGGHIGIIJGHAB?DBGCD>=7=FHACBACDDCDACBBD:AB5=@94>(4:CDDD -@SRR800764.59 59/2 -TCCTCTGCGCATGTATAGTTAAAAAATCGAAGAATTGGATGTAAATTGATAATTGGCCCGTTTTTAAAATGTCTCTCCCATGTACTCTAGAAATATATTCC -+ -CCCFFFFFHHHHHHJGIJJIJJJJIJJIJGHHHIJJJJGCHDGGEHIJGCHIJJIJJJJI@EHHFDFDEFEBEECEEDDDDDDEDEDDACDDDDDEEDFDC -@SRR800764.60 60/2 -AAAAAATGTGATCTTCCTTTCATCAGAAGAACAACTTGCTGCTAACGCTCTTGCCATAAGTGTTTTACCCGTACCAGGAGGACCATGGAAAAGAACACCCC -+ -CCCFFFFFHHHHHJJJJJIJHJJJJIIJJJJJJJJJJJJIJJGJJJJIJJHIJJJIIJJIFHFHIJIJJHHHFFFFEDDDDDDDDCDDDDDDDDBDDDDDB -@SRR800764.61 61/2 -AAGCAAAGATCACGTGCTAAATCGCAAACATGCTCGTCTACGGGTTATAACAACAGCAGCATTCTGAAAACGTTTGGCATAAGCTCCAAAATTTCTAATTC -+ -CCCFFFFFHHHHHJIIJJIIIIJJJJJJJJJJJJJJIJIJJGJIAGGIIJHIJJIIJJHHHHHFFFDFFEEDACDDDDDDDDDDDDDCCDDDDDDEEEEED -@SRR800764.62 62/2 -CTAAACTAACACTTCAAGTAATTCAAACTATGGTATCATGTTTTTCTGTAGGTGAAAATCCGGCCAATATGATATCCTGTGGGCTAGGAGTTGTAATCTTA -+ -CCCFFFFFGHHHHJJJJIHHJIIIIFGIGHGIIFHIGIIIFIIIJIIGGIHHBFHHIJEGGHIIGIIIJHGAGFFHDFHHEFFCEEACAC;>C;@DDEDAA -@SRR800764.63 63/2 -GATCATACTTTTGTTTCTTGGTGGTTGCTTTCAAACCCTGCCATGGCAAAGAACCCTTACAAAAATAGATCAAGACATAACCTAGTGATTCTAAGTCATCT -+ -@??DDDDDHHDHBBEEDBAIF:CF@DEHBDEFIEFHGHIJEGHGIHGIDHAFG;FGHJJJEFEEGEEAHC>EEFFFEDCCCCACC>>;@CDCDDCDCDDCC -@SRR800764.64 64/2 -GAAGTGGGATGGGATGAGATGATAAGAGATATTAAATTGGATTTAGATAAGGAGAGTGATGGCACACCCAGCGTGCGTGGAGCACTAAGGGCACGTACGAA -+ -@??DBBADFHHHHBFEIBHEHIICHIECAEGIIEIEGHBA?FDGGDFGGHFEIIJIBDFC4C;@CHIGGIGHB?<=BCAD@CDCDDBDDDD?A@@# -@SRR800764.65 65/2 -ATGACAAACTACCTTATTACATTGTAAGCACATTTCCTGCTCTATCAATACCAAATTTGCATGGTAAATACATGCCTTTTTTGAAATAACATTTCAGCTAT -+ -C@CFFFFFHHHHHJJJIJJJEIIJIHHIJJJIJJIJJIIJJJJJIGHIIJJHIIHHHIIHIIJJBGDGHIJJJJIJJJJJJGFFFFDEEEECDDEECDDDD -@SRR800764.66 66/2 -TTAGCAATGATGCCTTTTCTTTTTCATTTTTTTTCGCCAAAGGAAAAGATGTTTGCAATTGTTTTAACAGAACATCTTTTATTGGTTGTTCTACAATTGTT -+ -@CCFFFFFGHDFHJJIJJG@HGGGGIGJIJIEIIIIJBHHIJIIGIGIIJGCEHCEEHGDHDBCDFDCEECCDDDDDDDCDDCCC@BD=AC:4>ADCCCA> -@SRR800764.67 67/2 -GTCATCAACCATTGCAGATAATTTGTTCTGTCTTTTGAAGACATCTGCATATTTAGCCATATCTTCTTCATTTGTGAAGTCATCGAAATAACCTGCATCCG -+ -@=@DDDDFHHHFHIIIJHIIJICGH??CFHDFFHHIJEGFHGIBB?DBBDD@*??4D?DAGCCIJGIIDGHDEH@AFHHEHIIGA;CE=CB7?;>@@C>A6 -@SRR800764.68 68/2 -TAATTATATTAATTAATTAATAATATATATAATTATATTATATATTATATTTTTATATATAATATATATAATATAAACTAATAAAGATCAGGAAATAATTA -+ -@@@FDFFFHFHHGJJHIJJJGHIIJJJJJJIJJJIIIJJJJIJIIGJIIIGIIJJJJIIIJJJIIJIIIJGIEHJJJJGIIIJIIIIHIJIJJIJFHAAHE -@SRR800764.69 69/2 -ATTGCTGAAAACAATCATTGTTGACAAACAGGAAAAGGTGCTGATATTTTCCTTATTCACTCAAGTCCTGGATATTCTAGAGATGGTTTTGTCCACCTTAG -+ -@CCFFFFFHHHHHJJJJJJJIIIJJJJIIJGIGHJJJJ?FEHJJEIJIJJIIFJJIJJJJJJIHJFHIJIEGGGIJJJHHFHFFDF;?BAEBECCDDDDC@ -@SRR800764.70 70/2 -GGCATCTAAATGCAACTGATCCAGTAATCGATCAAATAGGAAACATCGACGGTTTTTCATTACTTTTGAACGATGTGGAAGTGTACGTAGGCAAGAATGAG -+ -=+=???DDHF;;;5@:@ACA############ -@SRR800764.71 71/2 -CTAAACATCAAACATGTTATGACAAGTGGGTGACGTTTTCCCTAGGCTCCTTTCCAAACAATTATNGAAGAGTTTTCCGAATTCGCGCCCTAAATCCCAGT -+ -BCCDDDEFHDFHHJJEHIGIIGGIGE;?ACDDD=B@5CDDCD3 -@SRR800764.72 72/2 -AGAACATACTCTGGGGCTGGCGTAGGCACAAAATCCGGTATTCCTAAAGTTTTGTGGTACAAAACTCCATACCTAAAACACAGAACAAATCTCACCCGTGG -+ -@B@FFFDEHHFFAC@?8CFEHBHHIIBEGGBGHGEFHB(A>D=>CC>G3;=??EEFFFB3>;AE>CCDC@ACBA<<955,98::+:@CDA#### -@SRR800764.73 73/2 -TATTCCTTCGTTTCACGATTTAATGCCCCTTACAGATGATGCTATTGCCTTGGTAATAGGGGTAAACAATCTTTTAGAAAAAACATCAGAGTTGTATCCCT -+ -BCCFFFFFDHBDHIGGIJDHIIJHJJJJIICDGAFFHGCIIJJJGI@@DFD?FFGHIIGGDG@FFGHIJIJGHHHHDBCFDFDBDDCCD@C:AACCD3;CC -@SRR800764.74 74/2 -CCTTCTTTACTTTTTTTTTTTTTTTGGGGATTTTTTATTTTAAAAAATAAAGAAACAAAATTCTTTTCTTTGTTCAAATTCCCCCCTAGTTTTGTTTTTCA -+ -CCCFFFFFHHHHHJJJJJJJJJJJ############################################################################# -@SRR800764.75 75/2 -AGGAAGAATAAACTAATTGCTAACTCTACTCCAAGAAACCCAGATCCTTATGGTTTCGAAGGAATNTTTGCCAGGGATATTGATACTGGCGAATTGCTCTC -+ -1?@D;?B+A22AFE@DBAFHIGGIGGGIGGEDCH>?ACAAA3>???D?ACDA:@> -@SRR800764.76 76/2 -GTGACGCTATCGACACCCGCATGACAGAATCTTAAGGCAATGCTCGCAACTTTCTTCCAAGATGCGTGAAAATGCTTATAAGTCTTACTAAGCTATCAAGA -+ -?===BDFDHHBHDGEAEHHGGIGGA@DHGGE>CCC:;@;@CDC>CCC@CCECC9>@>C@CDD -@SRR800764.77 77/2 -CGGGGCGGACCCCGAAGGAGTTTGGATAAAGAATATAAAGAATAAAAATTAAGAATATTATTTTATTTATTTTTAATATTATATATTAAAATATTAATAGA -+ -1+1+4)@?F;>>ACDD9555>@@(>(5>>(3@AAADC@3A::(:>A4>ACACCCCDCA:+(:3:@CDDC -@SRR800764.78 78/2 -AATAGTGGAGGCCAAACGACCCAACAAATGATCCTTAGCTATAATAAAAGGAGAAAAATAAAGTTAGTAAATGCTAATCTTGGTATTTTTTACTGAGTGGA -+ -:=;DDADDHD=DHEIG@FHDHHIGGIGH@?@<09?DHGE@G??D@GIJGDBFHIHGHGHJE@CHCECFFDDF:?AEC@AC>;;@@ADB;>=5:A5>:A### -@SRR800764.79 79/2 -GATGTTGATGGCACATTCAAATTAATCGAATTGGCGAAAGCCTCGAAGGAATCGTTAAAAATAATCCCCCTAGGGTCTAAAGAAAATCTAAACAATGATCA -+ -?@@;DD>,=AAA++?;)??G@BCDEEDDDDDDDDBCDDCDDDDDDDCCDBDDDDB -@SRR800764.82 82/2 -ATGGTTAACCAAGCTGAAGAGTTCAAGGCTGCCGATGAAGCTTTTGCCAAGAAGCACGAAGCTAGNCAAAGATTGGAATCCTACGTTGCCTCCATCGCACA -+ -;B?BDFFH=DBGBGH>@B3<+A:+2++@EG:81:BD??*9909BCCC65<9/:A@ACCD@#### -@SRR800764.83 83/2 -AGGTGTATGGAATCAAAGAGATGACAACATCGTTATCAGCCAGAACTTTGTCTAAGGCACTGTCATCGGTAACATCCAATGAAATAGCCTTGGATCCAGAG -+ -B@@ABDDDHFHFHJJIIFDHEGGGIHIJFBEGEGIIHGIIIDGGHEGIJIGIICHDGGJJIJIGGIIIGGEHECEEFFFFBE:AEEEDDDDC?CCCCCC:? -@SRR800764.84 84/2 -CCTTTAGTCCCTCGGAATTTGAGGCTAGAGGTGCCAGAAAAGTTACCACAGGGATAACTGGCTTGTGGCAGTCAAGCGTTCATAGCGACATTGCTTTTTGA -+ -CCCFFFFFHHHHHJIIIIJJJJIJIJJJIJIDHIIJJJJJJIBGHJJJJEHIJIEHHIGHIIJJHHGHFCD>ACECED=BBDDECDDBBB@C@C>CCCD@< -@SRR800764.85 85/2 -GTCATCATGGCTCGATGAACATAATAATCAGGAGATCAATGATGCTCTAGTGTCACAAATCATTAAAATGTCCCACCTTATGTTCGGCGGGTTAACTCACG -+ -B??;?DFDC>DFHEG?2:AA?AEF@FFBBAED>??D@?A@@>&0?(:A@CAC8 -@SRR800764.86 86/2 -GAAATAAAAACATGTCAAACAACCGAACGAAAAAAAGAGGCACCAGGGTGGCTAAAAATGCTAAAAATGGGAAAAACAATAAAAATAGTAATAAAGAGAGA -+ -CCCFFFFFHHHHHJJJJJJJJIJJJJJIJIJJIJJJIJCHIIGHHGFF7?>AADDDDDDDDDDDDDCBDDDDDDDDDBDDDDDDCBDC@CDEEDDDDDDDB -@SRR800764.87 87/2 -TGTACTGGCGCAAGGCAAGTAGCTACCATACTAAGAGAACTGAAAAAGGATCAAATCGGGGTTGTTAGTATGTGTATCGGTACTGGTATGGGTGCCGCCGC -+ -@@CFFFFDFHHHHJGEGIGIDEGHIGHIHGGGHGIGFDGHGHHGFGIEE>CBFCGCGGIEH9?CCDCC@CDD@@@CDDBB8@CD>DBDB>AFH:?;))<CF>BG<?BFC9)9(?:=???=@A############### -@SRR800764.89 89/2 -AAGGTGCAAGTGGAAAGAAAGGAAGGCTAAAGCAAAAGTGTTTCTTATATATAATTTTATGTACCAGAGGAAGCAAAGTACGAAAACTATCAGTTGAAATC -+ -=:BB42ABFD<2ABGF8?8?FEH=FE;>>>@C -@SRR800764.90 90/2 -ATTATTTATTATTTGGTTTCCTGCGGATTGTCCATACTTATACCCCCCCCCCCCCCCCCCTCCGGNGGGGGGGGGGGGGAGTAATCATTATTTTTTATATA -+ -@CCFFFFFHHHHHJJJIIIJJJJJJJJJJJIJJIJJIJJIJIIJJJJ@##################################################### -@SRR800764.91 91/2 -ATCCTGAATGGACAAGACTGACACTATAAGGAGACTTATTCTAGATATCGTAGAACAAACATATGTTACTTTAACGTCGCTGGACACTCACAGACAAGCCT -+ -CCCFFFFFHHGHGJIJGIJJIFGJJJJJJJIIJIIGIIJJJJIJJJJJJJHJIIEHFHIJJIIJIHIJJJIJIGIHHHFFDDDDDDDCCDCDCCDDDDBBC -@SRR800764.92 92/2 -CAGTGGAGCTTGGAGCAGCAGAAGTTGTCTTAGCTTCAGTGGAGCTTGGAGCAGCAGAAGAAGACTTATCTTCAGAAGAGCTTGGGGCAGCAGAAGAAGAC -+ -CCCDFFFFHHHHGGIIJJGJJHIIEHHHIJJIJJJIJJJHIIJIIIHHIIFGGIHJGGIJIGHIIGHG:EHFHDHEEFFDFEDDCDD@6=@BDDDDDCACC -@SRR800764.93 93/2 -GAATTCATTGTCCAGTGGCAAGAATTGAGGGACAATTATTTACCAAGATCCAAGTGGTTCGGCGTCCTTGTTTAAGTAAACCATTTATGTAGGATAGTAAA -+ -@@@DFFFFGHCCBFGEGG?@D@BHHEHHDBDBGHIIIIGHGIHGECCCGD?DHCFG;;;5>;?B5>CC@C;@CCDDDD:@CC -@SRR800764.94 94/2 -AAATCCAAACTTATCGCCGAAGAAATACTACGAACTTTATGTCATTATTTTCGACTCATTGACTANTCTATCTACGTACCTCATAGAAAACCATCCTCAAA -+ -CCCFFFFFHHHHHJJJJJJJJJIJIJJJJJJJIJJJJJIJJJJJJJIIJJHIJIIJJIHHHHHHF#,;ADDEEEDDDDDDDDDDCD>CDCDDDD>ACCDCC -@SRR800764.95 95/2 -GCATTGGCGGCCAAGATATCTTGTAGGTTTGAGTTGTGACTCAATGTGAATATAGATGAAGATTCGGTAGCGCTCATTCTGATGTGTAATAATTGAAATTT -+ -CCCFFFFFHHGHFJJHIGIIIIJGIIIDGIIIJDGGDGGIIGGIGIGH@FFCGGIGIGIGHEHHHFF?BCEDDDDBC;C>CC@CEDCFEACDEE>@@C@C@ -@SRR800764.96 96/2 -CAGCAGTTCAGATAAAATACACCCAGCTTTTGCCCCCCTCCCCTTTTCTCCTCTCTTTCCCATCGCTTTAATTACCCTCTAAATTCCCGCTTCCGTTCATC -+ -##################################################################################################### -@SRR800764.97 97/2 -GATAGTGGGGAAATCCAAGAGGATCTAGAAGTTGATCACATTGATCTAGAGACAAAACAGAAACTAGACTGGGAGAACAAAAATGATTTCCGTGAAGCTGA -+ -@@DGGG@CC> -@SRR800764.98 98/2 -GTATTAAAAGATAATAAAAAGTAATATTAATATATTAATTATATATAATATATTTATATATAATTATATATATATATATAAATAATAATAAATATATATAT -+ -@==B?ADDDHHHDIIIIBFAFFHHIEIIIIDHIDHIIGEEEB>GEHIIGIHAHIIJIGIJJHJJJIGIGIEIJJJJJIIJJIGGEGHHGIEHIIIIGHFH# -@SRR800764.99 99/2 -TCTTTTTTCAGGGCATGCAGATTTTGAAATTCATGTACTGCTTGAAACTTAACAACATTCAAACCATTGGGCAAGATACCATCCGGTTTCCTCTTCAACAA -+ -C@@FFFFFGHBHHEIBHIJIJJIJIGJJIIJBGHEEGIIJIIIJBGIJGIGHHHIJJJJJGIJHHJIIIIHHHHEECDEFECEEDB3;B:CCDDCCDCCCA -@SRR800764.100 100/2 -CGAGAACAAAGAAAAGTGTCTGTCCTATTATTTTACGGCACACTAAGCGTTATGCGAAATAACTTCAATCCAATTGCCACCGTTCACCCAAAAACTTAGGA -+ -<@@DBDFFHGHHHJJJEGFHIIHHHIJJJJGIJJICHIJIIIJIJJGIGHFGIIJDGHHHHGGEFFFFFFEEDEDEDCCDDD?@CCD@ABEDEFDDBDD;ABCCCCCDDFCC -@SRR800764.103 103/2 -AGATATGCTATACCGGCGGAACTTTGTTACAGACGGCTCGCGCGAATCCTTAGGGGAAAACATTGCGCTGACTTTCCCCAGAGCTGTTGCCACAACATAAG -+ -@;@ADDADHH<,22<@:EE################################################################################## -@SRR800764.104 104/2 -TTTATAAAGGAGATTAGCTTAATTGGTATAGCATTCGTTTTACACACGAAAGATTATAGGTTCGAACCCTATATTTCCTAAATCTAGATATAATATTATAT -+ -BCCFFEDFHGHHGJJJJJJGIIGIIIDHIJJJJJJJJIJJJIJJJJGIHIIHJJIIGGIIHIEIIIJHHGDFFFFFFEEEEEECDDCCDEEEEEEDFFEED -@SRR800764.105 105/2 -CGAAAAGTCGTCGTCCCAGGTATTTCTTTATTGATTTTCTTCCAGGGATGCCTTATTCTTTTGTTTCTCCAACTCACCTATAAGACTCTTTACTGTAGAAA -+ -BCBFFFFDHHHHHJJJJJJJ>;;;BCD -@SRR800764.108 108/2 -TGCTGGAAATTTCATTGATTTCCTTATGGACTTGGGAAGAATACTCCAATAGTTTGTTTAATTTTAGTAAAGAGCTATATGCCAACGAAAATTTGATCTTG -+ -CCCDDFFFHFHHHCB?J?43?:CF?CCFI4+A?92*111:CDE@CGGHGIIC>C -@SRR800764.111 111/2 -CAGGTATTGCCTTCTCTGGCGCATGTATCAGACGAGCAAAGACGGCCAATTGTTGTATGCGGTTCACTGTATTTATGTGGTGAATTATTACGGATTCACAA -+ -@CCFDEFFHHHHHJJJJIJJJIJIJHIJJJJJJJFGIJJJJJJIIJJJIIEECDECHHGHFFACDEDDDCDDFEEFDCFDCBCDFEDEEDDDDDDDDDDCC -@SRR800764.112 112/2 -CCACTGGCGGTAATGCAGCAGGTGCTGCGGCTACCTCTTCTAATCTTGCGGAAGTATGTATACAAGGTAGAACCGCCTTCGTTGTTGCAAAACCCCAAGCG -+ -8:;1::+=@1))+<49ACA:@C###### -@SRR800764.117 117/2 -AGCGAATGGTAGCAACATCCCTCTGGACAATGCCGCAGGAATTAATAATAGCAATAATAACATCAGTAGTAGTAATTCATTTTTTAACAATGGTCATTTAT -+ -B@@FFADEFADFHGIIIHIJJGHGGIIJJJIJJIHIGIIJIJIIIJJJGGHGHHIGGJIJJJJHHHHHG;CEBEFDDEEEDEEEDDDDDDCDCCCCCCCDD -@SRR800764.118 118/2 -GAACAAGAATTCATCCAAATCCTCTTTGCATGGGACACTGCAGTTTCATAATATAAACCGTTCTCNGAGTACGATGGAGCACACGCCTGACACTCCAAATG -+ -C@@FFDFFHGHFHIIIIJJJFGIJJJJJJJIJJIIJJIIJJAF?FGIIGEFHIIJJEFGGIIIJG#-;CDGEC?CBDDFCDE@B>?@DBDDDDDDDCAAAD -@SRR800764.119 119/2 -TTTTCAACAAACGCTACACCTTCTTTTGACGTTGGCACTACGCAAAAATAGTCTGAGGGTATATTTCTAGCTGATTCTTTATACTCTGAAAAATGGAACGA -+ -=B@DADDDF33ADFFHBFBGGGHHDEHGH@DFHE3BDHGCAGG?:AHIBHAC=77)@CH5?AAD;?BEF>@C;3>;>>@@@CDCACC>>>C@B?####### -@SRR800764.120 120/2 -TTTTACGGTATTTGATTCACTACTGAGAGAGAGGAAGGAACTGGATGAAATCGCACCTGTACCTGATGCGTTTGTCCCGATTATCAAGATAAAGTTCAGTG -+ -BCCFDDDDHHHHHJBHIIIJJJJJJGHFHEFFGHIIJJGHEBGIGIIGIIGIGIJIJJIEHIIJJGGHHFFFDDCEDC@BDDBCDEDCDCCCCD:CDCCC> -@SRR800764.121 121/2 -GGCTATTTTCTATTGGCGGCTCGTCTGTGGTAACAGAGTGGGGTTTAAAAACAGGGTTACCCCTAAGAAACTATTATTGCAATTCAGGAGAGATATGGGCT -+ -:++AA?DDHDF)?B@B################################################################## -@SRR800764.122 122/2 -CTCATAGTAGCAACAAACTTGAAAATGAAAGAAGTACATTGTTGCACAGTCAGTAGATATAAAATATACTGGAAGAAAGCACCAGCTTCATATTTCATAAA -+ -@@@BDAEFAHDHHGHHIFIGBDH9D>D>EFEHBFFFFCDCDDCDACDC; -@SRR800764.123 123/2 -ATTTCAACAATGAGCTTGTGGGGCTTCTTAATACCTCTTTCCATTATCAGCCTCAGCCTTTAATTTCGCATCATCTTTTTAGTTTCCTTTTCTTTTTCCTT -+ -:?+B?,B+A+2++2+2:++++<FDIFCGGGFGEGICJIJJDGHGI?DHHHGGII>HE=B?BDFEEADE;C@CCCCC -@SRR800764.126 126/2 -GGAGAACTATCTAAAGGTATTACAAATAAAGCTTTGCTGGAAAATAAAGAGGAACACAAACTTTACGTTAGTGCTCCAGATTACGGTATATTAAAGAATTA -+ -?@@D?DF>F4DFB@DFDA?F4ICCCBHDHGICHHIHG9BB)?*::4?BFBDDBGEHGI6BHEHGGHI(=3;@DDH>E>EEBCDBDD;2?DDDDACC<<@CC -@SRR800764.127 127/2 -ATCAATATCTTTTTTAGAAAATGTGCCTTCACTTATCAATTTTTCCGTATAGACGTCAATGACAGATTTTTGTTTTGCAATTTTTTTGTACATTAATGGTT -+ -@@@DDDDDBBFA>GBFFHH;(.;>?DBCCCBCCCC@C4: -@SRR800764.128 128/2 -CATCCTCGATGTTTTGGAATAAAGCGACTTCCTCTCCTGTACCAGGATCATCGCTGATTCAGAGTCTTGATTCGACGATTATACATCCCGATATCGTTCAA -+ -?@@FDDFD@FFAFHHHHFFGHIIGGGFBHIEHHJJJJIJ4DDFHGI;?EGEGGHFHEDHGGDDC.==CA;@BDB?==3,5A>A?9<9<@B3<>CBBDB?ACCCCDD@B@@BCACDDDAC -@SRR800764.130 130/2 -AAGACGAGAAGGCCGATGGAAAAGGTGTTGTTATGGCAACTACCCTAGAACAGTCACCTAATCCAGTTGAATTTGATGGTACTGTTTTTCATCATGGAAGA -+ -?@@ADDDD<:FDFHIFGHIGHIIJI?B??D?FHIGAC>>A;5-;A-5(55,,5ABCDDEDCCD>CA# -@SRR800764.131 131/2 -CGTACAGAAGGTATAAAACGTTAGTTTACTCACAGAAGATACCCTGGCTTTTCTTTTATTAATACATGGAGTTGCAAAAAACAAGGGAAAGGAAAATCAAT -+ -???DDDDB?DHADF9CHGJGCGGFAHHFEGGGI=;?ACBDC=?AB5599A<:>CCCC:3 -@SRR800764.132 132/2 -TAATGTCTAGGTTATAAAACATTGACAGCTCAGACGATAGAAAAACATGTGATACGAATCATTTCGCCGTTGTGTGTTTTAAGAAGAAAAATGTTAATGTT -+ -BBBDDADDHFHAAEEGGIJJIIJJIGHJGFCHHEGH:?GGGIJGHEHFF?9?BDGHGIHIBFFIEEEHE,9?,;.;,;=C@>@@CC?ACCA?>+4>>A### -@SRR800764.133 133/2 -TTAGGTTGGGAAATTGGCTTCTAATATCATCATAAATGCTTTTGCGAGATGTTGCACGAGGGCTTTTGCTTGAACTTTTGGTTGATGCTACCGAACTAGTC -+ -BBBDFBDDHH<;;ACDDDB;A@>CD:@>:C<)05?#### -@SRR800764.134 134/2 -ATTAGTTTTCACTATTTAGCCTAAACAACCCAACGCGAAAATGACCACGCGAAAAGAAAAATTAGTAAAAATATTTCACAACGCGAAAAATAAGGACGAAG -+ -:BBDBADDHH:?555(<5@:@:5;:@A9@DD>>CC>A(9@B00)08AC@CD@AB99< -@SRR800764.135 135/2 -AATGACAGAGATAACCTTGATAAGCTTTTTCTTATACGCTGTGTCACGTATTTATTAAATTACCACGTTTTCGCATAACATTCTGTAGTTCATGTGTACTA -+ -C@CFFFFFHHHHHJIJJJJJJJJJIHJJJJIJJJJIJJJJIGIIJJJJBGHIJIJJJIJJJJJIJII=DHGIHHHFFEFFEDEDDEFDEEEEED>CCCDCD -@SRR800764.136 136/2 -TCATTGACGTTGATTTCCTAGAAAACGTTCAATCTCTCTCACACGTAAATGAGCCCTTCACGAGANCCAATTTTGCAATCAGAGCAAACAGTTTGCACCAG -+ -CCCFFFFFHHHHHJJJJJIIJJJIJJJJJJJIJJJJJJIJJJJIIFHIIJIIJDHIJJIJJIFIH#-;A?DCFFFDEEEEECCDDDDDDDDACCDDEDDB@ -@SRR800764.137 137/2 -CCTTGGGACGTAAATGCAGCATTAATCAAAGAGGAAACCCATCCGAGAAAACGGCCCTCATTTTTATCACTGGAGATAATGCCAGGCCCCCAGGCTCCTGG -+ -+8:A4A+A??8AFG4,+AE9CC4++5>>>@############################# -@SRR800764.138 138/2 -TTTCATTAAATTTTAATCAAGCTTTATATAAAGCTGTATTATGAGGTGCTTTAAAAGCTAATAAATCATATAAATAATAAAATTTATCAATTAAAAATAAA -+ -CCCFFFFFHHHHHJIGIJJJIJJJJJJJJJIJJJJJCHIJJJJJJJEGIJFIIJJIIIIIJJIHHIIGJIJJIIIIGIJIICEHCGHHEHHGHFFBDBCCC -@SRR800764.139 139/2 -ATATCTAAGCAGGGGCCAACTTTGTCACCACAGCTTATCAACCGATTTATGCCCCATTTTCCCTCGAGCCCATCACCTCTGCGAAATACATTGGATTTTAG -+ -@@@FFFEFBDDDCCCCACC>CCDDC -@SRR800764.140 140/2 -ACCAGCCATTGCTGCTTTCTGGAGAGATTTTGGTAAAGACAAGGCTTACTTCGATGCCGAACACGNTATTCACATCTCTCACGGTTGGAGAACTTTCAGGT -+ -B==+4=:::AF4A<+2+2A<:AB;3A+A?<4:EHCFEHGEGGIJA?@@GDGHB):@G>@DGG6=@DC@C=;E7773.?C77>3>BBBBB94+4@<8>>>A8A>CAC######### -@SRR800764.142 142/2 -TGGGCAAAATATAAAAAAAATTTGCTTCTTACAAACCTATAGATGGGCACTTTTATAAGTTTCTGCTTTTCAAACTTTCTTGTTTTTTAACCTGAATTCAG -+ -@@@FFFFFGHHHHJIJIJJJJJJJIIJJJIIIJJGIIJIGHIJJJJIJJ?FFHIIJEGHGFHHHHHGFFFFFFEA@CCEEDC;ACDDDBCCDCBDDD>A@C -@SRR800764.143 143/2 -CAGTTTACTTCTTATCTTTCCTAATTCCTCATTAAACTCAACTTTAATCATAAATTCGTTATTTTCTTCATAAGCATCCAAATCAACCGTTGTTTCAACCA -+ -@@@FDE>>FFFFFIBFHGJDHHIIHC,AEH<9CFCHGCH>;C?G>?GHHHDFF@FC4B?DDFHIIIJJGGG=4=D7CFED@4@AEC9ABDB?CDCACD:A= -@SRR800764.144 144/2 -GGGAGGCGACTCGAATCTCTGACTTACTGAAATAGAATCTATTTTTTCGAAATTACTTACACTTTTGACGGCTAGAAAAGGATATACATACATATTAAAAT -+ -@@@FFFFFHHGHHJIJJIIIJIJJJHIIBGGIGIIGIEII@GHIIJJGB;DGHGHGGEHFFFFFFED?ABDDDDDACDDCB?@CC<@>C@CCDECC:B:CC -@SRR800764.145 145/2 -CCTAAATACTTTTTCCTTTTCACATCCCATCGGGTTTATCTTATACCAAATGTTTACCATTCTGAATCGTATAGCCAACAAGTACCCGCAACTGCAATTGT -+ -??1+A+=BD4**?*0*9BDD################################################## -@SRR800764.146 146/2 -TGCCAGAACAACAACACCAGTAGTACCATCACCAATTTCATCATCTTGAGATTTGGAAAGTTGTACTAACAACTTTGCAATCTCATTATCTAGGTCCATTT -+ -???BB;;;DFHHFBGBEBGBHE9AAC@?BBH*?GEBFDBHD@DG?FH9B9)/?B4?DFB@.=.=7=FDHI@@EHEEECA;CB>BD@CDDEEACCE@CDDC; -@SRR800764.147 147/2 -CAATTTCACGTACTTTTTCACTCTCTTTTCAAAGTTCTTTTCATCTTTCCATCACTGTACTTGATCGCTATCGGTCTCTCGCCAATATTTAGCTTTAGATG -+ -1B8+=:=BFHC:;AHBCG?E<FIE@DFAFGGBC@GGDHIIGI>GHG;:DG;?; -@SRR800764.149 149/2 -CAGGAGCAAAAATTTTAGAAAAAGTCTCCAAACGGATGACACGGGCATCTGTATCCAAAGTCAAGAATGATTTCATTAAAAAATCATTCAAATACCGTTCA -+ -CCCFFFFFHHGHHJJJJJJJJIIIHHIJJJJJJJJGIIJJJJIJJIGIJJHEGIJJHIJHHHHGHHFFFFFFEEEEEEEDDDDDDDDEEEDDCDDCD?@DC -@SRR800764.150 150/2 -GGCTCCTCTGGATATTCACTAGTCACTAATAGTTCTACTAGTTTTTCAATAATTGGTAAGTCGATGGAACCTTCGCCAGATTTGTCCCTCCTAATACTGAC -+ -CCCFFFFFHHGDHGIIEGIJIJHHDHIIIIFIHIGGIJIIJGGIJIJJJJIIGIEIGHIIEIIJIGGHIJJGJIEHHHHFEFDFB?A>C@BCA>CCCCCCC -@SRR800764.151 151/2 -CAAGCGGATTCTCCTCTGATTCCTCTCTGATATTGAATAAACCAGAAGTTCGTCAATACTGGTCATCCGTTTCATCTCATATTTCACGCTCAGGTGATGTG -+ -CCCFFFFFHHHHHJJJJJJJIIJJJJJIJIJJJIJIJJJJJIIJJIEHFFEGHIIJJJJJJJGIJJJJH;EHFFFFFFEEEEEEEECDDDDBDDCDCDDB> -@SRR800764.152 152/2 -TATATAATTATTATTTTTAATTATAAATAAAATATAATTATTATTTATTATATAATTTATATAAATATATATATATATTTATTATATATATAAATATAAAT -+ -C@@FFFFFHGHGFIJIIJIJJIJJJJJJIIJIJJJJIJJJJJJJCIHIIIJJJIIAHGIIIJIJJJIIJJJIJIIIIJIGJJCHGGGIIJFI>EAGIIGE= -@SRR800764.153 153/2 -TTCGTCTTTTATTCTAAATTACTCATTCTAGCACTCCAGGTTGATTTGCTCCTCCTTTTAAGCTTTCACTTCCGGCTCTATTTCCTCTTCTTCATCTTCTT -+ -CCCFDFFFHHGHHJJJJJJJJJJJIJJJJJJJJJJJJJJJCGIGGGIIJJJHIIJIJJEEHIJJIJJJJIIJGIIHFGFBEFFFFECCEEDEDCDDDCDDA -@SRR800764.154 154/2 -AATCTGATATGATTGGTGAGGATCTTCCACCGGCTTATCCCGAGGAAGAACTTGGAGTTCAAGAANATAAAAAAATTGAACTAGAAAGGCCACAAATTCTT -+ -C@CFFFFFHHGGHIJJJJIIJFHJJJEGIGEHIJIICGIGIGIGIIJIJIJIIAECH=?EEEEEB#,5??ACCDDB@A@CCDDDDCC4C@ -@SRR800764.155 155/2 -ATTAGATTCTGGCGGGAATCCACCGTACTCAAATAGACGTAGTAAATCATAGTATTGCCCATGAANGTCACCACATATCTAAAAAAAAAAAAAATAAAAAA -+ -B@@DDDEFFDFBBFHGCCDEEDFDDFCCECCDDCC#,8?BDDABBCCAACAC@CC@@DDDDD######### -@SRR800764.156 156/2 -AGAAGATCCGTTGTGGCAAAATGCTAAATACAAAAGCGCTTTGAAGTTTTTCGCAAGCAGCAAGCTACAATTGGGATTGAGTATGATGGAATTGCAAAGAA -+ -<@@DDFBDFHFD=GGA?EGIHHHGBHIEEIGHGBGHEGHGEGGBFG?8?D;B@GB?@;AAE@CA5>CCCC>@CC:ACACCAAAA@CCCC? -@SRR800764.157 157/2 -GAGGCTTGCTAGTATAGAATGGCAGTAGAAGAGGGTGGTTGCGTGACGAAACGTTTACAAAATGAGCTGCTACAGCTACTTAGTTCTACAACAGAAAGTAT -+ -B@@FFFFFHHHHBGHIIIIJJJICHGHHGEHHIIJ:CG:DAGFFHGIIEGGAE@EHBHHDFFFFEEAEECDCDDDCDCAACDC@CDDDDDDDDDA:AC>AB -@SRR800764.158 158/2 -GTGAGGTACGCAATAGCGGTTGAAGCTTCGATTGCCGTATCTATGTATAGAATATCCATGTCTCTTTTTACCAAATCCATTTCTTTTAGAGGTTTTGACAA -+ -BBCFFFDEHHHHHJIJJJJHIJJJJIJIJIIIJIIJJHIJIJJJIGIIIJIIFIEHJIJJJJHHHHHHFFFFFFDEDEEDFEEEDDDDDCDD@<@BDBDCC -@SRR800764.159 159/2 -GGATTATTATTTTCCCTGATTTTAATTATGGAAGCAGTAGAAGTGGCTAAGAACTGAATCATTTCTTGCGAAACAGGTTTTTTGTTGAATTGCAAAAGAGC -+ -?<@ADEFFHHGFHJIIDIIGIJJEGEIJIEIDGE@EEHG@>GDFGIGIGGIIDDCEDG>FBBAGIIGHIA;@EA?CA;;3;?@B=C?C>@CAC>CCCD?33 -@SRR800764.160 160/2 -TTGTAAAAAAAATATCAAAATATTAAACGTACCGGAAGTGTGTGATAAAAATGGATTTAAAATGAGGGAGCTTTTAAATCTACATGATAACAAAGTTTTAG -+ -CCCFFFFFHHHGHIJJIJIJJIJIJJIJIGHIJJJHIJCFCGCGGGGIIJGGCHH@EHHHFFFFFFEDDDBBACCCCCEDDDDDDDDDEDDDDDD>CDDD9 -@SRR800764.161 161/2 -TAGTTGAGGGCAAGGATAACCACGCTGGTATATAGGCTTCTACTTGGTCAAATTTTCTTGTCTTTATCAAACTGAATGGGTCAGTAAATGGACCTGTTTCT -+ -C@@FFFFFHGHGHJJJJJIIGIJJJGII?FHHGGGIJIGII@FGGEGBBCCCCC@CDCC:@CDC -@SRR800764.162 162/2 -CAGTTGCAGCAATTTCTTCATGTTCTGTTTGTTCCCCGTCCTCGTGTACCAGATCAACTACCCAANAACGTCGCGCATCAGATGGAGGTATGTGTTGGAGA -+ -CCCFFFFFHGHHHJJJJJJJJIIIJJJHIIJIJJJJJIHIJIIJHIHHIJIJFIIIJIJJJJJJI#-;CEHFFDDDBDDDDDDDDCDD8>CCDEDDDBDDC -@SRR800764.163 163/2 -GTTTACCAAATGCTCCAGATTTGCAAGCCGCAAGAAAGGTTGCCAAATTCATCGGCTCTATTCATCATGAACACACCTTTACATTACAAGAAGGTTTGGAT -+ -@@CF?DDFFHHGHIJIIIGGIBEGIJGHGGGGBHIJEHG?F@GHGIGIJIIIJ@FGEGCGEEHHFGFFGEEFFFDDDECDCCC>B>CDDDDDD?,:>?<@A -@SRR800764.164 164/2 -CTTCCAAGAAAACTAAAGTAAAAGGAAGCATACCTGTAAAGATTAGACGGAACCTTGAACTCCAGATAGACGATAGGTACGGAGAGTGCCAGTCCGTAAAC -+ -@@<:DDDDBDBH>G@?FDACFEH@FHII?*0??D@DBDF>=CGGACC;=A=DCEG@8/;?BAC:(98@BB85,5:>@::>?8ABBC -@SRR800764.165 165/2 -AATAGAATAAAAAATAAAAAGAATTAATAATATATAAATAATATAAAATATATTATATATATATATAATATATATATATATAAAATAAAAAAAATATATAA -+ -@?@DFDFDHHGHHJIGGIJIJJJJJIIGIIGIIJJGIJJIJJJIIJJJI*?DGIJJJJJIGIJJIIIJIIIJJJJJJJJJIJIJIIFEHHHFBDDCEEEEC -@SRR800764.166 166/2 -TTTTGATGGAAGGTCCAACAAAGAAAAAGAAACGTGCGCTTTTAAAAAAAGAAGCTTTTCCTACCAAAAGTTCTTTGATCTGCTTATTCAACGTAGCATCT -+ -CCCFFFFFHHHHHFHIJJJJJJIJJJJJJJJJJIGIJJJJJJIHIJJIJJHHHHFEFFFEEEEEEDDDDDCDDFDDDDDCEDDDDDDEEDEDDABDDDECD -@SRR800764.167 167/2 -CGAAAAGATTCCAGAAATCCCATTGGTTGTCTCCACTGACTTGGAATCTATTCAAAAGACCAAGGAAGCTGTTGCAGCTTTGAAGGCTGTTGGTGCTCATT -+ -@+=DDFDFDHFGA?DFE???FGHI>?BGG?BDHIIIJGIDGGC=5(5=8?AAC:@# -@SRR800764.168 168/2 -TACCCCTTGCGCTAAAGAAGAATATGTGCCTACTAACGCTTGTCTTTGTCTCTGTCACTAAACACTGGATTATTACTCCCAGATACTTATTTTGGACTAAT -+ -?@?AB2ADD8F61)+;38::::AC -@SRR800764.169 169/2 -GCAGAATCACATTAGGTAGAGAAACGGTTTTGCATGAAGGCTCCAGAAGAAGCAAGGGAATAAGCAGGGAAAATAAAGCAAAGGAAAGGAAGGTAGTCGTC -+ -@CCDDEDEFFHGFEHICEDHGGGGIIJGHIGHAIA?@GHIDGIIIJJIIEDDGGGIGGGHGHJIIB@EFEEEFEFACEEEEDDC?CCA@B>A<:AC@ABD0 -@SRR800764.170 170/2 -TGTTGGGTAAATGTAATAATTCTTCTTACTTAGCACACACACCTGTTCTTTTACTCGAGTTCAGAACACATTAATCGATAACAAACGCAACAGTTAAAATG -+ -@BBFFFFBFHHHHJIJIJJIIJIJGGGIJIGIGHGJJJIJJJJIJHJJJJIIHCHIJFIBDHIJIIJIJJJGGGHFHDFFFDD@BDBBDDDDD5;ADDCD> -@SRR800764.171 171/2 -AAGTTGTCATCTAAAACATTGGAAATATGATTGTCACCCTTGGTTGGAGTCCTAGTTAGCAATGTTGAATTTTCTGGGTTTTTGGACTCATCTGACGTTTG -+ -@@@DDFEFFHHHFJJIIJIJIGGJJJJIJJIIGIJIIIJIJJJHIIEIHDEDG9FHIHJIHIIIGHGGHGIIJIJGGI=AHHFF@A@ACCDDCDCDDD@C< -@SRR800764.172 172/2 -ACTTTCTGCCTGTAGAGTTCAATCTATATATCCTTGCTTTTGCACGTTTCATATCCTCTTTCCAAACAATTCCTGATTGCCCATTGTTTTCTGAAGTTAGG -+ -CCCFFFFFHHHHFIJIJHJJJJJJJJIJJJJIJIJJIIJIJJJJJJCGHIIJJIJJJIIJJJJIJJJJJIGGIIGGHIIGIIICEH?CEDFFF@DE;@EEE -@SRR800764.173 173/2 -ACCCCAGCTATTGCGGAACCTATAAAAGTAGATCCTTTTAGCTCTCTCTTTTCAACTGCAAAGGCATCTGCAGAAGCACCTAGTGCTACTAAAGCATCCCA -+ -??@D+B13;A7@@########################## -@SRR800764.174 174/2 -GACATCGATCTTTAGAGAACCCCATGGCAAGTTAGCTGGGTCTCTTTCTTGGTAGGTAGCGATCTTGACACCATCAATGATGATGTGCTTGTCGTCATGGG -+ -CCCFFFFFHHFHHJIJJJIJGIJDIJIJJJJFGGIIJHJIHGIIIIGIIJGGFBGIFFECGHIJJJCHFEHFBFFFEDEEDCEEDCCA@ACBCBDBBDDD? -@SRR800764.175 175/2 -CTAACTCCTTTTCCTTTGCATGCAGTGACGATGACAGTTTTCTGAATATCACTTCCAAGGAAGCTGGCAATTCGAAAGTTTGGGGTATATGGCAGTTTTCC -+ -@BCDFFBDDAHHHJIIGIGJJJHHJCDHIJCGEGFGIHHJIJIGIEIGEEBGFGHIIIHGHIGGIIFIIJIIIJACAE3?B@?BB3;AA>@>ACDCCAC:5 -@SRR800764.176 176/2 -TCTCTATTTTCGAATGGGAATGGTACCGCTGAAGATTGGTATTTCAAGTTTTTCTTATTAACTTTTTCATTTATGATCACATTTTGTAGATTCTTATCTCT -+ -;@@D;ADDHHGHFIG9?FHECA@C?CEGBIDH==F@CFFHGJAGEDHEEHC>EBDFFFFDEEDEDCEDD:5;@@ -@SRR800764.177 177/2 -AAATCACGAAGACTTTGAACTATTTGAGAGCCAGAGAATGGAGAAACATGTCTACCGTCAATTCCACCGAATCAAGGTTGACTTGGTTATCTATATTGATT -+ -CCCFFFFFHHGHHJGIGHIJJJJJJJJJIIIJJJJJJJIJJIGJIIJJGIAEFGGGHHHHIIDHIGHHHFFEDEDDE3;?CCACCCDDD:A@CDDDDDDE: -@SRR800764.178 178/2 -GAGAAAACCATAGAGGAATTATGATAACGGCACTCGCTATATCGTATGTCATTGCAGAGGGAGTCNGGCCTTTTATTGGTGGTGCATTTAATGAACATTTG -+ -@@@DFFFFHGHHHEGIDGIJJIIJICFGGGF>C;FHG=GIIIGIGGGE=CFDDHIDGCGII8=,7#,,55;@ACCCD@C58<'835;;AADDA:@CCCCC: -@SRR800764.179 179/2 -TTCTTACCCACTCTAATATCGACGTACTTCAGGTAGAATTCTGGATCAACATCACTCAAAATTAATTGATTTGCCTTTATAATTTTTTTTAAATCTGTATC -+ -CCCFFFFFHHHHHJJJJJJJJIJJHIIJJJJJJCGHHIJJJJIJIIIJJJIJJJJJJJJJIJJJJJJIEIHHDHHHFFFFFFFEEEEDDDDDDEDDEEEED -@SRR800764.180 180/2 -AGATGTACTTCTTGACGCTGTTTAAGTTCCATAAGAGGGATACAAATTTACTGGAAATTTTTGAGGCTGCTTTGTATACTCTGTATTCAAGATGGTCTGTG -+ -C@CFFFFFGHHHHIIJGIIIIIJIFHA(;@CCD -@SRR800764.181 181/2 -AGTATCAACCATAACCAAAACTCAGTAAGGGGCTCTACAGCGCAATTGCCTTTCACACCAGGCGGAATTCCCATGAAATCTGTCAAGACAGGTTCAGAACA -+ -@C?DFFFFHHHHHJJFIIJJJJJIJHGIIJH8CCCACD -@SRR800764.182 182/2 -GGTTCAGGTAAATCGAATTTCTTCGCTGCGATTAGATTTGTTCTTAGTGACGATTACTCTAATCTTAAGAGGGAAGAAAGGCAAGGGCTTATCCACCAAGG -+ -@@=DDFFFCFFHHJIJIIJJIJJIJJGEGI8FEHICIEHGHHHHICC################################## -@SRR800764.186 186/2 -ACTAAGTTGATTGTACGACGACAGGTCAAAGTTAAAGTTAAAGTCACCAGGTGTATAGACACCACATTGAAGGGGTGTCACAGCAATTTTTTTTATTTTTT -+ -@BCFDBBDHHFHGHIGIIIJJIJJIDGHIGGDEHGIJ@GFIIJ>BFHIJJG=BHEGHIGHEGHGHGHHHHFFDDC39;CCDDCBCC@CCCCBDDDDDCDCD -@SRR800764.187 187/2 -AAAGGTAAGTTACACTACACCAGAAGTGATATTGAAATTAGATTTATGAAGGATATCAAAAATCACTACGATCCAAATGGAATCTTGAACCCATACAAGTA -+ -B@?D?2A;<,AFD?CEGBFAHIDHGG2?FGII@B>C;>B5;?CCC@A -@SRR800764.188 188/2 -GAGAACATGCATCACGTACTCAATTCAACGAGACCTGACCATCGGTTTTGGTTTTACGATGACGTAACTCAGTACGGCAGAACAAAGTACCTTAATTATTA -+ -CCCFFFFFHHHHHJJJEHIIJJJIIIIJIIIIIBHIJIJJJJJJH7DFHGG@FHIBEIHFEHHFEFEDEEEECCDDDDDBBCACCBC>CC@@AACDCDEE: -@SRR800764.189 189/2 -TATCCTTCGCTGCTCATCTGATCTTTTTTTTATTGTTTCCTGTTGTTTTTATCTTTCTTCCTTTTCTAATTGTTCTTTAGTTTCTTTGCTTCTTTGTAATC -+ -1=+AD44=:C:FHG@F9E,A>,<)8)?FADFGBF;(555;3;(-;@(:>:5:ACCD;5; -@SRR800764.190 190/2 -TTTTGCAGCTTTACCAGTTGCTGATCATTTTTTTCCACTAAAAGTTTGTTCGTGTATTCTAGATGNGTCGTATAATTAATTAAGAAATTCTCCATCGACTG -+ -CCCFFFFFHHHHHJJIJHIIIJJJJJEIIIJJJJJJIJFIJIIJGHIJHIGHHIGHIJJJJIJIG#-;CHBDDEFEFEEEEDCCCDDDDDEDDCDCD?BBB -@SRR800764.191 191/2 -TCAATAATTTTATATATTTATTTATGGACTTATTCAGATACTTTTGCTGATAATGACGCCCCATCNAAACTACCAATTAGAGATTGTCTCTTATATTATAT -+ -@@@DDFDFGHHHHGGJIJGIIJIJGJJHGIJGJJIHJJJJIIIGIIGHIIHIIIJIJIGHIJJIG#-5BEIIHFHHHFEFFFBCEEA@CCCDDDCFDDEED -@SRR800764.192 192/2 -ATCCGAACAAACACTCATACAGGATAGTAACGCAAATCCAATCTTTGACAATTTCTCTTCCATTACCGGGATGTAGGATTAAATTCATAGAAAGAAATAAA -+ -CCCFFFFFHFGHHJIGGIIIJJFEHIGFEGIIIIJIIJJJGGJJJIEIJIGGIJJJJIJJJJJIJIHEHEACDCCCCDDCCCDDEDDDEDACCD>?CCDDC -@SRR800764.193 193/2 -TGATGGTGCAACAACAATAATAATAGTAATAGCAACAGTGGTAGTAACAATAACAATAACAATAACAATATCAATATCAATAATATATTATAATACTAATA -+ -81+4=:AB?F?3A+<;3E4<,ACCCCDDDD@C> -@SRR800764.195 195/2 -AAGACACCAGCGTCGCACAGCATTCGATAAGTAGAAATAAGAGATTTCCGCTAATTCTCGTGTTACCGATTTTTTCCTTTGTTCTTTTGTATCTAATGACT -+ -@@@DFFFDHHFHHIJGGIBBHHIIJJIIIIIHEIGIGHHGGJJFIIDHGJIIEGGHHHHHBDFFFCCD:@@BCDDDDDCCDCCCDDDCDDDDEEDCCCC>> -@SRR800764.196 196/2 -GATTTCTTATTGAGACCAATTAAGCAACGTCATAGAAACGAGGACAAGTACGTGTCGGTGGACGCTGCAGACGGATCGGTGTCTAAAATTGAGCCCATCGC -+ -?@1DD>DBFHFFDH=FHBDFH@HEE?AAB>9;?>==BB/-??@A:BA>@CD########### -@SRR800764.197 197/2 -TGAAAACTTTGCTGAAAGAAGAAGAAATCTCTGGTGGAAAGCTTTCTATTTCGAGAAAACTTTAGCCTCTAAACTTGGCTATCCTTCGAACATTGATGACT -+ -@@@DDDEF?BDFFJJIGIFGG;EHCHGGEIHJIJCAE?FHIAFHIJGIGGDGFBB9:)=CFHJIC4=CHIGCGEEEHE;;BDDEECE?CDD@CCCCCACA@ -@SRR800764.198 198/2 -TGTTGAAGATGGTCCACGTCCATTCAAGGTCTTCTTGGATATTGGTTTGCAAAGAACCACCACTGGTGCCAGAGTTTTCGGTGCTCTAAAGGGTGCTTCTG -+ -BC@FDEFFFFFFHIGCHIGFHGEGGIJJJGDHIGHHFI>GIGIEIBFHEBAGHGHGIIEHHIGGAH=C@EHCCE?EEFFE?5;?CCCC@CCCB(8?ACCCC -@SRR800764.199 199/2 -TCGCTAAAGCCATATGGCTTAAAGGCTGTCTCCATTTCTTACAGTGCTTTAGGTTCCATCAAAGANTTGAACCAACTCTTGAAATTAGTCTCTGAAAAAGA -+ -@@BFFFHIJJ?@FHIBGIIGIIJJGGIIJIJJJGIJJIHGHGHFFFFFDDBCBDDDDDEED@?CBCBBBBBDBDCDACC -@SRR800764.201 201/2 -ATTTTTTATTAACGCTTTTAATTTTTCTTGTCTTAGTCTTCGTAATTTCCAGTTAATCGCAACGTTCAGAATGATAGTATGGCGCTATCATGTTGTGCTCT -+ -;1;?D?)A4CCAFABHIJEF<9/..)).-5;'';.76ACCDD;;?((6>(.6;988''5@DC,(+3?CC>@ -@SRR800764.202 202/2 -GGACATGGTGCTCTATTTGACTATCCCAAAGCTAAAAAATCTGCAAGATATTGCATCCAAGATATATGCCAATGGGGGTGTGATCGCTGCCATCTGTCATG -+ -1:+4BD?322+2+:35>3>:??A###### -@SRR800764.204 204/2 -GTACTTCTGTTCTTGGTCATGTTCTACGTGAGTCGAAATGTCGTTGTAATGAAGGCTTTCTTGATTTTGCCAATTATACTCTAGCGCATCACTTAACAATC -+ -@?EAEEHFDB@CCCDDDDAC:>(5@CD>: -@SRR800764.205 205/2 -GATACTGTTGATGGGAACTTGCTTCGCCGTAAAAAACTTTATGAAAAGGTTTTACCAAAGCTAACTTCGTTGGAAACAATAATAGCTCCAACTGTATTGCA -+ -@???DDFEHGDAFIGIIGIIJIJJJIJJJIJIJJJJGIIIJIIEHGHGJ7=CFHJIIEHHHHHFFFFFFDECDCEDDDDDDDCDDD@CCDCDD>>@ADDDC -@SRR800764.206 206/2 -GGATTGTTAAAGGCTCTTTTTCGGAAGCCACATATTCCTATGCTGCACCAGCAATTGGTGTCTTCGGATCATACTACTTCGCACTAGTTTCTATTCAAGGC -+ -++++42=BFHB@3>@B/3;8:@5;5(5(,5@BCACCDDDCDDEDEEDDDDDDDDDDDDD? -@SRR800764.208 208/2 -CATTTTTACTTTTTTTATATATTAATTTTAATAATATTATTATTATTATATTCATTAAAATTATTAAATTTTTTTATTATTGTTATATCCTTAAGGATAAT -+ -<@@D??AD??CB?EHIGIIGFGIJEIJIIJIJIGGIGGIGGGIIIIJJGIEHIIJJEHIGHEGIIJ<>FHIHIHFFFFEDBCCECEDC@C>CDCC:ACCCC -@SRR800764.209 209/2 -TGGAGTACGGGAGTTAAATCGCTGATCTTTTCCAAAATAGCTTTTCTCACAGTTTCCCAAACGGCAGCCACACCGATCATAATAGTAAGCTTAAACTCAAC -+ -:8=4A=ABFF@8@AEFAHJ@E7B@FHB:C9**:0:BDFG<9*9DFHGD??DB./8/)B=FGE;1:=BBCBEC=;;=8/;>C>ACA:@(4(4::>3>:@C?< -@SRR800764.210 210/2 -ATATATATTTTTTATTCATAAAAATTCCTTTTGAAGATTTTTATTTTATTTTTATATAAATATCTNTTAATATTTATAATAAATAATAATATATTCATTAT -+ -CCCFFFFFHHHHHJJJJJJJJJJJJJJJJJJJJJJJIJJJJJJJJJJIJJIJJIJIJGIIJJJII#.;FHGIJJJIFJHGHHHHHFFFFFFEEECDEEEEE -@SRR800764.211 211/2 -ATTATTTATAAATCATAAATTATTATTAATTAATAATTTAATTAATAAGTATTAACATTTTATAATTAAAATATAAATATTAACTTCTTTATATTTAATAT -+ -CCCFFFFFHHHHHJJJJJIJJJJJIJJJJJJJJJJIJJIJJJJJJJJJJHGIIJJJJJJJJJIHJJJJHJJIJJIIGIIJIJJIJJIIJJJJJIJJJGHGH -@SRR800764.212 212/2 -CACTAAAATTGCAGAAAAAAGTGTACAATATCAGTAAATAAAATTGGCCAAAACAATACCATTAAAACCAGTCATGTCCATGCAACAAGTCCAACATTGTG -+ -B@@DDFFDHFCDCCD -@SRR800764.213 213/2 -TTGAGGCAGAAAACTTGTTCGCTAGCTCACTGTTGATTCGCATAGCTGAAATCCATCAACTACTTTGTTTCCACACCGTTCTGTGAGAATGATTTGTATAA -+ -@=8:=:2A2:AD;?G@+2+3382+1:*1CCH**1***:*))8)(/*9/*).B4B)8@F7@DG3)@G3AE################################ -@SRR800764.214 214/2 -TAAATAAATAAATAATAATTATAATAATAATAAATTTATTATGTAATTAAATTAAATTAAATTACATTGTATTATATTATTCATTATATTAATTATATGAA -+ -?@@DDEDDHDHFDHGIJIEHIIIJGHJJJGHGEHEHEHIJJJGFHIHIHIHGGHIHIGIIJJEGIIJIJDGIHIIECEEFHJIJJJJ>FHHIJGGGCHFF? -@SRR800764.215 215/2 -AACTTCGTCAAATTCTTCCAGGGACATCTTTCCCTTTATTTATTGGTATATTAATGGATGCAACTNTTATTCGATATTAGTCCTTTCGGGACTTTAAAAGC -+ -?=?DB?BDFBHHFBHHEEIIED@GG83='=A;BDFFFE@5>:@;5:A<3>:A? -@SRR800764.216 216/2 -TTTCGGCTTTAAAACCATCATATACCGACACTGCCACTTCTTCCATTACCATCTTCTCCAAATCAGCATCTCTAATCTCTTCTTTTTTGTAACGTCGTTGT -+ -CCCFFFFFHHHHHJJJJJJJJJJIJIJJIIIIIJJJJJJJJJJJJJJJJJIJIJJJJJJJJJJJHHHHHHFFFFFFEEEEEEEDDDDDBACDD@CDDDDC? -@SRR800764.217 217/2 -TAATATAAGATTCTTTTTAATTATAATAATAAATAAATAAAAAGAAGATATTATCAATGATTTATATTAATAATAAATATAAATAATAAAAAATATATATA -+ -?@GIGEFGF?CGGIGFC4AA9?BF@FBAEHHGHCHB=CD1@CC>CBCCCC;5>>CC:<;:3>CDDDCC -@SRR800764.220 220/2 -TCTGTGCTTTAGCTCACGTAAGTACTCCGGATCCTGCTTAAGGCGCGAATAGGCGTAGTGCCATCCGTCCTTGATATGGCCCCCCATATAATCTGAGCCTC -+ -CCCFDDFFHHHHHJJJJJFHJICJJJJJGIFJIIJJJJJJJJJJJJJIJBEHIHHEDFCCDEEEDDDBBDDDDDCEEDCDDDDDBBACCDDDCCDDC@CA< -@SRR800764.221 221/2 -CCGGGTTTTTTTTTCTCTTTCTTTTTCGCCCACTGGAGAGCCTCAGTCATATATGTCAAAGAAGACTGGTTGAGTAGCATGGGCTTCGGTACCAGGATTTA -+ -@@B?BFHBDHGICFF6@D'7CHC3==-(6C>C?77;B7;7;;7;(>A;(5;>AC@B@@?:@5@ACA34?A19?############### -@SRR800764.222 222/2 -AAAACAATAAAACAGCAAATTGATCATAATACTCCAATGAAGAAAGGTTCTATGATATATAACCCGAAAACTATGAAGTGGGAAGGAAATGAAAACGTCTT -+ -CC@DDFFFHGGHHJIEGHJHIGIHIIIIJGEIGHIJJIJIIIJGG@G*BFFGHIGHIEIGIIGHGGIIJHHHEEHDFD;@DAACDBBDDDDCCDACDDDD8 -@SRR800764.223 223/2 -TGCTTCACAACTGTACTTAATGAACTGAATCAATTTCCTTGGCAATGCAAATTCTTCCAGACAAGAGGCGGCCGCGGCGGTATCTCTAGAAAATTTGGCAG -+ -@@<1?;C@@B=35)0)0(4>@C@>>CCD3:3+:@@7 -@SRR800764.224 224/2 -TACAATATGGAGGAAACGTTGCGTAATCGTTGTCGCTATAGATATTGTCCCTCCCTTCCTCTGTGATAGTTCTTCTTTATATAACTTTCACAAAAGCTTCT -+ -@@@FDDDEA?FHHIIFGGFHGEIECEFHFIIIGGHGGGEIIIGJGIIGGIHGIFHCGHIJJHGHHGEFD?CEFFECEEEEEDCDDCEDDDDDCDDCB@@@: -@SRR800764.225 225/2 -TTACTATGCAAGTAATGTTTCTGCCTGCACCGGCTTCGTAGCTGGTGGAGTGCGATAGCGATGATACTACCTGAAAACACAGAGGAAGGCCGTCAGCCCCG -+ -@C@FFFFDFFH>:F@HH9??C@??>9FG??00:?:?B3BECAHHFFFFDCBDDDEDDCDDDDCDCCD<>AC< -@SRR800764.231 231/2 -GCCATTGCAAAATATTAATATTGTAAAAGCAGAGAATACCGGTAACGGTAAATCAGATCCATATAGCTCAATTAAAATAAGCAAACCGACAAAAACCGTGA -+ -B@=D:+ABDB:<?;?@;>A>8?@D<98A< -@SRR800764.232 232/2 -TAACTCTGGTATGCAATTGTGGTGGCATAGGGAAACAAACATCTTCTTCCGTCTCTTGAGAATCTCTCGACGCCTGTGATACGTCACTATCAAAAGAAGCT -+ -@@@FDDFFH=DDFIGHIJI@ADCDDDDDCCDDCACCDFF@BBAHHFFBDDBCDCDDDCC?@CCD>B>3>:>A@>>>ADA -@SRR800764.234 234/2 -TTAAAGTGGAAATAGCCCTCTCTTTTGCTTTTCTTGAGTTTTATCTAATGGCTCTAATAAGGAAANACGGGAAGAAAAGGAAAGAAAAAAAATACAAGAAA -+ -?B;ADADBBA@C6>.6>A(5(;CCDDDCDDEDD@@B>: -@SRR800764.236 236/2 -TATATTCGGCGTCATGGCGTTCAATTCTTCTGCGGAAATCGGTTGGACGGATTTGGCATCCGCTAATATATCTAAAATGGGCAAGAAGGTCTGAGGGGTTT -+ -?;@DDDBBAC6)0)29+A??0):?CHHI9@676@.@;@-;'5)7,99'';5;3;;?CB128>@CAABCCD3>CD####################### -@SRR800764.237 237/2 -CAGAGGAGGCAAAGGCAAAAGCAGTTGCAGAACAAGAGAAAGAGGCAAAGGCAAAAGAAAAGATAGCTGAACCTGAACCTGAACCTGTACCCACACTTCAA -+ -@BCABDDFHH:CBFHGHJIHJIIGFHHDGI@DFEGGGEAFGHIIIAE;5=C;A:5<:BD>@DC?:>BDCBA>CD>:CCD -@SRR800764.239 239/2 -ATCAGCAAAATAGAAAATAAACGGGCAATCAATCAATAACTACAGGAATATTGGGAGGTTTTAACTAAAATTTCCAGGATATTTCAACTTTTCATAAATCA -+ -:?==DD:2A:<<:AE37)))7.?BE######################### -@SRR800764.240 240/2 -CTACCATAGACGACAACTCAATTTTATTTTCAGAGCCTCCTCAGAAACAATCTATGATGATGTCTATATGCGTAGGTGTTTTTGTTGCAGTTGGCGGATTT -+ -@@@FABDABH?CFGHEHHIE;EHIEIHI9FI@GIIDDF9BFEFD>?BFGGGFFIID>AGGHIJIIIEDEHGH?EFDCCE=C>=;AA2>::C@A@C89&95@ -@SRR800764.241 241/2 -AGGAAACGAATAGTGGTTTCAAAAAATGCCTTTCACTCGTAGAGAAAACAATAAAAGTTACCGCACTCCAACACAGGCGATACTGGAGGATTATTTTCAAG -+ -CCCFFFFFGHHHHFHIGHJJJJIJJJJJGIJJJJJJJIJIJJJJJJGIJJHIJJJJJFGIJJJHHFFFEDEEDDDDBDDDGHHDGGIGCIGICFIDH@CBFHGI=FHICHIIFGHHH?DFDFAC;ABDA>@CDDC@>CD;=@? -@SRR800764.244 244/2 -CGAATCTGCCACTGCTTCCTCCGACGCTTCTTCTGCTTCAGAATCCTCTTCAGCTTCTTCTTCCTCTGCTTCAGAATCTTCTTCTGCTGCCTCCTCTTCTG -+ -??@############################# -@SRR800764.245 245/2 -ATAAGTGCGTTCATCTCATGGATCCTCGTGAGCAACATTTTCATATTCATCTTCTGGTCAACCACCTTTGTATCTTTGATCCTTTACTTATTCAATACCGT -+ -?B@FB?AB:AA:DE9A9,??333?;C?8C8*1?CC8?DH9*4BF<4??FI?E)7?CEF:A;C########### -@SRR800764.246 246/2 -ATATATTATTATTTATAATAATAAATAATATTATAATAAGGATGCATATTATATATATATATATTATATTTCTCCTTCCGGGGTTCCGGCTCCCGTGGCCG -+ -CCCFFFFFHHHHHJJJJJJJJJJJJJJJIJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJIJJIJJIIJJJJIJJJ=BDFFDDDDDB@?BD### -@SRR800764.247 247/2 -TAGGAAATGAAGCGGTAAAGGTTTGCGATGAGATGTACCTCCGATGTTTTTTGTCTTTATTCAAATATGGACGAAATAAGCCGCCCAAAGGTCTGACAGCA -+ -CCCFFFFFHGHHGJJFHIIJJFHIIJJIJJIJIIJIIIIIJJIEHHIHIJHIICEHHHHHHFFFFFFFEDDEDBDDDDDDACBDDDDBDDD:CACCDDDDD -@SRR800764.248 248/2 -TGATTATATTATAATATTTTAATATTTATTTCACTTATTATTTATTAGGAACTTTATATCTTAATCTGGGCTGTTTCCCTTTAGATTATTTACCTTATCGC -+ -CCCFFFFFGHHHHJJJJJJJJJJJJJJJJJJJJIJJJJJIIJJJIJIJJIGHIJJJIJIJJJIJJJJJIJJJIGEGIIIIJJJGIJJIIIGHGHHHFFFFE -@SRR800764.249 249/2 -AAGGTAACATGACTGCTGTGCGTCGCTCAACTAGAATAAGGACTAAATCTCAAGTTATTGAGGAAGATTACGATGACGAGCAAAACACCAGCGCACAACAC -+ -@?BDBDDFBDC?FIGEBHGGIJJIGIJIBEFIAFGEHGGIGJGHDFHGEGFHI9CHIGHAA77CD@C;=AHBDDEAEB;,;>C9ABBA?B??@BB@BBDBB -@SRR800764.250 250/2 -CATTGAGTATCAAGTCTGGTAATGCTGCAATTTTGAAGGGTGGTAAAGAGTCTGTGAACACGTTCNGAGAAATGGCAAAGATCGTTAACGACACCATTGCA -+ -?@@FDBDABCDHDEAE:CEHHFG@EHIIEEHDGGFFHHAB??GH58=68?8>CDC# diff --git a/latch_cli/services/init/example_snakemake/data/samples/B.fastq b/latch_cli/services/init/example_snakemake/data/samples/B.fastq deleted file mode 100644 index e022e580..00000000 --- a/latch_cli/services/init/example_snakemake/data/samples/B.fastq +++ /dev/null @@ -1,1000 +0,0 @@ -@SRR800764.25001 25001/2 -CTCGTTGATAGCAGCAAAAACTTCTGATTCAATGCGTTGTGTGCATCAGCTACGGCAGTATTTGACGGTACTATCAAAAGACCATTAATATTTTTTAAAGA -+ -??1B=+AB:?:AFB;C:CF??EFDHHGCCBCCF@E?1:@DDGHCC4*?BHCGAAAB;E==;@E>EE=D';>(;>A@5>CCDCDCDCCDDEB@@C@BDDDDA -@SRR800764.25002 25002/2 -TAGCACCTTCAGGACAATGCAAGTGGATAGACGCCTTTTCAAAAAATCTGTTCTCATGGAATTTTTGTGCTAAATACATCTTGGCGAATGAATAAGCAAGT -+ -;?1B4ADEAHD?83EB:FGIII<3ABCBIHJGGBGHJJJG>F@DEBD>GGBB8=C;)==7CAHEH>4?=:@;;7;@;AEEECC;>@@?B::>CDC@@C3<> -@SRR800764.25003 25003/2 -ATTCAAATTGGCAATCACTCAAGGCTCCTAATCCATACTTTTTAGCATAAGTGATATTATAGTGCCCAGTGGCTAGGGCATCCCAACATTCATTTAGGATA -+ -@@@D?DDDHHGFHIGGGIJEHIJIIJJIJIIIGIIJIIIJIIG?13>>>ACC###### -@SRR800764.25004 25004/2 -TATAAATTATTAATATATCCTTTTTAATAAAATAAAAAGGGGCATTATAAATATTAATAATTAATTTTTTTTTTATTTATATTTATATATATATTAAAGAT -+ -@CCFFFFFHHHGGJIJIJIJJJJJJJIJGIJJJIJJJJJJJJIDIJJJIJIIJJIIHIIJJIJIIHJJJIHFDDDDDEEEEFEFEEDEDEEEADECDCCCA -@SRR800764.25005 25005/2 -AACTACTGCTTATATATGGTGCAGAAAAGTGGCTCGGAATGAACACCTCTTTTAATTAAAAATTCATTTATAAAGTACAGGGCCTTCACGCCGCTTAGTAT -+ -@@?BA;B?DCFDFHHBEAEEE>@BAH@@@0?6BA*9?9BB(B(?################################################### -@SRR800764.25006 25006/2 -TTGACAGAAGATCTATATGACGAATTGCTTAAGCACAGATTGAATATTGATGAAGCCTTGAGAAGGCTAGGATCCAAGAGACCAAAAACCAAAATGGTTAG -+ -@B@DDFFFHH8?DHGGGHIGGIIIGGHIHEBFIHIGDHGGGF>D>4?@DGBDEEH?FCHIEE=EGEIJICGHECE>:AB>;;?AC@AA?=AABA:>C>:A# -@SRR800764.25007 25007/2 -TTTTAATATCAATAGATGCTGGTGTTACTAAAGGATTACCAGGAATATAGTTATCAGGATGCTTTTATAATAAATATAAAATGGACTATATCTTCATAAAA -+ -?@@FF?DFF?HHJFGHHIGII@GGGGHBDBHICBGG?DBF?BBGEIEHIG7?EEHFFEC:ACCCDDCEC -@SRR800764.25008 25008/2 -CTGACTTATATATGCGAATGCACATGAATAGACCGCATATGCTTCTTATCAGTCTTACCTCGCTTATCTTTCCCCATTTATTTGCCAATCCATCTTATCTT -+ -@C@DFFFFHHGHHGIIIJIHIIJJJIJJJJJJIIIIIJJJJJIJJIIIIIEFCHIEHGIGIIJJGHHHHFDFFCDCCECDEDEDDCCCCDCCDCCCDDCC@ -@SRR800764.25009 25009/2 -TAACTTTAGTTTTCAAATCTATCATCAATTCTTGAAGAACTGGAGAGCTTTCTAACGTATTCCCATATAATTCTAAAACCACGGCGACCCAATCCGCTACA -+ -CC@FDFFFAFHHHBHIJIJJJJIJJJJJJJIIJIFIJJJIJJHIJFCADHGGHIIGIBFHIFGGIDIJEIIIGIIIGEHDEEEFFDDDDDD?CCCBDDDD@ -@SRR800764.25010 25010/2 -AATAAATAATATACTATGTTTTATTAAATGAGATAATAATAAAATTTTATTATTATTAGATATATATTATAATGTATTATATAACTATCATAAACAACGTA -+ -CC@DFDDFGHHHHJJJIIJJJJJJJJJJJJJJJIIIIJJJIJGIIGIIIJJJJIJJDCGIHHIIIJJJJJJJIIBFGIIIJJIJJJJJJIJGIIJHHHF?> -@SRR800764.25011 25011/2 -TAGTACTTATGATGGTTTTGGTCTAGCTTGGGCAATTGCTGAACATATCGCAAGTAAGATTGGATGTTTCGCTTTGTTTGCAACTCACTTTCATGAATTGA -+ -CCCDFFFFHHHHHJJHIJJJJHIJJJFJIJJJJJJJJJIJJJJJJJIJJJGHIJHJJJJJJJJJJJGHIJHHHFFFFFEEEEEEDDCCDDDDDEDDDEEDC -@SRR800764.25012 25012/2 -GAATATTTATCAAGTGCATAGGATATGAGAAATTCTTTTATTGGATCAATTTCTCTTGAATGAGTTTGCCTCAACGAGTCGAAAGTCAAAATATTAACCAG -+ -?@@D=:ABDFHABHHEBHEGBHC@FEGGBFHEGGDHHG:BDHGCHIJIBFIJBG@HCC;/BB@DECC=>;>C>@BCDDD@ -@SRR800764.25013 25013/2 -CCTCAGCAGTAACTCCATCTACCTTTGGGGATTTGAACCATCTCATTCCAGTTTTGGATAACTGCGATTAGATTAAAAGATTAAAAGATTATCGATTAGAT -+ -CC@FFFFFHFHHHJJJJIJJJIIGJJJJJJ?GHJJJJJIIIJIIJIJIIJHFHIJIJGGIJJEIJIIJJHGHHHGFFFFDEEEEDEEDCDDDDDDDDDDDA -@SRR800764.25014 25014/2 -ACAGACTCTGTTAATATTTAAAAATTTTTCCTTTTCGGCAAGCACTGTGTTAACTAATTGTGCAAAAGCTTTGCTGGTTAACTCGGACTTCAACTTAGACT -+ -@@BF;;DDFHDFDEGGGIHHJIIIJGGIJJJIGIJJJIJJEHGG?FGDBDEGGIG@CHHIEFHCDDEEGGHGCEECCDDFFEEDDDDBBDDACDCCD@CC: -@SRR800764.25015 25015/2 -TATCAATAAATAATTCCTTTGAACTATTTATTATTTTATTATATTTATTTTCTCCTTCATTATTAATTTTTATTAATAATTAAAATCTTATCATTTTATGG -+ -@@CFFFFFHHGAHHGICHGIJIJJJJGIJJJJJJIJJJJJJJJJJIJJJIGFHIIIIGIHIGCAA2;;?BCEECECA@; -@SRR800764.25017 25017/2 -TATAAATCTTGTATACACTTCCTCAAATTCAAAGTTTTTGCCATTTAACTGGGGTGTCTGGGATGAATTCAAAACACGATACAGAATACAACAGTATCAGG -+ -@@@FDBDDHHDDFHAHGDHIIJJIIIIJIJ@EGG?FFHJJGICFHGIIIIE>GGFD7BFHGG9FHE=DGEHEHCHCBE?CCADDDDC@>>>@AB:@BCDDC -@SRR800764.25018 25018/2 -CTGGTAAAGGAGCTTATTTTGCAACCCCACCCGTACAACTAATTAATAGCCTTGATGTAGCCTTGAAAGAAATTCTCGAAGAGGGGTTGCATAAGAGATGG -+ -???DDDFFH>;FFHHGBGIIIIGHGGDHEHIGI8?DGGJDGBGFHIA>;=?B=@@<>>CDCDDDDD@ -@SRR800764.25019 25019/2 -AAAATATCATTGAAAAAGCACTCATTCTGGTTAAAGTCGCTGAACAAATTGGAAAGATCCAGTAAAGCTTTTTCTTTTGTAGTTTCATCTCTTTTCAGAAA -+ -1:8AD+2A4A=,AGHIA)+7)76A3(-=B7?37?################### -@SRR800764.25022 25022/2 -CTAACCTTAAGACCTGAAAAATGAACAGAGTTTTTATAAAATTTCAGTTTAAAATTGAATGTTGCCCTAACAATATGGATTAAAACCCTGACATATTAGGT -+ -@B?D=+ADDD>FHIEIEGHHJGG>HHIJEGHI@>GEDHIJIIIICB>GIG@GHI:D??FEHAF>FABACC@FG;C;CD@;>EHCHBD?;;@CA>;;C@### -@SRR800764.25023 25023/2 -TCTATCTAACGAGACCTTTGATTGAACGACAAAACTTAACATATCAGACAAACGATCCAAAGGATCTCTTAATAACGTGAATAAAGAAAGCGCAGTAAAGG -+ -1?+B=DADFBDFCFB?('5-&2>ACC> -@SRR800764.25024 25024/2 -ACAAGACTAAGCGAAGGAGAGAAAAATGCTTGAAATTTCGATTAAAAAAAAAAGGTGAGATGCAAGGTTGGTTAATATTACTGTGAATTGAATAAATTTCC -+ -@@@DD8BD?BDFA:EG6+<2BGIIEDG(?FHGIIDDC9;(5(=(>@:5AC(555-(2(+4>BD@##################### -@SRR800764.25025 25025/2 -TATATAAAATAAGCCAAGACAGTGGCCTTCCCTTATTATCAGCGTACTAAAATCTCATATGATTTATTTTTCGTGGTCCTGAACGAGTGTGAAAAATTTTG -+ -?;8BDDDFF?FHCBGEEEEEHJE:?FCGCCBGA>GGIDFAI>GHBF6B@??9EG?B)==888CHGHG>DC:@@AC'=?@>;)(6;'35=((;>>>AACC@3 -@SRR800764.25026 25026/2 -CTTCAAAAAGCATCTCTGGAAGAAGATCCGGCAAACCACGAATTCTGTTTGATTCTGCCAGAGCTCAAAGAAACTCCAAACGCAACCATTCTCTGAAAGCG -+ -C@@FFFFFFHFFHEGIFIIIJJIJIFIGIIIDEHGGIJJIGIGGIIJGIJ@FIAFHHIGEGHFHHFFDFFFEE3;;ACCDDDDDDBDDC:BDACDCDDCDB -@SRR800764.25027 25027/2 -AAAGCCAAGTTATCTGCCTACGGTTGTCACAGCAACATTGCGTGCCGTTGTTCTTTTGTTTTTTTTTTTTGTTTTTTTTTGTGGTTTTCGCAGCAACGAAC -+ -B@@B;;D:B2<CE=BCD);BDC>CEEDAACDD@=?@B?A?CDCCDCCDDDCDCC?>3 -@SRR800764.25029 25029/2 -AAATGCTGTAGTTACGAATACAGCTAGTGGCCGCTTCGATGTAACGCCCACTGTTCAAGACTACGTGTTTATACTTGACTTAAAAAAGCCGGAAAAACTAG -+ -+??D:+:DB>CF,1):8@@6@89909B?B####################################################### -@SRR800764.25030 25030/2 -ACAAAAGTTTTATTCGATCAATACATCGTTATACTGAATCTACTTTGGTGAAGCAGGGTTATCTTTACTGCTATACATTGGACAAGATTTATTTGTTCTAA -+ -@@@FDFDDCHFADGGH9EHII@EGIJGG;FCGIJIJJJIIEHIFJGDCBDGDGGI;FGHH=7=CHGDGEHE@CHEHHHHHG;CCC>@=@:;; -@SRR800764.25031 25031/2 -GATTCCAATGATAAGTTTGTGCATGTCCAGCTGTTAATTAACTTGAAAATCTCACCGTTGATGAAAAGTCAATACAATATGGTATTGAGGAACGTTATGGA -+ -CCCFFFFFHHHGGIIGHIIHHJJIJJIJJJJJJAGHIJJIIJIJJJIJII9BDHIFGGHIHGGIJJIJIGHIJJJIJJIFHG7?CEHFFFFFEDACCDDDD -@SRR800764.25032 25032/2 -AATAATTGTAGGGATAAATTTAAATATGGCATAAACTAAATAAGGAGAGCATGAAAAAACTGCAAAATCCAAAAAGCAAAAACGAAGGTCAGAAAGTAAAG -+ -8@1;?BABC4A>1A+H9BA@GGG3300BBFCG<***9--=@)=CHC@DEHC?############################ -@SRR800764.25033 25033/2 -ACTAAAACGTGGTGAAAGGAAATTAATATTTCCTGATCATTTCTTATGACTATAATTTTACGGCTTTCCTTCTTTTTATTTAGCTTTGCAAATTGCAACTC -+ -?;?=DDFFFHH?AE@F+FE@FGE>DF>4BDFHFAGGHIE9*09BF;:'-'=CG@;.7)77)6;???;?B:>CCDDA;;(;>CCDC -@SRR800764.25034 25034/2 -ATAAATAAAATAAAAAATAATAAATATTAATATTATTAAATATTATTTATAATAAATATTAATATTATTAAATATTATTCATATTAATAAATTTTATTATT -+ -BC@FFDBDHADHHBDHBEHHGH>HHGBF@HG?CED?GFHBFFHE@HGHHIH>FGGGIDGFHIJCIE:BCCGGDGGFGHJJIJJBG:@E>CEAE>EEHFFFF -@SRR800764.25035 25035/2 -ATTTATAAAATTATAAAATTAATTTATATATAATTCAATATATATATATTAATTTATATATTTAAATTAAATATAATTAAATAAATAATAAGATCGGAAGA -+ -?@CFDBDDFB?EHCH>?BFAEE@FA;E=4=4AED@ -@SRR800764.25036 25036/2 -CTCAACCACAAACTTTGAAAGTGTATGACTACAAGGGCAGTGGTGGGGCCATGGCCATGTACAATACTGACGAATCCATCGAAGGGTTTGCTCATTCGTCT -+ -;C>C@B=;@CC?>C??B5??BD(:>@:3:>2< -@SRR800764.25037 25037/2 -AGCAACCTACTTTATCTCAATCGAAAACGAAGTAAAGTTGCGGTTCCCTCTGTCTCTCCTAATATTATCCTAAATTTATGTTTACAGTCGCAAATTAGATA -+ -@@@DFFFFHHHGHJJJGIJJJJIJIIGIJIJIHIJJJIIIJJIFGDGIJIFIGGI>DHHIG>EEEFHG>A@@EFDEDEEC@@@ACCDBCBDBB=@ACCDCC -@SRR800764.25038 25038/2 -CTGATTTATCACTGCAAATGAAAAGCAATCAATACGAGATATTTTTCAATCAGTCAATTTCTGTGAAGAAGATCATTTTAGAAACAATGCCTAAATTTGAA -+ -@@@BDADFFAHGG9EGICIIJGIFGIIGDGGHH@DEEGIHHAHFHDB3;;AACECCC;>A@ -@SRR800764.25039 25039/2 -TTCCATGTGTAGATTTTTAAGGCAACGATTATTAATTCATTTACGACCAAAGCAGTGAAGCAAATAGCAACCATCCTTGTGAAATCAGTATCTAATAAAGT -+ -1++4=,,222C?,,<@G>F@9):8)?D?)8CG8B############################################ -@SRR800764.25040 25040/2 -CCCCTGCATTAATCGCTCTTTCATTTTCAATTTCTTTCTCGGAGTCCGCTATCTTTGTATCTTCTTCTTTCTCGTTTTTACTTATTAAAAATTCGATAGCG -+ -1++4A:3BF4+FEGHHHIJIGGHHGGGHIGGGGIGEHHHHHFFFFFFEDEEECEE -@SRR800764.25042 25042/2 -CCGCACGAGAATTTGTGAAACGTGGCATGTGGGGAACCCGCATGAATAGAAAATATGCTAGACACGACTCTTGTTTACATTGCCATTGGTGGTGTATGTAC -+ -:++=B8BA?))A@ADBDB>C>@AC@3>A>A@CC@CCD -@SRR800764.25044 25044/2 -CCGAATAATCTCTCTTTTTGCTATTTAGGGGAGTCAGTAGAAGGTTTTCGTGTGATTCATCAACTGTTTCTTGAGAACTATTCAACTGAGATGAGAGGGCT -+ -BBECEECCD@@CCC>ACA>@A8:?2 -@SRR800764.25045 25045/2 -ACTATTTACAAAGTTGAAGGTTCCGGATGGATACAGAATAGGGATCCTAAATATAAACACTATATTTATTTATTTTTTTCGAATAAAAGTCAAGTTAGCAA -+ -@@@BDFBFFDBHHIIIBHIJHGEGGIB?CHG@>D>DHAE9DGDHH@FDFHHB<8=CBFG@@;FGI4@@@E(7AC;;@DED36;>C;ACDDACC=<<ACAB? -@SRR800764.25047 25047/2 -CAAAGTAATAGAGCAAAAGTGACATCCGCAGCAAGCTGGACAGGTAAATTGCCTCATACAGTCTTACACGAAACATGTCAGAAACGAAAATGGAATAAGGT -+ -;;@;AD>?D?BDDBEGAHHAC?H?F>C@C(-5>@;?BD@CC######## -@SRR800764.25048 25048/2 -TCATCTAAATCGAATTCTGATACATTTTCCATGTCAGTTGGTAATTGATGCGAGCACGCTAGTAAATATGATGTACTTGTAGGTCTCCAGAAGAATGCGAA -+ -@@BFFDDFHFFDDEHFC>CCEEEDCDD?CCDCB@? -@SRR800764.25049 25049/2 -AAACAGGTAATGATACAGTAGGGCAGGATACATCACTTTCTGTACACTATTATACGCAGGCAGCGTTAAAAGGCGATTCTGTGGCAATGTTAGGTTTATGT -+ -@CCFFFFBFHHHHJJJIJIJIJJJJJJJJJJJJJIIJJJIIJIJJJJJJJGIJIJIIIJJJGGGHEHHFFFDFDCBBDDDEDCCDCCDD:>BCC+44?CCC -@SRR800764.25050 25050/2 -TAAGTTTGAATAAATTGAGATATTTGGATGCCGTATCGAGCTTTAATTCAAGTTCAGTCAAGTCGAATTTCGCGTCTAAGGTCAATACCCAGCTAAACCTT -+ -@@?DADDFGHHHFGGHE>HCHIIJIGEGIGGFFEE?DHHG)BDDF<9??D?DBF><88BGF>8@CC=EGI:D==9ACAA5=>3;A@C(>:A?CC -@SRR800764.25051 25051/2 -GACATTGAAGGGCTGATTAAACATAAAATAGAATTTGACTCAAGAAACATGAGCCAAGACGAAATTGAAGATGGCAACTCTTCTCAATCTCTGAATATATA -+ -;=@?BD442A;F7FADGH@HICCFGIJIE?<9C99::?<:DC;??;DBFH3?9D@;FDAA@AAG=D:;CECA3?7)).?>AC;@CEA(5(5@CC@@##### -@SRR800764.25052 25052/2 -CGTCGTGAGACTACCTGGTTGTGATTTGGGTAGTTTCCTACTTATGGATCGGTTCCTTAGATACGGTGGACGGCTACTGGTTGCATACATCTGGCTTCTTA -+ -+:1BD0)+<<2+++<3:<1+AFIEFD1*1:?D4B9 -@SRR800764.25054 25054/2 -AATCCTAGGATCTACCTTTATACGCATTTATCCTATAAAAACCCAATCTTTCAAATACACAGTATTTTATATGTGTGATTTCCTTGATTGACTCAATTTAA -+ -<@=C=D:@AD=CEHHC################### -@SRR800764.25055 25055/2 -TGTCAAGACGTTTTGGTAATAAATGCTACTTGAAAACCCTCAAGAGTCGCTACAAACTTGCCGTTCCTTAATAAATAAAGGCAAGCGTTATATACATGATA -+ -BDFHHFHBDF22CHHIIJEGC9FFBEFCDGIIGIIGD3FH?DAD'7FHHC(.==;);=E?;B;@C>@@C;@A>;5(5==55(58?C3>34@C>:> -@SRR800764.25056 25056/2 -GAAGAAAGAAAACATAACGATGCTTTACTTCGTGGGAAAGACATATTCCAGGATGTGTGGTTCCCTATGTTATTCTGCTTCAATGATACGATCATGACAGC -+ -CCCFFFFFHHHHHJJIJJIJJIGJIJJJJJJJHIJJGJJJIJIJJGIJIIFIEHHFHIIJ@EHIHHGHGHEFFFFFFFEEEEEEEDDEDDBDDDDDDCCCB -@SRR800764.25057 25057/2 -AGAGCCATCTTTACAACCAATAACCATATACTTACCATCATGACTAAACGTACAGCAGCATATTGAATTCTTGAATAGCTCTGAATTAGCAACTGCAGGTT -+ -@@CFDFFFGHHHHGJJJIJJJJJJJJIIJJIIIJIJJJJJJJJDIIJGIIJIJJJEGIEIIIIJIIIJIIIJJJIHFFFFHHCEFFFFEEEEDCDCDDD=@ -@SRR800764.25058 25058/2 -CGGAGGCGTTTTTCTTAGGGTTCAATAACCCAACGCCTGGATTAGAAGCTGAGCACTCAAGCACATCGCCTGCCCCCGAGAACTCCGAAACACATAATAGG -+ -:B?DDD7BC8DFH@FEBGGCIICFIIJJGJ?FHBEGIG=HIIDHECCGGGGAEHEC3?>@@(;;C@>B;?:??99(899<9&::AC?>80=FHIG=7=@A=E?7??>DCD?CCECC@;?A?####### -@SRR800764.25060 25060/2 -ATTCCTTAAAGAACAGTGCCAATTATATATAGGACACCCCCAAGTAATACCCAAAAGAGCTGAATTTGGGTCCAAATTTCTGAAAAACTATAGCAGTAAAG -+ -B@@F?,ABFBEFHGFHHCEAFHGGE;FHBAHG9?FGEGFEHGGH9;@@@GCGDGGH7=?A?>D);@CC@>AAEA;;@(5;;>CC@CACD -@SRR800764.25061 25061/2 -TCATAGTTTCAGTTCACAAGGTAATAATAACGGAGGTGGACGTAAGTCCCTATTTGCACCCTACCTTCCCCAAGCCAACATTCCAGAGCTAATCCAAGAAG -+ -CC@FDADFFFDFHGHH9BHHJ+AFEEHIJJIIFIGI?DFGHE0BBB?DGGFHCDFF/B@FH=;CGGHHFC>DBEDDA3@AEHE>;?7777;>ABD@B?BCACDDE>A@C>4 -@SRR800764.25063 25063/2 -GTCAAGGTTGGGCGCCAATGCTATCCTTGGTGTTTCCTTGTGCGTTGCTCGAGCTGCTGCCGCACAAAAGGGAATTACTCTCTACAAGTATATAGCCGAGT -+ -C@@FFFFFHHHHHJGIIIIJJJIJJJIJGH?DGIIGGJJJIHEHIIGIIJEEIFHH@DFFFB>BDDDD?C?BBA?ACCDDDDC@CCCD:>CE@BCCA>>@B -@SRR800764.25064 25064/2 -ATAATAATAATAATTTTATTTTTATAATTTATTAATAATAATAATAATTATATATATATTATTAATAAATATAGACCTTATCGTCTAATGGTTACGACATC -+ -@1?D?BDDHFHDDEGGBEGHJIGHJECHII9DHCFHIGGIIIGAG9BFGIIGGHIIEHIIGIIJJIHDGIIIGICF>F>GH;2@CCDHIJ@=AECAD?:A?+2AEAH<+<DD<@GB*:1*0::***:?@>>CDDD;AC><:>ACD@>@CDDDDDD@AACCD@CC@ -@SRR800764.25067 25067/2 -GGCATACATCATGAAACTAGATAATTCACCGACAGTCATTGAACCACTTTGAATCATGCTTGTTCCAACCAATAATAACGACAGCATTGCAGTGTTGCCAA -+ -@DD;'6.6(7;7;B'99?A>C############################# -@SRR800764.25070 25070/2 -TGCTGCTTGATGTCTTCGCACTTTTTTTTTCCAGATTTTTCAGGTGATGAGGTGGATCTGGCCGGTTTTACAATAATACTCAAATAATTTGTAGACAACGT -+ -@@CFA,FHII@8)..=C4@77.6(6).7)).(3'''35:@(5(:(:>@C>(9@@CC>@@########### -@SRR800764.25071 25071/2 -TTTTCACCTTTACCCTCGTACAAATCTGGTAAATCCTTTTTTAGAACTAACAATGCACTAATTACAGTATCAACCAAGATTTGAGTTTCTTCCTTAGTAAA -+ -;.6;BBB6@#################### -@SRR800764.25072 25072/2 -TGTAATGGGATGAGTCTATATTTAAACAAATTTCCTGAGATCCATTCCACTTATGATGAATCAAAAGCATGGCATTGTTTCTGGTGTTGTTTTATAATGGA -+ -CCBFFFFFHHHHFIHHGJJFJJJIIIIIIJIIHHIGIDGIGIHJHGHIEIDHIIJHCGIJGGIEGACHHD@CHIHCA=@DHAAE>A;BE3=A@CCCDCC:: -@SRR800764.25073 25073/2 -CAGGATACTTCAAGAATATTAGTAGCTTGAAATTTGAACACATTAATTCCGTATACAGTTCGTCATCATCCAGCAAATCGTCTAAGACGTCCAAATTAGGT -+ -?@BFDD?DDDBFHIBABADECJ>BEHHHIG>HH@HIDHH@EHBHH@DE>F;?;D39?00?B?(;C2==FECC:37.7@CE?;@BDEFDD;>?######### -@SRR800764.25074 25074/2 -CGGCATTTTACTGAATAATAATTGAGATATTCGTAACTCTTCCGAAATGATTCTAGAACTGTCTTCTACTTGCGAAAGAATATATTTTCTATACGTCCTGG -+ -??7;+A:DA:A,2A:EC?,3,,<3+<+3@C@;>CA3AED@@3;77;@C?CED@3-;;>C## -@SRR800764.25076 25076/2 -CTGTAGCTTGAAGCAAACATCACAAGGGACACCACCAGAATAAAGACATATATGAGAGGGGTATAAACGGAGATTGATTTCGTCTCCACAATTGCCTCTTC -+ -?B;;@>A(,89?3@<3?########## -@SRR800764.25077 25077/2 -TATTTTATATAATTTTATTATCATTTTATTATAGCACGTCTATTACCCATATTATAAGGATCATTATGATTTGTATTAATTCCTTTATTTATATTAATAAA -+ -<@FBGI4AHA81?:DBC;C>BF*B<4*?GFG>9CEC4//8>))(6B@''-,?).)>C@C6;5>;=>BA>C############### -@SRR800764.25082 25082/2 -CGCCCCAAACTACTTGACCAAATTTGTTTGATTTCTGCCAGTTCAAGTTTTGATCTATTCTTTGCACTTACTCCAAAAATGCTGATTTCTCCACCGAAACA -+ -=@@++=B7A;DFFABEAC@3CACFEA?)???DF?1*CFBFEFH>>B@*0*9??BCCE).;@6>;;A######## -@SRR800764.25083 25083/2 -AGCAATTTTTCTGGAATTTCAGCTGTTTCCAAACTCAATAAGTATCTTCTAGCAAGAGGGAATAGGTGGGAAAAAAAGAGATTTCGGTTTCTTTTTTTACT -+ -@@@FDEFDHHAHHHEGGHJ>?AFHF?FHB@AHHIJEGIGHHHC?FGIGE>FFHGHGGGGIDCGEHHIIIDAC;=>BA@D?CDCCC:@CDDDB### -@SRR800764.25084 25084/2 -AAAGCCATTTATGACACCTCAGTGGGCTATTGGCTACGTCACAACGTTGATGGATTTCGTATTGACGTAGGCAGCATGTATTCTAAGGATGAGGGCCTACC -+ -?@?BBDB+ABF4CEB+ABAFG>??@D9CB))8=)8(.)=@>CE?CABCC?=>(..5(;@>((-;(:5AA:?'5<>AA -@SRR800764.25085 25085/2 -TCCACGTTCAATTAAGTAACAAGGACTTCTTACATATTTAAAGTTTGAGAATAGGTCAAGGTCATTTCGACCCCGGAACCTCTAATCATTCGCTTTACCTC -+ -=?@+BD2ABFHDDDE>ACFIIIFEDEHCG>B@C>>>A;@CD:? -@SRR800764.25086 25086/2 -TTTCATAAGAAGGGATATGAAGTATTGTCATTCCACAGAGGATGATATAAATCAGTCAGGTCAACACTGCTAACAAACTCCTCTAAAGTACCCAAGTTGTA -+ -<@;;D>>D:4C:<1A:A?CE<43,AEH<2+++AEC3*):?C@9:B9??@B*9EG@@FB9C)8BCH@GEHHIDI(.=C)77;;?DC776.;A####### -@SRR800764.25087 25087/2 -CTGATGAAGCAATCCTGGCCGTGGCCACTGGTTTCTGTGCAGAATCCTCCCTTTTCAAGCATGAAATCGCCTACGTCGTCGGTCAAATAGGTAGTCCGGCT -+ -;@;:?;?+=CDFDG3+CE9A))2E;7.(5=<873.;'3,88280AC@C:>>@:::@#### -@SRR800764.25088 25088/2 -GCTATAATATTATGGATACAGAATATACTTTAGAAGGTCTCCTCGATGATATAGGAATCCTCGAAATGGAATCTATATTTCTACATACTAATATTACGATT -+ -::8D;A4=,ACHHA+C> -@SRR800764.25090 25090/2 -AAAATCTAAGAGATATGAACGGTGATCTTAAGAAACTGCAAGAAGAACTTCCCAGTGTAGAAAAAGACAGTAATATAGTGATTCTTTGCCGCTACGGTAAC -+ -@@CFFFFDFDHFFAE4CEHDHGHI7BFBHCHIG>DHII9DGGEHGII3BDFFGIJFGC>?@BB##### -@SRR800764.25091 25091/2 -TTTAAAACCTAAAGGTAAACCTTTATATTAATAATGTTATTTTTTATTATTTTTATAATAAGAATAATTATTAATAATAATAAACTAAGTGAACTGAAACA -+ -CCCFFFFFHHHHHIJ:CFHIIIIJJJIIJJJJJJJJDIIJJJJJIJJIHGHHHIJJIJJJJJJJJJIJJJJIIJIIIGGGJFHGFGHEFBEDFCEECEEEC -@SRR800764.25092 25092/2 -AGAGATCAATAGGAGCAACATAATGAACAATGCCCATGAAGAGAACATTTCTTCTGTAACAGGGTTTAAGTCTACATCAGGATCACCTGCAATAGGGTCAT -+ -8@@A?D?DBCFHD@GIIH3AEHID@9A9AC9:E?)?:DBB?DDHC3?GGFEII>*9??FGBCG;).;@G;=AEE@=:A>A??CFE;66(66@>:@5,5>A3 -@SRR800764.25093 25093/2 -AACCTTATCCCTTAGACACAAATGATCACATCGAGTGGATGAACTGTCAAACGACCCAAAGTGAATATGATTCCAGAGATTTCTATGCTTTCCATTGTTTT -+ -@@@?DFFBFBDHHGHCDDDD3-;;;;>BCCDD? -@SRR800764.25094 25094/2 -GAATTTATTAGTGCAGAAGAATTGTTTCGAAATGGATTCTTGGAAGATTTCGTGGTAATATTAAAAGGAACAGTAGGTTTAGAAATGAAACTCAACTCAGG -+ -BB@DFFDDHDHFHJJIGHHFGIIJIIIEHGHGHIIGIIJIJIGDFHCEGIIGGGIDFHIDGHHFHIIJGGIIIHEHH=>C@D@DFFDCCACE>CCDDDDCA -@SRR800764.25095 25095/2 -TATACTTTATATTATAATAATTATTATTAATATAAACTTATTATATTATATAATTTAATATAATAATAATAAGATAATTATCAATAAAAATTACATTTTGT -+ -@@<=DDDDH??BHIIIGGHIEHHGHGIADDHEIGG@HHIJIJJIGIJI>GAHHGIE>HCGGHIIIJGGAGH@HIIIIIJIEIIGICGFCCEHHGGHEEHEH -@SRR800764.25096 25096/2 -TTTGGATGTTGTAGTCAGACAAGGTTCTACCATCTTCTAGTTGCTTACCAGCAAAAATCAATCTCTGTTGATCCGGAGGGATACCTTCTTTATCTTGAATC -+ -@BCBDDDFHHHFHIIHJJGGHIIG@CCCCCDDCAC::>CC -@SRR800764.25097 25097/2 -AATGAAGCAAGAACTAGCGTTTATTGAAAACGTAATAGCACAAGATTTCACCACCACATATTCTACTAATAAGAATGATAAAGTGAAAGGTTTGGGAATCG -+ -@CCFFFFFHHHHGIIEGIIAGIJIIJJJJIIJ?GGHJJJJJJJJ@DHGGGHIJIJJIIIJJIJJIJJCHFHFEEFFFFFFCCC>CEDCCB>CC@BD@CDDB -@SRR800764.25098 25098/2 -GTATGGGCACGTATGCCAAGTCGTTGTTCTTGTGAAGAGAATGATATGTGCAGTGGTAAAAAGAGCCCGTGACACCCAGCAGCAAAGTGCGACCGCGCTTC -+ -++1=1B>>D1CD######################################################################################### -@SRR800764.25099 25099/2 -ATATATATACAGGCAACACGCAGATATAGGTGCGACGTGAACAGTGAGCTGTATGTGCGCAGCTCGCGTTGCATTTTCGGAAGCGCTCGTTTTCGGAAACG -+ -@CCFFFFFFHHHGIJIJJIIJJJJJJIICBCGGGIGGDGIGHGIHGIIDDGGHIGGI=HHFFDEEDDDDDDBDDEDEC99@BBDBCED=A>(;3,;@;@3:A>:55 -@SRR800764.25101 25101/2 -TTTCTATTTTATCGATGCCGTGTCTGCTGCCATTACGTACAGGTAGGCAAAAGCAAACAAGAATAGCACTTTTTCACTTGCTGCTTTTTTTTGTGAATGAA -+ -@@@DDFFFBHHFDGI9EEHGDHGHBFGEG@FDDFHGGGGHIEGHDHHE>?BFHIEFF;FDFCGGG;;EHHCFFFCCFBCEE@E;>C@A>@=BBAC:AC>@> -@SRR800764.25102 25102/2 -CCAGCAGCCGCGGTAATTCCAGCTCCAATAGCGTATATTAAAGTTGTTGCAGTTAAAAAGCTCGTAGTTGAACTTTGGGCCCGGTTGGCCGGTCCGATTTT -+ -CCCFFFFFHHHGHFHIIIJGIGGIJJJIJIJIJHIJIJJJIJJHIJIJIJJJGAHIJHHHHFFFDDDADDDDDDDDCCBC@CC################ -@SRR800764.25104 25104/2 -CACATCAGCAAAGTTTCGCTTTTGACATTCTGTTAAATTGGTCCCTAACTGTTGGTGCAGACCTACTGCAAGACTGTTAATTATGGTATATTATATATCAA -+ -CCCFFFFFGGFFHIIIJJJJJJJJJJIJJJJJEHHJJIJIJEHJJJGIJIGEHIIFGHIJIEHDIJJJIIGHCHHHHDFFFEFDFECDCCFDEEEFFEEED -@SRR800764.25105 25105/2 -CAAATCGCAAGTTTTCTCTCTGCATTAACTAAACAATACAAAGACTTAGTGGTCTTCAAAGGCACTTTGAGGGACTTTTTGGTGCAAATCAAAGAAGTCGG -+ -@CCDDFFFGFHHHJIIIJJJIJJJIJJJJIIJJJIJIJJJJJJIJJIIIIHGIGHIJIJEHIIJJJJJGGIJHEFFFFFEDD?@CD:A>CDDDD>BC::?9 -@SRR800764.25106 25106/2 -TCATTTACTATCCATTATGTTATGAACGGGAACTATACAACTAACCTAAGAATTTTGAAATCACAACAAAAATAATCAACATCACAGTCTCGAAGGGATTA -+ -CCCFFFFFHFFHHJJJJJJJJIIIJJJJJJHHIHGHGIJIJIIJJJJJGHIIJJJJIIJJGHIJIIJJIJJJHHGHHHFFFFFEEEECCDDC5=??B@CDC -@SRR800764.25107 25107/2 -ATAAATGTGGAAAGCTTAAATAAAAAGGTCGACGAGGTTATTAGAACAACAACTTTCAAACTGAAACCGCTAATGGATAACTATCAGAAAATTTTGAATTA -+ -CCCFFFFDHHHHHJJIJJJJJJIIJJJJHHGGJJGGI?DFHJJJJJJJJIHHGGIJJJIIJHHHHHHFFDDDDDDDDDEDDDDDDDCDDDDDCDDCDDDDC -@SRR800764.25108 25108/2 -GAAGCTGGTCTGCCTTGCTTGGCCAAGTACTCTTCCAATTCGACTTGTTGCATACATTCGATACCAATACCAGCATCAATCTTACCTTCGATGATGTACTT -+ -B@CDDFFFHGFFGIIJJIJIIJBFGEHJJJIGGGBFEGGIGEHDFGIDG@DHGHJJGICHGCGHGGIJIIIJHHHHEC@DFFDCCACEA?ACCADDADEB5 -@SRR800764.25109 25109/2 -ATTTATTATTATTGTTTTTTAATAATCTTATATATAATATAAAAAATATATATATATTATATATATATATAAATATAATATATATTATTATAAATATTTAT -+ -CCCFFFFFHHHHGIHGJJJJJIJJIJIJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJGGIIJGGIIIJJIJIIGGHIJJIJIHHGHFHHGFCBEFFFDDDC -@SRR800764.25110 25110/2 -AGAATCATTACCTAGATTATAACGAATTGAAAAATTTGATCTACACATTACAGACAGATGAATTGAAACAAGAAACGACAACCGGAGACTTAAACGATGAC -+ -???D1AB4A,=:?F377787=7CEH########################## -@SRR800764.25111 25111/2 -TTTGGGTGGTAAAAATAATACTTCCTTAGTTCCAAGGCTAAAAACAATAGAAATGTATAGACAAAACGTTAAAAAATCTAAAGATCCTGAAGTGTTATTCC -+ -?B@FFFDDDHDHHJJIGIJJIIJJJJJJJDCGGIJ@DGIJIJIIJGIEIEHHIGGGHGIIFDFHGEIGDHHFHHEDCECECDCCC@@CCACD@C;@ACCDA -@SRR800764.25112 25112/2 -GGTGTCAAACGGTTACCCTACGAACAGTTCGCGTCTTGGAGCCCAATAAAAGAAAATGAGGCTTATCAGTTCTATCACTATTTAACTTATTAAAAAACATA -+ -?;BA=BDDHDAAFFI@A2CDH<12?G?*:1:D?0?(?F93BCCG######################################################### -@SRR800764.25113 25113/2 -AGGCATTTCAAATTAATGAAGCAACCCTTATTATGGCAATCCTTTCAAAATCCAAATGATCACCATAATGAGTACTGTGACAGTAACGGCAGCAACAATAA -+ -B@@=??:DDHHBHGHI@EEIC<@H9A@+AFHIIDC9?GIIIGGEHECGCF@DH@BFH@7AC?A#### -@SRR800764.25114 25114/2 -AATTTCAAATTTATTGGTTCCAAAAATGAGATTTGATCTACATTAGCAGCACATGCACGCAAGGTTTTACCACCATCAGCAAAGGCGACGTCTGGAATGGG -+ -@@@BD;BDFHHFBGB+HCD?D):DAFAD>@((:;:@DCCD## -@SRR800764.25116 25116/2 -AGAAATACAAAACGTTAGCATTTGCATTTGTTGGACATGTACTGAATACAGACGACACACCGGGACTTGAAAAAGAACTGGATTGGCCAGATCCTGAACTG -+ -11+4B+A:2AF+<<22+2+AFFFBHIGIIGA;FED@DC@CC(;;>;;;=????CC@ -@SRR800764.25118 25118/2 -AGCGCTTACCACTGCTGTACTGGTCAATCAAACCATTAATGAGCATAACTATCCAAATACTCAACGCTATACAAAAGATTAAGTTAGGTGACTGAAAGGTG -+ -##################################################################################################### -@SRR800764.25119 25119/2 -CATAAGTTTTTCAAATTTTCCTTTTATTATGAATTTGCGCAACGACACCAGCGCTATTGCTAATGCGTTCAAAACAGGGAAAGTACACGTGAAATTTTAAA -+ -BC@BBFFDHHHGFGI@AC>4>4 -@SRR800764.25120 25120/2 -CATGTCATTATTTGTAAACCTTCTCCCCGCTCCACCACTCATCATTTCTGTTAAGGAGGCAGTAGGGCGTAATATTGACCCAGAATCCCCAATTGTTGAAT -+ -@C@FFFFFHHHGHJGFHJGGIJJIIJJJJIEIJIIIIIIGIJJJIIFIGIGIIJIGGGIHGGCEEBEHFACBDDDDDCCCABABCCCCCBC<9:ACCB:>C -@SRR800764.25121 25121/2 -TCCAAGCTGGGTAAAGATTTCAAAATTTAATATAGTCGTCTTTGACCCTTTGAGTAAAAAGTGCTTTTCCCAAAATTTTGTTAGCAAATTAATTGACTGAC -+ -@@@DFFD>?F;2@7BEEHH=;.7?@B>)7;;;66@C(->CC:AC: -@SRR800764.25122 25122/2 -AACGATTCGAACGATACCGACAAGCAACATACACGTCTGGATCCTACCGGTGTGGACGACGCCTACATTCCTCCGGAGCAGCCGGAAAAAAAGCACCAGCG -+ -?@@7DBD>CFFF@E+?:EB<@EG9)0:BG9*??3@(44:909@B529(8<@-003<>@######### -@SRR800764.25123 25123/2 -CTTGACTGACCGTGAATACTACTCCGCCTTCCACGACATCTGGAACTTCCATAAGACCGACATGAACAAGTACTTAGAAAAGCATCATACAGACGAGGTTT -+ -??@DDB,AD:;F@EECCH>??CA;C@A?FEC:8D6DCGBG>BB8=.8CH@CCG>E/C>;ACAA>?C9>53@CCDCCD######## -@SRR800764.25124 25124/2 -AGAAAAAAGTTAACTAAAAAGTAAGAACAGCAAAGTTGATTGTAGCCTATATTGCTGAAATAGATTTCGGAGCTCCCGTATAATATTAAAGTGCACCAAGA -+ -CCCFFFFFHHFHGJJJIIIJIAFHIHIJIGGIJJIGGIIIJJIIG@FCEDEGIIIHIIGGHJJJEEGIGGHHFDFFFC?ABDCDDCDA@CCCCCDDDDDDD -@SRR800764.25125 25125/2 -AGTGTGCAGATAACTATGAGAAAATTCTAATTAAAGGATTTGCCGGTAGAGATTCTGTGAAACTACCGATGTTTGATCTGTTTCTGCTTGGCTGCGCTCCT -+ -?@?DDDDEFH?FAHGHJJJJJJJJJJJJEIJJIGIJJFGHIIJIGIFHGIHG@GHIJIGGIIGCHGGIJHHE7?C>DFEE;ACEECCDCCDD@BDDBDDDC -@SRR800764.25126 25126/2 -CCCGCTTCAGCTTGATTCCGTGCTTGCGCCTCCTGTGATTCTAAGAGTGCAATTCTCAACTGAATGTCGTTTTCTTCATCGGTGTCGCCTGAAAGTTCAAG -+ -@?@BDDDDHFHHFIIJEBH;C@FAHEIGEHIEFB*0?(:@::> -@SRR800764.25127 25127/2 -GTGCTTCTCTCTGGTGGTTTTCTGTTTTTCTAATATTGATCGATTTTACGGTGAGTTAAACTACTTCCTTTTATCGCAATATCATATTTAGAGCGAGAAAG -+ -@?DDCDECCEDDCBACCBCBC@A -@SRR800764.25129 25129/2 -AACGAAGTCAGTACCTTTAGCAAATTGTGGCTTGTTTGGAGATAAGTCTAAAAGAGAGACAGATGCAAAAGTACACGGGTCTAAGTTAGGGGACAATTGGA -+ -?@@BAB;D>AB@:5>;;5(>CD5>?>(5>ACD@AA:@AC -@SRR800764.25131 25131/2 -GAAAAGTCCAAGAACAAATAACGAAGAAAGAAAACAAAGAAAGGCGATTAAGTAAAGTGCTAGTAGAGCAAGTACGAGAGAAGAGGAAGAGGCTTAGACAC -+ -BCCFFFDDHHHHHJJJJJ@HIIJJJIIIJIJIIJJJJIIIJIIIJGIHGGGH4@FHIDHEHIHHHHGHFFDD?CEDDBD??CDDDDBBDDDBB??CCDDD? -@SRR800764.25132 25132/2 -AAAGAGTGGATGTTGAAGAGTCAGGTCTTTTAGACTGTGTAAATTCAGCATTACTGTCTATCCAAAAATCCACACCATTTGTTTCTTCAATACGTTGTACG -+ -?B@DDFA?DHDFHIGGH@F3<GHIIGC7=CHAC@DCCCBBEDACC?=;>AA -@SRR800764.25133 25133/2 -ATGCATGTGCCGTGAAGCGGGACAACCAGAAAAGTCGTCTATAAATGCCGGCACGTGCGATCATCGTGGCGGGGATTTAAAAGTTCATATCACAAAATGTC -+ -@CC@FFDBFFHHFHHEGEIB<1CDGFFHDFHCGE?FE<;BFHGDAHCA@@:9B/9.=A@8ABBCA>5<;@BD############################# -@SRR800764.25134 25134/2 -TTCTGTTCTACAGCTTGAATACATGCCGTGGATCTGTTTATCAAAGATAATGTCATGTAGCGTGGCAAGTCGACACAGCAACGTGTGGATAATGGATGAGA -+ -@@@DFFFDHFHHHGHEBGGHJIG,::EF@CEE3CDGFHC>4BFHGII*?D5(5:A@>:AA -@SRR800764.25135 25135/2 -ATCTGAACTAACAAGTAAAATATCGATGTTAGAAATGGTTACAATAGAAGAAAGTAGTGTCATTCTTTCGCGTCAAAAAAAAAATGGAATTTGTGTCTTTT -+ -@@@DFDDD4CCDFGIGEIGFEC?@?F9D9D?EEHIEGEGDGG:CC4@FHGGIHJJJJIJFGFEGHGGGEFGIICAHGGHECCDFBDCCEEDE -@SRR800764.25144 25144/2 -GAACGCTTCATTTTAATCTCACGCATTTGCAACCCATGCTGATGTCTGAAGCGCTGACAAATACTTCATACGTTCTTCTTGTGACACATTAAGAGGTAGCA -+ -B@@FFDADHGGHHJIGIDHIJIJJGJJJJJJJJJIJJIIIGJJEEGIJE>FHIJJG@FHIHGHJGHHHGFFF@D@BCCEDECCD@AC?CDCACDDD::@CC -@SRR800764.25145 25145/2 -GATGAAAAAGGTGATTTGTCATTTACAAGAGGTAGGTCGAAACAGAACATGAAAGTTGGTCGGTAGGTGGCATGCAGAGGTAGTTTCAAGGTGACAGGTTA -+ -@B@B>CC(::ACCD### -@SRR800764.25146 25146/2 -AGTGTTGGAGTTGGTACTTTCAGTGGTAGTCGCACTAGTCCTGACGTTGATGCTGGCAGTGGTAGTAGCACTAGTCCTGGCGTTGGTGCTGGCAGTGGTAG -+ -?@@1BD??AD?FFEIG4C@EEIIGHDFHH>HGE?@FF@D??D<4D@B?G(>CG<3CC;<+CH9C:B@CC############## -@SRR800764.25150 25150/2 -GAGCACAGTTTTTGAAACTACAGACGTGCATCCATTCGTTAAAGAATGGCTCGCCGGCCGAAAGTTGCGAGAACGGACAACTTTCTTTGCAGTTCAGCAAT -+ -@@@FDFDDFFFHGGGCHGIIIJJIHIGHGGEGDHFIEHHEGIJIIJEBFEFHH:A -@SRR800764.25152 25152/2 -GGAGAACTCGACAAGGTTTCCCTCCAAACACTTAGTAAATGACATCAGTATTTTCTTCCCAAACGGGGAATGCAATAGGGCAAGATATTTGCCTCAAAATC -+ -@C@FFFDFHGHHHJJFEGIJJJJJJJGIIBHJJJJHDGFFHJGIJGIIFHHIIJIJJJIGJCHIIJIHFFFFDEEEEECBCD?@CCDDCCDDCDCDDDDDC -@SRR800764.25153 25153/2 -TATAATTTATATAAATATAAAAAAGTCTCCTTTTTTAATTTTAAGAATAAATAAAAATAATAATTAATCTAATAAAATATTTTTTTAAATATATTTATTTA -+ -?B@FFBDDHDHHFFB:<BDC@>@A@@C@CCCC -@SRR800764.25154 25154/2 -GTCCGTAGTGGATGAAATAACAGGCGCAAATTTATGGCGGCGGAATTTCTTTTCGAGGAGGTACGACTTCAATTCTGTCATTGAACAATATAGCATATTGG -+ -@?BDFBDDBDFHFGICGHIJIIGJIJJJIIIIIIJGJJGIA/=',8@C(5:@C>=2?@0+5(+:&+55<::@AC(:>@:4:@:(:>CC>A:@######### -@SRR800764.25155 25155/2 -ACGAAGAAAATCTAAAAAGAGTACTCTTTGGACATGAAACACAAAATTTTACGGAGGCTACACTAGAACCGGGTGAAATAATCATTAGGCTTTATCTGAGG -+ -??@D;ADBDHHHDFBACF?+3,<<+AA<<11H9::C91??D@GGHAG9BG49F?6'5-.=7.7)).?;76=A>B/;C:@35@################### -@SRR800764.25156 25156/2 -ACAACCTTCTTGGTAGTCTTAGCTTTCTTGTGGAAAACAGGCTTGGTTTGACCACCGAAACCAGATTGTTTACGGTCATAACGTCTCTTACCTTGGGCAAA -+ -@CCBDFFFHHHHHGHEIJJFEHJIIJIGIIHHIFGHIGIJJGIJFIBFG?AACHCGGABE@D;AEEC@;?DDCCD;=BD@>CBC?CDCDCDCCD<>BB?B1 -@SRR800764.25157 25157/2 -TAAACAACCATCAGCTTCAAAAAAACCAATAAATCATTCTAAAAATTCTTTAGATGGTAATTTATTATTAGGTTTAACTTTTTTAAATTCTTTATAAAATT -+ -@@@FDEFFHHHHHIIJIGCH@HGHEHIIIHGGEHGCCAIIHG9DHIIGHJGIIIIIIFCHJGIGIHCHFFFH;@DFFFEECC@??CCACCDEDCDC@>@C> -@SRR800764.25158 25158/2 -TTAGCGTTCGCATGTACACTGAATTGTCCCCTAATGGTTTTAACGTTCGAATGAATAGTTTCTAAAAATCTGTTATTATTGATATTGAAAGTATCAATTTC -+ -?B<=?:D?:@?CBA4ABDAFHC@HCECE9?DGBDHII?BDDE>?;7@BD@3@CCCDE:>C>>;;AC:C@CD -@SRR800764.25159 25159/2 -GGCTGACTGGAGCATTACTAGGTTCATTACTCACTGGTTCTACTCATGAAACCTTACTTATTTGACCTAAAGCTAAAAGACACAGAGAAGCTGGATTGGAA -+ -8=??D=DDD=+2E??DG@CFGIIJI1DFHCCBD4=BFCBCFHIGGF8@C@GE;==>?BEED<9;>>CCC@?@AB9?==BA?@BB03>CCCCDC>>:CC9BBBC -@SRR800764.25163 25163/2 -TCAGCATTAGAAGACCCAGCCACAAATGAAGGCGGTGTCGAGGCCGCCAGTGAAGAGAAGACAGGCCAAGGTAGCGGGGCTGGTTCCCTTCCATGGCAGGC -+ -=?+=1=D,C:C<+:2+<+<3 -@SRR800764.25165 25165/2 -GCAATTGAATCATTCACCTCATTAACCAAATGTGACCCCAAGGTATCCAGGAAGTACCTGCAGCGTAATCACTGGAACATCAATTACGCTCTCAATGATTT -+ -B8+ADDBD>D,+,2ABEEFF:AF4C@C:6-=/58?:(5>>ACF> -@SRR800764.25166 25166/2 -AAGCTTAATTGTATGAATATTTCTATGTTACCGGTTGAATAAACCTGGTCTCAAATAAAATTGGTAGAATGACCTAGAATGACCCATCCGCCGCGGAATCG -+ -=:BD?DEDBD<:DFFCHDGCHDECH>HD:CDBHE4C4?*:CG@F@CGA?4BF9DF:6BBHG4=CF@4C;.==@/459BB@;AC(5=>>@@((-:;5@>(5@ -@SRR800764.25169 25169/2 -ATGCATAGTCACGAATTTTCTTTGTGAGGAAATTGTTAGGGATTGGCGAGATTTCAAAATTTTTCTGAGCTTTAAGGATCCTTTCATAGTAAGAGACGTCT -+ -B@?;:B:B=2:D?C1C:AF@HIDD<;2<8+:;?B?*?*?DBGHH3)*?D'768@)BBHIJJECD=;?)==A>@)..;>C6;CEC35>CADACCCC?C?### -@SRR800764.25170 25170/2 -AAGATTTATTTGCTCCAAATGACAAAACAAAATCATTAATTAGAGAAATTTTATTATCCATCATCAATAGGAATATCACCAAAGGTGCGTCGATAGAGTAT -+ -=;?DDFFBHHHFDHIIJJB@BHGHBH;GGHG?E=@;BAC>?@@?AA@:> -@SRR800764.25171 25171/2 -AAAAAATTAATTCAACTCAAGAAATTAAAAAATGGAGGCACTAGAGGCAAGAAGGCTTAGTGAGTCCTTGCGGATTGCTGTGCTGCACTTAGGCTGTTGGA -+ -?B;A+)A<+2:C,C<<,A+A<3CG9+AH9EHI##################################################################### -@SRR800764.25172 25172/2 -AATCTTTATCATGAGTACCATGAACAAAGAAAGTCACCTATCAGTGGTTCTATCGTATATTGTTTCGGTGCCGTGGGGGGGACGGTTGGTATTTCCTTGGG -+ -CCCDFFFEHHHHHJIDGHHHIJJJIJIJJIJJIJIGIJJJJIIJIHIGGIHGIJIGGIHIIIFGGGGGFGGIHH6BEB:@B9>@B9@B><:>C@:ACDDA< -@SRR800764.25173 25173/2 -GATCAAAGGATAGACAATTTCAATACAGAGTTAAATATCGTCAGCCTAACAGTAAGGGCAGAAAATACTGTCACAGCTAAGCATCACAATGCGTTCCATGG -+ -##################################################################################################### -@SRR800764.25174 25174/2 -AAACGGTTGTTACAAGCAAGAAATGACAAGGCATCCTCAGTAATAACGGGGTTAGCCACATCTTTTACACTCGTGGCAATGACTCAGCCCATTGACGTCGG -+ -?1=DDDD+<;3)=;=)7=?7?B>>>>;..3/(;;>A:@>35A<@CCC@C5BAEGIICHCHGHGHGCCEHCB7<>A@AAC@CD@9@;>CDCCCCDACEA: -@SRR800764.25178 25178/2 -GAATCACCTGTGGGAGTGAACCTCAAAAAAAGAAAACACATATTTCATGCTGCATCATCCTTGCAACACAACGCTTCCTGCAGAAGTTTTCGAACAAAAGG -+ -@??BDB:BFFBFBGGB+2ADFEBFC?HF@GGHGIIEFIGGIEEGGJI=FGHCGIG>@;=3=>==7BD>?=?A>@B(,:@CCCDC>A(:AC>@######### -@SRR800764.25179 25179/2 -AACATTTATAAAACCGTTGACAAGATCGGTGTAAATAGAGTCGGTATTGCCGACACAGTTGGATGTGCCAACCCAAGACAAGTATATGAACTGATCAGAAC -+ -CCCFFFFFHHHHHJJIIIIIJJJJJJJJJEFFFIIIJHIJBGHIDFGIBGGHGGJHHHEECFDCFFCACCD?BBDDDBDDDBACDEEECDACDD@CDCDCD -@SRR800764.25180 25180/2 -AACGTAAGTCTGGATAGAATTGAAGACTGATACAATGGAAATGAAAAGTAACCATTTTGGTAAGTAACCTTTTGGCATTGCTGCCAAGGTGGTCTTGGTTG -+ -?@@DB>ADC,A@B376;.6;?;(;A>5@FGEHGIEEHEHADB@DFF:@>6@DE;@BACD??CCD@AD?',5>@3;5>ACDC# -@SRR800764.25183 25183/2 -ACTGCTACTTATGTCAAGGCAGTGGTCAGGGACATGAAGAAATACATCAAGGCTAGAAAATACAGACAAATTCCGGTAGGTTACTCGGCTGCTGATATCGC -+ -BCBFFFFFGAHHHHIIIJIIHIFGHCHHIIJIJJJIGIJJJJEIJJJIBHFGIIJIIJJJGGIIJJIJJGHCEE>A9BBC@>ACCC?BDDDDCDCCDEDB# -@SRR800764.25184 25184/2 -ATAGATGGAACTTACAAGTATGGAGCTTTGGATGACTTTATCAATTCATTCACAGATTCTGCATCTGCAGGAAAGTATGCTGTAAAAATAATCATCTTTTT -+ -@CCFDFFFHDFD:CDGIAACIEIJFJADCHGIEFEGCBBHHGE@G@HHEHHIGHH;4BBGI>HGIIA)7=DG@EH;==);@>:3;AC>@;>CD -@SRR800764.25185 25185/2 -GTCAGTGGCAAGTTTGATATAATCCAGATCTCTAAGGGGTAGTGCGCTGATTTCGACCATAGATGAAGACGTAGAGCTACTCAAACCAAATGACGAATTAT -+ -@=?BDDDEFD>D2A:CBD4?EDAF<@@H;CAC@A@?BDC:@:?2928@: -@SRR800764.25186 25186/2 -TAGGAAACAACAAATTCCGATGCTTACTTACCCCTTAAATTTTCTCATTGCTCTTCATTGAGGTTGCATAGCTCACCATATTTGTCATGGAAGGTCCCTTA -+ -CCCFFFFFHHHHHJJJJJJJIJJJJJJJJJJJJJJFJJJJJJJJIJJIJJHIJIJJJIJJGJJFHIJGJJJJJHHHHHFDFEFFCEEF@CCEDDACDBDCC -@SRR800764.25187 25187/2 -AGATTACGTTGGCCGAATTGGTTCAAGAATCGATTTTACAACTGTCTGTTTTGAAGACCATTATATTGAGTTTTCCCTTCGAATTGACCATTTCGAAGATT -+ -B@B+AB8DHB;+??9:CFHGDBFF1+A3FEF4?E9EFGIEGI*)?C6DD)??@AFHB@CB:',.;7.;(;@C>3@@:;AB=@8=C>>A@C>:>>@C############ -@SRR800764.25189 25189/2 -CTCTTCAAAGGAGAACAGGCCATACCTTTTGGAATCTCCTTCAGGACTCTTTTCATGTTCACTAGTCAGGTTTTCTCGGACATTCTGCTCGTTAAGATTAT -+ -@@CDFFFFHHHHGJJFIIIJIJJJIJJIJJJICEGJJIJJJIIIICHEIJHHIGIIE@HGEHGIJIIIFG7CGHHHHHBBDBECCEDCDCD@B@?CCCDDD -@SRR800764.25190 25190/2 -GATATAAATAGTTGCAAACTAAAGTAAGATAACTGAAGATGATTAGTCCTGTTTGCATACATAGTTCTGTTCTTGTTCTACGCTGATGCGATCAATAAAGT -+ -@@CFFFDDFFHHHJIIFGIJJJIIHJJIJIJIIHIJJGHIJIJJGI>FGGFHGIIGHGIIGIGIBFIDIGEHGIIGHCHIDGGHHGGFFEC;ABACDDDC; -@SRR800764.25191 25191/2 -TTATAATAGGTTCCTTTTAGATGATCTCCTAATCAACATCCGTTTAACTGATATGATTATTAACGGAAACAATGAATGCATAGAATATGAGAAAGGACATG -+ -CCCFFFFFHHHHHJJJJIJJJIJIJJJJIJJJJGIJIFIJJIDHIGIIJFIJIJIJIJJIIJJJIIJJJIEEGHHHHHHHHFEFFFFEEEEEEEDBDDDD> -@SRR800764.25192 25192/2 -GGAAGAGAATCAAACCAAAGTTCCCAAGAATCACGAAACGAAATTACGAATTGGATGCAAATTGTGTGAAATGGAGTTTTGACACATGATATTGAGTCTCC -+ -+1?7:BDDDC;C################################################################# -@SRR800764.25194 25194/2 -AAACCCGCTCAAACCAAGGCATATAGAGGAAGCCTGGAGAGTACTACAAACAATTGACATGAGGCATAGGGCTTTGACCAACTTTAAAGGTGGTAGACTCA -+ -@@CFFDFFFHHHHJJJJJIIGIIIIIGIJJJIJJIJJJJJGBFEDCGCGG4@@@)7=CC@EHHC>AC@?B;@6>53@=A@A#### -@SRR800764.25197 25197/2 -TGGAATCTAAATTTGCATGATTCAGTTGTTCCCTAGGTGACATTTTATTGAGGATTCCTCTATATGATATAGTGTTCGCTACTTTACTATTTGGGGTCGTT -+ -CCCFFFFFHHHHHIJIJJJHIGGIIHJJGIJIJJJII?EHHIJJJJJJIJJJJJIJIJJJIIIIIJJIJJJJIHHIJIJJJHHHGHFDFFFFFECD8?BD? -@SRR800764.25198 25198/2 -GGCTACGCAATCTGTGTGTTCGTCGCAAAACACAGCGACCACTGACGGTGTACGAAATCAATTTCAGAGTAATGGTTGGTGTTCAAATAACTGTGCTGGTC -+ -@??DFBDDFFC:@>;@;:@5::;>:++2<++(+>C3:A@344>@CCC#### -@SRR800764.25199 25199/2 -CTCTGTTCGTCAGATAAATCACCTGCGTTCAAGAAATAATCCCATCTATGATTCCAGACTACTTCAAATTCTTCTCTCCAATATACGGAGTAAGTAAATGG -+ -:1+442A,2C1C?+CFH+A..=)B=))..)...7)7@D@D;6(;8(--(-5>CDCC -@SRR800764.25200 25200/2 -TCCACCCGTTCAAGTCTTCAAATAAACCTTGAAAATTCTATAGTAATTATTGATGAGGCTCATAATTTGATAGAAACAATAAATTCTATATATTCCTCTCA -+ -CCCFFFFFHHHHHIGEIJJJJJIGIJHIJJIIGJJJIGIJCFIDGIIIJAGHIIGIIIFIJIJJI>GIIIIIGIJJJJJHHHHHBDDFFFFFDF@CEEEDD -@SRR800764.25201 25201/2 -AAGAAAATATAGAACTTCAATGGCAGCACTTGAAAAAGAAATTAAATGAATTGTATTCTAGGTTTAACTTCCACCGAGATCAATTATCCTTTCAAGTTAAC -+ -CCCFFFFFHHHHGJJJJJJJJJJJJJJIJIIJIIJJJJJJJJJIJJJJJIJJJGIJIJJJJJBGHJJJJJIJJJIIHHFFFFCEEEEEEEDDDDDDCCED@ -@SRR800764.25202 25202/2 -TCTAGTCCGGAAGAAATCTGCAAATTATTGTCTTCATTCAAAAAAGTTTCCTTGGTATCCAAATTAGAGACAAACAATGAGCTAGAGGGATTATCGGATGA -+ -@@FHFHIHGJJGGIGGIIJIJGEEGGFIIJEGIJIIE/?DDGGHHICB@FGGCHIJJFJJHHGFHFFDECCACEEECCBDDDCDCDD=BB>> -@SRR800764.25203 25203/2 -TCTATACTTGCAGGCACCTTCAAGTTCTGATCAGTGTCCATCTCTTCATTTTCCAAAGCAGCGTCGTCTGGCTCTTCAGTTATGGCGCCATTATCATCAAA -+ -BCCFFFFFGDGGHIIHGCGGGIIBB>CHHEBCC@CB;>;;?CA;ADEDDD> -@SRR800764.25204 25204/2 -CACAGATTCAATGACTTGGGAGTGTACTTTCAGTTTAGGCCCATTCGCTATTCAACATGTTTGGTGGCTCGCTAAAGGGTCCCTGCTCGTCACCATATTCA -+ -BB??4BB4?:DDFADD<=)=)B=4CF;EEE3?6?(?@7>C@>>6;(;>A;-5555;?BB? -@SRR800764.25206 25206/2 -AAAACACCATACAAGTACGTCGATATGGCAAAAGAGTATAACTACATTTCTCCCTTCATAATGTGCCTTTCAGAGCAATGGAAATACGTTGACAAGAGTGG -+ -@B@FFFDFFHGHFIECFGIDHIIBEGGGGIHGIGII:B9FHIDHIFIIIGAFHDIGIIJCGIIGEHGIIHHHHGHFFFEFCCEECEDD@ABDCCDDCB>@? -@SRR800764.25207 25207/2 -ATATACTTATTAAATTAATATAAATAAATGAATAATATAATATAACTATATTGAATTATAATCTATCTATCTTTTTTTTCCATATAATATTAAATAATAAT -+ -@B?:A=DDB<4CFHIGH?BFCB8=@FGGJIGGEGGDG:CDDEEHFCC@BDFFF:>ACCCC;; -@SRR800764.25209 25209/2 -CGTTCTTCTCAGCACGCTTTTGCATAATGGTAGAAGCACGCAAATGGTCTTTTCTGACAAGCATAAACACTTTTGAGCCGTACTTGGTCAAGAACTGAGCT -+ -CC@FFFFDHHHGHIJIJJJJJIGIJJJIJJFGHCGHIJIIJIIGHGI8BFFGGHHGAFHJI9@EEHEHFEEFDFDE?@CD;@B=ACCCDCCD@?CACACDD -@SRR800764.25210 25210/2 -TAATGCAGAGTACACCTTGAAGAGAGAGAAAAGAAAATCTTTGAATCCATAGCATAATAGCGATCAACGAAACTTTTTAAGAAGTAAAATGAACTGAAAGG -+ -@CCFFFFFHHCFHGIJJJJJJIIJJJIJJIJIJIJJJHIJEIJJJJJJJIGIHIIJJJJJIJJJJJJJHHHHFFFEEDDCEEDDDDDDDECDDDDDDDDD? -@SRR800764.25211 25211/2 -CTTTGCTCTGCTGGTTTCCGATCACTCTATGGCCTTGAGTATCTATTTCTTTGAAACGATCCCTGGATAACGCATTTTTAGAGAGATCTGTTAGTAATGAC -+ -?@?DDADDFHHFHIFGHIIIGGIICHIJJGDGIIJIFGGDBGFIIIJJICGFFHGI@FHGGGGGHIBHIFGFGF?ACCEBCDDDDDCC@@5>CACDDCA:@ -@SRR800764.25212 25212/2 -AGAAAATGAGATAGAAAATGAAACAGTAAACAAAACAGAAGACAAGGCTGAAAAAGGAAAAGAGGAAGAAGTAAATACCAAAGATAACAAGGAAGAAAAAG -+ -@@@FDDDD?FFD?GHIEHEIJIJGHHCCDDDC?(59AC??B# -@SRR800764.25213 25213/2 -CAGGTGAGTTCATTCATACTTTGGGGGATGCACATGTTTATAAAGACCACATTGATGCCTTGAAAGAACAAATCACCAGAAATCCAAGACCATTCCCGAAA -+ -BB@DBDDEDDFHFIGBHGHFJHBF@D8AHIEGHIEGD<9BDGCHF@FF@FBBGGGIGGCAHGGIGIHHH@DBCEDAED?ACCCACCCABCDCD>@B>?BB3 -@SRR800764.25214 25214/2 -AATACCTGAACTCATGGCCAATCCACCTACCAGAAGGCCTGATAACGCAAATCACGATAACAATGAAATAAGCAATAAAAAACTTGAATATGGATACCCCA -+ -CCCFFDFFHHHGHIIJJIJJJIJJJJJJIJIJJIJJIIJIIGJJJGIJGGGEGIIGHGJIHEEHHHHFFFFFFEEEDEEDDDDDDDDDCEADCCCDCCD@7 -@SRR800764.25215 25215/2 -TTCATTATCAGGTGACGAAGCGGCTCACAAATTGCTAAAATTAAAGATTGCGAACAATTTGAAAAAAAGCGTGGTAGATATAATCATCAAATCTAGTTTGC -+ -@@CFFFFFHHHHFHEGGGJDFHAGEGIIJIGIGJG@FEGICDACDDDCCDC@CCAC::4@:@C -@SRR800764.25216 25216/2 -TTAAGCGGTATTCTAAAGGCTCCGCGAGCGAGCCTCTTTAACCTAATGCAAAAAAAAATTGTTACGCACGTTCCCGGCTTTTACCGTAATAGTAGTCAAGA -+ -@@CFFFFF@FHHHJJJJJJGJJJJJJJJJGIIDIEIJJIJEGHFGHHEFFCFFFDDDDDCCDDDDDDDDDBDDDDBDBDDDDDDDD@BDDDD@DDBDDD>3 -@SRR800764.25217 25217/2 -TAATAAAATGAACTATTTATTACCATTAATAATTGGAGCTACAGATACAGCATTTCCAAGAATTAATAACATTGCTTTTTGAGTATTACCTATGGGGTTAG -+ -@@@FFFDDFGHHGHGBEBCHJIHJJ>HIGIHGDFCEFDCEGEAHDHH?DHFDCGGFEDHGGIJJGGHDGFHEHIHHGCHIGCE=?EHFCFBDEA@A##### -@SRR800764.25218 25218/2 -TTAGACGTGTTCCTAAAACTTTTGACGTTTTTTGGCGGGTAATAAGATGCGTCTACCCATTTTAAGGAACGCCCTCGTAACAGACAGAACGAAGAGTGGCA -+ -@@@DDDFDFFHHHGIGIJJJGIGIJIIIGGDE@@DBHHH4=A@@A@C@C>??@@?C:9::CCC@C>>AAA;;>B>B928FEEIEACHBI:>(5;28-)0&&&89BD(3:???BBC######## -@SRR800764.25222 25222/2 -ATTGCCAGAAAACGACTGTCTTTACGCCATTTACGATTTTGAATACGTAATTAATGGTAATGAAGGTAAGAGATCCAAGATTGTTTTCTTCACTTGGTCTC -+ -;?BF;;4BHB?AD:@?C:CFBCA77=BC;@@@:(6;A3;@->;?>555@>CA55>:@C -@SRR800764.25223 25223/2 -TTTGAATCACTGCAGAAATATGCACTGCGCCTTCTTTTTCTTTGCCTGAAGCACCCACACACAAGAACAGGAATGTGAATGGGCTCCCCATATCACTTTTA -+ -=?;;4+,=:=CF:+3+A+33A:,9*?38((-5((--;D3?=AD(6?C########################### -@SRR800764.25224 25224/2 -CTCAGTGCTTCTTTGAATTCTTCCTTTTTAGTCTGCCTGCCCTCTCCTAACCTTTTAGAGCTTGTCAACAAACTTGTATCTATCTTATAATCTTGAAGTTT -+ -CCCFFFFFHHHHGJJIIIJJJIIJJJIJJJJIJJJIJJJIJJJIJJIGIIHIIIJJHIIIIIJICHHIJEJJIIIJFFGHGHFHFFFFFFDEECC>@C@CA -@SRR800764.25225 25225/2 -AAACCAAAAGACTAACCAGGAAAGTTAATCAGAGGATGACTGTTTTTGTGGTGGGGGGGCGAGGATGTCAGATTCTGCTGACTTCGCAGCGGTAGATGACT -+ -:;?+4A;DDBCFHGIGHBB@+CC:ACAC@::449>C:8099&)055<44:>@@ -@SRR800764.25226 25226/2 -TATACTTAGCAATTTCATGTTTAGTCCCGGCCCCAGTCGGGACCCCGAAAAGGAGAACAATTAAAATGTAAACTAGCAGGTACATATCCTGTAAATGTTAT -+ -@C@FFFFFFHFH?CEFHEB?ABFGHEEE@::CFHHEHAFEBD@@CGGGAABEE;BB2ACCCC@CAADDCC@CCC@@CAC?(:(::4((4@@C34:>C>ADD -@SRR800764.25227 25227/2 -TAATAAAGGTCTAATAAGTATTATGTGAAAAAAATGTAAGAAAATAGGATAACAAATTCTAAGACTAAATACTATTAATAAGTATAGTAAGTACCGTAAGG -+ -@@@DD?DDHFHFHIIGGG@JJHIIIIIBFCHIAGCCDHIGEIH9FGHG4?DGGIE@=FCGFGHHEGI@GHIGHHHH>CE?BCDFDFF@CCCEECED@DDDC -@SRR800764.25228 25228/2 -TAAAGGCCACCATCGGAGAGGGTTTAGATATTAATGTAAAAGGCACGCTAAACCGCAGGGGAAAGGGTATCAGAAGGCCTAAAGGCGTATTTTTTAGATAC -+ -;;?D?BD?DDDHDGBB?'<557@E;=HFB8/''55;?,5::;55>((2<>>4>@@<9)0?>:>AB??4>C# -@SRR800764.25229 25229/2 -CAGAACGTCTAAGGGCATCACAGACCTGTTATTGCCTCAAACTTCCATCGGCTTGGAAACGATAGTCCCTCTAAGCAGTGGGTAAACAGGACATGATAACA -+ -@@@DDDDDFCB?FGG=DGFHICDE@HC444FECID8EBGG:)=FHG@GGGCEAD?AHHAHHC -@SRR800764.25231 25231/2 -CAGAATAGAAAAATAGATCGCCGACAATCGAGGGGTCTTAATTGATGGGGACATCGTTGGAGCTTATATAAGTTTGTCGCTACTTGGCGAAGATGGTTGAG -+ -;18=B;BDDAFD8AC:((,9>75AC################ -@SRR800764.25232 25232/2 -AAAGCACGCATAAATTTGGCTAAATGCATTTGCCTTGCGCTTAGTTCACCACGACCAGAAAAATCCGTACGGTATAGAGCCATAACAGAATCGACCACAAT -+ -@@@DFFDADAFHAEHHEHGGCEGGGEGBFHIJIIIJJIIJJIGGBFFIJIGGGEGHGHEFHFED:BCBECDD5=BDDDA>AACCCCDDDACDD?BB>DBBC -@SRR800764.25233 25233/2 -CAAAATTTCGAACAACCTAGCCCTCGTTTTCGCCGCATTGGAACACTTGAAGAATCTAAGCTTATTAGCTGAAGAAGTTGTAGATAAAATTGTTAATAAAT -+ -@@@DDFDFBFBHFGJHGGIIEIB;EADBHCFA:DFGH@FG3C4)=.77;77BCEC).)7));@DE@;3(..>C>@>(53555:;>C@(:;5>34:>@C@## -@SRR800764.25234 25234/2 -TAATACATATAATTCCATTTGTATCCATAATTCTCTTCATGTTGAGATATATATCTTGAGGGGTATTCGTATCGCTTGTATACAATGATAATCGAGGTAAA -+ -B@@B==ABFFHHFIJIGIJIIJIJJIIJIJJIIJIHHIIIJIIIJIGEHIIHAFGAFFGGIGIEFHH)=FHGGC@C@CHFEHAE>DFF>C@ACCA@BDCCC -@SRR800764.25235 25235/2 -TATATATATAAATATAAATATAAAATATACTTTTTATAATATAATATAATCTTTTATATTTATTAAAATATATATTAATTATATTATAAATCTTATTTAAT -+ -CCCFFFFFHHHHHIJJJIJJJJJJJIJJJJJJJJJJJJJJJJIJJJJJJJJJJJJJJIJJJJJJJJIIIJIIJJJIJJJJIJGJJJEIJJJIJJJJJJHHE -@SRR800764.25236 25236/2 -TTCGGGGTTCCGGCTCCCGTGGCCGGGCCCCGGAACTATTAATAATAAATAATATAATAAGTTTATAAATAATAAATATATAGTCTAAACCTCTTTTTTAT -+ -@CCFFFFAHHFHHGGGIJI;AHIJIGEGAGIIG=BFDCCCEEECDDDCDD>CDDEEEEDC>5@CDDDCDCDCEC:@CCCDEDD3>CACC>?9<:<4C:3I:F?FH+???F1B909:90990*00*9/?E?C:?6@AEE:AC: -@SRR800764.25238 25238/2 -CAGAAGCTTTCTAAATTAAGGGTTTTAGAGATATTATCCGGTCATGACATGATCAAGGAACAATACGGAGTACCATTGCTTGATAAAGATGGCAATTCACC -+ -?@@D?DDFHHHHDHIHGEHIII+ACGDHIGIIJIDHIIIEGGGGHCDBGHFEHEIGIJGIIGIGGIJJIHHHFEFFFFDEEE<@@;@@CDCC9>CCCDCC@ -@SRR800764.25239 25239/2 -GGAAGAACCTAAGGTTATATGTGACCTGATATCACCAGCTGCATTTTGTCTCTTAGAGCTCGAGCGTAGTTTTGATTGCAGTTTGTCGGTACTCAAACCGC -+ -B@CFFFFFHFHHHJHIJIJJIHHIJJJIGIJIIJJJIJJJGIJJJIHIIJ>FHIIJIJIIJJGIJIEHHCHFFFFFEEDCEEEEDDDDC?BDCCCCDA@BD -@SRR800764.25240 25240/2 -AAAAGGCTACAATCCTCGCATGAAACTAATAAAAACGAGCACAATATAAGCCGAGACGTAGCGTTTAACGTACTAACACTACTCGCCAAACCATAAGAGCT -+ -+11BD2+2=DH;?BBDCDC@CADDDBACBBDC>>@ -@SRR800764.25242 25242/2 -TACCTCAGAAAATACTGTTGAATTCTTTCAAGGGGTAGCAAAACTGTCCAGAGCTTATATCTACCTGTGCTCAAAATACAGTTGAAACCACCTCTTCCTAC -+ -@@@FFFDEHHHHGIIJGHGIJJJJJIIIEGHHIIJCFGIJGIIIIIIIIIGIIBHEGHGCGGHGIIGGIJJIGGIHFHEHFDDFCEDDCCCCDDCDDCD@A -@SRR800764.25243 25243/2 -TCCCGTGGTCAATGAAATCAAAGAAGGTACTGCAAACCATGCTAACCCACCGATGGCATATGCTTTCAAACTCGCTGCGGGACTAGCAGAAATCGCTTTAT -+ -:+=1+=D:FB?F8D9DGI@HAH>BGHIB@C8CHCHCGH?H;)7?C7;7?9=@>>(5;5>8ACC###### -@SRR800764.25246 25246/2 -TCGATTTTCACTTTAAAAAACCAGTAATTACAGTAAGAAGCAACAGTGAATTTCATTTGGACTGCCAACTTAATATATGTACTAAAATCGTCCATCATTTG -+ -?@@+B,AD8F?DA>EEBDFGEH+31:9:4?99?DGG>FHHAB*?B)=D=@@=D4.7?ACEEE?BBD>?7@C@?########### -@SRR800764.25247 25247/2 -TTGCATTTAGGCCATGAGCTTTTCTGGAAGAGGCTGAAGACCCCTTCAACACATCCTGCTGATCACTTTTACGCATTTCCCTCAAAGCTCTATTGCGCATT -+ -@@@DBFDFHHHDFGB??CHGIJJGIIFEGGIJJBHIHHGIGIJIGIGCACD########## -@SRR800764.25248 25248/2 -CAATCTATTGAAATACTTTAAGGATATATCATAATTAATGATCTCAAAATGAAGTTTTCCTAATTGCACTAGACACCATGGCATTGTGTCTTTAATATGAG -+ -CCCFFFFFHHHHHJIJJJJIHIJJIJJJJJJIJJIJJJJJJJJJJJJJJJHJJIFHHIJJJGIJJIJJJJJIIJIJJJIIIJIJHEEHHFFFFFFDCDEDE -@SRR800764.25249 25249/2 -ATTTAATAAATAATTTTTAATAAATATTGGTATATTATCAATAGGTTTTCAATTATTTAAAATATAATCTTTAATAGCTTCTAATGTTTTTTTTTTTATTT -+ -@@@DFDBDHBDHFGIIIGDFHGGHEJIGFGIJG@HBHGGEEFIGGIGIG>@DFGD@DGIEIIEHGGBC++++3AF<+AFII9***1?**:)))?*?4***9*(0??*9B8))8)/@78C;==7=7)=EEH######################## diff --git a/latch_cli/services/init/example_snakemake/data/samples/C.fastq b/latch_cli/services/init/example_snakemake/data/samples/C.fastq deleted file mode 100644 index e022e580..00000000 --- a/latch_cli/services/init/example_snakemake/data/samples/C.fastq +++ /dev/null @@ -1,1000 +0,0 @@ -@SRR800764.25001 25001/2 -CTCGTTGATAGCAGCAAAAACTTCTGATTCAATGCGTTGTGTGCATCAGCTACGGCAGTATTTGACGGTACTATCAAAAGACCATTAATATTTTTTAAAGA -+ -??1B=+AB:?:AFB;C:CF??EFDHHGCCBCCF@E?1:@DDGHCC4*?BHCGAAAB;E==;@E>EE=D';>(;>A@5>CCDCDCDCCDDEB@@C@BDDDDA -@SRR800764.25002 25002/2 -TAGCACCTTCAGGACAATGCAAGTGGATAGACGCCTTTTCAAAAAATCTGTTCTCATGGAATTTTTGTGCTAAATACATCTTGGCGAATGAATAAGCAAGT -+ -;?1B4ADEAHD?83EB:FGIII<3ABCBIHJGGBGHJJJG>F@DEBD>GGBB8=C;)==7CAHEH>4?=:@;;7;@;AEEECC;>@@?B::>CDC@@C3<> -@SRR800764.25003 25003/2 -ATTCAAATTGGCAATCACTCAAGGCTCCTAATCCATACTTTTTAGCATAAGTGATATTATAGTGCCCAGTGGCTAGGGCATCCCAACATTCATTTAGGATA -+ -@@@D?DDDHHGFHIGGGIJEHIJIIJJIJIIIGIIJIIIJIIG?13>>>ACC###### -@SRR800764.25004 25004/2 -TATAAATTATTAATATATCCTTTTTAATAAAATAAAAAGGGGCATTATAAATATTAATAATTAATTTTTTTTTTATTTATATTTATATATATATTAAAGAT -+ -@CCFFFFFHHHGGJIJIJIJJJJJJJIJGIJJJIJJJJJJJJIDIJJJIJIIJJIIHIIJJIJIIHJJJIHFDDDDDEEEEFEFEEDEDEEEADECDCCCA -@SRR800764.25005 25005/2 -AACTACTGCTTATATATGGTGCAGAAAAGTGGCTCGGAATGAACACCTCTTTTAATTAAAAATTCATTTATAAAGTACAGGGCCTTCACGCCGCTTAGTAT -+ -@@?BA;B?DCFDFHHBEAEEE>@BAH@@@0?6BA*9?9BB(B(?################################################### -@SRR800764.25006 25006/2 -TTGACAGAAGATCTATATGACGAATTGCTTAAGCACAGATTGAATATTGATGAAGCCTTGAGAAGGCTAGGATCCAAGAGACCAAAAACCAAAATGGTTAG -+ -@B@DDFFFHH8?DHGGGHIGGIIIGGHIHEBFIHIGDHGGGF>D>4?@DGBDEEH?FCHIEE=EGEIJICGHECE>:AB>;;?AC@AA?=AABA:>C>:A# -@SRR800764.25007 25007/2 -TTTTAATATCAATAGATGCTGGTGTTACTAAAGGATTACCAGGAATATAGTTATCAGGATGCTTTTATAATAAATATAAAATGGACTATATCTTCATAAAA -+ -?@@FF?DFF?HHJFGHHIGII@GGGGHBDBHICBGG?DBF?BBGEIEHIG7?EEHFFEC:ACCCDDCEC -@SRR800764.25008 25008/2 -CTGACTTATATATGCGAATGCACATGAATAGACCGCATATGCTTCTTATCAGTCTTACCTCGCTTATCTTTCCCCATTTATTTGCCAATCCATCTTATCTT -+ -@C@DFFFFHHGHHGIIIJIHIIJJJIJJJJJJIIIIIJJJJJIJJIIIIIEFCHIEHGIGIIJJGHHHHFDFFCDCCECDEDEDDCCCCDCCDCCCDDCC@ -@SRR800764.25009 25009/2 -TAACTTTAGTTTTCAAATCTATCATCAATTCTTGAAGAACTGGAGAGCTTTCTAACGTATTCCCATATAATTCTAAAACCACGGCGACCCAATCCGCTACA -+ -CC@FDFFFAFHHHBHIJIJJJJIJJJJJJJIIJIFIJJJIJJHIJFCADHGGHIIGIBFHIFGGIDIJEIIIGIIIGEHDEEEFFDDDDDD?CCCBDDDD@ -@SRR800764.25010 25010/2 -AATAAATAATATACTATGTTTTATTAAATGAGATAATAATAAAATTTTATTATTATTAGATATATATTATAATGTATTATATAACTATCATAAACAACGTA -+ -CC@DFDDFGHHHHJJJIIJJJJJJJJJJJJJJJIIIIJJJIJGIIGIIIJJJJIJJDCGIHHIIIJJJJJJJIIBFGIIIJJIJJJJJJIJGIIJHHHF?> -@SRR800764.25011 25011/2 -TAGTACTTATGATGGTTTTGGTCTAGCTTGGGCAATTGCTGAACATATCGCAAGTAAGATTGGATGTTTCGCTTTGTTTGCAACTCACTTTCATGAATTGA -+ -CCCDFFFFHHHHHJJHIJJJJHIJJJFJIJJJJJJJJJIJJJJJJJIJJJGHIJHJJJJJJJJJJJGHIJHHHFFFFFEEEEEEDDCCDDDDDEDDDEEDC -@SRR800764.25012 25012/2 -GAATATTTATCAAGTGCATAGGATATGAGAAATTCTTTTATTGGATCAATTTCTCTTGAATGAGTTTGCCTCAACGAGTCGAAAGTCAAAATATTAACCAG -+ -?@@D=:ABDFHABHHEBHEGBHC@FEGGBFHEGGDHHG:BDHGCHIJIBFIJBG@HCC;/BB@DECC=>;>C>@BCDDD@ -@SRR800764.25013 25013/2 -CCTCAGCAGTAACTCCATCTACCTTTGGGGATTTGAACCATCTCATTCCAGTTTTGGATAACTGCGATTAGATTAAAAGATTAAAAGATTATCGATTAGAT -+ -CC@FFFFFHFHHHJJJJIJJJIIGJJJJJJ?GHJJJJJIIIJIIJIJIIJHFHIJIJGGIJJEIJIIJJHGHHHGFFFFDEEEEDEEDCDDDDDDDDDDDA -@SRR800764.25014 25014/2 -ACAGACTCTGTTAATATTTAAAAATTTTTCCTTTTCGGCAAGCACTGTGTTAACTAATTGTGCAAAAGCTTTGCTGGTTAACTCGGACTTCAACTTAGACT -+ -@@BF;;DDFHDFDEGGGIHHJIIIJGGIJJJIGIJJJIJJEHGG?FGDBDEGGIG@CHHIEFHCDDEEGGHGCEECCDDFFEEDDDDBBDDACDCCD@CC: -@SRR800764.25015 25015/2 -TATCAATAAATAATTCCTTTGAACTATTTATTATTTTATTATATTTATTTTCTCCTTCATTATTAATTTTTATTAATAATTAAAATCTTATCATTTTATGG -+ -@@CFFFFFHHGAHHGICHGIJIJJJJGIJJJJJJIJJJJJJJJJJIJJJIGFHIIIIGIHIGCAA2;;?BCEECECA@; -@SRR800764.25017 25017/2 -TATAAATCTTGTATACACTTCCTCAAATTCAAAGTTTTTGCCATTTAACTGGGGTGTCTGGGATGAATTCAAAACACGATACAGAATACAACAGTATCAGG -+ -@@@FDBDDHHDDFHAHGDHIIJJIIIIJIJ@EGG?FFHJJGICFHGIIIIE>GGFD7BFHGG9FHE=DGEHEHCHCBE?CCADDDDC@>>>@AB:@BCDDC -@SRR800764.25018 25018/2 -CTGGTAAAGGAGCTTATTTTGCAACCCCACCCGTACAACTAATTAATAGCCTTGATGTAGCCTTGAAAGAAATTCTCGAAGAGGGGTTGCATAAGAGATGG -+ -???DDDFFH>;FFHHGBGIIIIGHGGDHEHIGI8?DGGJDGBGFHIA>;=?B=@@<>>CDCDDDDD@ -@SRR800764.25019 25019/2 -AAAATATCATTGAAAAAGCACTCATTCTGGTTAAAGTCGCTGAACAAATTGGAAAGATCCAGTAAAGCTTTTTCTTTTGTAGTTTCATCTCTTTTCAGAAA -+ -1:8AD+2A4A=,AGHIA)+7)76A3(-=B7?37?################### -@SRR800764.25022 25022/2 -CTAACCTTAAGACCTGAAAAATGAACAGAGTTTTTATAAAATTTCAGTTTAAAATTGAATGTTGCCCTAACAATATGGATTAAAACCCTGACATATTAGGT -+ -@B?D=+ADDD>FHIEIEGHHJGG>HHIJEGHI@>GEDHIJIIIICB>GIG@GHI:D??FEHAF>FABACC@FG;C;CD@;>EHCHBD?;;@CA>;;C@### -@SRR800764.25023 25023/2 -TCTATCTAACGAGACCTTTGATTGAACGACAAAACTTAACATATCAGACAAACGATCCAAAGGATCTCTTAATAACGTGAATAAAGAAAGCGCAGTAAAGG -+ -1?+B=DADFBDFCFB?('5-&2>ACC> -@SRR800764.25024 25024/2 -ACAAGACTAAGCGAAGGAGAGAAAAATGCTTGAAATTTCGATTAAAAAAAAAAGGTGAGATGCAAGGTTGGTTAATATTACTGTGAATTGAATAAATTTCC -+ -@@@DD8BD?BDFA:EG6+<2BGIIEDG(?FHGIIDDC9;(5(=(>@:5AC(555-(2(+4>BD@##################### -@SRR800764.25025 25025/2 -TATATAAAATAAGCCAAGACAGTGGCCTTCCCTTATTATCAGCGTACTAAAATCTCATATGATTTATTTTTCGTGGTCCTGAACGAGTGTGAAAAATTTTG -+ -?;8BDDDFF?FHCBGEEEEEHJE:?FCGCCBGA>GGIDFAI>GHBF6B@??9EG?B)==888CHGHG>DC:@@AC'=?@>;)(6;'35=((;>>>AACC@3 -@SRR800764.25026 25026/2 -CTTCAAAAAGCATCTCTGGAAGAAGATCCGGCAAACCACGAATTCTGTTTGATTCTGCCAGAGCTCAAAGAAACTCCAAACGCAACCATTCTCTGAAAGCG -+ -C@@FFFFFFHFFHEGIFIIIJJIJIFIGIIIDEHGGIJJIGIGGIIJGIJ@FIAFHHIGEGHFHHFFDFFFEE3;;ACCDDDDDDBDDC:BDACDCDDCDB -@SRR800764.25027 25027/2 -AAAGCCAAGTTATCTGCCTACGGTTGTCACAGCAACATTGCGTGCCGTTGTTCTTTTGTTTTTTTTTTTTGTTTTTTTTTGTGGTTTTCGCAGCAACGAAC -+ -B@@B;;D:B2<CE=BCD);BDC>CEEDAACDD@=?@B?A?CDCCDCCDDDCDCC?>3 -@SRR800764.25029 25029/2 -AAATGCTGTAGTTACGAATACAGCTAGTGGCCGCTTCGATGTAACGCCCACTGTTCAAGACTACGTGTTTATACTTGACTTAAAAAAGCCGGAAAAACTAG -+ -+??D:+:DB>CF,1):8@@6@89909B?B####################################################### -@SRR800764.25030 25030/2 -ACAAAAGTTTTATTCGATCAATACATCGTTATACTGAATCTACTTTGGTGAAGCAGGGTTATCTTTACTGCTATACATTGGACAAGATTTATTTGTTCTAA -+ -@@@FDFDDCHFADGGH9EHII@EGIJGG;FCGIJIJJJIIEHIFJGDCBDGDGGI;FGHH=7=CHGDGEHE@CHEHHHHHG;CCC>@=@:;; -@SRR800764.25031 25031/2 -GATTCCAATGATAAGTTTGTGCATGTCCAGCTGTTAATTAACTTGAAAATCTCACCGTTGATGAAAAGTCAATACAATATGGTATTGAGGAACGTTATGGA -+ -CCCFFFFFHHHGGIIGHIIHHJJIJJIJJJJJJAGHIJJIIJIJJJIJII9BDHIFGGHIHGGIJJIJIGHIJJJIJJIFHG7?CEHFFFFFEDACCDDDD -@SRR800764.25032 25032/2 -AATAATTGTAGGGATAAATTTAAATATGGCATAAACTAAATAAGGAGAGCATGAAAAAACTGCAAAATCCAAAAAGCAAAAACGAAGGTCAGAAAGTAAAG -+ -8@1;?BABC4A>1A+H9BA@GGG3300BBFCG<***9--=@)=CHC@DEHC?############################ -@SRR800764.25033 25033/2 -ACTAAAACGTGGTGAAAGGAAATTAATATTTCCTGATCATTTCTTATGACTATAATTTTACGGCTTTCCTTCTTTTTATTTAGCTTTGCAAATTGCAACTC -+ -?;?=DDFFFHH?AE@F+FE@FGE>DF>4BDFHFAGGHIE9*09BF;:'-'=CG@;.7)77)6;???;?B:>CCDDA;;(;>CCDC -@SRR800764.25034 25034/2 -ATAAATAAAATAAAAAATAATAAATATTAATATTATTAAATATTATTTATAATAAATATTAATATTATTAAATATTATTCATATTAATAAATTTTATTATT -+ -BC@FFDBDHADHHBDHBEHHGH>HHGBF@HG?CED?GFHBFFHE@HGHHIH>FGGGIDGFHIJCIE:BCCGGDGGFGHJJIJJBG:@E>CEAE>EEHFFFF -@SRR800764.25035 25035/2 -ATTTATAAAATTATAAAATTAATTTATATATAATTCAATATATATATATTAATTTATATATTTAAATTAAATATAATTAAATAAATAATAAGATCGGAAGA -+ -?@CFDBDDFB?EHCH>?BFAEE@FA;E=4=4AED@ -@SRR800764.25036 25036/2 -CTCAACCACAAACTTTGAAAGTGTATGACTACAAGGGCAGTGGTGGGGCCATGGCCATGTACAATACTGACGAATCCATCGAAGGGTTTGCTCATTCGTCT -+ -;C>C@B=;@CC?>C??B5??BD(:>@:3:>2< -@SRR800764.25037 25037/2 -AGCAACCTACTTTATCTCAATCGAAAACGAAGTAAAGTTGCGGTTCCCTCTGTCTCTCCTAATATTATCCTAAATTTATGTTTACAGTCGCAAATTAGATA -+ -@@@DFFFFHHHGHJJJGIJJJJIJIIGIJIJIHIJJJIIIJJIFGDGIJIFIGGI>DHHIG>EEEFHG>A@@EFDEDEEC@@@ACCDBCBDBB=@ACCDCC -@SRR800764.25038 25038/2 -CTGATTTATCACTGCAAATGAAAAGCAATCAATACGAGATATTTTTCAATCAGTCAATTTCTGTGAAGAAGATCATTTTAGAAACAATGCCTAAATTTGAA -+ -@@@BDADFFAHGG9EGICIIJGIFGIIGDGGHH@DEEGIHHAHFHDB3;;AACECCC;>A@ -@SRR800764.25039 25039/2 -TTCCATGTGTAGATTTTTAAGGCAACGATTATTAATTCATTTACGACCAAAGCAGTGAAGCAAATAGCAACCATCCTTGTGAAATCAGTATCTAATAAAGT -+ -1++4=,,222C?,,<@G>F@9):8)?D?)8CG8B############################################ -@SRR800764.25040 25040/2 -CCCCTGCATTAATCGCTCTTTCATTTTCAATTTCTTTCTCGGAGTCCGCTATCTTTGTATCTTCTTCTTTCTCGTTTTTACTTATTAAAAATTCGATAGCG -+ -1++4A:3BF4+FEGHHHIJIGGHHGGGHIGGGGIGEHHHHHFFFFFFEDEEECEE -@SRR800764.25042 25042/2 -CCGCACGAGAATTTGTGAAACGTGGCATGTGGGGAACCCGCATGAATAGAAAATATGCTAGACACGACTCTTGTTTACATTGCCATTGGTGGTGTATGTAC -+ -:++=B8BA?))A@ADBDB>C>@AC@3>A>A@CC@CCD -@SRR800764.25044 25044/2 -CCGAATAATCTCTCTTTTTGCTATTTAGGGGAGTCAGTAGAAGGTTTTCGTGTGATTCATCAACTGTTTCTTGAGAACTATTCAACTGAGATGAGAGGGCT -+ -BBECEECCD@@CCC>ACA>@A8:?2 -@SRR800764.25045 25045/2 -ACTATTTACAAAGTTGAAGGTTCCGGATGGATACAGAATAGGGATCCTAAATATAAACACTATATTTATTTATTTTTTTCGAATAAAAGTCAAGTTAGCAA -+ -@@@BDFBFFDBHHIIIBHIJHGEGGIB?CHG@>D>DHAE9DGDHH@FDFHHB<8=CBFG@@;FGI4@@@E(7AC;;@DED36;>C;ACDDACC=<<ACAB? -@SRR800764.25047 25047/2 -CAAAGTAATAGAGCAAAAGTGACATCCGCAGCAAGCTGGACAGGTAAATTGCCTCATACAGTCTTACACGAAACATGTCAGAAACGAAAATGGAATAAGGT -+ -;;@;AD>?D?BDDBEGAHHAC?H?F>C@C(-5>@;?BD@CC######## -@SRR800764.25048 25048/2 -TCATCTAAATCGAATTCTGATACATTTTCCATGTCAGTTGGTAATTGATGCGAGCACGCTAGTAAATATGATGTACTTGTAGGTCTCCAGAAGAATGCGAA -+ -@@BFFDDFHFFDDEHFC>CCEEEDCDD?CCDCB@? -@SRR800764.25049 25049/2 -AAACAGGTAATGATACAGTAGGGCAGGATACATCACTTTCTGTACACTATTATACGCAGGCAGCGTTAAAAGGCGATTCTGTGGCAATGTTAGGTTTATGT -+ -@CCFFFFBFHHHHJJJIJIJIJJJJJJJJJJJJJIIJJJIIJIJJJJJJJGIJIJIIIJJJGGGHEHHFFFDFDCBBDDDEDCCDCCDD:>BCC+44?CCC -@SRR800764.25050 25050/2 -TAAGTTTGAATAAATTGAGATATTTGGATGCCGTATCGAGCTTTAATTCAAGTTCAGTCAAGTCGAATTTCGCGTCTAAGGTCAATACCCAGCTAAACCTT -+ -@@?DADDFGHHHFGGHE>HCHIIJIGEGIGGFFEE?DHHG)BDDF<9??D?DBF><88BGF>8@CC=EGI:D==9ACAA5=>3;A@C(>:A?CC -@SRR800764.25051 25051/2 -GACATTGAAGGGCTGATTAAACATAAAATAGAATTTGACTCAAGAAACATGAGCCAAGACGAAATTGAAGATGGCAACTCTTCTCAATCTCTGAATATATA -+ -;=@?BD442A;F7FADGH@HICCFGIJIE?<9C99::?<:DC;??;DBFH3?9D@;FDAA@AAG=D:;CECA3?7)).?>AC;@CEA(5(5@CC@@##### -@SRR800764.25052 25052/2 -CGTCGTGAGACTACCTGGTTGTGATTTGGGTAGTTTCCTACTTATGGATCGGTTCCTTAGATACGGTGGACGGCTACTGGTTGCATACATCTGGCTTCTTA -+ -+:1BD0)+<<2+++<3:<1+AFIEFD1*1:?D4B9 -@SRR800764.25054 25054/2 -AATCCTAGGATCTACCTTTATACGCATTTATCCTATAAAAACCCAATCTTTCAAATACACAGTATTTTATATGTGTGATTTCCTTGATTGACTCAATTTAA -+ -<@=C=D:@AD=CEHHC################### -@SRR800764.25055 25055/2 -TGTCAAGACGTTTTGGTAATAAATGCTACTTGAAAACCCTCAAGAGTCGCTACAAACTTGCCGTTCCTTAATAAATAAAGGCAAGCGTTATATACATGATA -+ -BDFHHFHBDF22CHHIIJEGC9FFBEFCDGIIGIIGD3FH?DAD'7FHHC(.==;);=E?;B;@C>@@C;@A>;5(5==55(58?C3>34@C>:> -@SRR800764.25056 25056/2 -GAAGAAAGAAAACATAACGATGCTTTACTTCGTGGGAAAGACATATTCCAGGATGTGTGGTTCCCTATGTTATTCTGCTTCAATGATACGATCATGACAGC -+ -CCCFFFFFHHHHHJJIJJIJJIGJIJJJJJJJHIJJGJJJIJIJJGIJIIFIEHHFHIIJ@EHIHHGHGHEFFFFFFFEEEEEEEDDEDDBDDDDDDCCCB -@SRR800764.25057 25057/2 -AGAGCCATCTTTACAACCAATAACCATATACTTACCATCATGACTAAACGTACAGCAGCATATTGAATTCTTGAATAGCTCTGAATTAGCAACTGCAGGTT -+ -@@CFDFFFGHHHHGJJJIJJJJJJJJIIJJIIIJIJJJJJJJJDIIJGIIJIJJJEGIEIIIIJIIIJIIIJJJIHFFFFHHCEFFFFEEEEDCDCDDD=@ -@SRR800764.25058 25058/2 -CGGAGGCGTTTTTCTTAGGGTTCAATAACCCAACGCCTGGATTAGAAGCTGAGCACTCAAGCACATCGCCTGCCCCCGAGAACTCCGAAACACATAATAGG -+ -:B?DDD7BC8DFH@FEBGGCIICFIIJJGJ?FHBEGIG=HIIDHECCGGGGAEHEC3?>@@(;;C@>B;?:??99(899<9&::AC?>80=FHIG=7=@A=E?7??>DCD?CCECC@;?A?####### -@SRR800764.25060 25060/2 -ATTCCTTAAAGAACAGTGCCAATTATATATAGGACACCCCCAAGTAATACCCAAAAGAGCTGAATTTGGGTCCAAATTTCTGAAAAACTATAGCAGTAAAG -+ -B@@F?,ABFBEFHGFHHCEAFHGGE;FHBAHG9?FGEGFEHGGH9;@@@GCGDGGH7=?A?>D);@CC@>AAEA;;@(5;;>CC@CACD -@SRR800764.25061 25061/2 -TCATAGTTTCAGTTCACAAGGTAATAATAACGGAGGTGGACGTAAGTCCCTATTTGCACCCTACCTTCCCCAAGCCAACATTCCAGAGCTAATCCAAGAAG -+ -CC@FDADFFFDFHGHH9BHHJ+AFEEHIJJIIFIGI?DFGHE0BBB?DGGFHCDFF/B@FH=;CGGHHFC>DBEDDA3@AEHE>;?7777;>ABD@B?BCACDDE>A@C>4 -@SRR800764.25063 25063/2 -GTCAAGGTTGGGCGCCAATGCTATCCTTGGTGTTTCCTTGTGCGTTGCTCGAGCTGCTGCCGCACAAAAGGGAATTACTCTCTACAAGTATATAGCCGAGT -+ -C@@FFFFFHHHHHJGIIIIJJJIJJJIJGH?DGIIGGJJJIHEHIIGIIJEEIFHH@DFFFB>BDDDD?C?BBA?ACCDDDDC@CCCD:>CE@BCCA>>@B -@SRR800764.25064 25064/2 -ATAATAATAATAATTTTATTTTTATAATTTATTAATAATAATAATAATTATATATATATTATTAATAAATATAGACCTTATCGTCTAATGGTTACGACATC -+ -@1?D?BDDHFHDDEGGBEGHJIGHJECHII9DHCFHIGGIIIGAG9BFGIIGGHIIEHIIGIIJJIHDGIIIGICF>F>GH;2@CCDHIJ@=AECAD?:A?+2AEAH<+<DD<@GB*:1*0::***:?@>>CDDD;AC><:>ACD@>@CDDDDDD@AACCD@CC@ -@SRR800764.25067 25067/2 -GGCATACATCATGAAACTAGATAATTCACCGACAGTCATTGAACCACTTTGAATCATGCTTGTTCCAACCAATAATAACGACAGCATTGCAGTGTTGCCAA -+ -@DD;'6.6(7;7;B'99?A>C############################# -@SRR800764.25070 25070/2 -TGCTGCTTGATGTCTTCGCACTTTTTTTTTCCAGATTTTTCAGGTGATGAGGTGGATCTGGCCGGTTTTACAATAATACTCAAATAATTTGTAGACAACGT -+ -@@CFA,FHII@8)..=C4@77.6(6).7)).(3'''35:@(5(:(:>@C>(9@@CC>@@########### -@SRR800764.25071 25071/2 -TTTTCACCTTTACCCTCGTACAAATCTGGTAAATCCTTTTTTAGAACTAACAATGCACTAATTACAGTATCAACCAAGATTTGAGTTTCTTCCTTAGTAAA -+ -;.6;BBB6@#################### -@SRR800764.25072 25072/2 -TGTAATGGGATGAGTCTATATTTAAACAAATTTCCTGAGATCCATTCCACTTATGATGAATCAAAAGCATGGCATTGTTTCTGGTGTTGTTTTATAATGGA -+ -CCBFFFFFHHHHFIHHGJJFJJJIIIIIIJIIHHIGIDGIGIHJHGHIEIDHIIJHCGIJGGIEGACHHD@CHIHCA=@DHAAE>A;BE3=A@CCCDCC:: -@SRR800764.25073 25073/2 -CAGGATACTTCAAGAATATTAGTAGCTTGAAATTTGAACACATTAATTCCGTATACAGTTCGTCATCATCCAGCAAATCGTCTAAGACGTCCAAATTAGGT -+ -?@BFDD?DDDBFHIBABADECJ>BEHHHIG>HH@HIDHH@EHBHH@DE>F;?;D39?00?B?(;C2==FECC:37.7@CE?;@BDEFDD;>?######### -@SRR800764.25074 25074/2 -CGGCATTTTACTGAATAATAATTGAGATATTCGTAACTCTTCCGAAATGATTCTAGAACTGTCTTCTACTTGCGAAAGAATATATTTTCTATACGTCCTGG -+ -??7;+A:DA:A,2A:EC?,3,,<3+<+3@C@;>CA3AED@@3;77;@C?CED@3-;;>C## -@SRR800764.25076 25076/2 -CTGTAGCTTGAAGCAAACATCACAAGGGACACCACCAGAATAAAGACATATATGAGAGGGGTATAAACGGAGATTGATTTCGTCTCCACAATTGCCTCTTC -+ -?B;;@>A(,89?3@<3?########## -@SRR800764.25077 25077/2 -TATTTTATATAATTTTATTATCATTTTATTATAGCACGTCTATTACCCATATTATAAGGATCATTATGATTTGTATTAATTCCTTTATTTATATTAATAAA -+ -<@FBGI4AHA81?:DBC;C>BF*B<4*?GFG>9CEC4//8>))(6B@''-,?).)>C@C6;5>;=>BA>C############### -@SRR800764.25082 25082/2 -CGCCCCAAACTACTTGACCAAATTTGTTTGATTTCTGCCAGTTCAAGTTTTGATCTATTCTTTGCACTTACTCCAAAAATGCTGATTTCTCCACCGAAACA -+ -=@@++=B7A;DFFABEAC@3CACFEA?)???DF?1*CFBFEFH>>B@*0*9??BCCE).;@6>;;A######## -@SRR800764.25083 25083/2 -AGCAATTTTTCTGGAATTTCAGCTGTTTCCAAACTCAATAAGTATCTTCTAGCAAGAGGGAATAGGTGGGAAAAAAAGAGATTTCGGTTTCTTTTTTTACT -+ -@@@FDEFDHHAHHHEGGHJ>?AFHF?FHB@AHHIJEGIGHHHC?FGIGE>FFHGHGGGGIDCGEHHIIIDAC;=>BA@D?CDCCC:@CDDDB### -@SRR800764.25084 25084/2 -AAAGCCATTTATGACACCTCAGTGGGCTATTGGCTACGTCACAACGTTGATGGATTTCGTATTGACGTAGGCAGCATGTATTCTAAGGATGAGGGCCTACC -+ -?@?BBDB+ABF4CEB+ABAFG>??@D9CB))8=)8(.)=@>CE?CABCC?=>(..5(;@>((-;(:5AA:?'5<>AA -@SRR800764.25085 25085/2 -TCCACGTTCAATTAAGTAACAAGGACTTCTTACATATTTAAAGTTTGAGAATAGGTCAAGGTCATTTCGACCCCGGAACCTCTAATCATTCGCTTTACCTC -+ -=?@+BD2ABFHDDDE>ACFIIIFEDEHCG>B@C>>>A;@CD:? -@SRR800764.25086 25086/2 -TTTCATAAGAAGGGATATGAAGTATTGTCATTCCACAGAGGATGATATAAATCAGTCAGGTCAACACTGCTAACAAACTCCTCTAAAGTACCCAAGTTGTA -+ -<@;;D>>D:4C:<1A:A?CE<43,AEH<2+++AEC3*):?C@9:B9??@B*9EG@@FB9C)8BCH@GEHHIDI(.=C)77;;?DC776.;A####### -@SRR800764.25087 25087/2 -CTGATGAAGCAATCCTGGCCGTGGCCACTGGTTTCTGTGCAGAATCCTCCCTTTTCAAGCATGAAATCGCCTACGTCGTCGGTCAAATAGGTAGTCCGGCT -+ -;@;:?;?+=CDFDG3+CE9A))2E;7.(5=<873.;'3,88280AC@C:>>@:::@#### -@SRR800764.25088 25088/2 -GCTATAATATTATGGATACAGAATATACTTTAGAAGGTCTCCTCGATGATATAGGAATCCTCGAAATGGAATCTATATTTCTACATACTAATATTACGATT -+ -::8D;A4=,ACHHA+C> -@SRR800764.25090 25090/2 -AAAATCTAAGAGATATGAACGGTGATCTTAAGAAACTGCAAGAAGAACTTCCCAGTGTAGAAAAAGACAGTAATATAGTGATTCTTTGCCGCTACGGTAAC -+ -@@CFFFFDFDHFFAE4CEHDHGHI7BFBHCHIG>DHII9DGGEHGII3BDFFGIJFGC>?@BB##### -@SRR800764.25091 25091/2 -TTTAAAACCTAAAGGTAAACCTTTATATTAATAATGTTATTTTTTATTATTTTTATAATAAGAATAATTATTAATAATAATAAACTAAGTGAACTGAAACA -+ -CCCFFFFFHHHHHIJ:CFHIIIIJJJIIJJJJJJJJDIIJJJJJIJJIHGHHHIJJIJJJJJJJJJIJJJJIIJIIIGGGJFHGFGHEFBEDFCEECEEEC -@SRR800764.25092 25092/2 -AGAGATCAATAGGAGCAACATAATGAACAATGCCCATGAAGAGAACATTTCTTCTGTAACAGGGTTTAAGTCTACATCAGGATCACCTGCAATAGGGTCAT -+ -8@@A?D?DBCFHD@GIIH3AEHID@9A9AC9:E?)?:DBB?DDHC3?GGFEII>*9??FGBCG;).;@G;=AEE@=:A>A??CFE;66(66@>:@5,5>A3 -@SRR800764.25093 25093/2 -AACCTTATCCCTTAGACACAAATGATCACATCGAGTGGATGAACTGTCAAACGACCCAAAGTGAATATGATTCCAGAGATTTCTATGCTTTCCATTGTTTT -+ -@@@?DFFBFBDHHGHCDDDD3-;;;;>BCCDD? -@SRR800764.25094 25094/2 -GAATTTATTAGTGCAGAAGAATTGTTTCGAAATGGATTCTTGGAAGATTTCGTGGTAATATTAAAAGGAACAGTAGGTTTAGAAATGAAACTCAACTCAGG -+ -BB@DFFDDHDHFHJJIGHHFGIIJIIIEHGHGHIIGIIJIJIGDFHCEGIIGGGIDFHIDGHHFHIIJGGIIIHEHH=>C@D@DFFDCCACE>CCDDDDCA -@SRR800764.25095 25095/2 -TATACTTTATATTATAATAATTATTATTAATATAAACTTATTATATTATATAATTTAATATAATAATAATAAGATAATTATCAATAAAAATTACATTTTGT -+ -@@<=DDDDH??BHIIIGGHIEHHGHGIADDHEIGG@HHIJIJJIGIJI>GAHHGIE>HCGGHIIIJGGAGH@HIIIIIJIEIIGICGFCCEHHGGHEEHEH -@SRR800764.25096 25096/2 -TTTGGATGTTGTAGTCAGACAAGGTTCTACCATCTTCTAGTTGCTTACCAGCAAAAATCAATCTCTGTTGATCCGGAGGGATACCTTCTTTATCTTGAATC -+ -@BCBDDDFHHHFHIIHJJGGHIIG@CCCCCDDCAC::>CC -@SRR800764.25097 25097/2 -AATGAAGCAAGAACTAGCGTTTATTGAAAACGTAATAGCACAAGATTTCACCACCACATATTCTACTAATAAGAATGATAAAGTGAAAGGTTTGGGAATCG -+ -@CCFFFFFHHHHGIIEGIIAGIJIIJJJJIIJ?GGHJJJJJJJJ@DHGGGHIJIJJIIIJJIJJIJJCHFHFEEFFFFFFCCC>CEDCCB>CC@BD@CDDB -@SRR800764.25098 25098/2 -GTATGGGCACGTATGCCAAGTCGTTGTTCTTGTGAAGAGAATGATATGTGCAGTGGTAAAAAGAGCCCGTGACACCCAGCAGCAAAGTGCGACCGCGCTTC -+ -++1=1B>>D1CD######################################################################################### -@SRR800764.25099 25099/2 -ATATATATACAGGCAACACGCAGATATAGGTGCGACGTGAACAGTGAGCTGTATGTGCGCAGCTCGCGTTGCATTTTCGGAAGCGCTCGTTTTCGGAAACG -+ -@CCFFFFFFHHHGIJIJJIIJJJJJJIICBCGGGIGGDGIGHGIHGIIDDGGHIGGI=HHFFDEEDDDDDDBDDEDEC99@BBDBCED=A>(;3,;@;@3:A>:55 -@SRR800764.25101 25101/2 -TTTCTATTTTATCGATGCCGTGTCTGCTGCCATTACGTACAGGTAGGCAAAAGCAAACAAGAATAGCACTTTTTCACTTGCTGCTTTTTTTTGTGAATGAA -+ -@@@DDFFFBHHFDGI9EEHGDHGHBFGEG@FDDFHGGGGHIEGHDHHE>?BFHIEFF;FDFCGGG;;EHHCFFFCCFBCEE@E;>C@A>@=BBAC:AC>@> -@SRR800764.25102 25102/2 -CCAGCAGCCGCGGTAATTCCAGCTCCAATAGCGTATATTAAAGTTGTTGCAGTTAAAAAGCTCGTAGTTGAACTTTGGGCCCGGTTGGCCGGTCCGATTTT -+ -CCCFFFFFHHHGHFHIIIJGIGGIJJJIJIJIJHIJIJJJIJJHIJIJIJJJGAHIJHHHHFFFDDDADDDDDDDDCCBC@CC################ -@SRR800764.25104 25104/2 -CACATCAGCAAAGTTTCGCTTTTGACATTCTGTTAAATTGGTCCCTAACTGTTGGTGCAGACCTACTGCAAGACTGTTAATTATGGTATATTATATATCAA -+ -CCCFFFFFGGFFHIIIJJJJJJJJJJIJJJJJEHHJJIJIJEHJJJGIJIGEHIIFGHIJIEHDIJJJIIGHCHHHHDFFFEFDFECDCCFDEEEFFEEED -@SRR800764.25105 25105/2 -CAAATCGCAAGTTTTCTCTCTGCATTAACTAAACAATACAAAGACTTAGTGGTCTTCAAAGGCACTTTGAGGGACTTTTTGGTGCAAATCAAAGAAGTCGG -+ -@CCDDFFFGFHHHJIIIJJJIJJJIJJJJIIJJJIJIJJJJJJIJJIIIIHGIGHIJIJEHIIJJJJJGGIJHEFFFFFEDD?@CD:A>CDDDD>BC::?9 -@SRR800764.25106 25106/2 -TCATTTACTATCCATTATGTTATGAACGGGAACTATACAACTAACCTAAGAATTTTGAAATCACAACAAAAATAATCAACATCACAGTCTCGAAGGGATTA -+ -CCCFFFFFHFFHHJJJJJJJJIIIJJJJJJHHIHGHGIJIJIIJJJJJGHIIJJJJIIJJGHIJIIJJIJJJHHGHHHFFFFFEEEECCDDC5=??B@CDC -@SRR800764.25107 25107/2 -ATAAATGTGGAAAGCTTAAATAAAAAGGTCGACGAGGTTATTAGAACAACAACTTTCAAACTGAAACCGCTAATGGATAACTATCAGAAAATTTTGAATTA -+ -CCCFFFFDHHHHHJJIJJJJJJIIJJJJHHGGJJGGI?DFHJJJJJJJJIHHGGIJJJIIJHHHHHHFFDDDDDDDDDEDDDDDDDCDDDDDCDDCDDDDC -@SRR800764.25108 25108/2 -GAAGCTGGTCTGCCTTGCTTGGCCAAGTACTCTTCCAATTCGACTTGTTGCATACATTCGATACCAATACCAGCATCAATCTTACCTTCGATGATGTACTT -+ -B@CDDFFFHGFFGIIJJIJIIJBFGEHJJJIGGGBFEGGIGEHDFGIDG@DHGHJJGICHGCGHGGIJIIIJHHHHEC@DFFDCCACEA?ACCADDADEB5 -@SRR800764.25109 25109/2 -ATTTATTATTATTGTTTTTTAATAATCTTATATATAATATAAAAAATATATATATATTATATATATATATAAATATAATATATATTATTATAAATATTTAT -+ -CCCFFFFFHHHHGIHGJJJJJIJJIJIJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJGGIIJGGIIIJJIJIIGGHIJJIJIHHGHFHHGFCBEFFFDDDC -@SRR800764.25110 25110/2 -AGAATCATTACCTAGATTATAACGAATTGAAAAATTTGATCTACACATTACAGACAGATGAATTGAAACAAGAAACGACAACCGGAGACTTAAACGATGAC -+ -???D1AB4A,=:?F377787=7CEH########################## -@SRR800764.25111 25111/2 -TTTGGGTGGTAAAAATAATACTTCCTTAGTTCCAAGGCTAAAAACAATAGAAATGTATAGACAAAACGTTAAAAAATCTAAAGATCCTGAAGTGTTATTCC -+ -?B@FFFDDDHDHHJJIGIJJIIJJJJJJJDCGGIJ@DGIJIJIIJGIEIEHHIGGGHGIIFDFHGEIGDHHFHHEDCECECDCCC@@CCACD@C;@ACCDA -@SRR800764.25112 25112/2 -GGTGTCAAACGGTTACCCTACGAACAGTTCGCGTCTTGGAGCCCAATAAAAGAAAATGAGGCTTATCAGTTCTATCACTATTTAACTTATTAAAAAACATA -+ -?;BA=BDDHDAAFFI@A2CDH<12?G?*:1:D?0?(?F93BCCG######################################################### -@SRR800764.25113 25113/2 -AGGCATTTCAAATTAATGAAGCAACCCTTATTATGGCAATCCTTTCAAAATCCAAATGATCACCATAATGAGTACTGTGACAGTAACGGCAGCAACAATAA -+ -B@@=??:DDHHBHGHI@EEIC<@H9A@+AFHIIDC9?GIIIGGEHECGCF@DH@BFH@7AC?A#### -@SRR800764.25114 25114/2 -AATTTCAAATTTATTGGTTCCAAAAATGAGATTTGATCTACATTAGCAGCACATGCACGCAAGGTTTTACCACCATCAGCAAAGGCGACGTCTGGAATGGG -+ -@@@BD;BDFHHFBGB+HCD?D):DAFAD>@((:;:@DCCD## -@SRR800764.25116 25116/2 -AGAAATACAAAACGTTAGCATTTGCATTTGTTGGACATGTACTGAATACAGACGACACACCGGGACTTGAAAAAGAACTGGATTGGCCAGATCCTGAACTG -+ -11+4B+A:2AF+<<22+2+AFFFBHIGIIGA;FED@DC@CC(;;>;;;=????CC@ -@SRR800764.25118 25118/2 -AGCGCTTACCACTGCTGTACTGGTCAATCAAACCATTAATGAGCATAACTATCCAAATACTCAACGCTATACAAAAGATTAAGTTAGGTGACTGAAAGGTG -+ -##################################################################################################### -@SRR800764.25119 25119/2 -CATAAGTTTTTCAAATTTTCCTTTTATTATGAATTTGCGCAACGACACCAGCGCTATTGCTAATGCGTTCAAAACAGGGAAAGTACACGTGAAATTTTAAA -+ -BC@BBFFDHHHGFGI@AC>4>4 -@SRR800764.25120 25120/2 -CATGTCATTATTTGTAAACCTTCTCCCCGCTCCACCACTCATCATTTCTGTTAAGGAGGCAGTAGGGCGTAATATTGACCCAGAATCCCCAATTGTTGAAT -+ -@C@FFFFFHHHGHJGFHJGGIJJIIJJJJIEIJIIIIIIGIJJJIIFIGIGIIJIGGGIHGGCEEBEHFACBDDDDDCCCABABCCCCCBC<9:ACCB:>C -@SRR800764.25121 25121/2 -TCCAAGCTGGGTAAAGATTTCAAAATTTAATATAGTCGTCTTTGACCCTTTGAGTAAAAAGTGCTTTTCCCAAAATTTTGTTAGCAAATTAATTGACTGAC -+ -@@@DFFD>?F;2@7BEEHH=;.7?@B>)7;;;66@C(->CC:AC: -@SRR800764.25122 25122/2 -AACGATTCGAACGATACCGACAAGCAACATACACGTCTGGATCCTACCGGTGTGGACGACGCCTACATTCCTCCGGAGCAGCCGGAAAAAAAGCACCAGCG -+ -?@@7DBD>CFFF@E+?:EB<@EG9)0:BG9*??3@(44:909@B529(8<@-003<>@######### -@SRR800764.25123 25123/2 -CTTGACTGACCGTGAATACTACTCCGCCTTCCACGACATCTGGAACTTCCATAAGACCGACATGAACAAGTACTTAGAAAAGCATCATACAGACGAGGTTT -+ -??@DDB,AD:;F@EECCH>??CA;C@A?FEC:8D6DCGBG>BB8=.8CH@CCG>E/C>;ACAA>?C9>53@CCDCCD######## -@SRR800764.25124 25124/2 -AGAAAAAAGTTAACTAAAAAGTAAGAACAGCAAAGTTGATTGTAGCCTATATTGCTGAAATAGATTTCGGAGCTCCCGTATAATATTAAAGTGCACCAAGA -+ -CCCFFFFFHHFHGJJJIIIJIAFHIHIJIGGIJJIGGIIIJJIIG@FCEDEGIIIHIIGGHJJJEEGIGGHHFDFFFC?ABDCDDCDA@CCCCCDDDDDDD -@SRR800764.25125 25125/2 -AGTGTGCAGATAACTATGAGAAAATTCTAATTAAAGGATTTGCCGGTAGAGATTCTGTGAAACTACCGATGTTTGATCTGTTTCTGCTTGGCTGCGCTCCT -+ -?@?DDDDEFH?FAHGHJJJJJJJJJJJJEIJJIGIJJFGHIIJIGIFHGIHG@GHIJIGGIIGCHGGIJHHE7?C>DFEE;ACEECCDCCDD@BDDBDDDC -@SRR800764.25126 25126/2 -CCCGCTTCAGCTTGATTCCGTGCTTGCGCCTCCTGTGATTCTAAGAGTGCAATTCTCAACTGAATGTCGTTTTCTTCATCGGTGTCGCCTGAAAGTTCAAG -+ -@?@BDDDDHFHHFIIJEBH;C@FAHEIGEHIEFB*0?(:@::> -@SRR800764.25127 25127/2 -GTGCTTCTCTCTGGTGGTTTTCTGTTTTTCTAATATTGATCGATTTTACGGTGAGTTAAACTACTTCCTTTTATCGCAATATCATATTTAGAGCGAGAAAG -+ -@?DDCDECCEDDCBACCBCBC@A -@SRR800764.25129 25129/2 -AACGAAGTCAGTACCTTTAGCAAATTGTGGCTTGTTTGGAGATAAGTCTAAAAGAGAGACAGATGCAAAAGTACACGGGTCTAAGTTAGGGGACAATTGGA -+ -?@@BAB;D>AB@:5>;;5(>CD5>?>(5>ACD@AA:@AC -@SRR800764.25131 25131/2 -GAAAAGTCCAAGAACAAATAACGAAGAAAGAAAACAAAGAAAGGCGATTAAGTAAAGTGCTAGTAGAGCAAGTACGAGAGAAGAGGAAGAGGCTTAGACAC -+ -BCCFFFDDHHHHHJJJJJ@HIIJJJIIIJIJIIJJJJIIIJIIIJGIHGGGH4@FHIDHEHIHHHHGHFFDD?CEDDBD??CDDDDBBDDDBB??CCDDD? -@SRR800764.25132 25132/2 -AAAGAGTGGATGTTGAAGAGTCAGGTCTTTTAGACTGTGTAAATTCAGCATTACTGTCTATCCAAAAATCCACACCATTTGTTTCTTCAATACGTTGTACG -+ -?B@DDFA?DHDFHIGGH@F3<GHIIGC7=CHAC@DCCCBBEDACC?=;>AA -@SRR800764.25133 25133/2 -ATGCATGTGCCGTGAAGCGGGACAACCAGAAAAGTCGTCTATAAATGCCGGCACGTGCGATCATCGTGGCGGGGATTTAAAAGTTCATATCACAAAATGTC -+ -@CC@FFDBFFHHFHHEGEIB<1CDGFFHDFHCGE?FE<;BFHGDAHCA@@:9B/9.=A@8ABBCA>5<;@BD############################# -@SRR800764.25134 25134/2 -TTCTGTTCTACAGCTTGAATACATGCCGTGGATCTGTTTATCAAAGATAATGTCATGTAGCGTGGCAAGTCGACACAGCAACGTGTGGATAATGGATGAGA -+ -@@@DFFFDHFHHHGHEBGGHJIG,::EF@CEE3CDGFHC>4BFHGII*?D5(5:A@>:AA -@SRR800764.25135 25135/2 -ATCTGAACTAACAAGTAAAATATCGATGTTAGAAATGGTTACAATAGAAGAAAGTAGTGTCATTCTTTCGCGTCAAAAAAAAAATGGAATTTGTGTCTTTT -+ -@@@DFDDD4CCDFGIGEIGFEC?@?F9D9D?EEHIEGEGDGG:CC4@FHGGIHJJJJIJFGFEGHGGGEFGIICAHGGHECCDFBDCCEEDE -@SRR800764.25144 25144/2 -GAACGCTTCATTTTAATCTCACGCATTTGCAACCCATGCTGATGTCTGAAGCGCTGACAAATACTTCATACGTTCTTCTTGTGACACATTAAGAGGTAGCA -+ -B@@FFDADHGGHHJIGIDHIJIJJGJJJJJJJJJIJJIIIGJJEEGIJE>FHIJJG@FHIHGHJGHHHGFFF@D@BCCEDECCD@AC?CDCACDDD::@CC -@SRR800764.25145 25145/2 -GATGAAAAAGGTGATTTGTCATTTACAAGAGGTAGGTCGAAACAGAACATGAAAGTTGGTCGGTAGGTGGCATGCAGAGGTAGTTTCAAGGTGACAGGTTA -+ -@B@B>CC(::ACCD### -@SRR800764.25146 25146/2 -AGTGTTGGAGTTGGTACTTTCAGTGGTAGTCGCACTAGTCCTGACGTTGATGCTGGCAGTGGTAGTAGCACTAGTCCTGGCGTTGGTGCTGGCAGTGGTAG -+ -?@@1BD??AD?FFEIG4C@EEIIGHDFHH>HGE?@FF@D??D<4D@B?G(>CG<3CC;<+CH9C:B@CC############## -@SRR800764.25150 25150/2 -GAGCACAGTTTTTGAAACTACAGACGTGCATCCATTCGTTAAAGAATGGCTCGCCGGCCGAAAGTTGCGAGAACGGACAACTTTCTTTGCAGTTCAGCAAT -+ -@@@FDFDDFFFHGGGCHGIIIJJIHIGHGGEGDHFIEHHEGIJIIJEBFEFHH:A -@SRR800764.25152 25152/2 -GGAGAACTCGACAAGGTTTCCCTCCAAACACTTAGTAAATGACATCAGTATTTTCTTCCCAAACGGGGAATGCAATAGGGCAAGATATTTGCCTCAAAATC -+ -@C@FFFDFHGHHHJJFEGIJJJJJJJGIIBHJJJJHDGFFHJGIJGIIFHHIIJIJJJIGJCHIIJIHFFFFDEEEEECBCD?@CCDDCCDDCDCDDDDDC -@SRR800764.25153 25153/2 -TATAATTTATATAAATATAAAAAAGTCTCCTTTTTTAATTTTAAGAATAAATAAAAATAATAATTAATCTAATAAAATATTTTTTTAAATATATTTATTTA -+ -?B@FFBDDHDHHFFB:<BDC@>@A@@C@CCCC -@SRR800764.25154 25154/2 -GTCCGTAGTGGATGAAATAACAGGCGCAAATTTATGGCGGCGGAATTTCTTTTCGAGGAGGTACGACTTCAATTCTGTCATTGAACAATATAGCATATTGG -+ -@?BDFBDDBDFHFGICGHIJIIGJIJJJIIIIIIJGJJGIA/=',8@C(5:@C>=2?@0+5(+:&+55<::@AC(:>@:4:@:(:>CC>A:@######### -@SRR800764.25155 25155/2 -ACGAAGAAAATCTAAAAAGAGTACTCTTTGGACATGAAACACAAAATTTTACGGAGGCTACACTAGAACCGGGTGAAATAATCATTAGGCTTTATCTGAGG -+ -??@D;ADBDHHHDFBACF?+3,<<+AA<<11H9::C91??D@GGHAG9BG49F?6'5-.=7.7)).?;76=A>B/;C:@35@################### -@SRR800764.25156 25156/2 -ACAACCTTCTTGGTAGTCTTAGCTTTCTTGTGGAAAACAGGCTTGGTTTGACCACCGAAACCAGATTGTTTACGGTCATAACGTCTCTTACCTTGGGCAAA -+ -@CCBDFFFHHHHHGHEIJJFEHJIIJIGIIHHIFGHIGIJJGIJFIBFG?AACHCGGABE@D;AEEC@;?DDCCD;=BD@>CBC?CDCDCDCCD<>BB?B1 -@SRR800764.25157 25157/2 -TAAACAACCATCAGCTTCAAAAAAACCAATAAATCATTCTAAAAATTCTTTAGATGGTAATTTATTATTAGGTTTAACTTTTTTAAATTCTTTATAAAATT -+ -@@@FDEFFHHHHHIIJIGCH@HGHEHIIIHGGEHGCCAIIHG9DHIIGHJGIIIIIIFCHJGIGIHCHFFFH;@DFFFEECC@??CCACCDEDCDC@>@C> -@SRR800764.25158 25158/2 -TTAGCGTTCGCATGTACACTGAATTGTCCCCTAATGGTTTTAACGTTCGAATGAATAGTTTCTAAAAATCTGTTATTATTGATATTGAAAGTATCAATTTC -+ -?B<=?:D?:@?CBA4ABDAFHC@HCECE9?DGBDHII?BDDE>?;7@BD@3@CCCDE:>C>>;;AC:C@CD -@SRR800764.25159 25159/2 -GGCTGACTGGAGCATTACTAGGTTCATTACTCACTGGTTCTACTCATGAAACCTTACTTATTTGACCTAAAGCTAAAAGACACAGAGAAGCTGGATTGGAA -+ -8=??D=DDD=+2E??DG@CFGIIJI1DFHCCBD4=BFCBCFHIGGF8@C@GE;==>?BEED<9;>>CCC@?@AB9?==BA?@BB03>CCCCDC>>:CC9BBBC -@SRR800764.25163 25163/2 -TCAGCATTAGAAGACCCAGCCACAAATGAAGGCGGTGTCGAGGCCGCCAGTGAAGAGAAGACAGGCCAAGGTAGCGGGGCTGGTTCCCTTCCATGGCAGGC -+ -=?+=1=D,C:C<+:2+<+<3 -@SRR800764.25165 25165/2 -GCAATTGAATCATTCACCTCATTAACCAAATGTGACCCCAAGGTATCCAGGAAGTACCTGCAGCGTAATCACTGGAACATCAATTACGCTCTCAATGATTT -+ -B8+ADDBD>D,+,2ABEEFF:AF4C@C:6-=/58?:(5>>ACF> -@SRR800764.25166 25166/2 -AAGCTTAATTGTATGAATATTTCTATGTTACCGGTTGAATAAACCTGGTCTCAAATAAAATTGGTAGAATGACCTAGAATGACCCATCCGCCGCGGAATCG -+ -=:BD?DEDBD<:DFFCHDGCHDECH>HD:CDBHE4C4?*:CG@F@CGA?4BF9DF:6BBHG4=CF@4C;.==@/459BB@;AC(5=>>@@((-:;5@>(5@ -@SRR800764.25169 25169/2 -ATGCATAGTCACGAATTTTCTTTGTGAGGAAATTGTTAGGGATTGGCGAGATTTCAAAATTTTTCTGAGCTTTAAGGATCCTTTCATAGTAAGAGACGTCT -+ -B@?;:B:B=2:D?C1C:AF@HIDD<;2<8+:;?B?*?*?DBGHH3)*?D'768@)BBHIJJECD=;?)==A>@)..;>C6;CEC35>CADACCCC?C?### -@SRR800764.25170 25170/2 -AAGATTTATTTGCTCCAAATGACAAAACAAAATCATTAATTAGAGAAATTTTATTATCCATCATCAATAGGAATATCACCAAAGGTGCGTCGATAGAGTAT -+ -=;?DDFFBHHHFDHIIJJB@BHGHBH;GGHG?E=@;BAC>?@@?AA@:> -@SRR800764.25171 25171/2 -AAAAAATTAATTCAACTCAAGAAATTAAAAAATGGAGGCACTAGAGGCAAGAAGGCTTAGTGAGTCCTTGCGGATTGCTGTGCTGCACTTAGGCTGTTGGA -+ -?B;A+)A<+2:C,C<<,A+A<3CG9+AH9EHI##################################################################### -@SRR800764.25172 25172/2 -AATCTTTATCATGAGTACCATGAACAAAGAAAGTCACCTATCAGTGGTTCTATCGTATATTGTTTCGGTGCCGTGGGGGGGACGGTTGGTATTTCCTTGGG -+ -CCCDFFFEHHHHHJIDGHHHIJJJIJIJJIJJIJIGIJJJJIIJIHIGGIHGIJIGGIHIIIFGGGGGFGGIHH6BEB:@B9>@B9@B><:>C@:ACDDA< -@SRR800764.25173 25173/2 -GATCAAAGGATAGACAATTTCAATACAGAGTTAAATATCGTCAGCCTAACAGTAAGGGCAGAAAATACTGTCACAGCTAAGCATCACAATGCGTTCCATGG -+ -##################################################################################################### -@SRR800764.25174 25174/2 -AAACGGTTGTTACAAGCAAGAAATGACAAGGCATCCTCAGTAATAACGGGGTTAGCCACATCTTTTACACTCGTGGCAATGACTCAGCCCATTGACGTCGG -+ -?1=DDDD+<;3)=;=)7=?7?B>>>>;..3/(;;>A:@>35A<@CCC@C5BAEGIICHCHGHGHGCCEHCB7<>A@AAC@CD@9@;>CDCCCCDACEA: -@SRR800764.25178 25178/2 -GAATCACCTGTGGGAGTGAACCTCAAAAAAAGAAAACACATATTTCATGCTGCATCATCCTTGCAACACAACGCTTCCTGCAGAAGTTTTCGAACAAAAGG -+ -@??BDB:BFFBFBGGB+2ADFEBFC?HF@GGHGIIEFIGGIEEGGJI=FGHCGIG>@;=3=>==7BD>?=?A>@B(,:@CCCDC>A(:AC>@######### -@SRR800764.25179 25179/2 -AACATTTATAAAACCGTTGACAAGATCGGTGTAAATAGAGTCGGTATTGCCGACACAGTTGGATGTGCCAACCCAAGACAAGTATATGAACTGATCAGAAC -+ -CCCFFFFFHHHHHJJIIIIIJJJJJJJJJEFFFIIIJHIJBGHIDFGIBGGHGGJHHHEECFDCFFCACCD?BBDDDBDDDBACDEEECDACDD@CDCDCD -@SRR800764.25180 25180/2 -AACGTAAGTCTGGATAGAATTGAAGACTGATACAATGGAAATGAAAAGTAACCATTTTGGTAAGTAACCTTTTGGCATTGCTGCCAAGGTGGTCTTGGTTG -+ -?@@DB>ADC,A@B376;.6;?;(;A>5@FGEHGIEEHEHADB@DFF:@>6@DE;@BACD??CCD@AD?',5>@3;5>ACDC# -@SRR800764.25183 25183/2 -ACTGCTACTTATGTCAAGGCAGTGGTCAGGGACATGAAGAAATACATCAAGGCTAGAAAATACAGACAAATTCCGGTAGGTTACTCGGCTGCTGATATCGC -+ -BCBFFFFFGAHHHHIIIJIIHIFGHCHHIIJIJJJIGIJJJJEIJJJIBHFGIIJIIJJJGGIIJJIJJGHCEE>A9BBC@>ACCC?BDDDDCDCCDEDB# -@SRR800764.25184 25184/2 -ATAGATGGAACTTACAAGTATGGAGCTTTGGATGACTTTATCAATTCATTCACAGATTCTGCATCTGCAGGAAAGTATGCTGTAAAAATAATCATCTTTTT -+ -@CCFDFFFHDFD:CDGIAACIEIJFJADCHGIEFEGCBBHHGE@G@HHEHHIGHH;4BBGI>HGIIA)7=DG@EH;==);@>:3;AC>@;>CD -@SRR800764.25185 25185/2 -GTCAGTGGCAAGTTTGATATAATCCAGATCTCTAAGGGGTAGTGCGCTGATTTCGACCATAGATGAAGACGTAGAGCTACTCAAACCAAATGACGAATTAT -+ -@=?BDDDEFD>D2A:CBD4?EDAF<@@H;CAC@A@?BDC:@:?2928@: -@SRR800764.25186 25186/2 -TAGGAAACAACAAATTCCGATGCTTACTTACCCCTTAAATTTTCTCATTGCTCTTCATTGAGGTTGCATAGCTCACCATATTTGTCATGGAAGGTCCCTTA -+ -CCCFFFFFHHHHHJJJJJJJIJJJJJJJJJJJJJJFJJJJJJJJIJJIJJHIJIJJJIJJGJJFHIJGJJJJJHHHHHFDFEFFCEEF@CCEDDACDBDCC -@SRR800764.25187 25187/2 -AGATTACGTTGGCCGAATTGGTTCAAGAATCGATTTTACAACTGTCTGTTTTGAAGACCATTATATTGAGTTTTCCCTTCGAATTGACCATTTCGAAGATT -+ -B@B+AB8DHB;+??9:CFHGDBFF1+A3FEF4?E9EFGIEGI*)?C6DD)??@AFHB@CB:',.;7.;(;@C>3@@:;AB=@8=C>>A@C>:>>@C############ -@SRR800764.25189 25189/2 -CTCTTCAAAGGAGAACAGGCCATACCTTTTGGAATCTCCTTCAGGACTCTTTTCATGTTCACTAGTCAGGTTTTCTCGGACATTCTGCTCGTTAAGATTAT -+ -@@CDFFFFHHHHGJJFIIIJIJJJIJJIJJJICEGJJIJJJIIIICHEIJHHIGIIE@HGEHGIJIIIFG7CGHHHHHBBDBECCEDCDCD@B@?CCCDDD -@SRR800764.25190 25190/2 -GATATAAATAGTTGCAAACTAAAGTAAGATAACTGAAGATGATTAGTCCTGTTTGCATACATAGTTCTGTTCTTGTTCTACGCTGATGCGATCAATAAAGT -+ -@@CFFFDDFFHHHJIIFGIJJJIIHJJIJIJIIHIJJGHIJIJJGI>FGGFHGIIGHGIIGIGIBFIDIGEHGIIGHCHIDGGHHGGFFEC;ABACDDDC; -@SRR800764.25191 25191/2 -TTATAATAGGTTCCTTTTAGATGATCTCCTAATCAACATCCGTTTAACTGATATGATTATTAACGGAAACAATGAATGCATAGAATATGAGAAAGGACATG -+ -CCCFFFFFHHHHHJJJJIJJJIJIJJJJIJJJJGIJIFIJJIDHIGIIJFIJIJIJIJJIIJJJIIJJJIEEGHHHHHHHHFEFFFFEEEEEEEDBDDDD> -@SRR800764.25192 25192/2 -GGAAGAGAATCAAACCAAAGTTCCCAAGAATCACGAAACGAAATTACGAATTGGATGCAAATTGTGTGAAATGGAGTTTTGACACATGATATTGAGTCTCC -+ -+1?7:BDDDC;C################################################################# -@SRR800764.25194 25194/2 -AAACCCGCTCAAACCAAGGCATATAGAGGAAGCCTGGAGAGTACTACAAACAATTGACATGAGGCATAGGGCTTTGACCAACTTTAAAGGTGGTAGACTCA -+ -@@CFFDFFFHHHHJJJJJIIGIIIIIGIJJJIJJIJJJJJGBFEDCGCGG4@@@)7=CC@EHHC>AC@?B;@6>53@=A@A#### -@SRR800764.25197 25197/2 -TGGAATCTAAATTTGCATGATTCAGTTGTTCCCTAGGTGACATTTTATTGAGGATTCCTCTATATGATATAGTGTTCGCTACTTTACTATTTGGGGTCGTT -+ -CCCFFFFFHHHHHIJIJJJHIGGIIHJJGIJIJJJII?EHHIJJJJJJIJJJJJIJIJJJIIIIIJJIJJJJIHHIJIJJJHHHGHFDFFFFFECD8?BD? -@SRR800764.25198 25198/2 -GGCTACGCAATCTGTGTGTTCGTCGCAAAACACAGCGACCACTGACGGTGTACGAAATCAATTTCAGAGTAATGGTTGGTGTTCAAATAACTGTGCTGGTC -+ -@??DFBDDFFC:@>;@;:@5::;>:++2<++(+>C3:A@344>@CCC#### -@SRR800764.25199 25199/2 -CTCTGTTCGTCAGATAAATCACCTGCGTTCAAGAAATAATCCCATCTATGATTCCAGACTACTTCAAATTCTTCTCTCCAATATACGGAGTAAGTAAATGG -+ -:1+442A,2C1C?+CFH+A..=)B=))..)...7)7@D@D;6(;8(--(-5>CDCC -@SRR800764.25200 25200/2 -TCCACCCGTTCAAGTCTTCAAATAAACCTTGAAAATTCTATAGTAATTATTGATGAGGCTCATAATTTGATAGAAACAATAAATTCTATATATTCCTCTCA -+ -CCCFFFFFHHHHHIGEIJJJJJIGIJHIJJIIGJJJIGIJCFIDGIIIJAGHIIGIIIFIJIJJI>GIIIIIGIJJJJJHHHHHBDDFFFFFDF@CEEEDD -@SRR800764.25201 25201/2 -AAGAAAATATAGAACTTCAATGGCAGCACTTGAAAAAGAAATTAAATGAATTGTATTCTAGGTTTAACTTCCACCGAGATCAATTATCCTTTCAAGTTAAC -+ -CCCFFFFFHHHHGJJJJJJJJJJJJJJIJIIJIIJJJJJJJJJIJJJJJIJJJGIJIJJJJJBGHJJJJJIJJJIIHHFFFFCEEEEEEEDDDDDDCCED@ -@SRR800764.25202 25202/2 -TCTAGTCCGGAAGAAATCTGCAAATTATTGTCTTCATTCAAAAAAGTTTCCTTGGTATCCAAATTAGAGACAAACAATGAGCTAGAGGGATTATCGGATGA -+ -@@FHFHIHGJJGGIGGIIJIJGEEGGFIIJEGIJIIE/?DDGGHHICB@FGGCHIJJFJJHHGFHFFDECCACEEECCBDDDCDCDD=BB>> -@SRR800764.25203 25203/2 -TCTATACTTGCAGGCACCTTCAAGTTCTGATCAGTGTCCATCTCTTCATTTTCCAAAGCAGCGTCGTCTGGCTCTTCAGTTATGGCGCCATTATCATCAAA -+ -BCCFFFFFGDGGHIIHGCGGGIIBB>CHHEBCC@CB;>;;?CA;ADEDDD> -@SRR800764.25204 25204/2 -CACAGATTCAATGACTTGGGAGTGTACTTTCAGTTTAGGCCCATTCGCTATTCAACATGTTTGGTGGCTCGCTAAAGGGTCCCTGCTCGTCACCATATTCA -+ -BB??4BB4?:DDFADD<=)=)B=4CF;EEE3?6?(?@7>C@>>6;(;>A;-5555;?BB? -@SRR800764.25206 25206/2 -AAAACACCATACAAGTACGTCGATATGGCAAAAGAGTATAACTACATTTCTCCCTTCATAATGTGCCTTTCAGAGCAATGGAAATACGTTGACAAGAGTGG -+ -@B@FFFDFFHGHFIECFGIDHIIBEGGGGIHGIGII:B9FHIDHIFIIIGAFHDIGIIJCGIIGEHGIIHHHHGHFFFEFCCEECEDD@ABDCCDDCB>@? -@SRR800764.25207 25207/2 -ATATACTTATTAAATTAATATAAATAAATGAATAATATAATATAACTATATTGAATTATAATCTATCTATCTTTTTTTTCCATATAATATTAAATAATAAT -+ -@B?:A=DDB<4CFHIGH?BFCB8=@FGGJIGGEGGDG:CDDEEHFCC@BDFFF:>ACCCC;; -@SRR800764.25209 25209/2 -CGTTCTTCTCAGCACGCTTTTGCATAATGGTAGAAGCACGCAAATGGTCTTTTCTGACAAGCATAAACACTTTTGAGCCGTACTTGGTCAAGAACTGAGCT -+ -CC@FFFFDHHHGHIJIJJJJJIGIJJJIJJFGHCGHIJIIJIIGHGI8BFFGGHHGAFHJI9@EEHEHFEEFDFDE?@CD;@B=ACCCDCCD@?CACACDD -@SRR800764.25210 25210/2 -TAATGCAGAGTACACCTTGAAGAGAGAGAAAAGAAAATCTTTGAATCCATAGCATAATAGCGATCAACGAAACTTTTTAAGAAGTAAAATGAACTGAAAGG -+ -@CCFFFFFHHCFHGIJJJJJJIIJJJIJJIJIJIJJJHIJEIJJJJJJJIGIHIIJJJJJIJJJJJJJHHHHFFFEEDDCEEDDDDDDDECDDDDDDDDD? -@SRR800764.25211 25211/2 -CTTTGCTCTGCTGGTTTCCGATCACTCTATGGCCTTGAGTATCTATTTCTTTGAAACGATCCCTGGATAACGCATTTTTAGAGAGATCTGTTAGTAATGAC -+ -?@?DDADDFHHFHIFGHIIIGGIICHIJJGDGIIJIFGGDBGFIIIJJICGFFHGI@FHGGGGGHIBHIFGFGF?ACCEBCDDDDDCC@@5>CACDDCA:@ -@SRR800764.25212 25212/2 -AGAAAATGAGATAGAAAATGAAACAGTAAACAAAACAGAAGACAAGGCTGAAAAAGGAAAAGAGGAAGAAGTAAATACCAAAGATAACAAGGAAGAAAAAG -+ -@@@FDDDD?FFD?GHIEHEIJIJGHHCCDDDC?(59AC??B# -@SRR800764.25213 25213/2 -CAGGTGAGTTCATTCATACTTTGGGGGATGCACATGTTTATAAAGACCACATTGATGCCTTGAAAGAACAAATCACCAGAAATCCAAGACCATTCCCGAAA -+ -BB@DBDDEDDFHFIGBHGHFJHBF@D8AHIEGHIEGD<9BDGCHF@FF@FBBGGGIGGCAHGGIGIHHH@DBCEDAED?ACCCACCCABCDCD>@B>?BB3 -@SRR800764.25214 25214/2 -AATACCTGAACTCATGGCCAATCCACCTACCAGAAGGCCTGATAACGCAAATCACGATAACAATGAAATAAGCAATAAAAAACTTGAATATGGATACCCCA -+ -CCCFFDFFHHHGHIIJJIJJJIJJJJJJIJIJJIJJIIJIIGJJJGIJGGGEGIIGHGJIHEEHHHHFFFFFFEEEDEEDDDDDDDDDCEADCCCDCCD@7 -@SRR800764.25215 25215/2 -TTCATTATCAGGTGACGAAGCGGCTCACAAATTGCTAAAATTAAAGATTGCGAACAATTTGAAAAAAAGCGTGGTAGATATAATCATCAAATCTAGTTTGC -+ -@@CFFFFFHHHHFHEGGGJDFHAGEGIIJIGIGJG@FEGICDACDDDCCDC@CCAC::4@:@C -@SRR800764.25216 25216/2 -TTAAGCGGTATTCTAAAGGCTCCGCGAGCGAGCCTCTTTAACCTAATGCAAAAAAAAATTGTTACGCACGTTCCCGGCTTTTACCGTAATAGTAGTCAAGA -+ -@@CFFFFF@FHHHJJJJJJGJJJJJJJJJGIIDIEIJJIJEGHFGHHEFFCFFFDDDDDCCDDDDDDDDDBDDDDBDBDDDDDDDD@BDDDD@DDBDDD>3 -@SRR800764.25217 25217/2 -TAATAAAATGAACTATTTATTACCATTAATAATTGGAGCTACAGATACAGCATTTCCAAGAATTAATAACATTGCTTTTTGAGTATTACCTATGGGGTTAG -+ -@@@FFFDDFGHHGHGBEBCHJIHJJ>HIGIHGDFCEFDCEGEAHDHH?DHFDCGGFEDHGGIJJGGHDGFHEHIHHGCHIGCE=?EHFCFBDEA@A##### -@SRR800764.25218 25218/2 -TTAGACGTGTTCCTAAAACTTTTGACGTTTTTTGGCGGGTAATAAGATGCGTCTACCCATTTTAAGGAACGCCCTCGTAACAGACAGAACGAAGAGTGGCA -+ -@@@DDDFDFFHHHGIGIJJJGIGIJIIIGGDE@@DBHHH4=A@@A@C@C>??@@?C:9::CCC@C>>AAA;;>B>B928FEEIEACHBI:>(5;28-)0&&&89BD(3:???BBC######## -@SRR800764.25222 25222/2 -ATTGCCAGAAAACGACTGTCTTTACGCCATTTACGATTTTGAATACGTAATTAATGGTAATGAAGGTAAGAGATCCAAGATTGTTTTCTTCACTTGGTCTC -+ -;?BF;;4BHB?AD:@?C:CFBCA77=BC;@@@:(6;A3;@->;?>555@>CA55>:@C -@SRR800764.25223 25223/2 -TTTGAATCACTGCAGAAATATGCACTGCGCCTTCTTTTTCTTTGCCTGAAGCACCCACACACAAGAACAGGAATGTGAATGGGCTCCCCATATCACTTTTA -+ -=?;;4+,=:=CF:+3+A+33A:,9*?38((-5((--;D3?=AD(6?C########################### -@SRR800764.25224 25224/2 -CTCAGTGCTTCTTTGAATTCTTCCTTTTTAGTCTGCCTGCCCTCTCCTAACCTTTTAGAGCTTGTCAACAAACTTGTATCTATCTTATAATCTTGAAGTTT -+ -CCCFFFFFHHHHGJJIIIJJJIIJJJIJJJJIJJJIJJJIJJJIJJIGIIHIIIJJHIIIIIJICHHIJEJJIIIJFFGHGHFHFFFFFFDEECC>@C@CA -@SRR800764.25225 25225/2 -AAACCAAAAGACTAACCAGGAAAGTTAATCAGAGGATGACTGTTTTTGTGGTGGGGGGGCGAGGATGTCAGATTCTGCTGACTTCGCAGCGGTAGATGACT -+ -:;?+4A;DDBCFHGIGHBB@+CC:ACAC@::449>C:8099&)055<44:>@@ -@SRR800764.25226 25226/2 -TATACTTAGCAATTTCATGTTTAGTCCCGGCCCCAGTCGGGACCCCGAAAAGGAGAACAATTAAAATGTAAACTAGCAGGTACATATCCTGTAAATGTTAT -+ -@C@FFFFFFHFH?CEFHEB?ABFGHEEE@::CFHHEHAFEBD@@CGGGAABEE;BB2ACCCC@CAADDCC@CCC@@CAC?(:(::4((4@@C34:>C>ADD -@SRR800764.25227 25227/2 -TAATAAAGGTCTAATAAGTATTATGTGAAAAAAATGTAAGAAAATAGGATAACAAATTCTAAGACTAAATACTATTAATAAGTATAGTAAGTACCGTAAGG -+ -@@@DD?DDHFHFHIIGGG@JJHIIIIIBFCHIAGCCDHIGEIH9FGHG4?DGGIE@=FCGFGHHEGI@GHIGHHHH>CE?BCDFDFF@CCCEECED@DDDC -@SRR800764.25228 25228/2 -TAAAGGCCACCATCGGAGAGGGTTTAGATATTAATGTAAAAGGCACGCTAAACCGCAGGGGAAAGGGTATCAGAAGGCCTAAAGGCGTATTTTTTAGATAC -+ -;;?D?BD?DDDHDGBB?'<557@E;=HFB8/''55;?,5::;55>((2<>>4>@@<9)0?>:>AB??4>C# -@SRR800764.25229 25229/2 -CAGAACGTCTAAGGGCATCACAGACCTGTTATTGCCTCAAACTTCCATCGGCTTGGAAACGATAGTCCCTCTAAGCAGTGGGTAAACAGGACATGATAACA -+ -@@@DDDDDFCB?FGG=DGFHICDE@HC444FECID8EBGG:)=FHG@GGGCEAD?AHHAHHC -@SRR800764.25231 25231/2 -CAGAATAGAAAAATAGATCGCCGACAATCGAGGGGTCTTAATTGATGGGGACATCGTTGGAGCTTATATAAGTTTGTCGCTACTTGGCGAAGATGGTTGAG -+ -;18=B;BDDAFD8AC:((,9>75AC################ -@SRR800764.25232 25232/2 -AAAGCACGCATAAATTTGGCTAAATGCATTTGCCTTGCGCTTAGTTCACCACGACCAGAAAAATCCGTACGGTATAGAGCCATAACAGAATCGACCACAAT -+ -@@@DFFDADAFHAEHHEHGGCEGGGEGBFHIJIIIJJIIJJIGGBFFIJIGGGEGHGHEFHFED:BCBECDD5=BDDDA>AACCCCDDDACDD?BB>DBBC -@SRR800764.25233 25233/2 -CAAAATTTCGAACAACCTAGCCCTCGTTTTCGCCGCATTGGAACACTTGAAGAATCTAAGCTTATTAGCTGAAGAAGTTGTAGATAAAATTGTTAATAAAT -+ -@@@DDFDFBFBHFGJHGGIIEIB;EADBHCFA:DFGH@FG3C4)=.77;77BCEC).)7));@DE@;3(..>C>@>(53555:;>C@(:;5>34:>@C@## -@SRR800764.25234 25234/2 -TAATACATATAATTCCATTTGTATCCATAATTCTCTTCATGTTGAGATATATATCTTGAGGGGTATTCGTATCGCTTGTATACAATGATAATCGAGGTAAA -+ -B@@B==ABFFHHFIJIGIJIIJIJJIIJIJJIIJIHHIIIJIIIJIGEHIIHAFGAFFGGIGIEFHH)=FHGGC@C@CHFEHAE>DFF>C@ACCA@BDCCC -@SRR800764.25235 25235/2 -TATATATATAAATATAAATATAAAATATACTTTTTATAATATAATATAATCTTTTATATTTATTAAAATATATATTAATTATATTATAAATCTTATTTAAT -+ -CCCFFFFFHHHHHIJJJIJJJJJJJIJJJJJJJJJJJJJJJJIJJJJJJJJJJJJJJIJJJJJJJJIIIJIIJJJIJJJJIJGJJJEIJJJIJJJJJJHHE -@SRR800764.25236 25236/2 -TTCGGGGTTCCGGCTCCCGTGGCCGGGCCCCGGAACTATTAATAATAAATAATATAATAAGTTTATAAATAATAAATATATAGTCTAAACCTCTTTTTTAT -+ -@CCFFFFAHHFHHGGGIJI;AHIJIGEGAGIIG=BFDCCCEEECDDDCDD>CDDEEEEDC>5@CDDDCDCDCEC:@CCCDEDD3>CACC>?9<:<4C:3I:F?FH+???F1B909:90990*00*9/?E?C:?6@AEE:AC: -@SRR800764.25238 25238/2 -CAGAAGCTTTCTAAATTAAGGGTTTTAGAGATATTATCCGGTCATGACATGATCAAGGAACAATACGGAGTACCATTGCTTGATAAAGATGGCAATTCACC -+ -?@@D?DDFHHHHDHIHGEHIII+ACGDHIGIIJIDHIIIEGGGGHCDBGHFEHEIGIJGIIGIGGIJJIHHHFEFFFFDEEE<@@;@@CDCC9>CCCDCC@ -@SRR800764.25239 25239/2 -GGAAGAACCTAAGGTTATATGTGACCTGATATCACCAGCTGCATTTTGTCTCTTAGAGCTCGAGCGTAGTTTTGATTGCAGTTTGTCGGTACTCAAACCGC -+ -B@CFFFFFHFHHHJHIJIJJIHHIJJJIGIJIIJJJIJJJGIJJJIHIIJ>FHIIJIJIIJJGIJIEHHCHFFFFFEEDCEEEEDDDDC?BDCCCCDA@BD -@SRR800764.25240 25240/2 -AAAAGGCTACAATCCTCGCATGAAACTAATAAAAACGAGCACAATATAAGCCGAGACGTAGCGTTTAACGTACTAACACTACTCGCCAAACCATAAGAGCT -+ -+11BD2+2=DH;?BBDCDC@CADDDBACBBDC>>@ -@SRR800764.25242 25242/2 -TACCTCAGAAAATACTGTTGAATTCTTTCAAGGGGTAGCAAAACTGTCCAGAGCTTATATCTACCTGTGCTCAAAATACAGTTGAAACCACCTCTTCCTAC -+ -@@@FFFDEHHHHGIIJGHGIJJJJJIIIEGHHIIJCFGIJGIIIIIIIIIGIIBHEGHGCGGHGIIGGIJJIGGIHFHEHFDDFCEDDCCCCDDCDDCD@A -@SRR800764.25243 25243/2 -TCCCGTGGTCAATGAAATCAAAGAAGGTACTGCAAACCATGCTAACCCACCGATGGCATATGCTTTCAAACTCGCTGCGGGACTAGCAGAAATCGCTTTAT -+ -:+=1+=D:FB?F8D9DGI@HAH>BGHIB@C8CHCHCGH?H;)7?C7;7?9=@>>(5;5>8ACC###### -@SRR800764.25246 25246/2 -TCGATTTTCACTTTAAAAAACCAGTAATTACAGTAAGAAGCAACAGTGAATTTCATTTGGACTGCCAACTTAATATATGTACTAAAATCGTCCATCATTTG -+ -?@@+B,AD8F?DA>EEBDFGEH+31:9:4?99?DGG>FHHAB*?B)=D=@@=D4.7?ACEEE?BBD>?7@C@?########### -@SRR800764.25247 25247/2 -TTGCATTTAGGCCATGAGCTTTTCTGGAAGAGGCTGAAGACCCCTTCAACACATCCTGCTGATCACTTTTACGCATTTCCCTCAAAGCTCTATTGCGCATT -+ -@@@DBFDFHHHDFGB??CHGIJJGIIFEGGIJJBHIHHGIGIJIGIGCACD########## -@SRR800764.25248 25248/2 -CAATCTATTGAAATACTTTAAGGATATATCATAATTAATGATCTCAAAATGAAGTTTTCCTAATTGCACTAGACACCATGGCATTGTGTCTTTAATATGAG -+ -CCCFFFFFHHHHHJIJJJJIHIJJIJJJJJJIJJIJJJJJJJJJJJJJJJHJJIFHHIJJJGIJJIJJJJJIIJIJJJIIIJIJHEEHHFFFFFFDCDEDE -@SRR800764.25249 25249/2 -ATTTAATAAATAATTTTTAATAAATATTGGTATATTATCAATAGGTTTTCAATTATTTAAAATATAATCTTTAATAGCTTCTAATGTTTTTTTTTTTATTT -+ -@@@DFDBDHBDHFGIIIGDFHGGHEJIGFGIJG@HBHGGEEFIGGIGIG>@DFGD@DGIEIIEHGGBC++++3AF<+AFII9***1?**:)))?*?4***9*(0??*9B8))8)/@78C;==7=7)=EEH######################## diff --git a/latch_cli/services/init/init.py b/latch_cli/services/init/init.py index f34b9fc2..6855a9e1 100644 --- a/latch_cli/services/init/init.py +++ b/latch_cli/services/init/init.py @@ -188,9 +188,21 @@ def _gen_example_snakemake(pkg_root: Path): snakefile_src = source_path / "latch_metadata.py" shutil.copy(snakefile_src, snakefile_dest) - data_dest = pkg_root / "data" - data_src = source_path / "data" - shutil.copytree(data_src, data_dest) + print("Downloading data") + snakemake_base_name = "snakemake_tutorial_data" + subprocess.run( + [ + "curl", + f"https://latch-public.s3.us-west-2.amazonaws.com/sdk/{snakemake_base_name}.zip", + "-o", + str(pkg_root / f"{snakemake_base_name}.zip"), + ], + check=True, + ) + subprocess.run( + ["unzip", str(pkg_root / f"{snakemake_base_name}.zip"), "-d", str(pkg_root)], + check=True, + ) scripts_dest = pkg_root / "scripts" scripts_src = source_path / "scripts" From 8094646d4a8b7ab3dfc8677301e11ebf3057b861 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Fri, 22 Sep 2023 11:44:31 -0700 Subject: [PATCH 261/356] fixes --- latch_cli/centromere/ctx.py | 24 ++++++++++++-------- latch_cli/services/init/common/.dockerignore | 5 ++-- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/latch_cli/centromere/ctx.py b/latch_cli/centromere/ctx.py index 7b17ec54..d6646621 100644 --- a/latch_cli/centromere/ctx.py +++ b/latch_cli/centromere/ctx.py @@ -122,11 +122,15 @@ def __init__( pkg_dir=entity.dockerfile_path.parent, ) if not hasattr(self, "workflow_name"): - raise ValueError(dedent(""" + click.secho( + dedent(""" Unable to locate workflow code. If you are a registering a Snakemake project, make sure to pass the Snakefile path with - the --snakefile flag.""")) + the --snakefile flag."""), + fg="red", + ) + raise click.exceptions.Exit(1) else: assert snakefile is not None @@ -214,14 +218,16 @@ def __init__( click.secho("Failed to open file", fg="red") sys.exit(1) - if ( - metadata._snakemake_metadata is None - or metadata._snakemake_metadata.name is None - ): - raise ValueError( - "Make sure a `latch_metadata.py` file exists in the Snakemake" - " project root." + if metadata._snakemake_metadata is None: + click.secho( + dedent( + """ + Make sure a `latch_metadata.py` file exists in the Snakemake + project root.""", + ), + fg="red", ) + raise click.exceptions.Exit(1) # todo(kenny): support per container task and custom workflow # name for snakemake diff --git a/latch_cli/services/init/common/.dockerignore b/latch_cli/services/init/common/.dockerignore index 28605f0e..87f0fa0e 100644 --- a/latch_cli/services/init/common/.dockerignore +++ b/latch_cli/services/init/common/.dockerignore @@ -1,9 +1,10 @@ -# commonly ignored files README.md CHANGELOG.md docker-compose.yml Dockerfile -.latch/.logs +.latch .git **/__pycache__ .latch_report.tar.gz + +!.latch/snakemake_jit_entrypoint.py From 46fba47c9a8d171df3aac49a5641e6b5f346ecda Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Wed, 27 Sep 2023 14:57:33 -0700 Subject: [PATCH 262/356] update black v Signed-off-by: Ayush Kamat --- .pre-commit-config.yaml | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bb801d91..e48210ce 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,7 +36,7 @@ repos: # - id: sort-simple-yaml # - id: trailing-whitespace - repo: https://github.com/psf/black - rev: 23.7.0 + rev: 23.9.1 hooks: - id: black args: [--preview] diff --git a/pyproject.toml b/pyproject.toml index b9fec2c4..0cab99a5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.poetry.dev-dependencies] -black = "^23.3.0" +black = "^23.9.1" isort = "^5.12.0" ruff = "^0.0.261" From 5f98adb9c9faf1d47f28e8b2fbc6376dd7c1715e Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Wed, 27 Sep 2023 14:58:19 -0700 Subject: [PATCH 263/356] new formatting Signed-off-by: Ayush Kamat --- latch/account.py | 6 ++---- latch/registry/project.py | 12 ++++------- latch/registry/record.py | 18 ++++++---------- latch/registry/table.py | 12 ++++------- latch/registry/types.py | 6 ++---- latch/registry/utils.py | 3 +-- latch/verified/deseq2.py | 3 +-- latch/verified/mafft.py | 3 +-- latch/verified/pathway.py | 3 +-- latch/verified/rnaseq.py | 3 +-- latch/verified/trim_galore.py | 3 +-- latch_cli/auth/csrf.py | 3 +-- latch_cli/auth/pkce.py | 3 +-- latch_cli/centromere/ctx.py | 21 +++++++------------ latch_cli/click_utils.py | 3 +-- latch_cli/docker_utils/__init__.py | 3 +-- latch_cli/exceptions/errors.py | 3 +-- latch_cli/main.py | 6 ++---- latch_cli/menus.py | 3 +-- latch_cli/services/cp/exceptions.py | 3 +-- latch_cli/services/get_executions.py | 12 ++++------- latch_cli/services/get_params.py | 6 ++---- .../example_snakemake/scripts/plot-quals.py | 1 + latch_cli/services/local_dev_old.py | 3 +-- latch_cli/services/preview.py | 3 +-- latch_cli/snakemake/workflow.py | 3 +-- latch_cli/utils/__init__.py | 6 ++---- 27 files changed, 53 insertions(+), 101 deletions(-) diff --git a/latch/account.py b/latch/account.py index 2ddf1971..e18c4be3 100644 --- a/latch/account.py +++ b/latch/account.py @@ -155,14 +155,12 @@ def load(self) -> None: @overload def list_registry_projects( self, *, load_if_missing: Literal[True] = True - ) -> List[Project]: - ... + ) -> List[Project]: ... @overload def list_registry_projects( self, *, load_if_missing: bool - ) -> Optional[List[Project]]: - ... + ) -> Optional[List[Project]]: ... def list_registry_projects( self, *, load_if_missing: bool = True diff --git a/latch/registry/project.py b/latch/registry/project.py index d4c099ed..a2a52d72 100644 --- a/latch/registry/project.py +++ b/latch/registry/project.py @@ -85,12 +85,10 @@ def load(self) -> None: # get_display_name @overload - def get_display_name(self, *, load_if_missing: Literal[True] = True) -> str: - ... + def get_display_name(self, *, load_if_missing: Literal[True] = True) -> str: ... @overload - def get_display_name(self, *, load_if_missing: bool) -> Optional[str]: - ... + def get_display_name(self, *, load_if_missing: bool) -> Optional[str]: ... def get_display_name(self, *, load_if_missing: bool = True) -> Optional[str]: """Get the display name of this project. @@ -116,12 +114,10 @@ def get_display_name(self, *, load_if_missing: bool = True) -> Optional[str]: # list_tables @overload - def list_tables(self, *, load_if_missing: Literal[True] = True) -> List[Table]: - ... + def list_tables(self, *, load_if_missing: Literal[True] = True) -> List[Table]: ... @overload - def list_tables(self, *, load_if_missing: bool) -> Optional[List[Table]]: - ... + def list_tables(self, *, load_if_missing: bool) -> Optional[List[Table]]: ... def list_tables(self, *, load_if_missing: bool = True) -> Optional[List[Table]]: """List Registry tables contained in this project. diff --git a/latch/registry/record.py b/latch/registry/record.py index 5710c68d..d217732b 100644 --- a/latch/registry/record.py +++ b/latch/registry/record.py @@ -167,12 +167,10 @@ def load(self) -> None: # get_name @overload - def get_name(self, *, load_if_missing: Literal[True] = True) -> str: - ... + def get_name(self, *, load_if_missing: Literal[True] = True) -> str: ... @overload - def get_name(self, *, load_if_missing: bool) -> Optional[str]: - ... + def get_name(self, *, load_if_missing: bool) -> Optional[str]: ... def get_name(self, *, load_if_missing: bool = True) -> Optional[str]: """Get the name of this record. @@ -200,16 +198,14 @@ def get_columns( self, *, load_if_missing: Literal[True] = True, - ) -> Dict[str, Column]: - ... + ) -> Dict[str, Column]: ... @overload def get_columns( self, *, load_if_missing: bool, - ) -> Optional[Dict[str, Column]]: - ... + ) -> Optional[Dict[str, Column]]: ... def get_columns( self, @@ -238,16 +234,14 @@ def get_values( self, *, load_if_missing: Literal[True] = True, - ) -> Dict[str, RecordValue]: - ... + ) -> Dict[str, RecordValue]: ... @overload def get_values( self, *, load_if_missing: bool, - ) -> Optional[Dict[str, RecordValue]]: - ... + ) -> Optional[Dict[str, RecordValue]]: ... def get_values( self, diff --git a/latch/registry/table.py b/latch/registry/table.py index 7dcff1a1..f8a9a603 100644 --- a/latch/registry/table.py +++ b/latch/registry/table.py @@ -131,12 +131,10 @@ def load(self) -> None: # get_display_name @overload - def get_display_name(self, *, load_if_missing: Literal[True] = True) -> str: - ... + def get_display_name(self, *, load_if_missing: Literal[True] = True) -> str: ... @overload - def get_display_name(self, *, load_if_missing: bool) -> Optional[str]: - ... + def get_display_name(self, *, load_if_missing: bool) -> Optional[str]: ... def get_display_name(self, *, load_if_missing: bool = True) -> Optional[str]: """Get the display name of this table. @@ -164,12 +162,10 @@ def get_display_name(self, *, load_if_missing: bool = True) -> Optional[str]: @overload def get_columns( self, *, load_if_missing: Literal[True] = True - ) -> Dict[str, Column]: - ... + ) -> Dict[str, Column]: ... @overload - def get_columns(self, *, load_if_missing: bool) -> Optional[Dict[str, Column]]: - ... + def get_columns(self, *, load_if_missing: bool) -> Optional[Dict[str, Column]]: ... def get_columns( self, *, load_if_missing: bool = True diff --git a/latch/registry/types.py b/latch/registry/types.py index ee56973b..48608010 100644 --- a/latch/registry/types.py +++ b/latch/registry/types.py @@ -16,13 +16,11 @@ from enum import StrEnum except ImportError: - class StrEnum(str, Enum): - ... + class StrEnum(str, Enum): ... else: - class StrEnum(str, Enum): - ... + class StrEnum(str, Enum): ... @dataclass(frozen=True) diff --git a/latch/registry/utils.py b/latch/registry/utils.py index a32f6d83..fa98ae09 100644 --- a/latch/registry/utils.py +++ b/latch/registry/utils.py @@ -26,8 +26,7 @@ T = TypeVar("T") -class RegistryTransformerException(ValueError): - ... +class RegistryTransformerException(ValueError): ... def to_python_type(registry_type: RegistryType) -> Type[RegistryPythonValue]: diff --git a/latch/verified/deseq2.py b/latch/verified/deseq2.py index eb984cbc..d99b6445 100644 --- a/latch/verified/deseq2.py +++ b/latch/verified/deseq2.py @@ -70,5 +70,4 @@ def deseq2_wf( ), ] = [], number_of_genes_to_plot: int = 30, -) -> LatchDir: - ... +) -> LatchDir: ... diff --git a/latch/verified/mafft.py b/latch/verified/mafft.py index 083ae69c..531e9aba 100644 --- a/latch/verified/mafft.py +++ b/latch/verified/mafft.py @@ -27,5 +27,4 @@ def mafft( offset: float = 0.0, maxiterate: int = 0, output_file: str = "aligned_mafft.fa", -) -> LatchFile: - ... +) -> LatchFile: ... diff --git a/latch/verified/pathway.py b/latch/verified/pathway.py index 0c97e41e..436d136e 100644 --- a/latch/verified/pathway.py +++ b/latch/verified/pathway.py @@ -15,5 +15,4 @@ def gene_ontology_pathway_analysis( report_name: str, number_of_pathways: int = 20, output_location: LatchDir = LatchDir("latch:///Pathway Analysis/"), -) -> LatchDir: - ... +) -> LatchDir: ... diff --git a/latch/verified/rnaseq.py b/latch/verified/rnaseq.py index 4d3277cc..3f7c57e5 100644 --- a/latch/verified/rnaseq.py +++ b/latch/verified/rnaseq.py @@ -76,5 +76,4 @@ def rnaseq( salmon_index: Optional[LatchFile] = None, save_indices: bool = False, custom_output_dir: Optional[LatchDir] = None, -) -> List[LatchFile]: - ... +) -> List[LatchFile]: ... diff --git a/latch/verified/trim_galore.py b/latch/verified/trim_galore.py index 2973cb8b..4b6c34e0 100644 --- a/latch/verified/trim_galore.py +++ b/latch/verified/trim_galore.py @@ -58,5 +58,4 @@ def trim_galore( retain_unpaired: bool = True, length_1: int = 35, length_2: int = 35, -) -> LatchDir: - ... +) -> LatchDir: ... diff --git a/latch_cli/auth/csrf.py b/latch_cli/auth/csrf.py index eced4e4c..b511a8cb 100644 --- a/latch_cli/auth/csrf.py +++ b/latch_cli/auth/csrf.py @@ -27,5 +27,4 @@ def __init__(self): def __enter__(self, *args): return self - def __exit__(self, *args): - ... + def __exit__(self, *args): ... diff --git a/latch_cli/auth/pkce.py b/latch_cli/auth/pkce.py index e9df3bf5..f800758e 100644 --- a/latch_cli/auth/pkce.py +++ b/latch_cli/auth/pkce.py @@ -86,8 +86,7 @@ def __init__(self): def __enter__(self, *args): return self - def __exit__(self, *args): - ... + def __exit__(self, *args): ... def construct_challenge(self) -> Tuple[str, str]: """Construct verifier & challenge to verify a client's identity in PKCE. diff --git a/latch_cli/centromere/ctx.py b/latch_cli/centromere/ctx.py index d6646621..e16f290b 100644 --- a/latch_cli/centromere/ctx.py +++ b/latch_cli/centromere/ctx.py @@ -159,13 +159,11 @@ def __init__( fg="red", ) click.secho( - ( - "\nIt is possible to avoid including the Snakefile" - " prior to registration by providing a" - " `latch_metadata.py` file in the workflow root.\nThis" - " way it is not necessary to install dependencies or" - " ensure that Snakemake inputs locally." - ), + "\nIt is possible to avoid including the Snakefile" + " prior to registration by providing a" + " `latch_metadata.py` file in the workflow root.\nThis" + " way it is not necessary to install dependencies or" + " ensure that Snakemake inputs locally.", fg="red", ) click.secho("\nExample ", fg="red", nl=False) @@ -251,10 +249,8 @@ def __init__( if self.nucleus_check_version(self.version, self.workflow_name): click.secho( - ( - f"\nVersion ({self.version}) already exists." - " Make sure that you've saved any changes you made." - ), + f"\nVersion ({self.version}) already exists." + " Make sure that you've saved any changes you made.", fg="red", bold=True, ) @@ -293,8 +289,7 @@ def __init__( ) self.ssh_client = ssh_client - def _patched_connect(self): - ... + def _patched_connect(self): ... def _patched_create_paramiko_client(self, base_url): self.ssh_client = ssh_client diff --git a/latch_cli/click_utils.py b/latch_cli/click_utils.py index ff5fb627..7b941e0a 100644 --- a/latch_cli/click_utils.py +++ b/latch_cli/click_utils.py @@ -51,8 +51,7 @@ def format_epilog(self, ctx: Context, formatter: HelpFormatter) -> None: ) -class LatchGroup(LatchCommand, Group): - ... +class LatchGroup(LatchCommand, Group): ... def colored_exception_show(self, file: Optional[IO] = None) -> None: diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 1abff553..1a33e3cb 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -242,8 +242,7 @@ def infer_commands(pkg_root: Path) -> List[DockerCmdBlock]: has_buildable_pyproject = True break - except FileNotFoundError: - ... + except FileNotFoundError: ... # from https://peps.python.org/pep-0518/ and https://peps.python.org/pep-0621/ if has_setup_py or has_buildable_pyproject: diff --git a/latch_cli/exceptions/errors.py b/latch_cli/exceptions/errors.py index da7c3241..1016532f 100644 --- a/latch_cli/exceptions/errors.py +++ b/latch_cli/exceptions/errors.py @@ -12,8 +12,7 @@ class _SyntaxError(BaseException): end_offset: int -class _FlytekitError(BaseException): - ... +class _FlytekitError(BaseException): ... _HandledError = Union[_SyntaxError, _FlytekitError] diff --git a/latch_cli/main.py b/latch_cli/main.py index 471e50d6..5fdcdeaa 100644 --- a/latch_cli/main.py +++ b/latch_cli/main.py @@ -439,10 +439,8 @@ def get_params(wf_name: Union[str, None], version: Union[str, None] = None): if version is None: version = "latest" click.secho( - ( - f"Successfully generated python param map named {wf_name}.params.py with" - f" version {version}\n Run `latch launch {wf_name}.params.py` to launch it." - ), + f"Successfully generated python param map named {wf_name}.params.py with" + f" version {version}\n Run `latch launch {wf_name}.params.py` to launch it.", fg="green", ) diff --git a/latch_cli/menus.py b/latch_cli/menus.py index d91b35bc..70cebed9 100644 --- a/latch_cli/menus.py +++ b/latch_cli/menus.py @@ -295,8 +295,7 @@ def render( start_index=start_index, max_per_page=max_per_page, ) - except KeyboardInterrupt: - ... + except KeyboardInterrupt: ... finally: clear(num_lines_rendered) reveal_cursor() diff --git a/latch_cli/services/cp/exceptions.py b/latch_cli/services/cp/exceptions.py index 0e4645d4..a57e099f 100644 --- a/latch_cli/services/cp/exceptions.py +++ b/latch_cli/services/cp/exceptions.py @@ -1,2 +1 @@ -class PathResolutionError(ValueError): - ... +class PathResolutionError(ValueError): ... diff --git a/latch_cli/services/get_executions.py b/latch_cli/services/get_executions.py index 8d3fa401..5232eb0f 100644 --- a/latch_cli/services/get_executions.py +++ b/latch_cli/services/get_executions.py @@ -223,8 +223,7 @@ def render( prev = (curr_selected, hor_index, term_width, term_height) menus.clear_screen() max_row_len = render(curr_selected, hor_index, term_width, term_height) - except KeyboardInterrupt: - ... + except KeyboardInterrupt: ... finally: menus.clear_screen() menus.reveal_cursor() @@ -317,8 +316,7 @@ def render(curr_selected: int, term_width: int, term_height: int): menus.clear_screen() prev = (curr_selected, term_width, term_height) render(curr_selected, term_width, term_height) - except KeyboardInterrupt: - ... + except KeyboardInterrupt: ... finally: menus.clear_screen() menus.move_cursor((0, 0)) @@ -454,8 +452,7 @@ def render(vert_index, hor_index, term_width, term_height): menus.clear_screen() prev_term_dims = (vert_index, hor_index, term_width, term_height) render(vert_index, hor_index, term_width, term_height) - except KeyboardInterrupt: - ... + except KeyboardInterrupt: ... finally: log_sched.shutdown() log_file.unlink(missing_ok=True) @@ -516,8 +513,7 @@ def render(term_width: int, term_height: int): if prev_term_dims != (term_width, term_height): prev_term_dims = (term_width, term_height) render(term_width, term_height) - except KeyboardInterrupt: - ... + except KeyboardInterrupt: ... finally: menus.clear_screen() menus.move_cursor((0, 0)) diff --git a/latch_cli/services/get_params.py b/latch_cli/services/get_params.py index 2aaf5320..f7e450a6 100644 --- a/latch_cli/services/get_params.py +++ b/latch_cli/services/get_params.py @@ -21,8 +21,7 @@ from latch_cli.utils import retrieve_or_login -class _Unsupported: - ... +class _Unsupported: ... _simple_table = { @@ -326,8 +325,7 @@ def _guess_python_type(literal: LiteralType, param_name: str): # we can parse the variants and define the object in the param map # code. - class _VariantCarrier(enum.Enum): - ... + class _VariantCarrier(enum.Enum): ... _VariantCarrier._variants = literal.enum_type.values # Use param name to uniquely identify each enum diff --git a/latch_cli/services/init/example_snakemake/scripts/plot-quals.py b/latch_cli/services/init/example_snakemake/scripts/plot-quals.py index 345189e0..fe896946 100644 --- a/latch_cli/services/init/example_snakemake/scripts/plot-quals.py +++ b/latch_cli/services/init/example_snakemake/scripts/plot-quals.py @@ -1,4 +1,5 @@ import matplotlib + matplotlib.use("Agg") import matplotlib.pyplot as plt from pysam import VariantFile diff --git a/latch_cli/services/local_dev_old.py b/latch_cli/services/local_dev_old.py index 27a53bbe..13b33263 100644 --- a/latch_cli/services/local_dev_old.py +++ b/latch_cli/services/local_dev_old.py @@ -311,8 +311,7 @@ async def output_task(): try: io_task = asyncio.gather(input_task(), output_task(), resize_task()) await io_task - except asyncio.CancelledError: - ... + except asyncio.CancelledError: ... finally: termios.tcsetattr(sys.stdin.fileno(), termios.TCSANOW, old_settings_stdin) signal.signal(signal.SIGWINCH, old_sigwinch_handler) diff --git a/latch_cli/services/preview.py b/latch_cli/services/preview.py index 8fc42f29..db6a54d3 100644 --- a/latch_cli/services/preview.py +++ b/latch_cli/services/preview.py @@ -176,8 +176,7 @@ def render( start_index=start_index, max_per_page=max_per_page, ) - except KeyboardInterrupt: - ... + except KeyboardInterrupt: ... finally: menus.clear(num_lines_rendered) menus.reveal_cursor() diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 7ca1c7c8..e1ca4704 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -85,8 +85,7 @@ class JobOutputInfo: type_: Union[LatchFile, LatchDir] -def task_fn_placeholder(): - ... +def task_fn_placeholder(): ... def variable_name_for_file(file: snakemake.io.AnnotatedString): diff --git a/latch_cli/utils/__init__.py b/latch_cli/utils/__init__.py index 7ce0b718..884cdc77 100644 --- a/latch_cli/utils/__init__.py +++ b/latch_cli/utils/__init__.py @@ -58,8 +58,7 @@ def urljoins(*args: str, dir: bool = False) -> str: return res -class AuthenticationError(RuntimeError): - ... +class AuthenticationError(RuntimeError): ... def get_auth_header() -> str: @@ -199,8 +198,7 @@ def hash_directory(dir_path: Path) -> str: continue exclude.append(l) - except FileNotFoundError: - ... + except FileNotFoundError: ... from docker.utils import exclude_paths From 35a4554e84d400f7bb9c717de33636e89320df54 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Wed, 27 Sep 2023 22:24:11 -0700 Subject: [PATCH 264/356] change imported typehints --- latch_cli/snakemake/workflow.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 7ca1c7c8..ded756eb 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -2,10 +2,20 @@ import json import textwrap import typing -from collections.abc import Generator, Iterable from dataclasses import dataclass from pathlib import Path -from typing import Any, Dict, List, Optional, Tuple, Type, TypeVar, Union +from typing import ( + Any, + Dict, + Generator, + Iterable, + List, + Optional, + Tuple, + Type, + TypeVar, + Union, +) from urllib.parse import urlparse import snakemake From d9b50d86249e7811147d08bd9a3570622c4fd282 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Wed, 27 Sep 2023 22:37:56 -0700 Subject: [PATCH 265/356] lets trust these again --- .github/workflows/test.yaml | 19 +--- tests/__init__.py | 0 tests/test.py | 7 ++ tests/test_cli.py | 190 ------------------------------------ tests/test_launch.py | 102 ------------------- tests/test_login.py | 7 -- tests/test_types.py | 20 ---- 7 files changed, 9 insertions(+), 336 deletions(-) delete mode 100644 tests/__init__.py create mode 100644 tests/test.py delete mode 100644 tests/test_cli.py delete mode 100644 tests/test_launch.py delete mode 100644 tests/test_login.py delete mode 100644 tests/test_types.py diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 435348a4..049f1ffe 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -7,7 +7,7 @@ jobs: strategy: fail-fast: false matrix: - python: ["3.8", "3.9"] + python: ["3.8", "3.9", "3.10", "3.11"] platform: ["macos-10.15"] runs-on: ${{ matrix.platform }} steps: @@ -17,21 +17,6 @@ jobs: uses: actions/setup-python@v2 with: python-version: ${{ matrix.python }} - - name: Download Docker - run: | - brew install docker docker-machine - - # Latest virtualbox has breaking change for mac - brew uninstall virtualbox - cd $(brew --repo homebrew/cask) - git checkout 8670a72380c57c606d6582b645421e31dad2eee2 - brew install --cask virtualbox - - # Avoids throttling git api in `docker-machine create` cmd - curl --create-dirs -Lo /Users/runner/.docker/machine/cache/boot2docker.iso https://github.com/boot2docker/boot2docker/releases/download/v18.09.1-rc1/boot2docker.iso - - docker-machine create --driver virtualbox default - docker-machine env default - name: Install dev run: | python3 -m pip install -r dev-requirements.txt @@ -49,7 +34,7 @@ jobs: strategy: fail-fast: false matrix: - python: ["3.8", "3.9"] + python: ["3.8", "3.9", "3.10", "3.11"] platform: ["ubuntu-18.04"] runs-on: ${{ matrix.platform }} steps: diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/test.py b/tests/test.py new file mode 100644 index 00000000..e4eacf78 --- /dev/null +++ b/tests/test.py @@ -0,0 +1,7 @@ +import subprocess + +from tests.fixtures import test_account_jwt + + +def test_ls(test_account_jwt): + subprocess.run(["latch", "ls"], check=True) diff --git a/tests/test_cli.py b/tests/test_cli.py deleted file mode 100644 index 56c77b78..00000000 --- a/tests/test_cli.py +++ /dev/null @@ -1,190 +0,0 @@ -import os -import secrets -import string -import subprocess -import textwrap -from pathlib import Path -from typing import List - -import pytest -import requests - -from latch_cli.config.latch import config -from tests.fixtures import test_account_jwt - - -def _random_name(length: int): - return "".join(secrets.choice(string.ascii_letters) for _ in range(length)) - - -def _normalize_remote_path(path: str): - if path.startswith("latch://"): - path = path[len("latch://") :] - path = path.strip("/") - return path - - -def _run_and_verify(cmd: List[str], does_exist: str): - output = subprocess.run(cmd, capture_output=True, check=True) - stdout = output.stdout.decode("utf-8") - assert does_exist in stdout - - -def _file_exists(token, remote_dir: str, filename: str) -> bool: - filename = _normalize_remote_path(filename) - remote_dir = _normalize_remote_path(remote_dir) - - if not remote_dir: - remote_path = filename - else: - remote_path = f"{remote_dir}/{filename}" - - headers = {"Authorization": f"Bearer {token}"} - data = {"filename": remote_path} - response = requests.post(url=config.api.data.verify, headers=headers, json=data) - try: - assert response.status_code == 200 - except: - raise ValueError(f"{response.content}") - return response.json()["exists"] - - -def _run_mkdir_touch_recursive(token, curr_dir: str, branching_factor: int, depth: int): - if depth > 2: - return - curr_dir = _normalize_remote_path(curr_dir) - for _ in range(branching_factor): - name = _random_name(10) - if not curr_dir: - remote_path = name - else: - remote_path = f"{curr_dir}/{name}" - operation = secrets.choice(["mkdir", "touch"]) - _cmd = ["latch", operation, remote_path] - _run_and_verify(_cmd, "Success") - assert _file_exists(token, curr_dir, name) - if operation == "mkdir": - _run_mkdir_touch_recursive(token, remote_path, branching_factor, depth + 1) - _cmd = ["latch", "rm", remote_path] - _run_and_verify(_cmd, "Success") - - -def _run_nested_cp(token, curr_dir: str, filename: str, depth: int): - if depth > 5: - return - filename = _normalize_remote_path(filename) - curr_dir = _normalize_remote_path(curr_dir) - _cmd = ["latch", "mkdir", curr_dir] - _run_and_verify(_cmd, f"Successfully created directory {curr_dir}.") - _run_cp_and_clean_up(token, curr_dir, filename) - nested_dir_name = _random_name(10) - nested_filename = _random_name(10) - _run_nested_cp(token, f"{curr_dir}/{nested_dir_name}", nested_filename, depth + 1) - _cmd = ["latch", "rm", curr_dir] - _run_and_verify(_cmd, f"Successfully deleted {curr_dir}.") - - -def _run_cp_and_clean_up(token, remote_dir: str, filename: str): - """ - Checks that - (1) the file was actually copied to latch, and - (2) the file contents do not change from local -> latch -> local - """ - filename = _normalize_remote_path(filename) - remote_dir = _normalize_remote_path(remote_dir) - - initial = Path(f"initial_{filename}").resolve() - final = Path(f"final_{filename}").resolve() - try: - if not remote_dir: - remote_path = f"latch:///{filename}" - else: - remote_path = f"latch:///{remote_dir}/{filename}" - initial_text = _random_name(100) - with open(initial, "w") as f: - f.write(initial_text) - cmd = ["latch", "cp", initial, remote_path] - _run_and_verify(cmd, f"Successfully copied {initial} to {remote_path}") - assert _file_exists(token, remote_dir, filename) - cmd = ["latch", "cp", remote_path, final] - _run_and_verify(cmd, f"Successfully copied {remote_path} to {final}") - with open(final, "r") as f: - final_text = f.read() - assert initial_text == final_text - cmd = ["latch", "rm", remote_path] - _run_and_verify(cmd, f"Successfully deleted {remote_path}") - assert not _file_exists(token, remote_dir, filename) - finally: - if os.path.isfile(initial): - os.remove(initial) - if os.path.isfile(final): - os.remove(final) - - -def test_cp_home_robustness(test_account_jwt): - for _ in range(5): - filename = _random_name(10) - filename = f"{filename}.txt" - _run_cp_and_clean_up(test_account_jwt, "", filename) - - -def test_cp_nested(test_account_jwt): - initial_dir_name = _random_name(10) - initial_filename = _random_name(10) - _run_nested_cp(test_account_jwt, initial_dir_name, initial_filename, 0) - - -def test_touch_mkdir_higher_branching_factor(test_account_jwt): - # don't do any more than 3 for the branching_factor - _run_mkdir_touch_recursive(test_account_jwt, "/", branching_factor=3, depth=2) - - -@pytest.mark.xfail(strict=True) -def test_bad_input_cp_1(): - name1 = _random_name(10) - name2 = _random_name(10) - _cmd = ["latch", "cp", name1, name2] - _run_and_verify(_cmd, "Success") - - -@pytest.mark.xfail(strict=True) -def test_bad_input_cp_2(): - name1 = _random_name(10) - name2 = _random_name(10) - _cmd = ["latch", "cp", f"latch:///{name1}", f"latch:///{name2}"] - _run_and_verify(_cmd, "Success") - - -def test_ls(test_account_jwt): - for _ in range(5): - name = _random_name(10) - _cmd = ["latch", "mkdir", name] - _run_and_verify(_cmd, "Success") - _cmd = ["latch", "ls"] - _run_and_verify(_cmd, name) - _cmd = ["latch", "rm", name] - _run_and_verify(_cmd, "Success") - - -# def test_launch(test_account_jwt): -# with open("foo.py", "w") as f: -# f.write( -# textwrap.dedent( -# """ -# from latch.types import LatchFile -# -# params = { -# "_name": "wf.__init__.assemble_and_sort", -# "read1": LatchFile("latch:///read1"), -# "read2": LatchFile("latch:///read2"), -# } -# """ -# ) -# ) -# -# _cmd = ["latch", "launch", "foo.py"] -# _run_and_verify( -# _cmd, -# "Successfully launched workflow named wf.__init__.assemble_and_sort with" -# " version latest.", -# ) diff --git a/tests/test_launch.py b/tests/test_launch.py deleted file mode 100644 index a6bd20fa..00000000 --- a/tests/test_launch.py +++ /dev/null @@ -1,102 +0,0 @@ -""" -test.test_launch -~~~ - - - -""" - -from tempfile import NamedTemporaryFile - -from latch_cli.services.launch import launch - -simple_plan = """from latch.types import LatchFile - -params = { - "_name": "wf.__init__.assemble_and_sort", - "read1": LatchFile("latch:///read1"), - "read2": LatchFile("latch:///read2"), -}""" - -crispresso_plan = """from latch.types import LatchFile, LatchDir - - -params = { - "_name": "wf.__init__.crispresso2_wf", - "output_folder": LatchDir("latch:///CRISPResso2_output/"), - "fastq_r1": LatchFile("s3://latch-public/welcome/CRISPResso2/nhej.r1.fastq.gz"), - "fastq_r2": LatchFile("s3://latch-public/welcome/CRISPResso2/nhej.r2.fastq.gz"), - "amplicon_seq": [ - "AATGTCCCCCAATGGGAAGTTCATCTGGCACTGCCCACAGGTGAGGAGGTCATGATCCCCTTCTGGAGCTCCCAACGGGCCGTGGTCTGGTTCATCATCTGTAAGAATGGCTTCAAGAGGCTCGGCTGTGGTT" - ], - "name": "nhej", -}""" - -rnaseq_plan = """from latch.types import LatchFile, LatchDir -from enum import Enum - -class Strandedness(Enum): - reverse = "reverse" - forward = "forward" - -params = { - "_name": "wf.__init__.nf_rnaseq_wf", - "sample_ids": [ - "WT_REP1", - "RAP1_UNINDUCED_REP1", - "RAP1_IAA_30M_REP1", - ], - "samples": [ - [ - LatchFile("s3://latch-public/welcome/nf_rnaseq/SRR6357070_1.fastq.gz"), - LatchFile("s3://latch-public/welcome/nf_rnaseq/SRR6357070_2.fastq.gz"), - ], - [ - LatchFile("s3://latch-public/welcome/nf_rnaseq/SRR6357073_1.fastq.gz"), - ], - [ - LatchFile("s3://latch-public/welcome/nf_rnaseq/SRR6357076_1.fastq.gz"), - LatchFile("s3://latch-public/welcome/nf_rnaseq/SRR6357076_2.fastq.gz"), - ], - ], - "strandedness": [ - Strandedness.reverse, - Strandedness.reverse, - Strandedness.reverse, - ], - "fasta": LatchFile("s3://latch-public/welcome/nf_rnaseq/genome.fa.gz"), - "gtf": LatchFile("s3://latch-public/welcome/nf_rnaseq/genes.gtf.gz"), - "gene_bed": LatchFile("s3://latch-public/welcome/nf_rnaseq/genes.bed"), - "output_dir": LatchDir("latch://nf_rnaseq_results/"), -}""" - -# NOTE (kenny) ~ This is a poor test for the moment , but without mocking out -# the connection to Latch nucleus, we can rely on the boolean response as -# success. - - -# def test_execute_previous_versions(): -# with NamedTemporaryFile("w+") as tf: -# tf.write(simple_plan) -# tf.seek(0) - -# assert launch(tf.name) == "wf.__init__.assemble_and_sort" -# assert launch(tf.name, "barrackobama") == "wf.__init__.assemble_and_sort" - - -# def test_execute_rnaseq(): -# with NamedTemporaryFile("w+") as tf: -# tf.write(rnaseq_plan) -# tf.seek(0) - -# assert launch(tf.name) == "wf.__init__.nf_rnaseq_wf" - - -# TODO(ayush, kenny): fix this test - -# def test_execute_crispresso(): - -# with NamedTemporaryFile("w+") as tf: -# tf.write(crispresso_plan) -# tf.seek(0) - -# assert launch(tf.name) == "wf.__init__.crispresso2_wf" diff --git a/tests/test_login.py b/tests/test_login.py deleted file mode 100644 index 6268f2c4..00000000 --- a/tests/test_login.py +++ /dev/null @@ -1,7 +0,0 @@ -""" -test.test_login -~~~ -User can retrieve a authorization token for the sdk using 0Auth browser flow. -""" - -# We will need selenium for this diff --git a/tests/test_types.py b/tests/test_types.py deleted file mode 100644 index 6b23bf0b..00000000 --- a/tests/test_types.py +++ /dev/null @@ -1,20 +0,0 @@ -import pytest - -from latch.types.utils import _is_valid_url - - -def test_validate_latch_url(): - valid_urls = ( - "latch:///foo.txt", - "latch:///foo/bar.txt", - "latch:///foo/bar/", - "latch:///foo/bar", - "s3:///foo/bar", - ) - invalid_urls = ("latch://foo.txt", "lach:///foo.txt", "gcp:///foo.txt") - - for url in valid_urls: - assert _is_valid_url(url) is True - - for url in invalid_urls: - assert _is_valid_url(url) is False From 71f2ae77bbbdeba62ccb23b13aa93a4a9a14d91c Mon Sep 17 00:00:00 2001 From: Hannah Le Date: Thu, 28 Sep 2023 10:00:59 -0700 Subject: [PATCH 266/356] updated dockerfile command --- docs/source/manual/tutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/manual/tutorial.md b/docs/source/manual/tutorial.md index 493d9329..b36b87f2 100644 --- a/docs/source/manual/tutorial.md +++ b/docs/source/manual/tutorial.md @@ -116,7 +116,7 @@ dependencies: A Dockerfile can be automatically generated by typing: ```console -latch dockerfile snakemake-wf +latch dockerfile snakemake-wf --snakemake ``` ## Step 3: Upload the workflow to Latch From dcc6e856981c07d4ef3b1983f6596b2f5098b5ee Mon Sep 17 00:00:00 2001 From: Hannah Le Date: Thu, 28 Sep 2023 10:04:19 -0700 Subject: [PATCH 267/356] removed pre-release --- docs/source/manual/snakemake.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/docs/source/manual/snakemake.md b/docs/source/manual/snakemake.md index 3a5f5bcb..25bb89ca 100644 --- a/docs/source/manual/snakemake.md +++ b/docs/source/manual/snakemake.md @@ -1,11 +1,5 @@ # [Alpha Pre-release] Snakemake Integration -## Pre-release Disclaimer - Currently not ready for production use - -Latch support for Snakemake is in active development. Some workflows already work but a lot of common use cases need minor work. This documentation is also in active development. - -This pre-release was created to integrate miscellaneous improvements that accumulated over the course of developing the integration and to prevent the codebase from further diverging from the main branch. - ## Getting Started Latch's snakemake integration allows developers to build graphical interfaces to expose their workflows to wet lab teams. It also provides managed cloud infrastructure for execution of the workflow's jobs. From 5d82406dff3708f0c46fdd377c080bcf82471bdd Mon Sep 17 00:00:00 2001 From: Hannah Le Date: Thu, 28 Sep 2023 10:05:26 -0700 Subject: [PATCH 268/356] changed title --- docs/source/manual/snakemake.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/manual/snakemake.md b/docs/source/manual/snakemake.md index 25bb89ca..e551dff4 100644 --- a/docs/source/manual/snakemake.md +++ b/docs/source/manual/snakemake.md @@ -1,4 +1,4 @@ -# [Alpha Pre-release] Snakemake Integration +# Snakemake Integration ## Getting Started From 0bc2046e51522c59bfd1d9e0ea165941380565eb Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Thu, 28 Sep 2023 10:14:28 -0700 Subject: [PATCH 269/356] use sm extras --- latch_cli/docker_utils/__init__.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 1abff553..be1c4acb 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -32,7 +32,13 @@ def write_block(self, f: TextIOWrapper): f.write("\n".join(self.commands) + "\n\n") -def get_prologue(config: LatchWorkflowConfig) -> List[str]: +def get_prologue( + config: LatchWorkflowConfig, wf_type: WorkflowType = WorkflowType.latchbiosdk +) -> List[str]: + if wf_type == WorkflowType.snakemake: + library_name = '"latch[snakemake]"' + else: + library_name = "latch" return [ "# DO NOT CHANGE", f"from {config.base_image}", @@ -59,7 +65,7 @@ def get_prologue(config: LatchWorkflowConfig) -> List[str]: "", "# Latch SDK", "# DO NOT REMOVE", - f"run pip install latch=={config.latch_version}", + f"run pip install {library_name}=={config.latch_version}", "run mkdir /opt/latch", ] @@ -361,7 +367,7 @@ def generate_dockerfile( click.echo() with outfile.open("w") as f: - f.write("\n".join(get_prologue(config)) + "\n\n") + f.write("\n".join(get_prologue(config, wf_type)) + "\n\n") commands = infer_commands(pkg_root) if len(commands) > 0: From 9d7fd73d5941b21ace7e9ddeb6dc0b1f10a82062 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Thu, 28 Sep 2023 18:36:30 -0700 Subject: [PATCH 270/356] add empty priorityrules --- latch_cli/snakemake/serialize.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index 1b702f51..382bddcd 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -120,6 +120,8 @@ def extract_dag(self): self.rules, targetfiles=target_files, targetrules=target_rules, + priorityrules=set(), + priorityfiles=set(), ) self.persistence = Persistence( From 0e12907f89a1c36ca53b61fdeba4f56f81fbda49 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Thu, 28 Sep 2023 22:29:16 -0700 Subject: [PATCH 271/356] init Signed-off-by: Ayush Kamat --- docs/source/manual/snakemake.md | 98 ++++++++++--------- latch/types/metadata.py | 18 +++- latch_cli/docker_utils/__init__.py | 2 +- .../services/init/example_snakemake/Snakefile | 32 +++--- .../init/example_snakemake/latch_metadata.py | 6 +- latch_cli/snakemake/serialize.py | 18 ++-- latch_cli/snakemake/workflow.py | 71 +++++++++----- 7 files changed, 146 insertions(+), 99 deletions(-) diff --git a/docs/source/manual/snakemake.md b/docs/source/manual/snakemake.md index 3a5f5bcb..a9b024e8 100644 --- a/docs/source/manual/snakemake.md +++ b/docs/source/manual/snakemake.md @@ -12,7 +12,7 @@ Latch's snakemake integration allows developers to build graphical interfaces to A primary design goal for integration is to allow developers to register existing projects with minimal added boilerplate and modifications to code. Here we outline exactly what these changes are and why they are needed. -Recall a snakemake project consists of a `Snakefile`, which describes workflow +Recall a snakemake project consists of a `Snakefile` , which describes workflow rules in an ["extension"](https://snakemake.readthedocs.io/en/stable/snakefiles/rules.html) of Python, and associated python code imported and called by these rules. To make this project compatible with Latch, we need to do the following: 1. Identify and construct explicit parameters for each file dependency in `latch_metadata.py` @@ -52,7 +52,7 @@ from pathlib import Path from latch.types.directory import LatchDir from latch.types.file import LatchFile -from latch.types.metadata import LatchAuthor, SnakemakeFileParameter, SnakemakeMetadata +from latch.types.metadata import LatchAuthor, SnakemakeParameter, SnakemakeMetadata SnakemakeMetadata( display_name="fgbio Best Practise FASTQ -> Consensus Pipeline", @@ -60,17 +60,17 @@ SnakemakeMetadata( name="Fulcrum Genomics", ), parameters={ - "r1_fastq": SnakemakeFileParameter( + "r1_fastq": SnakemakeParameter( display_name="Read 1 FastQ", type=LatchFile, path=Path("tests/r1.fq.gz"), ), - "r2_fastq": SnakemakeFileParameter( + "r2_fastq": SnakemakeParameter( display_name="Read 2 FastQ", type=LatchFile, path=Path("tests/r2.fq.gz"), ), - "genome": SnakemakeFileParameter( + "genome": SnakemakeParameter( display_name="Reference Genome", type=LatchDir, path=Path("tests/hs38DH"), @@ -80,23 +80,24 @@ SnakemakeMetadata( ``` ### Step 2: Define all dependencies in a container -When executing Snakemake jobs on Latch, the jobs run within an environment specified by a `Dockerfile`. It is important to ensure that all required dependencies, whether they are third-party binaries, python libraries, or shell scripts, are correctly installed and configured within this `Dockerfile` so the job has access to them. + +When executing Snakemake jobs on Latch, the jobs run within an environment specified by a `Dockerfile` . It is important to ensure that all required dependencies, whether they are third-party binaries, python libraries, or shell scripts, are correctly installed and configured within this `Dockerfile` so the job has access to them. **Key Dependencies to Consider**: * Python Packages: - * Specify these in a `requirements.txt` or `environment.yaml` file. + + Specify these in a `requirements.txt` or `environment.yaml` file. * Conda Packages: - * List these in an `environment.yaml` file. + + List these in an `environment.yaml` file. * Bioinformatics Tools: - * Often includes third-party binaries. They will need to be manually added to the Dockerfile. + + Often includes third-party binaries. They will need to be manually added to the Dockerfile. * Snakemake wrappers and containers: - * Note that while many Snakefile rules use singularity or docker containers, Latch doesn't currently support these wrapper or containerized environments. Therefore, all installation codes for these must be manually added into the Dockerfile. + + Note that while many Snakefile rules use singularity or docker containers, Latch doesn't currently support these wrapper or containerized environments. Therefore, all installation codes for these must be manually added into the Dockerfile. **Generating a Customizable Dockerfile:** To generate a `Dockerfile` that can be modified, use the following command: -`latch dockerfile ` + `latch dockerfile ` The above command searches for the `environment.yaml` and `requirements.txt` files within your project directory. Based on these, it generates Dockerfile instructions to install the specified Conda and Python dependencies. @@ -108,20 +109,21 @@ When you register your snakemake project with Latch, a container is automaticall When snakemake workflows are executed on Latch, each generated job is run in a separate container on a potentially isolated machine. This means your `Snakefile` might need to be modified to address problems that arise from this type of execution that were not present when executing locally: -- Add missing rule inputs that are implicitly fulfiled when executing locally. Index files for biological data are commonly expected to always be alongside their matching data. -- Make sure shared code does not rely on input files. This is any code that is not under a rule and so gets executed by every task -- Add `resources` directives if tasks run out of memory or disk space -- Optimize data transfer by merging tasks that have 1-to-1 dependencies +* Add missing rule inputs that are implicitly fulfiled when executing locally. Index files for biological data are commonly expected to always be alongside their matching data. +* Make sure shared code does not rely on input files. This is any code that is not under a rule and so gets executed by every task +* Add `resources` directives if tasks run out of memory or disk space +* Optimize data transfer by merging tasks that have 1-to-1 dependencies ### Step 4: Register your project -When the above steps have been taken, it is safe to register your project with the Latch CLI. +When the above steps have been taken, it is safe to register your project with the Latch CLI. Example: `latch register / --snakefile /Snakefile` -This command will build a container and construct a graphical interface from your `latch_metdata.py` file. When this process has completed, a link to view your workflow on the Latch console will be printed to `stdout`. +This command will build a container and construct a graphical interface from your `latch_metdata.py` file. When this process has completed, a link to view your workflow on the Latch console will be printed to `stdout` . --- + ## Lifecycle of a Snakemake Execution on Latch Snakemake support is currently based on JIT (Just-In-Time) registraton. This means that the workflow produced by `latch register` will only register a second workflow, which will run the actual pipeline tasks. This is because the actual structure of the workflow cannot be specified until parameter values are provided. @@ -137,8 +139,8 @@ The first ("JIT") workflow does the following: Debugging: -- The generated runtime workflow entrypoint is uploaded to `latch:///.snakemake_latch/workflows//entrypoint.py` -- Internal workflow specifications are uploaded to `latch:///.snakemake_latch/workflows//spec` +* The generated runtime workflow entrypoint is uploaded to `latch:///.snakemake_latch/workflows//entrypoint.py` +* Internal workflow specifications are uploaded to `latch:///.snakemake_latch/workflows//spec` ### Runtime Workflow @@ -151,7 +153,7 @@ Each task runs a modified Snakemake executable using a script from the Latch SDK Debugging: -- The Snakemake-compiled tasks are uploaded to `latch:///.snakemake_latch/workflows//compiled_tasks` +* The Snakemake-compiled tasks are uploaded to `latch:///.snakemake_latch/workflows//compiled_tasks` #### Example @@ -197,8 +199,8 @@ def __rule_fastqc(input, output, ...): Note: -- The "all" rule is entirely commented out -- The "fastqc" rule has no wildcards in its decorators +* The "all" rule is entirely commented out +* The "fastqc" rule has no wildcards in its decorators ### Limitations @@ -227,9 +229,9 @@ If registration fails before metadata can be pulled, the CLI will generate an ex ### Input Parameters -Since there is no explicit entrypoint (`@workflow`) function in a Snakemake workflow, parameters are instead specified in the metadata file. +Since there is no explicit entrypoint ( `@workflow` ) function in a Snakemake workflow, parameters are instead specified in the metadata file. -Currently only `LatchFile` and `LatchDir` parameters are supported. Both directory and file inputs are specified using `SnakemakeFileParameter` and setting the `type` field as appropriate. +Currently only `LatchFile` and `LatchDir` parameters are supported. Both directory and file inputs are specified using `SnakemakeParameter` and setting the `type` field as appropriate. Parameters must include a `path` field which specifies where the data will be downloaded to. This usually matches some file location expected by a Snakemake rule. Frequently, instead of simple paths, a rule with use a `configfile` to dynamically find input paths. In this case the only requiremtn is that the path matches the config file included in the workflow Docker image. @@ -237,7 +239,7 @@ Example: ```py parameters = { - "example": SnakemakeFileParameter( + "example": SnakemakeParameter( display_name="Example Parameter", type=LatchFile, path=Path("example.txt"), @@ -249,12 +251,11 @@ parameters = { | Problem | Common Solution | | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `The above error occured when reading the Snakefile to extract workflow metadata.` | Snakefile has errors outside of any rules. Frequently caused by missing dependencies (look for `ModuleNotFoundError`). Either install dependencies or add a `latch_metadata.py` file | +| `The above error occured when reading the Snakefile to extract workflow metadata.` | Snakefile has errors outside of any rules. Frequently caused by missing dependencies (look for `ModuleNotFoundError` ). Either install dependencies or add a `latch_metadata.py` file | | `snakemake.exceptions.WorkflowError: Workflow defines configfile config.yaml but it is not present or accessible (full checked path: /root/config.yaml)` | Include a `config.yaml` in the workflow Docker image. Currently, config files cannot be generated from workflow parameters. | -| `Command '['/usr/local/bin/python', '-m', 'latch_cli.snakemake.single_task_snakemake', ...]' returned non-zero exit status 1.` | The runtime single-job task failed. Look at logs to find the error. It will be marked with the string `[!] Failed`. | +| `Command '['/usr/local/bin/python', '-m', 'latch_cli.snakemake.single_task_snakemake', ...]' returned non-zero exit status 1.` | The runtime single-job task failed. Look at logs to find the error. It will be marked with the string `[!] Failed` . | | Runtime workflow task fails with `FileNotFoundError in file /root/workflow/Snakefile` but the file is specified in workflow parameters | Wrap the code that reads the file in a function. **See section "Input Files Referenced Outside of Rules"** | -| MultiQC `No analysis results found. Cleaning up..` | FastQC outputs two files for every FastQ file: the raw `.zip` data and the HTML report. Include the raw `.zip` outputs of FastQC in the MultiQC rule inputs. **See section "Input Files Not Explicitly Defined in Rules"** " - +| MultiQC `No analysis results found. Cleaning up..` | FastQC outputs two files for every FastQ file: the raw `.zip` data and the HTML report. Include the raw `.zip` outputs of FastQC in the MultiQC rule inputs. **See section "Input Files Not Explicitly Defined in Rules"** " ## Troubleshooting: Input Files Referenced Outside of Rules @@ -279,7 +280,7 @@ rule fastqc: fastqc {input} -o {output} ``` -Since the `Path("inputs").glob(...)` call is not under any rule, _it runs in all tasks._ Because the `fastqc` rule does not specify `input_dir` as an `input`, it will not be downloaded and the code will throw an error. +Since the `Path("inputs").glob(...)` call is not under any rule, _it runs in all tasks._ Because the `fastqc` rule does not specify `input_dir` as an `input` , it will not be downloaded and the code will throw an error. ### Solution @@ -303,7 +304,7 @@ rule all_function: expand("fastqc/{sample}.html", sample=get_samples()) ``` -This works because the JIT step replaces `input`, `output`, `params`, and other declarations with static strings for the runtime workflow so any function calls within them will be replaced with pre-computed strings and the Snakefile will not attempt to read the files again. +This works because the JIT step replaces `input` , `output` , `params` , and other declarations with static strings for the runtime workflow so any function calls within them will be replaced with pre-computed strings and the Snakefile will not attempt to read the files again. **Same example at runtime:** @@ -339,9 +340,11 @@ rule all: ``` ## Troubleshooting: Input Files Not Explicitly Defined in Rules + When running the snakemake workflow locally, not all input files must be explicitly defined in every rule because all files are generated on one computer. However, tasks on Latch only download files specified by their target rules. Thus, unspecified input files will cause the Snakefile rule to fail due to missing input files. **Example** + ```python # ERROR: the .zip file produced by the the fastqc rule is not found in the multiqc rule! @@ -359,7 +362,7 @@ rule fastqc: shell("fastqc -o {params} --noextract -k 5 -t 8 -f fastq {input} 2>{log}") rule multiqc: - input: + input: aligned_sequences = join(WORKDIR, "plasmid_wells_aligned_sequences.csv") output: directory(join(WORKDIR, "QC", "multiqc_report", 'raw')) params: @@ -373,9 +376,11 @@ rule multiqc: ``` ### Solution -For programs that produce multiple types of input files (e.g. `.zip` and `.html` in the case of FastQC), explicitly specify these files in the outputs of the previous rule and in the inputs of the subsequent rule. + +For programs that produce multiple types of input files (e.g. `.zip` and `.html` in the case of FastQC), explicitly specify these files in the outputs of the previous rule and in the inputs of the subsequent rule. **Example** + ```python def get_samples(): samples = Path("/root").glob("*fastqc.zip") @@ -396,7 +401,7 @@ rule fastqc: shell("fastqc -o {params} --noextract -k 5 -t 8 -f fastq {input} 2>{log}") rule multiqc: - input: + input: aligned_sequences = join(WORKDIR, "plasmid_wells_aligned_sequences.csv") # Specify zip as the input for every sample from fastqc zip = expand( @@ -417,20 +422,21 @@ rule multiqc: ``` ## Snakemake Roadmap + ### Known Issues -- Task caching does not work, tasks always re-run when a new version of the workflow is run even if nothing specific has changed -- It is not possible to configure the amount of available ephemeral storage -- Remote registration is not supported -- Snakemake tasks are serialized using a faulty custom implementation which does not support things like caching. Should use actual generated python code instead -- JIT workflow image should run snakemake extraction as a smoketest before being registered as a workflow -- Workflows with no parameters break the workflow params page on console UI -- Cannot set parameter defaults -- Parameter keys are unusued but are required in the metadata -- Log file tailing does not work +* Task caching does not work, tasks always re-run when a new version of the workflow is run even if nothing specific has changed +* It is not possible to configure the amount of available ephemeral storage +* Remote registration is not supported +* Snakemake tasks are serialized using a faulty custom implementation which does not support things like caching. Should use actual generated python code instead +* JIT workflow image should run snakemake extraction as a smoketest before being registered as a workflow +* Workflows with no parameters break the workflow params page on console UI +* Cannot set parameter defaults +* Parameter keys are unusued but are required in the metadata +* Log file tailing does not work ### Future Work -- Warn when the Snakefile reads files not on the docker image outside of any rules -- FUSE -- File/directory APIs +* Warn when the Snakefile reads files not on the docker image outside of any rules +* FUSE +* File/directory APIs diff --git a/latch/types/metadata.py b/latch/types/metadata.py index ca974a3d..28c52d51 100644 --- a/latch/types/metadata.py +++ b/latch/types/metadata.py @@ -3,7 +3,7 @@ from enum import Enum from pathlib import Path from textwrap import indent -from typing import Dict, List, Optional, Tuple, Type, Union +from typing import Dict, Generic, List, Optional, Tuple, Type, TypeVar, Union import yaml @@ -335,14 +335,23 @@ def dict(self): @dataclass -class SnakemakeFileParameter(LatchParameter): - type: Optional[Union[Type[LatchFile], Type[LatchDir]]] = None +class SnakemakeParameter(LatchParameter): + type: Optional[ + Union[ + Type[LatchFile], + Type[LatchDir], + Type[str], + Type[Enum], + ] + ] = None """ The python type of the parameter. """ path: Optional[Path] = None """ The path where the file passed to this parameter will be copied. + + Only relevant if self.type is `LatchFile` or `LatchDir`. """ @@ -413,7 +422,7 @@ def wf(read1: LatchFile): no_standard_bulk_execution: bool = False """ Disable the standard CSV-based bulk execution. Intended for workflows that - support an aleternative way of processing bulk data e.g. using a samplesheet + support an alternative way of processing bulk data e.g. using a samplesheet parameter """ _non_standard: Dict[str, object] = field(default_factory=dict) @@ -452,6 +461,7 @@ def _parameter_str(t: Tuple[str, LatchParameter]): class SnakemakeMetadata(LatchMetadata): output_dir: Optional[LatchDir] = None name: Optional[str] = None + parameters: Dict[str, SnakemakeParameter] = field(default_factory=dict) def __post_init__(self): if self.name is None: diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 1a33e3cb..f90a2ed7 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -237,7 +237,7 @@ def infer_commands(pkg_root: Path) -> List[DockerCmdBlock]: try: with (pkg_root / "pyproject.toml").open("r") as f: for line in f: - if not line.startswith("[build-syste]"): + if not line.startswith("[build-system]"): continue has_buildable_pyproject = True diff --git a/latch_cli/services/init/example_snakemake/Snakefile b/latch_cli/services/init/example_snakemake/Snakefile index 8404f5b0..45646d9e 100644 --- a/latch_cli/services/init/example_snakemake/Snakefile +++ b/latch_cli/services/init/example_snakemake/Snakefile @@ -1,4 +1,4 @@ -from latch.types.metadata import SnakemakeMetadata, SnakemakeFileParameter +from latch.types.metadata import SnakemakeMetadata, SnakemakeParameter from latch.types.directory import LatchDir from latch.types.metadata import LatchAuthor, LatchMetadata, LatchParameter @@ -8,7 +8,7 @@ SAMPLES = ["A", "B"] rule all: input: - "plots/quals.svg" + "plots/quals.svg", rule bwa_map: @@ -16,22 +16,22 @@ rule bwa_map: "genome/genome.fa", "data/samples/{sample}.fastq", "genome/genome.fa.amb", - "genome/genome.fa.ann", - "genome/genome.fa.bwt", - "genome/genome.fa.fai", - "genome/genome.fa.pac", - "genome/genome.fa.sa" + "genome/genome.fa.ann", + "genome/genome.fa.bwt", + "genome/genome.fa.fai", + "genome/genome.fa.pac", + "genome/genome.fa.sa", output: - "mapped_reads/{sample}.bam" + "mapped_reads/{sample}.bam", shell: "bwa mem genome/genome.fa data/samples/{wildcards.sample}.fastq | samtools view -Sb - > {output}" rule samtools_sort: input: - "mapped_reads/{sample}.bam" + "mapped_reads/{sample}.bam", output: - "sorted_reads/{sample}.bam" + "sorted_reads/{sample}.bam", shell: "samtools sort -T sorted_reads/{wildcards.sample} " "-O bam {input} > {output}" @@ -39,9 +39,9 @@ rule samtools_sort: rule samtools_index: input: - "sorted_reads/{sample}.bam" + "sorted_reads/{sample}.bam", output: - "sorted_reads/{sample}.bam.bai" + "sorted_reads/{sample}.bam.bai", shell: "samtools index {input}" @@ -50,9 +50,9 @@ rule bcftools_call: input: fa="genome/genome.fa", bam=expand("sorted_reads/{sample}.bam", sample=SAMPLES), - bai=expand("sorted_reads/{sample}.bam.bai", sample=SAMPLES) + bai=expand("sorted_reads/{sample}.bam.bai", sample=SAMPLES), output: - "calls/all.vcf" + "calls/all.vcf", shell: "bcftools mpileup -f {input.fa} {input.bam} | " "bcftools call -mv - > {output}" @@ -60,8 +60,8 @@ rule bcftools_call: rule plot_quals: input: - "calls/all.vcf" + "calls/all.vcf", output: - "plots/quals.svg" + "plots/quals.svg", script: "scripts/plot-quals.py" diff --git a/latch_cli/services/init/example_snakemake/latch_metadata.py b/latch_cli/services/init/example_snakemake/latch_metadata.py index 386d71d9..30ec781b 100644 --- a/latch_cli/services/init/example_snakemake/latch_metadata.py +++ b/latch_cli/services/init/example_snakemake/latch_metadata.py @@ -1,7 +1,7 @@ from pathlib import Path from latch.types import LatchDir -from latch.types.metadata import LatchAuthor, SnakemakeFileParameter, SnakemakeMetadata +from latch.types.metadata import LatchAuthor, SnakemakeMetadata, SnakemakeParameter SnakemakeMetadata( output_dir=LatchDir("latch:///sample_output"), @@ -10,13 +10,13 @@ name="Kenneth", ), parameters={ - "samples": SnakemakeFileParameter( + "samples": SnakemakeParameter( display_name="Sample Input Directory", description="A directory full of FastQ files", type=LatchDir, path=Path("data/samples"), ), - "ref_genome": SnakemakeFileParameter( + "ref_genome": SnakemakeParameter( display_name="Indexed Reference Genome", description=( "A directory with a reference Fasta file and the 6 index files produced" diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index 1b702f51..606777fe 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -4,7 +4,7 @@ import traceback from pathlib import Path from textwrap import dedent -from typing import List, Optional, Set, Union, get_args +from typing import Dict, List, Optional, Set, Union, get_args import click from flyteidl.admin.launch_plan_pb2 import LaunchPlan as _idl_admin_LaunchPlan @@ -46,7 +46,7 @@ def should_register_with_admin(entity: RegistrableEntity) -> bool: def get_snakemake_metadata_example(name: str) -> str: return dedent(f""" from pathlib import Path - from latch.types.metadata import SnakemakeMetadata, SnakemakeFileParameter + from latch.types.metadata import SnakemakeMetadata, SnakemakeParameter from latch.types.file import LatchFile from latch.types.metadata import LatchAuthor @@ -56,7 +56,7 @@ def get_snakemake_metadata_example(name: str) -> str: name="Anonymous", ), parameters={{ - "example": SnakemakeFileParameter( + "example": SnakemakeParameter( display_name="Example Parameter", type=LatchFile, path=Path("example.txt"), @@ -122,9 +122,7 @@ def extract_dag(self): targetrules=target_rules, ) - self.persistence = Persistence( - dag=dag, - ) + self._persistence = Persistence(dag=dag) dag.init() dag.update_checkpoint_dependencies() @@ -312,6 +310,7 @@ def generate_snakemake_entrypoint( pkg_root: Path, snakefile: Path, remote_output_url: Optional[str] = None, + non_blob_parameters: Optional[Dict[str, str]] = None, ): entrypoint_code_block = textwrap.dedent(r""" import os @@ -358,9 +357,12 @@ def file_name_and_size(x: Path): return f"{si_unit(s.st_size):>7}B {x.name}" """).lstrip() + entrypoint_code_block += "\n\n".join( task.get_fn_code( - snakefile_path_in_container(snakefile, pkg_root), remote_output_url + snakefile_path_in_container(snakefile, pkg_root), + remote_output_url, + non_blob_parameters, ) for task in wf.snakemake_tasks ) @@ -423,6 +425,8 @@ def generate_jit_register_code( from latch.types.directory import LatchDir from latch.types.file import LatchFile + from latch_metadata import * + sys.stdout.reconfigure(line_buffering=True) sys.stderr.reconfigure(line_buffering=True) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index e1ca4704..833cc32e 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1,9 +1,11 @@ import importlib import json +import sys import textwrap import typing from collections.abc import Generator, Iterable from dataclasses import dataclass +from enum import Enum from pathlib import Path from typing import Any, Dict, List, Optional, Tuple, Type, TypeVar, Union from urllib.parse import urlparse @@ -82,7 +84,7 @@ def reindent(x: str, level: int) -> str: class JobOutputInfo: jobid: str output_param_name: str - type_: Union[LatchFile, LatchDir] + type_: Union[Type[LatchFile], Type[LatchDir]] def task_fn_placeholder(): ... @@ -116,22 +118,20 @@ class RemoteFile: def snakemake_dag_to_interface( dag: DAG, wf_name: str, docstring: Optional[Docstring] = None ) -> Tuple[Interface, LiteralMap, List[RemoteFile]]: - outputs: Dict[str, LatchFile] = {} + outputs: Dict[str, Union[Type[LatchFile], Type[LatchDir]]] = {} for target in dag.targetjobs: for desired in target.input: param = variable_name_for_value(desired, target.input) jobs: List[snakemake.jobs.Job] = dag.file2jobs(desired) - producer_out: snakemake.io._IOFile = next( - x for x in jobs[0].output if x == x - ) + producer_out: snakemake.io._IOFile = next(x for x in jobs[0].output) if producer_out.is_directory: outputs[param] = LatchDir else: outputs[param] = LatchFile literals: Dict[str, Literal] = {} - inputs: Dict[str, Tuple[LatchFile, None]] = {} + inputs: Dict[str, Tuple[Type[LatchFile], None]] = {} return_files: List[RemoteFile] = [] for job in dag.jobs: dep_outputs = [] @@ -259,7 +259,6 @@ def __init__( assert metadata._snakemake_metadata is not None parameter_metadata = metadata._snakemake_metadata.parameters - metadata._snakemake_metadata.parameters = parameter_metadata display_name = metadata._snakemake_metadata.display_name name = metadata._snakemake_metadata.name @@ -267,7 +266,7 @@ def __init__( f"{display_name}\n\nSample Description\n\n" + str(metadata._snakemake_metadata) ) - native_interface = Interface( + python_interface = Interface( {k: v.type for k, v in parameter_metadata.items()}, {self.out_parameter_name: bool}, docstring=docstring, @@ -287,7 +286,7 @@ def __init__( name=name, workflow_metadata=workflow_metadata, workflow_metadata_defaults=workflow_metadata_defaults, - python_interface=native_interface, + python_interface=python_interface, ) def get_fn_interface( @@ -334,13 +333,19 @@ def get_fn_code( ): task_name = f"{self.name}_task" - code_block = "" - code_block += self.get_fn_interface(fn_name=task_name) + code_block = self.get_fn_interface(fn_name=task_name) + + code_block += reindent( + r""" + non_blob_parameters = {} + """, + 1, + ) for param, t in self.python_interface.inputs.items(): if t in (LatchFile, LatchDir): param_meta = self.parameter_metadata[param] - assert isinstance(param_meta, metadata.SnakemakeFileParameter) + assert isinstance(param_meta, metadata.SnakemakeParameter) code_block += reindent( rf""" @@ -372,6 +377,18 @@ def get_fn_code( {param}_dst_p ) + """, + 1, + ) + elif t is str or issubclass(t, Enum): + ending = "" + if issubclass(t, Enum): + ending = ".value" + + code_block += reindent( + rf""" + print(f"Saving parameter value {param} = {{{param}{ending}}}") + non_blob_parameters[{repr(param)}] = {param}{ending} """, 1, ) @@ -400,7 +417,7 @@ def get_fn_code( wf = extract_snakemake_workflow(pkg_root, snakefile, version) wf_name = wf.name - generate_snakemake_entrypoint(wf, pkg_root, snakefile, {repr(remote_output_url)}) + generate_snakemake_entrypoint(wf, pkg_root, snakefile, {repr(remote_output_url)}, non_blob_parameters) entrypoint_remote = f"latch:///.snakemake_latch/workflows/{{wf_name}}/entrypoint.py" lp.upload("latch_entrypoint.py", entrypoint_remote) @@ -595,14 +612,15 @@ def __init__( assert name is not None - native_interface, literal_map, return_files = snakemake_dag_to_interface( + python_interface, literal_map, return_files = snakemake_dag_to_interface( dag, name, None ) + self.literal_map = literal_map self.return_files = return_files self._input_parameters = None self._dag = dag - self.snakemake_tasks = [] + self.snakemake_tasks: List[SnakemakeJobTask] = [] workflow_metadata = WorkflowMetadata( on_failure=WorkflowFailurePolicy.FAIL_IMMEDIATELY @@ -612,7 +630,7 @@ def __init__( name=name, workflow_metadata=workflow_metadata, workflow_metadata_defaults=workflow_metadata_defaults, - python_interface=native_interface, + python_interface=python_interface, ) def compile(self, **kwargs): @@ -641,7 +659,7 @@ def compile(self, **kwargs): target_file_for_output_param: Dict[str, str] = {} target_file_for_input_param: Dict[str, str] = {} - python_outputs: Dict[str, Union[LatchFile, LatchDir]] = {} + python_outputs: Dict[str, Union[Type[LatchFile], Type[LatchDir]]] = {} for x in job.output: assert isinstance(x, SnakemakeInputVal) @@ -669,7 +687,7 @@ def compile(self, **kwargs): type_=LatchDir if o.is_directory else LatchFile, ) - python_inputs: Dict[str, Union[LatchFile, LatchDir]] = {} + python_inputs: Dict[str, Union[Type[LatchFile], Type[LatchDir]]] = {} promise_map: Dict[str, JobOutputInfo] = {} for x in job.input: param = variable_name_for_value(x, job.input) @@ -1122,10 +1140,12 @@ def get_fn_return_stmt(self, remote_output_url: Optional[str] = None): ) def get_fn_code( - self, snakefile_path_in_container: str, remote_output_url: Optional[str] = None + self, + snakefile_path_in_container: str, + remote_output_url: Optional[str] = None, + non_blob_parameters: Optional[Dict[str, str]] = None, ): - code_block = "" - code_block += self.get_fn_interface() + code_block = self.get_fn_interface() for param, t in self._python_inputs.items(): if not issubclass(t, (LatchFile, LatchDir)): @@ -1160,6 +1180,13 @@ def get_fn_code( need_conda = any(x.conda_env is not None for x in jobs) + config_args = [] + if non_blob_parameters is not None and len(non_blob_parameters) > 0: + config_args = ["--config"] + for k, v in non_blob_parameters.items(): + self.job.rule.workflow.globals["config"][k] = v + config_args.append(f"{k}={v}") + snakemake_args = [ "-m", "latch_cli.snakemake.single_task_snakemake", @@ -1174,7 +1201,7 @@ def get_fn_code( str(self.job.jobid), "--cores", str(self.job.threads), - # "--print-compilation", + *config_args, ] if not self.job.is_group(): snakemake_args.append("--force-use-threads") From a4b650d063a7e2d904c3a2997492b22bf45bef0c Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Fri, 29 Sep 2023 10:21:11 -0700 Subject: [PATCH 272/356] dont run tests twice on prs Signed-off-by: Ayush Kamat --- .github/workflows/test.yaml | 39 +++++-------------------------------- 1 file changed, 5 insertions(+), 34 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 049f1ffe..1d65c7ae 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -1,14 +1,13 @@ name: Test -on: [push, pull_request_target] - +on: push jobs: macos: - name: Test MacOs + name: Test strategy: fail-fast: false matrix: python: ["3.8", "3.9", "3.10", "3.11"] - platform: ["macos-10.15"] + platform: ["macos-12", "ubuntu-22.04"] runs-on: ${{ matrix.platform }} steps: - name: Checkout @@ -19,40 +18,12 @@ jobs: python-version: ${{ matrix.python }} - name: Install dev run: | - python3 -m pip install -r dev-requirements.txt + pip install -r dev-requirements.txt - name: Install latch run: | - python3 -m pip install -e . + pip install . - name: Test env: TEST_TOKEN: ${{ secrets.TEST_TOKEN }} run: | - eval $(docker-machine env default) - cd tests; python3 -m pytest -s . - linux: - name: Test Linux - strategy: - fail-fast: false - matrix: - python: ["3.8", "3.9", "3.10", "3.11"] - platform: ["ubuntu-18.04"] - runs-on: ${{ matrix.platform }} - steps: - - name: Checkout - uses: actions/checkout@v2 - - name: Setup Python - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python }} - - name: Install dev - run: | - python3 -m pip install -r dev-requirements.txt - - name: Install latch - run: | - python3 -m pip install -e . - - name: Test - env: - TEST_TOKEN: ${{ secrets.TEST_TOKEN }} - run: | - eval $(docker-machine env default) cd tests; python3 -m pytest -s . From d5f012a0884cd154b7b4f50950d29f0ffd016c73 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Fri, 29 Sep 2023 10:32:32 -0700 Subject: [PATCH 273/356] make pytest work Signed-off-by: Ayush Kamat --- .gitignore | 1 - pyproject.toml | 3 +++ tests/{test.py => test_ls.py} | 0 3 files changed, 3 insertions(+), 1 deletion(-) rename tests/{test.py => test_ls.py} (100%) diff --git a/.gitignore b/.gitignore index 1fae6583..4be4e4c5 100644 --- a/.gitignore +++ b/.gitignore @@ -18,5 +18,4 @@ docs/build .vscode scratch.py /scratch -test_* .latch_report.tar.gz diff --git a/pyproject.toml b/pyproject.toml index 0cab99a5..76a342e0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,3 +37,6 @@ extend-ignore = [ "UP006", "UP035", ] + +[tool.pytest.ini_options] +testpaths = ["tests"] diff --git a/tests/test.py b/tests/test_ls.py similarity index 100% rename from tests/test.py rename to tests/test_ls.py From 9284e1047d197029afc4881d1ba8e83f34d796b6 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Fri, 29 Sep 2023 10:33:00 -0700 Subject: [PATCH 274/356] better pytest call in ci Signed-off-by: Ayush Kamat --- .github/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 1d65c7ae..11afb3e2 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -26,4 +26,4 @@ jobs: env: TEST_TOKEN: ${{ secrets.TEST_TOKEN }} run: | - cd tests; python3 -m pytest -s . + pytest -s From 4285af8a8df4dddc8b3158265c931d8b457e5e91 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Fri, 29 Sep 2023 10:35:01 -0700 Subject: [PATCH 275/356] try rel import Signed-off-by: Ayush Kamat --- tests/__init__.py | 0 tests/test_ls.py | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 tests/__init__.py diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_ls.py b/tests/test_ls.py index e4eacf78..6defd6f7 100644 --- a/tests/test_ls.py +++ b/tests/test_ls.py @@ -1,6 +1,6 @@ import subprocess -from tests.fixtures import test_account_jwt +from .fixtures import test_account_jwt def test_ls(test_account_jwt): From a61e72768708b2cad0c7cd8281982e1340827e40 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Fri, 29 Sep 2023 10:55:00 -0700 Subject: [PATCH 276/356] signal from sdk that the create-execution call is coming from sm Signed-off-by: Ayush Kamat --- latch_cli/snakemake/workflow.py | 1 + 1 file changed, 1 insertion(+) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index e1ca4704..b6e9ef63 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -573,6 +573,7 @@ class _WorkflowInfoNode(TypedDict): _interface_request = { "workflow_id": wf_id, "params": params, + "snakemake_jit": True, } response = requests.post(urljoin(config.nucleus_url, "/api/create-execution"), headers=headers, json=_interface_request) From 6d5ff1cdcdec47de00f2f09e6e81a618d87ded34 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Fri, 29 Sep 2023 11:48:36 -0700 Subject: [PATCH 277/356] strip useless declaration --- latch_cli/snakemake/workflow.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index ded756eb..0eb98169 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1221,6 +1221,8 @@ def get_fn_code( log_files = self.job.log if self.job.log is not None else [] + print(f"\n\nSnakemake data to be serialized:\n{snakemake_data}") + code_block += reindent( rf""" lp = LatchPersistence() From 772445ee6184698b2dd4009655f5c908291ef6ed Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Fri, 29 Sep 2023 11:52:18 -0700 Subject: [PATCH 278/356] support temp + report flags --- latch_cli/snakemake/single_task_snakemake.py | 24 +++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index be4e6b7b..e347888d 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -106,17 +106,26 @@ def render_annotated_str(x) -> str: flags = dict(x["flags"]) res = repr(value) - if flags.get("directory", False): + + if len(flags) > 1: + raise RuntimeError(f"can only have one flag for {res} but found: {repr(flags)}") + + if "directory" in flags: res = f"directory({res})" - del flags["directory"] - # TODO (kenny) ~ handle temporary values - if "temp" in flags: + elif "report" in flags: + report_vals = flags.get("report", False) + res = ( + f"report({res}, caption={report_vals['caption']}," + f" category={report_vals['category']})" + ) + + elif "temp" in flags: + # A temporary modifier is no different from a normal file as all files + # are deleted on Latch after a job completes. + # https://snakemake.readthedocs.io/en/stable/snakefiles/rules.html#protected-and-temporary-files del flags["temp"] - if len(flags) != 0: - raise RuntimeError(f"found unsupported flags: {repr(flags)}") - return res @@ -184,7 +193,6 @@ def skipping_block_content(self, token): Params.block_content = skipping_block_content Benchmark.block_content = skipping_block_content Log.block_content = skipping_block_content -# todo(kenny): enforce rule order instead of ignoring it Ruleorder.block_content = lambda self, token: None From 82e4292b188043764e7a70fcbe8d648e27928892 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Fri, 29 Sep 2023 12:25:29 -0700 Subject: [PATCH 279/356] store fields for report --- latch_cli/snakemake/workflow.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 0eb98169..22958673 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -392,7 +392,6 @@ def get_fn_code( code_block += reindent( rf""" image_name = "{image_name}" - image_base_name = image_name.split(":")[0] account_id = "{account_id}" snakefile = Path("{snakefile_path}") @@ -409,6 +408,8 @@ def get_fn_code( exec_id_hash.update(os.environ["FLYTE_INTERNAL_EXECUTION_ID"].encode("utf-8")) version = exec_id_hash.hexdigest()[:16] + import time + time.sleep(1000000) wf = extract_snakemake_workflow(pkg_root, snakefile, version) wf_name = wf.name generate_snakemake_entrypoint(wf, pkg_root, snakefile, {repr(remote_output_url)}) From c20208d0dcc3e5633414d9618afd22831e3055da Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Fri, 29 Sep 2023 13:41:45 -0700 Subject: [PATCH 280/356] strip time --- latch_cli/snakemake/workflow.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 22958673..9d57e154 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -408,8 +408,6 @@ def get_fn_code( exec_id_hash.update(os.environ["FLYTE_INTERNAL_EXECUTION_ID"].encode("utf-8")) version = exec_id_hash.hexdigest()[:16] - import time - time.sleep(1000000) wf = extract_snakemake_workflow(pkg_root, snakefile, version) wf_name = wf.name generate_snakemake_entrypoint(wf, pkg_root, snakefile, {repr(remote_output_url)}) @@ -865,7 +863,15 @@ def annotated_str_to_json( if not isinstance(x, (snakemake.io.AnnotatedString, snakemake.io._IOFile)): return x - return {"value": str(x), "flags": dict(x.flags.items())} + flags = dict(x.flags.items()) + if "report" in flags: + report = flags["report"] + flags["report"] = { + "caption": report.caption.get_filename(), + "category": report.category, + } + + return {"value": str(x), "flags": flags} IONamedListItem = Union[MaybeAnnotatedStrJson, List[MaybeAnnotatedStrJson]] @@ -1209,7 +1215,7 @@ def get_fn_code( snakemake_data["rules"][job.rule.name] = { "inputs": named_list_to_json(job.input), "outputs": named_list_to_json(job.output), - "params": named_list_to_json(job.params), + "params": json.dumps(job.params), "benchmark": job.benchmark, "log": job.log, "shellcmd": job.shellcmd, From 90e18a1e96089f4443c439b394a64d1af21689c9 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Fri, 29 Sep 2023 13:56:26 -0700 Subject: [PATCH 281/356] print params correctly --- latch_cli/snakemake/single_task_snakemake.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index e347888d..17f5fc66 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -56,7 +56,7 @@ def eprint_named_list(xs): eprint_named_list(rule_data["outputs"]) eprint(" Params:") - eprint_named_list(rule_data["params"]) + e(rule_data["params"]) eprint(" Benchmark:") eprint(f" {rule_data['benchmark']}") From 7e36682bd1a99808b44a4f20113bcdf32befebb4 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 29 Sep 2023 14:39:49 -0700 Subject: [PATCH 282/356] add sync draft Signed-off-by: maximsmol --- latch_cli/main.py | 18 +++ latch_cli/services/cp/upload.py | 37 +++-- latch_cli/services/sync.py | 264 ++++++++++++++++++++++++++++++++ 3 files changed, 303 insertions(+), 16 deletions(-) create mode 100644 latch_cli/services/sync.py diff --git a/latch_cli/main.py b/latch_cli/main.py index 5fdcdeaa..ed1ec5ce 100644 --- a/latch_cli/main.py +++ b/latch_cli/main.py @@ -684,3 +684,21 @@ def test_data_ls(): click.secho("Listing your managed objects by full S3 path.\n", fg="green") for o in objects: print(f"\ts3://latch-public/{o}") + + +@main.command() +@click.argument("srcs", nargs=-1) +@click.argument("dst", nargs=1) +@click.option( + "--delete", + help="Delete extraneous files from destination.", + is_flag=True, + default=False, +) +def sync(srcs: List[str], dst: str, delete: bool): + """ + Update the contents of a remote directory with local data or vice versa. + """ + from latch_cli.services.sync import sync + + sync(srcs, dst, delete=delete) diff --git a/latch_cli/services/cp/upload.py b/latch_cli/services/cp/upload.py index a642660d..0bdaf16f 100644 --- a/latch_cli/services/cp/upload.py +++ b/latch_cli/services/cp/upload.py @@ -380,8 +380,8 @@ def upload_file_chunk( url: str, part_index: int, part_size: int, - progress_bars: ProgressBars, - pbar_index: Optional[int], + progress_bars: Optional[ProgressBars] = None, + pbar_index: Optional[int] = None, parts_by_source: Optional["PartsBySrcType"] = None, upload_id: Optional[str] = None, dest: Optional[str] = None, @@ -405,20 +405,25 @@ def upload_file_chunk( if parts_by_source is not None: parts_by_source[src].append(ret) - progress_bars.update(pbar_index, len(data)) - pending_parts = progress_bars.dec_usage(str(src)) - - if pending_parts == 0: - progress_bars.return_task_bar(pbar_index) - progress_bars.update_total_progress(1) - progress_bars.write(f"Copied {src}") - - if dest is not None and parts_by_source is not None and upload_id is not None: - end_upload( - dest=dest, - upload_id=upload_id, - parts=list(parts_by_source[src]), - ) + if progress_bars is not None: + progress_bars.update(pbar_index, len(data)) + pending_parts = progress_bars.dec_usage(str(src)) + + if pending_parts == 0: + progress_bars.return_task_bar(pbar_index) + progress_bars.update_total_progress(1) + progress_bars.write(f"Copied {src}") + + if ( + dest is not None + and parts_by_source is not None + and upload_id is not None + ): + end_upload( + dest=dest, + upload_id=upload_id, + parts=list(parts_by_source[src]), + ) return ret diff --git a/latch_cli/services/sync.py b/latch_cli/services/sync.py new file mode 100644 index 00000000..b827ace0 --- /dev/null +++ b/latch_cli/services/sync.py @@ -0,0 +1,264 @@ +import os +import stat +import sys +from datetime import datetime +from pathlib import Path +from typing import Dict, List, Optional, Tuple + +import click +import gql +from gql.transport.exceptions import TransportQueryError +from latch_sdk_gql.execute import execute + +import latch_cli.services.cp.upload as upl + + +def upload_file(src: Path, dest: str): + start = upl.start_upload(src, dest) + if start is None: + return + + parts: List[upl.CompletedPart] = [] + for idx, url in enumerate(start.urls): + parts.append( + upl.upload_file_chunk( + src, + url, + idx, + start.part_size, + ) + ) + + upl.end_upload(dest, start.upload_id, parts) + + +def check_src(p: Path, *, indent: str = "") -> Optional[Tuple[Path, os.stat_result]]: + try: + p_stat = os.stat(p) + except FileNotFoundError: + click.echo( + indent + + click.style(p, bold=True, fg="red") + + click.style(": no such file or directory", fg="red") + ) + return + + if not stat.S_ISREG(p_stat.st_mode) and not stat.S_ISDIR(p_stat.st_mode): + click.echo( + indent + + click.style(p, bold=True, fg="red") + + click.style(": not a regular file", fg="red") + ) + return + + return (p, p_stat) + + +def sync_rec( + srcs: Dict[str, Tuple[Path, os.stat_result]], + dest: str, + *, + delete: bool, + indent: str = "", +): + name_filter = list(srcs.keys()) + if delete: + name_filter = [] + + try: + resolve_data = execute( + gql.gql(""" + query LatchCLISync($argPath: String!, $nameFilter: [String!]) { + ldataResolvePathData(argPath: $argPath) { + finalLinkTarget { + type + childLdataTreeEdges( + filter: { + child: { + removed: {equalTo: false}, + pending: {equalTo: false}, + copiedFrom: {isNull: true}, + name: {in: $nameFilter} + } + } + ) { + nodes { + child { + name + finalLinkTarget { + type + ldataObjectMeta { + modifyTime + } + } + } + } + } + } + } + } + """), + {"argPath": dest, "nameFilter": name_filter}, + )["ldataResolvePathData"] + + dest_data = None + if resolve_data is not None: + dest_data = resolve_data["finalLinkTarget"] + except TransportQueryError as e: + if e.errors is None or len(e.errors) == 0: + raise + + msg: str = e.errors[0]["message"] + + raise + + if ( + (len(srcs) > 1 or stat.S_ISDIR(list(srcs.values())[0][1].st_mode)) + and dest_data is not None + and dest_data["type"] != "DIR" + ): + click.secho(f"`{dest}` is not a directory", fg="red") + click.secho( + "\nOnly a single file can be synced with a file", fg="red", bold=True + ) + sys.exit(1) + + if dest_data is not None and dest_data["type"] != "DIR": + # todo(maximsmol): implement + click.secho( + "Syncing single files is currently not supported", bold=True, fg="red" + ) + sys.exit(1) + + dest_children_by_name = ( + { + x["name"]: x["finalLinkTarget"] + for x in (raw["child"] for raw in dest_data["childLdataTreeEdges"]["nodes"]) + } + if dest_data is not None + else {} + ) + + for name, (p, p_stat) in srcs.items(): + is_dir = stat.S_ISDIR(p_stat.st_mode) + + child = dest_children_by_name.get(name) + child_dest = f"{dest}/{name}" + + skip = False + verb = "Uploading" + reason = "new" + if child is not None: + if child["type"] not in {"DIR", "OBJ"}: + # todo(maximsmol): skip? pre-check? + click.secho( + click.style(child_dest, bold=True, fg="red") + + click.style(" is not a file or directory", fg="red"), + ) + sys.exit(1) + + if child["type"] == "DIR" and not is_dir: + # todo(maximsmol): skip? pre-check? + click.secho( + click.style(child_dest, bold=True, fg="red") + + click.style(" is in the way of a file", fg="red"), + ) + sys.exit(1) + + if child["type"] == "OBJ" and is_dir: + # todo(maximsmol): skip? pre-check? + click.secho( + click.style(child_dest, bold=True, fg="red") + + click.style(" is in the way of a directory", fg="red"), + ) + sys.exit(1) + + if child["type"] == "OBJ": + meta = child["ldataObjectMeta"] + remote_mtime = datetime.fromisoformat(meta["modifyTime"]) + + local_mtime = datetime.fromtimestamp(p_stat.st_mtime).astimezone() + if remote_mtime == local_mtime: + verb = "Skipping" + reason = "unmodified" + skip = True + elif remote_mtime > local_mtime: + verb = "Skipping" + reason = "older" + skip = True + else: + verb = "Uploading" + reason = "updated" + else: + reason = "existing" + + if verb == "Uploading" and is_dir: + verb = "Syncing" + + fg = "bright_blue" + dim = None + if verb == "Skipping": + fg = None + dim = True + + click.echo( + click.style( + indent + verb + " " + click.style(reason, underline=True) + ": ", + fg=fg, + dim=dim, + ) + + click.style( + str(p) + + ("" if not is_dir else "/") + + ("" if skip else click.style(" -> ", dim=True) + child_dest), + dim=dim, + ) + ) + if skip: + continue + + if is_dir: + sub_srcs: Dict[str, Tuple[Path, os.stat_result]] = {} + for x in p.iterdir(): + res = check_src(x, indent=indent + " ") + if res is None: + # todo(maximsmol): pre-check or confirm? + continue + + sub_srcs[x.name] = res + sync_rec(sub_srcs, child_dest, delete=delete, indent=indent + " ") + continue + + # todo(maximsmol): upload in parallel? + upload_file(p, child_dest) + + +def sync(srcs_raw: List[str], dest: str, *, delete: bool): + srcs: Dict[str, Tuple[Path, os.stat_result]] = {} + have_errors = False + for x in srcs_raw: + p = Path(x) + res = check_src(p) + if res is None: + have_errors = True + continue + + srcs[p.name] = res + + if len(srcs) == 0: + click.secho( + "\nAll source paths were skipped due to errors", fg="red", bold=True + ) + sys.exit(1) + + if have_errors: + # todo(maximsmol): do we want to precheck recursively? + click.secho( + "\nSome source paths will be skipped due to errors", fg="red", bold=True + ) + + if not click.confirm(click.style(f"Confirm to proceed", fg="red")): + sys.exit(1) + click.echo() + + sync_rec(srcs, dest, delete=delete) From 6f440e3f78c5aeb3acec13cde6bfbfc80809f01a Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 29 Sep 2023 14:58:05 -0700 Subject: [PATCH 283/356] working --delete Signed-off-by: maximsmol --- latch_cli/services/sync.py | 107 ++++++++++++++++++++++++------------- 1 file changed, 70 insertions(+), 37 deletions(-) diff --git a/latch_cli/services/sync.py b/latch_cli/services/sync.py index b827ace0..11e5b9c1 100644 --- a/latch_cli/services/sync.py +++ b/latch_cli/services/sync.py @@ -8,7 +8,7 @@ import click import gql from gql.transport.exceptions import TransportQueryError -from latch_sdk_gql.execute import execute +from latch_sdk_gql.execute import JsonValue, execute import latch_cli.services.cp.upload as upl @@ -59,37 +59,36 @@ def sync_rec( dest: str, *, delete: bool, - indent: str = "", + level: int = 0, ): - name_filter = list(srcs.keys()) - if delete: - name_filter = [] + # rsync never deletes from the top level destination + delete_effective = delete and level > 0 + indent = " " * level try: - resolve_data = execute( - gql.gql(""" - query LatchCLISync($argPath: String!, $nameFilter: [String!]) { - ldataResolvePathData(argPath: $argPath) { - finalLinkTarget { - type - childLdataTreeEdges( - filter: { - child: { - removed: {equalTo: false}, - pending: {equalTo: false}, - copiedFrom: {isNull: true}, - name: {in: $nameFilter} - } + query = """ + query LatchCLISync($argPath: String! ${name_filter_arg}) { + ldataResolvePathData(argPath: $argPath) { + finalLinkTarget { + type + childLdataTreeEdges( + filter: { + child: { + removed: {equalTo: false}, + pending: {equalTo: false}, + copiedFrom: {isNull: true} + ${name_filter} } - ) { - nodes { - child { - name - finalLinkTarget { - type - ldataObjectMeta { - modifyTime - } + } + ) { + nodes { + child { + id + name + finalLinkTarget { + type + ldataObjectMeta { + modifyTime } } } @@ -97,8 +96,21 @@ def sync_rec( } } } - """), - {"argPath": dest, "nameFilter": name_filter}, + } + """ + + args: JsonValue = {"argPath": dest, "nameFilter": []} + if not delete_effective: + query = query.replace("${name_filter_arg}", ", $nameFilter: [String!]") + query = query.replace("${name_filter}", ", name: {in: $nameFilter}") + args["nameFilter"] = list(srcs.keys()) + else: + query = query.replace("${name_filter_arg}", "") + query = query.replace("${name_filter}", "") + + resolve_data = execute( + gql.gql(query), + args, )["ldataResolvePathData"] dest_data = None @@ -132,7 +144,7 @@ def sync_rec( dest_children_by_name = ( { - x["name"]: x["finalLinkTarget"] + x["name"]: x for x in (raw["child"] for raw in dest_data["childLdataTreeEdges"]["nodes"]) } if dest_data is not None @@ -149,7 +161,8 @@ def sync_rec( verb = "Uploading" reason = "new" if child is not None: - if child["type"] not in {"DIR", "OBJ"}: + flt = child["finalLinkTarget"] + if flt["type"] not in {"DIR", "OBJ"}: # todo(maximsmol): skip? pre-check? click.secho( click.style(child_dest, bold=True, fg="red") @@ -157,7 +170,7 @@ def sync_rec( ) sys.exit(1) - if child["type"] == "DIR" and not is_dir: + if flt["type"] == "DIR" and not is_dir: # todo(maximsmol): skip? pre-check? click.secho( click.style(child_dest, bold=True, fg="red") @@ -165,7 +178,7 @@ def sync_rec( ) sys.exit(1) - if child["type"] == "OBJ" and is_dir: + if flt["type"] == "OBJ" and is_dir: # todo(maximsmol): skip? pre-check? click.secho( click.style(child_dest, bold=True, fg="red") @@ -173,8 +186,8 @@ def sync_rec( ) sys.exit(1) - if child["type"] == "OBJ": - meta = child["ldataObjectMeta"] + if flt["type"] == "OBJ": + meta = flt["ldataObjectMeta"] remote_mtime = datetime.fromisoformat(meta["modifyTime"]) local_mtime = datetime.fromtimestamp(p_stat.st_mtime).astimezone() @@ -226,12 +239,32 @@ def sync_rec( continue sub_srcs[x.name] = res - sync_rec(sub_srcs, child_dest, delete=delete, indent=indent + " ") + sync_rec(sub_srcs, child_dest, delete=delete, level=level + 1) continue # todo(maximsmol): upload in parallel? upload_file(p, child_dest) + if delete_effective: + for name, child in dest_children_by_name.items(): + child_dest = f"{dest}/{name}" + if name in srcs: + continue + + click.echo( + indent + click.style("Removing extraneous: ", fg="yellow") + child_dest + ) + execute( + gql.gql(""" + mutation LatchCLISyncRemove($argNodeId: BigInt!) { + ldataRmr(input: {argNodeId: $argNodeId}) { + clientMutationId + } + } + """), + {"argNodeId": child["id"]}, + ) + def sync(srcs_raw: List[str], dest: str, *, delete: bool): srcs: Dict[str, Tuple[Path, os.stat_result]] = {} From 58d26aea8d251da0d80b074aaffb7bbc83fbbbcc Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 29 Sep 2023 14:59:25 -0700 Subject: [PATCH 284/356] add todo Signed-off-by: maximsmol --- latch_cli/main.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/latch_cli/main.py b/latch_cli/main.py index ed1ec5ce..2a376333 100644 --- a/latch_cli/main.py +++ b/latch_cli/main.py @@ -701,4 +701,6 @@ def sync(srcs: List[str], dst: str, delete: bool): """ from latch_cli.services.sync import sync + # todo(maximsmol): remote -> local + # todo(maximsmol): remote -> remote sync(srcs, dst, delete=delete) From ca8c334e70a9cbd767d76fdad4bca991571fd200 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Fri, 29 Sep 2023 15:06:32 -0700 Subject: [PATCH 285/356] fixes --- latch_cli/snakemake/single_task_snakemake.py | 2 +- latch_cli/snakemake/workflow.py | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 17f5fc66..e347888d 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -56,7 +56,7 @@ def eprint_named_list(xs): eprint_named_list(rule_data["outputs"]) eprint(" Params:") - e(rule_data["params"]) + eprint_named_list(rule_data["params"]) eprint(" Benchmark:") eprint(f" {rule_data['benchmark']}") diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 9d57e154..9e0c2f61 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1215,7 +1215,10 @@ def get_fn_code( snakemake_data["rules"][job.rule.name] = { "inputs": named_list_to_json(job.input), "outputs": named_list_to_json(job.output), - "params": json.dumps(job.params), + "params": { + "keyword": {k: v for k, v in job.params.items()}, + "positional": [], + }, "benchmark": job.benchmark, "log": job.log, "shellcmd": job.shellcmd, @@ -1228,8 +1231,6 @@ def get_fn_code( log_files = self.job.log if self.job.log is not None else [] - print(f"\n\nSnakemake data to be serialized:\n{snakemake_data}") - code_block += reindent( rf""" lp = LatchPersistence() From 933a33e2ffa0515a70cdb4b14ed3d2e482f16d24 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 29 Sep 2023 15:09:13 -0700 Subject: [PATCH 286/356] improve errors Signed-off-by: maximsmol --- latch_cli/main.py | 18 +++++++++++-- latch_cli/services/sync.py | 52 +++++++++++++++++++------------------- 2 files changed, 42 insertions(+), 28 deletions(-) diff --git a/latch_cli/main.py b/latch_cli/main.py index 2a376333..ef92a906 100644 --- a/latch_cli/main.py +++ b/latch_cli/main.py @@ -695,7 +695,16 @@ def test_data_ls(): is_flag=True, default=False, ) -def sync(srcs: List[str], dst: str, delete: bool): +@click.option( + "--ignore-unsyncable", + help=( + "Synchronize even if some source paths are do not exist or refer to special" + " files." + ), + is_flag=True, + default=False, +) +def sync(srcs: List[str], dst: str, delete: bool, ignore_unsyncable: bool): """ Update the contents of a remote directory with local data or vice versa. """ @@ -703,4 +712,9 @@ def sync(srcs: List[str], dst: str, delete: bool): # todo(maximsmol): remote -> local # todo(maximsmol): remote -> remote - sync(srcs, dst, delete=delete) + sync( + srcs, + dst, + delete=delete, + ignore_unsyncable=ignore_unsyncable, + ) diff --git a/latch_cli/services/sync.py b/latch_cli/services/sync.py index 11e5b9c1..cf2feef1 100644 --- a/latch_cli/services/sync.py +++ b/latch_cli/services/sync.py @@ -36,19 +36,11 @@ def check_src(p: Path, *, indent: str = "") -> Optional[Tuple[Path, os.stat_resu try: p_stat = os.stat(p) except FileNotFoundError: - click.echo( - indent - + click.style(p, bold=True, fg="red") - + click.style(": no such file or directory", fg="red") - ) + click.secho(indent + f"`{p}`: no such file or directory", fg="red", bold=True) return if not stat.S_ISREG(p_stat.st_mode) and not stat.S_ISDIR(p_stat.st_mode): - click.echo( - indent - + click.style(p, bold=True, fg="red") - + click.style(": not a regular file", fg="red") - ) + click.secho(indent + f"`{p}`: not a regular file", fg="red", bold=True) return return (p, p_stat) @@ -129,10 +121,8 @@ def sync_rec( and dest_data is not None and dest_data["type"] != "DIR" ): - click.secho(f"`{dest}` is not a directory", fg="red") - click.secho( - "\nOnly a single file can be synced with a file", fg="red", bold=True - ) + click.secho(f"`{dest}` is not a directory", fg="red", bold=True) + click.secho("\nOnly a single file can be synced with a file", fg="red") sys.exit(1) if dest_data is not None and dest_data["type"] != "DIR": @@ -163,28 +153,28 @@ def sync_rec( if child is not None: flt = child["finalLinkTarget"] if flt["type"] not in {"DIR", "OBJ"}: - # todo(maximsmol): skip? pre-check? + # todo(maximsmol): confirm? pre-check? click.secho( click.style(child_dest, bold=True, fg="red") + click.style(" is not a file or directory", fg="red"), ) - sys.exit(1) + continue if flt["type"] == "DIR" and not is_dir: - # todo(maximsmol): skip? pre-check? + # todo(maximsmol): confirm? pre-check? click.secho( click.style(child_dest, bold=True, fg="red") + click.style(" is in the way of a file", fg="red"), ) - sys.exit(1) + continue if flt["type"] == "OBJ" and is_dir: - # todo(maximsmol): skip? pre-check? + # todo(maximsmol): confirm? pre-check? click.secho( click.style(child_dest, bold=True, fg="red") + click.style(" is in the way of a directory", fg="red"), ) - sys.exit(1) + continue if flt["type"] == "OBJ": meta = flt["ldataObjectMeta"] @@ -266,7 +256,13 @@ def sync_rec( ) -def sync(srcs_raw: List[str], dest: str, *, delete: bool): +def sync( + srcs_raw: List[str], + dest: str, + *, + delete: bool, + ignore_unsyncable: bool, +): srcs: Dict[str, Tuple[Path, os.stat_result]] = {} have_errors = False for x in srcs_raw: @@ -286,12 +282,16 @@ def sync(srcs_raw: List[str], dest: str, *, delete: bool): if have_errors: # todo(maximsmol): do we want to precheck recursively? - click.secho( - "\nSome source paths will be skipped due to errors", fg="red", bold=True - ) + click.secho("\nSome source paths will be skipped due to errors", fg="red") - if not click.confirm(click.style(f"Confirm to proceed", fg="red")): - sys.exit(1) + if not ignore_unsyncable: + if not click.confirm(click.style(f"Proceed?", fg="red")): + sys.exit(1) + else: + click.secho( + "Proceeding due to " + click.style("`--ignore-unsyncable`", bold=True), + fg="yellow", + ) click.echo() sync_rec(srcs, dest, delete=delete) From a34681a9158b397faef6f724152b7399347e0dab Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 29 Sep 2023 15:16:23 -0700 Subject: [PATCH 287/356] sync empty directories Signed-off-by: maximsmol --- latch_cli/services/sync.py | 69 +++++++++++++++++++++++++++----------- 1 file changed, 50 insertions(+), 19 deletions(-) diff --git a/latch_cli/services/sync.py b/latch_cli/services/sync.py index cf2feef1..5aa39cc4 100644 --- a/latch_cli/services/sync.py +++ b/latch_cli/services/sync.py @@ -116,6 +116,34 @@ def sync_rec( raise + if len(srcs) == 0: + if dest_data is not None: + if dest_data["type"] != "DIR": + click.secho( + indent + f"`{dest}` is in the way of a directory", + fg="red", + ) + return + + click.secho(indent + "Empty directory", dim=True) + return + + if not dest[-1] == "/": + dest += "/" + + click.secho(indent + "Creating empty directory", fg="bright_blue") + execute( + gql.gql(""" + mutation LatchCLISyncMkdir($argPath: String!) { + ldataMkdirp(input: {argPath: $argPath}) { + clientMutationId + } + } + """), + {"argPath": dest}, + ) + return + if ( (len(srcs) > 1 or stat.S_ISDIR(list(srcs.values())[0][1].st_mode)) and dest_data is not None @@ -152,27 +180,19 @@ def sync_rec( reason = "new" if child is not None: flt = child["finalLinkTarget"] - if flt["type"] not in {"DIR", "OBJ"}: - # todo(maximsmol): confirm? pre-check? - click.secho( - click.style(child_dest, bold=True, fg="red") - + click.style(" is not a file or directory", fg="red"), - ) - continue - if flt["type"] == "DIR" and not is_dir: # todo(maximsmol): confirm? pre-check? click.secho( - click.style(child_dest, bold=True, fg="red") - + click.style(" is in the way of a file", fg="red"), + indent + f"`{dest}` is in the way of a file", + fg="red", ) continue - if flt["type"] == "OBJ" and is_dir: + if flt["type"] != "DIR" and is_dir: # todo(maximsmol): confirm? pre-check? click.secho( - click.style(child_dest, bold=True, fg="red") - + click.style(" is in the way of a directory", fg="red"), + indent + f"`{dest}` is in the way of a directory", + fg="red", ) continue @@ -206,7 +226,18 @@ def sync_rec( click.echo( click.style( - indent + verb + " " + click.style(reason, underline=True) + ": ", + indent + verb + " ", + fg=fg, + dim=dim, + ) + + click.style( + reason, + underline=True, + fg=fg, + dim=dim, + ) + + click.style( + ": ", fg=fg, dim=dim, ) @@ -246,12 +277,12 @@ def sync_rec( ) execute( gql.gql(""" - mutation LatchCLISyncRemove($argNodeId: BigInt!) { - ldataRmr(input: {argNodeId: $argNodeId}) { - clientMutationId + mutation LatchCLISyncRemove($argNodeId: BigInt!) { + ldataRmr(input: {argNodeId: $argNodeId}) { + clientMutationId + } } - } - """), + """), {"argNodeId": child["id"]}, ) From 3243fc767df99614a0890bb37e29d1045d815279 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 29 Sep 2023 15:30:27 -0700 Subject: [PATCH 288/356] typo Signed-off-by: maximsmol --- latch_cli/main.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/latch_cli/main.py b/latch_cli/main.py index ef92a906..46671da7 100644 --- a/latch_cli/main.py +++ b/latch_cli/main.py @@ -698,8 +698,7 @@ def test_data_ls(): @click.option( "--ignore-unsyncable", help=( - "Synchronize even if some source paths are do not exist or refer to special" - " files." + "Synchronize even if some source paths do not exist or refer to special files." ), is_flag=True, default=False, From ac545ece1ac393a28e7ca45493cfc5201a18f2d3 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 29 Sep 2023 15:42:05 -0700 Subject: [PATCH 289/356] 2.33 Signed-off-by: maximsmol --- CHANGELOG.md | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9515c75f..ba24cc5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,12 @@ Types of changes # Latch SDK Changelog +## 2.33.0 - 2023-09-29 + +### Added + +* Add `latch sync` for synchronization from local to remote directories that only uploads modified content + ## 2.32.8 - 2023-09-07 ### Fixed diff --git a/setup.py b/setup.py index d09f1f05..3831f10e 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ setup( name="latch", - version="v2.32.8", + version="v2.33.0", author_email="kenny@latch.bio", description="The Latch SDK", packages=find_packages(), From dacdd84f2ea891ac537877f2df3824b94c6913bc Mon Sep 17 00:00:00 2001 From: Kenny Workman <31255434+kennyworkman@users.noreply.github.com> Date: Fri, 29 Sep 2023 15:43:27 -0700 Subject: [PATCH 290/356] use repr Co-authored-by: Max Smolin --- latch_cli/snakemake/single_task_snakemake.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index e347888d..acef3270 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -116,7 +116,7 @@ def render_annotated_str(x) -> str: elif "report" in flags: report_vals = flags.get("report", False) res = ( - f"report({res}, caption={report_vals['caption']}," + f"report({res}, caption={repr(report_vals['caption'])}," f" category={report_vals['category']})" ) From c0f5add30392307914cec262c6bcf29d9acc654b Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 29 Sep 2023 15:53:21 -0700 Subject: [PATCH 291/356] fix minor sync bugs Signed-off-by: maximsmol --- latch_cli/services/sync.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/latch_cli/services/sync.py b/latch_cli/services/sync.py index 5aa39cc4..012bf3c9 100644 --- a/latch_cli/services/sync.py +++ b/latch_cli/services/sync.py @@ -79,8 +79,14 @@ def sync_rec( name finalLinkTarget { type - ldataObjectMeta { - modifyTime + ldataNodeEvents( + condition: {type: INGRESS}, + orderBy: TIME_DESC, + first: 1 + ) { + nodes { + time + } } } } @@ -147,13 +153,13 @@ def sync_rec( if ( (len(srcs) > 1 or stat.S_ISDIR(list(srcs.values())[0][1].st_mode)) and dest_data is not None - and dest_data["type"] != "DIR" + and dest_data["type"] not in {"DIR", "ACCOUNT_ROOT"} ): click.secho(f"`{dest}` is not a directory", fg="red", bold=True) click.secho("\nOnly a single file can be synced with a file", fg="red") sys.exit(1) - if dest_data is not None and dest_data["type"] != "DIR": + if dest_data is not None and dest_data["type"] not in {"DIR", "ACCOUNT_ROOT"}: # todo(maximsmol): implement click.secho( "Syncing single files is currently not supported", bold=True, fg="red" @@ -197,8 +203,9 @@ def sync_rec( continue if flt["type"] == "OBJ": - meta = flt["ldataObjectMeta"] - remote_mtime = datetime.fromisoformat(meta["modifyTime"]) + remote_mtime = datetime.fromisoformat( + flt["ldataNodeEvents"]["nodes"][0]["time"] + ) local_mtime = datetime.fromtimestamp(p_stat.st_mtime).astimezone() if remote_mtime == local_mtime: From 9b1547e07cecd3ab600100293516b8f9e8f953e7 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Fri, 29 Sep 2023 15:57:02 -0700 Subject: [PATCH 292/356] fix sync on <3.11 Signed-off-by: maximsmol --- latch_cli/services/sync.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/latch_cli/services/sync.py b/latch_cli/services/sync.py index 012bf3c9..08281a94 100644 --- a/latch_cli/services/sync.py +++ b/latch_cli/services/sync.py @@ -6,6 +6,7 @@ from typing import Dict, List, Optional, Tuple import click +import dateutil.parser as dp import gql from gql.transport.exceptions import TransportQueryError from latch_sdk_gql.execute import JsonValue, execute @@ -203,9 +204,7 @@ def sync_rec( continue if flt["type"] == "OBJ": - remote_mtime = datetime.fromisoformat( - flt["ldataNodeEvents"]["nodes"][0]["time"] - ) + remote_mtime = dp.isoparse(flt["ldataNodeEvents"]["nodes"][0]["time"]) local_mtime = datetime.fromtimestamp(p_stat.st_mtime).astimezone() if remote_mtime == local_mtime: From 84228dfbc1d2ff0d7f707d6b96403aea5b12c35e Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Tue, 3 Oct 2023 10:23:22 -0700 Subject: [PATCH 293/356] better params Signed-off-by: Ayush Kamat --- docs/source/manual/snakemake.md | 12 ++++++------ latch/types/metadata.py | 17 +++++++++++++---- .../services/init/example_snakemake/Snakefile | 2 +- .../init/example_snakemake/latch_metadata.py | 6 +++--- latch_cli/snakemake/serialize.py | 6 +++--- latch_cli/snakemake/single_task_snakemake.py | 8 ++++++++ latch_cli/snakemake/workflow.py | 11 ++++------- 7 files changed, 38 insertions(+), 24 deletions(-) diff --git a/docs/source/manual/snakemake.md b/docs/source/manual/snakemake.md index 509569a6..950f0ef5 100644 --- a/docs/source/manual/snakemake.md +++ b/docs/source/manual/snakemake.md @@ -46,7 +46,7 @@ from pathlib import Path from latch.types.directory import LatchDir from latch.types.file import LatchFile -from latch.types.metadata import LatchAuthor, SnakemakeParameter, SnakemakeMetadata +from latch.types.metadata import LatchAuthor, SnakemakeFileParameter, SnakemakeMetadata SnakemakeMetadata( display_name="fgbio Best Practise FASTQ -> Consensus Pipeline", @@ -54,17 +54,17 @@ SnakemakeMetadata( name="Fulcrum Genomics", ), parameters={ - "r1_fastq": SnakemakeParameter( + "r1_fastq": SnakemakeFileParameter( display_name="Read 1 FastQ", type=LatchFile, path=Path("tests/r1.fq.gz"), ), - "r2_fastq": SnakemakeParameter( + "r2_fastq": SnakemakeFileParameter( display_name="Read 2 FastQ", type=LatchFile, path=Path("tests/r2.fq.gz"), ), - "genome": SnakemakeParameter( + "genome": SnakemakeFileParameter( display_name="Reference Genome", type=LatchDir, path=Path("tests/hs38DH"), @@ -225,7 +225,7 @@ If registration fails before metadata can be pulled, the CLI will generate an ex Since there is no explicit entrypoint ( `@workflow` ) function in a Snakemake workflow, parameters are instead specified in the metadata file. -Currently only `LatchFile` and `LatchDir` parameters are supported. Both directory and file inputs are specified using `SnakemakeParameter` and setting the `type` field as appropriate. +Currently only `LatchFile` and `LatchDir` parameters are supported. Both directory and file inputs are specified using `SnakemakeFileParameter` and setting the `type` field as appropriate. Parameters must include a `path` field which specifies where the data will be downloaded to. This usually matches some file location expected by a Snakemake rule. Frequently, instead of simple paths, a rule with use a `configfile` to dynamically find input paths. In this case the only requiremtn is that the path matches the config file included in the workflow Docker image. @@ -233,7 +233,7 @@ Example: ```py parameters = { - "example": SnakemakeParameter( + "example": SnakemakeFileParameter( display_name="Example Parameter", type=LatchFile, path=Path("example.txt"), diff --git a/latch/types/metadata.py b/latch/types/metadata.py index 28c52d51..eb294465 100644 --- a/latch/types/metadata.py +++ b/latch/types/metadata.py @@ -338,8 +338,6 @@ def dict(self): class SnakemakeParameter(LatchParameter): type: Optional[ Union[ - Type[LatchFile], - Type[LatchDir], Type[str], Type[Enum], ] @@ -347,11 +345,22 @@ class SnakemakeParameter(LatchParameter): """ The python type of the parameter. """ + + +@dataclass +class SnakemakeFileParameter(SnakemakeParameter): + type: Optional[ + Union[ + Type[LatchFile], + Type[LatchDir], + ] + ] = None + """ + The python type of the parameter. + """ path: Optional[Path] = None """ The path where the file passed to this parameter will be copied. - - Only relevant if self.type is `LatchFile` or `LatchDir`. """ diff --git a/latch_cli/services/init/example_snakemake/Snakefile b/latch_cli/services/init/example_snakemake/Snakefile index 45646d9e..5838a0fc 100644 --- a/latch_cli/services/init/example_snakemake/Snakefile +++ b/latch_cli/services/init/example_snakemake/Snakefile @@ -1,4 +1,4 @@ -from latch.types.metadata import SnakemakeMetadata, SnakemakeParameter +from latch.types.metadata import SnakemakeMetadata, SnakemakeFileParameter from latch.types.directory import LatchDir from latch.types.metadata import LatchAuthor, LatchMetadata, LatchParameter diff --git a/latch_cli/services/init/example_snakemake/latch_metadata.py b/latch_cli/services/init/example_snakemake/latch_metadata.py index 30ec781b..386d71d9 100644 --- a/latch_cli/services/init/example_snakemake/latch_metadata.py +++ b/latch_cli/services/init/example_snakemake/latch_metadata.py @@ -1,7 +1,7 @@ from pathlib import Path from latch.types import LatchDir -from latch.types.metadata import LatchAuthor, SnakemakeMetadata, SnakemakeParameter +from latch.types.metadata import LatchAuthor, SnakemakeFileParameter, SnakemakeMetadata SnakemakeMetadata( output_dir=LatchDir("latch:///sample_output"), @@ -10,13 +10,13 @@ name="Kenneth", ), parameters={ - "samples": SnakemakeParameter( + "samples": SnakemakeFileParameter( display_name="Sample Input Directory", description="A directory full of FastQ files", type=LatchDir, path=Path("data/samples"), ), - "ref_genome": SnakemakeParameter( + "ref_genome": SnakemakeFileParameter( display_name="Indexed Reference Genome", description=( "A directory with a reference Fasta file and the 6 index files produced" diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index a759a06b..11c850f0 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -46,7 +46,7 @@ def should_register_with_admin(entity: RegistrableEntity) -> bool: def get_snakemake_metadata_example(name: str) -> str: return dedent(f""" from pathlib import Path - from latch.types.metadata import SnakemakeMetadata, SnakemakeParameter + from latch.types.metadata import SnakemakeMetadata, SnakemakeFileParameter from latch.types.file import LatchFile from latch.types.metadata import LatchAuthor @@ -56,7 +56,7 @@ def get_snakemake_metadata_example(name: str) -> str: name="Anonymous", ), parameters={{ - "example": SnakemakeParameter( + "example": SnakemakeFileParameter( display_name="Example Parameter", type=LatchFile, path=Path("example.txt"), @@ -427,7 +427,7 @@ def generate_jit_register_code( from latch.types.directory import LatchDir from latch.types.file import LatchFile - from latch_metadata import * + import latch_metadata sys.stdout.reconfigure(line_buffering=True) sys.stderr.reconfigure(line_buffering=True) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index acef3270..2babf3f4 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -6,6 +6,7 @@ from typing import Dict, Set import snakemake +import snakemake.workflow from snakemake.parser import ( INDENT, Benchmark, @@ -32,6 +33,13 @@ def eprint(x: str) -> None: rules = data["rules"] outputs = data["outputs"] +non_blob_parameters = data.get("non_blob_parameters", {}) + +sw = sys.modules["snakemake.workflow"] +for k, v in non_blob_parameters.items(): + if not hasattr(sw, k): + setattr(sw, k, v) + def eprint_named_list(xs): eprint(" Positional:") diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 08313e3b..77403599 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -308,7 +308,7 @@ def get_fn_interface( params_str = ",\n".join( reindent( rf""" - {param}: {t.__name__} + {param}: {"latch_metadata." if t.__name__ not in {"str", "LatchFile", "LatchDir"} else ""}{t.__name__} """, 1, ).rstrip() @@ -355,7 +355,7 @@ def get_fn_code( for param, t in self.python_interface.inputs.items(): if t in (LatchFile, LatchDir): param_meta = self.parameter_metadata[param] - assert isinstance(param_meta, metadata.SnakemakeParameter) + assert isinstance(param_meta, metadata.SnakemakeFileParameter) code_block += reindent( rf""" @@ -1198,12 +1198,9 @@ def get_fn_code( need_conda = any(x.conda_env is not None for x in jobs) - config_args = [] if non_blob_parameters is not None and len(non_blob_parameters) > 0: - config_args = ["--config"] for k, v in non_blob_parameters.items(): - self.job.rule.workflow.globals["config"][k] = v - config_args.append(f"{k}={v}") + self.job.rule.workflow.globals[k] = v snakemake_args = [ "-m", @@ -1219,7 +1216,6 @@ def get_fn_code( str(self.job.jobid), "--cores", str(self.job.threads), - *config_args, ] if not self.job.is_group(): snakemake_args.append("--force-use-threads") @@ -1236,6 +1232,7 @@ def get_fn_code( snakemake_data = { "rules": {}, "outputs": self.job.output, + "non_blob_parameters": non_blob_parameters, } for job in jobs: From 7b6d57f9403ccf6fdca4e94a831dfb0e79364db4 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Tue, 3 Oct 2023 18:45:39 -0700 Subject: [PATCH 294/356] render params + replace rules with ellipse --- latch_cli/snakemake/single_task_snakemake.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index e347888d..7e2abbd4 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -155,9 +155,12 @@ def emit_overrides(self, token): raise ValueError(f"tried to emit overrides for unknown state: {type(self)}") positional_data = (render_annotated_str_list(x) for x in xs["positional"]) - keyword_data = ( - f"{k}={render_annotated_str_list(v)}" for k, v in xs["keyword"].items() - ) + + modifier_fn = render_annotated_str_list + if isinstance(self, Params): + modifier_fn = repr + + keyword_data = (f"{k}={modifier_fn(v)}" for k, v in xs["keyword"].items()) data = chain(positional_data, keyword_data) for x in data: @@ -199,6 +202,14 @@ def skipping_block_content(self, token): class SkippingRule(Rule): def start(self, aux=""): if self.rulename not in rules: + # Rules can be nested in conditional statements: + # + # if (): + # rule A: + # + # + # We want correct python code if we remove them. + yield "..." return yield from super().start(aux) From 28ac3e2a1696b6fa5e12225d461f7498f8887e26 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Tue, 3 Oct 2023 19:50:54 -0700 Subject: [PATCH 295/356] support multiext --- latch_cli/snakemake/single_task_snakemake.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 7e2abbd4..79a2b520 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -154,7 +154,17 @@ def emit_overrides(self, token): else: raise ValueError(f"tried to emit overrides for unknown state: {type(self)}") - positional_data = (render_annotated_str_list(x) for x in xs["positional"]) + if ( + isinstance(self, Params) + and xs[0].get("flags") + and "multiext" in xs[0].get("flags") + ): + quote = "'" + positional_data = ( + f"multiext('{xs[0]['value']}',{','.join([quote + x['value'].split('.')[-1] + quote for x in xs])})" + ) + else: + positional_data = (render_annotated_str_list(x) for x in xs["positional"]) modifier_fn = render_annotated_str_list if isinstance(self, Params): From c067ebfbd455a471bfae005939499520facbe960 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Tue, 3 Oct 2023 20:02:26 -0700 Subject: [PATCH 296/356] strip directory print after job failure --- latch_cli/snakemake/workflow.py | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 9e0c2f61..2ac22efb 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1325,21 +1325,6 @@ def get_fn_code( finally: ignored_paths = {{".cache", ".snakemake/conda"}} ignored_names = {{".git", ".latch", "__pycache__"}} - - print("Recursive directory listing:") - stack = [(Path("."), 0)] - while len(stack) > 0: - cur, indent = stack.pop() - print(" " * indent + cur.name) - - if cur.is_dir(): - if cur.name in ignored_names or str(cur) in ignored_paths: - print(" " * indent + " ...") - continue - - for x in cur.iterdir(): - stack.append((x, indent + 1)) - """, 1, ) From df456424382ff2883d55884bc46bfc7507d6537f Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Tue, 3 Oct 2023 20:02:32 -0700 Subject: [PATCH 297/356] bug --- latch_cli/snakemake/single_task_snakemake.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 79a2b520..dfa0c13c 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -155,7 +155,7 @@ def emit_overrides(self, token): raise ValueError(f"tried to emit overrides for unknown state: {type(self)}") if ( - isinstance(self, Params) + isinstance(self, Output) and xs[0].get("flags") and "multiext" in xs[0].get("flags") ): From 7aa3e123205aff070a1f96afd54f9dda816762ae Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Tue, 3 Oct 2023 20:49:21 -0700 Subject: [PATCH 298/356] bug --- latch_cli/snakemake/single_task_snakemake.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index dfa0c13c..e9902028 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -161,7 +161,9 @@ def emit_overrides(self, token): ): quote = "'" positional_data = ( - f"multiext('{xs[0]['value']}',{','.join([quote + x['value'].split('.')[-1] + quote for x in xs])})" + ( + f"multiext('{xs[0]['value']}',{','.join([quote + x['value'].split('.')[-1] + quote for x in xs])})" + ), ) else: positional_data = (render_annotated_str_list(x) for x in xs["positional"]) From 1b1510267a7eee46b73412848d9827300108d742 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Wed, 4 Oct 2023 13:14:29 -0700 Subject: [PATCH 299/356] trisomy --- latch_cli/snakemake/single_task_snakemake.py | 19 +++++++++++++++++-- latch_cli/snakemake/workflow.py | 3 ++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index e9902028..72480d2f 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -9,6 +9,7 @@ from snakemake.parser import ( INDENT, Benchmark, + Include, Input, Log, Output, @@ -28,6 +29,11 @@ def eprint(x: str) -> None: print(x, file=sys.stderr) +print_compilation_env = os.environ["LATCH_PRINT_COMPILATION"] +print_compilation = False +if print_compilation_env == "1": + print_compilation = True + data = json.loads(os.environ["LATCH_SNAKEMAKE_DATA"]) rules = data["rules"] outputs = data["outputs"] @@ -156,9 +162,10 @@ def emit_overrides(self, token): if ( isinstance(self, Output) - and xs[0].get("flags") - and "multiext" in xs[0].get("flags") + and xs["positional"][0].get("flags") + and "multiext" in xs["positional"][0].get("flags") ): + eprint("inside") quote = "'" positional_data = ( ( @@ -203,12 +210,20 @@ def skipping_block_content(self, token): emitted_overrides.add(self.rulename) +def block_content_with_print_compilation(self, token): + if print_compilation: + yield f"{token.string}, print_compilation=True", token + else: + yield token.string, token + + Input.block_content = skipping_block_content Output.block_content = skipping_block_content Params.block_content = skipping_block_content Benchmark.block_content = skipping_block_content Log.block_content = skipping_block_content Ruleorder.block_content = lambda self, token: None +Include.block_content = block_content_with_print_compilation class SkippingRule(Rule): diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 2ac22efb..300419a3 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1243,7 +1243,8 @@ def get_fn_code( check=True, env={{ **os.environ, - "LATCH_SNAKEMAKE_DATA": {repr(json.dumps(snakemake_data))} + "LATCH_SNAKEMAKE_DATA": {repr(json.dumps(snakemake_data))}, + "LATCH_PRINT_COMPILATION": "1" }}, stdout=f ) From 00c68195cb69815324f39a4667ce500923d7d79e Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Wed, 4 Oct 2023 13:29:23 -0700 Subject: [PATCH 300/356] better --- latch_cli/snakemake/single_task_snakemake.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 72480d2f..c380eaea 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -29,8 +29,7 @@ def eprint(x: str) -> None: print(x, file=sys.stderr) -print_compilation_env = os.environ["LATCH_PRINT_COMPILATION"] -print_compilation = False +print_compilation_env = os.environ.get("LATCH_PRINT_COMPILATION", False) if print_compilation_env == "1": print_compilation = True From 0c70e54a0922c1a5fd55113d990ed0be0834170e Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Wed, 4 Oct 2023 13:32:57 -0700 Subject: [PATCH 301/356] fix --- latch_cli/snakemake/single_task_snakemake.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index c380eaea..1621b1a6 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -168,7 +168,7 @@ def emit_overrides(self, token): quote = "'" positional_data = ( ( - f"multiext('{xs[0]['value']}',{','.join([quote + x['value'].split('.')[-1] + quote for x in xs])})" + f"multiext('{xs['positional'][0]['value']}',{','.join([quote + x['value'].split('.')[-1] + quote for x in xs])})" ), ) else: From 6e9216f539fb4c4551f3421452a90847f139fd32 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Wed, 4 Oct 2023 13:52:00 -0700 Subject: [PATCH 302/356] more readable --- latch_cli/snakemake/single_task_snakemake.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 1621b1a6..7861b24a 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -164,13 +164,9 @@ def emit_overrides(self, token): and xs["positional"][0].get("flags") and "multiext" in xs["positional"][0].get("flags") ): - eprint("inside") - quote = "'" - positional_data = ( - ( - f"multiext('{xs['positional'][0]['value']}',{','.join([quote + x['value'].split('.')[-1] + quote for x in xs])})" - ), - ) + filename = repr(xs["positional"][0]["value"]) + exts = [repr(x["value"].split(".")[-1]) for x in xs["positional"]] + positional_data = (f"multiext({filename},{','.join(exts)})",) else: positional_data = (render_annotated_str_list(x) for x in xs["positional"]) From 725e4512a5e915fe8fb5dd9bec319b6321982d2c Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Wed, 4 Oct 2023 14:00:12 -0700 Subject: [PATCH 303/356] slop --- latch_cli/snakemake/single_task_snakemake.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 7861b24a..76a8a9ba 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -29,8 +29,8 @@ def eprint(x: str) -> None: print(x, file=sys.stderr) -print_compilation_env = os.environ.get("LATCH_PRINT_COMPILATION", False) -if print_compilation_env == "1": +print_compilation = os.environ.get("LATCH_PRINT_COMPILATION", False) +if print_compilation == "1": print_compilation = True data = json.loads(os.environ["LATCH_SNAKEMAKE_DATA"]) @@ -161,7 +161,7 @@ def emit_overrides(self, token): if ( isinstance(self, Output) - and xs["positional"][0].get("flags") + and xs["positional"][0].get("flags") is not None and "multiext" in xs["positional"][0].get("flags") ): filename = repr(xs["positional"][0]["value"]) From b9d9caef78ce3465d9c9ebb12b6bec5f7c1b0aab Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Wed, 4 Oct 2023 14:21:38 -0700 Subject: [PATCH 304/356] positionals can be empty --- latch_cli/snakemake/single_task_snakemake.py | 1 + 1 file changed, 1 insertion(+) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 76a8a9ba..fc7f44a2 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -161,6 +161,7 @@ def emit_overrides(self, token): if ( isinstance(self, Output) + and len(xs["positional"]) > 0 and xs["positional"][0].get("flags") is not None and "multiext" in xs["positional"][0].get("flags") ): From 4d97a9a279ca9d1c65544ab309a86611753f10e2 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Wed, 4 Oct 2023 15:14:29 -0700 Subject: [PATCH 305/356] bug --- latch_cli/snakemake/single_task_snakemake.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index fc7f44a2..6331e059 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -165,8 +165,8 @@ def emit_overrides(self, token): and xs["positional"][0].get("flags") is not None and "multiext" in xs["positional"][0].get("flags") ): - filename = repr(xs["positional"][0]["value"]) - exts = [repr(x["value"].split(".")[-1]) for x in xs["positional"]] + filename = repr(xs["positional"][0]["flags"]["multiext"]) + exts = [repr("." + x["value"].split(".")[-1]) for x in xs["positional"]] positional_data = (f"multiext({filename},{','.join(exts)})",) else: positional_data = (render_annotated_str_list(x) for x in xs["positional"]) From 95ea976d3028ee4126eb3f6b46a01ea8b3abd615 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Wed, 4 Oct 2023 17:51:38 -0700 Subject: [PATCH 306/356] save state Signed-off-by: Ayush Kamat --- latch/types/directory.py | 80 ++++++++++++++++++++++++++++++++-------- latch/types/file.py | 10 +++++ 2 files changed, 75 insertions(+), 15 deletions(-) diff --git a/latch/types/directory.py b/latch/types/directory.py index 0570a58c..45a8e6aa 100644 --- a/latch/types/directory.py +++ b/latch/types/directory.py @@ -7,6 +7,7 @@ from flytekit.core.annotation import FlyteAnnotation from flytekit.core.context_manager import FlyteContext, FlyteContextManager from flytekit.core.type_engine import TypeEngine, TypeTransformer +from flytekit.exceptions.user import FlyteUserException from flytekit.models.literals import Literal from flytekit.types.directory.types import ( FlyteDirectory, @@ -21,25 +22,41 @@ from latch_cli.utils.path import normalize_path -class Child(TypedDict): +class IterdirChild(TypedDict): type: str name: str -class ChildLdataTreeEdge(TypedDict): - child: Child +class IterdirChildLdataTreeEdge(TypedDict): + child: IterdirChild -class ChildLdataTreeEdges(TypedDict): - nodes: List[ChildLdataTreeEdge] +class IterdirChildLdataTreeEdges(TypedDict): + nodes: List[IterdirChildLdataTreeEdge] -class LDataResolvePathFinalLinkTarget(TypedDict): - childLdataTreeEdges: ChildLdataTreeEdges +class IterDirLDataResolvePathFinalLinkTarget(TypedDict): + childLdataTreeEdges: IterdirChildLdataTreeEdges -class LdataResolvePathData(TypedDict): - finalLinkTarget: LDataResolvePathFinalLinkTarget +class IterdirLdataResolvePathData(TypedDict): + finalLinkTarget: IterDirLDataResolvePathFinalLinkTarget + + +class NodeDescendantsNode(TypedDict): + relPath: str + + +class NodeDescendantsDescendants(TypedDict): + nodes: List[NodeDescendantsNode] + + +class NodeDescendantsFinalLinkTarget(TypedDict): + descendants: NodeDescendantsDescendants + + +class NodeDescendantsLDataResolvePathData(TypedDict): + finalLinkTarget: NodeDescendantsFinalLinkTarget class LatchDir(FlyteDirectory): @@ -78,6 +95,8 @@ def __init__( self, path: Union[str, PathLike], remote_path: Optional[PathLike] = None, + *, + do_download: bool = True, **kwargs, ): if path is None: @@ -112,11 +131,42 @@ def downloader(): and ctx.inspect_objects_only is False ): self.path = ctx.file_access.get_random_local_directory() - return ctx.file_access.get_data( - self._remote_directory, - self.path, - is_multipart=True, - ) + + if do_download: + return ctx.file_access.get_data( + self._remote_directory, + self.path, + is_multipart=True, + ) + + res: Optional[NodeDescendantsLDataResolvePathData] = execute( + gql.gql(""" + query NodeDescendantsQuery($path: String!) { + ldataResolvePathData(argPath: $path) { + finalLinkTarget { + descendants { + nodes { + relPath + } + } + } + } + } + """), + {"path": self._remote_directory}, + )["ldataResolvePathData"] + + if res is None: + # todo(ayush): proper error message + exit + raise FlyteUserException( + f"No directory at {self._remote_directory}" + ) + + for x in res["finalLinkTarget"]["descendants"]["nodes"]: + p = Path(self.path) / x["relPath"] + + p.parent.mkdir(exist_ok=True, parents=True) + p.touch(exist_ok=True) super().__init__(self.path, downloader, self._remote_directory) @@ -132,7 +182,7 @@ def iterdir(self) -> List[Union[LatchFile, "LatchDir"]]: return ret - res: Optional[LdataResolvePathData] = execute( + res: Optional[IterdirLdataResolvePathData] = execute( gql.gql(""" query LDataChildren($argPath: String!) { ldataResolvePathData(argPath: $argPath) { diff --git a/latch/types/file.py b/latch/types/file.py index 6af46837..061fbd25 100644 --- a/latch/types/file.py +++ b/latch/types/file.py @@ -1,5 +1,7 @@ +import os import re from os import PathLike +from pathlib import Path from typing import Optional, Type, Union from urllib.parse import urlparse @@ -58,6 +60,8 @@ def __init__( self, path: Union[str, PathLike], remote_path: Optional[Union[str, PathLike]] = None, + *, + do_download: bool = True, **kwargs, ): if path is None: @@ -108,6 +112,12 @@ def downloader(): local_path_hint = data["name"] self.path = ctx.file_access.get_random_local_path(local_path_hint) + + if not do_download: + Path(self.path).parent.mkdir(parents=True, exist_ok=True) + Path(self.path).touch(exist_ok=True) + return + return ctx.file_access.get_data( self._remote_path, self.path, From 2810bdafd330d0509a36c1bc5d608281f0ec7c79 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Wed, 4 Oct 2023 17:52:57 -0700 Subject: [PATCH 307/356] changelog Signed-off-by: Ayush Kamat --- CHANGELOG.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba24cc5b..c73efbf3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,12 @@ Types of changes # Latch SDK Changelog +## 2.33.1 - 2023-10-04 + +### Added + +* Support for `str` and `Enum` parameters for Snakemake workflows + ## 2.33.0 - 2023-09-29 ### Added @@ -27,17 +33,18 @@ Types of changes ### Fixed * Snakemake: - * Better errors if `Snakefile` or `latch_metadata.py` file missing - * Correct issues with snakemake example project + - Better errors if `Snakefile` or `latch_metadata.py` file missing + - Correct issues with snakemake example project ## 2.32.7 - 2023-09-07 ### Fixed * Snakemake: - * `--snakemake` for `latch dockerfile` command to generate `Dockerfile` with + - `--snakemake` for `latch dockerfile` command to generate `Dockerfile` with necessary instructions - * Snakemake example for `latch init` + + - Snakemake example for `latch init` ## 2.32.6 - 2023-09-07 From 0e11a96987f6562f06f18baad2a94a8d1b58bf26 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Wed, 4 Oct 2023 19:12:08 -0700 Subject: [PATCH 308/356] retry job on conda create exception --- latch_cli/snakemake/serialize.py | 3 ++- latch_cli/snakemake/workflow.py | 27 +++++++++++++++++++-------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index 382bddcd..35a5261b 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -321,12 +321,13 @@ def generate_snakemake_entrypoint( import shutil import subprocess from subprocess import CalledProcessError + import traceback from typing import NamedTuple import stat import sys from flytekit.extras.persistence import LatchPersistence - import traceback + from snakemake.exceptions import CreateCondaEnvironmentException from latch.resources.tasks import custom_task from latch.types.directory import LatchDir diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 300419a3..17014be0 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1269,14 +1269,25 @@ def get_fn_code( print("\n\n\n") try: - subprocess.run( - [sys.executable,{','.join(repr(x) for x in snakemake_args)}], - check=True, - env={{ - **os.environ, - "LATCH_SNAKEMAKE_DATA": {repr(json.dumps(snakemake_data))} - }} - ) + conda_retries = 0 + while conda_retries < 3: + try: + subprocess.run( + [sys.executable,{','.join(repr(x) for x in snakemake_args)}], + check=True, + env={{ + **os.environ, + "LATCH_SNAKEMAKE_DATA": {repr(json.dumps(snakemake_data))} + }} + ) + break + except CreateCondaEnvironmentException as e: + if conda_retries < 3: + print("Retrying snakemake\n\n") + conda_retries +=1 + continue + else: + raise e finally: if tail is not None: import signal From 75edee35051e76fa28a80e99e0e5eb5ec30e98bb Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Wed, 4 Oct 2023 20:25:28 -0700 Subject: [PATCH 309/356] Revert "retry job on conda create exception" This reverts commit 0e11a96987f6562f06f18baad2a94a8d1b58bf26. --- latch_cli/snakemake/serialize.py | 3 +-- latch_cli/snakemake/workflow.py | 27 ++++++++------------------- 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index 35a5261b..382bddcd 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -321,13 +321,12 @@ def generate_snakemake_entrypoint( import shutil import subprocess from subprocess import CalledProcessError - import traceback from typing import NamedTuple import stat import sys from flytekit.extras.persistence import LatchPersistence - from snakemake.exceptions import CreateCondaEnvironmentException + import traceback from latch.resources.tasks import custom_task from latch.types.directory import LatchDir diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 17014be0..300419a3 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -1269,25 +1269,14 @@ def get_fn_code( print("\n\n\n") try: - conda_retries = 0 - while conda_retries < 3: - try: - subprocess.run( - [sys.executable,{','.join(repr(x) for x in snakemake_args)}], - check=True, - env={{ - **os.environ, - "LATCH_SNAKEMAKE_DATA": {repr(json.dumps(snakemake_data))} - }} - ) - break - except CreateCondaEnvironmentException as e: - if conda_retries < 3: - print("Retrying snakemake\n\n") - conda_retries +=1 - continue - else: - raise e + subprocess.run( + [sys.executable,{','.join(repr(x) for x in snakemake_args)}], + check=True, + env={{ + **os.environ, + "LATCH_SNAKEMAKE_DATA": {repr(json.dumps(snakemake_data))} + }} + ) finally: if tail is not None: import signal From f2069ac18e0654f24a1b15848742c14cbcce5e00 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Wed, 4 Oct 2023 20:41:00 -0700 Subject: [PATCH 310/356] changelog + setup --- CHANGELOG.md | 18 ++++++++++++++++++ setup.py | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9515c75f..92399912 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,24 @@ Types of changes # Latch SDK Changelog +## 2.33.0 - 2023-10-04 + +### Added + +* `directory` modifier for input / outputs +* Support `temp` by removing from compiled rules. All files / directories are +temporary because they are deleted at the end of each job on Latch. +* `multiext` output modifier +* `report` output modifier +* `params` in rules + +### Fixed + +* Replace skipped rules with `Ellipsis`. Supports rules nested in conditionals where previously an empty block was produced. +* Patched parser to generate compiled code for `workflow.include` calls Compiled workflow.include should carry `print_compilation` keyword (snakemake/snakemake#2469) +* Detect use of `conda` keyword and install in image. This effectively supports wrapper/conda keywords. +* `Iterable, Generator` cause issues as type hints when imported from `collections.abc` rather than `typing` + ## 2.32.8 - 2023-09-07 ### Fixed diff --git a/setup.py b/setup.py index d09f1f05..3831f10e 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ setup( name="latch", - version="v2.32.8", + version="v2.33.0", author_email="kenny@latch.bio", description="The Latch SDK", packages=find_packages(), From 53fe74ddda5d9cda503b350151e5617aa0362218 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Wed, 4 Oct 2023 20:50:38 -0700 Subject: [PATCH 311/356] bump setup version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 3831f10e..8f13abc2 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ setup( name="latch", - version="v2.33.0", + version="v2.34.0", author_email="kenny@latch.bio", description="The Latch SDK", packages=find_packages(), From 19ae7ad2a22654279ff2ebe74341d9012a8fbc67 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Sat, 7 Oct 2023 13:07:39 -0700 Subject: [PATCH 312/356] init Signed-off-by: Ayush Kamat --- latch/types/directory.py | 85 ++++++++++++++++++-------------- latch/types/file.py | 29 ++++++++--- latch_cli/snakemake/serialize.py | 4 +- latch_cli/snakemake/workflow.py | 3 +- 4 files changed, 72 insertions(+), 49 deletions(-) diff --git a/latch/types/directory.py b/latch/types/directory.py index 45a8e6aa..c716e8dd 100644 --- a/latch/types/directory.py +++ b/latch/types/directory.py @@ -95,8 +95,6 @@ def __init__( self, path: Union[str, PathLike], remote_path: Optional[PathLike] = None, - *, - do_download: bool = True, **kwargs, ): if path is None: @@ -112,6 +110,8 @@ def __init__( else: self.path = str(path) + self._path_witness = False + if _is_valid_url(self.path) and remote_path is None: self._remote_directory = self.path else: @@ -130,45 +130,26 @@ def downloader(): # todo(kenny) is this necessary? and ctx.inspect_objects_only is False ): - self.path = ctx.file_access.get_random_local_directory() - - if do_download: - return ctx.file_access.get_data( - self._remote_directory, - self.path, - is_multipart=True, - ) - - res: Optional[NodeDescendantsLDataResolvePathData] = execute( - gql.gql(""" - query NodeDescendantsQuery($path: String!) { - ldataResolvePathData(argPath: $path) { - finalLinkTarget { - descendants { - nodes { - relPath - } - } - } - } - } - """), - {"path": self._remote_directory}, - )["ldataResolvePathData"] + self._idempotent_set_path() - if res is None: - # todo(ayush): proper error message + exit - raise FlyteUserException( - f"No directory at {self._remote_directory}" - ) + return ctx.file_access.get_data( + self._remote_directory, + self.path, + is_multipart=True, + ) - for x in res["finalLinkTarget"]["descendants"]["nodes"]: - p = Path(self.path) / x["relPath"] + super().__init__(self.path, downloader, self._remote_directory) - p.parent.mkdir(exist_ok=True, parents=True) - p.touch(exist_ok=True) + def _idempotent_set_path(self): + if self._path_witness: + return - super().__init__(self.path, downloader, self._remote_directory) + ctx = FlyteContextManager.current_context() + if ctx is None: + return + + self.path = ctx.file_access.get_random_local_directory() + self._path_witness = True def iterdir(self) -> List[Union[LatchFile, "LatchDir"]]: ret: List[Union[LatchFile, "LatchDir"]] = [] @@ -215,6 +196,36 @@ def iterdir(self) -> List[Union[LatchFile, "LatchDir"]]: return ret + def touch(self): # fixme(ayush): better name + self._idempotent_set_path() + + res: Optional[NodeDescendantsLDataResolvePathData] = execute( + gql.gql(""" + query NodeDescendantsQuery($path: String!) { + ldataResolvePathData(argPath: $path) { + finalLinkTarget { + descendants { + nodes { + relPath + } + } + } + } + } + """), + {"path": self._remote_directory}, + )["ldataResolvePathData"] + + if res is None: + # todo(ayush): proper error message + exit + raise FlyteUserException(f"No directory at {self._remote_directory}") + + for x in res["finalLinkTarget"]["descendants"]["nodes"]: + p = Path(self.path) / x["relPath"] + + p.parent.mkdir(exist_ok=True, parents=True) + p.touch(exist_ok=True) + @property def local_path(self) -> str: """File path local to the environment executing the task.""" diff --git a/latch/types/file.py b/latch/types/file.py index 061fbd25..5888ca3f 100644 --- a/latch/types/file.py +++ b/latch/types/file.py @@ -60,8 +60,6 @@ def __init__( self, path: Union[str, PathLike], remote_path: Optional[Union[str, PathLike]] = None, - *, - do_download: bool = True, **kwargs, ): if path is None: @@ -77,6 +75,8 @@ def __init__( else: self.path = str(path) + self._path_witness = False + if _is_valid_url(self.path) and remote_path is None: self._remote_path = str(path) else: @@ -111,12 +111,7 @@ def downloader(): if data is not None and data["name"] is not None: local_path_hint = data["name"] - self.path = ctx.file_access.get_random_local_path(local_path_hint) - - if not do_download: - Path(self.path).parent.mkdir(parents=True, exist_ok=True) - Path(self.path).touch(exist_ok=True) - return + self._idempotent_set_path(local_path_hint) return ctx.file_access.get_data( self._remote_path, @@ -126,6 +121,24 @@ def downloader(): super().__init__(self.path, downloader, self._remote_path) + def _idempotent_set_path(self, hint: Optional[str] = None): + if self._path_witness: + return + + ctx = FlyteContextManager.current_context() + if ctx is None: + return + + self.path = ctx.file_access.get_random_local_path(hint) + self._path_witness = True + + def touch(self): + self._idempotent_set_path() + + p = Path(self.path) + p.parent.mkdir(exist_ok=True, parents=True) + p.touch(exist_ok=True) + @property def local_path(self) -> str: """File path local to the environment executing the task.""" diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index 382bddcd..6b7ed075 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -124,9 +124,7 @@ def extract_dag(self): priorityfiles=set(), ) - self.persistence = Persistence( - dag=dag, - ) + self._persistence = Persistence(dag=dag) dag.init() dag.update_checkpoint_dependencies() diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 102878a1..8241f5a7 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -357,7 +357,8 @@ def get_fn_code( {param}_dst_p = Path("{param_meta.path}") print(f"Downloading {param}: {{{param}.remote_path}}") - {param}_p = Path({param}).resolve() + {param}.touch() + {param}_p = Path({param}.path) print(f" {{file_name_and_size({param}_p)}}") """, From 4043e2efe3e73438408ed48aa443df3256e00fea Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Wed, 11 Oct 2023 10:32:04 -0700 Subject: [PATCH 313/356] add config -> metadata parser Signed-off-by: Ayush Kamat --- latch_cli/snakemake/config_parser.py | 158 +++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 latch_cli/snakemake/config_parser.py diff --git a/latch_cli/snakemake/config_parser.py b/latch_cli/snakemake/config_parser.py new file mode 100644 index 00000000..51f81e67 --- /dev/null +++ b/latch_cli/snakemake/config_parser.py @@ -0,0 +1,158 @@ +import json +import textwrap as tw +from dataclasses import fields, is_dataclass, make_dataclass +from pathlib import Path +from typing import Any, Dict, List, Optional, Type, Union, get_args, get_origin + +import yaml +from typing_extensions import TypeAlias, TypeGuard + +from latch_cli.snakemake.workflow import reindent +from latch_cli.utils import identifier_suffix_from_str + +JSONValue: TypeAlias = Union[int, str, bool, float, List["JSONValue"], "JSONDict"] +JSONDict: TypeAlias = Dict[str, "JSONValue"] + + +def parse_type(v: JSONValue, name: Optional[str] = None) -> Type: + if is_primitive_value(v): + return type(v) + + if isinstance(v, list): + parsed_types = tuple(parse_type(x) for x in v) + return List[Union[parsed_types]] + + if name is None: + name = "SnakemakeRecord" + + fields = {} + for k, x in v.items(): + fields[identifier_suffix_from_str(k)] = parse_type( + x, identifier_suffix_from_str(k) + ) + + return make_dataclass(name, fields.items()) + + +def parse_config(config_path: Path) -> Dict[str, Type]: + res: JSONValue = yaml.safe_load(config_path.read_text()) + + if not isinstance(res, dict): + return {} + + params: Dict[str, Type] = {} + for k, v in res.items(): + params[k] = parse_type(v, identifier_suffix_from_str(k)) + + return params + + +def is_primitive_type( + typ: Type, +) -> TypeGuard[Union[Type[str], Type[bool], Type[int], Type[float]]]: + return _is_primitive(t=typ) + + +def is_primitive_value( + val: Any, +) -> TypeGuard[Union[str, bool, int, float]]: + return _is_primitive(v=val) + + +def _is_primitive( + *, + t: Optional[Type] = None, + v: Optional[Any] = None, +) -> bool: + if v is not None: + t = type(v) + + assert t is not None + + return t in {str, bool, int, float} + + +def type_repr(t: Type) -> str: + if is_dataclass(t) or is_primitive_type(t): + return t.__name__ + + return repr(t) + + +def dataclass_repr(typ: Type) -> str: + assert is_dataclass(typ) + + lines = ["@dataclass", f"class {typ.__name__}:"] + for f in fields(typ): + lines.append(f" {f.name}: {type_repr(f.type)}") + + return "\n".join(lines) + "\n\n\n" + + +def get_preamble(typ: Type) -> str: + if typ in {str, int, bool}: + return "" + + if get_origin(typ) in {Union, list}: + return "".join([get_preamble(t) for t in get_args(typ)]) + + assert is_dataclass(typ), typ + + preamble = "".join([get_preamble(f.type) for f in fields(typ)]) + + return "".join([preamble, dataclass_repr(typ)]) + + +def generate_metadata(config_path: Path): + parsed = parse_config(config_path) + + preambles = [] + params = [] + + for k, typ in parsed.items(): + preambles.append(get_preamble(typ)) + params.append( + reindent( + f"""\ + {repr(k)}: SnakemakeParameter( + display_name={repr(k)}, + type={type_repr(typ)}, + ),""", + 2, + ) + ) + + with open("latch_metadata.py", "w") as f: + f.write( + reindent( + f""" + from dataclasses import dataclass + import typing + + from latch.types.metadata import SnakemakeParameter, SnakemakeMetadata, LatchAuthor + from latch.types.directory import LatchDir + from latch.types.file import LatchFile + + __preambles__ + SnakemakeMetadata( + output_dir=LatchDir("latch:///your_output_directory``"), + display_name="Your Workflow Name", + author=LatchAuthor( + name="Your Name", + ), + parameters={{ + __params__ + }}, + ) + """, + 0, + ) + .replace("__preambles__", "".join(preambles)) + .replace("__params__", "\n".join(params)) + ) + + +if __name__ == "__main__": + generate_metadata( + Path("/Users/ayush/Desktop/core/latch/scratch/snakemake/config.yaml") + ) From e85a0d6f01f551f936fd927df8ed87364b157a88 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Thu, 12 Oct 2023 18:39:43 -0700 Subject: [PATCH 314/356] finish Signed-off-by: Ayush Kamat --- latch/types/metadata.py | 22 ++- latch_cli/main.py | 10 ++ latch_cli/snakemake/config/__init__.py | 0 latch_cli/snakemake/config/parser.py | 116 ++++++++++++++ latch_cli/snakemake/config/utils.py | 109 +++++++++++++ latch_cli/snakemake/config_parser.py | 158 ------------------- latch_cli/snakemake/serialize.py | 28 ++++ latch_cli/snakemake/single_task_snakemake.py | 4 +- latch_cli/snakemake/workflow.py | 22 ++- 9 files changed, 294 insertions(+), 175 deletions(-) create mode 100644 latch_cli/snakemake/config/__init__.py create mode 100644 latch_cli/snakemake/config/parser.py create mode 100644 latch_cli/snakemake/config/utils.py delete mode 100644 latch_cli/snakemake/config_parser.py diff --git a/latch/types/metadata.py b/latch/types/metadata.py index eb294465..2df1166b 100644 --- a/latch/types/metadata.py +++ b/latch/types/metadata.py @@ -3,7 +3,18 @@ from enum import Enum from pathlib import Path from textwrap import indent -from typing import Dict, Generic, List, Optional, Tuple, Type, TypeVar, Union +from typing import ( + ClassVar, + Dict, + Generic, + List, + Optional, + Protocol, + Tuple, + Type, + TypeVar, + Union, +) import yaml @@ -334,12 +345,21 @@ def dict(self): return {"__metadata__": parameter_dict} +# https://stackoverflow.com/questions/54668000/type-hint-for-an-instance-of-a-non-specific-dataclass +class _IsDataclass(Protocol): + __dataclass_fields__: ClassVar[Dict] + + @dataclass class SnakemakeParameter(LatchParameter): type: Optional[ Union[ + Type[int], + Type[float], Type[str], + Type[bool], Type[Enum], + Type[_IsDataclass], ] ] = None """ diff --git a/latch_cli/main.py b/latch_cli/main.py index 46671da7..a046d905 100644 --- a/latch_cli/main.py +++ b/latch_cli/main.py @@ -396,6 +396,16 @@ def ls(paths: Tuple[str], group_directories_first: bool): click.echo("") +@main.command("generate-metadata") +@click.argument("config_file", nargs=1, type=click.Path(exists=True, path_type=Path)) +def generate_metadata(config_file: Path): + """Generate a `latch_metadata.py` file from a Snakemake config file""" + + from latch_cli.snakemake.config.parser import generate_metadata + + generate_metadata(config_file) + + @main.command("launch") @click.argument("params_file", nargs=1, type=click.Path(exists=True)) @click.option( diff --git a/latch_cli/snakemake/config/__init__.py b/latch_cli/snakemake/config/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/latch_cli/snakemake/config/parser.py b/latch_cli/snakemake/config/parser.py new file mode 100644 index 00000000..67d8572d --- /dev/null +++ b/latch_cli/snakemake/config/parser.py @@ -0,0 +1,116 @@ +from pathlib import Path +from typing import Dict, Type + +import click +import yaml + +from latch_cli.snakemake.workflow import reindent +from latch_cli.utils import identifier_suffix_from_str + +from .utils import * + + +def parse_config(config_path: Path) -> Dict[str, Type]: + if not config_path.exists(): + click.secho( + reindent( + f""" + No config file found at {config_path}. + """, + 0, + ), + fg="red", + ) + raise click.exceptions.Exit(1) + + if config_path.is_dir(): + click.secho( + reindent( + f""" + Path {config_path} points to a directory. + """, + 0, + ), + fg="red", + ) + raise click.exceptions.Exit(1) + + try: + res: JSONValue = yaml.safe_load(config_path.read_text()) + except yaml.YAMLError as e: + click.secho( + reindent( + f""" + Error loading config from {config_path}: + + {e} + """, + 0, + ), + fg="red", + ) + raise click.exceptions.Exit(1) from e + + if not isinstance(res, dict): + # todo(ayush): think more about correct behavior for pathological .yaml files + return {"snakemake_parameter": res} + + parsed: Dict[str, Type] = {} + for k, v in res.items(): + parsed[k] = parse_type(v, identifier_suffix_from_str(k)) + + return parsed + + +def generate_metadata(config_path: Path): + parsed = parse_config(config_path) + + preambles = [] + params = [] + + for k, typ in parsed.items(): + preambles.append(get_preamble(typ)) + params.append( + reindent( + f"""\ + {repr(k)}: SnakemakeParameter( + display_name={repr(k)}, + type={type_repr(typ)}, + ),""", + 2, + ) + ) + + metadata_path = Path("latch_metadata.py") + if metadata_path.exists() and not click.confirm( + "File `latch_metadata.py` already exists. Overwrite?" + ): + return + + metadata_path.write_text( + reindent( + f""" + from dataclasses import dataclass + import typing + + from latch.types.metadata import SnakemakeParameter, SnakemakeMetadata, LatchAuthor + from latch.types.directory import LatchDir + from latch.types.file import LatchFile + + __preambles__ + SnakemakeMetadata( + output_dir=LatchDir("latch:///your_output_directory"), + display_name="Your Workflow Name", + author=LatchAuthor( + name="Your Name", + ), + parameters={{ + __params__ + }}, + ) + """, + 0, + ) + .replace("__preambles__", "".join(preambles)) + .replace("__params__", "\n".join(params)) + ) diff --git a/latch_cli/snakemake/config/utils.py b/latch_cli/snakemake/config/utils.py new file mode 100644 index 00000000..d3ab7785 --- /dev/null +++ b/latch_cli/snakemake/config/utils.py @@ -0,0 +1,109 @@ +from dataclasses import asdict, fields, is_dataclass, make_dataclass +from enum import Enum +from typing import Any, Dict, List, Optional, Type, Union, get_args, get_origin + +from typing_extensions import TypeAlias, TypeGuard, TypeVar + +from latch.types.directory import LatchDir +from latch.types.file import LatchFile +from latch_cli.utils import identifier_suffix_from_str + +JSONValue: TypeAlias = Union[int, str, bool, float, List["JSONValue"], "JSONDict"] +JSONDict: TypeAlias = Dict[str, "JSONValue"] + + +def parse_type(v: JSONValue, name: Optional[str] = None) -> Type: + if is_primitive_value(v): + return type(v) + + if isinstance(v, list): + parsed_types = tuple(parse_type(x) for x in v) + return List[Union[parsed_types]] + + assert isinstance(v, dict) + + if name is None: + name = "SnakemakeRecord" + + fields = {} + for k, x in v.items(): + fields[identifier_suffix_from_str(k)] = parse_type( + x, identifier_suffix_from_str(k) + ) + + return make_dataclass(name, fields.items()) + + +def is_primitive_type( + typ: Type, +) -> TypeGuard[Union[Type[str], Type[bool], Type[int], Type[float]]]: + return _is_primitive(t=typ) + + +def is_primitive_value( + val: Any, +) -> TypeGuard[Union[str, bool, int, float]]: + return _is_primitive(v=val) + + +def _is_primitive( + *, + t: Optional[Type] = None, + v: Optional[Any] = None, +) -> bool: + if v is not None: + t = type(v) + + assert t is not None + + return t in {str, bool, int, float} + + +def type_repr(t: Type, *, add_namespace: bool = False) -> str: + if is_primitive_type(t) or t is LatchFile or t is LatchDir: + return t.__name__ + + if get_origin(t) is None: + return f"{'latch_metadata.' if add_namespace else ''}{t.__name__}" + + if get_origin(t) is list: + args = get_args(t) + if len(args) > 0: + return f"typing.List[{type_repr(args[0], add_namespace=add_namespace)}]" + + return "typing.List" + + if get_origin(t) is Union: + args = get_args(t) + + assert len(args) > 0 + + return ( + f"typing.Union[{', '.join([type_repr(arg, add_namespace=add_namespace) for arg in args])}]" + ) + + return t.__name__ + + +def dataclass_repr(typ: Type) -> str: + assert is_dataclass(typ) + + lines = ["@dataclass", f"class {typ.__name__}:"] + for f in fields(typ): + lines.append(f" {f.name}: {type_repr(f.type)}") + + return "\n".join(lines) + "\n\n\n" + + +def get_preamble(typ: Type) -> str: + if typ in {str, int, bool}: + return "" + + if get_origin(typ) in {Union, list}: + return "".join([get_preamble(t) for t in get_args(typ)]) + + assert is_dataclass(typ), typ + + preamble = "".join([get_preamble(f.type) for f in fields(typ)]) + + return "".join([preamble, dataclass_repr(typ)]) diff --git a/latch_cli/snakemake/config_parser.py b/latch_cli/snakemake/config_parser.py deleted file mode 100644 index 51f81e67..00000000 --- a/latch_cli/snakemake/config_parser.py +++ /dev/null @@ -1,158 +0,0 @@ -import json -import textwrap as tw -from dataclasses import fields, is_dataclass, make_dataclass -from pathlib import Path -from typing import Any, Dict, List, Optional, Type, Union, get_args, get_origin - -import yaml -from typing_extensions import TypeAlias, TypeGuard - -from latch_cli.snakemake.workflow import reindent -from latch_cli.utils import identifier_suffix_from_str - -JSONValue: TypeAlias = Union[int, str, bool, float, List["JSONValue"], "JSONDict"] -JSONDict: TypeAlias = Dict[str, "JSONValue"] - - -def parse_type(v: JSONValue, name: Optional[str] = None) -> Type: - if is_primitive_value(v): - return type(v) - - if isinstance(v, list): - parsed_types = tuple(parse_type(x) for x in v) - return List[Union[parsed_types]] - - if name is None: - name = "SnakemakeRecord" - - fields = {} - for k, x in v.items(): - fields[identifier_suffix_from_str(k)] = parse_type( - x, identifier_suffix_from_str(k) - ) - - return make_dataclass(name, fields.items()) - - -def parse_config(config_path: Path) -> Dict[str, Type]: - res: JSONValue = yaml.safe_load(config_path.read_text()) - - if not isinstance(res, dict): - return {} - - params: Dict[str, Type] = {} - for k, v in res.items(): - params[k] = parse_type(v, identifier_suffix_from_str(k)) - - return params - - -def is_primitive_type( - typ: Type, -) -> TypeGuard[Union[Type[str], Type[bool], Type[int], Type[float]]]: - return _is_primitive(t=typ) - - -def is_primitive_value( - val: Any, -) -> TypeGuard[Union[str, bool, int, float]]: - return _is_primitive(v=val) - - -def _is_primitive( - *, - t: Optional[Type] = None, - v: Optional[Any] = None, -) -> bool: - if v is not None: - t = type(v) - - assert t is not None - - return t in {str, bool, int, float} - - -def type_repr(t: Type) -> str: - if is_dataclass(t) or is_primitive_type(t): - return t.__name__ - - return repr(t) - - -def dataclass_repr(typ: Type) -> str: - assert is_dataclass(typ) - - lines = ["@dataclass", f"class {typ.__name__}:"] - for f in fields(typ): - lines.append(f" {f.name}: {type_repr(f.type)}") - - return "\n".join(lines) + "\n\n\n" - - -def get_preamble(typ: Type) -> str: - if typ in {str, int, bool}: - return "" - - if get_origin(typ) in {Union, list}: - return "".join([get_preamble(t) for t in get_args(typ)]) - - assert is_dataclass(typ), typ - - preamble = "".join([get_preamble(f.type) for f in fields(typ)]) - - return "".join([preamble, dataclass_repr(typ)]) - - -def generate_metadata(config_path: Path): - parsed = parse_config(config_path) - - preambles = [] - params = [] - - for k, typ in parsed.items(): - preambles.append(get_preamble(typ)) - params.append( - reindent( - f"""\ - {repr(k)}: SnakemakeParameter( - display_name={repr(k)}, - type={type_repr(typ)}, - ),""", - 2, - ) - ) - - with open("latch_metadata.py", "w") as f: - f.write( - reindent( - f""" - from dataclasses import dataclass - import typing - - from latch.types.metadata import SnakemakeParameter, SnakemakeMetadata, LatchAuthor - from latch.types.directory import LatchDir - from latch.types.file import LatchFile - - __preambles__ - SnakemakeMetadata( - output_dir=LatchDir("latch:///your_output_directory``"), - display_name="Your Workflow Name", - author=LatchAuthor( - name="Your Name", - ), - parameters={{ - __params__ - }}, - ) - """, - 0, - ) - .replace("__preambles__", "".join(preambles)) - .replace("__params__", "\n".join(params)) - ) - - -if __name__ == "__main__": - generate_metadata( - Path("/Users/ayush/Desktop/core/latch/scratch/snakemake/config.yaml") - ) diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index 11c850f0..16064ff9 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -323,6 +323,8 @@ def generate_snakemake_entrypoint( from typing import NamedTuple import stat import sys + from dataclasses import is_dataclass, asdict + from enum import Enum from flytekit.extras.persistence import LatchPersistence import traceback @@ -334,6 +336,18 @@ def generate_snakemake_entrypoint( sys.stdout.reconfigure(line_buffering=True) sys.stderr.reconfigure(line_buffering=True) + def get_parameter_json_value(v): + if is_dataclass(v): + return asdict(v) + elif isinstance(v, Enum): + return v.value + elif isinstance(v, list): + return [get_parameter_json_value(x) for x in v] + elif isinstance(v, dict): + return {k: get_parameter_json_value(x) for k, x in v.items()} + else: + return v + def check_exists_and_rename(old: Path, new: Path): if new.exists(): print(f"A file already exists at {new} and will be overwritten.") @@ -395,6 +409,8 @@ def generate_jit_register_code( from typing import List, NamedTuple, Optional, TypedDict import hashlib from urllib.parse import urljoin + from dataclasses import is_dataclass, asdict + from enum import Enum import stat import base64 @@ -432,6 +448,18 @@ def generate_jit_register_code( sys.stdout.reconfigure(line_buffering=True) sys.stderr.reconfigure(line_buffering=True) + def get_parameter_json_value(v): + if is_dataclass(v): + return asdict(v) + elif isinstance(v, Enum): + return v.value + elif isinstance(v, list): + return [get_parameter_json_value(x) for x in v] + elif isinstance(v, dict): + return {k: get_parameter_json_value(x) for k, x in v.items()} + else: + return v + def check_exists_and_rename(old: Path, new: Path): if new.exists(): print(f"A file already exists at {new} and will be overwritten.") diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index 0491f7e6..b757158e 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -41,9 +41,7 @@ def eprint(x: str) -> None: non_blob_parameters = data.get("non_blob_parameters", {}) sw = sys.modules["snakemake.workflow"] -for k, v in non_blob_parameters.items(): - if not hasattr(sw, k): - setattr(sw, k, v) +setattr(sw, "config", non_blob_parameters) def eprint_named_list(xs): diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 3ee6c6f4..5cd99f16 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -3,7 +3,7 @@ import sys import textwrap import typing -from dataclasses import dataclass +from dataclasses import dataclass, is_dataclass from enum import Enum from pathlib import Path from typing import ( @@ -17,6 +17,8 @@ Type, TypeVar, Union, + get_args, + get_origin, ) from urllib.parse import urlparse @@ -63,6 +65,7 @@ from latch.resources.tasks import custom_task from latch.types.directory import LatchDir from latch.types.file import LatchFile +from latch_cli.snakemake.config.utils import is_primitive_type, type_repr from ..utils import identifier_suffix_from_str @@ -308,7 +311,7 @@ def get_fn_interface( params_str = ",\n".join( reindent( rf""" - {param}: {"latch_metadata." if t.__name__ not in {"str", "LatchFile", "LatchDir"} else ""}{t.__name__} + {param}: {type_repr(t, add_namespace=True)} """, 1, ).rstrip() @@ -390,20 +393,14 @@ def get_fn_code( """, 1, ) - elif t is str or issubclass(t, Enum): - ending = "" - if issubclass(t, Enum): - ending = ".value" - + else: code_block += reindent( rf""" - print(f"Saving parameter value {param} = {{{param}{ending}}}") - non_blob_parameters[{repr(param)}] = {param}{ending} + print(f"Saving parameter value {param} = {{get_parameter_json_value({param})}}") + non_blob_parameters[{repr(param)}] = get_parameter_json_value({param}) """, 1, ) - else: - raise ValueError(f"Unsupported parameter type {t} for {param}") code_block += reindent( rf""" @@ -1199,8 +1196,7 @@ def get_fn_code( need_conda = any(x.conda_env is not None for x in jobs) if non_blob_parameters is not None and len(non_blob_parameters) > 0: - for k, v in non_blob_parameters.items(): - self.job.rule.workflow.globals[k] = v + self.job.rule.workflow.globals["config"] = non_blob_parameters snakemake_args = [ "-m", From 9069c60651058b15c0f7e1e7fe604fb44d181f63 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Thu, 12 Oct 2023 18:42:40 -0700 Subject: [PATCH 315/356] fix typing Signed-off-by: Ayush Kamat --- latch/types/metadata.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/latch/types/metadata.py b/latch/types/metadata.py index 2df1166b..0f99697f 100644 --- a/latch/types/metadata.py +++ b/latch/types/metadata.py @@ -17,6 +17,7 @@ ) import yaml +from typing_extensions import TypeAlias from latch_cli.utils import identifier_suffix_from_str @@ -350,18 +351,20 @@ class _IsDataclass(Protocol): __dataclass_fields__: ClassVar[Dict] +ParameterType: TypeAlias = Union[ + Type[int], + Type[float], + Type[str], + Type[bool], + Type[Enum], + Type[_IsDataclass], + Type[List["ParameterType"]], +] + + @dataclass class SnakemakeParameter(LatchParameter): - type: Optional[ - Union[ - Type[int], - Type[float], - Type[str], - Type[bool], - Type[Enum], - Type[_IsDataclass], - ] - ] = None + type: Optional[ParameterType] = None """ The python type of the parameter. """ From 4c5294beee34fc64fdaa2ed3e73672529ec366e0 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Fri, 13 Oct 2023 13:55:20 -0700 Subject: [PATCH 316/356] rename things Signed-off-by: Ayush Kamat --- latch/types/directory.py | 8 ++++---- latch/types/file.py | 8 ++++---- latch_cli/snakemake/workflow.py | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/latch/types/directory.py b/latch/types/directory.py index c716e8dd..90823af7 100644 --- a/latch/types/directory.py +++ b/latch/types/directory.py @@ -110,7 +110,7 @@ def __init__( else: self.path = str(path) - self._path_witness = False + self._path_generated = False if _is_valid_url(self.path) and remote_path is None: self._remote_directory = self.path @@ -141,7 +141,7 @@ def downloader(): super().__init__(self.path, downloader, self._remote_directory) def _idempotent_set_path(self): - if self._path_witness: + if self._path_generated: return ctx = FlyteContextManager.current_context() @@ -149,7 +149,7 @@ def _idempotent_set_path(self): return self.path = ctx.file_access.get_random_local_directory() - self._path_witness = True + self._path_generated = True def iterdir(self) -> List[Union[LatchFile, "LatchDir"]]: ret: List[Union[LatchFile, "LatchDir"]] = [] @@ -196,7 +196,7 @@ def iterdir(self) -> List[Union[LatchFile, "LatchDir"]]: return ret - def touch(self): # fixme(ayush): better name + def _create_imposters(self): self._idempotent_set_path() res: Optional[NodeDescendantsLDataResolvePathData] = execute( diff --git a/latch/types/file.py b/latch/types/file.py index 5888ca3f..2f37d62e 100644 --- a/latch/types/file.py +++ b/latch/types/file.py @@ -75,7 +75,7 @@ def __init__( else: self.path = str(path) - self._path_witness = False + self._path_generated = False if _is_valid_url(self.path) and remote_path is None: self._remote_path = str(path) @@ -122,7 +122,7 @@ def downloader(): super().__init__(self.path, downloader, self._remote_path) def _idempotent_set_path(self, hint: Optional[str] = None): - if self._path_witness: + if self._path_generated: return ctx = FlyteContextManager.current_context() @@ -130,9 +130,9 @@ def _idempotent_set_path(self, hint: Optional[str] = None): return self.path = ctx.file_access.get_random_local_path(hint) - self._path_witness = True + self._path_generated = True - def touch(self): + def _create_imposters(self): self._idempotent_set_path() p = Path(self.path) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 8241f5a7..2ac0c3ae 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -357,7 +357,7 @@ def get_fn_code( {param}_dst_p = Path("{param_meta.path}") print(f"Downloading {param}: {{{param}.remote_path}}") - {param}.touch() + {param}._create_imposters() {param}_p = Path({param}.path) print(f" {{file_name_and_size({param}_p)}}") From 29ababe54075d4e2412c22637c1b0fd0f55f1b34 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Fri, 13 Oct 2023 13:57:38 -0700 Subject: [PATCH 317/356] only initialize path once Signed-off-by: Ayush Kamat --- latch/types/directory.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/latch/types/directory.py b/latch/types/directory.py index 90823af7..71463e71 100644 --- a/latch/types/directory.py +++ b/latch/types/directory.py @@ -220,8 +220,9 @@ def _create_imposters(self): # todo(ayush): proper error message + exit raise FlyteUserException(f"No directory at {self._remote_directory}") + root = Path(self.path) for x in res["finalLinkTarget"]["descendants"]["nodes"]: - p = Path(self.path) / x["relPath"] + p = root / x["relPath"] p.parent.mkdir(exist_ok=True, parents=True) p.touch(exist_ok=True) From 8c1cb0041109e28f55d4911a692515aa58d6ce68 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Tue, 17 Oct 2023 14:27:39 -0700 Subject: [PATCH 318/356] jit touch Signed-off-by: Ayush Kamat --- latch_cli/snakemake/serialize.py | 32 +++++++++++++++++--- latch_cli/snakemake/workflow.py | 52 +++++++++++++++++++++++++++----- 2 files changed, 71 insertions(+), 13 deletions(-) diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index 6b7ed075..e6e4816d 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -4,7 +4,7 @@ import traceback from pathlib import Path from textwrap import dedent -from typing import List, Optional, Set, Union, get_args +from typing import Dict, List, Optional, Set, Union, get_args import click from flyteidl.admin.launch_plan_pb2 import LaunchPlan as _idl_admin_LaunchPlan @@ -189,12 +189,15 @@ def snakemake_workflow_extractor( def extract_snakemake_workflow( - pkg_root: Path, snakefile: Path, version: Optional[str] = None + pkg_root: Path, + snakefile: Path, + version: Optional[str] = None, + local_to_remote_path_mapping: Optional[Dict[str, str]] = None, ) -> SnakemakeWorkflow: extractor = snakemake_workflow_extractor(pkg_root, snakefile, version) with extractor: dag = extractor.extract_dag() - wf = SnakemakeWorkflow(dag, version) + wf = SnakemakeWorkflow(dag, version, local_to_remote_path_mapping) wf.compile() return wf @@ -319,7 +322,7 @@ def generate_snakemake_entrypoint( import shutil import subprocess from subprocess import CalledProcessError - from typing import NamedTuple + from typing import NamedTuple, Dict import stat import sys @@ -330,9 +333,19 @@ def generate_snakemake_entrypoint( from latch.types.directory import LatchDir from latch.types.file import LatchFile + from latch_cli.utils import urljoins + sys.stdout.reconfigure(line_buffering=True) sys.stderr.reconfigure(line_buffering=True) + def update_mapping(local: Path, remote: str, mapping: Dict[str, str]): + if local.is_file(): + mapping[str(local)] = remote + return + + for p in local.iterdir(): + update_mapping(p, urljoins(remote, p.name), mapping) + def check_exists_and_rename(old: Path, new: Path): if new.exists(): print(f"A file already exists at {new} and will be overwritten.") @@ -388,7 +401,7 @@ def generate_jit_register_code( from functools import partial from pathlib import Path import shutil - from typing import List, NamedTuple, Optional, TypedDict + from typing import List, NamedTuple, Optional, TypedDict, Dict import hashlib from urllib.parse import urljoin @@ -417,6 +430,7 @@ def generate_jit_register_code( serialize_snakemake, ) import latch_cli.snakemake + from latch_cli.utils import urljoins from latch import small_task from latch_sdk_gql.execute import execute @@ -426,6 +440,14 @@ def generate_jit_register_code( sys.stdout.reconfigure(line_buffering=True) sys.stderr.reconfigure(line_buffering=True) + def update_mapping(local: Path, remote: str, mapping: Dict[str, str]): + if local.is_file(): + mapping[str(local)] = remote + return + + for p in local.iterdir(): + update_mapping(p, urljoins(remote, p.name), mapping) + def check_exists_and_rename(old: Path, new: Path): if new.exists(): print(f"A file already exists at {new} and will be overwritten.") diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 2ac0c3ae..a122cf8a 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -124,9 +124,12 @@ class RemoteFile: def snakemake_dag_to_interface( - dag: DAG, wf_name: str, docstring: Optional[Docstring] = None + dag: DAG, + wf_name: str, + docstring: Optional[Docstring] = None, + local_to_remote_path_mapping: Optional[Dict[str, str]] = None, ) -> Tuple[Interface, LiteralMap, List[RemoteFile]]: - outputs: Dict[str, LatchFile] = {} + outputs: Dict[str, Union[Type[LatchFile], Type[LatchDir]]] = {} for target in dag.targetjobs: for desired in target.input: param = variable_name_for_value(desired, target.input) @@ -141,7 +144,7 @@ def snakemake_dag_to_interface( outputs[param] = LatchFile literals: Dict[str, Literal] = {} - inputs: Dict[str, Tuple[LatchFile, None]] = {} + inputs: Dict[str, Tuple[Type[LatchFile], None]] = {} return_files: List[RemoteFile] = [] for job in dag.jobs: dep_outputs = [] @@ -157,11 +160,31 @@ def snakemake_dag_to_interface( LatchFile, None, ) + + print(x) + + print(local_to_remote_path_mapping) + remote_path = ( Path("/.snakemake_latch") / "workflows" / wf_name / "inputs" / x ) - remote_url = f"latch://{remote_path}" - return_files.append(RemoteFile(local_path=x, remote_path=remote_url)) + use_original_remote_path: bool = ( + local_to_remote_path_mapping is not None + and x in local_to_remote_path_mapping + ) + + if use_original_remote_path: + remote_path = local_to_remote_path_mapping.get(x) + + remote_url = ( + urlparse(str(remote_path))._replace(scheme="latch").geturl() + ) + + if not use_original_remote_path: + return_files.append( + RemoteFile(local_path=x, remote_path=remote_url) + ) + literals[param] = Literal( scalar=Scalar( blob=Blob( @@ -347,6 +370,13 @@ def get_fn_code( code_block = "" code_block += self.get_fn_interface(fn_name=task_name) + code_block += reindent( + r""" + local_to_remote_path_mapping = {} + """, + 1, + ) + for param, t in self.python_interface.inputs.items(): if t in (LatchFile, LatchDir): param_meta = self.parameter_metadata[param] @@ -383,6 +413,8 @@ def get_fn_code( {param}_dst_p ) + update_mapping({param}_dst_p, {param}.remote_path, local_to_remote_path_mapping) + """, 1, ) @@ -408,7 +440,7 @@ def get_fn_code( exec_id_hash.update(os.environ["FLYTE_INTERNAL_EXECUTION_ID"].encode("utf-8")) version = exec_id_hash.hexdigest()[:16] - wf = extract_snakemake_workflow(pkg_root, snakefile, version) + wf = extract_snakemake_workflow(pkg_root, snakefile, version, local_to_remote_path_mapping) wf_name = wf.name generate_snakemake_entrypoint(wf, pkg_root, snakefile, {repr(remote_output_url)}) @@ -583,7 +615,7 @@ class _WorkflowInfoNode(TypedDict): _interface_request = { "workflow_id": wf_id, "params": params, - "snakemake_jit": True, + # "snakemake_jit": True, } response = requests.post(urljoin(config.nucleus_url, "/api/create-execution"), headers=headers, json=_interface_request) @@ -600,6 +632,7 @@ def __init__( self, dag: DAG, version: Optional[str] = None, + local_to_remote_path_mapping: Optional[Dict[str, str]] = None, ): assert metadata._snakemake_metadata is not None name = metadata._snakemake_metadata.name @@ -607,7 +640,10 @@ def __init__( assert name is not None native_interface, literal_map, return_files = snakemake_dag_to_interface( - dag, name, None + dag, + name, + None, + local_to_remote_path_mapping, ) self.literal_map = literal_map self.return_files = return_files From 2ecdf9f7fd11b1602e11d3b1f02b83c4b6e0f99a Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Tue, 17 Oct 2023 16:29:55 -0700 Subject: [PATCH 319/356] dur Signed-off-by: Ayush Kamat --- latch_cli/snakemake/config/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latch_cli/snakemake/config/utils.py b/latch_cli/snakemake/config/utils.py index d3ab7785..d0d05cd5 100644 --- a/latch_cli/snakemake/config/utils.py +++ b/latch_cli/snakemake/config/utils.py @@ -96,7 +96,7 @@ def dataclass_repr(typ: Type) -> str: def get_preamble(typ: Type) -> str: - if typ in {str, int, bool}: + if is_primitive_type(typ): return "" if get_origin(typ) in {Union, list}: From f43d5ffa3ff4ff859c33cb1712a42547fd88b49e Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Tue, 17 Oct 2023 16:44:52 -0700 Subject: [PATCH 320/356] fixies Signed-off-by: Ayush Kamat --- latch_cli/snakemake/config/utils.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/latch_cli/snakemake/config/utils.py b/latch_cli/snakemake/config/utils.py index d0d05cd5..34231f82 100644 --- a/latch_cli/snakemake/config/utils.py +++ b/latch_cli/snakemake/config/utils.py @@ -8,11 +8,14 @@ from latch.types.file import LatchFile from latch_cli.utils import identifier_suffix_from_str -JSONValue: TypeAlias = Union[int, str, bool, float, List["JSONValue"], "JSONDict"] +JSONValue: TypeAlias = Union[int, str, bool, float, None, List["JSONValue"], "JSONDict"] JSONDict: TypeAlias = Dict[str, "JSONValue"] def parse_type(v: JSONValue, name: Optional[str] = None) -> Type: + if v is None: + return str + if is_primitive_value(v): return type(v) From 3595ff0acfd1c6150bbbca6fc72711f08cb620b7 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Wed, 18 Oct 2023 10:54:34 -0700 Subject: [PATCH 321/356] save state Signed-off-by: Ayush Kamat --- latch/types/metadata.py | 6 +++-- latch_cli/snakemake/config/parser.py | 28 ++++++++--------------- latch_cli/snakemake/config/utils.py | 33 +++++++--------------------- 3 files changed, 21 insertions(+), 46 deletions(-) diff --git a/latch/types/metadata.py b/latch/types/metadata.py index 0f99697f..d795631a 100644 --- a/latch/types/metadata.py +++ b/latch/types/metadata.py @@ -1,9 +1,10 @@ import re -from dataclasses import asdict, dataclass, field +from dataclasses import Field, asdict, dataclass, field from enum import Enum from pathlib import Path from textwrap import indent from typing import ( + Any, ClassVar, Dict, Generic, @@ -348,10 +349,11 @@ def dict(self): # https://stackoverflow.com/questions/54668000/type-hint-for-an-instance-of-a-non-specific-dataclass class _IsDataclass(Protocol): - __dataclass_fields__: ClassVar[Dict] + __dataclass_fields__: ClassVar[Dict[str, Field[Any]]] ParameterType: TypeAlias = Union[ + Type[None], Type[int], Type[float], Type[str], diff --git a/latch_cli/snakemake/config/parser.py b/latch_cli/snakemake/config/parser.py index 67d8572d..ec01cfca 100644 --- a/latch_cli/snakemake/config/parser.py +++ b/latch_cli/snakemake/config/parser.py @@ -1,36 +1,26 @@ from pathlib import Path -from typing import Dict, Type +from typing import Dict, List, Type import click import yaml from latch_cli.snakemake.workflow import reindent -from latch_cli.utils import identifier_suffix_from_str +from latch_cli.utils import identifier_from_str -from .utils import * +from .utils import JSONValue, get_preamble, parse_type, type_repr def parse_config(config_path: Path) -> Dict[str, Type]: if not config_path.exists(): click.secho( - reindent( - f""" - No config file found at {config_path}. - """, - 0, - ), + f"No config file found at {config_path}.", fg="red", ) raise click.exceptions.Exit(1) if config_path.is_dir(): click.secho( - reindent( - f""" - Path {config_path} points to a directory. - """, - 0, - ), + f"Path {config_path} points to a directory.", fg="red", ) raise click.exceptions.Exit(1) @@ -57,7 +47,7 @@ def parse_config(config_path: Path) -> Dict[str, Type]: parsed: Dict[str, Type] = {} for k, v in res.items(): - parsed[k] = parse_type(v, identifier_suffix_from_str(k)) + parsed[k] = parse_type(v, k) return parsed @@ -65,15 +55,15 @@ def parse_config(config_path: Path) -> Dict[str, Type]: def generate_metadata(config_path: Path): parsed = parse_config(config_path) - preambles = [] - params = [] + preambles: List[str] = [] + params: List[str] = [] for k, typ in parsed.items(): preambles.append(get_preamble(typ)) params.append( reindent( f"""\ - {repr(k)}: SnakemakeParameter( + {repr(identifier_from_str(k))}: SnakemakeParameter( display_name={repr(k)}, type={type_repr(typ)}, ),""", diff --git a/latch_cli/snakemake/config/utils.py b/latch_cli/snakemake/config/utils.py index 34231f82..7d396d72 100644 --- a/latch_cli/snakemake/config/utils.py +++ b/latch_cli/snakemake/config/utils.py @@ -6,7 +6,7 @@ from latch.types.directory import LatchDir from latch.types.file import LatchFile -from latch_cli.utils import identifier_suffix_from_str +from latch_cli.utils import identifier_from_str JSONValue: TypeAlias = Union[int, str, bool, float, None, List["JSONValue"], "JSONDict"] JSONDict: TypeAlias = Dict[str, "JSONValue"] @@ -28,38 +28,21 @@ def parse_type(v: JSONValue, name: Optional[str] = None) -> Type: if name is None: name = "SnakemakeRecord" - fields = {} + fields: Dict[str, Type] = {} for k, x in v.items(): - fields[identifier_suffix_from_str(k)] = parse_type( - x, identifier_suffix_from_str(k) - ) + fields[identifier_from_str(k)] = parse_type(x, k) - return make_dataclass(name, fields.items()) + return make_dataclass(identifier_from_str(name), fields.items()) def is_primitive_type( typ: Type, -) -> TypeGuard[Union[Type[str], Type[bool], Type[int], Type[float]]]: - return _is_primitive(t=typ) - - -def is_primitive_value( - val: Any, -) -> TypeGuard[Union[str, bool, int, float]]: - return _is_primitive(v=val) - - -def _is_primitive( - *, - t: Optional[Type] = None, - v: Optional[Any] = None, -) -> bool: - if v is not None: - t = type(v) +) -> TypeGuard[Union[Type[None], Type[str], Type[bool], Type[int], Type[float]]]: + return typ in {Type[None], str, bool, int, float} - assert t is not None - return t in {str, bool, int, float} +def is_primitive_value(val: object) -> TypeGuard[Union[None, str, bool, int, float]]: + return is_primitive_type(type(val)) def type_repr(t: Type, *, add_namespace: bool = False) -> str: From 219167611b7d6cec226a5856c47087e1308c8d39 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Wed, 18 Oct 2023 13:03:36 -0700 Subject: [PATCH 322/356] copy snakemake entrypoint if it exists in all dockerfiles Signed-off-by: Ayush Kamat --- latch_cli/docker_utils/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/latch_cli/docker_utils/__init__.py b/latch_cli/docker_utils/__init__.py index 3bf3c607..5b64c607 100644 --- a/latch_cli/docker_utils/__init__.py +++ b/latch_cli/docker_utils/__init__.py @@ -379,7 +379,9 @@ def generate_dockerfile( block.write_block(f) f.write("# Copy workflow data (use .dockerignore to skip files)\n") - f.write("copy . /root/\n\n") + + # this will only copy the snakemake entrypoint (if it exists) due to .dockerignore + f.write("copy . .latch/* /root/\n\n") for block in commands: if block.order != DockerCmdBlockOrder.postcopy: From 2d1265e1185c09794791403228e1010278b4941f Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Fri, 20 Oct 2023 10:25:04 -0700 Subject: [PATCH 323/356] disable defaults for now Signed-off-by: Ayush Kamat --- latch/types/metadata.py | 2 + latch_cli/main.py | 13 ++- latch_cli/snakemake/config/parser.py | 139 ++++++++++++++++++++------- latch_cli/snakemake/config/utils.py | 27 ++++++ latch_cli/snakemake/serialize.py | 27 +----- latch_cli/utils/__init__.py | 14 +++ 6 files changed, 163 insertions(+), 59 deletions(-) diff --git a/latch/types/metadata.py b/latch/types/metadata.py index d795631a..102961c0 100644 --- a/latch/types/metadata.py +++ b/latch/types/metadata.py @@ -370,6 +370,8 @@ class SnakemakeParameter(LatchParameter): """ The python type of the parameter. """ + # todo(ayush): unused rn, needs to be typed properly + default: Optional[Any] = None @dataclass diff --git a/latch_cli/main.py b/latch_cli/main.py index a046d905..a2f5fa85 100644 --- a/latch_cli/main.py +++ b/latch_cli/main.py @@ -398,12 +398,21 @@ def ls(paths: Tuple[str], group_directories_first: bool): @main.command("generate-metadata") @click.argument("config_file", nargs=1, type=click.Path(exists=True, path_type=Path)) -def generate_metadata(config_file: Path): +@click.option( + "--yes", + "-y", + is_flag=True, + default=False, + help=( + "Overwrite an existing `latch_metadata_parameters.py` file without confirming." + ), +) +def generate_metadata(config_file: Path, yes: bool): """Generate a `latch_metadata.py` file from a Snakemake config file""" from latch_cli.snakemake.config.parser import generate_metadata - generate_metadata(config_file) + generate_metadata(config_file, skip_confirmation=yes) @main.command("launch") diff --git a/latch_cli/snakemake/config/parser.py b/latch_cli/snakemake/config/parser.py index ec01cfca..42da2208 100644 --- a/latch_cli/snakemake/config/parser.py +++ b/latch_cli/snakemake/config/parser.py @@ -1,5 +1,5 @@ from pathlib import Path -from typing import Dict, List, Type +from typing import Dict, List, Tuple, Type, TypeVar import click import yaml @@ -7,10 +7,12 @@ from latch_cli.snakemake.workflow import reindent from latch_cli.utils import identifier_from_str -from .utils import JSONValue, get_preamble, parse_type, type_repr +from .utils import JSONValue, get_preamble, parse_type, parse_value, type_repr +T = TypeVar("T") -def parse_config(config_path: Path) -> Dict[str, Type]: + +def parse_config(config_path: Path) -> Dict[str, Tuple[Type[T], T]]: if not config_path.exists(): click.secho( f"No config file found at {config_path}.", @@ -42,62 +44,133 @@ def parse_config(config_path: Path) -> Dict[str, Type]: raise click.exceptions.Exit(1) from e if not isinstance(res, dict): - # todo(ayush): think more about correct behavior for pathological .yaml files - return {"snakemake_parameter": res} + # ayush: this case doesn't matter bc a non-dict .yaml file isn't valid snakemake + return {"snakemake_parameter": (parse_type(res), res)} parsed: Dict[str, Type] = {} for k, v in res.items(): - parsed[k] = parse_type(v, k) + typ = parse_type(v, k) + val = parse_value(typ, v) + + parsed[k] = (typ, val) return parsed -def generate_metadata(config_path: Path): +def generate_metadata( + config_path: Path, + *, + skip_confirmation: bool = False, + generate_defaults: bool = False, +): parsed = parse_config(config_path) preambles: List[str] = [] params: List[str] = [] - for k, typ in parsed.items(): + for k, (typ, val) in parsed.items(): preambles.append(get_preamble(typ)) - params.append( + + param = reindent( + f"""\ + {repr(identifier_from_str(k))}: SnakemakeParameter( + display_name={repr(k)}, + type={type_repr(typ)}, + __default__),""", + 0, + ) + + default = "" + if generate_defaults: + default = f" default={repr(val)},\n" + + param = param.replace("__default__", default) + param = reindent(param, 1) + + params.append(param) + + metadata_root = Path("latch_metadata") + if metadata_root.is_file(): + if not click.confirm("A file exists at `latch_metadata`. Delete it?"): + raise click.exceptions.Exit(0) + + metadata_root.unlink() + + metadata_root.mkdir(exist_ok=True) + + metadata_path = metadata_root / Path("__init__.py") + old_metadata_path = Path("latch_metadata.py") + + if old_metadata_path.exists() and not metadata_path.exists(): + if click.confirm( + "Found legacy `latch_metadata.py` file in current directory. This is" + " deprecated and will be ignored in future releases. Move to" + " `latch_metadata/__init__.py`? (This will not change file contents)" + ): + old_metadata_path.rename(metadata_path) + elif old_metadata_path.exists() and metadata_path.exists(): + # todo(ayush): seems like python path-based import hooks seem to choose the + # package latch_metadata/__init__.py over latch_metadata.py + # + # Couldn't find this documented anywhere - is this a CPython implementation detail? + click.secho( + "Warning: Found both `latch_metadata.py` and `latch_metadata/__init__.py`" + " in current directory. `latch_metadata.py` will be ignored.", + fg="yellow", + ) + + if not metadata_path.exists() and click.confirm( + "Could not find an `__init__.py` file in `latch_metadata`. Generate one?" + ): + metadata_path.write_text( reindent( - f"""\ - {repr(identifier_from_str(k))}: SnakemakeParameter( - display_name={repr(k)}, - type={type_repr(typ)}, - ),""", - 2, + r""" + from latch.types.metadata import SnakemakeMetadata, LatchAuthor + from latch.types.directory import LatchDir + + from .parameters import generated_parameters + + SnakemakeMetadata( + output_dir=LatchDir("latch:///your_output_directory"), + display_name="Your Workflow Name", + author=LatchAuthor( + name="Your Name", + ), + # Add more parameters + parameters=generated_parameters, + ) + """, + 0, ) ) - metadata_path = Path("latch_metadata.py") - if metadata_path.exists() and not click.confirm( - "File `latch_metadata.py` already exists. Overwrite?" + params_path = metadata_root / Path("parameters.py") + if ( + params_path.exists() + and not skip_confirmation + and not click.confirm( + "File `latch_metadata/parameters.py` already exists. Overwrite?" + ) ): - return + raise click.exceptions.Exit(0) - metadata_path.write_text( + params_path.write_text( reindent( - f""" + r""" from dataclasses import dataclass import typing - from latch.types.metadata import SnakemakeParameter, SnakemakeMetadata, LatchAuthor - from latch.types.directory import LatchDir - from latch.types.file import LatchFile + from latch.types.metadata import SnakemakeParameter __preambles__ - SnakemakeMetadata( - output_dir=LatchDir("latch:///your_output_directory"), - display_name="Your Workflow Name", - author=LatchAuthor( - name="Your Name", - ), - parameters={{ + + # Import these into your `__init__.py` file: + # + # from .parameters import generated_parameters + # + generated_parameters = { __params__ - }}, - ) + } """, 0, ) diff --git a/latch_cli/snakemake/config/utils.py b/latch_cli/snakemake/config/utils.py index 7d396d72..c28ee0bd 100644 --- a/latch_cli/snakemake/config/utils.py +++ b/latch_cli/snakemake/config/utils.py @@ -35,6 +35,33 @@ def parse_type(v: JSONValue, name: Optional[str] = None) -> Type: return make_dataclass(identifier_from_str(name), fields.items()) +def parse_value(t: Type, v: JSONValue): + if is_primitive_value(v): + return v + + if isinstance(v, list): + assert get_origin(t) is list + + sub_type = get_args(t)[0] + + return [parse_value(sub_type, x) for x in v] + + assert isinstance(v, dict), v + assert is_dataclass(t), t + + ret = {} + fs = {identifier_from_str(f.name): f for f in fields(t)} + + print(fs) + for k, x in v.items(): + sanitized = identifier_from_str(k) + assert sanitized in fs, sanitized + + ret[sanitized] = parse_value(fs[sanitized].type, x) + + return t(**ret) + + def is_primitive_type( typ: Type, ) -> TypeGuard[Union[Type[None], Type[str], Type[bool], Type[int], Type[float]]]: diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index 16064ff9..234d6374 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -333,21 +333,11 @@ def generate_snakemake_entrypoint( from latch.types.directory import LatchDir from latch.types.file import LatchFile + from latch_cli.utils import get_parameter_json_value + sys.stdout.reconfigure(line_buffering=True) sys.stderr.reconfigure(line_buffering=True) - def get_parameter_json_value(v): - if is_dataclass(v): - return asdict(v) - elif isinstance(v, Enum): - return v.value - elif isinstance(v, list): - return [get_parameter_json_value(x) for x in v] - elif isinstance(v, dict): - return {k: get_parameter_json_value(x) for k, x in v.items()} - else: - return v - def check_exists_and_rename(old: Path, new: Path): if new.exists(): print(f"A file already exists at {new} and will be overwritten.") @@ -436,6 +426,7 @@ def generate_jit_register_code( generate_snakemake_entrypoint, serialize_snakemake, ) + from latch_cli.utils import get_parameter_json_value import latch_cli.snakemake from latch import small_task @@ -448,18 +439,6 @@ def generate_jit_register_code( sys.stdout.reconfigure(line_buffering=True) sys.stderr.reconfigure(line_buffering=True) - def get_parameter_json_value(v): - if is_dataclass(v): - return asdict(v) - elif isinstance(v, Enum): - return v.value - elif isinstance(v, list): - return [get_parameter_json_value(x) for x in v] - elif isinstance(v, dict): - return {k: get_parameter_json_value(x) for k, x in v.items()} - else: - return v - def check_exists_and_rename(old: Path, new: Path): if new.exists(): print(f"A file already exists at {new} and will be overwritten.") diff --git a/latch_cli/utils/__init__.py b/latch_cli/utils/__init__.py index 884cdc77..d4e4f044 100644 --- a/latch_cli/utils/__init__.py +++ b/latch_cli/utils/__init__.py @@ -5,6 +5,7 @@ import stat import subprocess import urllib.parse +from dataclasses import asdict, is_dataclass from datetime import datetime, timedelta from enum import Enum from pathlib import Path @@ -384,3 +385,16 @@ def identifier_suffix_from_str(x: str) -> str: def identifier_from_str(x: str) -> str: return (x[0] if x[0].isidentifier() else "_") + identifier_suffix_from_str(x[1:]) + + +def get_parameter_json_value(v): + if is_dataclass(v): + return asdict(v) + elif isinstance(v, Enum): + return v.value + elif isinstance(v, list): + return [get_parameter_json_value(x) for x in v] + elif isinstance(v, dict): + return {k: get_parameter_json_value(x) for k, x in v.items()} + else: + return v From ae9aee916cbbc030c20abcf531f1d9f956b6355d Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Fri, 20 Oct 2023 12:06:41 -0700 Subject: [PATCH 324/356] compatible woot Signed-off-by: Ayush Kamat --- latch_cli/centromere/ctx.py | 28 +++++++++++++++++++--------- latch_cli/services/register/utils.py | 6 ++++-- latch_cli/snakemake/config/utils.py | 1 - latch_cli/snakemake/serialize.py | 15 +++++++++++---- latch_cli/snakemake/workflow.py | 2 +- 5 files changed, 35 insertions(+), 17 deletions(-) diff --git a/latch_cli/centromere/ctx.py b/latch_cli/centromere/ctx.py index e16f290b..694dc85a 100644 --- a/latch_cli/centromere/ctx.py +++ b/latch_cli/centromere/ctx.py @@ -141,10 +141,18 @@ def __init__( snakemake_workflow_extractor, ) - meta = pkg_root / "latch_metadata.py" - if meta.exists(): - click.echo(f"Using metadata file {click.style(meta, italic=True)}") - import_module_by_path(meta) + new_meta = pkg_root / "latch_metadata" / "__init__.py" + old_meta = pkg_root / "latch_metadata.py" + if new_meta.exists(): + click.echo( + f"Using metadata file {click.style(new_meta, italic=True)}" + ) + import_module_by_path(new_meta) + elif old_meta.exists(): + click.echo( + f"Using metadata file {click.style(old_meta, italic=True)}" + ) + import_module_by_path(old_meta) else: click.echo("Trying to extract metadata from the Snakefile") try: @@ -171,7 +179,7 @@ def __init__( snakemake_metadata_example = get_snakemake_metadata_example( pkg_root.name ) - click.secho(f"`{meta}`", bold=True, fg="red", nl=False) + click.secho(f"`{new_meta}`", bold=True, fg="red", nl=False) click.secho( f" file:\n```\n{snakemake_metadata_example}```", fg="red", @@ -184,7 +192,7 @@ def __init__( ), default=True, ): - meta.write_text(snakemake_metadata_example) + new_meta.write_text(snakemake_metadata_example) import platform @@ -202,13 +210,15 @@ def __init__( import subprocess if system == "Linux": - res = subprocess.run(["xdg-open", meta]).returncode + res = subprocess.run( + ["xdg-open", new_meta] + ).returncode elif system == "Darwin": - res = subprocess.run(["open", meta]).returncode + res = subprocess.run(["open", new_meta]).returncode elif system == "Windows": import os - res = os.system(str(meta.resolve())) + res = os.system(str(new_meta.resolve())) else: res = None diff --git a/latch_cli/services/register/utils.py b/latch_cli/services/register/utils.py index 2ef8fa65..148f8ea7 100644 --- a/latch_cli/services/register/utils.py +++ b/latch_cli/services/register/utils.py @@ -1,5 +1,6 @@ import base64 import contextlib +import importlib.machinery as im import importlib.util as iu import io import os @@ -179,12 +180,13 @@ def register_serialized_pkg( return response.json() -def import_module_by_path(x: Path): - spec = iu.spec_from_file_location("metadata", x) +def import_module_by_path(x: Path, *, module_name: str = "latch_metadata"): + spec = iu.spec_from_file_location(module_name, x) assert spec is not None assert spec.loader is not None module = iu.module_from_spec(spec) + sys.modules[module_name] = module spec.loader.exec_module(module) return module diff --git a/latch_cli/snakemake/config/utils.py b/latch_cli/snakemake/config/utils.py index c28ee0bd..b752cbfe 100644 --- a/latch_cli/snakemake/config/utils.py +++ b/latch_cli/snakemake/config/utils.py @@ -52,7 +52,6 @@ def parse_value(t: Type, v: JSONValue): ret = {} fs = {identifier_from_str(f.name): f for f in fields(t)} - print(fs) for k, x in v.items(): sanitized = identifier_from_str(k) assert sanitized in fs, sanitized diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index 0d9e8969..37594edf 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -170,9 +170,13 @@ def snakemake_workflow_extractor( ) -> SnakemakeWorkflowExtractor: snakefile = snakefile.resolve() - meta = pkg_root / "latch_metadata.py" - if meta.exists(): - import_module_by_path(meta) + new_meta = pkg_root / "latch_metadata" / "__init__.py" + if new_meta.exists(): + import_module_by_path(new_meta) + + old_meta = pkg_root / "latch_metadata.py" + if old_meta.exists(): + import_module_by_path(old_meta) extractor = SnakemakeWorkflowExtractor( pkg_root=pkg_root, @@ -446,7 +450,10 @@ def generate_jit_register_code( from latch.types.directory import LatchDir from latch.types.file import LatchFile - import latch_metadata + try: + import latch_metadata.parameters as latch_metadata + except ImportError: + import latch_metadata sys.stdout.reconfigure(line_buffering=True) sys.stderr.reconfigure(line_buffering=True) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 86a815a8..807f78ef 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -629,7 +629,7 @@ class _WorkflowInfoNode(TypedDict): _interface_request = { "workflow_id": wf_id, "params": params, - # "snakemake_jit": True, + "snakemake_jit": True, } response = requests.post(urljoin(config.nucleus_url, "/api/create-execution"), headers=headers, json=_interface_request) From de62e43b254c4b1cb85894e94f7a46749475a814 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Fri, 20 Oct 2023 13:21:31 -0700 Subject: [PATCH 325/356] support remote register --- latch_cli/services/register/register.py | 34 +++++++++++++------------ 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index f72a7e92..6aa3be9d 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -172,8 +172,10 @@ def _print_reg_resp(resp, image): sys.exit(1) elif not "Successfully registered file" in resp["stdout"]: click.secho( - f"\nVersion ({version}) already exists." - " Make sure that you've saved any changes you made.", + ( + f"\nVersion ({version}) already exists." + " Make sure that you've saved any changes you made." + ), fg="red", bold=True, ) @@ -317,14 +319,6 @@ def register( """ if snakefile is not None: - if remote: - click.secho( - "Cannot use remote builds with Snakemake, switching to a local build\n", - fg="yellow", - bold=True, - ) - remote = False - try: import snakemake except ImportError as e: @@ -411,7 +405,11 @@ def register( scp = SCPClient(transport=transport, sanitize=lambda x: x) with contextlib.ExitStack() as stack: - td: str = stack.enter_context(MaybeRemoteDir(ctx.ssh_client)) + # We serialize locally with snakemake projects + remote_dir_client = None + if snakefile is None: + remote_dir_client = ctx.ssh_client + td: str = stack.enter_context(MaybeRemoteDir(remote_dir_client)) _build_and_serialize( ctx, ctx.default_container.image_name, @@ -421,7 +419,7 @@ def register( progress_plain=progress_plain, ) - if remote: + if remote and snakefile is None: local_td = Path(stack.enter_context(tempfile.TemporaryDirectory())) assert scp is not None @@ -524,8 +522,10 @@ def register( fg="red", ) click.secho( - "If the workflow is not visible in latch console, contact" - " support.", + ( + "If the workflow is not visible in latch console, contact" + " support." + ), fg="red", ) break @@ -535,8 +535,10 @@ def register( if len(wf_infos) > 0: if len(wf_infos) > 1: click.secho( - f"Worfklow {ctx.workflow_name}:{ctx.version} is not unique. The" - " link below might be wrong.", + ( + f"Worfklow {ctx.workflow_name}:{ctx.version} is not unique." + " The link below might be wrong." + ), fg="yellow", ) From 8dc511454e1647ad8469b75cd766fe31634ad955 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Fri, 20 Oct 2023 13:53:04 -0700 Subject: [PATCH 326/356] add file inference at the top level Signed-off-by: Ayush Kamat --- latch/types/metadata.py | 4 + latch_cli/snakemake/config/parser.py | 45 +++++++---- latch_cli/snakemake/config/utils.py | 109 +++++++++++++++++++++++++-- latch_cli/snakemake/workflow.py | 27 ++++--- 4 files changed, 155 insertions(+), 30 deletions(-) diff --git a/latch/types/metadata.py b/latch/types/metadata.py index 102961c0..6c8dcb0f 100644 --- a/latch/types/metadata.py +++ b/latch/types/metadata.py @@ -389,6 +389,10 @@ class SnakemakeFileParameter(SnakemakeParameter): """ The path where the file passed to this parameter will be copied. """ + config: bool = False + """ + Whether or not the file path is exposed in the Snakemake config + """ @dataclass diff --git a/latch_cli/snakemake/config/parser.py b/latch_cli/snakemake/config/parser.py index 42da2208..b9b4603d 100644 --- a/latch_cli/snakemake/config/parser.py +++ b/latch_cli/snakemake/config/parser.py @@ -4,6 +4,8 @@ import click import yaml +from latch.types.directory import LatchDir +from latch.types.file import LatchFile from latch_cli.snakemake.workflow import reindent from latch_cli.utils import identifier_from_str @@ -12,7 +14,11 @@ T = TypeVar("T") -def parse_config(config_path: Path) -> Dict[str, Tuple[Type[T], T]]: +def parse_config( + config_path: Path, + *, + infer_files: bool = False, +) -> Dict[str, Tuple[Type[T], T]]: if not config_path.exists(): click.secho( f"No config file found at {config_path}.", @@ -45,11 +51,11 @@ def parse_config(config_path: Path) -> Dict[str, Tuple[Type[T], T]]: if not isinstance(res, dict): # ayush: this case doesn't matter bc a non-dict .yaml file isn't valid snakemake - return {"snakemake_parameter": (parse_type(res), res)} + return {"snakemake_parameter": (parse_type(res, infer_files=infer_files), res)} parsed: Dict[str, Type] = {} for k, v in res.items(): - typ = parse_type(v, k) + typ = parse_type(v, k, infer_files=infer_files) val = parse_value(typ, v) parsed[k] = (typ, val) @@ -62,8 +68,9 @@ def generate_metadata( *, skip_confirmation: bool = False, generate_defaults: bool = False, + infer_files: bool = False, ): - parsed = parse_config(config_path) + parsed = parse_config(config_path, infer_files=infer_files) preambles: List[str] = [] params: List[str] = [] @@ -71,23 +78,31 @@ def generate_metadata( for k, (typ, val) in parsed.items(): preambles.append(get_preamble(typ)) - param = reindent( + is_file = typ in {LatchFile, LatchDir} + param_typ = "SnakemakeFileParameter" if is_file else "SnakemakeParameter" + param_str = reindent( f"""\ - {repr(identifier_from_str(k))}: SnakemakeParameter( + {repr(identifier_from_str(k))}: {param_typ}( display_name={repr(k)}, type={type_repr(typ)}, - __default__),""", + __config____default__),""", 0, ) + config = "" + if is_file: + config = " config=True,\n" + + param_str = param_str.replace("__config__", config) + default = "" - if generate_defaults: + if generate_defaults and val is not None: default = f" default={repr(val)},\n" - param = param.replace("__default__", default) - param = reindent(param, 1) + param_str = param_str.replace("__default__", default) - params.append(param) + param_str = reindent(param_str, 1) + params.append(param_str) metadata_root = Path("latch_metadata") if metadata_root.is_file(): @@ -109,10 +124,6 @@ def generate_metadata( ): old_metadata_path.rename(metadata_path) elif old_metadata_path.exists() and metadata_path.exists(): - # todo(ayush): seems like python path-based import hooks seem to choose the - # package latch_metadata/__init__.py over latch_metadata.py - # - # Couldn't find this documented anywhere - is this a CPython implementation detail? click.secho( "Warning: Found both `latch_metadata.py` and `latch_metadata/__init__.py`" " in current directory. `latch_metadata.py` will be ignored.", @@ -160,7 +171,9 @@ def generate_metadata( from dataclasses import dataclass import typing - from latch.types.metadata import SnakemakeParameter + from latch.types.metadata import SnakemakeParameter, SnakemakeFileParameter + from latch.types.file import LatchFile + from latch.types.directory import LatchDir __preambles__ diff --git a/latch_cli/snakemake/config/utils.py b/latch_cli/snakemake/config/utils.py index b752cbfe..b9768d46 100644 --- a/latch_cli/snakemake/config/utils.py +++ b/latch_cli/snakemake/config/utils.py @@ -11,16 +11,106 @@ JSONValue: TypeAlias = Union[int, str, bool, float, None, List["JSONValue"], "JSONDict"] JSONDict: TypeAlias = Dict[str, "JSONValue"] - -def parse_type(v: JSONValue, name: Optional[str] = None) -> Type: +# ayush: yoinked from console +valid_extensions = { + "vcf", + "css", + "csv", + "gif", + "png", + "pdf", + "webp", + "xhtml", + "xlsx", + "xml", + "py", + "log", + "json", + "gz", + "mmtf", + "deseqreport", + "sam", + "bam", + "cram", + "tsv", + "tab", + "sf", + "txt", + "text", + "license", + "readme", + "r", + "rscript", + "md", + "markdown", + "markdn", + "mdown", + "htm", + "html", + "ipynb", + "jpeg", + "jpg", + "jif", + "jpe", + "jfif", + "js", + "mjs", + "es", + "ts", + "jsx", + "tsx", + "svg", + "svgz", + "fasta", + "fna", + "fa", + "ffn", + "faa", + "frn", + "fastq", + "fq", + "pdb", + "pdb1", + "ent", + "brk", + "ml2", + "mol2", + "sy2", + "hdf", + "h4", + "hdf4", + "he4", + "h5", + "hdf5", + "he5", + "h5ad", +} + + +def parse_type( + v: JSONValue, name: Optional[str] = None, *, infer_files: bool = False +) -> Type: if v is None: return str + if infer_files and isinstance(v, str): + if any([v.endswith(ext) for ext in valid_extensions]): + return LatchFile + elif v.endswith("/"): + return LatchDir + if is_primitive_value(v): return type(v) if isinstance(v, list): - parsed_types = tuple(parse_type(x) for x in v) + parsed_types = tuple( + parse_type( + x, + name, + infer_files=False, # todo(ayush): enable recursive file inference + ) + for x in v + ) return List[Union[parsed_types]] assert isinstance(v, dict) @@ -30,12 +120,21 @@ def parse_type(v: JSONValue, name: Optional[str] = None) -> Type: fields: Dict[str, Type] = {} for k, x in v.items(): - fields[identifier_from_str(k)] = parse_type(x, k) + fields[identifier_from_str(k)] = parse_type( + x, + k, + infer_files=False, # todo(ayush): enable recursive file inference + ) return make_dataclass(identifier_from_str(name), fields.items()) def parse_value(t: Type, v: JSONValue): + if t in {LatchFile, LatchDir}: + # ayush: autogenerated defaults don't make sense for files/dirs since their + # value in the config is their local path + return None + if is_primitive_value(v): return v @@ -108,7 +207,7 @@ def dataclass_repr(typ: Type) -> str: def get_preamble(typ: Type) -> str: - if is_primitive_type(typ): + if is_primitive_type(typ) or typ in {LatchFile, LatchDir}: return "" if get_origin(typ) in {Union, list}: diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 807f78ef..2535aa6b 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -386,8 +386,9 @@ def get_fn_code( ) for param, t in self.python_interface.inputs.items(): + param_meta = self.parameter_metadata[param] + if t in (LatchFile, LatchDir): - param_meta = self.parameter_metadata[param] assert isinstance(param_meta, metadata.SnakemakeFileParameter) code_block += reindent( @@ -426,14 +427,22 @@ def get_fn_code( """, 1, ) - else: - code_block += reindent( - rf""" - print(f"Saving parameter value {param} = {{get_parameter_json_value({param})}}") - non_blob_parameters[{repr(param)}] = get_parameter_json_value({param}) - """, - 1, - ) + + if not getattr(param_meta, "config", True): + continue + + val_str = f"get_parameter_json_value({param})" + if hasattr(param_meta, "path"): + val_str = repr(str(param_meta.path)) + + code_block += reindent( + rf""" + print(f"Saving parameter value {param} = {{{val_str}}}") + non_blob_parameters[{repr(param)}] = {val_str} + + """, + 1, + ) code_block += reindent( rf""" From 8679500a6f6d0d76f01b375632a3fbbc9e105787 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Fri, 20 Oct 2023 13:54:18 -0700 Subject: [PATCH 327/356] add todo Signed-off-by: Ayush Kamat --- latch_cli/snakemake/single_task_snakemake.py | 1 + 1 file changed, 1 insertion(+) diff --git a/latch_cli/snakemake/single_task_snakemake.py b/latch_cli/snakemake/single_task_snakemake.py index b757158e..505392af 100644 --- a/latch_cli/snakemake/single_task_snakemake.py +++ b/latch_cli/snakemake/single_task_snakemake.py @@ -40,6 +40,7 @@ def eprint(x: str) -> None: non_blob_parameters = data.get("non_blob_parameters", {}) +# todo(ayush): do this without overwriting globals sw = sys.modules["snakemake.workflow"] setattr(sw, "config", non_blob_parameters) From a29420b9f79e9c6f44d5f9c214a362236d2362b2 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Fri, 20 Oct 2023 14:00:22 -0700 Subject: [PATCH 328/356] expose infer files option Signed-off-by: Ayush Kamat --- latch_cli/main.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/latch_cli/main.py b/latch_cli/main.py index a2f5fa85..7ba0ad21 100644 --- a/latch_cli/main.py +++ b/latch_cli/main.py @@ -407,12 +407,19 @@ def ls(paths: Tuple[str], group_directories_first: bool): "Overwrite an existing `latch_metadata_parameters.py` file without confirming." ), ) -def generate_metadata(config_file: Path, yes: bool): +@click.option( + "--infer-files", + "-i", + is_flag=True, + default=False, + help="Parse strings with common file extensions as file parameters", +) +def generate_metadata(config_file: Path, yes: bool, infer_files: bool): """Generate a `latch_metadata.py` file from a Snakemake config file""" from latch_cli.snakemake.config.parser import generate_metadata - generate_metadata(config_file, skip_confirmation=yes) + generate_metadata(config_file, skip_confirmation=yes, infer_files=infer_files) @main.command("launch") From 0c39331262973454b59bccda2ca373a1d0344802 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Fri, 20 Oct 2023 14:12:25 -0700 Subject: [PATCH 329/356] make file inference opt-out Signed-off-by: Ayush Kamat --- latch_cli/main.py | 12 ++++++++---- latch_cli/snakemake/config/parser.py | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/latch_cli/main.py b/latch_cli/main.py index 7ba0ad21..92dbdef2 100644 --- a/latch_cli/main.py +++ b/latch_cli/main.py @@ -408,18 +408,22 @@ def ls(paths: Tuple[str], group_directories_first: bool): ), ) @click.option( - "--infer-files", - "-i", + "--no-infer-files", + "-I", is_flag=True, default=False, help="Parse strings with common file extensions as file parameters", ) -def generate_metadata(config_file: Path, yes: bool, infer_files: bool): +def generate_metadata(config_file: Path, yes: bool, no_infer_files: bool): """Generate a `latch_metadata.py` file from a Snakemake config file""" from latch_cli.snakemake.config.parser import generate_metadata - generate_metadata(config_file, skip_confirmation=yes, infer_files=infer_files) + generate_metadata( + config_file, + skip_confirmation=yes, + infer_files=not no_infer_files, + ) @main.command("launch") diff --git a/latch_cli/snakemake/config/parser.py b/latch_cli/snakemake/config/parser.py index b9b4603d..e4e4f994 100644 --- a/latch_cli/snakemake/config/parser.py +++ b/latch_cli/snakemake/config/parser.py @@ -63,6 +63,7 @@ def parse_config( return parsed +# todo(ayush): print informative stuff here ala register def generate_metadata( config_path: Path, *, From bf7e2f90415007039f6869a274d3ad26e436c79a Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Fri, 20 Oct 2023 16:22:30 -0700 Subject: [PATCH 330/356] add defaults Signed-off-by: Ayush Kamat --- latch_cli/exceptions/traceback.py | 2 +- latch_cli/main.py | 14 +++++++-- latch_cli/snakemake/config/utils.py | 3 ++ latch_cli/snakemake/workflow.py | 48 +++++++++++++++++++---------- 4 files changed, 47 insertions(+), 20 deletions(-) diff --git a/latch_cli/exceptions/traceback.py b/latch_cli/exceptions/traceback.py index debecb2a..47608514 100644 --- a/latch_cli/exceptions/traceback.py +++ b/latch_cli/exceptions/traceback.py @@ -42,7 +42,7 @@ class _Stack: error: Optional[_HandledError] = None frames: List[_Frame] = field(default_factory=list) - def pretty_print(self, max_frames: int = 2): + def pretty_print(self, max_frames: int = 20): render_full_idx = len(self.frames) - max_frames for i, frame in enumerate(self.frames): if i < render_full_idx: diff --git a/latch_cli/main.py b/latch_cli/main.py index 92dbdef2..a60ff6c5 100644 --- a/latch_cli/main.py +++ b/latch_cli/main.py @@ -412,9 +412,18 @@ def ls(paths: Tuple[str], group_directories_first: bool): "-I", is_flag=True, default=False, - help="Parse strings with common file extensions as file parameters", + help="Don't parse strings with common file extensions as file parameters", ) -def generate_metadata(config_file: Path, yes: bool, no_infer_files: bool): +@click.option( + "--no-defaults", + "-D", + is_flag=True, + default=False, + help="Don't generate defaults for parameters.", +) +def generate_metadata( + config_file: Path, yes: bool, no_infer_files: bool, no_defaults: bool +): """Generate a `latch_metadata.py` file from a Snakemake config file""" from latch_cli.snakemake.config.parser import generate_metadata @@ -423,6 +432,7 @@ def generate_metadata(config_file: Path, yes: bool, no_infer_files: bool): config_file, skip_confirmation=yes, infer_files=not no_infer_files, + generate_defaults=not no_defaults, ) diff --git a/latch_cli/snakemake/config/utils.py b/latch_cli/snakemake/config/utils.py index b9768d46..4025a1db 100644 --- a/latch_cli/snakemake/config/utils.py +++ b/latch_cli/snakemake/config/utils.py @@ -130,6 +130,9 @@ def parse_type( def parse_value(t: Type, v: JSONValue): + if v is None: + return None + if t in {LatchFile, LatchDir}: # ayush: autogenerated defaults don't make sense for files/dirs since their # value in the config is their local path diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 2535aa6b..58462c8c 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -28,6 +28,7 @@ from flytekit.configuration import SerializationSettings from flytekit.core import constants as _common_constants from flytekit.core.class_based_resolver import ClassStorageTaskResolver +from flytekit.core.context_manager import FlyteContext, FlyteContextManager from flytekit.core.docstring import Docstring from flytekit.core.interface import Interface, transform_interface_to_typed_interface from flytekit.core.node import Node @@ -265,21 +266,26 @@ def interface_to_parameters( ) -> interface_models.ParameterMap: if interface is None or interface.inputs_with_defaults is None: return interface_models.ParameterMap({}) + if interface.docstring is None: inputs_vars = transform_types_in_variable_map(interface.inputs) else: inputs_vars = transform_types_in_variable_map( interface.inputs, interface.docstring.input_descriptions ) + params: Dict[str, interface_models.Parameter] = {} for k, v in inputs_vars.items(): val, default = interface.inputs_with_defaults[k] required = default is None default_lv = None + + ctx = FlyteContextManager.current_context() if default is not None: default_lv = TypeEngine.to_literal( - None, default, python_type=interface.inputs[k], expected=v.type + ctx, default, python_type=interface.inputs[k], expected=v.type ) + params[k] = interface_models.Parameter( var=v, default=default_lv, required=required ) @@ -303,7 +309,7 @@ def __init__( + str(metadata._snakemake_metadata) ) python_interface = Interface( - {k: v.type for k, v in parameter_metadata.items()}, + {k: (v.type, v.default) for k, v in parameter_metadata.items()}, {self.out_parameter_name: bool}, docstring=docstring, ) @@ -331,15 +337,29 @@ def get_fn_interface( if fn_name is None: fn_name = self.name - params_str = ",\n".join( - reindent( - rf""" - {param}: {type_repr(t, add_namespace=True)} - """, - 1, - ).rstrip() - for param, t in self.python_interface.inputs.items() - ) + params: List[str] = [] + for param, t in self.python_interface.inputs.items(): + meta = self.parameter_metadata[param] + + if meta.default is None: + default_str = "" + elif isinstance(meta.default, (LatchFile, LatchDir)): + default_str = f"= {meta.type.__name__}({repr(meta.default.path)})" + else: + default_str = f"= {repr(meta.default)}" + + params.append( + reindent( + rf""" + {param}: {type_repr(t, add_namespace=True)} __default__ + """, + 1, + ) + .replace("__default__", default_str) + .rstrip() + ) + + params_str = ",\n".join(params) return reindent( rf""" @@ -374,12 +394,6 @@ def get_fn_code( code_block += reindent( r""" non_blob_parameters = {} - """, - 1, - ) - - code_block += reindent( - r""" local_to_remote_path_mapping = {} """, 1, From 4d194d3f4bd2686a940be567ce668c69f667e200 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Fri, 20 Oct 2023 16:23:39 -0700 Subject: [PATCH 331/356] typos Signed-off-by: Ayush Kamat --- latch_cli/main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/latch_cli/main.py b/latch_cli/main.py index a60ff6c5..c01535bf 100644 --- a/latch_cli/main.py +++ b/latch_cli/main.py @@ -404,7 +404,7 @@ def ls(paths: Tuple[str], group_directories_first: bool): is_flag=True, default=False, help=( - "Overwrite an existing `latch_metadata_parameters.py` file without confirming." + "Overwrite an existing `latch_metadata/parameters.py` file without confirming." ), ) @click.option( @@ -412,7 +412,7 @@ def ls(paths: Tuple[str], group_directories_first: bool): "-I", is_flag=True, default=False, - help="Don't parse strings with common file extensions as file parameters", + help="Don't parse strings with common file extensions as file parameters.", ) @click.option( "--no-defaults", From 06a8c84488c92dec14f1ec0284a4300258e661f1 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Fri, 20 Oct 2023 18:29:29 -0700 Subject: [PATCH 332/356] support persistence attribute for different versions of sm --- latch_cli/snakemake/serialize.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index 37594edf..dea28125 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -124,7 +124,7 @@ def extract_dag(self): priorityfiles=set(), ) - self._persistence = Persistence(dag=dag) + self._persistence = self.persistence = Persistence(dag=dag) dag.init() dag.update_checkpoint_dependencies() From 0cb616d1a5e37c7ecf0b75a2190b12b5ad99d69e Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Sat, 21 Oct 2023 08:20:15 -0700 Subject: [PATCH 333/356] update persistence setter Signed-off-by: Ayush Kamat --- latch_cli/snakemake/serialize.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index e6e4816d..2e19db4d 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -124,7 +124,10 @@ def extract_dag(self): priorityfiles=set(), ) - self._persistence = Persistence(dag=dag) + try: + self.persistence = Persistence(dag=dag) + except AttributeError: + self._persistence = Persistence(dag=dag) dag.init() dag.update_checkpoint_dependencies() From 2ce855600ee4bc86c1690026c7fcee94d25dd5e0 Mon Sep 17 00:00:00 2001 From: Kenny Workman Date: Sat, 21 Oct 2023 10:39:09 -0700 Subject: [PATCH 334/356] better --- latch_cli/snakemake/serialize.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index dea28125..965cc85c 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -124,7 +124,11 @@ def extract_dag(self): priorityfiles=set(), ) - self._persistence = self.persistence = Persistence(dag=dag) + if hasattr(self, "persistence"): + self.persistence = Persistence(dag=dag) + else: + # snakemake version 7.30.2 introduced new attribute + self._persistence = Persistence(dag=dag) dag.init() dag.update_checkpoint_dependencies() From c0c57dcc256c84318334e583b3af051caeb107a1 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Sat, 21 Oct 2023 11:49:18 -0700 Subject: [PATCH 335/356] patch .bed Signed-off-by: Ayush Kamat --- latch_cli/snakemake/config/utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/latch_cli/snakemake/config/utils.py b/latch_cli/snakemake/config/utils.py index 4025a1db..dbd4929e 100644 --- a/latch_cli/snakemake/config/utils.py +++ b/latch_cli/snakemake/config/utils.py @@ -13,6 +13,7 @@ # ayush: yoinked from console valid_extensions = { + "bed", "vcf", "css", "csv", From 5d8c68e0be47d8c2a6f0507c763593c8f95afea8 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Sat, 21 Oct 2023 11:58:58 -0700 Subject: [PATCH 336/356] formatting, again Signed-off-by: Ayush Kamat --- latch_cli/services/register/register.py | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index 6aa3be9d..731a701c 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -172,10 +172,8 @@ def _print_reg_resp(resp, image): sys.exit(1) elif not "Successfully registered file" in resp["stdout"]: click.secho( - ( - f"\nVersion ({version}) already exists." - " Make sure that you've saved any changes you made." - ), + f"\nVersion ({version}) already exists." + " Make sure that you've saved any changes you made.", fg="red", bold=True, ) @@ -522,10 +520,8 @@ def register( fg="red", ) click.secho( - ( - "If the workflow is not visible in latch console, contact" - " support." - ), + "If the workflow is not visible in latch console, contact" + " support.", fg="red", ) break @@ -535,10 +531,8 @@ def register( if len(wf_infos) > 0: if len(wf_infos) > 1: click.secho( - ( - f"Worfklow {ctx.workflow_name}:{ctx.version} is not unique." - " The link below might be wrong." - ), + f"Worfklow {ctx.workflow_name}:{ctx.version} is not unique." + " The link below might be wrong.", fg="yellow", ) From 3e1e4ed285c63d80438ae0f4714844913739dfbb Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Sat, 21 Oct 2023 12:01:59 -0700 Subject: [PATCH 337/356] worfklow Signed-off-by: Ayush Kamat --- latch_cli/services/register/register.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latch_cli/services/register/register.py b/latch_cli/services/register/register.py index 731a701c..93704cfe 100644 --- a/latch_cli/services/register/register.py +++ b/latch_cli/services/register/register.py @@ -531,7 +531,7 @@ def register( if len(wf_infos) > 0: if len(wf_infos) > 1: click.secho( - f"Worfklow {ctx.workflow_name}:{ctx.version} is not unique." + f"Workflow {ctx.workflow_name}:{ctx.version} is not unique." " The link below might be wrong.", fg="yellow", ) From 00bf3eb3f2c5d82149ba8b07dabbe8478a2358f5 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Sat, 21 Oct 2023 12:43:49 -0700 Subject: [PATCH 338/356] add download flag Signed-off-by: Ayush Kamat --- latch/types/metadata.py | 6 +++++- latch_cli/snakemake/workflow.py | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/latch/types/metadata.py b/latch/types/metadata.py index 6c8dcb0f..1dc449d0 100644 --- a/latch/types/metadata.py +++ b/latch/types/metadata.py @@ -370,7 +370,7 @@ class SnakemakeParameter(LatchParameter): """ The python type of the parameter. """ - # todo(ayush): unused rn, needs to be typed properly + # todo(ayush): needs to be typed properly default: Optional[Any] = None @@ -393,6 +393,10 @@ class SnakemakeFileParameter(SnakemakeParameter): """ Whether or not the file path is exposed in the Snakemake config """ + download: bool = False + """ + Whether or not the file is downloaded in the JIT step + """ @dataclass diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 58462c8c..895de647 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -405,12 +405,16 @@ def get_fn_code( if t in (LatchFile, LatchDir): assert isinstance(param_meta, metadata.SnakemakeFileParameter) + touch_str = f"{param}._create_imposters()" + if param_meta.download: + touch_str = f"Path({param}).resolve()" + code_block += reindent( rf""" {param}_dst_p = Path("{param_meta.path}") print(f"Downloading {param}: {{{param}.remote_path}}") - {param}._create_imposters() + {touch_str} {param}_p = Path({param}.path) print(f" {{file_name_and_size({param}_p)}}") From 71c94b66401b4837107c7999742a355200011a8a Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Sat, 21 Oct 2023 12:46:26 -0700 Subject: [PATCH 339/356] move print Signed-off-by: Ayush Kamat --- latch_cli/snakemake/workflow.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 895de647..9829ec78 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -407,13 +407,15 @@ def get_fn_code( touch_str = f"{param}._create_imposters()" if param_meta.download: - touch_str = f"Path({param}).resolve()" + touch_str = ( + f'print(f"Downloading {param}: {{{param}.remote_path}}");' + f" Path({param}).resolve()" + ) code_block += reindent( rf""" {param}_dst_p = Path("{param_meta.path}") - print(f"Downloading {param}: {{{param}.remote_path}}") {touch_str} {param}_p = Path({param}.path) print(f" {{file_name_and_size({param}_p)}}") From 14260e09e84f4f7f10ce742f8b68e565ad1927ed Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Sat, 21 Oct 2023 12:54:53 -0700 Subject: [PATCH 340/356] dur Signed-off-by: Ayush Kamat --- latch_cli/snakemake/workflow.py | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 9829ec78..26d270f7 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -339,24 +339,13 @@ def get_fn_interface( params: List[str] = [] for param, t in self.python_interface.inputs.items(): - meta = self.parameter_metadata[param] - - if meta.default is None: - default_str = "" - elif isinstance(meta.default, (LatchFile, LatchDir)): - default_str = f"= {meta.type.__name__}({repr(meta.default.path)})" - else: - default_str = f"= {repr(meta.default)}" - params.append( reindent( rf""" - {param}: {type_repr(t, add_namespace=True)} __default__ + {param}: {type_repr(t, add_namespace=True)} """, 1, - ) - .replace("__default__", default_str) - .rstrip() + ).rstrip() ) params_str = ",\n".join(params) From 01697332d8d790e90e5f72cbcc210db2f245fbb2 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Sat, 21 Oct 2023 13:21:47 -0700 Subject: [PATCH 341/356] better check exists and rename Signed-off-by: Ayush Kamat --- latch_cli/snakemake/serialize.py | 17 ++-------------- latch_cli/utils/__init__.py | 33 ++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/latch_cli/snakemake/serialize.py b/latch_cli/snakemake/serialize.py index 8feea935..45f09b96 100644 --- a/latch_cli/snakemake/serialize.py +++ b/latch_cli/snakemake/serialize.py @@ -343,7 +343,7 @@ def generate_snakemake_entrypoint( from latch.types.directory import LatchDir from latch.types.file import LatchFile - from latch_cli.utils import get_parameter_json_value, urljoins + from latch_cli.utils import get_parameter_json_value, urljoins, check_exists_and_rename sys.stdout.reconfigure(line_buffering=True) sys.stderr.reconfigure(line_buffering=True) @@ -356,13 +356,6 @@ def update_mapping(local: Path, remote: str, mapping: Dict[str, str]): for p in local.iterdir(): update_mapping(p, urljoins(remote, p.name), mapping) - def check_exists_and_rename(old: Path, new: Path): - if new.exists(): - print(f"A file already exists at {new} and will be overwritten.") - if new.is_dir(): - shutil.rmtree(new) - os.renames(old, new) - def si_unit(num, base: float = 1000.0): for unit in (" ", "k", "M", "G", "T", "P", "E", "Z"): @@ -444,7 +437,7 @@ def generate_jit_register_code( generate_snakemake_entrypoint, serialize_snakemake, ) - from latch_cli.utils import get_parameter_json_value + from latch_cli.utils import get_parameter_json_value, check_exists_and_rename import latch_cli.snakemake from latch_cli.utils import urljoins @@ -469,12 +462,6 @@ def update_mapping(local: Path, remote: str, mapping: Dict[str, str]): for p in local.iterdir(): update_mapping(p, urljoins(remote, p.name), mapping) - def check_exists_and_rename(old: Path, new: Path): - if new.exists(): - print(f"A file already exists at {new} and will be overwritten.") - if new.is_dir(): - shutil.rmtree(new) - os.renames(old, new) def si_unit(num, base: float = 1000.0): for unit in (" ", "k", "M", "G", "T", "P", "E", "Z"): diff --git a/latch_cli/utils/__init__.py b/latch_cli/utils/__init__.py index d4e4f044..3bb806f9 100644 --- a/latch_cli/utils/__init__.py +++ b/latch_cli/utils/__init__.py @@ -2,6 +2,7 @@ import hashlib import os +import shutil import stat import subprocess import urllib.parse @@ -398,3 +399,35 @@ def get_parameter_json_value(v): return {k: get_parameter_json_value(x) for k, x in v.items()} else: return v + + +def check_exists_and_rename(old: Path, new: Path): + if not new.exists(): + os.renames(old, new) + return + + if old.is_file(): + if new.is_file(): + print(f"Warning: A file already exists at {new} and will be overwritten.") + os.renames(old, new) + return + + print( + f"Warning: {old} is a file but {new} is not. Everything within {new} will" + " be overwritten." + ) + shutil.rmtree(new) + os.renames(old, new) + return + + if new.is_file(): + print( + f"Warning: {old} is a directory but {new} is not. {new} will be" + " overwritten." + ) + shutil.rmtree(new) + os.renames(old, new) + return + + for sub in old.iterdir(): + check_exists_and_rename(sub, new / sub.name) From d0aa78b54dfa8528b6f28eb1c9b477c15fc72355 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Sat, 21 Oct 2023 13:32:55 -0700 Subject: [PATCH 342/356] del print statement Signed-off-by: Ayush Kamat --- latch_cli/snakemake/workflow.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index 26d270f7..c2fb24b1 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -165,10 +165,6 @@ def snakemake_dag_to_interface( None, ) - print(x) - - print(local_to_remote_path_mapping) - remote_path = ( Path("/.snakemake_latch") / "workflows" / wf_name / "inputs" / x ) From 0163e9bacda242055446f60b05a3a03d2933aa52 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Sat, 21 Oct 2023 18:05:34 -0700 Subject: [PATCH 343/356] fixies Signed-off-by: Ayush Kamat --- latch_cli/snakemake/workflow.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index c2fb24b1..ea3666d5 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -156,6 +156,9 @@ def snakemake_dag_to_interface( for o in dep.output: if o in dep_files: dep_outputs.append(o) + for o in dep.log: + if o in dep_files: + dep_outputs.append(o) for x in job.input: if x not in dep_outputs: @@ -587,7 +590,8 @@ def get_fn_code( protos = _recursive_list(td) reg_resp = register_serialized_pkg(protos, None, version, account_id) - _print_reg_resp(reg_resp, new_image_name) + reg_resp.get("stdout") + # _print_reg_resp(reg_resp, new_image_name, silent=True) wf_spec_remote = f"latch:///.snakemake_latch/workflows/{wf_name}/spec" spec_dir = Path("spec") @@ -610,8 +614,9 @@ class _WorkflowInfoNode(TypedDict): nodes: Optional[List[_WorkflowInfoNode]] = None - while not nodes: + while True: time.sleep(1) + print("Getting Workflow Data:", end=" ") nodes = execute( gql.gql(''' query workflowQuery($name: String, $ownerId: BigInt, $version: String) { @@ -625,6 +630,13 @@ class _WorkflowInfoNode(TypedDict): {"name": wf_name, "version": version, "ownerId": account_id}, )["workflowInfos"]["nodes"] + if not nodes: + print("Failed. Trying again.") + else: + print("Succeeded.") + break + + if len(nodes) > 1: raise ValueError( "Invariant violated - more than one workflow identified for unique combination" @@ -640,6 +652,8 @@ class _WorkflowInfoNode(TypedDict): wf_id = nodes[0]["id"] params = gpjson.MessageToDict(wf.literal_map.to_flyte_idl()).get("literals", {}) + print(params) + _interface_request = { "workflow_id": wf_id, "params": params, From 5f6bca2a2099bbf62d51392b06c645db94911b65 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Sat, 21 Oct 2023 18:06:23 -0700 Subject: [PATCH 344/356] del Signed-off-by: Ayush Kamat --- latch_cli/snakemake/workflow.py | 1 - 1 file changed, 1 deletion(-) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index ea3666d5..fb4f0d32 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -590,7 +590,6 @@ def get_fn_code( protos = _recursive_list(td) reg_resp = register_serialized_pkg(protos, None, version, account_id) - reg_resp.get("stdout") # _print_reg_resp(reg_resp, new_image_name, silent=True) wf_spec_remote = f"latch:///.snakemake_latch/workflows/{wf_name}/spec" From b7410f79b7cb2772fa17a74b2587c6f79eaecc96 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Sat, 21 Oct 2023 19:02:24 -0700 Subject: [PATCH 345/356] release Signed-off-by: Ayush Kamat --- CHANGELOG.md | 40 ++++++++++++++++++++++++++++++---------- setup.py | 2 +- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f09a096f..aad2444f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,23 +16,43 @@ Types of changes # Latch SDK Changelog +## 2.35.0 + +### Added + +* Snakemake + + Remote register support + + `download` field for file inputs + + `config` field for file inputs + + Blanket support for parameters of any type via the `SnakemakeParameter` class + + Support for generating a `latch_metadata` directory from a `config.yaml` with `latch generate-metadata` + + Support for default values for parameters + +### Changed + +* Snakemake + + JIT register step no longer downloads input files by default + + `latch_metadata` should now be a module (directory containing an `__init__.py` file), as opposed to just being a file + ## 2.34.0 - 2023-10-04 ### Added -* `directory` modifier for input / outputs -* Support `temp` by removing from compiled rules. All files / directories are -temporary because they are deleted at the end of each job on Latch. -* `multiext` output modifier -* `report` output modifier -* `params` in rules +* Snakemake + + `directory` modifier for input / outputs + + Support `temp` by removing from compiled rules. All files / directories are + temporary because they are deleted at the end of each job on Latch. + + `multiext` output modifier + + `report` output modifier + + `params` in rules ### Fixed -* Replace skipped rules with `Ellipsis`. Supports rules nested in conditionals where previously an empty block was produced. -* Patched parser to generate compiled code for `workflow.include` calls Compiled workflow.include should carry `print_compilation` keyword (snakemake/snakemake#2469) -* Detect use of `conda` keyword and install in image. This effectively supports wrapper/conda keywords. -* `Iterable, Generator` cause issues as type hints when imported from `collections.abc` rather than `typing` +* Snakemake + + Replace skipped rules with `Ellipsis`. Supports rules nested in conditionals where previously an empty block was produced. + + Patched parser to generate compiled code for `workflow.include` calls Compiled workflow.include should carry `print_compilation` keyword (snakemake/snakemake#2469) + + Detect use of `conda` keyword and install in image. This effectively supports wrapper/conda keywords. + + `Iterable, Generator` cause issues as type hints when imported from `collections.abc` rather than `typing` ## 2.33.0 - 2023-09-29 diff --git a/setup.py b/setup.py index 8f13abc2..dd31b0c7 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ setup( name="latch", - version="v2.34.0", + version="v2.35.0", author_email="kenny@latch.bio", description="The Latch SDK", packages=find_packages(), From 428e4b774a6498b96419018c82e8e32b6448c905 Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 23 Oct 2023 17:09:39 -0700 Subject: [PATCH 346/356] add get_table_id Signed-off-by: maximsmol --- latch/registry/record.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/latch/registry/record.py b/latch/registry/record.py index d217732b..5fa19c53 100644 --- a/latch/registry/record.py +++ b/latch/registry/record.py @@ -47,6 +47,7 @@ class _ColumnDefinitionConnection(TypedDict): class _CatalogExperiment(TypedDict): + id: str catalogExperimentColumnDefinitionsByExperimentId: _ColumnDefinitionConnection @@ -70,6 +71,7 @@ class _CatalogSample(TypedDict): class _Cache: """Internal cache class to organize information for a `Record`.""" + table_id: Optional[str] = None name: Optional[str] = None columns: Optional[Dict[str, Column]] = None values: Optional[Dict[str, RecordValue]] = None @@ -117,6 +119,7 @@ def load(self) -> None: } } experiment { + id catalogExperimentColumnDefinitionsByExperimentId { nodes { type @@ -132,6 +135,7 @@ def load(self) -> None: )["catalogSample"] # todo(maximsmol): deal with nonexistent records + self._cache.table_id = data["experiment"]["id"] self._cache.name = data["name"] typeNodes = data["experiment"][ @@ -164,6 +168,32 @@ def load(self) -> None: self._cache.values = vals + # get_table_id + @overload + def get_table_id(self, *, load_if_missing: Literal[True] = True) -> str: ... + + @overload + def get_table_id(self, *, load_if_missing: bool) -> Optional[str]: ... + + def get_table_id(self, *, load_if_missing: bool = True) -> Optional[str]: + """Get the ID of the table that contains this record. + + Args: + load_if_missing: + If true, :meth:`load` the table ID if not in cache. + If false, return `None` if not in cache. + + Returns: + ID of the :class:`Table` containing this record. + """ + if self._cache.table_id is None: + if not load_if_missing: + return None + + self.load() + + return self._cache.table_id + # get_name @overload From a90a1b4d9e16807c51f3fe8b5ef14f39afb3447f Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 23 Oct 2023 17:11:31 -0700 Subject: [PATCH 347/356] new release Signed-off-by: maximsmol --- CHANGELOG.md | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 208f4d93..9c2075cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,12 @@ Types of changes # Latch SDK Changelog +## 2.35.0 - 2023-10-23 + +### Added + +* `latch.registry.record.Record.get_table_id` method for querying the ID of the table containing a given registry record + ## 2.34.0 - 2023-10-04 ### Added diff --git a/setup.py b/setup.py index 8f13abc2..dd31b0c7 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ setup( name="latch", - version="v2.34.0", + version="v2.35.0", author_email="kenny@latch.bio", description="The Latch SDK", packages=find_packages(), From a93317f654f95712b0ee9038926a29d51da735fd Mon Sep 17 00:00:00 2001 From: maximsmol Date: Mon, 23 Oct 2023 17:40:58 -0700 Subject: [PATCH 348/356] add table project_id Signed-off-by: maximsmol --- CHANGELOG.md | 3 ++- latch/registry/record.py | 1 + latch/registry/table.py | 30 ++++++++++++++++++++++++++++++ setup.py | 2 +- 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c2075cf..19dbbb0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,11 +16,12 @@ Types of changes # Latch SDK Changelog -## 2.35.0 - 2023-10-23 +## 2.36.0 - 2023-10-23 ### Added * `latch.registry.record.Record.get_table_id` method for querying the ID of the table containing a given registry record +* `latch.registry.table.Table.get_project_id` method for querying the ID of the project containing a given registry table ## 2.34.0 - 2023-10-04 diff --git a/latch/registry/record.py b/latch/registry/record.py index 5fa19c53..b0923e12 100644 --- a/latch/registry/record.py +++ b/latch/registry/record.py @@ -169,6 +169,7 @@ def load(self) -> None: self._cache.values = vals # get_table_id + @overload def get_table_id(self, *, load_if_missing: Literal[True] = True) -> str: ... diff --git a/latch/registry/table.py b/latch/registry/table.py index f8a9a603..76ddbacc 100644 --- a/latch/registry/table.py +++ b/latch/registry/table.py @@ -67,6 +67,7 @@ class _ColumnNode(TypedDict("_ColumnNodeReserved", {"def": DBValue})): class _Cache: display_name: Optional[str] = None columns: Optional[Dict[str, Column]] = None + project_id: Optional[str] = None @dataclass(frozen=True) @@ -107,6 +108,7 @@ def load(self) -> None: def } } + projectId } } """), @@ -114,6 +116,7 @@ def load(self) -> None: )["catalogExperiment"] # todo(maximsmol): deal with nonexistent tables + self._cache.project_id = data["projectId"] self._cache.display_name = data["displayName"] self._cache.columns = {} @@ -128,6 +131,33 @@ def load(self) -> None: cur = Column(x["key"], py_type, x["type"]) self._cache.columns[cur.key] = cur + # get_project_id + + @overload + def get_project_id(self, *, load_if_missing: Literal[True] = True) -> str: ... + + @overload + def get_project_id(self, *, load_if_missing: bool) -> Optional[str]: ... + + def get_project_id(self, *, load_if_missing: bool = True) -> Optional[str]: + """Get the ID of the project that contains this table. + + Args: + load_if_missing: + If true, :meth:`load` the project ID if not in cache. + If false, return `None` if not in cache. + + Returns: + ID of the :class:`Project` containing this table. + """ + if self._cache.project_id is None: + if not load_if_missing: + return None + + self.load() + + return self._cache.project_id + # get_display_name @overload diff --git a/setup.py b/setup.py index dd31b0c7..a73637d6 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ setup( name="latch", - version="v2.35.0", + version="v2.36.0", author_email="kenny@latch.bio", description="The Latch SDK", packages=find_packages(), From 3c1e5112db2f58b6e0a6d95034ff6e965aed6900 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Tue, 24 Oct 2023 12:05:51 -0700 Subject: [PATCH 349/356] add glob support to mv Signed-off-by: Ayush Kamat --- latch_cli/main.py | 14 ++- latch_cli/services/move.py | 210 ++++++++++++++++++++++--------------- 2 files changed, 138 insertions(+), 86 deletions(-) diff --git a/latch_cli/main.py b/latch_cli/main.py index 46671da7..c6e0b365 100644 --- a/latch_cli/main.py +++ b/latch_cli/main.py @@ -347,9 +347,17 @@ def cp( @main.command("mv") -@click.argument("src", shell_complete=remote_complete, nargs=-1) +@click.argument("src", shell_complete=remote_complete, nargs=1) @click.argument("dest", shell_complete=remote_complete, nargs=1) -def mv(src: str, dest: str): +@click.option( + "--no-glob", + "-G", + help="Don't expand globs in remote paths", + is_flag=True, + default=False, + show_default=True, +) +def mv(src: str, dest: str, no_glob: bool): """Move remote files in LatchData.""" crash_handler.message = f"Unable to move {src} to {dest}" @@ -357,7 +365,7 @@ def mv(src: str, dest: str): from latch_cli.services.move import move - move(src, dest) + move(src, dest, no_glob=no_glob) @main.command("ls") diff --git a/latch_cli/services/move.py b/latch_cli/services/move.py index 1a135c7b..d1b60e11 100644 --- a/latch_cli/services/move.py +++ b/latch_cli/services/move.py @@ -1,8 +1,11 @@ +from textwrap import dedent + import click import gql from gql.transport.exceptions import TransportQueryError from latch_sdk_gql.execute import execute +from latch_cli.services.cp.glob import expand_pattern from latch_cli.services.cp.ldata_utils import LDataNodeType, get_node_data from latch_cli.utils.path import get_name_from_path, get_path_error, is_remote_path @@ -10,96 +13,137 @@ def move( src: str, dest: str, + *, + no_glob: bool = False, ): - if not is_remote_path(src) or not is_remote_path(dest): - raise ValueError( + if no_glob: + srcs = [src] + else: + srcs = expand_pattern(src) + + if len(srcs) == 0: + click.secho(f"Could not find any files that match pattern {src}. Exiting.") + raise click.exceptions.Exit(0) + + if not all([is_remote_path(s) for s in srcs]) or not is_remote_path(dest): + click.secho( f"`latch mv` cannot be used for local file operations. Please make sure" - f" both of your input paths are remote (beginning with `latch://`)" + f" all of your input paths are remote (beginning with `latch://`)", + fg="red", ) + raise click.exceptions.Exit(1) - node_data = get_node_data(src, dest, allow_resolve_to_parent=True) + node_data = get_node_data(*srcs, dest, allow_resolve_to_parent=True) - src_data = node_data.data[src] dest_data = node_data.data[dest] acc_id = node_data.acc_id - path_by_id = {v.id: k for k, v in node_data.data.items()} - - if src_data.is_parent: - raise get_path_error(src, "not found", acc_id) - - new_name = None - if dest_data.is_parent: - new_name = get_name_from_path(dest) - elif dest_data.type in {LDataNodeType.obj, LDataNodeType.link}: - raise get_path_error(dest, "object already exists at path.", acc_id) - - try: - execute( - gql.gql(""" - mutation Move( - $argNode: BigInt! - $argDestParent: BigInt! - $argNewName: String - ) { - ldataMove( - input: { - argNode: $argNode - argDestParent: $argDestParent - argNewName: $argNewName - } - ) { - clientMutationId - } - }"""), - { - "argNode": src_data.id, - "argDestParent": dest_data.id, - "argNewName": new_name, - }, + multi_src = len(srcs) > 1 + + if multi_src and dest_data.is_parent: + click.secho( + f"Remote destination {dest} does not exist. Cannot move multiple source" + " files to a destination that does not exist.", + fg="red", ) - except TransportQueryError as e: - if e.errors is None or len(e.errors) == 0: - raise e - - msg: str = e.errors[0]["message"] - - if msg.startswith("Permission denied on node"): - node_id = msg.rsplit(" ", 1)[1] - path = path_by_id[node_id] - - raise get_path_error(path, "permission denied.", acc_id) from e - elif msg == "Refusing to make node its own parent": - raise get_path_error(dest, f"is a parent of {src}.", acc_id) from e - elif msg == "Refusing to parent node to an object node": - raise get_path_error(dest, f"object exists at path.", acc_id) from e - elif msg == "Refusing to move a share link (or into a share link)": - if src_data.type is LDataNodeType.link: - path = src + raise click.exceptions.Exit(1) + elif multi_src and dest_data.type in {LDataNodeType.obj, LDataNodeType.link}: + click.secho( + f"Remote destination {dest} is not a directory. Cannot move multiple source" + " files to a destination that is not a directory.", + fg="red", + ) + raise click.exceptions.Exit(1) + + for s in srcs: + src_data = node_data.data[s] + + path_by_id = {v.id: k for k, v in node_data.data.items()} + + if src_data.is_parent: + raise get_path_error(s, "not found", acc_id) + + new_name = None + if dest_data.is_parent: + new_name = get_name_from_path(dest) + elif dest_data.type in {LDataNodeType.obj, LDataNodeType.link}: + raise get_path_error(dest, "object already exists at path.", acc_id) + + try: + execute( + gql.gql(""" + mutation Move( + $argNode: BigInt! + $argDestParent: BigInt! + $argNewName: String + ) { + ldataMove( + input: { + argNode: $argNode + argDestParent: $argDestParent + argNewName: $argNewName + } + ) { + clientMutationId + } + } + """), + { + "argNode": src_data.id, + "argDestParent": dest_data.id, + "argNewName": new_name, + }, + ) + except TransportQueryError as e: + if e.errors is None or len(e.errors) == 0: + raise e + + msg: str = e.errors[0]["message"] + + if msg.startswith("Permission denied on node"): + node_id = msg.rsplit(" ", 1)[1] + path = path_by_id[node_id] + + raise get_path_error(path, "permission denied.", acc_id) from e + elif msg == "Refusing to make node its own parent": + raise get_path_error(dest, f"is a parent of {s}.", acc_id) from e + elif msg == "Refusing to parent node to an object node": + raise get_path_error(dest, f"object exists at path.", acc_id) from e + elif msg == "Refusing to move a share link (or into a share link)": + if src_data.type is LDataNodeType.link: + path = s + else: + path = dest + + raise get_path_error(path, f"is a share link.", acc_id) from e + elif msg.startswith("Refusing to move account root"): + raise get_path_error(s, "is an account root.", acc_id) from e + elif msg.startswith("Refusing to move removed node"): + raise get_path_error(s, "not found.", acc_id) from e + elif msg.startswith("Refusing to move already moved node"): + raise get_path_error( + s, + "copy in progress. Please wait until the node has finished copying" + " before moving.", + acc_id, + ) from e + elif msg == "Conflicting object in destination": + raise get_path_error(dest, "object exists at path.", acc_id) from e + elif msg.startswith("Refusing to do noop move"): + raise get_path_error(dest, "cannot move node to itself.", acc_id) from e else: - path = dest - - raise get_path_error(path, f"is a share link.", acc_id) from e - elif msg.startswith("Refusing to move account root"): - raise get_path_error(src, "is an account root.", acc_id) from e - elif msg.startswith("Refusing to move removed node"): - raise get_path_error(src, "not found.", acc_id) from e - elif msg.startswith("Refusing to move already moved node"): - raise get_path_error( - src, - "copy in progress. Please wait until the node has finished copying" - " before moving.", - acc_id, - ) from e - elif msg == "Conflicting object in destination": - raise get_path_error(dest, "object exists at path.", acc_id) from e - elif msg.startswith("Refusing to do noop move"): - raise get_path_error(dest, "cannot move node to itself.", acc_id) from e - else: - raise e - - click.echo(f""" -{click.style("Move Succeeded.", fg="green")} - -{click.style("Source: ", fg="blue")}{(src)} -{click.style("Destination: ", fg="blue")}{(dest)}""") + raise e + + if len(srcs) == 1: + src_str = f'{click.style("Source: ", fg="blue")}{srcs[0]}' + else: + src_str = "\n".join( + [click.style("Sources: ", fg="blue"), *[f" {s}" for s in srcs]] + ) + + click.echo(dedent(f""" + {click.style("Move Succeeded.", fg="green")} + + __srcs__ + {click.style("Destination: ", fg="blue")}{(dest)} + """).replace("__srcs__", src_str).strip()) From 745bb2dc48c79f687a49bcf57fd9414a4620aff8 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Tue, 24 Oct 2023 12:52:59 -0700 Subject: [PATCH 350/356] comment Signed-off-by: Ayush Kamat --- latch_cli/services/move.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/latch_cli/services/move.py b/latch_cli/services/move.py index d1b60e11..f4bf7de4 100644 --- a/latch_cli/services/move.py +++ b/latch_cli/services/move.py @@ -16,6 +16,14 @@ def move( *, no_glob: bool = False, ): + if not is_remote_path(src) or not is_remote_path(dest): + click.secho( + f"`latch mv` cannot be used for local file operations. Please make sure" + f" all of your input paths are remote (beginning with `latch://`)", + fg="red", + ) + raise click.exceptions.Exit(1) + if no_glob: srcs = [src] else: @@ -25,14 +33,6 @@ def move( click.secho(f"Could not find any files that match pattern {src}. Exiting.") raise click.exceptions.Exit(0) - if not all([is_remote_path(s) for s in srcs]) or not is_remote_path(dest): - click.secho( - f"`latch mv` cannot be used for local file operations. Please make sure" - f" all of your input paths are remote (beginning with `latch://`)", - fg="red", - ) - raise click.exceptions.Exit(1) - node_data = get_node_data(*srcs, dest, allow_resolve_to_parent=True) dest_data = node_data.data[dest] From d76a4d8c22fa434150d244e778aab3ba910f2543 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Tue, 24 Oct 2023 13:06:32 -0700 Subject: [PATCH 351/356] fail gracefully if source path does not exist Signed-off-by: Ayush Kamat --- CHANGELOG.md | 15 +++++++++++---- latch_cli/services/cp/ldata_utils.py | 3 +++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 19dbbb0c..7546f680 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,12 @@ Types of changes # Latch SDK Changelog +## 2.36.1 - 2023-10-24 + +### Changed + +* `latch mv` now supports glob patterns (with the same restrictions as `latch cp`) + ## 2.36.0 - 2023-10-23 ### Added @@ -52,17 +58,18 @@ temporary because they are deleted at the end of each job on Latch. ### Fixed * Snakemake: - * Better errors if `Snakefile` or `latch_metadata.py` file missing - * Correct issues with snakemake example project + - Better errors if `Snakefile` or `latch_metadata.py` file missing + - Correct issues with snakemake example project ## 2.32.7 - 2023-09-07 ### Fixed * Snakemake: - * `--snakemake` for `latch dockerfile` command to generate `Dockerfile` with + - `--snakemake` for `latch dockerfile` command to generate `Dockerfile` with necessary instructions - * Snakemake example for `latch init` + + - Snakemake example for `latch init` ## 2.32.6 - 2023-09-07 diff --git a/latch_cli/services/cp/ldata_utils.py b/latch_cli/services/cp/ldata_utils.py index 5215d7ec..6a291e64 100644 --- a/latch_cli/services/cp/ldata_utils.py +++ b/latch_cli/services/cp/ldata_utils.py @@ -184,6 +184,9 @@ def _get_immediate_children_of_node(path: str) -> List[str]: {"argPath": path}, )["ldataResolvePathData"] + if lrpd is None: + return [] + res: List[str] = [] for node in lrpd["childLdataTreeEdges"]["nodes"]: res.append(node["child"]["name"]) From 9513eac9183fd12e4eea1ad4cbd605e164eb5f71 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Tue, 24 Oct 2023 13:08:43 -0700 Subject: [PATCH 352/356] version Signed-off-by: Ayush Kamat --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index a73637d6..abf5a512 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ setup( name="latch", - version="v2.36.0", + version="v2.36.1", author_email="kenny@latch.bio", description="The Latch SDK", packages=find_packages(), From 303a8ac02ba6f4b11938dd7370bc6833a09e2eca Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Wed, 25 Oct 2023 10:12:58 -0700 Subject: [PATCH 353/356] finish Signed-off-by: Ayush Kamat --- latch_cli/snakemake/workflow.py | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/latch_cli/snakemake/workflow.py b/latch_cli/snakemake/workflow.py index fb4f0d32..37772cb3 100644 --- a/latch_cli/snakemake/workflow.py +++ b/latch_cli/snakemake/workflow.py @@ -163,10 +163,7 @@ def snakemake_dag_to_interface( for x in job.input: if x not in dep_outputs: param = variable_name_for_value(x, job.input) - inputs[param] = ( - LatchFile, - None, - ) + inputs[param] = (LatchFile, None) remote_path = ( Path("/.snakemake_latch") / "workflows" / wf_name / "inputs" / x @@ -744,6 +741,19 @@ def compile(self, **kwargs): else: python_outputs[param] = LatchFile + for x in job.log: + assert isinstance(x, SnakemakeInputVal) + + if x in target_files: + is_target = True + param = variable_name_for_value(x, job.log) + target_file_for_output_param[param] = x + + if x.is_directory: + python_outputs[param] = LatchDir + else: + python_outputs[param] = LatchFile + dep_outputs: Dict[SnakemakeInputVal, JobOutputInfo] = {} for dep, dep_files in self._dag.dependencies[job].items(): for o in dep.output: @@ -758,6 +768,16 @@ def compile(self, **kwargs): type_=LatchDir if o.is_directory else LatchFile, ) + for o in dep.log: + if o in dep_files: + assert isinstance(o, SnakemakeInputVal) + + dep_outputs[o] = JobOutputInfo( + jobid=dep.jobid, + output_param_name=variable_name_for_value(o, dep.log), + type_=LatchDir if o.is_directory else LatchFile, + ) + python_inputs: Dict[str, Union[Type[LatchFile], Type[LatchDir]]] = {} promise_map: Dict[str, JobOutputInfo] = {} for x in job.input: From 56f4f19451293f71f815cc8db10de11d405d58cd Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Wed, 25 Oct 2023 12:28:53 -0700 Subject: [PATCH 354/356] release Signed-off-by: Ayush Kamat --- CHANGELOG.md | 7 +++++++ setup.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2bf3059..b7facf10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,13 @@ Types of changes # Latch SDK Changelog +## 2.36.2 - 2023-10-25 + +### Changed + +* Snakemake + + Log files are now marked as outputs - this enables rules to use logs of previous rules as inputs + ## 2.36.1 - 2023-10-24 ### Changed diff --git a/setup.py b/setup.py index abf5a512..da8c298b 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ setup( name="latch", - version="v2.36.1", + version="v2.36.2", author_email="kenny@latch.bio", description="The Latch SDK", packages=find_packages(), From 644fc06110fc924f00c0280f66e2fb5187d70060 Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Wed, 25 Oct 2023 16:33:32 -0700 Subject: [PATCH 355/356] fix 3.8 specific bug in type annotation Signed-off-by: Ayush Kamat --- latch/types/metadata.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/latch/types/metadata.py b/latch/types/metadata.py index 1dc449d0..2274059a 100644 --- a/latch/types/metadata.py +++ b/latch/types/metadata.py @@ -1,4 +1,5 @@ import re +import sys from dataclasses import Field, asdict, dataclass, field from enum import Enum from pathlib import Path @@ -349,7 +350,7 @@ def dict(self): # https://stackoverflow.com/questions/54668000/type-hint-for-an-instance-of-a-non-specific-dataclass class _IsDataclass(Protocol): - __dataclass_fields__: ClassVar[Dict[str, Field[Any]]] + __dataclass_fields__: ClassVar[Dict[str, Field]] ParameterType: TypeAlias = Union[ From 9321ec15dd43715959133899df54209ba76db17d Mon Sep 17 00:00:00 2001 From: Ayush Kamat Date: Wed, 25 Oct 2023 16:35:25 -0700 Subject: [PATCH 356/356] bump version Signed-off-by: Ayush Kamat --- CHANGELOG.md | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7facf10..dc880085 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,12 @@ Types of changes # Latch SDK Changelog +## 2.36.3 - 2023-10-25 + +### Fixed + +* Bug where Python 3.8 clients would crash due to a broken type annotation + ## 2.36.2 - 2023-10-25 ### Changed diff --git a/setup.py b/setup.py index da8c298b..42492080 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ setup( name="latch", - version="v2.36.2", + version="v2.36.3", author_email="kenny@latch.bio", description="The Latch SDK", packages=find_packages(),

  • )H+O?EPZWvyaBd7$OGv$T%FM2Ug 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