re
Some checks failed
smoke-mm / Install & smoke test mm --help (push) Has been cancelled

This commit is contained in:
nose
2025-12-25 04:49:22 -08:00
parent 2542a68479
commit 43afa4e3fa
19 changed files with 2766 additions and 234 deletions

195
CLI.py
View File

@@ -1710,6 +1710,51 @@ class PipelineExecutor:
return False
@staticmethod
def _maybe_open_url_selection(current_table: Any, selected_items: list, *, stage_is_last: bool) -> bool:
if not stage_is_last:
return False
if not selected_items or len(selected_items) != 1:
return False
table_type = ""
source_cmd = ""
try:
table_type = str(getattr(current_table, "table", "") or "").strip().lower()
except Exception:
table_type = ""
try:
source_cmd = str(getattr(current_table, "source_command", "") or "").strip().replace("_", "-").lower()
except Exception:
source_cmd = ""
if table_type != "url" and source_cmd != "get-url":
return False
item = selected_items[0]
url = None
try:
from cmdlet._shared import get_field
url = get_field(item, "url")
except Exception:
try:
url = item.get("url") if isinstance(item, dict) else getattr(item, "url", None)
except Exception:
url = None
url_text = str(url or "").strip()
if not url_text:
return False
try:
import webbrowser
webbrowser.open(url_text, new=2)
return True
except Exception:
return False
def _maybe_enable_background_notifier(self, worker_manager: Any, config: Any, pipeline_session: Any) -> None:
if not (pipeline_session and worker_manager and isinstance(config, dict)):
return
@@ -1798,12 +1843,15 @@ class PipelineExecutor:
else:
selected_row_args: List[str] = []
skip_pipe_expansion = source_cmd == ".pipe" and len(stages) > 0
if source_cmd and not skip_pipe_expansion:
for idx in selection_indices:
row_args = ctx.get_current_stage_table_row_selection_args(idx)
if row_args:
selected_row_args.extend(row_args)
break
# Only perform @N command expansion for *single-item* selections.
# For multi-item selections (e.g. @*, @1-5), expanding to a single
# row would silently drop items. In those cases we pipe the selected
# items downstream instead.
if source_cmd and not skip_pipe_expansion and len(selection_indices) == 1:
idx = selection_indices[0]
row_args = ctx.get_current_stage_table_row_selection_args(idx)
if row_args:
selected_row_args.extend(row_args)
if selected_row_args:
if isinstance(source_cmd, list):
@@ -1834,30 +1882,42 @@ class PipelineExecutor:
command_expanded = True
if (not command_expanded) and selection_indices:
last_piped_items = None
try:
last_piped_items = ctx.get_last_result_items()
except Exception:
last_piped_items = None
stage_table = None
try:
stage_table = ctx.get_current_stage_table()
except Exception:
stage_table = None
if not stage_table and hasattr(ctx, "get_display_table"):
try:
stage_table = ctx.get_display_table()
except Exception:
stage_table = None
display_table = None
try:
display_table = ctx.get_display_table() if hasattr(ctx, "get_display_table") else None
except Exception:
display_table = None
if not stage_table and display_table is not None:
stage_table = display_table
if not stage_table:
try:
stage_table = ctx.get_last_result_table()
except Exception:
stage_table = None
resolved_items = last_piped_items if last_piped_items else []
if last_piped_items:
# Prefer selecting from the last selectable *table* (search/playlist)
# rather than from display-only emitted items, unless we're explicitly
# selecting from an overlay table.
try:
if display_table is not None and stage_table is display_table:
items_list = ctx.get_last_result_items() or []
else:
if hasattr(ctx, "get_last_selectable_result_items"):
items_list = ctx.get_last_selectable_result_items() or []
else:
items_list = ctx.get_last_result_items() or []
except Exception:
items_list = []
resolved_items = items_list if items_list else []
if items_list:
filtered = [resolved_items[i] for i in selection_indices if 0 <= i < len(resolved_items)]
if not filtered:
print("No items matched selection in pipeline\n")
@@ -2003,6 +2063,14 @@ class PipelineExecutor:
try:
self._try_clear_pipeline_stop(ctx)
# Preflight (URL-duplicate prompts, etc.) should be cached within a single
# pipeline run, not across independent pipelines.
try:
ctx.store_value("preflight", {})
except Exception:
pass
stages = self._split_stages(tokens)
if not stages:
print("Invalid pipeline syntax\n")
@@ -2066,11 +2134,39 @@ class PipelineExecutor:
stage_args = stage_tokens[1:]
if cmd_name == "@":
# Prefer piping the last emitted/visible items (e.g. add-file results)
# over the result-table subject. The subject can refer to older context
# (e.g. a playlist row) and may not contain store+hash.
last_items = None
try:
last_items = ctx.get_last_result_items()
except Exception:
last_items = None
if last_items:
from cmdlet._shared import coerce_to_pipe_object
try:
pipe_items = [coerce_to_pipe_object(x) for x in list(last_items)]
except Exception:
pipe_items = list(last_items)
piped_result = pipe_items if len(pipe_items) > 1 else pipe_items[0]
try:
ctx.set_last_items(pipe_items)
except Exception:
pass
if pipeline_session and worker_manager:
try:
worker_manager.log_step(pipeline_session.worker_id, "@ used last result items")
except Exception:
pass
continue
subject = ctx.get_last_result_subject()
if subject is None:
print("No current result context available for '@'\n")
pipeline_status = "failed"
pipeline_error = "No result subject for @"
pipeline_error = "No result items/subject for @"
return
piped_result = subject
try:
@@ -2095,18 +2191,34 @@ class PipelineExecutor:
return
selected_indices = []
# Prefer selecting from the last selectable *table* (search/playlist)
# rather than from display-only emitted items, unless we're explicitly
# selecting from an overlay table.
display_table = None
try:
display_table = ctx.get_display_table() if hasattr(ctx, "get_display_table") else None
except Exception:
display_table = None
stage_table = ctx.get_current_stage_table()
if not stage_table and display_table is not None:
stage_table = display_table
if not stage_table:
stage_table = ctx.get_last_result_table()
if display_table is not None and stage_table is display_table:
items_list = ctx.get_last_result_items() or []
else:
if hasattr(ctx, "get_last_selectable_result_items"):
items_list = ctx.get_last_selectable_result_items() or []
else:
items_list = ctx.get_last_result_items() or []
if is_select_all:
last_items = ctx.get_last_result_items() or []
selected_indices = list(range(len(last_items)))
selected_indices = list(range(len(items_list)))
else:
selected_indices = sorted([i - 1 for i in selection]) # type: ignore[arg-type]
stage_table = ctx.get_current_stage_table()
if not stage_table and hasattr(ctx, "get_display_table"):
stage_table = ctx.get_display_table()
if not stage_table:
stage_table = ctx.get_last_result_table()
items_list = ctx.get_last_result_items() or []
resolved_items = items_list if items_list else []
filtered = [resolved_items[i] for i in selected_indices if 0 <= i < len(resolved_items)]
if not filtered:
@@ -2115,6 +2227,20 @@ class PipelineExecutor:
pipeline_error = "Empty selection"
return
# UX: selecting a single URL row from get-url tables should open it.
# Only do this when the selection stage is terminal to avoid surprising
# side-effects in pipelines like `@1 | download-file`.
current_table = ctx.get_current_stage_table() or ctx.get_last_result_table()
if (not is_select_all) and (len(filtered) == 1):
try:
PipelineExecutor._maybe_open_url_selection(
current_table,
filtered,
stage_is_last=(stage_index + 1 >= len(stages)),
)
except Exception:
pass
if PipelineExecutor._maybe_run_class_selector(ctx, config, filtered, stage_is_last=(stage_index + 1 >= len(stages))):
return
@@ -2366,12 +2492,19 @@ class PipelineExecutor:
# the table and pause the pipeline so the user can pick @N.
stage_table = ctx.get_current_stage_table() if hasattr(ctx, "get_current_stage_table") else None
stage_table_type = str(getattr(stage_table, "table", "") or "").strip().lower() if stage_table else ""
try:
stage_table_source = str(getattr(stage_table, "source_command", "") or "").strip().replace("_", "-").lower() if stage_table else ""
except Exception:
stage_table_source = ""
if (
(not stage_is_last)
and (not emits)
and cmd_name in {"download-media", "download_media"}
and stage_table is not None
and stage_table_type in {"ytdlp.formatlist", "download-media", "download_media"}
and (
stage_table_type in {"ytdlp.formatlist", "download-media", "download_media", "bandcamp", "youtube"}
or stage_table_source in {"download-media", "download_media"}
)
):
try:
is_selectable = not bool(getattr(stage_table, "no_choice", False))
@@ -2407,6 +2540,10 @@ class PipelineExecutor:
stdout_console().print()
stdout_console().print(stage_table)
# Always pause the pipeline when a selectable table was produced.
# The user will continue by running @N/@* which will re-attach the
# pending downstream stages.
try:
remaining = stages[stage_index + 1 :]
source_cmd = (

View File

@@ -1,5 +1,6 @@
from __future__ import annotations
import html as html_std
import logging
import re
import requests
@@ -22,6 +23,595 @@ except ImportError:
lxml_html = None
def _strip_html_to_text(raw: str) -> str:
s = html_std.unescape(str(raw or ""))
s = re.sub(r"(?i)<br\s*/?>", "\n", s)
# Help keep lists readable when they are link-heavy.
s = re.sub(r"(?i)</a>", ", ", s)
s = re.sub(r"<[^>]+>", " ", s)
s = re.sub(r"\s+", " ", s)
return s.strip()
def _strip_html_to_lines(raw: str) -> List[str]:
"""Convert a small HTML snippet to a list of meaningful text lines.
Unlike `_strip_html_to_text`, this preserves `<br>` as line breaks so we can
parse LibGen ads.php tag blocks that use `<br>` separators.
"""
s = html_std.unescape(str(raw or ""))
s = re.sub(r"(?is)<script\b.*?</script>", " ", s)
s = re.sub(r"(?is)<style\b.*?</style>", " ", s)
s = re.sub(r"(?i)<br\s*/?>", "\n", s)
s = re.sub(r"(?i)</p\s*>", "\n", s)
s = re.sub(r"(?i)</tr\s*>", "\n", s)
# Help keep link-heavy lists readable.
s = re.sub(r"(?i)</a>", ", ", s)
s = re.sub(r"<[^>]+>", " ", s)
s = s.replace("\r\n", "\n").replace("\r", "\n")
out: List[str] = []
for line in s.split("\n"):
t = re.sub(r"\s+", " ", str(line or "")).strip()
if t:
out.append(t)
return out
def _libgen_md5_from_url(url: str) -> str:
try:
p = urlparse(str(url or ""))
q = p.query or ""
except Exception:
q = ""
m = re.search(r"(?:^|[&?])md5=([a-fA-F0-9]{32})(?:&|$)", q)
return str(m.group(1)).lower() if m else ""
def _libgen_ads_url_for_target(url: str) -> str:
"""Best-effort conversion of any LibGen URL to an ads.php URL (same host).
If md5 is not present, returns empty string.
"""
md5 = _libgen_md5_from_url(url)
if not md5:
return ""
try:
p = urlparse(str(url or ""))
scheme = p.scheme or "https"
netloc = p.netloc
if not netloc:
return ""
return f"{scheme}://{netloc}/ads.php?md5={md5}"
except Exception:
return ""
def _parse_libgen_ads_tags_html(html: str) -> Dict[str, Any]:
"""Parse tags embedded on LibGen ads.php pages.
Some mirrors render all metadata as a single `<td>` with `<br>` separators:
title: ...<br>author(s): ...<br>isbn: ...
Returns a metadata dict similar to `_parse_libgen_details_html` (subset), plus
`_raw_fields` with captured keys.
"""
s = str(html or "")
td_blocks = re.findall(r"(?is)<td\b[^>]*>(.*?)</td>", s)
best_lines: List[str] = []
best_score = 0
for td in td_blocks:
lines = _strip_html_to_lines(td)
if not lines:
continue
score = 0
for ln in lines:
lo = ln.lower()
if ":" in ln and any(k in lo for k in ("title", "author", "publisher", "year", "isbn", "language", "series", "tags")):
score += 1
if score > best_score:
best_score = score
best_lines = lines
# Fallback: treat the entire page as a line list.
if not best_lines:
best_lines = _strip_html_to_lines(s)
raw_fields: Dict[str, str] = {}
pending_key: Optional[str] = None
def _norm_key(k: str) -> str:
kk = str(k or "").strip().lower()
kk = re.sub(r"\s+", " ", kk)
if kk in {"authors", "author(s)", "author(s).", "author(s):"}:
return "author"
if kk in {"tag", "tags"}:
return "tags"
return kk
for ln in best_lines:
line = str(ln or "").strip()
if not line:
continue
if ":" in line:
k, v = line.split(":", 1)
k = _norm_key(k)
v = str(v or "").strip()
if v:
raw_fields[k] = v
pending_key = None
else:
pending_key = k
continue
# Continuation line: if the previous key had no inline value, use this.
if pending_key:
raw_fields[pending_key] = line
pending_key = None
out: Dict[str, Any] = {"_raw_fields": dict(raw_fields)}
title = str(raw_fields.get("title") or "").strip()
if title:
out["title"] = title
publisher = str(raw_fields.get("publisher") or "").strip()
if publisher:
out["publisher"] = publisher
year = str(raw_fields.get("year") or "").strip()
if year:
out["year"] = year
language = str(raw_fields.get("language") or "").strip()
if language:
out["language"] = language
authors_raw = str(raw_fields.get("author") or "").strip()
if authors_raw:
out["authors"] = _split_listish_text(authors_raw)
# ISBN: extract all tokens (some pages include multiple).
isbn_raw = str(raw_fields.get("isbn") or "").strip()
if isbn_raw:
isbns = _extract_isbns(isbn_raw)
if isbns:
out["isbn"] = isbns
tags_raw = str(raw_fields.get("tags") or "").strip()
if tags_raw:
# Keep these as freeform tags (split on commas/semicolons/pipes).
out["tags"] = _split_listish_text(tags_raw)
return out
def _extract_anchor_texts(raw_html: str) -> List[str]:
out: List[str] = []
for m in re.finditer(r"(?is)<a\b[^>]*>(.*?)</a>", str(raw_html or "")):
t = _strip_html_to_text(m.group(1))
if t:
out.append(t)
# De-dupe, preserve order
seen: set[str] = set()
uniq: List[str] = []
for x in out:
k = x.strip()
if not k:
continue
if k.lower() in seen:
continue
seen.add(k.lower())
uniq.append(k)
return uniq
def _split_listish_text(value: str) -> List[str]:
s = str(value or "").strip()
if not s:
return []
parts = re.split(r"\s*(?:,|;|\|)\s*", s)
out: List[str] = []
for p in parts:
p = str(p or "").strip()
if p:
out.append(p)
return out
def _extract_isbns(text: str) -> List[str]:
s = str(text or "")
candidates = re.findall(r"\b[0-9Xx][0-9Xx\-\s]{8,20}[0-9Xx]\b", s)
out: List[str] = []
for c in candidates:
n = re.sub(r"[^0-9Xx]", "", c).upper()
if len(n) not in (10, 13):
continue
if n not in out:
out.append(n)
# Also handle already-clean tokens.
for c in re.findall(r"\b(?:97[89])?\d{9}[\dXx]\b", s):
n = str(c).upper()
if n not in out:
out.append(n)
return out
def _libgen_id_from_url(url: str) -> str:
# Handles edition.php?id=..., file.php?id=...
m = re.search(r"(?:\?|&)id=(\d+)", str(url or ""), flags=re.IGNORECASE)
return str(m.group(1)) if m else ""
def _prefer_isbn(isbns: List[str]) -> str:
vals = [str(x or "").strip() for x in (isbns or []) if str(x or "").strip()]
# Prefer ISBN-13, then ISBN-10.
for v in vals:
if len(v) == 13:
return v
for v in vals:
if len(v) == 10:
return v
return vals[0] if vals else ""
def _enrich_book_tags_from_isbn(isbn: str, *, config: Optional[Dict[str, Any]] = None) -> Tuple[List[str], str]:
"""Return (tags, source_name) for the given ISBN.
Priority:
1) OpenLibrary API-by-ISBN scrape (fast, structured)
2) isbnsearch.org scrape via MetadataProvider
"""
isbn_clean = re.sub(r"[^0-9Xx]", "", str(isbn or "")).upper()
if len(isbn_clean) not in (10, 13):
return [], ""
# 1) OpenLibrary API lookup by ISBN (short timeout, silent failure).
try:
url = f"https://openlibrary.org/api/books?bibkeys=ISBN:{isbn_clean}&jscmd=data&format=json"
resp = requests.get(url, timeout=4)
resp.raise_for_status()
data = resp.json()
if isinstance(data, dict) and data:
book_data = next(iter(data.values()), None)
else:
book_data = None
if isinstance(book_data, dict):
tags: List[str] = []
def _add(t: str) -> None:
s = str(t or "").strip()
if s:
tags.append(s)
if book_data.get("title"):
_add(f"title:{book_data['title']}")
authors = book_data.get("authors")
if isinstance(authors, list):
for a in authors[:3]:
if isinstance(a, dict) and a.get("name"):
_add(f"author:{a['name']}")
if book_data.get("publish_date"):
_add(f"publish_date:{book_data['publish_date']}")
publishers = book_data.get("publishers")
if isinstance(publishers, list) and publishers:
pub0 = publishers[0]
if isinstance(pub0, dict) and pub0.get("name"):
_add(f"publisher:{pub0['name']}")
desc = book_data.get("description")
if isinstance(desc, dict) and "value" in desc:
desc = desc.get("value")
if desc:
desc_str = str(desc).strip()
if desc_str:
_add(f"description:{desc_str[:200]}")
pages = book_data.get("number_of_pages")
if isinstance(pages, int) and pages > 0:
_add(f"pages:{pages}")
identifiers = book_data.get("identifiers")
if isinstance(identifiers, dict):
def _first(value: Any) -> Any:
if isinstance(value, list) and value:
return value[0]
return value
for key, ns in (
("openlibrary", "openlibrary"),
("lccn", "lccn"),
("oclc", "oclc"),
("goodreads", "goodreads"),
("librarything", "librarything"),
("doi", "doi"),
("internet_archive", "internet_archive"),
):
val = _first(identifiers.get(key))
if val:
_add(f"{ns}:{val}")
if not any(str(t).lower().startswith("isbn:") for t in tags):
tags.insert(0, f"isbn:{isbn_clean}")
# De-dupe case-insensitively, preserve order.
seen: set[str] = set()
out: List[str] = []
for t in tags:
k = str(t).strip().lower()
if not k or k in seen:
continue
seen.add(k)
out.append(str(t).strip())
if out:
return out, "openlibrary"
except Exception:
pass
# 2) isbnsearch metadata provider fallback.
try:
from Provider.metadata_provider import get_metadata_provider
provider = get_metadata_provider("isbnsearch", config or {})
if provider is None:
return [], ""
items = provider.search(isbn_clean, limit=1)
if not items:
return [], ""
tags = provider.to_tags(items[0])
if not any(str(t).lower().startswith("isbn:") for t in tags):
tags = [f"isbn:{isbn_clean}"] + [str(t) for t in tags]
return [str(t) for t in tags if str(t).strip()], provider.name
except Exception:
return [], ""
def _fetch_libgen_details_html(url: str, *, timeout: Optional[Tuple[float, float]] = None) -> Optional[str]:
try:
if timeout is None:
timeout = (DEFAULT_CONNECT_TIMEOUT, DEFAULT_READ_TIMEOUT)
session = requests.Session()
session.headers.update(
{
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36",
}
)
with session.get(str(url), stream=True, timeout=timeout) as resp:
resp.raise_for_status()
ct = str(resp.headers.get("Content-Type", "")).lower()
if "text/html" not in ct:
return None
return resp.text
except Exception:
return None
def _parse_libgen_details_html(html: str) -> Dict[str, Any]:
"""Parse LibGen details-page HTML (edition.php/file.php) into a metadata dict.
Best-effort and intentionally tolerant of mirror variations.
"""
out: Dict[str, Any] = {}
raw_fields: Dict[str, str] = {}
s = str(html or "")
# Fast path: try to pull simple Label/Value table rows.
for m in re.finditer(
r"(?is)<tr\b[^>]*>\s*<t[dh]\b[^>]*>\s*([^<]{1,80}?)\s*:??\s*</t[dh]>\s*<t[dh]\b[^>]*>(.*?)</t[dh]>\s*</tr>",
s,
):
label = _strip_html_to_text(m.group(1))
raw_val_html = str(m.group(2) or "")
if not label:
continue
val_text = _strip_html_to_text(raw_val_html)
if not val_text:
continue
raw_fields[label] = val_text
norm = re.sub(r"[^a-z0-9]+", "_", label.strip().lower()).strip("_")
if not norm:
continue
# Prefer anchors for multi-valued fields.
anchors = _extract_anchor_texts(raw_val_html)
if anchors:
out[norm] = anchors
else:
out[norm] = val_text
# Some libgen.gl edition pages group metadata as repeated blocks like:
# <strong>Title:</strong>
# The Title
# We'll parse those too (best-effort, no DOM required).
strong_matches = list(re.finditer(r"(?is)<strong\b[^>]*>(.*?)</strong>", s))
if strong_matches:
for idx, m in enumerate(strong_matches):
label_raw = _strip_html_to_text(m.group(1))
label = str(label_raw or "").strip()
if not label:
continue
# Normalize label (strip trailing colon if present).
if label.endswith(":"):
label = label[:-1].strip()
chunk_start = m.end()
chunk_end = strong_matches[idx + 1].start() if (idx + 1) < len(strong_matches) else len(s)
raw_val_html = s[chunk_start:chunk_end]
# If we already have a value for this label from a table row, keep it.
if label in raw_fields:
continue
val_text = _strip_html_to_text(raw_val_html)
if not val_text:
continue
raw_fields[label] = val_text
norm = re.sub(r"[^a-z0-9]+", "_", label.strip().lower()).strip("_")
if not norm:
continue
anchors = _extract_anchor_texts(raw_val_html)
if anchors:
out[norm] = anchors
else:
out[norm] = val_text
# Normalize keys of interest.
def _first_str(v: Any) -> str:
if isinstance(v, list) and v:
return str(v[0] or "").strip()
return str(v or "").strip()
title = _first_str(out.get("title"))
if title:
out["title"] = title
authors = out.get("author_s") or out.get("authors") or out.get("author")
if isinstance(authors, str):
authors_list = _split_listish_text(authors)
elif isinstance(authors, list):
authors_list = [str(x).strip() for x in authors if str(x).strip()]
else:
authors_list = []
if authors_list:
out["authors"] = authors_list
publisher = _first_str(out.get("publisher"))
if publisher:
out["publisher"] = publisher
year = _first_str(out.get("year"))
if year:
out["year"] = year
language = _first_str(out.get("language"))
if language:
out["language"] = language
oclc = _first_str(out.get("oclc_worldcat")) or _first_str(out.get("oclc"))
if oclc:
m_oclc = re.search(r"\b\d{5,15}\b", oclc)
out["oclc"] = str(m_oclc.group(0)) if m_oclc else oclc
tags_val = out.get("tags")
if isinstance(tags_val, list):
tags_list = [str(x).strip() for x in tags_val if str(x).strip()]
elif isinstance(tags_val, str):
tags_list = _split_listish_text(tags_val)
else:
tags_list = []
if tags_list:
out["tags"] = tags_list
isbn_val = out.get("isbn")
isbn_text = ""
if isinstance(isbn_val, list):
isbn_text = " ".join([str(x) for x in isbn_val if x])
else:
isbn_text = str(isbn_val or "")
isbns = _extract_isbns(isbn_text)
if isbns:
out["isbn"] = isbns
edition_id = _first_str(out.get("edition_id"))
if edition_id:
m_eid = re.search(r"\b\d+\b", edition_id)
out["edition_id"] = str(m_eid.group(0)) if m_eid else edition_id
if raw_fields:
out["_raw_fields"] = raw_fields
return out
def _libgen_metadata_to_tags(meta: Dict[str, Any]) -> List[str]:
tags: List[str] = []
seen: set[str] = set()
def _add(t: str) -> None:
s = str(t or "").strip()
if not s:
return
k = s.lower()
if k in seen:
return
seen.add(k)
tags.append(s)
title = str(meta.get("title") or "").strip()
if title:
_add(f"title:{title}")
for a in meta.get("authors") or []:
a = str(a or "").strip()
if a:
_add(f"author:{a}")
publisher = str(meta.get("publisher") or "").strip()
if publisher:
_add(f"publisher:{publisher}")
year = str(meta.get("year") or "").strip()
if year:
_add(f"year:{year}")
language = str(meta.get("language") or "").strip()
if language:
_add(f"language:{language}")
for isbn in meta.get("isbn") or []:
isbn = str(isbn or "").strip().replace("-", "")
if isbn:
_add(f"isbn:{isbn}")
oclc = str(meta.get("oclc") or "").strip()
if oclc:
_add(f"oclc:{oclc}")
edition_id = str(meta.get("edition_id") or "").strip()
if edition_id:
_add(f"libgen_edition_id:{edition_id}")
# Freeform tags (no "tags:" prefix).
for t in meta.get("tags") or []:
t = str(t or "").strip()
if t:
_add(t)
# Any additional structured fields we captured are preserved under a libgen_ namespace.
raw_fields = meta.get("_raw_fields")
if isinstance(raw_fields, dict):
for k, v in raw_fields.items():
lk = str(k or "").strip().lower()
if lk in {"title", "author(s)", "authors", "author", "publisher", "year", "isbn", "language", "oclc/worldcat", "tags", "edition id"}:
continue
vv = str(v or "").strip()
if not vv:
continue
ns = re.sub(r"[^a-z0-9]+", "_", lk).strip("_")
if ns:
_add(f"libgen_{ns}:{vv}")
return tags
class Libgen(Provider):
# Domains that should be routed to this provider when the user supplies a URL.
# (Used by ProviderCore.registry.match_provider_name_for_url)
@@ -146,6 +736,15 @@ class Libgen(Provider):
md5 = str(md.get("md5") or "").strip()
extension = str(md.get("extension") or "").strip().lstrip(".")
# If the user passed ads.php/get.php directly, capture md5 from the URL so
# filenames are stable (avoid always writing `libgen.pdf`).
if (not md5) and isinstance(target, str) and target.startswith("http"):
md5 = _libgen_md5_from_url(target)
if md5:
md["md5"] = md5
# Defer LibGen details-page metadata and ISBN enrichment until AFTER the file is downloaded.
if (not target) or target.startswith("libgen:"):
if md5 and re.fullmatch(r"[a-fA-F0-9]{32}", md5):
target = urljoin(MIRRORS[0], f"/ads.php?md5={md5}")
@@ -153,7 +752,10 @@ class Libgen(Provider):
if not target:
return None
base_name = sanitize_filename(title or md5 or "libgen")
if title and title.startswith("http"):
title = ""
base_name = sanitize_filename(title or md5 or (f"libgen_{_libgen_id_from_url(target)}" if _libgen_id_from_url(target) else "libgen"))
out_path = output_dir / base_name
if extension:
out_path = out_path.with_suffix(f".{extension}")
@@ -190,6 +792,122 @@ class Libgen(Provider):
ok, final_path = download_from_mirror(target, out_path, progress_callback=progress_callback)
progress_bar.finish()
if ok and final_path:
# After the download completes, best-effort fetch details metadata (title + ISBN)
# and then enrich tags via OpenLibrary/isbnsearch. This ensures enrichment never
# blocks the download itself.
try:
if isinstance(target, str) and target.startswith("http"):
low = target.lower()
# Preferred: ads.php pages often embed a complete tag block.
# Parse it post-download (best-effort) and do NOT perform external
# enrichment (OpenLibrary/isbnsearch) unless the user later chooses to.
if ("/ads.php" in low) or ("/get.php" in low):
ads_url = target if "/ads.php" in low else _libgen_ads_url_for_target(target)
if ads_url:
html = _fetch_libgen_details_html(ads_url, timeout=(DEFAULT_CONNECT_TIMEOUT, 4.0))
if html:
meta = _parse_libgen_ads_tags_html(html)
extracted_title = str(meta.get("title") or "").strip()
if extracted_title:
md["title"] = extracted_title
result.tag.add(f"title:{extracted_title}")
if (not title) or title.startswith("http"):
title = extracted_title
authors = meta.get("authors") if isinstance(meta.get("authors"), list) else []
for a in (authors or []):
aa = str(a or "").strip()
if aa:
result.tag.add(f"author:{aa}")
publisher = str(meta.get("publisher") or "").strip()
if publisher:
md["publisher"] = publisher
result.tag.add(f"publisher:{publisher}")
year = str(meta.get("year") or "").strip()
if year:
md["year"] = year
result.tag.add(f"year:{year}")
language = str(meta.get("language") or "").strip()
if language:
md["language"] = language
result.tag.add(f"language:{language}")
isbns = meta.get("isbn") if isinstance(meta.get("isbn"), list) else []
isbns = [str(x).strip() for x in (isbns or []) if str(x).strip()]
if isbns:
md["isbn"] = isbns
for isbn_val in isbns:
result.tag.add(f"isbn:{isbn_val}")
free_tags = meta.get("tags") if isinstance(meta.get("tags"), list) else []
for t in (free_tags or []):
tt = str(t or "").strip()
if tt:
result.tag.add(tt)
# Preserve any other extracted fields (namespaced).
raw_fields = meta.get("_raw_fields")
if isinstance(raw_fields, dict):
for k, v in raw_fields.items():
lk = str(k or "").strip().lower()
if lk in {"title", "author", "authors", "publisher", "year", "isbn", "language", "tags"}:
continue
vv = str(v or "").strip()
if not vv:
continue
ns = re.sub(r"[^a-z0-9]+", "_", lk).strip("_")
if ns:
result.tag.add(f"libgen_{ns}:{vv}")
# Legacy: edition/file/series details pages (title + ISBN) + external enrichment.
if ("/edition.php" in low) or ("/file.php" in low) or ("/series.php" in low):
html = _fetch_libgen_details_html(target)
if html:
meta = _parse_libgen_details_html(html)
if not meta.get("edition_id"):
eid = _libgen_id_from_url(target)
if eid:
meta["edition_id"] = eid
extracted_title = str(meta.get("title") or "").strip()
extracted_isbns = meta.get("isbn") if isinstance(meta.get("isbn"), list) else []
extracted_isbns = [str(x).strip() for x in (extracted_isbns or []) if str(x).strip()]
if extracted_title:
md["title"] = extracted_title
result.tag.add(f"title:{extracted_title}")
if extracted_isbns:
md["isbn"] = extracted_isbns
for isbn_val in extracted_isbns:
isbn_norm = str(isbn_val).strip().replace("-", "")
if isbn_norm:
result.tag.add(f"isbn:{isbn_norm}")
if meta.get("edition_id"):
md["edition_id"] = str(meta.get("edition_id"))
preferred_isbn = _prefer_isbn(extracted_isbns)
if preferred_isbn:
enriched_tags, enriched_source = _enrich_book_tags_from_isbn(
preferred_isbn,
config=getattr(self, "config", None),
)
if enriched_tags:
try:
result.tag.update(set(enriched_tags))
except Exception:
pass
if enriched_source:
md["metadata_enriched_from"] = enriched_source
if extracted_title and ((not title) or title.startswith("http")):
title = extracted_title
except Exception:
pass
return Path(final_path)
return None
except Exception:
@@ -751,6 +1469,34 @@ def _resolve_download_url(
if not html:
return None
# LibGen chain helpers (for environments without lxml).
# Typical chain:
# edition.php?id=... -> file.php?id=...
# file.php?id=... -> ads.php?md5=... (or get.php?md5=...)
# ads.php?md5=... -> get.php?md5=...
# get.php?md5=... -> file response
# Handle edition -> file links.
m = re.search(r'href=["\']([^"\']*file\.php\?id=\d+[^"\']*)["\']', html, flags=re.IGNORECASE)
if m:
href = str(m.group(1) or "").strip()
if href and not href.lower().startswith("javascript:"):
return urljoin(base_url, href)
# Handle series -> edition links.
m = re.search(r'href=["\']([^"\']*edition\.php\?id=\d+[^"\']*)["\']', html, flags=re.IGNORECASE)
if m:
href = str(m.group(1) or "").strip()
if href and not href.lower().startswith("javascript:"):
return urljoin(base_url, href)
# Handle file -> ads/get links (sometimes present as the "Libgen" mirror).
m = re.search(r'href=["\']([^"\']*ads\.php\?md5=[a-fA-F0-9]{32}[^"\']*)["\']', html, flags=re.IGNORECASE)
if m:
href = str(m.group(1) or "").strip()
if href and not href.lower().startswith("javascript:"):
return urljoin(base_url, href)
# Prefer explicit get.php md5 links (most common successful chain).
m = re.search(r'href=["\']([^"\']*get\.php\?md5=[a-fA-F0-9]{32}[^"\']*)["\']', html, flags=re.IGNORECASE)
if m:

View File

@@ -2,6 +2,8 @@ from __future__ import annotations
from abc import ABC, abstractmethod
from typing import Any, Dict, List, Optional, Type, cast
import html as html_std
import re
import requests
import sys
import json
@@ -279,6 +281,199 @@ class GoogleBooksMetadataProvider(MetadataProvider):
return tags
class ISBNsearchMetadataProvider(MetadataProvider):
"""Metadata provider that scrapes isbnsearch.org by ISBN.
This is a best-effort HTML scrape. It expects the query to be an ISBN.
"""
@property
def name(self) -> str: # type: ignore[override]
return "isbnsearch"
@staticmethod
def _strip_html_to_text(raw: str) -> str:
s = html_std.unescape(str(raw or ""))
s = re.sub(r"(?i)<br\s*/?>", "\n", s)
s = re.sub(r"<[^>]+>", " ", s)
s = re.sub(r"\s+", " ", s)
return s.strip()
@staticmethod
def _clean_isbn(query: str) -> str:
s = str(query or "").strip()
if not s:
return ""
s = s.replace("isbn:", "").replace("ISBN:", "")
s = re.sub(r"[^0-9Xx]", "", s).upper()
if len(s) in (10, 13):
return s
# Try to locate an ISBN-like token inside the query.
m = re.search(r"\b(?:97[89])?\d{9}[\dXx]\b", s)
return str(m.group(0)).upper() if m else ""
def search(self, query: str, limit: int = 10) -> List[Dict[str, Any]]:
_ = limit
isbn = self._clean_isbn(query)
if not isbn:
return []
url = f"https://isbnsearch.org/isbn/{isbn}"
try:
resp = requests.get(url, timeout=10)
resp.raise_for_status()
html = str(resp.text or "")
if not html:
return []
except Exception as exc:
log(f"ISBNsearch scrape failed: {exc}", file=sys.stderr)
return []
title = ""
m_title = re.search(r"(?is)<h1\b[^>]*>(.*?)</h1>", html)
if m_title:
title = self._strip_html_to_text(m_title.group(1))
raw_fields: Dict[str, str] = {}
strong_matches = list(re.finditer(r"(?is)<strong\b[^>]*>(.*?)</strong>", html))
for idx, m in enumerate(strong_matches):
label_raw = self._strip_html_to_text(m.group(1))
label = str(label_raw or "").strip()
if not label:
continue
if label.endswith(":"):
label = label[:-1].strip()
chunk_start = m.end()
# Stop at next <strong> or end of document.
chunk_end = strong_matches[idx + 1].start() if (idx + 1) < len(strong_matches) else len(html)
chunk = html[chunk_start:chunk_end]
# Prefer stopping within the same paragraph when possible.
m_end = re.search(r"(?is)(</p>|<br\s*/?>)", chunk)
if m_end:
chunk = chunk[: m_end.start()]
val_text = self._strip_html_to_text(chunk)
if not val_text:
continue
raw_fields[label] = val_text
def _get(*labels: str) -> str:
for lab in labels:
for k, v in raw_fields.items():
if str(k).strip().lower() == str(lab).strip().lower():
return str(v or "").strip()
return ""
# Map common ISBNsearch labels.
author_text = _get("Author", "Authors", "Author(s)")
publisher = _get("Publisher")
published = _get("Published", "Publication Date", "Publish Date")
language = _get("Language")
pages = _get("Pages")
isbn_13 = _get("ISBN-13", "ISBN13")
isbn_10 = _get("ISBN-10", "ISBN10")
year = ""
if published:
m_year = re.search(r"\b(\d{4})\b", published)
year = str(m_year.group(1)) if m_year else ""
authors: List[str] = []
if author_text:
# Split on common separators; keep multi-part names intact.
for part in re.split(r"\s*(?:,|;|\band\b|\&|\|)\s*", author_text, flags=re.IGNORECASE):
p = str(part or "").strip()
if p:
authors.append(p)
# Prefer parsed title, but fall back to og:title if needed.
if not title:
m_og = re.search(r"(?is)<meta\b[^>]*property=['\"]og:title['\"][^>]*content=['\"](.*?)['\"][^>]*>", html)
if m_og:
title = self._strip_html_to_text(m_og.group(1))
# Ensure ISBN tokens are normalized.
isbn_tokens: List[str] = []
for token in [isbn_13, isbn_10, isbn]:
t = self._clean_isbn(token)
if t and t not in isbn_tokens:
isbn_tokens.append(t)
item: Dict[str, Any] = {
"title": title or "",
# Keep UI columns compatible with the generic metadata table.
"artist": ", ".join(authors) if authors else "",
"album": publisher or "",
"year": year or "",
"provider": self.name,
"authors": authors,
"publisher": publisher or "",
"language": language or "",
"pages": pages or "",
"identifiers": {
"isbn_13": next((t for t in isbn_tokens if len(t) == 13), None),
"isbn_10": next((t for t in isbn_tokens if len(t) == 10), None),
},
"raw_fields": raw_fields,
}
# Only return usable items.
if not item.get("title") and not any(item["identifiers"].values()):
return []
return [item]
def to_tags(self, item: Dict[str, Any]) -> List[str]:
tags: List[str] = []
title = str(item.get("title") or "").strip()
if title:
tags.append(f"title:{title}")
authors = item.get("authors") or []
if isinstance(authors, list):
for a in authors:
a = str(a or "").strip()
if a:
tags.append(f"author:{a}")
publisher = str(item.get("publisher") or "").strip()
if publisher:
tags.append(f"publisher:{publisher}")
year = str(item.get("year") or "").strip()
if year:
tags.append(f"year:{year}")
language = str(item.get("language") or "").strip()
if language:
tags.append(f"language:{language}")
identifiers = item.get("identifiers") or {}
if isinstance(identifiers, dict):
for key in ("isbn_13", "isbn_10"):
val = identifiers.get(key)
if val:
tags.append(f"isbn:{val}")
tags.append(f"source:{self.name}")
# Dedup case-insensitively, preserve order.
seen: set[str] = set()
out: List[str] = []
for t in tags:
s = str(t or "").strip()
if not s:
continue
k = s.lower()
if k in seen:
continue
seen.add(k)
out.append(s)
return out
class MusicBrainzMetadataProvider(MetadataProvider):
"""Metadata provider for MusicBrainz recordings."""
@@ -517,6 +712,7 @@ _METADATA_PROVIDERS: Dict[str, Type[MetadataProvider]] = {
"openlibrary": OpenLibraryMetadataProvider,
"googlebooks": GoogleBooksMetadataProvider,
"google": GoogleBooksMetadataProvider,
"isbnsearch": ISBNsearchMetadataProvider,
"musicbrainz": MusicBrainzMetadataProvider,
"ytdlp": YtdlpMetadataProvider,
}

View File

@@ -190,6 +190,7 @@ def _archive_id_from_url(url: str) -> str:
u = str(url or "").strip()
if not u:
return ""
try:
p = urlparse(u)
host = (p.hostname or "").lower().strip()
@@ -215,6 +216,175 @@ def _archive_id_from_url(url: str) -> str:
return ""
def _coerce_archive_field_list(value: Any) -> List[str]:
"""Coerce an Archive.org metadata field to a list of strings."""
if value is None:
return []
if isinstance(value, list):
out: List[str] = []
for v in value:
try:
s = str(v).strip()
except Exception:
continue
if s:
out.append(s)
return out
if isinstance(value, (tuple, set)):
out = []
for v in value:
try:
s = str(v).strip()
except Exception:
continue
if s:
out.append(s)
return out
try:
s = str(value).strip()
except Exception:
return []
return [s] if s else []
def _archive_item_metadata_to_tags(archive_id: str, item_metadata: Dict[str, Any]) -> List[str]:
"""Map Archive.org metadata JSON (the `metadata` object) to tag strings.
This is intentionally best-effort and conservative: it focuses on stable,
useful bibliographic fields (title/author/publisher/ISBN/identifier/topics).
"""
archive_id_clean = str(archive_id or "").strip()
meta = item_metadata if isinstance(item_metadata, dict) else {}
tags: List[str] = []
seen: set[str] = set()
def _add(tag: str) -> None:
try:
t = str(tag).strip()
except Exception:
return
if not t:
return
if t.lower() in seen:
return
seen.add(t.lower())
tags.append(t)
if archive_id_clean:
_add(f"internet_archive:{archive_id_clean}")
# Title
for title in _coerce_archive_field_list(meta.get("title"))[:1]:
_add(f"title:{title}")
# Authors/creators
creators: List[str] = []
creators.extend(_coerce_archive_field_list(meta.get("creator")))
creators.extend(_coerce_archive_field_list(meta.get("author")))
for creator in creators[:3]:
_add(f"author:{creator}")
# Publisher
for publisher in _coerce_archive_field_list(meta.get("publisher"))[:3]:
_add(f"publisher:{publisher}")
# Publish date/year
for date_val in _coerce_archive_field_list(meta.get("date"))[:1]:
_add(f"publish_date:{date_val}")
for year_val in _coerce_archive_field_list(meta.get("year"))[:1]:
_add(f"publish_date:{year_val}")
# Language
for lang in _coerce_archive_field_list(meta.get("language"))[:3]:
_add(f"language:{lang}")
# Topics/subjects: follow existing OpenLibrary behavior (un-namespaced tags)
for subj in _coerce_archive_field_list(meta.get("subject"))[:15]:
if len(subj) > 200:
subj = subj[:200]
_add(subj)
# ISBNs and identifiers
def _clean_isbn(raw: str) -> str:
return str(raw or "").replace("-", "").strip()
for isbn in _coerce_archive_field_list(meta.get("isbn"))[:10]:
isbn_clean = _clean_isbn(isbn)
if isbn_clean:
_add(f"isbn:{isbn_clean}")
identifiers: List[str] = []
identifiers.extend(_coerce_archive_field_list(meta.get("identifier")))
identifiers.extend(_coerce_archive_field_list(meta.get("external-identifier")))
added_other = 0
for ident in identifiers:
ident_s = str(ident or "").strip()
if not ident_s:
continue
low = ident_s.lower()
if low.startswith("urn:isbn:"):
val = _clean_isbn(ident_s.split(":", 2)[-1])
if val:
_add(f"isbn:{val}")
continue
if low.startswith("isbn:"):
val = _clean_isbn(ident_s.split(":", 1)[-1])
if val:
_add(f"isbn:{val}")
continue
if low.startswith("urn:oclc:"):
val = ident_s.split(":", 2)[-1].strip()
if val:
_add(f"oclc:{val}")
continue
if low.startswith("oclc:"):
val = ident_s.split(":", 1)[-1].strip()
if val:
_add(f"oclc:{val}")
continue
if low.startswith("urn:lccn:"):
val = ident_s.split(":", 2)[-1].strip()
if val:
_add(f"lccn:{val}")
continue
if low.startswith("lccn:"):
val = ident_s.split(":", 1)[-1].strip()
if val:
_add(f"lccn:{val}")
continue
if low.startswith("doi:"):
val = ident_s.split(":", 1)[-1].strip()
if val:
_add(f"doi:{val}")
continue
if archive_id_clean and low == archive_id_clean.lower():
continue
if added_other >= 5:
continue
if len(ident_s) > 200:
ident_s = ident_s[:200]
_add(f"identifier:{ident_s}")
added_other += 1
return tags
def _fetch_archive_item_metadata(archive_id: str, *, timeout: int = 8) -> Dict[str, Any]:
ident = str(archive_id or "").strip()
if not ident:
return {}
resp = requests.get(f"https://archive.org/metadata/{ident}", timeout=int(timeout))
resp.raise_for_status()
data = resp.json() if resp is not None else {}
if not isinstance(data, dict):
return {}
meta = data.get("metadata")
return meta if isinstance(meta, dict) else {}
class OpenLibrary(Provider):
# Domains that should be routed to this provider when the user supplies a URL.
# (Used by ProviderCore.registry.match_provider_name_for_url)
@@ -1046,6 +1216,25 @@ class OpenLibrary(Provider):
log("[openlibrary] No archive identifier available; cannot download", file=sys.stderr)
return None
# Best-effort metadata scrape to attach bibliographic tags for downstream cmdlets.
try:
archive_meta = _fetch_archive_item_metadata(archive_id)
tags = _archive_item_metadata_to_tags(archive_id, archive_meta)
if tags:
try:
result.tag.update(tags)
except Exception:
# Fallback for callers that pass plain dicts.
pass
if isinstance(meta, dict):
meta["archive_id"] = archive_id
if archive_meta:
meta["archive_metadata"] = archive_meta
result.full_metadata = meta
except Exception:
# Never block downloads on metadata fetch.
pass
safe_title = sanitize_filename(result.title)
if not safe_title or "http" in safe_title.lower():
safe_title = sanitize_filename(archive_id) or "archive"

View File

@@ -306,36 +306,41 @@ class Soulseek(Provider):
client = SoulSeekClient(settings)
with _suppress_aioslsk_noise():
try:
await client.start()
await client.login()
except Exception as exc:
log(f"[soulseek] Login failed: {type(exc).__name__}: {exc}", file=sys.stderr)
return []
async with _suppress_aioslsk_asyncio_task_noise():
try:
await client.start()
await client.login()
except Exception as exc:
log(f"[soulseek] Login failed: {type(exc).__name__}: {exc}", file=sys.stderr)
return []
try:
search_request = await client.searches.search(query)
await self._collect_results(search_request, timeout=timeout)
return self._flatten_results(search_request)[:limit]
except Exception as exc:
log(f"[soulseek] Search error: {type(exc).__name__}: {exc}", file=sys.stderr)
return []
finally:
# Best-effort: try to cancel/close the search request before stopping
# the client to reduce stray reply spam.
try:
if "search_request" in locals() and search_request is not None:
cancel = getattr(search_request, "cancel", None)
if callable(cancel):
maybe = cancel()
if asyncio.iscoroutine(maybe):
await maybe
except Exception:
pass
try:
await client.stop()
except Exception:
pass
search_request = await client.searches.search(query)
await self._collect_results(search_request, timeout=timeout)
return self._flatten_results(search_request)[:limit]
except Exception as exc:
log(f"[soulseek] Search error: {type(exc).__name__}: {exc}", file=sys.stderr)
return []
finally:
# Best-effort: try to cancel/close the search request before stopping
# the client to reduce stray reply spam.
try:
if "search_request" in locals() and search_request is not None:
cancel = getattr(search_request, "cancel", None)
if callable(cancel):
maybe = cancel()
if asyncio.iscoroutine(maybe):
await maybe
except Exception:
pass
try:
await client.stop()
except Exception:
pass
try:
await asyncio.sleep(0)
except Exception:
pass
def _flatten_results(self, search_request: Any) -> List[dict]:
flat: List[dict] = []
@@ -558,93 +563,101 @@ async def download_soulseek_file(
async def _attempt_once(attempt_num: int) -> tuple[Optional[Path], Any, int, float]:
client = SoulSeekClient(settings)
with _suppress_aioslsk_noise():
try:
async with _suppress_aioslsk_asyncio_task_noise():
await client.start()
await client.login()
debug(f"[soulseek] Logged in as {login_user}")
log(
f"[soulseek] Download attempt {attempt_num}: {username} :: {local_filename}",
file=sys.stderr,
)
debug(f"[soulseek] Requesting download from {username}: {filename}")
transfer = await client.transfers.add(Transfer(username, filename, TransferDirection.DOWNLOAD))
transfer.local_path = str(output_path)
await client.transfers.queue(transfer)
start_time = time.time()
last_progress_time = start_time
progress_bar = ProgressBar()
while not transfer.is_finalized():
elapsed = time.time() - start_time
if elapsed > timeout:
log(f"[soulseek] Download timeout after {timeout}s", file=sys.stderr)
bytes_done = int(getattr(transfer, "bytes_transfered", 0) or 0)
state_val = getattr(getattr(transfer, "state", None), "VALUE", None)
progress_bar.finish()
return None, state_val, bytes_done, elapsed
bytes_done = int(getattr(transfer, "bytes_transfered", 0) or 0)
total_bytes = int(getattr(transfer, "filesize", 0) or 0)
now = time.time()
if now - last_progress_time >= 0.5:
progress_bar.update(
downloaded=bytes_done,
total=total_bytes if total_bytes > 0 else None,
label="download",
file=sys.stderr,
)
last_progress_time = now
await asyncio.sleep(1)
final_state = getattr(getattr(transfer, "state", None), "VALUE", None)
downloaded_path = Path(transfer.local_path) if getattr(transfer, "local_path", None) else output_path
final_elapsed = time.time() - start_time
# Clear in-place progress bar.
progress_bar.finish()
# If a file was written, treat it as success even if state is odd.
async with _suppress_aioslsk_asyncio_task_noise():
try:
if downloaded_path.exists() and downloaded_path.stat().st_size > 0:
if final_state != TransferState.COMPLETE:
log(
f"[soulseek] Transfer finalized as {final_state}, but file exists ({downloaded_path.stat().st_size} bytes). Keeping file.",
await client.start()
await client.login()
debug(f"[soulseek] Logged in as {login_user}")
log(
f"[soulseek] Download attempt {attempt_num}: {username} :: {local_filename}",
file=sys.stderr,
)
debug(f"[soulseek] Requesting download from {username}: {filename}")
transfer = await client.transfers.add(Transfer(username, filename, TransferDirection.DOWNLOAD))
transfer.local_path = str(output_path)
await client.transfers.queue(transfer)
start_time = time.time()
last_progress_time = start_time
progress_bar = ProgressBar()
while not transfer.is_finalized():
elapsed = time.time() - start_time
if elapsed > timeout:
log(f"[soulseek] Download timeout after {timeout}s", file=sys.stderr)
bytes_done = int(getattr(transfer, "bytes_transfered", 0) or 0)
state_val = getattr(getattr(transfer, "state", None), "VALUE", None)
progress_bar.finish()
return None, state_val, bytes_done, elapsed
bytes_done = int(getattr(transfer, "bytes_transfered", 0) or 0)
total_bytes = int(getattr(transfer, "filesize", 0) or 0)
now = time.time()
if now - last_progress_time >= 0.5:
progress_bar.update(
downloaded=bytes_done,
total=total_bytes if total_bytes > 0 else None,
label="download",
file=sys.stderr,
)
last_progress_time = now
await asyncio.sleep(1)
final_state = getattr(getattr(transfer, "state", None), "VALUE", None)
downloaded_path = (
Path(transfer.local_path)
if getattr(transfer, "local_path", None)
else output_path
)
final_elapsed = time.time() - start_time
# Clear in-place progress bar.
progress_bar.finish()
# If a file was written, treat it as success even if state is odd.
try:
if downloaded_path.exists() and downloaded_path.stat().st_size > 0:
if final_state != TransferState.COMPLETE:
log(
f"[soulseek] Transfer finalized as {final_state}, but file exists ({downloaded_path.stat().st_size} bytes). Keeping file.",
file=sys.stderr,
)
return downloaded_path, final_state, int(downloaded_path.stat().st_size), final_elapsed
except Exception:
pass
if final_state == TransferState.COMPLETE and downloaded_path.exists():
debug(f"[soulseek] Download complete: {downloaded_path}")
return downloaded_path, final_state, int(downloaded_path.stat().st_size), final_elapsed
except Exception:
pass
if final_state == TransferState.COMPLETE and downloaded_path.exists():
debug(f"[soulseek] Download complete: {downloaded_path}")
return downloaded_path, final_state, int(downloaded_path.stat().st_size), final_elapsed
fail_bytes = int(getattr(transfer, "bytes_transfered", 0) or 0)
fail_total = int(getattr(transfer, "filesize", 0) or 0)
reason = getattr(transfer, "reason", None)
log(
f"[soulseek] Download failed: state={final_state} bytes={fail_bytes}/{fail_total} reason={reason}",
file=sys.stderr,
)
fail_bytes = int(getattr(transfer, "bytes_transfered", 0) or 0)
fail_total = int(getattr(transfer, "filesize", 0) or 0)
reason = getattr(transfer, "reason", None)
log(
f"[soulseek] Download failed: state={final_state} bytes={fail_bytes}/{fail_total} reason={reason}",
file=sys.stderr,
)
# Clean up 0-byte placeholder.
try:
if downloaded_path.exists() and downloaded_path.stat().st_size == 0:
downloaded_path.unlink(missing_ok=True)
except Exception:
pass
return None, final_state, fail_bytes, final_elapsed
finally:
try:
await client.stop()
except Exception:
pass
# Clean up 0-byte placeholder.
try:
if downloaded_path.exists() and downloaded_path.stat().st_size == 0:
downloaded_path.unlink(missing_ok=True)
except Exception:
pass
return None, final_state, fail_bytes, final_elapsed
finally:
try:
await client.stop()
except Exception:
pass
# Let cancellation/cleanup callbacks run while our exception handler is still installed.
try:
await asyncio.sleep(0)
except Exception:
pass
# Retry a couple times only for fast 0-byte failures (common transient case).
max_attempts = 3

View File

@@ -606,6 +606,34 @@ def _download_direct_file(
except Exception as e:
if not quiet:
log(f"Could not get filename from headers: {e}", file=sys.stderr)
# Guardrail: never treat HTML landing pages as downloadable files.
# We explicitly probe with GET for page-like endpoints (e.g. *.php) since some
# servers block/lie on HEAD, and a URL path like `edition.php` would otherwise
# be saved as a bogus file.
try:
page_like_exts = {".php", ".asp", ".aspx", ".jsp", ".cgi"}
ext = ""
try:
ext = Path(str(filename or "")).suffix.lower()
except Exception:
ext = ""
ct0 = (content_type or "").split(";", 1)[0].strip().lower()
must_probe = bool(ct0.startswith("text/html") or ext in page_like_exts)
if must_probe:
with HTTPClient(timeout=10.0) as client:
with client._request_stream("GET", url, follow_redirects=True) as resp:
resp.raise_for_status()
ct = str(resp.headers.get("content-type", "") or "").split(";", 1)[0].strip().lower()
if ct.startswith("text/html"):
raise DownloadError("URL appears to be an HTML page, not a direct file")
except DownloadError:
raise
except Exception:
# If we can't probe, keep going; later logic may still infer a safe extension.
pass
# Apply suggested filename (from provider title) if given.
suggested = _sanitize_filename(suggested_filename) if suggested_filename else ""

View File

@@ -319,6 +319,18 @@ class Download_File(Cmdlet):
except Exception:
provider_name = None
# Heuristic: LibGen often uses landing pages like edition.php/file.php.
# These should never be treated as direct file URLs.
if not provider_name:
try:
p = urlparse(str(url))
h = (p.hostname or "").strip().lower()
path = (p.path or "").strip().lower()
if "libgen" in h and any(x in path for x in ("/edition.php", "/file.php", "/ads.php", "/get.php", "/series.php")):
provider_name = "libgen"
except Exception:
pass
if provider_name and get_provider is not None and SearchResult is not None:
# OpenLibrary URLs should be handled by the OpenLibrary provider.
if provider_name == "openlibrary":
@@ -391,11 +403,19 @@ class Download_File(Cmdlet):
progress.clear_status()
if downloaded_path:
tags_hint: Optional[List[str]] = None
try:
sr_tags = getattr(sr, "tag", None)
if isinstance(sr_tags, set) and sr_tags:
tags_hint = sorted([str(t) for t in sr_tags if t])
except Exception:
tags_hint = None
self._emit_local_file(
downloaded_path=Path(downloaded_path),
source=str(url),
title_hint=title_hint,
tags_hint=None,
tags_hint=tags_hint,
media_kind_hint="book",
full_metadata=sr.full_metadata,
provider_hint="openlibrary",
@@ -472,14 +492,42 @@ class Download_File(Cmdlet):
except Exception:
downloaded_path = None
# Refuse to fall back to direct-download for LibGen landing pages.
# This prevents saving HTML (e.g. edition.php) as a bogus file.
if (not downloaded_path) and str(provider_name).lower() == "libgen":
raise DownloadError("LibGen URL did not resolve to a downloadable file")
if downloaded_path:
tags_hint: Optional[List[str]] = None
full_md: Optional[Dict[str, Any]] = None
title_hint = Path(str(downloaded_path)).stem
media_kind_hint = "file"
if str(provider_name).lower() == "libgen":
media_kind_hint = "book"
try:
sr_tags = getattr(sr, "tag", None)
if isinstance(sr_tags, set) and sr_tags:
tags_hint = sorted([str(t) for t in sr_tags if t])
except Exception:
tags_hint = None
try:
if isinstance(getattr(sr, "full_metadata", None), dict):
full_md = sr.full_metadata
t = str(full_md.get("title") or "").strip()
if t:
title_hint = t
except Exception:
full_md = None
self._emit_local_file(
downloaded_path=Path(downloaded_path),
source=str(url),
title_hint=Path(str(downloaded_path)).stem,
tags_hint=None,
media_kind_hint="file",
full_metadata=None,
title_hint=title_hint,
tags_hint=tags_hint,
media_kind_hint=media_kind_hint,
full_metadata=full_md,
provider_hint=str(provider_name),
progress=progress,
config=config,
@@ -600,6 +648,7 @@ class Download_File(Cmdlet):
# If this looks like a provider item and providers are available, prefer provider.download()
downloaded_path: Optional[Path] = None
attempted_provider_download = False
provider_sr = None
if table and get_search_provider and SearchResult:
provider = get_search_provider(str(table), config)
if provider is not None:
@@ -612,6 +661,7 @@ class Download_File(Cmdlet):
)
debug(f"[download-file] Downloading provider item via {table}: {sr.title}")
downloaded_path = provider.download(sr, final_output_dir)
provider_sr = sr
# OpenLibrary: if provider download failed, do NOT try to download the OpenLibrary page HTML.
if downloaded_path is None and attempted_provider_download and str(table or "").lower() == "openlibrary":
@@ -693,6 +743,30 @@ class Download_File(Cmdlet):
log(f"Cannot download item (no provider handler / unsupported target): {title or target}", file=sys.stderr)
continue
# Allow providers to add/enrich tags and metadata during download.
if str(table or "").lower() == "libgen" and provider_sr is not None:
try:
sr_tags = getattr(provider_sr, "tag", None)
if tags_list is None and isinstance(sr_tags, set) and sr_tags:
tags_list = sorted([str(t) for t in sr_tags if t])
except Exception:
pass
try:
sr_md = getattr(provider_sr, "full_metadata", None)
if isinstance(sr_md, dict) and sr_md:
full_metadata = sr_md
except Exception:
pass
try:
if isinstance(full_metadata, dict):
t = str(full_metadata.get("title") or "").strip()
if t:
title = t
except Exception:
pass
self._emit_local_file(
downloaded_path=downloaded_path,
source=str(target) if target else None,

View File

@@ -1593,6 +1593,36 @@ class Download_Media(Cmdlet):
debug("Preflight URL check: no matches")
return True
# If the user already answered the duplicate URL prompt for this pipeline/command,
# respect that decision and don't re-prompt for every item.
try:
current_cmd_text = pipeline_context.get_current_command_text("")
except Exception:
current_cmd_text = ""
try:
stage_ctx = pipeline_context.get_stage_context()
except Exception:
stage_ctx = None
in_pipeline = bool(stage_ctx is not None or ("|" in str(current_cmd_text or "")))
if in_pipeline:
try:
cached_cmd = pipeline_context.load_value("preflight.url_duplicates.command", default="")
cached_decision = pipeline_context.load_value("preflight.url_duplicates.continue", default=None)
except Exception:
cached_cmd = ""
cached_decision = None
if cached_decision is not None and str(cached_cmd or "") == str(current_cmd_text or ""):
if bool(cached_decision):
return True
try:
pipeline_context.request_pipeline_stop(reason="duplicate-url declined", exit_code=0)
except Exception:
pass
return False
table = ResultTable(f"URL already exists ({len(url_matches)} match(es))")
results_list: List[Dict[str, Any]] = []
for item in url_matches:
@@ -1639,8 +1669,28 @@ class Download_Media(Cmdlet):
with cm:
get_stderr_console().print(table)
setattr(table, "_rendered_by_cmdlet", True)
if not Confirm.ask("Continue anyway?", default=False, console=get_stderr_console()):
if used_suspend:
answered_yes = bool(Confirm.ask("Continue anyway?", default=False, console=get_stderr_console()))
# Cache decision for the duration of this pipeline/command.
if in_pipeline:
try:
existing = pipeline_context.load_value("preflight", default=None)
except Exception:
existing = None
preflight_cache: Dict[str, Any] = existing if isinstance(existing, dict) else {}
url_dup_cache = preflight_cache.get("url_duplicates")
if not isinstance(url_dup_cache, dict):
url_dup_cache = {}
url_dup_cache["command"] = str(current_cmd_text or "")
url_dup_cache["continue"] = bool(answered_yes)
preflight_cache["url_duplicates"] = url_dup_cache
try:
pipeline_context.store_value("preflight", preflight_cache)
except Exception:
pass
if not answered_yes:
if in_pipeline and used_suspend:
try:
pipeline_context.request_pipeline_stop(reason="duplicate-url declined", exit_code=0)
except Exception:
@@ -1666,6 +1716,35 @@ class Download_Media(Cmdlet):
debug("Bulk URL preflight skipped: storage unavailable")
return True
# Honor any prior duplicate URL decision for this pipeline/command.
try:
current_cmd_text = pipeline_context.get_current_command_text("")
except Exception:
current_cmd_text = ""
try:
stage_ctx = pipeline_context.get_stage_context()
except Exception:
stage_ctx = None
in_pipeline = bool(stage_ctx is not None or ("|" in str(current_cmd_text or "")))
if in_pipeline:
try:
cached_cmd = pipeline_context.load_value("preflight.url_duplicates.command", default="")
cached_decision = pipeline_context.load_value("preflight.url_duplicates.continue", default=None)
except Exception:
cached_cmd = ""
cached_decision = None
if cached_decision is not None and str(cached_cmd or "") == str(current_cmd_text or ""):
if bool(cached_decision):
return True
try:
pipeline_context.request_pipeline_stop(reason="duplicate-url declined", exit_code=0)
except Exception:
pass
return False
unique_urls: List[str] = []
for u in urls or []:
s = str(u or "").strip()
@@ -1930,7 +2009,32 @@ class Download_Media(Cmdlet):
cm = nullcontext()
with cm:
if not Confirm.ask("Continue anyway?", default=False, console=get_stderr_console()):
answered_yes = bool(Confirm.ask("Continue anyway?", default=False, console=get_stderr_console()))
# Cache decision for the duration of this pipeline/command.
if in_pipeline:
try:
existing = pipeline_context.load_value("preflight", default=None)
except Exception:
existing = None
preflight_cache: Dict[str, Any] = existing if isinstance(existing, dict) else {}
url_dup_cache = preflight_cache.get("url_duplicates")
if not isinstance(url_dup_cache, dict):
url_dup_cache = {}
url_dup_cache["command"] = str(current_cmd_text or "")
url_dup_cache["continue"] = bool(answered_yes)
preflight_cache["url_duplicates"] = url_dup_cache
try:
pipeline_context.store_value("preflight", preflight_cache)
except Exception:
pass
if not answered_yes:
if in_pipeline:
try:
pipeline_context.request_pipeline_stop(reason="duplicate-url declined", exit_code=0)
except Exception:
pass
return False
return True
@@ -1947,6 +2051,20 @@ class Download_Media(Cmdlet):
if not isinstance(entries, list) or len(entries) <= 1:
return False
# Identify a stable table type so `@* | ...` pipelines can auto-insert the
# appropriate downloader stage (e.g., Bandcamp selections should insert
# `download-media` before `merge-file`).
extractor_name = ""
try:
extractor_name = str(pr.get("extractor") or pr.get("extractor_key") or "").strip().lower()
except Exception:
extractor_name = ""
table_type: Optional[str] = None
if "bandcamp" in extractor_name:
table_type = "bandcamp"
elif "youtube" in extractor_name:
table_type = "youtube"
# Display table (limit rows to keep output reasonable)
max_rows = 200
display_entries = entries[:max_rows]
@@ -1976,6 +2094,11 @@ class Download_Media(Cmdlet):
table = ResultTable()
safe_url = str(url or "").strip()
table.title = f'download-media -url "{safe_url}"' if safe_url else "download-media"
if table_type:
try:
table.set_table(table_type)
except Exception:
table.table = table_type
table.set_source_command("download-media", [])
try:
table.set_preserve_order(True)
@@ -2581,7 +2704,10 @@ class Download_Media(Cmdlet):
PipelineProgress(pipeline_context).step("finalized")
stage_ctx = pipeline_context.get_stage_context()
emit_enabled = bool(stage_ctx is not None and not getattr(stage_ctx, "is_last_stage", False))
# Emit per downloaded item whenever we're running under the pipeline runner.
# Live progress advances on emit(), and suppressing emits for the last stage
# causes the pipe bar to stay at 0% even while downloads complete.
emit_enabled = bool(stage_ctx is not None)
for pipe_obj_dict in pipe_objects:
if emit_enabled:
pipeline_context.emit(pipe_obj_dict)

View File

@@ -85,7 +85,12 @@ class Get_Url(Cmdlet):
if title:
table_title = f"Title: {title}"
table = ResultTable(table_title, max_columns=1).set_preserve_order(True)
table = (
ResultTable(table_title, max_columns=1)
.set_preserve_order(True)
.set_table("url")
.set_value_case("preserve")
)
table.set_source_command("get-url", [])
items: List[UrlItem] = []

283
docs/img/bandcamp-album.svg Normal file
View File

@@ -0,0 +1,283 @@
<svg class="rich-terminal" viewBox="0 0 2556 1440.8" xmlns="http://www.w3.org/2000/svg">
<!-- Generated with Rich https://www.textualize.io -->
<style>
@font-face {
font-family: "Fira Code";
src: local("FiraCode-Regular"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Regular.woff2") format("woff2"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Regular.woff") format("woff");
font-style: normal;
font-weight: 400;
}
@font-face {
font-family: "Fira Code";
src: local("FiraCode-Bold"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Bold.woff2") format("woff2"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Bold.woff") format("woff");
font-style: bold;
font-weight: 700;
}
.terminal-1756251412-matrix {
font-family: Fira Code, monospace;
font-size: 20px;
line-height: 24.4px;
font-variant-east-asian: full-width;
}
.terminal-1756251412-title {
font-size: 18px;
font-weight: bold;
font-family: arial;
}
.terminal-1756251412-r1 { fill: #c5c8c6 }
.terminal-1756251412-r2 { fill: #c5c8c6;font-weight: bold }
</style>
<defs>
<clipPath id="terminal-1756251412-clip-terminal">
<rect x="0" y="0" width="2536.6" height="1389.8" />
</clipPath>
<clipPath id="terminal-1756251412-line-0">
<rect x="0" y="1.5" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-1">
<rect x="0" y="25.9" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-2">
<rect x="0" y="50.3" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-3">
<rect x="0" y="74.7" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-4">
<rect x="0" y="99.1" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-5">
<rect x="0" y="123.5" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-6">
<rect x="0" y="147.9" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-7">
<rect x="0" y="172.3" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-8">
<rect x="0" y="196.7" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-9">
<rect x="0" y="221.1" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-10">
<rect x="0" y="245.5" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-11">
<rect x="0" y="269.9" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-12">
<rect x="0" y="294.3" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-13">
<rect x="0" y="318.7" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-14">
<rect x="0" y="343.1" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-15">
<rect x="0" y="367.5" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-16">
<rect x="0" y="391.9" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-17">
<rect x="0" y="416.3" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-18">
<rect x="0" y="440.7" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-19">
<rect x="0" y="465.1" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-20">
<rect x="0" y="489.5" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-21">
<rect x="0" y="513.9" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-22">
<rect x="0" y="538.3" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-23">
<rect x="0" y="562.7" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-24">
<rect x="0" y="587.1" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-25">
<rect x="0" y="611.5" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-26">
<rect x="0" y="635.9" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-27">
<rect x="0" y="660.3" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-28">
<rect x="0" y="684.7" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-29">
<rect x="0" y="709.1" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-30">
<rect x="0" y="733.5" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-31">
<rect x="0" y="757.9" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-32">
<rect x="0" y="782.3" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-33">
<rect x="0" y="806.7" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-34">
<rect x="0" y="831.1" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-35">
<rect x="0" y="855.5" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-36">
<rect x="0" y="879.9" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-37">
<rect x="0" y="904.3" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-38">
<rect x="0" y="928.7" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-39">
<rect x="0" y="953.1" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-40">
<rect x="0" y="977.5" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-41">
<rect x="0" y="1001.9" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-42">
<rect x="0" y="1026.3" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-43">
<rect x="0" y="1050.7" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-44">
<rect x="0" y="1075.1" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-45">
<rect x="0" y="1099.5" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-46">
<rect x="0" y="1123.9" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-47">
<rect x="0" y="1148.3" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-48">
<rect x="0" y="1172.7" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-49">
<rect x="0" y="1197.1" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-50">
<rect x="0" y="1221.5" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-51">
<rect x="0" y="1245.9" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-52">
<rect x="0" y="1270.3" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-53">
<rect x="0" y="1294.7" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-54">
<rect x="0" y="1319.1" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1756251412-line-55">
<rect x="0" y="1343.5" width="2537.6" height="24.65"/>
</clipPath>
</defs>
<rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="2554" height="1438.8" rx="8"/><text class="terminal-1756251412-title" fill="#c5c8c6" text-anchor="middle" x="1277" y="27">Rich</text>
<g transform="translate(26,22)">
<circle cx="0" cy="0" r="7" fill="#ff5f57"/>
<circle cx="22" cy="0" r="7" fill="#febc2e"/>
<circle cx="44" cy="0" r="7" fill="#28c840"/>
</g>
<g transform="translate(9, 41)" clip-path="url(#terminal-1756251412-clip-terminal)">
<g class="terminal-1756251412-matrix">
<text class="terminal-1756251412-r1" x="0" y="20" textLength="24.4" clip-path="url(#terminal-1756251412-line-0)">╭─</text><text class="terminal-1756251412-r1" x="24.4" y="20" textLength="2488.8" clip-path="url(#terminal-1756251412-line-0)">──────────────────────────────────────────────────────────────────────────────────&#160;Bandcamp:&#160;artist:Altrusian&#160;Grace&#160;Media&#160;──────────────────────────────────────────────────────────────────────────────────</text><text class="terminal-1756251412-r1" x="2513.2" y="20" textLength="24.4" clip-path="url(#terminal-1756251412-line-0)">─╮</text><text class="terminal-1756251412-r1" x="2537.6" y="20" textLength="12.2" clip-path="url(#terminal-1756251412-line-0)">
</text><text class="terminal-1756251412-r1" x="0" y="44.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-1)"></text><text class="terminal-1756251412-r1" x="2525.4" y="44.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-1)"></text><text class="terminal-1756251412-r1" x="2537.6" y="44.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-1)">
</text><text class="terminal-1756251412-r1" x="0" y="68.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-2)"></text><text class="terminal-1756251412-r2" x="48.8" y="68.8" textLength="24.4" clip-path="url(#terminal-1756251412-line-2)">&#160;#</text><text class="terminal-1756251412-r2" x="109.8" y="68.8" textLength="1122.4" clip-path="url(#terminal-1756251412-line-2)">TITLE&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r2" x="1268.8" y="68.8" textLength="61" clip-path="url(#terminal-1756251412-line-2)">TYPE&#160;</text><text class="terminal-1756251412-r2" x="1366.4" y="68.8" textLength="1122.4" clip-path="url(#terminal-1756251412-line-2)">URL&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="68.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-2)"></text><text class="terminal-1756251412-r1" x="2537.6" y="68.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-2)">
</text><text class="terminal-1756251412-r1" x="0" y="93.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-3)"></text><text class="terminal-1756251412-r1" x="24.4" y="93.2" textLength="2488.8" clip-path="url(#terminal-1756251412-line-3)">&#160;──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="93.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-3)"></text><text class="terminal-1756251412-r1" x="2537.6" y="93.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-3)">
</text><text class="terminal-1756251412-r1" x="0" y="117.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-4)"></text><text class="terminal-1756251412-r1" x="48.8" y="117.6" textLength="24.4" clip-path="url(#terminal-1756251412-line-4)">&#160;1</text><text class="terminal-1756251412-r1" x="109.8" y="117.6" textLength="1122.4" clip-path="url(#terminal-1756251412-line-4)">esoteric&#160;and&#160;occult&#160;wisdom&#160;-&#160;master&#160;collection&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="117.6" textLength="61" clip-path="url(#terminal-1756251412-line-4)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="117.6" textLength="1122.4" clip-path="url(#terminal-1756251412-line-4)">https://altrusiangrace.bandcamp.com/album/esoteric-and-occult-wisdom-master-collection&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="117.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-4)"></text><text class="terminal-1756251412-r1" x="2537.6" y="117.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-4)">
</text><text class="terminal-1756251412-r1" x="0" y="142" textLength="12.2" clip-path="url(#terminal-1756251412-line-5)"></text><text class="terminal-1756251412-r1" x="48.8" y="142" textLength="24.4" clip-path="url(#terminal-1756251412-line-5)">&#160;2</text><text class="terminal-1756251412-r1" x="109.8" y="142" textLength="1122.4" clip-path="url(#terminal-1756251412-line-5)">esoteric&#160;and&#160;occult&#160;wisdom&#160;-&#160;master&#160;collection&#160;(volume&#160;2)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="142" textLength="61" clip-path="url(#terminal-1756251412-line-5)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="142" textLength="1122.4" clip-path="url(#terminal-1756251412-line-5)">https://altrusiangrace.bandcamp.com/album/esoteric-and-occult-wisdom-master-collection-volu…</text><text class="terminal-1756251412-r1" x="2525.4" y="142" textLength="12.2" clip-path="url(#terminal-1756251412-line-5)"></text><text class="terminal-1756251412-r1" x="2537.6" y="142" textLength="12.2" clip-path="url(#terminal-1756251412-line-5)">
</text><text class="terminal-1756251412-r1" x="0" y="166.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-6)"></text><text class="terminal-1756251412-r1" x="48.8" y="166.4" textLength="24.4" clip-path="url(#terminal-1756251412-line-6)">&#160;3</text><text class="terminal-1756251412-r1" x="109.8" y="166.4" textLength="1122.4" clip-path="url(#terminal-1756251412-line-6)">the&#160;mystical&#160;hymns&#160;of&#160;orpheus&#160;(full&#160;audiobook)&#160;thomas&#160;taylor&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="166.4" textLength="61" clip-path="url(#terminal-1756251412-line-6)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="166.4" textLength="1122.4" clip-path="url(#terminal-1756251412-line-6)">https://altrusiangrace.bandcamp.com/album/the-mystical-hymns-of-orpheus-full-audiobook&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="166.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-6)"></text><text class="terminal-1756251412-r1" x="2537.6" y="166.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-6)">
</text><text class="terminal-1756251412-r1" x="0" y="190.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-7)"></text><text class="terminal-1756251412-r1" x="48.8" y="190.8" textLength="24.4" clip-path="url(#terminal-1756251412-line-7)">&#160;4</text><text class="terminal-1756251412-r1" x="109.8" y="190.8" textLength="1122.4" clip-path="url(#terminal-1756251412-line-7)">the&#160;prophecies&#160;of&#160;nostradamus&#160;(full&#160;audiobook)&#160;michel&#160;nostradamus&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="190.8" textLength="61" clip-path="url(#terminal-1756251412-line-7)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="190.8" textLength="1122.4" clip-path="url(#terminal-1756251412-line-7)">https://altrusiangrace.bandcamp.com/album/the-prophecies-of-nostradamus-full-audiobook&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="190.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-7)"></text><text class="terminal-1756251412-r1" x="2537.6" y="190.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-7)">
</text><text class="terminal-1756251412-r1" x="0" y="215.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-8)"></text><text class="terminal-1756251412-r1" x="48.8" y="215.2" textLength="24.4" clip-path="url(#terminal-1756251412-line-8)">&#160;5</text><text class="terminal-1756251412-r1" x="109.8" y="215.2" textLength="1122.4" clip-path="url(#terminal-1756251412-line-8)">psychic&#160;self-defense&#160;(full&#160;audiobook)&#160;dion&#160;fortune&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="215.2" textLength="61" clip-path="url(#terminal-1756251412-line-8)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="215.2" textLength="1122.4" clip-path="url(#terminal-1756251412-line-8)">https://altrusiangrace.bandcamp.com/album/psychic-self-defense-full-audiobook&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="215.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-8)"></text><text class="terminal-1756251412-r1" x="2537.6" y="215.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-8)">
</text><text class="terminal-1756251412-r1" x="0" y="239.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-9)"></text><text class="terminal-1756251412-r1" x="48.8" y="239.6" textLength="24.4" clip-path="url(#terminal-1756251412-line-9)">&#160;6</text><text class="terminal-1756251412-r1" x="109.8" y="239.6" textLength="1122.4" clip-path="url(#terminal-1756251412-line-9)">atlantean&#160;twilight&#160;(cinematic&#160;ambient&#160;pagan&#160;folk&#160;version)&#160;psyclopean&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="239.6" textLength="61" clip-path="url(#terminal-1756251412-line-9)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="239.6" textLength="1122.4" clip-path="url(#terminal-1756251412-line-9)">https://altrusiangrace.bandcamp.com/album/atlantean-twilight-cinematic-ambient-pagan-folk-v…</text><text class="terminal-1756251412-r1" x="2525.4" y="239.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-9)"></text><text class="terminal-1756251412-r1" x="2537.6" y="239.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-9)">
</text><text class="terminal-1756251412-r1" x="0" y="264" textLength="12.2" clip-path="url(#terminal-1756251412-line-10)"></text><text class="terminal-1756251412-r1" x="48.8" y="264" textLength="24.4" clip-path="url(#terminal-1756251412-line-10)">&#160;7</text><text class="terminal-1756251412-r1" x="109.8" y="264" textLength="1122.4" clip-path="url(#terminal-1756251412-line-10)">a&#160;road&#160;to&#160;self-knowledge&#160;(full&#160;audiobook)&#160;rudolf&#160;steiner&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="264" textLength="61" clip-path="url(#terminal-1756251412-line-10)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="264" textLength="1122.4" clip-path="url(#terminal-1756251412-line-10)">https://altrusiangrace.bandcamp.com/album/a-road-to-self-knowledge-full-audiobook&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="264" textLength="12.2" clip-path="url(#terminal-1756251412-line-10)"></text><text class="terminal-1756251412-r1" x="2537.6" y="264" textLength="12.2" clip-path="url(#terminal-1756251412-line-10)">
</text><text class="terminal-1756251412-r1" x="0" y="288.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-11)"></text><text class="terminal-1756251412-r1" x="48.8" y="288.4" textLength="24.4" clip-path="url(#terminal-1756251412-line-11)">&#160;8</text><text class="terminal-1756251412-r1" x="109.8" y="288.4" textLength="1122.4" clip-path="url(#terminal-1756251412-line-11)">zetetic&#160;astronomy:&#160;earth&#160;not&#160;a&#160;globe&#160;(full&#160;audiobook)&#160;samuel&#160;rowbotham&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="288.4" textLength="61" clip-path="url(#terminal-1756251412-line-11)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="288.4" textLength="1122.4" clip-path="url(#terminal-1756251412-line-11)">https://altrusiangrace.bandcamp.com/album/zetetic-astronomy-earth-not-a-globe-full-audiobook</text><text class="terminal-1756251412-r1" x="2525.4" y="288.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-11)"></text><text class="terminal-1756251412-r1" x="2537.6" y="288.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-11)">
</text><text class="terminal-1756251412-r1" x="0" y="312.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-12)"></text><text class="terminal-1756251412-r1" x="48.8" y="312.8" textLength="24.4" clip-path="url(#terminal-1756251412-line-12)">&#160;9</text><text class="terminal-1756251412-r1" x="109.8" y="312.8" textLength="1122.4" clip-path="url(#terminal-1756251412-line-12)">the&#160;philosophy&#160;of&#160;freedom&#160;(full&#160;audiobook)&#160;rudolf&#160;steiner&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="312.8" textLength="61" clip-path="url(#terminal-1756251412-line-12)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="312.8" textLength="1122.4" clip-path="url(#terminal-1756251412-line-12)">https://altrusiangrace.bandcamp.com/album/the-philosophy-of-freedom-full-audiobook&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="312.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-12)"></text><text class="terminal-1756251412-r1" x="2537.6" y="312.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-12)">
</text><text class="terminal-1756251412-r1" x="0" y="337.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-13)"></text><text class="terminal-1756251412-r1" x="48.8" y="337.2" textLength="24.4" clip-path="url(#terminal-1756251412-line-13)">10</text><text class="terminal-1756251412-r1" x="109.8" y="337.2" textLength="1122.4" clip-path="url(#terminal-1756251412-line-13)">the&#160;creative&#160;use&#160;of&#160;imagination&#160;(full&#160;audiobook)&#160;neville&#160;goddard&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="337.2" textLength="61" clip-path="url(#terminal-1756251412-line-13)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="337.2" textLength="1122.4" clip-path="url(#terminal-1756251412-line-13)">https://altrusiangrace.bandcamp.com/album/the-creative-use-of-imagination-full-audiobook&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="337.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-13)"></text><text class="terminal-1756251412-r1" x="2537.6" y="337.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-13)">
</text><text class="terminal-1756251412-r1" x="0" y="361.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-14)"></text><text class="terminal-1756251412-r1" x="48.8" y="361.6" textLength="24.4" clip-path="url(#terminal-1756251412-line-14)">11</text><text class="terminal-1756251412-r1" x="109.8" y="361.6" textLength="1122.4" clip-path="url(#terminal-1756251412-line-14)">the&#160;willows&#160;(full&#160;audiobook)&#160;algernon&#160;blackwood&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="361.6" textLength="61" clip-path="url(#terminal-1756251412-line-14)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="361.6" textLength="1122.4" clip-path="url(#terminal-1756251412-line-14)">https://altrusiangrace.bandcamp.com/album/the-willows-full-audiobook&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="361.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-14)"></text><text class="terminal-1756251412-r1" x="2537.6" y="361.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-14)">
</text><text class="terminal-1756251412-r1" x="0" y="386" textLength="12.2" clip-path="url(#terminal-1756251412-line-15)"></text><text class="terminal-1756251412-r1" x="48.8" y="386" textLength="24.4" clip-path="url(#terminal-1756251412-line-15)">12</text><text class="terminal-1756251412-r1" x="109.8" y="386" textLength="1122.4" clip-path="url(#terminal-1756251412-line-15)">hidden&#160;symbolism&#160;of&#160;alchemy&#160;and&#160;the&#160;occult&#160;arts&#160;(full&#160;audiobook)&#160;herbert&#160;silberer&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="386" textLength="61" clip-path="url(#terminal-1756251412-line-15)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="386" textLength="1122.4" clip-path="url(#terminal-1756251412-line-15)">https://altrusiangrace.bandcamp.com/album/hidden-symbolism-of-alchemy-and-the-occult-arts-f…</text><text class="terminal-1756251412-r1" x="2525.4" y="386" textLength="12.2" clip-path="url(#terminal-1756251412-line-15)"></text><text class="terminal-1756251412-r1" x="2537.6" y="386" textLength="12.2" clip-path="url(#terminal-1756251412-line-15)">
</text><text class="terminal-1756251412-r1" x="0" y="410.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-16)"></text><text class="terminal-1756251412-r1" x="48.8" y="410.4" textLength="24.4" clip-path="url(#terminal-1756251412-line-16)">13</text><text class="terminal-1756251412-r1" x="109.8" y="410.4" textLength="1122.4" clip-path="url(#terminal-1756251412-line-16)">the&#160;three&#160;books&#160;of&#160;enoch&#160;r.h.&#160;charles&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="410.4" textLength="61" clip-path="url(#terminal-1756251412-line-16)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="410.4" textLength="1122.4" clip-path="url(#terminal-1756251412-line-16)">https://altrusiangrace.bandcamp.com/album/the-three-books-of-enoch&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="410.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-16)"></text><text class="terminal-1756251412-r1" x="2537.6" y="410.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-16)">
</text><text class="terminal-1756251412-r1" x="0" y="434.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-17)"></text><text class="terminal-1756251412-r1" x="48.8" y="434.8" textLength="24.4" clip-path="url(#terminal-1756251412-line-17)">14</text><text class="terminal-1756251412-r1" x="109.8" y="434.8" textLength="1122.4" clip-path="url(#terminal-1756251412-line-17)">the&#160;rig&#160;veda&#160;ralph&#160;t.h.&#160;griffith&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="434.8" textLength="61" clip-path="url(#terminal-1756251412-line-17)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="434.8" textLength="1122.4" clip-path="url(#terminal-1756251412-line-17)">https://altrusiangrace.bandcamp.com/album/the-rig-veda&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="434.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-17)"></text><text class="terminal-1756251412-r1" x="2537.6" y="434.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-17)">
</text><text class="terminal-1756251412-r1" x="0" y="459.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-18)"></text><text class="terminal-1756251412-r1" x="48.8" y="459.2" textLength="24.4" clip-path="url(#terminal-1756251412-line-18)">15</text><text class="terminal-1756251412-r1" x="109.8" y="459.2" textLength="1122.4" clip-path="url(#terminal-1756251412-line-18)">the&#160;red&#160;fairy&#160;book&#160;(full&#160;audiobook)&#160;andrew&#160;lang&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="459.2" textLength="61" clip-path="url(#terminal-1756251412-line-18)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="459.2" textLength="1122.4" clip-path="url(#terminal-1756251412-line-18)">https://altrusiangrace.bandcamp.com/album/the-red-fairy-book-full-audiobook&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="459.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-18)"></text><text class="terminal-1756251412-r1" x="2537.6" y="459.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-18)">
</text><text class="terminal-1756251412-r1" x="0" y="483.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-19)"></text><text class="terminal-1756251412-r1" x="48.8" y="483.6" textLength="24.4" clip-path="url(#terminal-1756251412-line-19)">16</text><text class="terminal-1756251412-r1" x="109.8" y="483.6" textLength="1122.4" clip-path="url(#terminal-1756251412-line-19)">ancient&#160;egyptian&#160;legends&#160;(full&#160;audiobook)&#160;m.a.&#160;murray&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="483.6" textLength="61" clip-path="url(#terminal-1756251412-line-19)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="483.6" textLength="1122.4" clip-path="url(#terminal-1756251412-line-19)">https://altrusiangrace.bandcamp.com/album/ancient-egyptian-legends-full-audiobook&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="483.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-19)"></text><text class="terminal-1756251412-r1" x="2537.6" y="483.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-19)">
</text><text class="terminal-1756251412-r1" x="0" y="508" textLength="12.2" clip-path="url(#terminal-1756251412-line-20)"></text><text class="terminal-1756251412-r1" x="48.8" y="508" textLength="24.4" clip-path="url(#terminal-1756251412-line-20)">17</text><text class="terminal-1756251412-r1" x="109.8" y="508" textLength="1122.4" clip-path="url(#terminal-1756251412-line-20)">the&#160;ramayana&#160;(full&#160;audiobook)&#160;the&#160;sage&#160;valmiki&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="508" textLength="61" clip-path="url(#terminal-1756251412-line-20)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="508" textLength="1122.4" clip-path="url(#terminal-1756251412-line-20)">https://altrusiangrace.bandcamp.com/album/the-ramayana-full-audiobook&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="508" textLength="12.2" clip-path="url(#terminal-1756251412-line-20)"></text><text class="terminal-1756251412-r1" x="2537.6" y="508" textLength="12.2" clip-path="url(#terminal-1756251412-line-20)">
</text><text class="terminal-1756251412-r1" x="0" y="532.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-21)"></text><text class="terminal-1756251412-r1" x="48.8" y="532.4" textLength="24.4" clip-path="url(#terminal-1756251412-line-21)">18</text><text class="terminal-1756251412-r1" x="109.8" y="532.4" textLength="1122.4" clip-path="url(#terminal-1756251412-line-21)">a&#160;dreamer&#x27;s&#160;tales&#160;(full&#160;audiobook)&#160;lord&#160;dunsany&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="532.4" textLength="61" clip-path="url(#terminal-1756251412-line-21)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="532.4" textLength="1122.4" clip-path="url(#terminal-1756251412-line-21)">https://altrusiangrace.bandcamp.com/album/a-dreamers-tales-full-audiobook&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="532.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-21)"></text><text class="terminal-1756251412-r1" x="2537.6" y="532.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-21)">
</text><text class="terminal-1756251412-r1" x="0" y="556.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-22)"></text><text class="terminal-1756251412-r1" x="48.8" y="556.8" textLength="24.4" clip-path="url(#terminal-1756251412-line-22)">19</text><text class="terminal-1756251412-r1" x="109.8" y="556.8" textLength="1122.4" clip-path="url(#terminal-1756251412-line-22)">electric&#160;altar:&#160;psychedelic&#160;occult&#160;masterpieces&#160;from&#160;behind&#160;the&#160;veil&#160;various&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="556.8" textLength="61" clip-path="url(#terminal-1756251412-line-22)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="556.8" textLength="1122.4" clip-path="url(#terminal-1756251412-line-22)">https://altrusiangrace.bandcamp.com/album/electric-altar-psychedelic-occult-masterpieces-fr…</text><text class="terminal-1756251412-r1" x="2525.4" y="556.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-22)"></text><text class="terminal-1756251412-r1" x="2537.6" y="556.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-22)">
</text><text class="terminal-1756251412-r1" x="0" y="581.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-23)"></text><text class="terminal-1756251412-r1" x="48.8" y="581.2" textLength="24.4" clip-path="url(#terminal-1756251412-line-23)">20</text><text class="terminal-1756251412-r1" x="109.8" y="581.2" textLength="1122.4" clip-path="url(#terminal-1756251412-line-23)">electric&#160;altar&#160;2:&#160;more&#160;psychedelic&#160;occult&#160;masterpieces&#160;from&#160;behind&#160;the&#160;veil&#160;various&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="581.2" textLength="61" clip-path="url(#terminal-1756251412-line-23)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="581.2" textLength="1122.4" clip-path="url(#terminal-1756251412-line-23)">https://altrusiangrace.bandcamp.com/album/electric-altar-2-more-psychedelic-occult-masterpi…</text><text class="terminal-1756251412-r1" x="2525.4" y="581.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-23)"></text><text class="terminal-1756251412-r1" x="2537.6" y="581.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-23)">
</text><text class="terminal-1756251412-r1" x="0" y="605.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-24)"></text><text class="terminal-1756251412-r1" x="48.8" y="605.6" textLength="24.4" clip-path="url(#terminal-1756251412-line-24)">21</text><text class="terminal-1756251412-r1" x="109.8" y="605.6" textLength="1122.4" clip-path="url(#terminal-1756251412-line-24)">the&#160;1971&#160;interdimensional&#160;jazz&#160;festival&#160;various&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="605.6" textLength="61" clip-path="url(#terminal-1756251412-line-24)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="605.6" textLength="1122.4" clip-path="url(#terminal-1756251412-line-24)">https://altrusiangrace.bandcamp.com/album/the-1971-interdimensional-jazz-festival&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="605.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-24)"></text><text class="terminal-1756251412-r1" x="2537.6" y="605.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-24)">
</text><text class="terminal-1756251412-r1" x="0" y="630" textLength="12.2" clip-path="url(#terminal-1756251412-line-25)"></text><text class="terminal-1756251412-r1" x="48.8" y="630" textLength="24.4" clip-path="url(#terminal-1756251412-line-25)">22</text><text class="terminal-1756251412-r1" x="109.8" y="630" textLength="1122.4" clip-path="url(#terminal-1756251412-line-25)">the&#160;eschaton&#160;psyclopean&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="630" textLength="61" clip-path="url(#terminal-1756251412-line-25)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="630" textLength="1122.4" clip-path="url(#terminal-1756251412-line-25)">https://altrusiangrace.bandcamp.com/album/the-eschaton&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="630" textLength="12.2" clip-path="url(#terminal-1756251412-line-25)"></text><text class="terminal-1756251412-r1" x="2537.6" y="630" textLength="12.2" clip-path="url(#terminal-1756251412-line-25)">
</text><text class="terminal-1756251412-r1" x="0" y="654.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-26)"></text><text class="terminal-1756251412-r1" x="48.8" y="654.4" textLength="24.4" clip-path="url(#terminal-1756251412-line-26)">23</text><text class="terminal-1756251412-r1" x="109.8" y="654.4" textLength="1122.4" clip-path="url(#terminal-1756251412-line-26)">demonology&#160;and&#160;devil-lore&#160;(full&#160;audiobook)&#160;moncure&#160;daniel&#160;conway&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="654.4" textLength="61" clip-path="url(#terminal-1756251412-line-26)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="654.4" textLength="1122.4" clip-path="url(#terminal-1756251412-line-26)">https://altrusiangrace.bandcamp.com/album/demonology-and-devil-lore-full-audiobook&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="654.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-26)"></text><text class="terminal-1756251412-r1" x="2537.6" y="654.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-26)">
</text><text class="terminal-1756251412-r1" x="0" y="678.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-27)"></text><text class="terminal-1756251412-r1" x="48.8" y="678.8" textLength="24.4" clip-path="url(#terminal-1756251412-line-27)">24</text><text class="terminal-1756251412-r1" x="109.8" y="678.8" textLength="1122.4" clip-path="url(#terminal-1756251412-line-27)">fifty-one&#160;tales&#160;(full&#160;audiobook)&#160;lord&#160;dunsany&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="678.8" textLength="61" clip-path="url(#terminal-1756251412-line-27)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="678.8" textLength="1122.4" clip-path="url(#terminal-1756251412-line-27)">https://altrusiangrace.bandcamp.com/album/fifty-one-tales-full-audiobook&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="678.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-27)"></text><text class="terminal-1756251412-r1" x="2537.6" y="678.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-27)">
</text><text class="terminal-1756251412-r1" x="0" y="703.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-28)"></text><text class="terminal-1756251412-r1" x="48.8" y="703.2" textLength="24.4" clip-path="url(#terminal-1756251412-line-28)">25</text><text class="terminal-1756251412-r1" x="109.8" y="703.2" textLength="1122.4" clip-path="url(#terminal-1756251412-line-28)">meditations&#160;(full&#160;audiobook)&#160;marcus&#160;aurelius&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="703.2" textLength="61" clip-path="url(#terminal-1756251412-line-28)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="703.2" textLength="1122.4" clip-path="url(#terminal-1756251412-line-28)">https://altrusiangrace.bandcamp.com/album/meditations-full-audiobook&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="703.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-28)"></text><text class="terminal-1756251412-r1" x="2537.6" y="703.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-28)">
</text><text class="terminal-1756251412-r1" x="0" y="727.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-29)"></text><text class="terminal-1756251412-r1" x="48.8" y="727.6" textLength="24.4" clip-path="url(#terminal-1756251412-line-29)">26</text><text class="terminal-1756251412-r1" x="109.8" y="727.6" textLength="1122.4" clip-path="url(#terminal-1756251412-line-29)">time&#160;and&#160;the&#160;gods&#160;(full&#160;audiobook)&#160;lord&#160;dunsany&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="727.6" textLength="61" clip-path="url(#terminal-1756251412-line-29)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="727.6" textLength="1122.4" clip-path="url(#terminal-1756251412-line-29)">https://altrusiangrace.bandcamp.com/album/time-and-the-gods-full-audiobook&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="727.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-29)"></text><text class="terminal-1756251412-r1" x="2537.6" y="727.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-29)">
</text><text class="terminal-1756251412-r1" x="0" y="752" textLength="12.2" clip-path="url(#terminal-1756251412-line-30)"></text><text class="terminal-1756251412-r1" x="48.8" y="752" textLength="24.4" clip-path="url(#terminal-1756251412-line-30)">27</text><text class="terminal-1756251412-r1" x="109.8" y="752" textLength="1122.4" clip-path="url(#terminal-1756251412-line-30)">the&#160;biography&#160;of&#160;satan&#160;(full&#160;audiobook)&#160;kersey&#160;graves&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="752" textLength="61" clip-path="url(#terminal-1756251412-line-30)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="752" textLength="1122.4" clip-path="url(#terminal-1756251412-line-30)">https://altrusiangrace.bandcamp.com/album/the-biography-of-satan-full-audiobook&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="752" textLength="12.2" clip-path="url(#terminal-1756251412-line-30)"></text><text class="terminal-1756251412-r1" x="2537.6" y="752" textLength="12.2" clip-path="url(#terminal-1756251412-line-30)">
</text><text class="terminal-1756251412-r1" x="0" y="776.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-31)"></text><text class="terminal-1756251412-r1" x="48.8" y="776.4" textLength="24.4" clip-path="url(#terminal-1756251412-line-31)">28</text><text class="terminal-1756251412-r1" x="109.8" y="776.4" textLength="1122.4" clip-path="url(#terminal-1756251412-line-31)">applied&#160;magic&#160;(full&#160;audiobook)&#160;dion&#160;fortune&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="776.4" textLength="61" clip-path="url(#terminal-1756251412-line-31)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="776.4" textLength="1122.4" clip-path="url(#terminal-1756251412-line-31)">https://altrusiangrace.bandcamp.com/album/applied-magic-full-audiobook&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="776.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-31)"></text><text class="terminal-1756251412-r1" x="2537.6" y="776.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-31)">
</text><text class="terminal-1756251412-r1" x="0" y="800.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-32)"></text><text class="terminal-1756251412-r1" x="48.8" y="800.8" textLength="24.4" clip-path="url(#terminal-1756251412-line-32)">29</text><text class="terminal-1756251412-r1" x="109.8" y="800.8" textLength="1122.4" clip-path="url(#terminal-1756251412-line-32)">in&#160;search&#160;of&#160;the&#160;miraculous&#160;(full&#160;audiobook)&#160;p.d.&#160;ouspensky&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="800.8" textLength="61" clip-path="url(#terminal-1756251412-line-32)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="800.8" textLength="1122.4" clip-path="url(#terminal-1756251412-line-32)">https://altrusiangrace.bandcamp.com/album/in-search-of-the-miraculous-full-audiobook&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="800.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-32)"></text><text class="terminal-1756251412-r1" x="2537.6" y="800.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-32)">
</text><text class="terminal-1756251412-r1" x="0" y="825.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-33)"></text><text class="terminal-1756251412-r1" x="48.8" y="825.2" textLength="24.4" clip-path="url(#terminal-1756251412-line-33)">30</text><text class="terminal-1756251412-r1" x="109.8" y="825.2" textLength="1122.4" clip-path="url(#terminal-1756251412-line-33)">the&#160;sword&#160;of&#160;welleran&#160;and&#160;other&#160;stories&#160;(full&#160;audiobook)&#160;lord&#160;dunsany&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="825.2" textLength="61" clip-path="url(#terminal-1756251412-line-33)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="825.2" textLength="1122.4" clip-path="url(#terminal-1756251412-line-33)">https://altrusiangrace.bandcamp.com/album/the-sword-of-welleran-and-other-stories-full-audi…</text><text class="terminal-1756251412-r1" x="2525.4" y="825.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-33)"></text><text class="terminal-1756251412-r1" x="2537.6" y="825.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-33)">
</text><text class="terminal-1756251412-r1" x="0" y="849.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-34)"></text><text class="terminal-1756251412-r1" x="48.8" y="849.6" textLength="24.4" clip-path="url(#terminal-1756251412-line-34)">31</text><text class="terminal-1756251412-r1" x="109.8" y="849.6" textLength="1122.4" clip-path="url(#terminal-1756251412-line-34)">flying&#160;saucers:&#160;a&#160;modern&#160;myth&#160;of&#160;things&#160;seen&#160;in&#160;the&#160;sky&#160;(full&#160;audiobook)&#160;c.g&#160;jung&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="849.6" textLength="61" clip-path="url(#terminal-1756251412-line-34)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="849.6" textLength="1122.4" clip-path="url(#terminal-1756251412-line-34)">https://altrusiangrace.bandcamp.com/album/flying-saucers-a-modern-myth-of-things-seen-in-th…</text><text class="terminal-1756251412-r1" x="2525.4" y="849.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-34)"></text><text class="terminal-1756251412-r1" x="2537.6" y="849.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-34)">
</text><text class="terminal-1756251412-r1" x="0" y="874" textLength="12.2" clip-path="url(#terminal-1756251412-line-35)"></text><text class="terminal-1756251412-r1" x="48.8" y="874" textLength="24.4" clip-path="url(#terminal-1756251412-line-35)">32</text><text class="terminal-1756251412-r1" x="109.8" y="874" textLength="1122.4" clip-path="url(#terminal-1756251412-line-35)">aspects&#160;of&#160;occultism&#160;(full&#160;audiobook)&#160;dion&#160;fortune&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="874" textLength="61" clip-path="url(#terminal-1756251412-line-35)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="874" textLength="1122.4" clip-path="url(#terminal-1756251412-line-35)">https://altrusiangrace.bandcamp.com/album/aspects-of-occultism-full-audiobook&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="874" textLength="12.2" clip-path="url(#terminal-1756251412-line-35)"></text><text class="terminal-1756251412-r1" x="2537.6" y="874" textLength="12.2" clip-path="url(#terminal-1756251412-line-35)">
</text><text class="terminal-1756251412-r1" x="0" y="898.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-36)"></text><text class="terminal-1756251412-r1" x="48.8" y="898.4" textLength="24.4" clip-path="url(#terminal-1756251412-line-36)">33</text><text class="terminal-1756251412-r1" x="109.8" y="898.4" textLength="1122.4" clip-path="url(#terminal-1756251412-line-36)">mazes&#160;and&#160;labyrinths:&#160;a&#160;general&#160;account&#160;of&#160;their&#160;history&#160;and&#160;development&#160;(full&#160;audiobook)&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="898.4" textLength="61" clip-path="url(#terminal-1756251412-line-36)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="898.4" textLength="1122.4" clip-path="url(#terminal-1756251412-line-36)">https://altrusiangrace.bandcamp.com/album/mazes-and-labyrinths-a-general-account-of-their-h…</text><text class="terminal-1756251412-r1" x="2525.4" y="898.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-36)"></text><text class="terminal-1756251412-r1" x="2537.6" y="898.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-36)">
</text><text class="terminal-1756251412-r1" x="0" y="922.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-37)"></text><text class="terminal-1756251412-r1" x="109.8" y="922.8" textLength="1122.4" clip-path="url(#terminal-1756251412-line-37)">w.h.&#160;matthews&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="922.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-37)"></text><text class="terminal-1756251412-r1" x="2537.6" y="922.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-37)">
</text><text class="terminal-1756251412-r1" x="0" y="947.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-38)"></text><text class="terminal-1756251412-r1" x="48.8" y="947.2" textLength="24.4" clip-path="url(#terminal-1756251412-line-38)">34</text><text class="terminal-1756251412-r1" x="109.8" y="947.2" textLength="1122.4" clip-path="url(#terminal-1756251412-line-38)">crystal&#160;gazing:&#160;its&#160;history&#160;and&#160;practice&#160;(full&#160;audiobook)&#160;northcote&#160;thomas&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="947.2" textLength="61" clip-path="url(#terminal-1756251412-line-38)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="947.2" textLength="1122.4" clip-path="url(#terminal-1756251412-line-38)">https://altrusiangrace.bandcamp.com/album/crystal-gazing-its-history-and-practice-full-audi…</text><text class="terminal-1756251412-r1" x="2525.4" y="947.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-38)"></text><text class="terminal-1756251412-r1" x="2537.6" y="947.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-38)">
</text><text class="terminal-1756251412-r1" x="0" y="971.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-39)"></text><text class="terminal-1756251412-r1" x="48.8" y="971.6" textLength="24.4" clip-path="url(#terminal-1756251412-line-39)">35</text><text class="terminal-1756251412-r1" x="109.8" y="971.6" textLength="1122.4" clip-path="url(#terminal-1756251412-line-39)">the&#160;way&#160;of&#160;initiation&#160;(full&#160;audiobook)&#160;rudolf&#160;steiner&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="971.6" textLength="61" clip-path="url(#terminal-1756251412-line-39)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="971.6" textLength="1122.4" clip-path="url(#terminal-1756251412-line-39)">https://altrusiangrace.bandcamp.com/album/the-way-of-initiation-full-audiobook&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="971.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-39)"></text><text class="terminal-1756251412-r1" x="2537.6" y="971.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-39)">
</text><text class="terminal-1756251412-r1" x="0" y="996" textLength="12.2" clip-path="url(#terminal-1756251412-line-40)"></text><text class="terminal-1756251412-r1" x="48.8" y="996" textLength="24.4" clip-path="url(#terminal-1756251412-line-40)">36</text><text class="terminal-1756251412-r1" x="109.8" y="996" textLength="1122.4" clip-path="url(#terminal-1756251412-line-40)">thrice-greatest&#160;hermes&#160;(full&#160;audiobook)&#160;g.r.s.&#160;mead&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="996" textLength="61" clip-path="url(#terminal-1756251412-line-40)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="996" textLength="1122.4" clip-path="url(#terminal-1756251412-line-40)">https://altrusiangrace.bandcamp.com/album/thrice-greatest-hermes-full-audiobook&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="996" textLength="12.2" clip-path="url(#terminal-1756251412-line-40)"></text><text class="terminal-1756251412-r1" x="2537.6" y="996" textLength="12.2" clip-path="url(#terminal-1756251412-line-40)">
</text><text class="terminal-1756251412-r1" x="0" y="1020.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-41)"></text><text class="terminal-1756251412-r1" x="48.8" y="1020.4" textLength="24.4" clip-path="url(#terminal-1756251412-line-41)">37</text><text class="terminal-1756251412-r1" x="109.8" y="1020.4" textLength="1122.4" clip-path="url(#terminal-1756251412-line-41)">sane&#160;occultism&#160;(full&#160;audiobook)&#160;dion&#160;fortune&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="1020.4" textLength="61" clip-path="url(#terminal-1756251412-line-41)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="1020.4" textLength="1122.4" clip-path="url(#terminal-1756251412-line-41)">https://altrusiangrace.bandcamp.com/album/sane-occultism-full-audiobook&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="1020.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-41)"></text><text class="terminal-1756251412-r1" x="2537.6" y="1020.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-41)">
</text><text class="terminal-1756251412-r1" x="0" y="1044.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-42)"></text><text class="terminal-1756251412-r1" x="48.8" y="1044.8" textLength="24.4" clip-path="url(#terminal-1756251412-line-42)">38</text><text class="terminal-1756251412-r1" x="109.8" y="1044.8" textLength="1122.4" clip-path="url(#terminal-1756251412-line-42)">the&#160;agm&#160;lovecraft&#160;collection&#160;h.p.&#160;lovecraft&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="1044.8" textLength="61" clip-path="url(#terminal-1756251412-line-42)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="1044.8" textLength="1122.4" clip-path="url(#terminal-1756251412-line-42)">https://altrusiangrace.bandcamp.com/album/the-agm-lovecraft-collection&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="1044.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-42)"></text><text class="terminal-1756251412-r1" x="2537.6" y="1044.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-42)">
</text><text class="terminal-1756251412-r1" x="0" y="1069.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-43)"></text><text class="terminal-1756251412-r1" x="48.8" y="1069.2" textLength="24.4" clip-path="url(#terminal-1756251412-line-43)">39</text><text class="terminal-1756251412-r1" x="109.8" y="1069.2" textLength="1122.4" clip-path="url(#terminal-1756251412-line-43)">the&#160;agm&#160;clark&#160;ashton&#160;smith&#160;collection&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="1069.2" textLength="61" clip-path="url(#terminal-1756251412-line-43)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="1069.2" textLength="1122.4" clip-path="url(#terminal-1756251412-line-43)">https://altrusiangrace.bandcamp.com/album/the-agm-clark-ashton-smith-collection&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="1069.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-43)"></text><text class="terminal-1756251412-r1" x="2537.6" y="1069.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-43)">
</text><text class="terminal-1756251412-r1" x="0" y="1093.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-44)"></text><text class="terminal-1756251412-r1" x="48.8" y="1093.6" textLength="24.4" clip-path="url(#terminal-1756251412-line-44)">40</text><text class="terminal-1756251412-r1" x="109.8" y="1093.6" textLength="1122.4" clip-path="url(#terminal-1756251412-line-44)">the&#160;agm&#160;robert&#160;e.&#160;howard&#160;collection&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="1093.6" textLength="61" clip-path="url(#terminal-1756251412-line-44)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="1093.6" textLength="1122.4" clip-path="url(#terminal-1756251412-line-44)">https://altrusiangrace.bandcamp.com/album/the-agm-robert-e-howard-collection&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="1093.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-44)"></text><text class="terminal-1756251412-r1" x="2537.6" y="1093.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-44)">
</text><text class="terminal-1756251412-r1" x="0" y="1118" textLength="12.2" clip-path="url(#terminal-1756251412-line-45)"></text><text class="terminal-1756251412-r1" x="48.8" y="1118" textLength="24.4" clip-path="url(#terminal-1756251412-line-45)">41</text><text class="terminal-1756251412-r1" x="109.8" y="1118" textLength="1122.4" clip-path="url(#terminal-1756251412-line-45)">the&#160;book&#160;of&#160;wonder&#160;(full&#160;audiobook)&#160;lord&#160;dunsany&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="1118" textLength="61" clip-path="url(#terminal-1756251412-line-45)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="1118" textLength="1122.4" clip-path="url(#terminal-1756251412-line-45)">https://altrusiangrace.bandcamp.com/album/the-book-of-wonder-full-audiobook&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="1118" textLength="12.2" clip-path="url(#terminal-1756251412-line-45)"></text><text class="terminal-1756251412-r1" x="2537.6" y="1118" textLength="12.2" clip-path="url(#terminal-1756251412-line-45)">
</text><text class="terminal-1756251412-r1" x="0" y="1142.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-46)"></text><text class="terminal-1756251412-r1" x="48.8" y="1142.4" textLength="24.4" clip-path="url(#terminal-1756251412-line-46)">42</text><text class="terminal-1756251412-r1" x="109.8" y="1142.4" textLength="1122.4" clip-path="url(#terminal-1756251412-line-46)">the&#160;secret&#160;destiny&#160;of&#160;america&#160;(full&#160;audiobook)&#160;manly&#160;p.&#160;hall&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="1142.4" textLength="61" clip-path="url(#terminal-1756251412-line-46)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="1142.4" textLength="1122.4" clip-path="url(#terminal-1756251412-line-46)">https://altrusiangrace.bandcamp.com/album/the-secret-destiny-of-america-full-audiobook&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="1142.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-46)"></text><text class="terminal-1756251412-r1" x="2537.6" y="1142.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-46)">
</text><text class="terminal-1756251412-r1" x="0" y="1166.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-47)"></text><text class="terminal-1756251412-r1" x="48.8" y="1166.8" textLength="24.4" clip-path="url(#terminal-1756251412-line-47)">43</text><text class="terminal-1756251412-r1" x="109.8" y="1166.8" textLength="1122.4" clip-path="url(#terminal-1756251412-line-47)">atlantean&#160;twilight:&#160;vaporous&#160;vignettes&#160;inspired&#160;by&#160;clark&#160;ashton&#160;smith&#160;psyclopean&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="1166.8" textLength="61" clip-path="url(#terminal-1756251412-line-47)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="1166.8" textLength="1122.4" clip-path="url(#terminal-1756251412-line-47)">https://altrusiangrace.bandcamp.com/album/atlantean-twilight-vaporous-vignettes-inspired-by…</text><text class="terminal-1756251412-r1" x="2525.4" y="1166.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-47)"></text><text class="terminal-1756251412-r1" x="2537.6" y="1166.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-47)">
</text><text class="terminal-1756251412-r1" x="0" y="1191.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-48)"></text><text class="terminal-1756251412-r1" x="48.8" y="1191.2" textLength="24.4" clip-path="url(#terminal-1756251412-line-48)">44</text><text class="terminal-1756251412-r1" x="109.8" y="1191.2" textLength="1122.4" clip-path="url(#terminal-1756251412-line-48)">pistis&#160;sophia&#160;(full&#160;audiobook)&#160;g.r.s.&#160;mead&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="1191.2" textLength="61" clip-path="url(#terminal-1756251412-line-48)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="1191.2" textLength="1122.4" clip-path="url(#terminal-1756251412-line-48)">https://altrusiangrace.bandcamp.com/album/pistis-sophia-full-audiobook&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="1191.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-48)"></text><text class="terminal-1756251412-r1" x="2537.6" y="1191.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-48)">
</text><text class="terminal-1756251412-r1" x="0" y="1215.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-49)"></text><text class="terminal-1756251412-r1" x="48.8" y="1215.6" textLength="24.4" clip-path="url(#terminal-1756251412-line-49)">45</text><text class="terminal-1756251412-r1" x="109.8" y="1215.6" textLength="1122.4" clip-path="url(#terminal-1756251412-line-49)">the&#160;ten&#160;principal&#160;upanishads&#160;(full&#160;audiobook)&#160;w.&#160;b.&#160;yeats&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="1215.6" textLength="61" clip-path="url(#terminal-1756251412-line-49)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="1215.6" textLength="1122.4" clip-path="url(#terminal-1756251412-line-49)">https://altrusiangrace.bandcamp.com/album/the-ten-principal-upanishads-full-audiobook&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="1215.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-49)"></text><text class="terminal-1756251412-r1" x="2537.6" y="1215.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-49)">
</text><text class="terminal-1756251412-r1" x="0" y="1240" textLength="12.2" clip-path="url(#terminal-1756251412-line-50)"></text><text class="terminal-1756251412-r1" x="48.8" y="1240" textLength="24.4" clip-path="url(#terminal-1756251412-line-50)">46</text><text class="terminal-1756251412-r1" x="109.8" y="1240" textLength="1122.4" clip-path="url(#terminal-1756251412-line-50)">dreams&#160;-&#160;what&#160;they&#160;are&#160;and&#160;how&#160;they&#160;are&#160;caused&#160;(full&#160;audiobook)&#160;c.w.&#160;leadbeater&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="1240" textLength="61" clip-path="url(#terminal-1756251412-line-50)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="1240" textLength="1122.4" clip-path="url(#terminal-1756251412-line-50)">https://altrusiangrace.bandcamp.com/album/dreams-what-they-are-and-how-they-are-caused-full…</text><text class="terminal-1756251412-r1" x="2525.4" y="1240" textLength="12.2" clip-path="url(#terminal-1756251412-line-50)"></text><text class="terminal-1756251412-r1" x="2537.6" y="1240" textLength="12.2" clip-path="url(#terminal-1756251412-line-50)">
</text><text class="terminal-1756251412-r1" x="0" y="1264.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-51)"></text><text class="terminal-1756251412-r1" x="48.8" y="1264.4" textLength="24.4" clip-path="url(#terminal-1756251412-line-51)">47</text><text class="terminal-1756251412-r1" x="109.8" y="1264.4" textLength="1122.4" clip-path="url(#terminal-1756251412-line-51)">secret&#160;of&#160;the&#160;golden&#160;flower&#160;(full&#160;audiobook)&#160;richard&#160;wilhelm,&#160;c.g.&#160;jung&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="1264.4" textLength="61" clip-path="url(#terminal-1756251412-line-51)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="1264.4" textLength="1122.4" clip-path="url(#terminal-1756251412-line-51)">https://altrusiangrace.bandcamp.com/album/secret-of-the-golden-flower-full-audiobook&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="1264.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-51)"></text><text class="terminal-1756251412-r1" x="2537.6" y="1264.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-51)">
</text><text class="terminal-1756251412-r1" x="0" y="1288.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-52)"></text><text class="terminal-1756251412-r1" x="48.8" y="1288.8" textLength="24.4" clip-path="url(#terminal-1756251412-line-52)">48</text><text class="terminal-1756251412-r1" x="109.8" y="1288.8" textLength="1122.4" clip-path="url(#terminal-1756251412-line-52)">the&#160;hymns&#160;of&#160;hermes&#160;(full&#160;audiobook)&#160;g.r.s.&#160;mead&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="1288.8" textLength="61" clip-path="url(#terminal-1756251412-line-52)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="1288.8" textLength="1122.4" clip-path="url(#terminal-1756251412-line-52)">https://altrusiangrace.bandcamp.com/album/the-hymns-of-hermes-full-audiobook&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="1288.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-52)"></text><text class="terminal-1756251412-r1" x="2537.6" y="1288.8" textLength="12.2" clip-path="url(#terminal-1756251412-line-52)">
</text><text class="terminal-1756251412-r1" x="0" y="1313.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-53)"></text><text class="terminal-1756251412-r1" x="48.8" y="1313.2" textLength="24.4" clip-path="url(#terminal-1756251412-line-53)">49</text><text class="terminal-1756251412-r1" x="109.8" y="1313.2" textLength="1122.4" clip-path="url(#terminal-1756251412-line-53)">the&#160;prose&#160;of&#160;clark&#160;ashton&#160;smith&#160;(full&#160;audiobook)&#160;clark&#160;ashton&#160;smith&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="1313.2" textLength="61" clip-path="url(#terminal-1756251412-line-53)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="1313.2" textLength="1122.4" clip-path="url(#terminal-1756251412-line-53)">https://altrusiangrace.bandcamp.com/album/the-prose-of-clark-ashton-smith-full-audiobook&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="1313.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-53)"></text><text class="terminal-1756251412-r1" x="2537.6" y="1313.2" textLength="12.2" clip-path="url(#terminal-1756251412-line-53)">
</text><text class="terminal-1756251412-r1" x="0" y="1337.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-54)"></text><text class="terminal-1756251412-r1" x="48.8" y="1337.6" textLength="24.4" clip-path="url(#terminal-1756251412-line-54)">50</text><text class="terminal-1756251412-r1" x="109.8" y="1337.6" textLength="1122.4" clip-path="url(#terminal-1756251412-line-54)">veriditas&#160;illuminated&#160;void&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="1268.8" y="1337.6" textLength="61" clip-path="url(#terminal-1756251412-line-54)">album</text><text class="terminal-1756251412-r1" x="1366.4" y="1337.6" textLength="1122.4" clip-path="url(#terminal-1756251412-line-54)">https://altrusiangrace.bandcamp.com/album/veriditas&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1756251412-r1" x="2525.4" y="1337.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-54)"></text><text class="terminal-1756251412-r1" x="2537.6" y="1337.6" textLength="12.2" clip-path="url(#terminal-1756251412-line-54)">
</text><text class="terminal-1756251412-r1" x="0" y="1362" textLength="12.2" clip-path="url(#terminal-1756251412-line-55)"></text><text class="terminal-1756251412-r1" x="2525.4" y="1362" textLength="12.2" clip-path="url(#terminal-1756251412-line-55)"></text><text class="terminal-1756251412-r1" x="2537.6" y="1362" textLength="12.2" clip-path="url(#terminal-1756251412-line-55)">
</text><text class="terminal-1756251412-r1" x="0" y="1386.4" textLength="2537.6" clip-path="url(#terminal-1756251412-line-56)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="terminal-1756251412-r1" x="2537.6" y="1386.4" textLength="12.2" clip-path="url(#terminal-1756251412-line-56)">
</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 83 KiB

View File

@@ -0,0 +1,83 @@
<svg class="rich-terminal" viewBox="0 0 2556 220.79999999999998" xmlns="http://www.w3.org/2000/svg">
<!-- Generated with Rich https://www.textualize.io -->
<style>
@font-face {
font-family: "Fira Code";
src: local("FiraCode-Regular"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Regular.woff2") format("woff2"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Regular.woff") format("woff");
font-style: normal;
font-weight: 400;
}
@font-face {
font-family: "Fira Code";
src: local("FiraCode-Bold"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Bold.woff2") format("woff2"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Bold.woff") format("woff");
font-style: bold;
font-weight: 700;
}
.terminal-2157116369-matrix {
font-family: Fira Code, monospace;
font-size: 20px;
line-height: 24.4px;
font-variant-east-asian: full-width;
}
.terminal-2157116369-title {
font-size: 18px;
font-weight: bold;
font-family: arial;
}
.terminal-2157116369-r1 { fill: #c5c8c6 }
.terminal-2157116369-r2 { fill: #c5c8c6;font-weight: bold }
</style>
<defs>
<clipPath id="terminal-2157116369-clip-terminal">
<rect x="0" y="0" width="2536.6" height="169.79999999999998" />
</clipPath>
<clipPath id="terminal-2157116369-line-0">
<rect x="0" y="1.5" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2157116369-line-1">
<rect x="0" y="25.9" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2157116369-line-2">
<rect x="0" y="50.3" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2157116369-line-3">
<rect x="0" y="74.7" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2157116369-line-4">
<rect x="0" y="99.1" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2157116369-line-5">
<rect x="0" y="123.5" width="2537.6" height="24.65"/>
</clipPath>
</defs>
<rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="2554" height="218.8" rx="8"/><text class="terminal-2157116369-title" fill="#c5c8c6" text-anchor="middle" x="1277" y="27">Rich</text>
<g transform="translate(26,22)">
<circle cx="0" cy="0" r="7" fill="#ff5f57"/>
<circle cx="22" cy="0" r="7" fill="#febc2e"/>
<circle cx="44" cy="0" r="7" fill="#28c840"/>
</g>
<g transform="translate(9, 41)" clip-path="url(#terminal-2157116369-clip-terminal)">
<g class="terminal-2157116369-matrix">
<text class="terminal-2157116369-r1" x="0" y="20" textLength="24.4" clip-path="url(#terminal-2157116369-line-0)">╭─</text><text class="terminal-2157116369-r1" x="24.4" y="20" textLength="2488.8" clip-path="url(#terminal-2157116369-line-0)">──────────────────────────────────────────────────────────────────────────────────&#160;Bandcamp:&#160;artist:altrusian&#160;grace&#160;media&#160;──────────────────────────────────────────────────────────────────────────────────</text><text class="terminal-2157116369-r1" x="2513.2" y="20" textLength="24.4" clip-path="url(#terminal-2157116369-line-0)">─╮</text><text class="terminal-2157116369-r1" x="2537.6" y="20" textLength="12.2" clip-path="url(#terminal-2157116369-line-0)">
</text><text class="terminal-2157116369-r1" x="0" y="44.4" textLength="12.2" clip-path="url(#terminal-2157116369-line-1)"></text><text class="terminal-2157116369-r1" x="2525.4" y="44.4" textLength="12.2" clip-path="url(#terminal-2157116369-line-1)"></text><text class="terminal-2157116369-r1" x="2537.6" y="44.4" textLength="12.2" clip-path="url(#terminal-2157116369-line-1)">
</text><text class="terminal-2157116369-r1" x="0" y="68.8" textLength="12.2" clip-path="url(#terminal-2157116369-line-2)"></text><text class="terminal-2157116369-r2" x="48.8" y="68.8" textLength="61" clip-path="url(#terminal-2157116369-line-2)">&#160;&#160;&#160;&#160;#</text><text class="terminal-2157116369-r2" x="146.4" y="68.8" textLength="573.4" clip-path="url(#terminal-2157116369-line-2)">TITLE&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2157116369-r2" x="756.4" y="68.8" textLength="549" clip-path="url(#terminal-2157116369-line-2)">LOCATION&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2157116369-r2" x="1342" y="68.8" textLength="183" clip-path="url(#terminal-2157116369-line-2)">TYPE&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2157116369-r2" x="1561.6" y="68.8" textLength="927.2" clip-path="url(#terminal-2157116369-line-2)">URL&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2157116369-r1" x="2525.4" y="68.8" textLength="12.2" clip-path="url(#terminal-2157116369-line-2)"></text><text class="terminal-2157116369-r1" x="2537.6" y="68.8" textLength="12.2" clip-path="url(#terminal-2157116369-line-2)">
</text><text class="terminal-2157116369-r1" x="0" y="93.2" textLength="12.2" clip-path="url(#terminal-2157116369-line-3)"></text><text class="terminal-2157116369-r1" x="24.4" y="93.2" textLength="2488.8" clip-path="url(#terminal-2157116369-line-3)">&#160;──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────&#160;</text><text class="terminal-2157116369-r1" x="2525.4" y="93.2" textLength="12.2" clip-path="url(#terminal-2157116369-line-3)"></text><text class="terminal-2157116369-r1" x="2537.6" y="93.2" textLength="12.2" clip-path="url(#terminal-2157116369-line-3)">
</text><text class="terminal-2157116369-r1" x="0" y="117.6" textLength="12.2" clip-path="url(#terminal-2157116369-line-4)"></text><text class="terminal-2157116369-r1" x="48.8" y="117.6" textLength="61" clip-path="url(#terminal-2157116369-line-4)">&#160;&#160;&#160;&#160;1</text><text class="terminal-2157116369-r1" x="146.4" y="117.6" textLength="573.4" clip-path="url(#terminal-2157116369-line-4)">altrusian&#160;grace&#160;media&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2157116369-r1" x="756.4" y="117.6" textLength="549" clip-path="url(#terminal-2157116369-line-4)">milwaukee,&#160;wisconsin&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2157116369-r1" x="1342" y="117.6" textLength="183" clip-path="url(#terminal-2157116369-line-4)">artist&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2157116369-r1" x="1561.6" y="117.6" textLength="927.2" clip-path="url(#terminal-2157116369-line-4)">https://altrusiangrace.bandcamp.com&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2157116369-r1" x="2525.4" y="117.6" textLength="12.2" clip-path="url(#terminal-2157116369-line-4)"></text><text class="terminal-2157116369-r1" x="2537.6" y="117.6" textLength="12.2" clip-path="url(#terminal-2157116369-line-4)">
</text><text class="terminal-2157116369-r1" x="0" y="142" textLength="12.2" clip-path="url(#terminal-2157116369-line-5)"></text><text class="terminal-2157116369-r1" x="2525.4" y="142" textLength="12.2" clip-path="url(#terminal-2157116369-line-5)"></text><text class="terminal-2157116369-r1" x="2537.6" y="142" textLength="12.2" clip-path="url(#terminal-2157116369-line-5)">
</text><text class="terminal-2157116369-r1" x="0" y="166.4" textLength="2537.6" clip-path="url(#terminal-2157116369-line-6)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="terminal-2157116369-r1" x="2537.6" y="166.4" textLength="12.2" clip-path="url(#terminal-2157116369-line-6)">
</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -0,0 +1,151 @@
<svg class="rich-terminal" viewBox="0 0 2556 635.5999999999999" xmlns="http://www.w3.org/2000/svg">
<!-- Generated with Rich https://www.textualize.io -->
<style>
@font-face {
font-family: "Fira Code";
src: local("FiraCode-Regular"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Regular.woff2") format("woff2"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Regular.woff") format("woff");
font-style: normal;
font-weight: 400;
}
@font-face {
font-family: "Fira Code";
src: local("FiraCode-Bold"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Bold.woff2") format("woff2"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Bold.woff") format("woff");
font-style: bold;
font-weight: 700;
}
.terminal-3450042185-matrix {
font-family: Fira Code, monospace;
font-size: 20px;
line-height: 24.4px;
font-variant-east-asian: full-width;
}
.terminal-3450042185-title {
font-size: 18px;
font-weight: bold;
font-family: arial;
}
.terminal-3450042185-r1 { fill: #c5c8c6 }
.terminal-3450042185-r2 { fill: #c5c8c6;font-weight: bold }
</style>
<defs>
<clipPath id="terminal-3450042185-clip-terminal">
<rect x="0" y="0" width="2536.6" height="584.5999999999999" />
</clipPath>
<clipPath id="terminal-3450042185-line-0">
<rect x="0" y="1.5" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-3450042185-line-1">
<rect x="0" y="25.9" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-3450042185-line-2">
<rect x="0" y="50.3" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-3450042185-line-3">
<rect x="0" y="74.7" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-3450042185-line-4">
<rect x="0" y="99.1" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-3450042185-line-5">
<rect x="0" y="123.5" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-3450042185-line-6">
<rect x="0" y="147.9" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-3450042185-line-7">
<rect x="0" y="172.3" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-3450042185-line-8">
<rect x="0" y="196.7" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-3450042185-line-9">
<rect x="0" y="221.1" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-3450042185-line-10">
<rect x="0" y="245.5" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-3450042185-line-11">
<rect x="0" y="269.9" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-3450042185-line-12">
<rect x="0" y="294.3" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-3450042185-line-13">
<rect x="0" y="318.7" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-3450042185-line-14">
<rect x="0" y="343.1" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-3450042185-line-15">
<rect x="0" y="367.5" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-3450042185-line-16">
<rect x="0" y="391.9" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-3450042185-line-17">
<rect x="0" y="416.3" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-3450042185-line-18">
<rect x="0" y="440.7" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-3450042185-line-19">
<rect x="0" y="465.1" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-3450042185-line-20">
<rect x="0" y="489.5" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-3450042185-line-21">
<rect x="0" y="513.9" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-3450042185-line-22">
<rect x="0" y="538.3" width="2537.6" height="24.65"/>
</clipPath>
</defs>
<rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="2554" height="633.6" rx="8"/><text class="terminal-3450042185-title" fill="#c5c8c6" text-anchor="middle" x="1277" y="27">Rich</text>
<g transform="translate(26,22)">
<circle cx="0" cy="0" r="7" fill="#ff5f57"/>
<circle cx="22" cy="0" r="7" fill="#febc2e"/>
<circle cx="44" cy="0" r="7" fill="#28c840"/>
</g>
<g transform="translate(9, 41)" clip-path="url(#terminal-3450042185-clip-terminal)">
<g class="terminal-3450042185-matrix">
<text class="terminal-3450042185-r1" x="0" y="20" textLength="24.4" clip-path="url(#terminal-3450042185-line-0)">╭─</text><text class="terminal-3450042185-r1" x="24.4" y="20" textLength="2488.8" clip-path="url(#terminal-3450042185-line-0)">────────────────────────────────────────────&#160;download-media&#160;-url&#160;&quot;https://altrusiangrace.bandcamp.com/album/zetetic-astronomy-earth-not-a-globe-full-audiobook&quot;&#160;────────────────────────────────────────────</text><text class="terminal-3450042185-r1" x="2513.2" y="20" textLength="24.4" clip-path="url(#terminal-3450042185-line-0)">─╮</text><text class="terminal-3450042185-r1" x="2537.6" y="20" textLength="12.2" clip-path="url(#terminal-3450042185-line-0)">
</text><text class="terminal-3450042185-r1" x="0" y="44.4" textLength="12.2" clip-path="url(#terminal-3450042185-line-1)"></text><text class="terminal-3450042185-r1" x="2525.4" y="44.4" textLength="12.2" clip-path="url(#terminal-3450042185-line-1)"></text><text class="terminal-3450042185-r1" x="2537.6" y="44.4" textLength="12.2" clip-path="url(#terminal-3450042185-line-1)">
</text><text class="terminal-3450042185-r1" x="0" y="68.8" textLength="12.2" clip-path="url(#terminal-3450042185-line-2)"></text><text class="terminal-3450042185-r2" x="48.8" y="68.8" textLength="195.2" clip-path="url(#terminal-3450042185-line-2)">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;#</text><text class="terminal-3450042185-r2" x="280.6" y="68.8" textLength="1110.2" clip-path="url(#terminal-3450042185-line-2)">TITLE&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3450042185-r2" x="1427.4" y="68.8" textLength="512.4" clip-path="url(#terminal-3450042185-line-2)">DURATION&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3450042185-r2" x="1976.4" y="68.8" textLength="512.4" clip-path="url(#terminal-3450042185-line-2)">UPLOADER&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3450042185-r1" x="2525.4" y="68.8" textLength="12.2" clip-path="url(#terminal-3450042185-line-2)"></text><text class="terminal-3450042185-r1" x="2537.6" y="68.8" textLength="12.2" clip-path="url(#terminal-3450042185-line-2)">
</text><text class="terminal-3450042185-r1" x="0" y="93.2" textLength="12.2" clip-path="url(#terminal-3450042185-line-3)"></text><text class="terminal-3450042185-r1" x="24.4" y="93.2" textLength="2488.8" clip-path="url(#terminal-3450042185-line-3)">&#160;──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────&#160;</text><text class="terminal-3450042185-r1" x="2525.4" y="93.2" textLength="12.2" clip-path="url(#terminal-3450042185-line-3)"></text><text class="terminal-3450042185-r1" x="2537.6" y="93.2" textLength="12.2" clip-path="url(#terminal-3450042185-line-3)">
</text><text class="terminal-3450042185-r1" x="0" y="117.6" textLength="12.2" clip-path="url(#terminal-3450042185-line-4)"></text><text class="terminal-3450042185-r1" x="48.8" y="117.6" textLength="195.2" clip-path="url(#terminal-3450042185-line-4)">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;1</text><text class="terminal-3450042185-r1" x="280.6" y="117.6" textLength="1110.2" clip-path="url(#terminal-3450042185-line-4)">opening&#160;credits&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3450042185-r1" x="2525.4" y="117.6" textLength="12.2" clip-path="url(#terminal-3450042185-line-4)"></text><text class="terminal-3450042185-r1" x="2537.6" y="117.6" textLength="12.2" clip-path="url(#terminal-3450042185-line-4)">
</text><text class="terminal-3450042185-r1" x="0" y="142" textLength="12.2" clip-path="url(#terminal-3450042185-line-5)"></text><text class="terminal-3450042185-r1" x="48.8" y="142" textLength="195.2" clip-path="url(#terminal-3450042185-line-5)">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;2</text><text class="terminal-3450042185-r1" x="280.6" y="142" textLength="1110.2" clip-path="url(#terminal-3450042185-line-5)">preface&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3450042185-r1" x="2525.4" y="142" textLength="12.2" clip-path="url(#terminal-3450042185-line-5)"></text><text class="terminal-3450042185-r1" x="2537.6" y="142" textLength="12.2" clip-path="url(#terminal-3450042185-line-5)">
</text><text class="terminal-3450042185-r1" x="0" y="166.4" textLength="12.2" clip-path="url(#terminal-3450042185-line-6)"></text><text class="terminal-3450042185-r1" x="48.8" y="166.4" textLength="195.2" clip-path="url(#terminal-3450042185-line-6)">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;3</text><text class="terminal-3450042185-r1" x="280.6" y="166.4" textLength="1110.2" clip-path="url(#terminal-3450042185-line-6)">chapter&#160;1&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3450042185-r1" x="2525.4" y="166.4" textLength="12.2" clip-path="url(#terminal-3450042185-line-6)"></text><text class="terminal-3450042185-r1" x="2537.6" y="166.4" textLength="12.2" clip-path="url(#terminal-3450042185-line-6)">
</text><text class="terminal-3450042185-r1" x="0" y="190.8" textLength="12.2" clip-path="url(#terminal-3450042185-line-7)"></text><text class="terminal-3450042185-r1" x="48.8" y="190.8" textLength="195.2" clip-path="url(#terminal-3450042185-line-7)">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;4</text><text class="terminal-3450042185-r1" x="280.6" y="190.8" textLength="1110.2" clip-path="url(#terminal-3450042185-line-7)">chapter&#160;2&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3450042185-r1" x="2525.4" y="190.8" textLength="12.2" clip-path="url(#terminal-3450042185-line-7)"></text><text class="terminal-3450042185-r1" x="2537.6" y="190.8" textLength="12.2" clip-path="url(#terminal-3450042185-line-7)">
</text><text class="terminal-3450042185-r1" x="0" y="215.2" textLength="12.2" clip-path="url(#terminal-3450042185-line-8)"></text><text class="terminal-3450042185-r1" x="48.8" y="215.2" textLength="195.2" clip-path="url(#terminal-3450042185-line-8)">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;5</text><text class="terminal-3450042185-r1" x="280.6" y="215.2" textLength="1110.2" clip-path="url(#terminal-3450042185-line-8)">chapter&#160;3&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3450042185-r1" x="2525.4" y="215.2" textLength="12.2" clip-path="url(#terminal-3450042185-line-8)"></text><text class="terminal-3450042185-r1" x="2537.6" y="215.2" textLength="12.2" clip-path="url(#terminal-3450042185-line-8)">
</text><text class="terminal-3450042185-r1" x="0" y="239.6" textLength="12.2" clip-path="url(#terminal-3450042185-line-9)"></text><text class="terminal-3450042185-r1" x="48.8" y="239.6" textLength="195.2" clip-path="url(#terminal-3450042185-line-9)">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;6</text><text class="terminal-3450042185-r1" x="280.6" y="239.6" textLength="1110.2" clip-path="url(#terminal-3450042185-line-9)">chapter&#160;4&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3450042185-r1" x="2525.4" y="239.6" textLength="12.2" clip-path="url(#terminal-3450042185-line-9)"></text><text class="terminal-3450042185-r1" x="2537.6" y="239.6" textLength="12.2" clip-path="url(#terminal-3450042185-line-9)">
</text><text class="terminal-3450042185-r1" x="0" y="264" textLength="12.2" clip-path="url(#terminal-3450042185-line-10)"></text><text class="terminal-3450042185-r1" x="48.8" y="264" textLength="195.2" clip-path="url(#terminal-3450042185-line-10)">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;7</text><text class="terminal-3450042185-r1" x="280.6" y="264" textLength="1110.2" clip-path="url(#terminal-3450042185-line-10)">chapter&#160;5&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3450042185-r1" x="2525.4" y="264" textLength="12.2" clip-path="url(#terminal-3450042185-line-10)"></text><text class="terminal-3450042185-r1" x="2537.6" y="264" textLength="12.2" clip-path="url(#terminal-3450042185-line-10)">
</text><text class="terminal-3450042185-r1" x="0" y="288.4" textLength="12.2" clip-path="url(#terminal-3450042185-line-11)"></text><text class="terminal-3450042185-r1" x="48.8" y="288.4" textLength="195.2" clip-path="url(#terminal-3450042185-line-11)">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;8</text><text class="terminal-3450042185-r1" x="280.6" y="288.4" textLength="1110.2" clip-path="url(#terminal-3450042185-line-11)">chapter&#160;6&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3450042185-r1" x="2525.4" y="288.4" textLength="12.2" clip-path="url(#terminal-3450042185-line-11)"></text><text class="terminal-3450042185-r1" x="2537.6" y="288.4" textLength="12.2" clip-path="url(#terminal-3450042185-line-11)">
</text><text class="terminal-3450042185-r1" x="0" y="312.8" textLength="12.2" clip-path="url(#terminal-3450042185-line-12)"></text><text class="terminal-3450042185-r1" x="48.8" y="312.8" textLength="195.2" clip-path="url(#terminal-3450042185-line-12)">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;9</text><text class="terminal-3450042185-r1" x="280.6" y="312.8" textLength="1110.2" clip-path="url(#terminal-3450042185-line-12)">chapter&#160;7&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3450042185-r1" x="2525.4" y="312.8" textLength="12.2" clip-path="url(#terminal-3450042185-line-12)"></text><text class="terminal-3450042185-r1" x="2537.6" y="312.8" textLength="12.2" clip-path="url(#terminal-3450042185-line-12)">
</text><text class="terminal-3450042185-r1" x="0" y="337.2" textLength="12.2" clip-path="url(#terminal-3450042185-line-13)"></text><text class="terminal-3450042185-r1" x="48.8" y="337.2" textLength="195.2" clip-path="url(#terminal-3450042185-line-13)">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;10</text><text class="terminal-3450042185-r1" x="280.6" y="337.2" textLength="1110.2" clip-path="url(#terminal-3450042185-line-13)">chapter&#160;8&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3450042185-r1" x="2525.4" y="337.2" textLength="12.2" clip-path="url(#terminal-3450042185-line-13)"></text><text class="terminal-3450042185-r1" x="2537.6" y="337.2" textLength="12.2" clip-path="url(#terminal-3450042185-line-13)">
</text><text class="terminal-3450042185-r1" x="0" y="361.6" textLength="12.2" clip-path="url(#terminal-3450042185-line-14)"></text><text class="terminal-3450042185-r1" x="48.8" y="361.6" textLength="195.2" clip-path="url(#terminal-3450042185-line-14)">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;11</text><text class="terminal-3450042185-r1" x="280.6" y="361.6" textLength="1110.2" clip-path="url(#terminal-3450042185-line-14)">chapter&#160;9&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3450042185-r1" x="2525.4" y="361.6" textLength="12.2" clip-path="url(#terminal-3450042185-line-14)"></text><text class="terminal-3450042185-r1" x="2537.6" y="361.6" textLength="12.2" clip-path="url(#terminal-3450042185-line-14)">
</text><text class="terminal-3450042185-r1" x="0" y="386" textLength="12.2" clip-path="url(#terminal-3450042185-line-15)"></text><text class="terminal-3450042185-r1" x="48.8" y="386" textLength="195.2" clip-path="url(#terminal-3450042185-line-15)">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;12</text><text class="terminal-3450042185-r1" x="280.6" y="386" textLength="1110.2" clip-path="url(#terminal-3450042185-line-15)">chapter&#160;10&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3450042185-r1" x="2525.4" y="386" textLength="12.2" clip-path="url(#terminal-3450042185-line-15)"></text><text class="terminal-3450042185-r1" x="2537.6" y="386" textLength="12.2" clip-path="url(#terminal-3450042185-line-15)">
</text><text class="terminal-3450042185-r1" x="0" y="410.4" textLength="12.2" clip-path="url(#terminal-3450042185-line-16)"></text><text class="terminal-3450042185-r1" x="48.8" y="410.4" textLength="195.2" clip-path="url(#terminal-3450042185-line-16)">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;13</text><text class="terminal-3450042185-r1" x="280.6" y="410.4" textLength="1110.2" clip-path="url(#terminal-3450042185-line-16)">chapter&#160;11&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3450042185-r1" x="2525.4" y="410.4" textLength="12.2" clip-path="url(#terminal-3450042185-line-16)"></text><text class="terminal-3450042185-r1" x="2537.6" y="410.4" textLength="12.2" clip-path="url(#terminal-3450042185-line-16)">
</text><text class="terminal-3450042185-r1" x="0" y="434.8" textLength="12.2" clip-path="url(#terminal-3450042185-line-17)"></text><text class="terminal-3450042185-r1" x="48.8" y="434.8" textLength="195.2" clip-path="url(#terminal-3450042185-line-17)">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;14</text><text class="terminal-3450042185-r1" x="280.6" y="434.8" textLength="1110.2" clip-path="url(#terminal-3450042185-line-17)">chapter&#160;12&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3450042185-r1" x="2525.4" y="434.8" textLength="12.2" clip-path="url(#terminal-3450042185-line-17)"></text><text class="terminal-3450042185-r1" x="2537.6" y="434.8" textLength="12.2" clip-path="url(#terminal-3450042185-line-17)">
</text><text class="terminal-3450042185-r1" x="0" y="459.2" textLength="12.2" clip-path="url(#terminal-3450042185-line-18)"></text><text class="terminal-3450042185-r1" x="48.8" y="459.2" textLength="195.2" clip-path="url(#terminal-3450042185-line-18)">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;15</text><text class="terminal-3450042185-r1" x="280.6" y="459.2" textLength="1110.2" clip-path="url(#terminal-3450042185-line-18)">chapter&#160;13&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3450042185-r1" x="2525.4" y="459.2" textLength="12.2" clip-path="url(#terminal-3450042185-line-18)"></text><text class="terminal-3450042185-r1" x="2537.6" y="459.2" textLength="12.2" clip-path="url(#terminal-3450042185-line-18)">
</text><text class="terminal-3450042185-r1" x="0" y="483.6" textLength="12.2" clip-path="url(#terminal-3450042185-line-19)"></text><text class="terminal-3450042185-r1" x="48.8" y="483.6" textLength="195.2" clip-path="url(#terminal-3450042185-line-19)">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;16</text><text class="terminal-3450042185-r1" x="280.6" y="483.6" textLength="1110.2" clip-path="url(#terminal-3450042185-line-19)">chapter&#160;14&#160;(part&#160;1)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3450042185-r1" x="2525.4" y="483.6" textLength="12.2" clip-path="url(#terminal-3450042185-line-19)"></text><text class="terminal-3450042185-r1" x="2537.6" y="483.6" textLength="12.2" clip-path="url(#terminal-3450042185-line-19)">
</text><text class="terminal-3450042185-r1" x="0" y="508" textLength="12.2" clip-path="url(#terminal-3450042185-line-20)"></text><text class="terminal-3450042185-r1" x="48.8" y="508" textLength="195.2" clip-path="url(#terminal-3450042185-line-20)">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;17</text><text class="terminal-3450042185-r1" x="280.6" y="508" textLength="1110.2" clip-path="url(#terminal-3450042185-line-20)">chapter&#160;14&#160;(part&#160;2)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3450042185-r1" x="2525.4" y="508" textLength="12.2" clip-path="url(#terminal-3450042185-line-20)"></text><text class="terminal-3450042185-r1" x="2537.6" y="508" textLength="12.2" clip-path="url(#terminal-3450042185-line-20)">
</text><text class="terminal-3450042185-r1" x="0" y="532.4" textLength="12.2" clip-path="url(#terminal-3450042185-line-21)"></text><text class="terminal-3450042185-r1" x="48.8" y="532.4" textLength="195.2" clip-path="url(#terminal-3450042185-line-21)">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;18</text><text class="terminal-3450042185-r1" x="280.6" y="532.4" textLength="1110.2" clip-path="url(#terminal-3450042185-line-21)">chapter&#160;15&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3450042185-r1" x="2525.4" y="532.4" textLength="12.2" clip-path="url(#terminal-3450042185-line-21)"></text><text class="terminal-3450042185-r1" x="2537.6" y="532.4" textLength="12.2" clip-path="url(#terminal-3450042185-line-21)">
</text><text class="terminal-3450042185-r1" x="0" y="556.8" textLength="12.2" clip-path="url(#terminal-3450042185-line-22)"></text><text class="terminal-3450042185-r1" x="2525.4" y="556.8" textLength="12.2" clip-path="url(#terminal-3450042185-line-22)"></text><text class="terminal-3450042185-r1" x="2537.6" y="556.8" textLength="12.2" clip-path="url(#terminal-3450042185-line-22)">
</text><text class="terminal-3450042185-r1" x="0" y="581.2" textLength="2537.6" clip-path="url(#terminal-3450042185-line-23)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="terminal-3450042185-r1" x="2537.6" y="581.2" textLength="12.2" clip-path="url(#terminal-3450042185-line-23)">
</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 32 KiB

87
docs/img/get-url.svg Normal file
View File

@@ -0,0 +1,87 @@
<svg class="rich-terminal" viewBox="0 0 2556 245.2" xmlns="http://www.w3.org/2000/svg">
<!-- Generated with Rich https://www.textualize.io -->
<style>
@font-face {
font-family: "Fira Code";
src: local("FiraCode-Regular"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Regular.woff2") format("woff2"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Regular.woff") format("woff");
font-style: normal;
font-weight: 400;
}
@font-face {
font-family: "Fira Code";
src: local("FiraCode-Bold"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Bold.woff2") format("woff2"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Bold.woff") format("woff");
font-style: bold;
font-weight: 700;
}
.terminal-606838084-matrix {
font-family: Fira Code, monospace;
font-size: 20px;
line-height: 24.4px;
font-variant-east-asian: full-width;
}
.terminal-606838084-title {
font-size: 18px;
font-weight: bold;
font-family: arial;
}
.terminal-606838084-r1 { fill: #c5c8c6 }
.terminal-606838084-r2 { fill: #c5c8c6;font-weight: bold }
</style>
<defs>
<clipPath id="terminal-606838084-clip-terminal">
<rect x="0" y="0" width="2536.6" height="194.2" />
</clipPath>
<clipPath id="terminal-606838084-line-0">
<rect x="0" y="1.5" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-606838084-line-1">
<rect x="0" y="25.9" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-606838084-line-2">
<rect x="0" y="50.3" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-606838084-line-3">
<rect x="0" y="74.7" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-606838084-line-4">
<rect x="0" y="99.1" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-606838084-line-5">
<rect x="0" y="123.5" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-606838084-line-6">
<rect x="0" y="147.9" width="2537.6" height="24.65"/>
</clipPath>
</defs>
<rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="2554" height="243.2" rx="8"/><text class="terminal-606838084-title" fill="#c5c8c6" text-anchor="middle" x="1277" y="27">Rich</text>
<g transform="translate(26,22)">
<circle cx="0" cy="0" r="7" fill="#ff5f57"/>
<circle cx="22" cy="0" r="7" fill="#febc2e"/>
<circle cx="44" cy="0" r="7" fill="#28c840"/>
</g>
<g transform="translate(9, 41)" clip-path="url(#terminal-606838084-clip-terminal)">
<g class="terminal-606838084-matrix">
<text class="terminal-606838084-r1" x="0" y="20" textLength="24.4" clip-path="url(#terminal-606838084-line-0)">╭─</text><text class="terminal-606838084-r1" x="24.4" y="20" textLength="2488.8" clip-path="url(#terminal-606838084-line-0)">───────────────────────────────────────────────────────────────────────────────────────────────────&#160;url&#160;────────────────────────────────────────────────────────────────────────────────────────────────────</text><text class="terminal-606838084-r1" x="2513.2" y="20" textLength="24.4" clip-path="url(#terminal-606838084-line-0)">─╮</text><text class="terminal-606838084-r1" x="2537.6" y="20" textLength="12.2" clip-path="url(#terminal-606838084-line-0)">
</text><text class="terminal-606838084-r1" x="0" y="44.4" textLength="12.2" clip-path="url(#terminal-606838084-line-1)"></text><text class="terminal-606838084-r1" x="2525.4" y="44.4" textLength="12.2" clip-path="url(#terminal-606838084-line-1)"></text><text class="terminal-606838084-r1" x="2537.6" y="44.4" textLength="12.2" clip-path="url(#terminal-606838084-line-1)">
</text><text class="terminal-606838084-r1" x="0" y="68.8" textLength="12.2" clip-path="url(#terminal-606838084-line-2)"></text><text class="terminal-606838084-r2" x="48.8" y="68.8" textLength="48.8" clip-path="url(#terminal-606838084-line-2)">&#160;&#160;&#160;#</text><text class="terminal-606838084-r2" x="134.2" y="68.8" textLength="597.8" clip-path="url(#terminal-606838084-line-2)">URL&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-606838084-r2" x="768.6" y="68.8" textLength="1488.4" clip-path="url(#terminal-606838084-line-2)">HASH&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-606838084-r2" x="2293.6" y="68.8" textLength="195.2" clip-path="url(#terminal-606838084-line-2)">STORE&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-606838084-r1" x="2525.4" y="68.8" textLength="12.2" clip-path="url(#terminal-606838084-line-2)"></text><text class="terminal-606838084-r1" x="2537.6" y="68.8" textLength="12.2" clip-path="url(#terminal-606838084-line-2)">
</text><text class="terminal-606838084-r1" x="0" y="93.2" textLength="12.2" clip-path="url(#terminal-606838084-line-3)"></text><text class="terminal-606838084-r1" x="24.4" y="93.2" textLength="2488.8" clip-path="url(#terminal-606838084-line-3)">&#160;──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────&#160;</text><text class="terminal-606838084-r1" x="2525.4" y="93.2" textLength="12.2" clip-path="url(#terminal-606838084-line-3)"></text><text class="terminal-606838084-r1" x="2537.6" y="93.2" textLength="12.2" clip-path="url(#terminal-606838084-line-3)">
</text><text class="terminal-606838084-r1" x="0" y="117.6" textLength="12.2" clip-path="url(#terminal-606838084-line-4)"></text><text class="terminal-606838084-r1" x="48.8" y="117.6" textLength="48.8" clip-path="url(#terminal-606838084-line-4)">&#160;&#160;&#160;1</text><text class="terminal-606838084-r1" x="134.2" y="117.6" textLength="597.8" clip-path="url(#terminal-606838084-line-4)">https://www.timecube.net/&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-606838084-r1" x="768.6" y="117.6" textLength="1488.4" clip-path="url(#terminal-606838084-line-4)">e7e50263f8644a28b6b6af1e10283a47c018af504277c83363b38cd76cf89365&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-606838084-r1" x="2293.6" y="117.6" textLength="195.2" clip-path="url(#terminal-606838084-line-4)">tutorial&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-606838084-r1" x="2525.4" y="117.6" textLength="12.2" clip-path="url(#terminal-606838084-line-4)"></text><text class="terminal-606838084-r1" x="2537.6" y="117.6" textLength="12.2" clip-path="url(#terminal-606838084-line-4)">
</text><text class="terminal-606838084-r1" x="0" y="142" textLength="12.2" clip-path="url(#terminal-606838084-line-5)"></text><text class="terminal-606838084-r1" x="48.8" y="142" textLength="48.8" clip-path="url(#terminal-606838084-line-5)">&#160;&#160;&#160;2</text><text class="terminal-606838084-r1" x="134.2" y="142" textLength="597.8" clip-path="url(#terminal-606838084-line-5)">https://0x0.st/pzgy.webp&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-606838084-r1" x="768.6" y="142" textLength="1488.4" clip-path="url(#terminal-606838084-line-5)">e7e50263f8644a28b6b6af1e10283a47c018af504277c83363b38cd76cf89365&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-606838084-r1" x="2293.6" y="142" textLength="195.2" clip-path="url(#terminal-606838084-line-5)">tutorial&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-606838084-r1" x="2525.4" y="142" textLength="12.2" clip-path="url(#terminal-606838084-line-5)"></text><text class="terminal-606838084-r1" x="2537.6" y="142" textLength="12.2" clip-path="url(#terminal-606838084-line-5)">
</text><text class="terminal-606838084-r1" x="0" y="166.4" textLength="12.2" clip-path="url(#terminal-606838084-line-6)"></text><text class="terminal-606838084-r1" x="2525.4" y="166.4" textLength="12.2" clip-path="url(#terminal-606838084-line-6)"></text><text class="terminal-606838084-r1" x="2537.6" y="166.4" textLength="12.2" clip-path="url(#terminal-606838084-line-6)">
</text><text class="terminal-606838084-r1" x="0" y="190.8" textLength="2537.6" clip-path="url(#terminal-606838084-line-7)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="terminal-606838084-r1" x="2537.6" y="190.8" textLength="12.2" clip-path="url(#terminal-606838084-line-7)">
</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

83
docs/img/screen-shot.svg Normal file
View File

@@ -0,0 +1,83 @@
<svg class="rich-terminal" viewBox="0 0 2556 220.79999999999998" xmlns="http://www.w3.org/2000/svg">
<!-- Generated with Rich https://www.textualize.io -->
<style>
@font-face {
font-family: "Fira Code";
src: local("FiraCode-Regular"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Regular.woff2") format("woff2"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Regular.woff") format("woff");
font-style: normal;
font-weight: 400;
}
@font-face {
font-family: "Fira Code";
src: local("FiraCode-Bold"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Bold.woff2") format("woff2"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Bold.woff") format("woff");
font-style: bold;
font-weight: 700;
}
.terminal-1605829847-matrix {
font-family: Fira Code, monospace;
font-size: 20px;
line-height: 24.4px;
font-variant-east-asian: full-width;
}
.terminal-1605829847-title {
font-size: 18px;
font-weight: bold;
font-family: arial;
}
.terminal-1605829847-r1 { fill: #c5c8c6 }
.terminal-1605829847-r2 { fill: #c5c8c6;font-weight: bold }
</style>
<defs>
<clipPath id="terminal-1605829847-clip-terminal">
<rect x="0" y="0" width="2536.6" height="169.79999999999998" />
</clipPath>
<clipPath id="terminal-1605829847-line-0">
<rect x="0" y="1.5" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1605829847-line-1">
<rect x="0" y="25.9" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1605829847-line-2">
<rect x="0" y="50.3" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1605829847-line-3">
<rect x="0" y="74.7" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1605829847-line-4">
<rect x="0" y="99.1" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-1605829847-line-5">
<rect x="0" y="123.5" width="2537.6" height="24.65"/>
</clipPath>
</defs>
<rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="2554" height="218.8" rx="8"/><text class="terminal-1605829847-title" fill="#c5c8c6" text-anchor="middle" x="1277" y="27">Rich</text>
<g transform="translate(26,22)">
<circle cx="0" cy="0" r="7" fill="#ff5f57"/>
<circle cx="22" cy="0" r="7" fill="#febc2e"/>
<circle cx="44" cy="0" r="7" fill="#28c840"/>
</g>
<g transform="translate(9, 41)" clip-path="url(#terminal-1605829847-clip-terminal)">
<g class="terminal-1605829847-matrix">
<text class="terminal-1605829847-r1" x="0" y="20" textLength="24.4" clip-path="url(#terminal-1605829847-line-0)">╭─</text><text class="terminal-1605829847-r1" x="24.4" y="20" textLength="2488.8" clip-path="url(#terminal-1605829847-line-0)">─────────────────────────────────────────────────────────────────────────────────────────&#160;add-file&#160;-store&#160;tutorial&#160;─────────────────────────────────────────────────────────────────────────────────────────</text><text class="terminal-1605829847-r1" x="2513.2" y="20" textLength="24.4" clip-path="url(#terminal-1605829847-line-0)">─╮</text><text class="terminal-1605829847-r1" x="2537.6" y="20" textLength="12.2" clip-path="url(#terminal-1605829847-line-0)">
</text><text class="terminal-1605829847-r1" x="0" y="44.4" textLength="12.2" clip-path="url(#terminal-1605829847-line-1)"></text><text class="terminal-1605829847-r1" x="2525.4" y="44.4" textLength="12.2" clip-path="url(#terminal-1605829847-line-1)"></text><text class="terminal-1605829847-r1" x="2537.6" y="44.4" textLength="12.2" clip-path="url(#terminal-1605829847-line-1)">
</text><text class="terminal-1605829847-r1" x="0" y="68.8" textLength="12.2" clip-path="url(#terminal-1605829847-line-2)"></text><text class="terminal-1605829847-r2" x="48.8" y="68.8" textLength="134.2" clip-path="url(#terminal-1605829847-line-2)">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;#</text><text class="terminal-1605829847-r2" x="219.6" y="68.8" textLength="951.6" clip-path="url(#terminal-1605829847-line-2)">TITLE&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1605829847-r2" x="1207.8" y="68.8" textLength="488" clip-path="url(#terminal-1605829847-line-2)">STORE&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1605829847-r2" x="1732.4" y="68.8" textLength="439.2" clip-path="url(#terminal-1605829847-line-2)">SIZE&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1605829847-r2" x="2208.2" y="68.8" textLength="280.6" clip-path="url(#terminal-1605829847-line-2)">EXT&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1605829847-r1" x="2525.4" y="68.8" textLength="12.2" clip-path="url(#terminal-1605829847-line-2)"></text><text class="terminal-1605829847-r1" x="2537.6" y="68.8" textLength="12.2" clip-path="url(#terminal-1605829847-line-2)">
</text><text class="terminal-1605829847-r1" x="0" y="93.2" textLength="12.2" clip-path="url(#terminal-1605829847-line-3)"></text><text class="terminal-1605829847-r1" x="24.4" y="93.2" textLength="2488.8" clip-path="url(#terminal-1605829847-line-3)">&#160;──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────&#160;</text><text class="terminal-1605829847-r1" x="2525.4" y="93.2" textLength="12.2" clip-path="url(#terminal-1605829847-line-3)"></text><text class="terminal-1605829847-r1" x="2537.6" y="93.2" textLength="12.2" clip-path="url(#terminal-1605829847-line-3)">
</text><text class="terminal-1605829847-r1" x="0" y="117.6" textLength="12.2" clip-path="url(#terminal-1605829847-line-4)"></text><text class="terminal-1605829847-r1" x="48.8" y="117.6" textLength="134.2" clip-path="url(#terminal-1605829847-line-4)">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;1</text><text class="terminal-1605829847-r1" x="219.6" y="117.6" textLength="951.6" clip-path="url(#terminal-1605829847-line-4)">timecube&#160;homepage&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1605829847-r1" x="1207.8" y="117.6" textLength="488" clip-path="url(#terminal-1605829847-line-4)">tutorial&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1605829847-r1" x="1732.4" y="117.6" textLength="439.2" clip-path="url(#terminal-1605829847-line-4)">2.69&#160;mb&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1605829847-r1" x="2208.2" y="117.6" textLength="280.6" clip-path="url(#terminal-1605829847-line-4)">webp&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-1605829847-r1" x="2525.4" y="117.6" textLength="12.2" clip-path="url(#terminal-1605829847-line-4)"></text><text class="terminal-1605829847-r1" x="2537.6" y="117.6" textLength="12.2" clip-path="url(#terminal-1605829847-line-4)">
</text><text class="terminal-1605829847-r1" x="0" y="142" textLength="12.2" clip-path="url(#terminal-1605829847-line-5)"></text><text class="terminal-1605829847-r1" x="2525.4" y="142" textLength="12.2" clip-path="url(#terminal-1605829847-line-5)"></text><text class="terminal-1605829847-r1" x="2537.6" y="142" textLength="12.2" clip-path="url(#terminal-1605829847-line-5)">
</text><text class="terminal-1605829847-r1" x="0" y="166.4" textLength="2537.6" clip-path="url(#terminal-1605829847-line-6)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="terminal-1605829847-r1" x="2537.6" y="166.4" textLength="12.2" clip-path="url(#terminal-1605829847-line-6)">
</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

251
docs/img/soulseek.svg Normal file
View File

@@ -0,0 +1,251 @@
<svg class="rich-terminal" viewBox="0 0 2556 1245.6" xmlns="http://www.w3.org/2000/svg">
<!-- Generated with Rich https://www.textualize.io -->
<style>
@font-face {
font-family: "Fira Code";
src: local("FiraCode-Regular"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Regular.woff2") format("woff2"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Regular.woff") format("woff");
font-style: normal;
font-weight: 400;
}
@font-face {
font-family: "Fira Code";
src: local("FiraCode-Bold"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Bold.woff2") format("woff2"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Bold.woff") format("woff");
font-style: bold;
font-weight: 700;
}
.terminal-2892301316-matrix {
font-family: Fira Code, monospace;
font-size: 20px;
line-height: 24.4px;
font-variant-east-asian: full-width;
}
.terminal-2892301316-title {
font-size: 18px;
font-weight: bold;
font-family: arial;
}
.terminal-2892301316-r1 { fill: #c5c8c6 }
.terminal-2892301316-r2 { fill: #c5c8c6;font-weight: bold }
</style>
<defs>
<clipPath id="terminal-2892301316-clip-terminal">
<rect x="0" y="0" width="2536.6" height="1194.6" />
</clipPath>
<clipPath id="terminal-2892301316-line-0">
<rect x="0" y="1.5" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-1">
<rect x="0" y="25.9" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-2">
<rect x="0" y="50.3" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-3">
<rect x="0" y="74.7" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-4">
<rect x="0" y="99.1" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-5">
<rect x="0" y="123.5" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-6">
<rect x="0" y="147.9" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-7">
<rect x="0" y="172.3" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-8">
<rect x="0" y="196.7" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-9">
<rect x="0" y="221.1" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-10">
<rect x="0" y="245.5" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-11">
<rect x="0" y="269.9" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-12">
<rect x="0" y="294.3" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-13">
<rect x="0" y="318.7" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-14">
<rect x="0" y="343.1" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-15">
<rect x="0" y="367.5" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-16">
<rect x="0" y="391.9" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-17">
<rect x="0" y="416.3" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-18">
<rect x="0" y="440.7" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-19">
<rect x="0" y="465.1" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-20">
<rect x="0" y="489.5" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-21">
<rect x="0" y="513.9" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-22">
<rect x="0" y="538.3" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-23">
<rect x="0" y="562.7" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-24">
<rect x="0" y="587.1" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-25">
<rect x="0" y="611.5" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-26">
<rect x="0" y="635.9" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-27">
<rect x="0" y="660.3" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-28">
<rect x="0" y="684.7" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-29">
<rect x="0" y="709.1" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-30">
<rect x="0" y="733.5" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-31">
<rect x="0" y="757.9" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-32">
<rect x="0" y="782.3" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-33">
<rect x="0" y="806.7" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-34">
<rect x="0" y="831.1" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-35">
<rect x="0" y="855.5" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-36">
<rect x="0" y="879.9" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-37">
<rect x="0" y="904.3" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-38">
<rect x="0" y="928.7" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-39">
<rect x="0" y="953.1" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-40">
<rect x="0" y="977.5" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-41">
<rect x="0" y="1001.9" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-42">
<rect x="0" y="1026.3" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-43">
<rect x="0" y="1050.7" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-44">
<rect x="0" y="1075.1" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-45">
<rect x="0" y="1099.5" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-46">
<rect x="0" y="1123.9" width="2537.6" height="24.65"/>
</clipPath>
<clipPath id="terminal-2892301316-line-47">
<rect x="0" y="1148.3" width="2537.6" height="24.65"/>
</clipPath>
</defs>
<rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="2554" height="1243.6" rx="8"/><text class="terminal-2892301316-title" fill="#c5c8c6" text-anchor="middle" x="1277" y="27">Rich</text>
<g transform="translate(26,22)">
<circle cx="0" cy="0" r="7" fill="#ff5f57"/>
<circle cx="22" cy="0" r="7" fill="#febc2e"/>
<circle cx="44" cy="0" r="7" fill="#28c840"/>
</g>
<g transform="translate(9, 41)" clip-path="url(#terminal-2892301316-clip-terminal)">
<g class="terminal-2892301316-matrix">
<text class="terminal-2892301316-r1" x="0" y="20" textLength="24.4" clip-path="url(#terminal-2892301316-line-0)">╭─</text><text class="terminal-2892301316-r1" x="24.4" y="20" textLength="2488.8" clip-path="url(#terminal-2892301316-line-0)">────────────────────────────────────────────────────────────────────────────────────────&#160;Soulseek:&#160;erika&#160;herms&#160;niel&#160;────────────────────────────────────────────────────────────────────────────────────────</text><text class="terminal-2892301316-r1" x="2513.2" y="20" textLength="24.4" clip-path="url(#terminal-2892301316-line-0)">─╮</text><text class="terminal-2892301316-r1" x="2537.6" y="20" textLength="12.2" clip-path="url(#terminal-2892301316-line-0)">
</text><text class="terminal-2892301316-r1" x="0" y="44.4" textLength="12.2" clip-path="url(#terminal-2892301316-line-1)"></text><text class="terminal-2892301316-r1" x="2525.4" y="44.4" textLength="12.2" clip-path="url(#terminal-2892301316-line-1)"></text><text class="terminal-2892301316-r1" x="2537.6" y="44.4" textLength="12.2" clip-path="url(#terminal-2892301316-line-1)">
</text><text class="terminal-2892301316-r1" x="0" y="68.8" textLength="12.2" clip-path="url(#terminal-2892301316-line-2)"></text><text class="terminal-2892301316-r2" x="48.8" y="68.8" textLength="61" clip-path="url(#terminal-2892301316-line-2)">&#160;&#160;&#160;&#160;#</text><text class="terminal-2892301316-r2" x="146.4" y="68.8" textLength="122" clip-path="url(#terminal-2892301316-line-2)">TRACK&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r2" x="305" y="68.8" textLength="805.2" clip-path="url(#terminal-2892301316-line-2)">TITLE&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r2" x="1146.8" y="68.8" textLength="524.6" clip-path="url(#terminal-2892301316-line-2)">ARTIST&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r2" x="1708" y="68.8" textLength="634.4" clip-path="url(#terminal-2892301316-line-2)">ALBUM&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r2" x="2379" y="68.8" textLength="109.8" clip-path="url(#terminal-2892301316-line-2)">SIZE&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="68.8" textLength="12.2" clip-path="url(#terminal-2892301316-line-2)"></text><text class="terminal-2892301316-r1" x="2537.6" y="68.8" textLength="12.2" clip-path="url(#terminal-2892301316-line-2)">
</text><text class="terminal-2892301316-r1" x="0" y="93.2" textLength="12.2" clip-path="url(#terminal-2892301316-line-3)"></text><text class="terminal-2892301316-r1" x="24.4" y="93.2" textLength="2488.8" clip-path="url(#terminal-2892301316-line-3)">&#160;──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="93.2" textLength="12.2" clip-path="url(#terminal-2892301316-line-3)"></text><text class="terminal-2892301316-r1" x="2537.6" y="93.2" textLength="12.2" clip-path="url(#terminal-2892301316-line-3)">
</text><text class="terminal-2892301316-r1" x="0" y="117.6" textLength="12.2" clip-path="url(#terminal-2892301316-line-4)"></text><text class="terminal-2892301316-r1" x="48.8" y="117.6" textLength="61" clip-path="url(#terminal-2892301316-line-4)">&#160;&#160;&#160;&#160;1</text><text class="terminal-2892301316-r1" x="146.4" y="117.6" textLength="122" clip-path="url(#terminal-2892301316-line-4)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="117.6" textLength="805.2" clip-path="url(#terminal-2892301316-line-4)">&#160;01&#160;stay&#160;awhile&#160;thy&#160;flying&#160;(unmada&#160;in&#160;u)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="117.6" textLength="524.6" clip-path="url(#terminal-2892301316-line-4)">freak&#160;folk&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="117.6" textLength="634.4" clip-path="url(#terminal-2892301316-line-4)">matt&#160;valentine&#160;&amp;&#160;erika&#160;elder&#160;fan&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="117.6" textLength="109.8" clip-path="url(#terminal-2892301316-line-4)">4&#160;mb&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="117.6" textLength="12.2" clip-path="url(#terminal-2892301316-line-4)"></text><text class="terminal-2892301316-r1" x="2537.6" y="117.6" textLength="12.2" clip-path="url(#terminal-2892301316-line-4)">
</text><text class="terminal-2892301316-r1" x="0" y="142" textLength="12.2" clip-path="url(#terminal-2892301316-line-5)"></text><text class="terminal-2892301316-r1" x="48.8" y="142" textLength="61" clip-path="url(#terminal-2892301316-line-5)">&#160;&#160;&#160;&#160;2</text><text class="terminal-2892301316-r1" x="146.4" y="142" textLength="122" clip-path="url(#terminal-2892301316-line-5)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="142" textLength="805.2" clip-path="url(#terminal-2892301316-line-5)">&#160;02&#160;the&#160;devil&#x27;s&#160;dream.aif&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="142" textLength="524.6" clip-path="url(#terminal-2892301316-line-5)">freak&#160;folk&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="142" textLength="634.4" clip-path="url(#terminal-2892301316-line-5)">matt&#160;valentine&#160;&amp;&#160;erika&#160;elder&#160;fan&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="142" textLength="109.8" clip-path="url(#terminal-2892301316-line-5)">9&#160;mb&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="142" textLength="12.2" clip-path="url(#terminal-2892301316-line-5)"></text><text class="terminal-2892301316-r1" x="2537.6" y="142" textLength="12.2" clip-path="url(#terminal-2892301316-line-5)">
</text><text class="terminal-2892301316-r1" x="0" y="166.4" textLength="12.2" clip-path="url(#terminal-2892301316-line-6)"></text><text class="terminal-2892301316-r1" x="48.8" y="166.4" textLength="61" clip-path="url(#terminal-2892301316-line-6)">&#160;&#160;&#160;&#160;3</text><text class="terminal-2892301316-r1" x="146.4" y="166.4" textLength="122" clip-path="url(#terminal-2892301316-line-6)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="166.4" textLength="805.2" clip-path="url(#terminal-2892301316-line-6)">03-offcut_stamp_blues-hit&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="166.4" textLength="524.6" clip-path="url(#terminal-2892301316-line-6)">freak&#160;folk&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="166.4" textLength="634.4" clip-path="url(#terminal-2892301316-line-6)">matt&#160;valentine&#160;&amp;&#160;erika&#160;elder&#160;fan&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="166.4" textLength="109.8" clip-path="url(#terminal-2892301316-line-6)">4&#160;mb&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="166.4" textLength="12.2" clip-path="url(#terminal-2892301316-line-6)"></text><text class="terminal-2892301316-r1" x="2537.6" y="166.4" textLength="12.2" clip-path="url(#terminal-2892301316-line-6)">
</text><text class="terminal-2892301316-r1" x="0" y="190.8" textLength="12.2" clip-path="url(#terminal-2892301316-line-7)"></text><text class="terminal-2892301316-r1" x="48.8" y="190.8" textLength="61" clip-path="url(#terminal-2892301316-line-7)">&#160;&#160;&#160;&#160;4</text><text class="terminal-2892301316-r1" x="146.4" y="190.8" textLength="122" clip-path="url(#terminal-2892301316-line-7)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="190.8" textLength="805.2" clip-path="url(#terminal-2892301316-line-7)">04-astral_reeperbahn-hit&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="190.8" textLength="524.6" clip-path="url(#terminal-2892301316-line-7)">freak&#160;folk&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="190.8" textLength="634.4" clip-path="url(#terminal-2892301316-line-7)">matt&#160;valentine&#160;&amp;&#160;erika&#160;elder&#160;fan&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="190.8" textLength="109.8" clip-path="url(#terminal-2892301316-line-7)">3&#160;mb&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="190.8" textLength="12.2" clip-path="url(#terminal-2892301316-line-7)"></text><text class="terminal-2892301316-r1" x="2537.6" y="190.8" textLength="12.2" clip-path="url(#terminal-2892301316-line-7)">
</text><text class="terminal-2892301316-r1" x="0" y="215.2" textLength="12.2" clip-path="url(#terminal-2892301316-line-8)"></text><text class="terminal-2892301316-r1" x="48.8" y="215.2" textLength="61" clip-path="url(#terminal-2892301316-line-8)">&#160;&#160;&#160;&#160;5</text><text class="terminal-2892301316-r1" x="146.4" y="215.2" textLength="122" clip-path="url(#terminal-2892301316-line-8)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="215.2" textLength="805.2" clip-path="url(#terminal-2892301316-line-8)">05-refried_cocola_again-hit&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="215.2" textLength="524.6" clip-path="url(#terminal-2892301316-line-8)">freak&#160;folk&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="215.2" textLength="634.4" clip-path="url(#terminal-2892301316-line-8)">matt&#160;valentine&#160;&amp;&#160;erika&#160;elder&#160;fan&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="215.2" textLength="109.8" clip-path="url(#terminal-2892301316-line-8)">12&#160;mb&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="215.2" textLength="12.2" clip-path="url(#terminal-2892301316-line-8)"></text><text class="terminal-2892301316-r1" x="2537.6" y="215.2" textLength="12.2" clip-path="url(#terminal-2892301316-line-8)">
</text><text class="terminal-2892301316-r1" x="0" y="239.6" textLength="12.2" clip-path="url(#terminal-2892301316-line-9)"></text><text class="terminal-2892301316-r1" x="48.8" y="239.6" textLength="61" clip-path="url(#terminal-2892301316-line-9)">&#160;&#160;&#160;&#160;6</text><text class="terminal-2892301316-r1" x="146.4" y="239.6" textLength="122" clip-path="url(#terminal-2892301316-line-9)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="239.6" textLength="805.2" clip-path="url(#terminal-2892301316-line-9)">06-cocola_and_kif-hit&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="239.6" textLength="524.6" clip-path="url(#terminal-2892301316-line-9)">freak&#160;folk&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="239.6" textLength="634.4" clip-path="url(#terminal-2892301316-line-9)">matt&#160;valentine&#160;&amp;&#160;erika&#160;elder&#160;fan&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="239.6" textLength="109.8" clip-path="url(#terminal-2892301316-line-9)">1&#160;mb&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="239.6" textLength="12.2" clip-path="url(#terminal-2892301316-line-9)"></text><text class="terminal-2892301316-r1" x="2537.6" y="239.6" textLength="12.2" clip-path="url(#terminal-2892301316-line-9)">
</text><text class="terminal-2892301316-r1" x="0" y="264" textLength="12.2" clip-path="url(#terminal-2892301316-line-10)"></text><text class="terminal-2892301316-r1" x="48.8" y="264" textLength="61" clip-path="url(#terminal-2892301316-line-10)">&#160;&#160;&#160;&#160;7</text><text class="terminal-2892301316-r1" x="146.4" y="264" textLength="122" clip-path="url(#terminal-2892301316-line-10)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="264" textLength="805.2" clip-path="url(#terminal-2892301316-line-10)">07-128&#160;one&#160;hot&#160;pleasure(dave&#160;aude&#160;club&#160;d&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="264" textLength="524.6" clip-path="url(#terminal-2892301316-line-10)">10housemix&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="264" textLength="634.4" clip-path="url(#terminal-2892301316-line-10)">04&#160;housemix&#160;2011-04&#160;peak&#160;hour&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="264" textLength="109.8" clip-path="url(#terminal-2892301316-line-10)">18&#160;mb&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="264" textLength="12.2" clip-path="url(#terminal-2892301316-line-10)"></text><text class="terminal-2892301316-r1" x="2537.6" y="264" textLength="12.2" clip-path="url(#terminal-2892301316-line-10)">
</text><text class="terminal-2892301316-r1" x="0" y="288.4" textLength="12.2" clip-path="url(#terminal-2892301316-line-11)"></text><text class="terminal-2892301316-r1" x="48.8" y="288.4" textLength="61" clip-path="url(#terminal-2892301316-line-11)">&#160;&#160;&#160;&#160;8</text><text class="terminal-2892301316-r1" x="146.4" y="288.4" textLength="122" clip-path="url(#terminal-2892301316-line-11)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="288.4" textLength="805.2" clip-path="url(#terminal-2892301316-line-11)">07-129&#160;one&#160;hot&#160;pleasure(dave&#160;aude&#160;remix)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="288.4" textLength="524.6" clip-path="url(#terminal-2892301316-line-11)">10housemix&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="288.4" textLength="634.4" clip-path="url(#terminal-2892301316-line-11)">06&#160;housemix&#160;2011-06&#160;peak&#160;hour&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="288.4" textLength="109.8" clip-path="url(#terminal-2892301316-line-11)">19&#160;mb&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="288.4" textLength="12.2" clip-path="url(#terminal-2892301316-line-11)"></text><text class="terminal-2892301316-r1" x="2537.6" y="288.4" textLength="12.2" clip-path="url(#terminal-2892301316-line-11)">
</text><text class="terminal-2892301316-r1" x="0" y="312.8" textLength="12.2" clip-path="url(#terminal-2892301316-line-12)"></text><text class="terminal-2892301316-r1" x="48.8" y="312.8" textLength="61" clip-path="url(#terminal-2892301316-line-12)">&#160;&#160;&#160;&#160;9</text><text class="terminal-2892301316-r1" x="146.4" y="312.8" textLength="122" clip-path="url(#terminal-2892301316-line-12)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="312.8" textLength="805.2" clip-path="url(#terminal-2892301316-line-12)">08-burying_ground_zero_blues-hit&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="312.8" textLength="524.6" clip-path="url(#terminal-2892301316-line-12)">freak&#160;folk&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="312.8" textLength="634.4" clip-path="url(#terminal-2892301316-line-12)">matt&#160;valentine&#160;&amp;&#160;erika&#160;elder&#160;fan&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="312.8" textLength="109.8" clip-path="url(#terminal-2892301316-line-12)">4&#160;mb&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="312.8" textLength="12.2" clip-path="url(#terminal-2892301316-line-12)"></text><text class="terminal-2892301316-r1" x="2537.6" y="312.8" textLength="12.2" clip-path="url(#terminal-2892301316-line-12)">
</text><text class="terminal-2892301316-r1" x="0" y="337.2" textLength="12.2" clip-path="url(#terminal-2892301316-line-13)"></text><text class="terminal-2892301316-r1" x="48.8" y="337.2" textLength="61" clip-path="url(#terminal-2892301316-line-13)">&#160;&#160;&#160;10</text><text class="terminal-2892301316-r1" x="146.4" y="337.2" textLength="122" clip-path="url(#terminal-2892301316-line-13)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="337.2" textLength="805.2" clip-path="url(#terminal-2892301316-line-13)">09-where_is_the_transcendental_thana-hit&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="337.2" textLength="524.6" clip-path="url(#terminal-2892301316-line-13)">freak&#160;folk&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="337.2" textLength="634.4" clip-path="url(#terminal-2892301316-line-13)">matt&#160;valentine&#160;&amp;&#160;erika&#160;elder&#160;fan&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="337.2" textLength="109.8" clip-path="url(#terminal-2892301316-line-13)">16&#160;mb&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="337.2" textLength="12.2" clip-path="url(#terminal-2892301316-line-13)"></text><text class="terminal-2892301316-r1" x="2537.6" y="337.2" textLength="12.2" clip-path="url(#terminal-2892301316-line-13)">
</text><text class="terminal-2892301316-r1" x="0" y="361.6" textLength="12.2" clip-path="url(#terminal-2892301316-line-14)"></text><text class="terminal-2892301316-r1" x="48.8" y="361.6" textLength="61" clip-path="url(#terminal-2892301316-line-14)">&#160;&#160;&#160;11</text><text class="terminal-2892301316-r1" x="146.4" y="361.6" textLength="122" clip-path="url(#terminal-2892301316-line-14)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="361.6" textLength="805.2" clip-path="url(#terminal-2892301316-line-14)">2.22.&#160;feel&#160;me&#160;(feat.&#160;erika&#160;scherlin)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="361.6" textLength="524.6" clip-path="url(#terminal-2892301316-line-14)">down&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="361.6" textLength="634.4" clip-path="url(#terminal-2892301316-line-14)">papik&#160;-&#160;sounds&#160;for&#160;the&#160;open&#160;road&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="361.6" textLength="109.8" clip-path="url(#terminal-2892301316-line-14)">10&#160;mb&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="361.6" textLength="12.2" clip-path="url(#terminal-2892301316-line-14)"></text><text class="terminal-2892301316-r1" x="2537.6" y="361.6" textLength="12.2" clip-path="url(#terminal-2892301316-line-14)">
</text><text class="terminal-2892301316-r1" x="0" y="386" textLength="12.2" clip-path="url(#terminal-2892301316-line-15)"></text><text class="terminal-2892301316-r1" x="48.8" y="386" textLength="61" clip-path="url(#terminal-2892301316-line-15)">&#160;&#160;&#160;12</text><text class="terminal-2892301316-r1" x="146.4" y="386" textLength="122" clip-path="url(#terminal-2892301316-line-15)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="386" textLength="805.2" clip-path="url(#terminal-2892301316-line-15)">d11&#160;erika&#160;(herms&#160;niel)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="386" textLength="524.6" clip-path="url(#terminal-2892301316-line-15)">wunschkonzert&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="386" textLength="634.4" clip-path="url(#terminal-2892301316-line-15)">cd4&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="386" textLength="109.8" clip-path="url(#terminal-2892301316-line-15)">4&#160;mb&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="386" textLength="12.2" clip-path="url(#terminal-2892301316-line-15)"></text><text class="terminal-2892301316-r1" x="2537.6" y="386" textLength="12.2" clip-path="url(#terminal-2892301316-line-15)">
</text><text class="terminal-2892301316-r1" x="0" y="410.4" textLength="12.2" clip-path="url(#terminal-2892301316-line-16)"></text><text class="terminal-2892301316-r1" x="48.8" y="410.4" textLength="61" clip-path="url(#terminal-2892301316-line-16)">&#160;&#160;&#160;13</text><text class="terminal-2892301316-r1" x="146.4" y="410.4" textLength="122" clip-path="url(#terminal-2892301316-line-16)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="410.4" textLength="805.2" clip-path="url(#terminal-2892301316-line-16)">erika&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="410.4" textLength="524.6" clip-path="url(#terminal-2892301316-line-16)">herms&#160;niel&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="410.4" textLength="634.4" clip-path="url(#terminal-2892301316-line-16)">classical&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="410.4" textLength="109.8" clip-path="url(#terminal-2892301316-line-16)">17&#160;mb&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="410.4" textLength="12.2" clip-path="url(#terminal-2892301316-line-16)"></text><text class="terminal-2892301316-r1" x="2537.6" y="410.4" textLength="12.2" clip-path="url(#terminal-2892301316-line-16)">
</text><text class="terminal-2892301316-r1" x="0" y="434.8" textLength="12.2" clip-path="url(#terminal-2892301316-line-17)"></text><text class="terminal-2892301316-r1" x="48.8" y="434.8" textLength="61" clip-path="url(#terminal-2892301316-line-17)">&#160;&#160;&#160;14</text><text class="terminal-2892301316-r1" x="146.4" y="434.8" textLength="122" clip-path="url(#terminal-2892301316-line-17)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="434.8" textLength="805.2" clip-path="url(#terminal-2892301316-line-17)">erika&#160;vip3&#160;mehdizz&#160;special&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="434.8" textLength="524.6" clip-path="url(#terminal-2892301316-line-17)">!!!&#160;plts&#160;!!!&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="434.8" textLength="634.4" clip-path="url(#terminal-2892301316-line-17)">!&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;fresh&#160;dubs&#160;(oc&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="434.8" textLength="109.8" clip-path="url(#terminal-2892301316-line-17)">3&#160;mb&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="434.8" textLength="12.2" clip-path="url(#terminal-2892301316-line-17)"></text><text class="terminal-2892301316-r1" x="2537.6" y="434.8" textLength="12.2" clip-path="url(#terminal-2892301316-line-17)">
</text><text class="terminal-2892301316-r1" x="0" y="459.2" textLength="12.2" clip-path="url(#terminal-2892301316-line-18)"></text><text class="terminal-2892301316-r1" x="48.8" y="459.2" textLength="61" clip-path="url(#terminal-2892301316-line-18)">&#160;&#160;&#160;15</text><text class="terminal-2892301316-r1" x="146.4" y="459.2" textLength="122" clip-path="url(#terminal-2892301316-line-18)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="459.2" textLength="805.2" clip-path="url(#terminal-2892301316-line-18)">herms&#160;niel&#160;-&#160;erika&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="459.2" textLength="524.6" clip-path="url(#terminal-2892301316-line-18)">@@nlnfo&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="459.2" textLength="634.4" clip-path="url(#terminal-2892301316-line-18)">lossless&#160;audio&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="459.2" textLength="109.8" clip-path="url(#terminal-2892301316-line-18)">17&#160;mb&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="459.2" textLength="12.2" clip-path="url(#terminal-2892301316-line-18)"></text><text class="terminal-2892301316-r1" x="2537.6" y="459.2" textLength="12.2" clip-path="url(#terminal-2892301316-line-18)">
</text><text class="terminal-2892301316-r1" x="0" y="483.6" textLength="12.2" clip-path="url(#terminal-2892301316-line-19)"></text><text class="terminal-2892301316-r1" x="48.8" y="483.6" textLength="61" clip-path="url(#terminal-2892301316-line-19)">&#160;&#160;&#160;16</text><text class="terminal-2892301316-r1" x="146.4" y="483.6" textLength="122" clip-path="url(#terminal-2892301316-line-19)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="483.6" textLength="805.2" clip-path="url(#terminal-2892301316-line-19)">herms&#160;niel&#160;-&#160;erika&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="483.6" textLength="524.6" clip-path="url(#terminal-2892301316-line-19)">musique&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="483.6" textLength="634.4" clip-path="url(#terminal-2892301316-line-19)">herms&#160;niel&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="483.6" textLength="109.8" clip-path="url(#terminal-2892301316-line-19)">17&#160;mb&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="483.6" textLength="12.2" clip-path="url(#terminal-2892301316-line-19)"></text><text class="terminal-2892301316-r1" x="2537.6" y="483.6" textLength="12.2" clip-path="url(#terminal-2892301316-line-19)">
</text><text class="terminal-2892301316-r1" x="0" y="508" textLength="12.2" clip-path="url(#terminal-2892301316-line-20)"></text><text class="terminal-2892301316-r1" x="48.8" y="508" textLength="61" clip-path="url(#terminal-2892301316-line-20)">&#160;&#160;&#160;17</text><text class="terminal-2892301316-r1" x="146.4" y="508" textLength="122" clip-path="url(#terminal-2892301316-line-20)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="508" textLength="805.2" clip-path="url(#terminal-2892301316-line-20)">herms&#160;niel&#160;-&#160;erika&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="508" textLength="524.6" clip-path="url(#terminal-2892301316-line-20)">@@nlnfo&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="508" textLength="634.4" clip-path="url(#terminal-2892301316-line-20)">lossless&#160;audio&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="508" textLength="109.8" clip-path="url(#terminal-2892301316-line-20)">30&#160;mb&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="508" textLength="12.2" clip-path="url(#terminal-2892301316-line-20)"></text><text class="terminal-2892301316-r1" x="2537.6" y="508" textLength="12.2" clip-path="url(#terminal-2892301316-line-20)">
</text><text class="terminal-2892301316-r1" x="0" y="532.4" textLength="12.2" clip-path="url(#terminal-2892301316-line-21)"></text><text class="terminal-2892301316-r1" x="48.8" y="532.4" textLength="61" clip-path="url(#terminal-2892301316-line-21)">&#160;&#160;&#160;18</text><text class="terminal-2892301316-r1" x="146.4" y="532.4" textLength="122" clip-path="url(#terminal-2892301316-line-21)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="532.4" textLength="805.2" clip-path="url(#terminal-2892301316-line-21)">herms&#160;niel&#160;-&#160;erika&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="532.4" textLength="524.6" clip-path="url(#terminal-2892301316-line-21)">music&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="532.4" textLength="634.4" clip-path="url(#terminal-2892301316-line-21)">unordered&#160;2&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="532.4" textLength="109.8" clip-path="url(#terminal-2892301316-line-21)">2&#160;mb&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="532.4" textLength="12.2" clip-path="url(#terminal-2892301316-line-21)"></text><text class="terminal-2892301316-r1" x="2537.6" y="532.4" textLength="12.2" clip-path="url(#terminal-2892301316-line-21)">
</text><text class="terminal-2892301316-r1" x="0" y="556.8" textLength="12.2" clip-path="url(#terminal-2892301316-line-22)"></text><text class="terminal-2892301316-r1" x="48.8" y="556.8" textLength="61" clip-path="url(#terminal-2892301316-line-22)">&#160;&#160;&#160;19</text><text class="terminal-2892301316-r1" x="146.4" y="556.8" textLength="122" clip-path="url(#terminal-2892301316-line-22)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="556.8" textLength="805.2" clip-path="url(#terminal-2892301316-line-22)">john&#160;dahlback,&#160;erika,&#160;larsson&#160;-&#160;stay&#160;(or&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="556.8" textLength="524.6" clip-path="url(#terminal-2892301316-line-22)">aaaa&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="556.8" textLength="634.4" clip-path="url(#terminal-2892301316-line-22)">123&#160;april&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="556.8" textLength="109.8" clip-path="url(#terminal-2892301316-line-22)">8&#160;mb&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="556.8" textLength="12.2" clip-path="url(#terminal-2892301316-line-22)"></text><text class="terminal-2892301316-r1" x="2537.6" y="556.8" textLength="12.2" clip-path="url(#terminal-2892301316-line-22)">
</text><text class="terminal-2892301316-r1" x="0" y="581.2" textLength="12.2" clip-path="url(#terminal-2892301316-line-23)"></text><text class="terminal-2892301316-r1" x="48.8" y="581.2" textLength="61" clip-path="url(#terminal-2892301316-line-23)">&#160;&#160;&#160;20</text><text class="terminal-2892301316-r1" x="146.4" y="581.2" textLength="122" clip-path="url(#terminal-2892301316-line-23)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="581.2" textLength="805.2" clip-path="url(#terminal-2892301316-line-23)">matt&#160;valentine&#160;&amp;&#160;erika&#160;elder&#160;-&#160;03&#160;-&#160;offc&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="581.2" textLength="524.6" clip-path="url(#terminal-2892301316-line-23)">soulseek&#160;files&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="581.2" textLength="634.4" clip-path="url(#terminal-2892301316-line-23)">freak&#160;folk&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="581.2" textLength="109.8" clip-path="url(#terminal-2892301316-line-23)">3&#160;mb&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="581.2" textLength="12.2" clip-path="url(#terminal-2892301316-line-23)"></text><text class="terminal-2892301316-r1" x="2537.6" y="581.2" textLength="12.2" clip-path="url(#terminal-2892301316-line-23)">
</text><text class="terminal-2892301316-r1" x="0" y="605.6" textLength="12.2" clip-path="url(#terminal-2892301316-line-24)"></text><text class="terminal-2892301316-r1" x="48.8" y="605.6" textLength="61" clip-path="url(#terminal-2892301316-line-24)">&#160;&#160;&#160;21</text><text class="terminal-2892301316-r1" x="146.4" y="605.6" textLength="122" clip-path="url(#terminal-2892301316-line-24)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="605.6" textLength="805.2" clip-path="url(#terminal-2892301316-line-24)">matt&#160;valentine&#160;&amp;&#160;erika&#160;elder&#160;-&#160;06&#160;-&#160;coco&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="605.6" textLength="524.6" clip-path="url(#terminal-2892301316-line-24)">soulseek&#160;files&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="605.6" textLength="634.4" clip-path="url(#terminal-2892301316-line-24)">freak&#160;folk&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="605.6" textLength="109.8" clip-path="url(#terminal-2892301316-line-24)">1&#160;mb&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="605.6" textLength="12.2" clip-path="url(#terminal-2892301316-line-24)"></text><text class="terminal-2892301316-r1" x="2537.6" y="605.6" textLength="12.2" clip-path="url(#terminal-2892301316-line-24)">
</text><text class="terminal-2892301316-r1" x="0" y="630" textLength="12.2" clip-path="url(#terminal-2892301316-line-25)"></text><text class="terminal-2892301316-r1" x="48.8" y="630" textLength="61" clip-path="url(#terminal-2892301316-line-25)">&#160;&#160;&#160;22</text><text class="terminal-2892301316-r1" x="146.4" y="630" textLength="122" clip-path="url(#terminal-2892301316-line-25)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="630" textLength="805.2" clip-path="url(#terminal-2892301316-line-25)">matt&#160;valentine&#160;&amp;&#160;erika&#160;elder&#160;-&#160;07&#160;-&#160;the&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="630" textLength="524.6" clip-path="url(#terminal-2892301316-line-25)">soulseek&#160;files&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="630" textLength="634.4" clip-path="url(#terminal-2892301316-line-25)">freak&#160;folk&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="630" textLength="109.8" clip-path="url(#terminal-2892301316-line-25)">6&#160;mb&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="630" textLength="12.2" clip-path="url(#terminal-2892301316-line-25)"></text><text class="terminal-2892301316-r1" x="2537.6" y="630" textLength="12.2" clip-path="url(#terminal-2892301316-line-25)">
</text><text class="terminal-2892301316-r1" x="0" y="654.4" textLength="12.2" clip-path="url(#terminal-2892301316-line-26)"></text><text class="terminal-2892301316-r1" x="48.8" y="654.4" textLength="61" clip-path="url(#terminal-2892301316-line-26)">&#160;&#160;&#160;23</text><text class="terminal-2892301316-r1" x="146.4" y="654.4" textLength="122" clip-path="url(#terminal-2892301316-line-26)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="654.4" textLength="805.2" clip-path="url(#terminal-2892301316-line-26)">matt&#160;valentine&#160;&amp;&#160;erika&#160;elder&#160;-&#160;08&#160;-&#160;bury&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="654.4" textLength="524.6" clip-path="url(#terminal-2892301316-line-26)">soulseek&#160;files&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="654.4" textLength="634.4" clip-path="url(#terminal-2892301316-line-26)">freak&#160;folk&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="654.4" textLength="109.8" clip-path="url(#terminal-2892301316-line-26)">3&#160;mb&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="654.4" textLength="12.2" clip-path="url(#terminal-2892301316-line-26)"></text><text class="terminal-2892301316-r1" x="2537.6" y="654.4" textLength="12.2" clip-path="url(#terminal-2892301316-line-26)">
</text><text class="terminal-2892301316-r1" x="0" y="678.8" textLength="12.2" clip-path="url(#terminal-2892301316-line-27)"></text><text class="terminal-2892301316-r1" x="48.8" y="678.8" textLength="61" clip-path="url(#terminal-2892301316-line-27)">&#160;&#160;&#160;24</text><text class="terminal-2892301316-r1" x="146.4" y="678.8" textLength="122" clip-path="url(#terminal-2892301316-line-27)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="678.8" textLength="805.2" clip-path="url(#terminal-2892301316-line-27)">matt&#160;valentine&#160;&amp;&#160;erika&#160;elder&#160;-&#160;09&#160;-&#160;wher&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="678.8" textLength="524.6" clip-path="url(#terminal-2892301316-line-27)">soulseek&#160;files&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="678.8" textLength="634.4" clip-path="url(#terminal-2892301316-line-27)">freak&#160;folk&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="678.8" textLength="109.8" clip-path="url(#terminal-2892301316-line-27)">11&#160;mb&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="678.8" textLength="12.2" clip-path="url(#terminal-2892301316-line-27)"></text><text class="terminal-2892301316-r1" x="2537.6" y="678.8" textLength="12.2" clip-path="url(#terminal-2892301316-line-27)">
</text><text class="terminal-2892301316-r1" x="0" y="703.2" textLength="12.2" clip-path="url(#terminal-2892301316-line-28)"></text><text class="terminal-2892301316-r1" x="48.8" y="703.2" textLength="61" clip-path="url(#terminal-2892301316-line-28)">&#160;&#160;&#160;25</text><text class="terminal-2892301316-r1" x="146.4" y="703.2" textLength="122" clip-path="url(#terminal-2892301316-line-28)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="703.2" textLength="805.2" clip-path="url(#terminal-2892301316-line-28)">matt&#160;valentine&#160;&amp;&#160;erika&#160;elder&#160;-&#160;lunar&#160;blu&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="703.2" textLength="524.6" clip-path="url(#terminal-2892301316-line-28)">freak&#160;folk&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="703.2" textLength="634.4" clip-path="url(#terminal-2892301316-line-28)">matt&#160;valentine&#160;and&#160;erika&#160;elder-&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="703.2" textLength="109.8" clip-path="url(#terminal-2892301316-line-28)">7&#160;mb&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="703.2" textLength="12.2" clip-path="url(#terminal-2892301316-line-28)"></text><text class="terminal-2892301316-r1" x="2537.6" y="703.2" textLength="12.2" clip-path="url(#terminal-2892301316-line-28)">
</text><text class="terminal-2892301316-r1" x="0" y="727.6" textLength="12.2" clip-path="url(#terminal-2892301316-line-29)"></text><text class="terminal-2892301316-r1" x="48.8" y="727.6" textLength="61" clip-path="url(#terminal-2892301316-line-29)">&#160;&#160;&#160;26</text><text class="terminal-2892301316-r1" x="146.4" y="727.6" textLength="122" clip-path="url(#terminal-2892301316-line-29)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="727.6" textLength="805.2" clip-path="url(#terminal-2892301316-line-29)">matt&#160;valentine&#160;&amp;&#160;erika&#160;elder&#160;-&#160;lunar&#160;blu&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="727.6" textLength="524.6" clip-path="url(#terminal-2892301316-line-29)">freak&#160;folk&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="727.6" textLength="634.4" clip-path="url(#terminal-2892301316-line-29)">matt&#160;valentine&#160;and&#160;erika&#160;elder-&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="727.6" textLength="109.8" clip-path="url(#terminal-2892301316-line-29)">7&#160;mb&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="727.6" textLength="12.2" clip-path="url(#terminal-2892301316-line-29)"></text><text class="terminal-2892301316-r1" x="2537.6" y="727.6" textLength="12.2" clip-path="url(#terminal-2892301316-line-29)">
</text><text class="terminal-2892301316-r1" x="0" y="752" textLength="12.2" clip-path="url(#terminal-2892301316-line-30)"></text><text class="terminal-2892301316-r1" x="48.8" y="752" textLength="61" clip-path="url(#terminal-2892301316-line-30)">&#160;&#160;&#160;27</text><text class="terminal-2892301316-r1" x="146.4" y="752" textLength="122" clip-path="url(#terminal-2892301316-line-30)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="752" textLength="805.2" clip-path="url(#terminal-2892301316-line-30)">matt&#160;valentine&#160;&amp;&#160;erika&#160;elder&#160;-&#160;lunar&#160;blu&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="752" textLength="524.6" clip-path="url(#terminal-2892301316-line-30)">freak&#160;folk&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="752" textLength="634.4" clip-path="url(#terminal-2892301316-line-30)">matt&#160;valentine&#160;and&#160;erika&#160;elder-&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="752" textLength="109.8" clip-path="url(#terminal-2892301316-line-30)">3&#160;mb&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="752" textLength="12.2" clip-path="url(#terminal-2892301316-line-30)"></text><text class="terminal-2892301316-r1" x="2537.6" y="752" textLength="12.2" clip-path="url(#terminal-2892301316-line-30)">
</text><text class="terminal-2892301316-r1" x="0" y="776.4" textLength="12.2" clip-path="url(#terminal-2892301316-line-31)"></text><text class="terminal-2892301316-r1" x="48.8" y="776.4" textLength="61" clip-path="url(#terminal-2892301316-line-31)">&#160;&#160;&#160;28</text><text class="terminal-2892301316-r1" x="146.4" y="776.4" textLength="122" clip-path="url(#terminal-2892301316-line-31)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="776.4" textLength="805.2" clip-path="url(#terminal-2892301316-line-31)">matt&#160;valentine&#160;&amp;&#160;erika&#160;elder&#160;-&#160;ragantula&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="776.4" textLength="524.6" clip-path="url(#terminal-2892301316-line-31)">freak&#160;folk&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="776.4" textLength="634.4" clip-path="url(#terminal-2892301316-line-31)">mv&#160;&amp;&#160;ee-2002&#160;-&#160;ragantula&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="776.4" textLength="109.8" clip-path="url(#terminal-2892301316-line-31)">19&#160;mb&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="776.4" textLength="12.2" clip-path="url(#terminal-2892301316-line-31)"></text><text class="terminal-2892301316-r1" x="2537.6" y="776.4" textLength="12.2" clip-path="url(#terminal-2892301316-line-31)">
</text><text class="terminal-2892301316-r1" x="0" y="800.8" textLength="12.2" clip-path="url(#terminal-2892301316-line-32)"></text><text class="terminal-2892301316-r1" x="48.8" y="800.8" textLength="61" clip-path="url(#terminal-2892301316-line-32)">&#160;&#160;&#160;29</text><text class="terminal-2892301316-r1" x="146.4" y="800.8" textLength="122" clip-path="url(#terminal-2892301316-line-32)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="800.8" textLength="805.2" clip-path="url(#terminal-2892301316-line-32)">matt&#160;valentine&#160;&amp;&#160;erika&#160;elder&#160;-&#160;ragantula&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="800.8" textLength="524.6" clip-path="url(#terminal-2892301316-line-32)">freak&#160;folk&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="800.8" textLength="634.4" clip-path="url(#terminal-2892301316-line-32)">mv&#160;&amp;&#160;ee-2002&#160;-&#160;ragantula&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="800.8" textLength="109.8" clip-path="url(#terminal-2892301316-line-32)">9&#160;mb&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="800.8" textLength="12.2" clip-path="url(#terminal-2892301316-line-32)"></text><text class="terminal-2892301316-r1" x="2537.6" y="800.8" textLength="12.2" clip-path="url(#terminal-2892301316-line-32)">
</text><text class="terminal-2892301316-r1" x="0" y="825.2" textLength="12.2" clip-path="url(#terminal-2892301316-line-33)"></text><text class="terminal-2892301316-r1" x="48.8" y="825.2" textLength="61" clip-path="url(#terminal-2892301316-line-33)">&#160;&#160;&#160;30</text><text class="terminal-2892301316-r1" x="146.4" y="825.2" textLength="122" clip-path="url(#terminal-2892301316-line-33)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="825.2" textLength="805.2" clip-path="url(#terminal-2892301316-line-33)">matt&#160;valentine&#160;&amp;&#160;erika&#160;elder&#160;-&#160;ragantula&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="825.2" textLength="524.6" clip-path="url(#terminal-2892301316-line-33)">freak&#160;folk&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="825.2" textLength="634.4" clip-path="url(#terminal-2892301316-line-33)">mv&#160;&amp;&#160;ee-2002&#160;-&#160;ragantula&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="825.2" textLength="109.8" clip-path="url(#terminal-2892301316-line-33)">8&#160;mb&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="825.2" textLength="12.2" clip-path="url(#terminal-2892301316-line-33)"></text><text class="terminal-2892301316-r1" x="2537.6" y="825.2" textLength="12.2" clip-path="url(#terminal-2892301316-line-33)">
</text><text class="terminal-2892301316-r1" x="0" y="849.6" textLength="12.2" clip-path="url(#terminal-2892301316-line-34)"></text><text class="terminal-2892301316-r1" x="48.8" y="849.6" textLength="61" clip-path="url(#terminal-2892301316-line-34)">&#160;&#160;&#160;31</text><text class="terminal-2892301316-r1" x="146.4" y="849.6" textLength="122" clip-path="url(#terminal-2892301316-line-34)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="849.6" textLength="805.2" clip-path="url(#terminal-2892301316-line-34)">matt&#160;valentine&#160;&amp;&#160;erika&#160;elder&#160;-&#160;ragantula&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="849.6" textLength="524.6" clip-path="url(#terminal-2892301316-line-34)">freak&#160;folk&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="849.6" textLength="634.4" clip-path="url(#terminal-2892301316-line-34)">mv&#160;&amp;&#160;ee-2002&#160;-&#160;ragantula&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="849.6" textLength="109.8" clip-path="url(#terminal-2892301316-line-34)">8&#160;mb&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="849.6" textLength="12.2" clip-path="url(#terminal-2892301316-line-34)"></text><text class="terminal-2892301316-r1" x="2537.6" y="849.6" textLength="12.2" clip-path="url(#terminal-2892301316-line-34)">
</text><text class="terminal-2892301316-r1" x="0" y="874" textLength="12.2" clip-path="url(#terminal-2892301316-line-35)"></text><text class="terminal-2892301316-r1" x="48.8" y="874" textLength="61" clip-path="url(#terminal-2892301316-line-35)">&#160;&#160;&#160;32</text><text class="terminal-2892301316-r1" x="146.4" y="874" textLength="122" clip-path="url(#terminal-2892301316-line-35)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="874" textLength="805.2" clip-path="url(#terminal-2892301316-line-35)">matt&#160;valentine&#160;&amp;&#160;erika&#160;elder&#160;-&#160;ragantula&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="874" textLength="524.6" clip-path="url(#terminal-2892301316-line-35)">freak&#160;folk&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="874" textLength="634.4" clip-path="url(#terminal-2892301316-line-35)">mv&#160;&amp;&#160;ee-2002&#160;-&#160;ragantula&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="874" textLength="109.8" clip-path="url(#terminal-2892301316-line-35)">4&#160;mb&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="874" textLength="12.2" clip-path="url(#terminal-2892301316-line-35)"></text><text class="terminal-2892301316-r1" x="2537.6" y="874" textLength="12.2" clip-path="url(#terminal-2892301316-line-35)">
</text><text class="terminal-2892301316-r1" x="0" y="898.4" textLength="12.2" clip-path="url(#terminal-2892301316-line-36)"></text><text class="terminal-2892301316-r1" x="48.8" y="898.4" textLength="61" clip-path="url(#terminal-2892301316-line-36)">&#160;&#160;&#160;33</text><text class="terminal-2892301316-r1" x="146.4" y="898.4" textLength="122" clip-path="url(#terminal-2892301316-line-36)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="898.4" textLength="805.2" clip-path="url(#terminal-2892301316-line-36)">matt&#160;valentine&#160;&amp;&#160;erika&#160;elder&#160;-&#160;ragantula&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="898.4" textLength="524.6" clip-path="url(#terminal-2892301316-line-36)">freak&#160;folk&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="898.4" textLength="634.4" clip-path="url(#terminal-2892301316-line-36)">mv&#160;&amp;&#160;ee-2002&#160;-&#160;ragantula&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="898.4" textLength="109.8" clip-path="url(#terminal-2892301316-line-36)">4&#160;mb&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="898.4" textLength="12.2" clip-path="url(#terminal-2892301316-line-36)"></text><text class="terminal-2892301316-r1" x="2537.6" y="898.4" textLength="12.2" clip-path="url(#terminal-2892301316-line-36)">
</text><text class="terminal-2892301316-r1" x="0" y="922.8" textLength="12.2" clip-path="url(#terminal-2892301316-line-37)"></text><text class="terminal-2892301316-r1" x="48.8" y="922.8" textLength="61" clip-path="url(#terminal-2892301316-line-37)">&#160;&#160;&#160;34</text><text class="terminal-2892301316-r1" x="146.4" y="922.8" textLength="122" clip-path="url(#terminal-2892301316-line-37)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="922.8" textLength="805.2" clip-path="url(#terminal-2892301316-line-37)">matt&#160;valentine&#160;&amp;&#160;erika&#160;elder&#160;-&#160;ragantula&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="922.8" textLength="524.6" clip-path="url(#terminal-2892301316-line-37)">freak&#160;folk&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="922.8" textLength="634.4" clip-path="url(#terminal-2892301316-line-37)">mv&#160;&amp;&#160;ee-2002&#160;-&#160;ragantula&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="922.8" textLength="109.8" clip-path="url(#terminal-2892301316-line-37)">3&#160;mb&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="922.8" textLength="12.2" clip-path="url(#terminal-2892301316-line-37)"></text><text class="terminal-2892301316-r1" x="2537.6" y="922.8" textLength="12.2" clip-path="url(#terminal-2892301316-line-37)">
</text><text class="terminal-2892301316-r1" x="0" y="947.2" textLength="12.2" clip-path="url(#terminal-2892301316-line-38)"></text><text class="terminal-2892301316-r1" x="48.8" y="947.2" textLength="61" clip-path="url(#terminal-2892301316-line-38)">&#160;&#160;&#160;35</text><text class="terminal-2892301316-r1" x="146.4" y="947.2" textLength="122" clip-path="url(#terminal-2892301316-line-38)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="947.2" textLength="805.2" clip-path="url(#terminal-2892301316-line-38)">matt&#160;valentine&#160;&amp;&#160;erika&#160;elder&#160;-&#160;ragantula&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="947.2" textLength="524.6" clip-path="url(#terminal-2892301316-line-38)">freak&#160;folk&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="947.2" textLength="634.4" clip-path="url(#terminal-2892301316-line-38)">mv&#160;&amp;&#160;ee-2002&#160;-&#160;ragantula&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="947.2" textLength="109.8" clip-path="url(#terminal-2892301316-line-38)">2&#160;mb&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="947.2" textLength="12.2" clip-path="url(#terminal-2892301316-line-38)"></text><text class="terminal-2892301316-r1" x="2537.6" y="947.2" textLength="12.2" clip-path="url(#terminal-2892301316-line-38)">
</text><text class="terminal-2892301316-r1" x="0" y="971.6" textLength="12.2" clip-path="url(#terminal-2892301316-line-39)"></text><text class="terminal-2892301316-r1" x="48.8" y="971.6" textLength="61" clip-path="url(#terminal-2892301316-line-39)">&#160;&#160;&#160;36</text><text class="terminal-2892301316-r1" x="146.4" y="971.6" textLength="122" clip-path="url(#terminal-2892301316-line-39)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="971.6" textLength="805.2" clip-path="url(#terminal-2892301316-line-39)">matt&#160;valentine&#160;-&#160;lunar&#160;blues&#160;02&#160;-&#160;freigh&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="971.6" textLength="524.6" clip-path="url(#terminal-2892301316-line-39)">freak&#160;folk&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="971.6" textLength="634.4" clip-path="url(#terminal-2892301316-line-39)">matt&#160;valentine&#160;and&#160;erika&#160;elder-&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="971.6" textLength="109.8" clip-path="url(#terminal-2892301316-line-39)">7&#160;mb&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="971.6" textLength="12.2" clip-path="url(#terminal-2892301316-line-39)"></text><text class="terminal-2892301316-r1" x="2537.6" y="971.6" textLength="12.2" clip-path="url(#terminal-2892301316-line-39)">
</text><text class="terminal-2892301316-r1" x="0" y="996" textLength="12.2" clip-path="url(#terminal-2892301316-line-40)"></text><text class="terminal-2892301316-r1" x="48.8" y="996" textLength="61" clip-path="url(#terminal-2892301316-line-40)">&#160;&#160;&#160;37</text><text class="terminal-2892301316-r1" x="146.4" y="996" textLength="122" clip-path="url(#terminal-2892301316-line-40)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="996" textLength="805.2" clip-path="url(#terminal-2892301316-line-40)">matt&#160;valentine&#160;-&#160;lunar&#160;blues&#160;03&#160;-&#160;candym&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="996" textLength="524.6" clip-path="url(#terminal-2892301316-line-40)">freak&#160;folk&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="996" textLength="634.4" clip-path="url(#terminal-2892301316-line-40)">matt&#160;valentine&#160;and&#160;erika&#160;elder-&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="996" textLength="109.8" clip-path="url(#terminal-2892301316-line-40)">8&#160;mb&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="996" textLength="12.2" clip-path="url(#terminal-2892301316-line-40)"></text><text class="terminal-2892301316-r1" x="2537.6" y="996" textLength="12.2" clip-path="url(#terminal-2892301316-line-40)">
</text><text class="terminal-2892301316-r1" x="0" y="1020.4" textLength="12.2" clip-path="url(#terminal-2892301316-line-41)"></text><text class="terminal-2892301316-r1" x="48.8" y="1020.4" textLength="61" clip-path="url(#terminal-2892301316-line-41)">&#160;&#160;&#160;38</text><text class="terminal-2892301316-r1" x="146.4" y="1020.4" textLength="122" clip-path="url(#terminal-2892301316-line-41)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="1020.4" textLength="805.2" clip-path="url(#terminal-2892301316-line-41)">matt&#160;valentine&#160;-&#160;lunar&#160;blues&#160;04&#160;-&#160;mine&#160;a&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="1020.4" textLength="524.6" clip-path="url(#terminal-2892301316-line-41)">freak&#160;folk&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="1020.4" textLength="634.4" clip-path="url(#terminal-2892301316-line-41)">matt&#160;valentine&#160;and&#160;erika&#160;elder-&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="1020.4" textLength="109.8" clip-path="url(#terminal-2892301316-line-41)">5&#160;mb&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="1020.4" textLength="12.2" clip-path="url(#terminal-2892301316-line-41)"></text><text class="terminal-2892301316-r1" x="2537.6" y="1020.4" textLength="12.2" clip-path="url(#terminal-2892301316-line-41)">
</text><text class="terminal-2892301316-r1" x="0" y="1044.8" textLength="12.2" clip-path="url(#terminal-2892301316-line-42)"></text><text class="terminal-2892301316-r1" x="48.8" y="1044.8" textLength="61" clip-path="url(#terminal-2892301316-line-42)">&#160;&#160;&#160;39</text><text class="terminal-2892301316-r1" x="146.4" y="1044.8" textLength="122" clip-path="url(#terminal-2892301316-line-42)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="1044.8" textLength="805.2" clip-path="url(#terminal-2892301316-line-42)">matt&#160;valentine&#160;-&#160;lunar&#160;blues&#160;05&#160;-&#160;sic&#160;&#x27;e&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="1044.8" textLength="524.6" clip-path="url(#terminal-2892301316-line-42)">freak&#160;folk&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="1044.8" textLength="634.4" clip-path="url(#terminal-2892301316-line-42)">matt&#160;valentine&#160;and&#160;erika&#160;elder-&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="1044.8" textLength="109.8" clip-path="url(#terminal-2892301316-line-42)">4&#160;mb&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="1044.8" textLength="12.2" clip-path="url(#terminal-2892301316-line-42)"></text><text class="terminal-2892301316-r1" x="2537.6" y="1044.8" textLength="12.2" clip-path="url(#terminal-2892301316-line-42)">
</text><text class="terminal-2892301316-r1" x="0" y="1069.2" textLength="12.2" clip-path="url(#terminal-2892301316-line-43)"></text><text class="terminal-2892301316-r1" x="48.8" y="1069.2" textLength="61" clip-path="url(#terminal-2892301316-line-43)">&#160;&#160;&#160;40</text><text class="terminal-2892301316-r1" x="146.4" y="1069.2" textLength="122" clip-path="url(#terminal-2892301316-line-43)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="1069.2" textLength="805.2" clip-path="url(#terminal-2892301316-line-43)">matt&#160;valentine&#160;-&#160;lunar&#160;blues&#160;06&#160;-&#160;one&#160;st&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="1069.2" textLength="524.6" clip-path="url(#terminal-2892301316-line-43)">freak&#160;folk&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="1069.2" textLength="634.4" clip-path="url(#terminal-2892301316-line-43)">matt&#160;valentine&#160;and&#160;erika&#160;elder-&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="1069.2" textLength="109.8" clip-path="url(#terminal-2892301316-line-43)">5&#160;mb&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="1069.2" textLength="12.2" clip-path="url(#terminal-2892301316-line-43)"></text><text class="terminal-2892301316-r1" x="2537.6" y="1069.2" textLength="12.2" clip-path="url(#terminal-2892301316-line-43)">
</text><text class="terminal-2892301316-r1" x="0" y="1093.6" textLength="12.2" clip-path="url(#terminal-2892301316-line-44)"></text><text class="terminal-2892301316-r1" x="48.8" y="1093.6" textLength="61" clip-path="url(#terminal-2892301316-line-44)">&#160;&#160;&#160;41</text><text class="terminal-2892301316-r1" x="146.4" y="1093.6" textLength="122" clip-path="url(#terminal-2892301316-line-44)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="1093.6" textLength="805.2" clip-path="url(#terminal-2892301316-line-44)">matt&#160;valentine&#160;-&#160;lunar&#160;blues&#160;07&#160;-&#160;death&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="1093.6" textLength="524.6" clip-path="url(#terminal-2892301316-line-44)">freak&#160;folk&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="1093.6" textLength="634.4" clip-path="url(#terminal-2892301316-line-44)">matt&#160;valentine&#160;and&#160;erika&#160;elder-&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="1093.6" textLength="109.8" clip-path="url(#terminal-2892301316-line-44)">11&#160;mb&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="1093.6" textLength="12.2" clip-path="url(#terminal-2892301316-line-44)"></text><text class="terminal-2892301316-r1" x="2537.6" y="1093.6" textLength="12.2" clip-path="url(#terminal-2892301316-line-44)">
</text><text class="terminal-2892301316-r1" x="0" y="1118" textLength="12.2" clip-path="url(#terminal-2892301316-line-45)"></text><text class="terminal-2892301316-r1" x="48.8" y="1118" textLength="61" clip-path="url(#terminal-2892301316-line-45)">&#160;&#160;&#160;42</text><text class="terminal-2892301316-r1" x="146.4" y="1118" textLength="122" clip-path="url(#terminal-2892301316-line-45)">125&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="1118" textLength="805.2" clip-path="url(#terminal-2892301316-line-45)">speechless(ext)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="1118" textLength="524.6" clip-path="url(#terminal-2892301316-line-45)">08&#160;must&#160;play&#160;old&#160;but&#160;still&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="1118" textLength="634.4" clip-path="url(#terminal-2892301316-line-45)">must&#160;play&#160;old&#160;but&#160;still&#160;pt&#160;1&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="1118" textLength="109.8" clip-path="url(#terminal-2892301316-line-45)">10&#160;mb&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="1118" textLength="12.2" clip-path="url(#terminal-2892301316-line-45)"></text><text class="terminal-2892301316-r1" x="2537.6" y="1118" textLength="12.2" clip-path="url(#terminal-2892301316-line-45)">
</text><text class="terminal-2892301316-r1" x="0" y="1142.4" textLength="12.2" clip-path="url(#terminal-2892301316-line-46)"></text><text class="terminal-2892301316-r1" x="48.8" y="1142.4" textLength="61" clip-path="url(#terminal-2892301316-line-46)">&#160;&#160;&#160;43</text><text class="terminal-2892301316-r1" x="146.4" y="1142.4" textLength="122" clip-path="url(#terminal-2892301316-line-46)">?&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="305" y="1142.4" textLength="805.2" clip-path="url(#terminal-2892301316-line-46)">xpos3d&#160;-&#160;erika&#160;full&#160;v1&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1146.8" y="1142.4" textLength="524.6" clip-path="url(#terminal-2892301316-line-46)">!&#160;belgian&#160;jump&#160;up&#160;dubs&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="1708" y="1142.4" textLength="634.4" clip-path="url(#terminal-2892301316-line-46)">xpos3d&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2379" y="1142.4" textLength="109.8" clip-path="url(#terminal-2892301316-line-46)">19&#160;mb&#160;&#160;&#160;&#160;</text><text class="terminal-2892301316-r1" x="2525.4" y="1142.4" textLength="12.2" clip-path="url(#terminal-2892301316-line-46)"></text><text class="terminal-2892301316-r1" x="2537.6" y="1142.4" textLength="12.2" clip-path="url(#terminal-2892301316-line-46)">
</text><text class="terminal-2892301316-r1" x="0" y="1166.8" textLength="12.2" clip-path="url(#terminal-2892301316-line-47)"></text><text class="terminal-2892301316-r1" x="2525.4" y="1166.8" textLength="12.2" clip-path="url(#terminal-2892301316-line-47)"></text><text class="terminal-2892301316-r1" x="2537.6" y="1166.8" textLength="12.2" clip-path="url(#terminal-2892301316-line-47)">
</text><text class="terminal-2892301316-r1" x="0" y="1191.2" textLength="2537.6" clip-path="url(#terminal-2892301316-line-48)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="terminal-2892301316-r1" x="2537.6" y="1191.2" textLength="12.2" clip-path="url(#terminal-2892301316-line-48)">
</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 96 KiB

View File

@@ -79,6 +79,136 @@ or if you have mpv installed (the preferred way for video files)
# Bandcamp downloading (provider method)
<figure>
<figcaption><🜂🜄|🜁🜃></figcaption>
<pre><code class="language-powershell">search-provider -provider bandcamp "artist:altrusian grace media"
<pre><code class="language-powershell">search-provider -provider bandcamp -query "artist:altrusian grace media"
</code></pre>
</figure>
![search-provider -provider bandcamp](img/bandcamp-artist.svg)
this brings up special scraper for bandcamp on the artist page, the query syntax of "artist:" is how we parse args for some cmdlets. next run the following
<figure>
<figcaption><🜂🜄|🜁🜃></figcaption>
<pre><code class="language-powershell">@1
</code></pre>
</figure>
![bandcamp-artist](img/bandcamp-album.svg)
this shows a list of bandcamp album links, go ahead and enter this below
<figure>
<figcaption><🜂🜄|🜁🜃></figcaption>
<pre><code class="language-powershell">@8
</code></pre>
</figure>
![download-media-bandcamp](img/download-media-bandcamp.svg)
this shows a list of bandcamp album link, if you look at the title of the table, download-media -url "https://altrusiangrace.bandcamp.com/album/zetetic-astronomy-earth-not-a-globe-full-audiobook" , you could just copy the url from webpage and paste it as this command to get the table without going through the provider search. In this table, all these are playlist items, each item is its own file but in this case its connected and they are in an album. if you wanted to only download a couple you could do @1,5,7 and that would only download those items, you can also do a range @1-6 and that will download 1 through 6. For this tutorial, run this below.
<figure>
<figcaption><🜂🜄|🜁🜃></figcaption>
<pre><code class="language-powershell">@* | merge-file | add-file -store tutorial
</code></pre>
</figure>
this will download the entire playlist, merge them into one file while putting chapter markers for the file merge points.
# screenshot
medios can take screenshots of pages and output them as pdf, jpg, png, and webp. the default is webp as its the smallest format. the screenshot is fullscreen and scrolls. run this below
<figure>
<figcaption><🜂🜄|🜁🜃></figcaption>
<pre><code class="language-powershell">screen-shot "https://www.timecube.net/" | add-tag "title:timecube homepage" | add-file -store tutorial
</code></pre>
</figure>
![screen-shot](img/screen-shot.svg)
<figure>
<figcaption><🜂🜄|🜁🜃></figcaption>
<pre><code class="language-powershell">@1 | get-file
</code></pre>
</figure>
this opens up a webrowser with your media file embedded, you can copy and paste or if you want to share on a public hoster, you can do this
<figure>
<figcaption><🜂🜄|🜁🜃></figcaption>
<pre><code class="language-powershell">@1 | add-file -provider 0x0
</code></pre>
</figure>
this will upload your media file to 0x0.com and at the end provide you a link, you dont need to worry about saving it, you can always retrieve the link where you downloaded the file by running
<figure>
<figcaption><🜂🜄|🜁🜃></figcaption>
<pre><code class="language-powershell">@1 | get-url
</code></pre>
</figure>
![get-url](img/get-url.svg)
# soul seek
## soul-seek requires a psuedo account
to make an account in soulseek, simple enter in random username and password and put in your config.conf. you do not need to create an account on the website just put in random name that isint taken with random password, dont user special symbols or spaces.
<figure>
<figcaption>config.conf</figcaption>
<pre><code class="language-powershell">[provider=soulseek]
username="putinrandomusername"
password="putinrandompassword"
</code></pre>
</figure>
restart the cli and check the startup table, if soulseek says ENABLED then you are good to go, run this.
<figure>
<figcaption><🜂🜄|🜁🜃></figcaption>
<pre><code class="language-powershell">search-provider -provider soulseek "erika herms niel"
</code></pre>
</figure>
![soulseek](img/soulseek.svg)
next run
<figure>
<figcaption><🜂🜄|🜁🜃></figcaption>
<pre><code class="language-powershell">@13 | add-file -store tutorial
</code></pre>
</figure>
this will download and inject into your tutorial store, keep in mind that soulseek is p2p, so download speeds will vary and it may take a minute to connect.
# Open Library
## OPENLIBRARY/ARCHIVE.ORG ACCOUNT REQUIRED
[Open Library](https://archive.org/account/signup)
throw away account is fine to create.
<figure>
<figcaption>config.conf</figcaption>
<pre><code class="language-powershell">[provider=OpenLibrary]
email=""
password=""
</code></pre>
</figure>
openlibrary allows us to borrow books, merge them into a permement pdf, then return the book. run this below
<figure>
<figcaption><🜂🜄|🜁🜃></figcaption>
<pre><code class="language-powershell">download-file "https://archive.org/details/powerofsatiremag0000elli_h4h9" | add-file -store tutorial
</code></pre>
</figure>
we could have use the search-provider -provider openlibrary, but to show the versatile of the app, we able to use download-file and medios will be able to intelligently direct it the correct provider (with exception of download-media, download-media is just the frontend for yt-dlp).
# Libgen
libgen is self-explanatory,
<figure>
<figcaption><🜂🜄|🜁🜃></figcaption>
<pre><code class="language-powershell">download-file "https://libgen.gl/ads.php?md5=5c258cc177c1d735c7acfb60fbdb14bf&downloadname=10.1515/9781400870080-009" | add-file -store tutorial
</code></pre>
</figure>

View File

@@ -395,32 +395,10 @@ def normalize_urls(value: Any) -> List[str]:
if not u:
return None
lower = u.lower()
if not (lower.startswith("http://") or lower.startswith("https://")):
return u
try:
parsed = urlsplit(u)
except Exception:
return u
scheme = (parsed.scheme or "").lower()
netloc = (parsed.netloc or "").lower()
path = unquote(parsed.path or "")
query = parsed.query or ""
# Normalize default ports.
if scheme == "http" and netloc.endswith(":80"):
netloc = netloc[:-3]
elif scheme == "https" and netloc.endswith(":443"):
netloc = netloc[:-4]
# Prefer no trailing slash except root.
if path and path != "/":
path = path.rstrip("/")
# Fragments are not part of the resource.
return urlunsplit((scheme, netloc, path, query, ""))
# IMPORTANT: URLs can be case-sensitive in the path/query on some hosts
# (e.g., https://0x0.st/PzGY.webp). Do not lowercase or otherwise rewrite
# the URL here; preserve exact casing and percent-encoding.
return u
seen: Set[str] = set()
out: List[str] = []

View File

@@ -860,6 +860,20 @@ def get_last_result_items() -> List[Any]:
return []
def get_last_selectable_result_items() -> List[Any]:
"""Get items from the last *selectable* result table, ignoring display-only items.
This is useful when a selection stage should target the last visible selectable table
(e.g., a playlist/search table), even if a prior action command emitted items and
populated _DISPLAY_ITEMS.
"""
if _LAST_RESULT_TABLE is None:
return list(_LAST_RESULT_ITEMS)
if _is_selectable_table(_LAST_RESULT_TABLE):
return list(_LAST_RESULT_ITEMS)
return []
def get_last_result_table_source_command() -> Optional[str]:
"""Get the source command from the last displayed result table.

View File

@@ -9,66 +9,37 @@ Medios-Macina is a CLI media manager and toolkit focused on downloading, tagging
- **Module Mixing:** *[Playwright](https://github.com/microsoft/playwright), [yt-dlp](https://github.com/yt-dlp/yt-dlp), [aioslsk](https://github.com/JurgenR/aioslsk), [telethon](https://github.com/LonamiWebs/Telethon),[typer](https://github.com/fastapi/typer)*
- **MPV Manager:** Play audio, video, and even images in a custom designed MPV with trimming, screenshotting, and more built right in!
## Quick start
## installation
`docs/BOOTSTRAP.md` and use `scripts/bootstrap.ps1` (Windows) or `scripts/bootstrap.sh` (Linux/macOS) to create a venv and install the project. Alternatively, simply run the opinionated helper: `python ./scripts/setup.py`. By default (no flags), `setup.py` will auto-detect your platform and run the matching bootstrap script in **non-interactive (quiet)** mode so you don't need to run the platform-specific script yourself. The bootstrap scripts also attempt (best-effort) to install `mpv` if it's missing from PATH. Note: the Deno installer can require interactive input on some systems; if the automated Deno install fails, the script will warn and you can install Deno manually by following `docs/BOOTSTRAP.md`.
1. run python setup.py
1. Install Python requirements:
```powershell
python -m pip install -r requirements.txt
# Automated setup (recommended): run the single Python setup script which installs
# all Python dependencies (from requirements.txt) and downloads Playwright browsers.
# Usage:
# - Default: python ./scripts/setup.py # installs Chromium only (saves disk)
# - To install all Playwright engines: python ./scripts/setup.py --browsers all
# Advanced options:
# - Skip dependency installation: python ./scripts/setup.py --skip-deps
# - Install only Playwright browsers: python ./scripts/setup.py --playwright-only
# - Install only specific browsers (saves disk): python ./scripts/setup.py --browsers chromium
# - Example: install only Chromium browsers: python ./scripts/setup.py --playwright-only --browsers chromium
```
2. Copy or edit `config.conf` and set a required `temp` directory where intermediate files are written. Example:
2. rename config.conf.remove to config.conf the store=folder path should be empty folder with no other files in it.
```ini
temp="C:\\Users\\Admin\\Downloads"
[store=folder]
name="default"
path="C:\\Media Machina"
path="C:\Users\Public\Documents\library"
[store=hydrusnetwork]
NAME="home"
API="..."
URL="http://localhost:45869"
[provider=OpenLibrary]
email="user@example.com"
password="..."
```
3. Start the CLI:
```powershell
cd "C:\location\to\repository\medios-machina\"
python cli.py
```
3. Start the CLI by simply running "mm" in shell or run python cli.py
# [CLICK FOR GUIDED TUTORIAL](/docs/tutorial.md)
## Usage overview 🔧
- Pipelines: chain cmdlets with `|`, e.g., `download-media <url> | add-file -storage local`.
- From your shell you can pass a fully-quoted pipeline so the shell doesn't interpret `|` as a pipe: e.g.
`mm "download-media <url> | add-file -storage local"`
- Format selection (non-interactive): When `download-media` shows multiple formats, you can select one non-interactively by re-running the pipeline and specifying the format:
- Use a format id: `mm "download-media '<url>' -format 243 | add-file -store local"`
- Or use the listed index (1-based): `mm "download-media '<url>' -query 'format:7' | add-file -store local"`
- Use a format id: `mm "download-media '<url>' -query 'format:243' -path 'C://path' "
- Or use the listed index (1-based): `mm "download-media '<url>' -query 'format:7' "
Note: The `@N` selection syntax works in the interactive REPL, but shells like PowerShell treat `@` specially — prefer `-query 'format:N'` when running a quoted pipeline from your shell.
- Selections: search cmdlets populate a selectable ResultTable; refer to entries with `@<index>`.
- Tagging & metadata: `add-tag` mutates piped results (temporary path items) or writes to a configured store when `-store` is provided.
## Built-in image viewer 🎞️
- MPV automatically detects still-image files and flips into an image viewer mode while leaving the IPC helper aware via `user-data/mpv/image`.
## Built-in image viewer
- MPV automatically detects still-image files and flips into an image viewer
- Arrow keys, `WASD`, or `h/j/k/l` pan the image (recently tuned to ±0.05 steps), `Shift+arrow` offers finer nudges, `=`/`-` zoom quickly (~45% per press), `+`/`_` zoom slowly, and `0` resets zoom/pan back to default.
- Hit `f` while an image is active to take a screenshot (uses MPV's screenshot pipeline) and get an OSD confirmation.
- When MPV loads a video again, the script restores the regular video shortcuts automatically.
@@ -77,7 +48,7 @@ python cli.py
Simple download with metadata (tags and URL registration):
```bash
download-media "https://www.youtube.com/watch?v=dQw4w9WgXcQ" | add-file -storage local | add-url
download-media "https://www.youtube.com/watch?v=dQw4w9WgXcQ" | add-file -storage local
```
Download a playlist item:
@@ -87,19 +58,17 @@ download-media "https://www.youtube.com/playlist?list=PLxxxxx" -item 2 | add-fil
Take a website screenshot, tag it, and store locally:
```bash
screen-shot "https://example.com/page" | add-tag "title:Example Page,source:web" | add-file -store local
screen-shot "https://example.com/page" | add-tag "title:Example Page,source:web" -path "c://"
```
OpenLibrary ingestion (book metadata & PDF/ebook handling is automatically enriched when `add-file` detects an OpenLibrary URL):
```bash
add-file "https://openlibrary.org/books/OLxxxxxM/Book_Title" -storage local
download-file "https://openlibrary.org/books/OLxxxxxM/Book_Title" | add-file -storage local
```
Search & download flow (select with `@`):
Search your library:
```bash
search-file -provider youtube "my favourite track"
@1
download-media [URL] | add-file -store hydrus
search-store "ext:mp3"
```
## Providers & stores
@@ -110,19 +79,8 @@ download-media [URL] | add-file -store hydrus
- **Soulseek, LibGen, All-Debrid, Others**: provider support is modular—add or configure providers in `config.conf`.
## Troubleshooting & tips 🛠️
- If a cmdlet complains about an unknown store, ensure the piped item has a valid local `path` or use `-store <name>` to target a configured backend.
- For Playwright screenshots, run `python ./scripts/setup.py` (installs Chromium by default to save download space). To install all engines, run `python ./scripts/setup.py --browsers all`.
- Note: the `screen-shot` cmdlet forces the Playwright **Chromium** engine and will not use Firefox or WebKit.
- To run tests locally after removing `tests/conftest.py`, install the project in editable mode first so tests can import the package: `python -m pip install -e .` or run `python ./scripts/setup.py --install-editable`.
- Deno: The bootstrap scripts will install Deno automatically if it's not already installed (using the official installers). If the installer completes but `deno` is not available in your shell, restart your shell or add `$HOME/.deno/bin` (Windows: `%USERPROFILE%\\.deno\\bin`) to your PATH.
After installation, restart your shell (or add Deno's bin directory to your PATH) so `deno` is available on the command line.
- Use `--debug` to enable verbose logs when tracking down an error.
## Contributing & docs
- Developer docs are generated under `docs/` and tests live alongside the code; please run the test suite before submitting changes.
- Contributions welcome—open issues or pull requests with clear descriptions and small, focused diffs.
---
If you'd like, I can add a short _Quick Reference_ section listing the most-used cmdlets and flags, or add badges and a table of contents. What would you like me to add next? 🚀
- Contributions welcome—open issues or pull requests with clear descriptions and small, focused diffs.