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

185
CLI.py
View File

@@ -1710,6 +1710,51 @@ class PipelineExecutor:
return False 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: 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)): if not (pipeline_session and worker_manager and isinstance(config, dict)):
return return
@@ -1798,12 +1843,15 @@ class PipelineExecutor:
else: else:
selected_row_args: List[str] = [] selected_row_args: List[str] = []
skip_pipe_expansion = source_cmd == ".pipe" and len(stages) > 0 skip_pipe_expansion = source_cmd == ".pipe" and len(stages) > 0
if source_cmd and not skip_pipe_expansion: # Only perform @N command expansion for *single-item* selections.
for idx in selection_indices: # 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) row_args = ctx.get_current_stage_table_row_selection_args(idx)
if row_args: if row_args:
selected_row_args.extend(row_args) selected_row_args.extend(row_args)
break
if selected_row_args: if selected_row_args:
if isinstance(source_cmd, list): if isinstance(source_cmd, list):
@@ -1834,30 +1882,42 @@ class PipelineExecutor:
command_expanded = True command_expanded = True
if (not command_expanded) and selection_indices: 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 stage_table = None
try: try:
stage_table = ctx.get_current_stage_table() stage_table = ctx.get_current_stage_table()
except Exception: except Exception:
stage_table = None stage_table = None
if not stage_table and hasattr(ctx, "get_display_table"):
display_table = None
try: try:
stage_table = ctx.get_display_table() display_table = ctx.get_display_table() if hasattr(ctx, "get_display_table") else None
except Exception: except Exception:
stage_table = None display_table = None
if not stage_table and display_table is not None:
stage_table = display_table
if not stage_table: if not stage_table:
try: try:
stage_table = ctx.get_last_result_table() stage_table = ctx.get_last_result_table()
except Exception: except Exception:
stage_table = None stage_table = None
resolved_items = last_piped_items if last_piped_items else [] # Prefer selecting from the last selectable *table* (search/playlist)
if last_piped_items: # 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)] filtered = [resolved_items[i] for i in selection_indices if 0 <= i < len(resolved_items)]
if not filtered: if not filtered:
print("No items matched selection in pipeline\n") print("No items matched selection in pipeline\n")
@@ -2003,6 +2063,14 @@ class PipelineExecutor:
try: try:
self._try_clear_pipeline_stop(ctx) 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) stages = self._split_stages(tokens)
if not stages: if not stages:
print("Invalid pipeline syntax\n") print("Invalid pipeline syntax\n")
@@ -2066,11 +2134,39 @@ class PipelineExecutor:
stage_args = stage_tokens[1:] stage_args = stage_tokens[1:]
if cmd_name == "@": 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() subject = ctx.get_last_result_subject()
if subject is None: if subject is None:
print("No current result context available for '@'\n") print("No current result context available for '@'\n")
pipeline_status = "failed" pipeline_status = "failed"
pipeline_error = "No result subject for @" pipeline_error = "No result items/subject for @"
return return
piped_result = subject piped_result = subject
try: try:
@@ -2095,18 +2191,34 @@ class PipelineExecutor:
return return
selected_indices = [] 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: if is_select_all:
last_items = ctx.get_last_result_items() or [] selected_indices = list(range(len(items_list)))
selected_indices = list(range(len(last_items)))
else: else:
selected_indices = sorted([i - 1 for i in selection]) # type: ignore[arg-type] 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 [] resolved_items = items_list if items_list else []
filtered = [resolved_items[i] for i in selected_indices if 0 <= i < len(resolved_items)] filtered = [resolved_items[i] for i in selected_indices if 0 <= i < len(resolved_items)]
if not filtered: if not filtered:
@@ -2115,6 +2227,20 @@ class PipelineExecutor:
pipeline_error = "Empty selection" pipeline_error = "Empty selection"
return 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))): if PipelineExecutor._maybe_run_class_selector(ctx, config, filtered, stage_is_last=(stage_index + 1 >= len(stages))):
return return
@@ -2366,12 +2492,19 @@ class PipelineExecutor:
# the table and pause the pipeline so the user can pick @N. # 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 = 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 "" 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 ( if (
(not stage_is_last) (not stage_is_last)
and (not emits) and (not emits)
and cmd_name in {"download-media", "download_media"} and cmd_name in {"download-media", "download_media"}
and stage_table is not None 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: try:
is_selectable = not bool(getattr(stage_table, "no_choice", False)) is_selectable = not bool(getattr(stage_table, "no_choice", False))
@@ -2407,6 +2540,10 @@ class PipelineExecutor:
stdout_console().print() stdout_console().print()
stdout_console().print(stage_table) 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: try:
remaining = stages[stage_index + 1 :] remaining = stages[stage_index + 1 :]
source_cmd = ( source_cmd = (

View File

@@ -1,5 +1,6 @@
from __future__ import annotations from __future__ import annotations
import html as html_std
import logging import logging
import re import re
import requests import requests
@@ -22,6 +23,595 @@ except ImportError:
lxml_html = None 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): class Libgen(Provider):
# Domains that should be routed to this provider when the user supplies a URL. # Domains that should be routed to this provider when the user supplies a URL.
# (Used by ProviderCore.registry.match_provider_name_for_url) # (Used by ProviderCore.registry.match_provider_name_for_url)
@@ -146,6 +736,15 @@ class Libgen(Provider):
md5 = str(md.get("md5") or "").strip() md5 = str(md.get("md5") or "").strip()
extension = str(md.get("extension") or "").strip().lstrip(".") 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 (not target) or target.startswith("libgen:"):
if md5 and re.fullmatch(r"[a-fA-F0-9]{32}", md5): if md5 and re.fullmatch(r"[a-fA-F0-9]{32}", md5):
target = urljoin(MIRRORS[0], f"/ads.php?md5={md5}") target = urljoin(MIRRORS[0], f"/ads.php?md5={md5}")
@@ -153,7 +752,10 @@ class Libgen(Provider):
if not target: if not target:
return None 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 out_path = output_dir / base_name
if extension: if extension:
out_path = out_path.with_suffix(f".{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) ok, final_path = download_from_mirror(target, out_path, progress_callback=progress_callback)
progress_bar.finish() progress_bar.finish()
if ok and final_path: 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 Path(final_path)
return None return None
except Exception: except Exception:
@@ -751,6 +1469,34 @@ def _resolve_download_url(
if not html: if not html:
return None 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). # 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) m = re.search(r'href=["\']([^"\']*get\.php\?md5=[a-fA-F0-9]{32}[^"\']*)["\']', html, flags=re.IGNORECASE)
if m: if m:

View File

@@ -2,6 +2,8 @@ from __future__ import annotations
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from typing import Any, Dict, List, Optional, Type, cast from typing import Any, Dict, List, Optional, Type, cast
import html as html_std
import re
import requests import requests
import sys import sys
import json import json
@@ -279,6 +281,199 @@ class GoogleBooksMetadataProvider(MetadataProvider):
return tags 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): class MusicBrainzMetadataProvider(MetadataProvider):
"""Metadata provider for MusicBrainz recordings.""" """Metadata provider for MusicBrainz recordings."""
@@ -517,6 +712,7 @@ _METADATA_PROVIDERS: Dict[str, Type[MetadataProvider]] = {
"openlibrary": OpenLibraryMetadataProvider, "openlibrary": OpenLibraryMetadataProvider,
"googlebooks": GoogleBooksMetadataProvider, "googlebooks": GoogleBooksMetadataProvider,
"google": GoogleBooksMetadataProvider, "google": GoogleBooksMetadataProvider,
"isbnsearch": ISBNsearchMetadataProvider,
"musicbrainz": MusicBrainzMetadataProvider, "musicbrainz": MusicBrainzMetadataProvider,
"ytdlp": YtdlpMetadataProvider, "ytdlp": YtdlpMetadataProvider,
} }

View File

@@ -190,6 +190,7 @@ def _archive_id_from_url(url: str) -> str:
u = str(url or "").strip() u = str(url or "").strip()
if not u: if not u:
return "" return ""
try: try:
p = urlparse(u) p = urlparse(u)
host = (p.hostname or "").lower().strip() host = (p.hostname or "").lower().strip()
@@ -215,6 +216,175 @@ def _archive_id_from_url(url: str) -> str:
return "" 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): class OpenLibrary(Provider):
# Domains that should be routed to this provider when the user supplies a URL. # Domains that should be routed to this provider when the user supplies a URL.
# (Used by ProviderCore.registry.match_provider_name_for_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) log("[openlibrary] No archive identifier available; cannot download", file=sys.stderr)
return None 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) safe_title = sanitize_filename(result.title)
if not safe_title or "http" in safe_title.lower(): if not safe_title or "http" in safe_title.lower():
safe_title = sanitize_filename(archive_id) or "archive" safe_title = sanitize_filename(archive_id) or "archive"

View File

@@ -306,6 +306,7 @@ class Soulseek(Provider):
client = SoulSeekClient(settings) client = SoulSeekClient(settings)
with _suppress_aioslsk_noise(): with _suppress_aioslsk_noise():
async with _suppress_aioslsk_asyncio_task_noise():
try: try:
await client.start() await client.start()
await client.login() await client.login()
@@ -336,6 +337,10 @@ class Soulseek(Provider):
await client.stop() await client.stop()
except Exception: except Exception:
pass pass
try:
await asyncio.sleep(0)
except Exception:
pass
def _flatten_results(self, search_request: Any) -> List[dict]: def _flatten_results(self, search_request: Any) -> List[dict]:
flat: List[dict] = [] flat: List[dict] = []
@@ -558,8 +563,8 @@ async def download_soulseek_file(
async def _attempt_once(attempt_num: int) -> tuple[Optional[Path], Any, int, float]: async def _attempt_once(attempt_num: int) -> tuple[Optional[Path], Any, int, float]:
client = SoulSeekClient(settings) client = SoulSeekClient(settings)
with _suppress_aioslsk_noise(): with _suppress_aioslsk_noise():
try:
async with _suppress_aioslsk_asyncio_task_noise(): async with _suppress_aioslsk_asyncio_task_noise():
try:
await client.start() await client.start()
await client.login() await client.login()
debug(f"[soulseek] Logged in as {login_user}") debug(f"[soulseek] Logged in as {login_user}")
@@ -602,7 +607,11 @@ async def download_soulseek_file(
await asyncio.sleep(1) await asyncio.sleep(1)
final_state = getattr(getattr(transfer, "state", None), "VALUE", None) final_state = getattr(getattr(transfer, "state", None), "VALUE", None)
downloaded_path = Path(transfer.local_path) if getattr(transfer, "local_path", None) else output_path downloaded_path = (
Path(transfer.local_path)
if getattr(transfer, "local_path", None)
else output_path
)
final_elapsed = time.time() - start_time final_elapsed = time.time() - start_time
# Clear in-place progress bar. # Clear in-place progress bar.
@@ -639,12 +648,16 @@ async def download_soulseek_file(
except Exception: except Exception:
pass pass
return None, final_state, fail_bytes, final_elapsed return None, final_state, fail_bytes, final_elapsed
finally: finally:
try: try:
await client.stop() await client.stop()
except Exception: except Exception:
pass 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). # Retry a couple times only for fast 0-byte failures (common transient case).
max_attempts = 3 max_attempts = 3

View File

@@ -607,6 +607,34 @@ def _download_direct_file(
if not quiet: if not quiet:
log(f"Could not get filename from headers: {e}", file=sys.stderr) 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. # Apply suggested filename (from provider title) if given.
suggested = _sanitize_filename(suggested_filename) if suggested_filename else "" suggested = _sanitize_filename(suggested_filename) if suggested_filename else ""
if suggested: if suggested:

View File

@@ -319,6 +319,18 @@ class Download_File(Cmdlet):
except Exception: except Exception:
provider_name = None 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: if provider_name and get_provider is not None and SearchResult is not None:
# OpenLibrary URLs should be handled by the OpenLibrary provider. # OpenLibrary URLs should be handled by the OpenLibrary provider.
if provider_name == "openlibrary": if provider_name == "openlibrary":
@@ -391,11 +403,19 @@ class Download_File(Cmdlet):
progress.clear_status() progress.clear_status()
if downloaded_path: 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( self._emit_local_file(
downloaded_path=Path(downloaded_path), downloaded_path=Path(downloaded_path),
source=str(url), source=str(url),
title_hint=title_hint, title_hint=title_hint,
tags_hint=None, tags_hint=tags_hint,
media_kind_hint="book", media_kind_hint="book",
full_metadata=sr.full_metadata, full_metadata=sr.full_metadata,
provider_hint="openlibrary", provider_hint="openlibrary",
@@ -472,14 +492,42 @@ class Download_File(Cmdlet):
except Exception: except Exception:
downloaded_path = None 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: 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( self._emit_local_file(
downloaded_path=Path(downloaded_path), downloaded_path=Path(downloaded_path),
source=str(url), source=str(url),
title_hint=Path(str(downloaded_path)).stem, title_hint=title_hint,
tags_hint=None, tags_hint=tags_hint,
media_kind_hint="file", media_kind_hint=media_kind_hint,
full_metadata=None, full_metadata=full_md,
provider_hint=str(provider_name), provider_hint=str(provider_name),
progress=progress, progress=progress,
config=config, config=config,
@@ -600,6 +648,7 @@ class Download_File(Cmdlet):
# If this looks like a provider item and providers are available, prefer provider.download() # If this looks like a provider item and providers are available, prefer provider.download()
downloaded_path: Optional[Path] = None downloaded_path: Optional[Path] = None
attempted_provider_download = False attempted_provider_download = False
provider_sr = None
if table and get_search_provider and SearchResult: if table and get_search_provider and SearchResult:
provider = get_search_provider(str(table), config) provider = get_search_provider(str(table), config)
if provider is not None: if provider is not None:
@@ -612,6 +661,7 @@ class Download_File(Cmdlet):
) )
debug(f"[download-file] Downloading provider item via {table}: {sr.title}") debug(f"[download-file] Downloading provider item via {table}: {sr.title}")
downloaded_path = provider.download(sr, final_output_dir) 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. # 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": 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) log(f"Cannot download item (no provider handler / unsupported target): {title or target}", file=sys.stderr)
continue 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( self._emit_local_file(
downloaded_path=downloaded_path, downloaded_path=downloaded_path,
source=str(target) if target else None, source=str(target) if target else None,

View File

@@ -1593,6 +1593,36 @@ class Download_Media(Cmdlet):
debug("Preflight URL check: no matches") debug("Preflight URL check: no matches")
return True 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))") table = ResultTable(f"URL already exists ({len(url_matches)} match(es))")
results_list: List[Dict[str, Any]] = [] results_list: List[Dict[str, Any]] = []
for item in url_matches: for item in url_matches:
@@ -1639,8 +1669,28 @@ class Download_Media(Cmdlet):
with cm: with cm:
get_stderr_console().print(table) get_stderr_console().print(table)
setattr(table, "_rendered_by_cmdlet", True) setattr(table, "_rendered_by_cmdlet", True)
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()))
if used_suspend:
# 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: try:
pipeline_context.request_pipeline_stop(reason="duplicate-url declined", exit_code=0) pipeline_context.request_pipeline_stop(reason="duplicate-url declined", exit_code=0)
except Exception: except Exception:
@@ -1666,6 +1716,35 @@ class Download_Media(Cmdlet):
debug("Bulk URL preflight skipped: storage unavailable") debug("Bulk URL preflight skipped: storage unavailable")
return True 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] = [] unique_urls: List[str] = []
for u in urls or []: for u in urls or []:
s = str(u or "").strip() s = str(u or "").strip()
@@ -1930,7 +2009,32 @@ class Download_Media(Cmdlet):
cm = nullcontext() cm = nullcontext()
with cm: 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 False
return True return True
@@ -1947,6 +2051,20 @@ class Download_Media(Cmdlet):
if not isinstance(entries, list) or len(entries) <= 1: if not isinstance(entries, list) or len(entries) <= 1:
return False 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) # Display table (limit rows to keep output reasonable)
max_rows = 200 max_rows = 200
display_entries = entries[:max_rows] display_entries = entries[:max_rows]
@@ -1976,6 +2094,11 @@ class Download_Media(Cmdlet):
table = ResultTable() table = ResultTable()
safe_url = str(url or "").strip() safe_url = str(url or "").strip()
table.title = f'download-media -url "{safe_url}"' if safe_url else "download-media" 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", []) table.set_source_command("download-media", [])
try: try:
table.set_preserve_order(True) table.set_preserve_order(True)
@@ -2581,7 +2704,10 @@ class Download_Media(Cmdlet):
PipelineProgress(pipeline_context).step("finalized") PipelineProgress(pipeline_context).step("finalized")
stage_ctx = pipeline_context.get_stage_context() 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: for pipe_obj_dict in pipe_objects:
if emit_enabled: if emit_enabled:
pipeline_context.emit(pipe_obj_dict) pipeline_context.emit(pipe_obj_dict)

View File

@@ -85,7 +85,12 @@ class Get_Url(Cmdlet):
if title: if title:
table_title = f"Title: {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", []) table.set_source_command("get-url", [])
items: List[UrlItem] = [] 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) # Bandcamp downloading (provider method)
<figure> <figure>
<figcaption><🜂🜄|🜁🜃></figcaption> <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> </code></pre>
</figure> </figure>

View File

@@ -395,33 +395,11 @@ def normalize_urls(value: Any) -> List[str]:
if not u: if not u:
return None return None
lower = u.lower() # IMPORTANT: URLs can be case-sensitive in the path/query on some hosts
if not (lower.startswith("http://") or lower.startswith("https://")): # (e.g., https://0x0.st/PzGY.webp). Do not lowercase or otherwise rewrite
# the URL here; preserve exact casing and percent-encoding.
return u 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, ""))
seen: Set[str] = set() seen: Set[str] = set()
out: List[str] = [] out: List[str] = []
for raw_url in _iter_raw_urls(value): for raw_url in _iter_raw_urls(value):

View File

@@ -860,6 +860,20 @@ def get_last_result_items() -> List[Any]:
return [] 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]: def get_last_result_table_source_command() -> Optional[str]:
"""Get the source command from the last displayed result table. """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)* - **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! - **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: 2. rename config.conf.remove to config.conf the store=folder path should be empty folder with no other files in it.
```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:
```ini ```ini
temp="C:\\Users\\Admin\\Downloads" temp="C:\\Users\\Admin\\Downloads"
[store=folder] [store=folder]
name="default" 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: 3. Start the CLI by simply running "mm" in shell or run python cli.py
```powershell
cd "C:\location\to\repository\medios-machina\"
python cli.py
```
# [CLICK FOR GUIDED TUTORIAL](/docs/tutorial.md)
## Usage overview 🔧 ## Usage overview 🔧
- Pipelines: chain cmdlets with `|`, e.g., `download-media <url> | add-file -storage local`. - 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. - 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"` `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: - 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"` - 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' | add-file -store local"` - 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. 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>`. - 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. - Tagging & metadata: `add-tag` mutates piped results (temporary path items) or writes to a configured store when `-store` is provided.
## Built-in image viewer 🎞️ ## 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`. - 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. - 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. - 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. - 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): Simple download with metadata (tags and URL registration):
```bash ```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: 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: Take a website screenshot, tag it, and store locally:
```bash ```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): OpenLibrary ingestion (book metadata & PDF/ebook handling is automatically enriched when `add-file` detects an OpenLibrary URL):
```bash ```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 ```bash
search-file -provider youtube "my favourite track" search-store "ext:mp3"
@1
download-media [URL] | add-file -store hydrus
``` ```
## Providers & stores ## 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`. - **Soulseek, LibGen, All-Debrid, Others**: provider support is modular—add or configure providers in `config.conf`.
## Troubleshooting & tips 🛠️ ## 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 ## Contributing & docs
- Developer docs are generated under `docs/` and tests live alongside the code; please run the test suite before submitting changes. - 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. - 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? 🚀