Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f4bd9de93b | ||
|
|
01e60ba817 | ||
|
|
3ed0503bdf | ||
|
|
0ff888e41b | ||
|
|
783e2a0039 | ||
|
|
cab702aa24 | ||
|
|
dc8a5361fb | ||
|
|
7b13720a4f | ||
|
|
21e63089b9 | ||
|
|
6aa398c2e9 | ||
|
|
0562a31562 | ||
|
|
8ee0c46bba | ||
|
|
deb8e263b2 | ||
|
|
558c198957 | ||
|
|
ba38be122e | ||
|
|
4ab227e909 | ||
|
|
af39d0ee6a | ||
|
|
077619a6f1 | ||
|
|
6d22b5e19b | ||
|
|
1eb7ea8154 | ||
|
|
adad0efb08 | ||
|
|
7cfb0fd962 | ||
|
|
cfae926fbc | ||
|
|
3fa97df61e | ||
|
|
151723d5e1 | ||
|
|
d60a1d5180 | ||
|
|
ba8454e2c8 | ||
|
|
1cb7b59559 | ||
|
|
ed5e92b859 | ||
|
|
9a39ae62fe | ||
|
|
b96ae21c70 | ||
|
|
9a02f39d01 | ||
|
|
e3f784859b | ||
|
|
f885593e32 | ||
|
|
08d7fe6840 | ||
|
|
feb1d993b5 | ||
|
|
0c5dd03ca8 | ||
|
|
c3e0681b6e | ||
|
|
518bfbe059 | ||
|
|
924b6bb4b7 | ||
|
|
da876b628e | ||
|
|
d5ab45886c | ||
|
|
fa36e550c9 | ||
|
|
803f4aaec3 | ||
|
|
6bc42e53b7 | ||
|
|
98e16cf501 | ||
|
|
98f981b59e | ||
|
|
6ad0c53664 | ||
|
|
1e41acef27 | ||
|
|
b8e3cf233a | ||
|
|
b6e8177e5a | ||
|
|
0bf5576049 | ||
|
|
615a6139bf | ||
|
|
70001a0d6c | ||
|
|
edb59e4ee2 | ||
|
|
5164124438 | ||
|
|
6aebb31991 | ||
|
|
3a816a1c44 | ||
|
|
1aa9459525 | ||
|
|
03587b2b0a | ||
|
|
da4a67b59b | ||
|
|
3eb51639cc | ||
|
|
d235dc5419 | ||
|
|
0b05b0d346 | ||
|
|
522429b731 | ||
|
|
035e5ad66f | ||
|
|
4d5c9be4ae | ||
|
|
d40da1d670 | ||
|
|
f0d3739493 | ||
|
|
587fadbaef | ||
|
|
95e2338897 |
No files matched your search
@@ -0,0 +1,14 @@
|
|||||||
|
.git
|
||||||
|
.venv
|
||||||
|
data
|
||||||
|
refs
|
||||||
|
dist
|
||||||
|
results
|
||||||
|
_phase0_archive
|
||||||
|
**/__pycache__
|
||||||
|
**/target
|
||||||
|
*.idat
|
||||||
|
*.idat.gz
|
||||||
|
*.bpm
|
||||||
|
*.egt
|
||||||
|
*.gtc
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
name: Bug report
|
||||||
|
about: A crash, an error message, or a result that looks wrong
|
||||||
|
title: "[bug] "
|
||||||
|
labels: []
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Thank you for reporting. Please do **not** attach vendor files (IDAT, BPM, CSV, EGT, GTC) or any genetic data of real people. An automatic triage reads the text to suggest labels (see CONTRIBUTING.md).
|
||||||
|
- type: input
|
||||||
|
id: version
|
||||||
|
attributes:
|
||||||
|
label: SimurgArray version
|
||||||
|
description: Output of `simurg --version`
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
id: platform
|
||||||
|
attributes:
|
||||||
|
label: Platform
|
||||||
|
options:
|
||||||
|
- Linux x86_64
|
||||||
|
- Linux aarch64 (for example Raspberry Pi)
|
||||||
|
- Docker
|
||||||
|
- conda
|
||||||
|
- other
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: backend
|
||||||
|
attributes:
|
||||||
|
label: Backend
|
||||||
|
description: Output of `python -c "from simurg._core import backend; print(backend())"`
|
||||||
|
- type: textarea
|
||||||
|
id: command
|
||||||
|
attributes:
|
||||||
|
label: Command
|
||||||
|
description: The exact command you ran
|
||||||
|
render: shell
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: what
|
||||||
|
attributes:
|
||||||
|
label: What happened, and what you expected
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: log
|
||||||
|
attributes:
|
||||||
|
label: Error message or log
|
||||||
|
description: Add `--debug` for a traceback. Error codes look like `E_...` or `W_...`.
|
||||||
|
render: text
|
||||||
|
- type: textarea
|
||||||
|
id: manifest
|
||||||
|
attributes:
|
||||||
|
label: run_manifest.json
|
||||||
|
description: Paste or attach the run manifest of the run; it lists versions, options and input checksums.
|
||||||
|
render: json
|
||||||
|
- type: checkboxes
|
||||||
|
id: privacy
|
||||||
|
attributes:
|
||||||
|
label: Privacy
|
||||||
|
options:
|
||||||
|
- label: I did not attach vendor files or genetic data of real people.
|
||||||
|
required: true
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
blank_issues_enabled: false
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
name: Feature request
|
||||||
|
about: Suggest a new capability or a change in behaviour
|
||||||
|
title: "[feature] "
|
||||||
|
labels: []
|
||||||
|
body:
|
||||||
|
- type: textarea
|
||||||
|
id: problem
|
||||||
|
attributes:
|
||||||
|
label: What are you trying to do?
|
||||||
|
description: The research task or workflow, and where SimurgArray gets in the way.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: proposal
|
||||||
|
attributes:
|
||||||
|
label: What would help?
|
||||||
|
description: Describe the behaviour you would like. Mention spec items (for example CLI-021) if you know them.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: validation
|
||||||
|
attributes:
|
||||||
|
label: How could it be validated?
|
||||||
|
description: A public dataset, a reference tool or a paper the result could be checked against.
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
## What changes
|
||||||
|
|
||||||
|
## Spec items touched
|
||||||
|
|
||||||
|
<!-- for example CLI-021, OUT-031; update the spec in the same pull request if behaviour changes -->
|
||||||
|
|
||||||
|
## How it was validated
|
||||||
|
|
||||||
|
<!-- unit tests, oracle tests you ran, datasets, numbers -->
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
|
||||||
|
* [ ] `ruff`, `mypy` and `pytest tests/unit` pass
|
||||||
|
* [ ] `CHANGELOG.md` updated (Unreleased) if users would notice
|
||||||
|
* [ ] differences from reference tools recorded in `docs/known_unknowns.md`
|
||||||
|
* [ ] no vendor data, no genetic data of real people, no credentials
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
# Gitea Actions workflow: lint, types, secret scan and unit tests with and without the compiled kernels.
|
||||||
|
name: ci
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
python: ["3.12", "3.13"]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: astral-sh/setup-uv@v5
|
||||||
|
with:
|
||||||
|
python-version: ${{ matrix.python }}
|
||||||
|
- name: Secret scan (no cloud keys or private keys in the repository)
|
||||||
|
run: |
|
||||||
|
if git grep -nIE '(AKIA|ASIA)[A-Z0-9]{16}|aws_secret_access_key *=|BEGIN [A-Z ]*PRIVATE KEY|apikey_[0-9a-f]{20,}'; then
|
||||||
|
echo "::error::credential-like content found"; exit 1
|
||||||
|
fi
|
||||||
|
- name: Install
|
||||||
|
# setup-uv >= 5.x already creates and activates .venv when python-version is set; --clear works either way
|
||||||
|
run: uv venv --clear && uv pip install -e ".[dev]"
|
||||||
|
- name: Lint
|
||||||
|
run: uv run ruff check src tests && uv run ruff format --check src tests
|
||||||
|
- name: Type check
|
||||||
|
run: uv run mypy
|
||||||
|
- name: Unit tests (no downloaded data needed)
|
||||||
|
run: uv run pytest tests/unit -q
|
||||||
|
- name: Build the compiled kernels (rust/simurg-core)
|
||||||
|
run: |
|
||||||
|
command -v cc >/dev/null || { apt-get update -qq && apt-get install -y -qq gcc >/dev/null; } # Rust needs a C linker
|
||||||
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal
|
||||||
|
PATH="$HOME/.cargo/bin:$PATH" uv pip install ./rust/simurg-core
|
||||||
|
- name: Unit tests with the compiled kernels (must equal the pure-Python results)
|
||||||
|
run: uv run pytest tests/unit -q
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# Gitea Actions workflow: automatic first triage of new issues (scripts/jev/issue_triage.py, TypeSafe Jev).
|
||||||
|
# Needs the repository secret TYPESAFE_API_KEY; the built-in token applies labels and posts one comment.
|
||||||
|
name: issue-triage
|
||||||
|
on:
|
||||||
|
issues:
|
||||||
|
types: [opened, edited]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
triage:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Triage
|
||||||
|
env:
|
||||||
|
TYPESAFE_API_KEY: ${{ secrets.TYPESAFE_API_KEY }}
|
||||||
|
GITEA_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
GITEA_API: ${{ github.api_url }}
|
||||||
|
REPO: ${{ github.repository }}
|
||||||
|
run: python3 scripts/jev/issue_triage.py --event "$GITHUB_EVENT_PATH"
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
# Runs on Gitea Actions (reads .github/workflows) and GitHub Actions.
|
|
||||||
name: ci
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
python: ["3.12", "3.13"]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: astral-sh/setup-uv@v5
|
|
||||||
with:
|
|
||||||
python-version: ${{ matrix.python }}
|
|
||||||
- name: Install
|
|
||||||
run: uv venv && uv pip install -e ".[dev]"
|
|
||||||
- name: Lint
|
|
||||||
run: uv run ruff check src tests && uv run ruff format --check src tests
|
|
||||||
- name: Type check
|
|
||||||
run: uv run mypy
|
|
||||||
- name: Unit tests (no downloaded data needed)
|
|
||||||
run: uv run pytest tests/unit -q
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
# vendor / large data — never commit
|
# vendor / large data — never commit
|
||||||
data/
|
/data/
|
||||||
refs/
|
refs/
|
||||||
_phase0_archive/
|
_phase0_archive/
|
||||||
*.idat
|
*.idat
|
||||||
@@ -18,3 +18,21 @@ __pycache__/
|
|||||||
target/
|
target/
|
||||||
.trial-last
|
.trial-last
|
||||||
results/
|
results/
|
||||||
|
# editor lock files
|
||||||
|
.~lock.*#
|
||||||
|
# credentials and secrets (never commit)
|
||||||
|
.aws/
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
*.pem
|
||||||
|
*.key
|
||||||
|
*.p12
|
||||||
|
credentials
|
||||||
|
.git-credentials
|
||||||
|
.netrc
|
||||||
|
# local caches (claim checker and others)
|
||||||
|
.cache/
|
||||||
|
# claim checker output (local)
|
||||||
|
claims_report.md
|
||||||
|
spec_coverage_report.md
|
||||||
|
voice_report.md
|
||||||
@@ -1,5 +1,78 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
**Maintenance tools (TypeSafe Jev).** Spec coverage audit (152 of 354 testable spec items cited by tests, 23 more
|
||||||
|
judged covered, 150 without a test), brand voice check, automatic triage of failed nightly runs and of new Gitea
|
||||||
|
issues (labels, missing information, privacy and clinical use flags), and a weekly literature reading list. See
|
||||||
|
`CONTRIBUTING.md`.
|
||||||
|
|
||||||
|
**Documentation checks.** `scripts/docs/check_claims.py` checks the numeric claims of public texts against the
|
||||||
|
validation reports (code retrieves evidence, a TypeSafe System One model judges support). Its first run corrected the
|
||||||
|
manifest loading times (Omni2.5 about 18 s on a Pi, now measured in `docs/validation/P9.md`) and a demo timing
|
||||||
|
sentence in the README.
|
||||||
|
|
||||||
|
**Packaging.** The distributions are now `simurgarray` and `simurgarray-core` (the name `simurg` is taken on
|
||||||
|
PyPI); the `simurg` command and the `simurg` / `simurg_core` import names are unchanged. The conda recipe no longer pins
|
||||||
|
the kernel package to the Python package's version (it required `simurg-core == 2.0.0` while the kernels are 1.1.0).
|
||||||
|
Project URLs in the package metadata.
|
||||||
|
|
||||||
|
**Community.** `CONTRIBUTING.md`, `SECURITY.md`, `CODE_OF_CONDUCT.md`, `CITATION.cff`, Gitea issue and pull request
|
||||||
|
templates; CI moved to `.gitea/workflows/`. Probe names in the P6 oracle examples are replaced by stable pseudonyms.
|
||||||
|
|
||||||
|
**Repository tidy-up.** Removed the Phase-0 research notes (`docs/research/`), the P9 benchmark scripts (`bench/`,
|
||||||
|
`scripts/cloud/tasks/p9*.sh`) and a vendor probe-name list that should never have been committed (also purged from
|
||||||
|
the git history).
|
||||||
|
|
||||||
|
**Branding.** A visual identity (`branding/`, guide in `branding/README.md`): a dotted simurg mark in detailed, simple
|
||||||
|
and micro drawings, wordmark and lockups, icons, README banner, social preview and featured-image templates, with
|
||||||
|
contrast and colour-vision checks. HTML reports (QC report, compare dashboard, methylation QC) get a favicon and a
|
||||||
|
header band with the mark, the software version and a checksum of the data they show. The mark geometry lives in
|
||||||
|
`simurg/core/brand.py`. Blog posts and featured images in `blog/`.
|
||||||
|
|
||||||
|
## 2.0.0 — 2026-09-30 (v2 modules)
|
||||||
|
|
||||||
|
The Python package is 2.0.0. The optional Rust kernels are unchanged and stay `simurg_core` 1.1.0.
|
||||||
|
|
||||||
|
**Methylation control QC** (`simurg methyl qc`, `simurg methyl convert-manifest`; MET-001 … MET-018): methylation
|
||||||
|
CSV manifests, the 21 control metrics, pOOBAH detection p-values, noob, linear/nonlinear dye bias, β and M-values,
|
||||||
|
summary tsv/xlsx/html with a β PCA, per-sample tables; methylation folders load in `simurg qc report`;
|
||||||
|
`qc controls --array-type methylation`. Checked against sesame (`docs/validation/V2_methylation.md`, K-026).
|
||||||
|
|
||||||
|
**Copy number, LOH and mosaicism** (`simurg cn build-model|call|annotate`; CYTO-001 … CYTO-042): GC-wave
|
||||||
|
correction, sex-aware batch reference, HMM with constitutional, LOH and mosaic states, event statistics and
|
||||||
|
filters, CNV VCF + segments + sidecar, ISCN 2020 annotation from UCSC tables; noise-normalised mosaic fractions and
|
||||||
|
complete-loss promotion (CYTO-041), per-probe LRR noise (CYTO-042). Validated on implanted events and on 360
|
||||||
|
GSE165845 arrays against the NYGC 30x SV callset (`docs/validation/V2_cn.md`, K-027).
|
||||||
|
|
||||||
|
**Pharmacogenomics** (`simurg pgx db build|coverage`, `pgx copy-number train|call`, `pgx star-allele call`,
|
||||||
|
`pgx phenotype`; PCN-001 … PCN-017, PGX-001 … PGX-035): targeted CN for CYP2D6 sub-regions, CYP2A6, GSTM1, GSTT1,
|
||||||
|
UGT2B17, SULT1A1, CYP2E1 (HWE-constrained compression mixture); a deterministic PGx DB from CPIC, PharmVar and
|
||||||
|
ClinPGx (70 genes); solver-free diplotype calling with array-equivalence classes, CYP2D6 structures (*5, xN,
|
||||||
|
*68+*4, *36+*10, *13), G6PD, HLA tags, variant-based and *0 genes; probe masks from 1000G 30x concordance; CPIC and
|
||||||
|
DPWG phenotypes; per-sample JSON and the TSV set. The GSA v4 PGx demo arrays are 30 CEPH/1000G individuals: region
|
||||||
|
CN 224/240 vs NYGC SV, gene calls 154/168 vs GeT-RM (`docs/validation/V2_pgx_cn.md`, `V2_pgx_star.md`, K-028, K-029).
|
||||||
|
|
||||||
|
**ArrayTrain** (`simurg train`; plan §12): trains EGT cluster files (v3, dbv9) from a cohort's GTCs with sex-aware
|
||||||
|
sample selection, BIC-selected 1/2/3-cluster θ mixtures, HWE-guided labelling, and missing clusters imputed from
|
||||||
|
cross-locus relations. On GSE165845 (chr22 vs 1000G 30x) it gives 99.44 % concordance at a 99.61 % call rate;
|
||||||
|
the vendor EGT gives 99.46 % at 99.15 % (`docs/validation/V2_arraytrain.md`, K-030).
|
||||||
|
|
||||||
|
## 1.1.0 — 2026-09-28 (P9, P10)
|
||||||
|
|
||||||
|
**Packaging (P10).** `scripts/build_dist.sh` (sdist, pure wheel, manylinux_2_28 kernel wheels for x86_64 and
|
||||||
|
aarch64), `Dockerfile`, conda recipes (`packaging/conda/`). Verified on fresh x86_64 and aarch64 VMs: pip, Docker
|
||||||
|
and conda installs give identical outputs (`docs/validation/P10.md`). A closed stdout pipe now exits 141 silently
|
||||||
|
instead of reporting an internal error.
|
||||||
|
|
||||||
|
**Performance (P9).**
|
||||||
|
|
||||||
|
Optional compiled kernels `rust/simurg-core` (PyO3): fused GenCall calling and BAF/LRR, libm maps with CPython
|
||||||
|
semantics, normalization nearest-neighbour searches, BPM parser. Byte-identical outputs to the pure-Python paths
|
||||||
|
(`SIMURG_PURE_PYTHON=1`); 78–80 GSA samples/min per Graviton3 core (pure Python 30), manifest loading 4× faster.
|
||||||
|
Address coverage memoised per IDAT layout; worker state pickled once. `bench/profile_genotype.py`,
|
||||||
|
`bench/scaling.py`. Details and scaling limits: `docs/validation/P9.md`.
|
||||||
|
|
||||||
## 1.0.0 — 2026-09-28
|
## 1.0.0 — 2026-09-28
|
||||||
|
|
||||||
First release: the v1.0 goals of the master plan (§1.1), built and validated phase by phase (P0–P8).
|
First release: the v1.0 goals of the master plan (§1.1), built and validated phase by phase (P0–P8).
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
cff-version: 1.2.0
|
||||||
|
message: "If you use SimurgArray in your research, please cite it as below."
|
||||||
|
title: "SimurgArray: open analysis of Illumina Infinium genotyping arrays"
|
||||||
|
type: software
|
||||||
|
authors:
|
||||||
|
- family-names: "Yaylali"
|
||||||
|
given-names: "Kemal"
|
||||||
|
contact:
|
||||||
|
- family-names: "Yaylali"
|
||||||
|
given-names: "Kemal"
|
||||||
|
email: "[email protected]"
|
||||||
|
version: "2.0.0"
|
||||||
|
date-released: "2026-09-30"
|
||||||
|
license: MIT
|
||||||
|
repository-code: "https://gitea.yaylali.uk/kemal/SimurgArray"
|
||||||
|
url: "https://gitea.yaylali.uk/kemal/SimurgArray"
|
||||||
|
abstract: >-
|
||||||
|
SimurgArray takes Illumina Infinium BeadChip scans (IDAT files) to genotype calls, quality control reports,
|
||||||
|
VCF and PLINK files, and on to copy number, loss of heterozygosity and mosaicism, pharmacogenomics, cluster file
|
||||||
|
training and methylation control QC. Its genotype calling reproduces the vendor's GTC files byte for byte on
|
||||||
|
public data, and every difference from reference tools is documented. Research use only.
|
||||||
|
keywords:
|
||||||
|
- genotyping
|
||||||
|
- microarray
|
||||||
|
- Infinium
|
||||||
|
- IDAT
|
||||||
|
- VCF
|
||||||
|
- copy number
|
||||||
|
- pharmacogenomics
|
||||||
|
- bioinformatics
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
# Code of conduct
|
||||||
|
|
||||||
|
SimurgArray is a small scientific project. People who use it or contribute to it come from many fields, countries
|
||||||
|
and levels of experience. This page says how we treat each other here.
|
||||||
|
|
||||||
|
## Expected
|
||||||
|
|
||||||
|
* Be kind and assume good faith. Most disagreements are about evidence, so bring evidence.
|
||||||
|
* Criticise code, results and ideas, never people.
|
||||||
|
* Be patient with newcomers; everyone met their first cluster file once.
|
||||||
|
* Credit other people's work, including open source projects and papers.
|
||||||
|
* Respect privacy. Never post genetic data, sample identifiers of real people, or anyone's personal information.
|
||||||
|
|
||||||
|
## Not accepted
|
||||||
|
|
||||||
|
* Harassment, insults, threats, or discriminatory jokes and language, in any form.
|
||||||
|
* Sexualised language or imagery.
|
||||||
|
* Publishing someone else's private information without permission.
|
||||||
|
* Repeatedly derailing discussions or ignoring a request to stop.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This applies to issues, pull requests, commit messages, documentation and any other space of the project, and to
|
||||||
|
anyone representing the project elsewhere.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Report problems privately to **[email protected]**. Reports are handled confidentially. The maintainer may edit
|
||||||
|
or remove contributions and may block people who do not follow this code, starting with a private warning where
|
||||||
|
that is reasonable.
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
# Contributing to SimurgArray
|
||||||
|
|
||||||
|
Thank you for looking. SimurgArray is a small research project with strict habits, because its main promise is that
|
||||||
|
every number can be checked. The rules below keep that promise.
|
||||||
|
|
||||||
|
## Before you start
|
||||||
|
|
||||||
|
* Read the item in `SIMURGARRAY_FUNCTIONAL_SPEC.md` that your change touches. Behaviour is defined there item by item
|
||||||
|
(IDs such as `CLI-021` or `OUT-031`); algorithms and their sources are in `SIMURGARRAY_MASTER_PLAN.md`.
|
||||||
|
* For anything larger than a small fix, open an issue first and describe the change and how you will validate it.
|
||||||
|
|
||||||
|
## Setting up
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://gitea.yaylali.uk/kemal/SimurgArray.git && cd SimurgArray
|
||||||
|
uv venv && uv pip install -e ".[dev]"
|
||||||
|
uv pip install ./rust/simurg-core # optional compiled kernels (needs Rust and a C compiler)
|
||||||
|
uv run pytest tests/unit
|
||||||
|
```
|
||||||
|
|
||||||
|
## The checks every change must pass
|
||||||
|
|
||||||
|
```bash
|
||||||
|
uv run ruff check . && uv run ruff format --check .
|
||||||
|
uv run mypy
|
||||||
|
uv run pytest tests/unit
|
||||||
|
```
|
||||||
|
|
||||||
|
CI runs the same checks, a secret scan, and the unit tests with and without the compiled kernels on Python 3.12
|
||||||
|
and 3.13. If your change touches file formats, calling, QC or outputs, also run the oracle tests
|
||||||
|
(`uv run pytest tests/oracle`, see the README for the data they need) and say which ones you ran.
|
||||||
|
|
||||||
|
## Rules of the house
|
||||||
|
|
||||||
|
1. **Cite the spec.** Commit messages and tests name the spec items they implement or change. If behaviour changes,
|
||||||
|
change the spec item in the same commit.
|
||||||
|
2. **Science modules are pure.** Code under `signal/`, `genotype/`, `cn/`, `qc/`, `pgx/` and `train/` has no file or
|
||||||
|
network access; the `pipeline/` layer does the I/O.
|
||||||
|
3. **Every algorithm names its source** in its docstring: a paper, a public technical note, an expired patent, or an
|
||||||
|
open source project with a compatible licence.
|
||||||
|
4. **Licences.** Code from MIT, BSD, Apache 2.0 or Unlicense projects may be adapted with attribution in
|
||||||
|
`THIRD_PARTY_NOTICES.md`. GPL tools are used only as separate programs for comparison; their code is never copied.
|
||||||
|
5. **Exact by default.** Default mode stays bit exact with the reference outputs. A cleaner numerical choice goes
|
||||||
|
behind an explicit option.
|
||||||
|
6. **Never hide a difference.** When SimurgArray and a reference tool disagree, record it in `docs/known_unknowns.md`
|
||||||
|
with the date, the evidence and what was decided.
|
||||||
|
7. **No vendor data and no secrets in the repository.** No IDAT, BPM, CSV, EGT or GTC files from a vendor, no
|
||||||
|
probe name lists derived from them, no patient or participant data, and no credentials of any kind. Test fixtures
|
||||||
|
are synthetic or openly licensed. `.gitignore` and the CI secret scan help, but the responsibility is yours.
|
||||||
|
8. **Plain writing.** Documentation follows the voice in `branding/README.md`: short sentences, numbers instead of
|
||||||
|
adjectives, and every claim next to its limitation.
|
||||||
|
|
||||||
|
## Checking numbers before publishing
|
||||||
|
|
||||||
|
Text that quotes results (README, user guide, blog posts, announcements) is checked against the validation reports
|
||||||
|
before it goes out:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python scripts/docs/check_claims.py README.md blog/*.md docs/user_guide.md my_draft.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
Code finds every sentence or table row with a number and the passages in `docs/validation/`,
|
||||||
|
`docs/known_unknowns.md` and the spec that share it; a TypeSafe System One model only judges whether each passage
|
||||||
|
supports, contradicts or says nothing about the claim. `claims_report.md` lists contradicted claims, claims without
|
||||||
|
a source, low confidence cases for a person to read, and verified claims. Only this repository's documentation text
|
||||||
|
is sent to the API, never data. The key comes from `TYPESAFE_API_KEY` or `~/.config/typesafe/credentials` and never
|
||||||
|
enters the repository; a full check costs well under one cent. `--dry-run` shows the claims and evidence without
|
||||||
|
calling the API.
|
||||||
|
|
||||||
|
## Maintenance tools (TypeSafe Jev)
|
||||||
|
|
||||||
|
Small tools in `scripts/jev/` use TypeSafe System One judgments (Jev) where plain code needs semantic understanding.
|
||||||
|
Code always collects the evidence and decides what to do; the model only answers typed questions. They are never
|
||||||
|
part of the `simurg` commands, which stay offline. The key comes from `TYPESAFE_API_KEY` or
|
||||||
|
`~/.config/typesafe/credentials` (a repository secret of the same name for the issue workflow).
|
||||||
|
|
||||||
|
* `scripts/docs/check_claims.py FILES`: numeric claims of public texts against the validation reports.
|
||||||
|
* `scripts/jev/spec_coverage.py`: which spec items have a test; writes `spec_coverage_report.md`.
|
||||||
|
* `scripts/jev/voice_check.py FILES`: brand voice rules (dashes, banned words, claims without limits, hype, tone).
|
||||||
|
* `scripts/jev/nightly_triage.py NIGHT`: which known finding explains a failed nightly step; `scripts/nightly.py`
|
||||||
|
runs it automatically when a night fails.
|
||||||
|
* `scripts/jev/issue_triage.py`: first triage of new issues (`.gitea/workflows/issue_triage.yml`).
|
||||||
|
* `scripts/jev/literature_watch.py`: weekly reading list from bioRxiv and PubMed into `data/literature/`.
|
||||||
|
|
||||||
|
Each run costs a fraction of a cent; answers are cached in `.cache/jev/`.
|
||||||
|
|
||||||
|
## Pull requests
|
||||||
|
|
||||||
|
* One topic per pull request, with tests.
|
||||||
|
* Describe what changed, which spec items it touches, how you validated it, and any new entry in
|
||||||
|
`docs/known_unknowns.md`.
|
||||||
|
* Add a line to the `Unreleased` section of `CHANGELOG.md` for anything a user would notice.
|
||||||
|
|
||||||
|
## Reporting problems
|
||||||
|
|
||||||
|
Use the issue templates. New issues get an automatic first triage (`.gitea/workflows/issue_triage.yml`): the title
|
||||||
|
and text are sent to the TypeSafe API, which suggests kind and area labels, notes missing information, and flags
|
||||||
|
personal data, vendor file contents or credentials so they can be removed. A maintainer checks every label. For a wrong or unexpected result, attach the `run_manifest.json` of the run and the exact
|
||||||
|
command; it records every version, option and input checksum. Please do not attach vendor files or any genetic data
|
||||||
|
of real people. For security issues see `SECURITY.md`.
|
||||||
|
|
||||||
|
Questions and feedback that do not fit an issue are welcome at **[email protected]**.
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
# SimurgArray container: the `simurg` CLI with the compiled kernels.
|
||||||
|
# docker build -t simurg:2.0.0 .
|
||||||
|
# docker run --rm -v "$PWD":/work simurg:2.0.0 genotype --bpm M.bpm --egt C.egt --idats idats --out run/gtc
|
||||||
|
# Inputs and outputs live in the mounted /work folder; the image holds no data.
|
||||||
|
ARG PYTHON=3.12
|
||||||
|
|
||||||
|
FROM python:${PYTHON}-slim-bookworm AS build
|
||||||
|
RUN apt-get update -q && apt-get install -y -q --no-install-recommends curl gcc libc6-dev \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal
|
||||||
|
ENV PATH=/root/.cargo/bin:$PATH
|
||||||
|
WORKDIR /src
|
||||||
|
COPY pyproject.toml README.md LICENSE THIRD_PARTY_NOTICES.md ./
|
||||||
|
COPY src ./src
|
||||||
|
COPY rust/simurg-core ./rust/simurg-core
|
||||||
|
RUN pip wheel --no-cache-dir --no-deps -w /wheels . ./rust/simurg-core
|
||||||
|
|
||||||
|
FROM python:${PYTHON}-slim-bookworm
|
||||||
|
LABEL org.opencontainers.image.title="SimurgArray" \
|
||||||
|
org.opencontainers.image.description="Research toolkit for Illumina Infinium genotyping BeadChip data" \
|
||||||
|
org.opencontainers.image.licenses="MIT"
|
||||||
|
COPY --from=build /wheels /wheels
|
||||||
|
RUN pip install --no-cache-dir /wheels/*.whl && rm -rf /wheels \
|
||||||
|
&& useradd --create-home --uid 1000 simurg
|
||||||
|
USER simurg
|
||||||
|
WORKDIR /work
|
||||||
|
ENTRYPOINT ["simurg"]
|
||||||
|
CMD ["--help"]
|
||||||
@@ -1,44 +1,384 @@
|
|||||||
# SimurgArray
|
<p align="center"><img src="branding/templates/readme_banner_1280x320.png" alt="SimurgArray: Thirty birds, one picture." width="100%"></p>
|
||||||
|
|
||||||
Personal research toolkit for Illumina Infinium genotyping BeadChip data
|
<p align="center">
|
||||||
(IDAT → normalization → genotype calling → BAF/LRR → QC → VCF/PLINK; later CN/LOH, PGx, cluster training).
|
<a href="https://gitea.yaylali.uk/kemal/SimurgArray/actions"><img src="https://gitea.yaylali.uk/kemal/SimurgArray/actions/workflows/ci.yml/badge.svg?branch=main" alt="CI"></a>
|
||||||
|
<img src="https://img.shields.io/badge/version-2.0.0-D4A017" alt="Version 2.0.0">
|
||||||
|
<img src="https://img.shields.io/badge/python-3.12%20%7C%203.13-3776AB?logo=python&logoColor=white" alt="Python 3.12 and 3.13">
|
||||||
|
<img src="https://img.shields.io/badge/license-MIT-1E2240" alt="MIT licence">
|
||||||
|
<img src="https://img.shields.io/badge/platform-Linux%20x86__64%20%7C%20aarch64-2F8F5B?logo=linux&logoColor=white" alt="Linux x86_64 and aarch64">
|
||||||
|
<img src="https://img.shields.io/badge/kernels-Rust%20(optional)-B7410E?logo=rust&logoColor=white" alt="Optional Rust kernels">
|
||||||
|
<img src="https://img.shields.io/badge/docker-ready-2496ED?logo=docker&logoColor=white" alt="Docker ready">
|
||||||
|
<img src="https://img.shields.io/badge/runs%20on-Raspberry%20Pi%205-C51A4A?logo=raspberrypi&logoColor=white" alt="Runs on a Raspberry Pi 5">
|
||||||
|
<img src="https://img.shields.io/badge/use-research%20only-C8453A" alt="Research use only">
|
||||||
|
</p>
|
||||||
|
|
||||||
- **SIMURGARRAY_MASTER_PLAN.md** — architecture, algorithms, roadmap
|
<p align="center">
|
||||||
- **SIMURGARRAY_FUNCTIONAL_SPEC.md** — 416 itemised requirements (CLI, inputs, outputs, QC, CN, PGx, methylation, edge cases)
|
<b>Open analysis of Illumina Infinium genotyping arrays, from IDAT to genotypes, QC, VCF, copy number and pharmacogenomics.</b><br>
|
||||||
- `docs/validation/` — per-phase validation reports · `docs/known_unknowns.md` — findings log · `docs/research/` — background
|
<a href="#install">Install</a> · <a href="#quick-start">Quick start</a> · <a href="#usage">Usage</a> ·
|
||||||
|
<a href="docs/user_guide.md">User guide</a> · <a href="docs/validation/">Validation</a> · <a href="CHANGELOG.md">Changelog</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
## Status
|
SimurgArray reads the raw scanner files of Infinium BeadChips and takes them all the way to analysis ready outputs.
|
||||||
|
Its genotype calling reproduces the vendor's GTC files byte for byte on public data, every algorithm names its
|
||||||
|
source, and every place where it differs from a reference tool is written down in `docs/known_unknowns.md`.
|
||||||
|
It runs on anything from a Raspberry Pi to a cloud server.
|
||||||
|
|
||||||
**v1.0.0** (2026-09-28) — see `CHANGELOG.md`. IDAT → normalization → GenCall-equivalent genotype calling → GTC v5 →
|
> **Research use only.** SimurgArray is not a medical device and must not be used for diagnosis or treatment
|
||||||
sample/control QC with an HTML report → plus-strand VCF/BCF → PLINK 1/2, bedGraph, final report; plus a
|
> decisions, including its pharmacogenomics output.
|
||||||
differential-testing harness. Validation (`docs/validation/`):
|
|
||||||
|
## Contents
|
||||||
|
|
||||||
|
* [Features](#features)
|
||||||
|
* [Validation](#validation)
|
||||||
|
* [Requirements](#requirements)
|
||||||
|
* [Install](#install)
|
||||||
|
* [Input files](#input-files)
|
||||||
|
* [Quick start](#quick-start)
|
||||||
|
* [Usage](#usage)
|
||||||
|
* [Outputs at a glance](#outputs-at-a-glance)
|
||||||
|
* [Performance and memory](#performance-and-memory)
|
||||||
|
* [Development](#development)
|
||||||
|
* [Repository layout](#repository-layout)
|
||||||
|
* [Documentation](#documentation)
|
||||||
|
* [Feedback and support](#feedback-and-support)
|
||||||
|
* [Citing](#citing)
|
||||||
|
* [Licence, data and trademarks](#licence-data-and-trademarks)
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
| | Area | What you get |
|
||||||
|
|---|---|---|
|
||||||
|
| 🧬 | **Genotyping** | IDAT → normalization → GenCall equivalent calls, scores, BAF and LRR → GTC v3/v5, bit exact with the vendor software (`--preset current` or `autocall-1.6.2`) |
|
||||||
|
| 📊 | **Quality control** | 21 control probe metrics, sample QC, BAF regression contamination, KING kinship and Mendel errors, sex checks, per locus summaries, and a self contained interactive HTML report |
|
||||||
|
| 📄 | **Outputs** | Plus strand VCF/BCF with tabix/CSI indexes, PLINK 1 and 2, bedGraph tracks, final reports and genotype matrices, all written natively |
|
||||||
|
| 🪶 | **ArrayTrain** | Train your own EGT cluster file from a cohort's GTCs instead of borrowing one |
|
||||||
|
| 🧩 | **Copy number** | Genome wide CNV, LOH and mosaicism calling with an HMM, ISCN 2020 annotation, cytobands and genes |
|
||||||
|
| 💊 | **Pharmacogenomics** | Targeted copy number (CYP2D6 and others), star allele diplotypes for 70 genes, CPIC and DPWG phenotypes, from open databases |
|
||||||
|
| 🧪 | **Methylation QC** | EPIC and MSA control metrics, pOOBAH detection, noob, dye bias correction, β and M values |
|
||||||
|
| 🔍 | **Differential testing** | `simurg compare` checks two runs field by field (EXACT / NEAR / DISCREPANCY / UNKNOWN) with an HTML dashboard |
|
||||||
|
| ⚡ | **Speed** | Optional Rust kernels with identical outputs: about 80 GSA samples a minute per server core, about one sample a second on a Pi core |
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
Each phase has its own report in `docs/validation/`.
|
||||||
|
|
||||||
| Check | Result |
|
| Check | Result |
|
||||||
|---|---|
|
|---|---|
|
||||||
| 2141 vendor GTCs, 1000 Genomes Omni2.5 (`--preset autocall-1.6.2`) | normalization bit-identical; GTCs byte-identical in 2138/2141 |
|
| 2141 vendor GTCs, 1000 Genomes Omni2.5 (`--preset autocall-1.6.2`) | normalization bit identical; GTCs byte identical in 2138/2141 |
|
||||||
| GSA demo vs gtc2vcf, GTCtoVCF, plink2 | zero unexplained differences |
|
| GSA demo vs gtc2vcf, GTCtoVCF and plink2 | zero unexplained differences |
|
||||||
| 1000 Genomes pedigrees (Omni2.5) | 717/717 parent–offspring pairs; Mendel error median 0.031 % |
|
| 1000 Genomes pedigrees (Omni2.5) | 717/717 parent and offspring pairs; median Mendel error 0.031 % |
|
||||||
| 360 GSA arrays (GSE165845) vs NYGC 30x WGS / GIAB HG001 | concordance 0.9934 / 0.9985; replicates 0.9966 |
|
| 360 GSA arrays (GSE165845) vs NYGC 30x WGS / GIAB HG001 | concordance 0.9934 / 0.9985; replicates 0.9966 |
|
||||||
|
| ArrayTrain cluster file, GSE165845 chr22 vs 1000G 30x | 99.44 % concordance (vendor file 99.46 %) at a 99.61 % call rate |
|
||||||
|
| Copy number, 360 GSE165845 arrays vs NYGC 30x SV | PASS precision DEL 44 % / DUP 57 %; rare deletions found 30 % |
|
||||||
|
| Pharmacogenomics, GSA v4 demo vs GeT RM | 154/168 gene calls |
|
||||||
|
| Methylation QC vs sesame | β r = 0.99998 |
|
||||||
|
|
||||||
Commands: `simurg inspect`, `ingest`, `normalize`, `genotype`, `qc controls|samples|contamination|relatedness|loci|report|suggest-thresholds`,
|
## Requirements
|
||||||
`gtc-to-vcf`, `export plink|bedgraph|finalreport|locus-summary`, `compare`. **User guide: `docs/user_guide.md`**;
|
|
||||||
worked example: `examples/gsa_demo.sh`. Next (plan §18): P9 performance (compiled core), P10 packaging, then v2
|
* **Python 3.12 or 3.13** on 64 bit Linux (x86_64 or aarch64). Tested on Ubuntu 24.04 and Raspberry Pi OS.
|
||||||
modules (cluster training, CN/LOH, PGx).
|
* **Memory:** about 2 to 3 GB per worker process for GSA or Omni sized arrays. 8 GB is enough for a Pi with two workers.
|
||||||
|
* **Optional:** Rust and a C compiler for the compiled kernels; Docker or conda for those installs.
|
||||||
|
* The Python package is called `simurgarray`; the command and the import name are `simurg`.
|
||||||
|
* Only pure Python dependencies are needed (numpy, pyarrow, typer, rich, pyyaml, openpyxl). bcftools and plink2
|
||||||
|
are **not** required; SimurgArray writes VCF, BCF, indexes and PLINK files itself. They are used only as test oracles.
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
### From source (recommended)
|
||||||
|
|
||||||
|
With [uv](https://docs.astral.sh/uv/):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://gitea.yaylali.uk/kemal/SimurgArray.git
|
||||||
|
cd SimurgArray
|
||||||
|
uv venv && uv pip install -e . # add ".[dev]" for tests, ruff and mypy
|
||||||
|
source .venv/bin/activate
|
||||||
|
simurg --version
|
||||||
|
```
|
||||||
|
|
||||||
|
With plain pip:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python3 -m venv .venv && .venv/bin/pip install -e .
|
||||||
|
```
|
||||||
|
|
||||||
|
### Optional compiled kernels
|
||||||
|
|
||||||
|
Three to four times faster genotyping and four times faster manifest loading. Results are byte identical.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal # Rust (needs gcc or clang)
|
||||||
|
uv pip install ./rust/simurg-core
|
||||||
|
python -c "from simurg._core import backend; print(backend())" # prints: rust 1.1.0
|
||||||
|
```
|
||||||
|
|
||||||
|
Without the kernels the same code runs in pure Python and NumPy. `SIMURG_PURE_PYTHON=1` forces that path.
|
||||||
|
|
||||||
|
### From release files
|
||||||
|
|
||||||
|
`bash scripts/build_dist.sh` writes a pure wheel, an sdist and `manylinux_2_28` kernel wheels for x86_64 and
|
||||||
|
aarch64 (glibc 2.28 or newer) to `dist/`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python3 -m venv simurg-env
|
||||||
|
simurg-env/bin/pip install simurgarray-2.0.0-py3-none-any.whl \
|
||||||
|
simurgarray_core-1.1.0-cp312-abi3-manylinux_2_28_$(uname -m).whl # the kernel wheel is optional
|
||||||
|
```
|
||||||
|
|
||||||
|
### Docker
|
||||||
|
|
||||||
|
The image is about 550 MB, includes the kernels and runs as a non root user. Your data stay in the mounted folder.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker build -t simurg:2.0.0 .
|
||||||
|
docker run --rm --user "$(id -u):$(id -g)" -v "$PWD":/work simurg:2.0.0 \
|
||||||
|
genotype --bpm M.bpm --egt C.egt --idats idats --out run/gtc
|
||||||
|
```
|
||||||
|
|
||||||
|
### conda
|
||||||
|
|
||||||
|
```bash
|
||||||
|
conda build -c conda-forge --output-folder conda-bld packaging/conda/simurg-core packaging/conda/simurg
|
||||||
|
conda create -n simurgarray -c ./conda-bld -c conda-forge simurgarray simurgarray-core
|
||||||
|
```
|
||||||
|
|
||||||
|
All installs give identical results on x86_64 and aarch64 (`docs/validation/P10.md`).
|
||||||
|
|
||||||
|
## Input files
|
||||||
|
|
||||||
|
| File | Needed by | Notes |
|
||||||
|
|---|---|---|
|
||||||
|
| **IDAT pairs** (`<barcode>_<RxxCxx>_Grn.idat` and `_Red.idat`, optionally `.gz`) | `genotype`, `qc controls`, `methyl qc` | searched recursively; the sample ID is `<barcode>_<position>` |
|
||||||
|
| **BPM manifest** | almost every command | loci, bead addresses, normalization bins, positions; its genome build sets the VCF build |
|
||||||
|
| **EGT cluster file** | `genotype`, `qc loci` | from the vendor, or trained with `simurg train` |
|
||||||
|
| **CSV manifest** | `gtc-to-vcf` (indels), `export finalreport`, PGx | same product and version as the BPM |
|
||||||
|
| **Reference FASTA** | `gtc-to-vcf`, `cn`, `pgx` | GRCh38 or GRCh37, plain or bgzip; `bash scripts/fetch_data.sh p6` downloads GRCh38 |
|
||||||
|
| **Sample sheet** (optional) | most commands | `Sample_ID`, `Sample_Name`, `Sample_Group`, `Parent1`/`Parent2`, sex and custom columns |
|
||||||
|
|
||||||
|
Manifests and cluster files come from the array vendor's support pages for your product. They are licensed by
|
||||||
|
the vendor and are **never** committed to this repository; `.gitignore` blocks IDAT, BPM, EGT and GTC files.
|
||||||
|
|
||||||
## Quick start
|
## Quick start
|
||||||
|
|
||||||
|
A complete run on the public GSA v4 PGx demo (36 samples):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
uv venv && uv pip install -e ".[dev]"
|
bash scripts/fetch_data.sh p0 # demo IDATs, manifest and cluster file (~1.4 GB)
|
||||||
uv run pytest tests/unit # no downloads needed
|
bash scripts/fetch_data.sh p6 # GRCh38 FASTA for VCF output (~0.9 GB download)
|
||||||
bash scripts/bootstrap_refs.sh # reference open-source repos → refs/ (oracles)
|
bash examples/gsa_demo.sh results/gsa_demo 6 # end to end on 6 samples; drop the 6 for all 36
|
||||||
bash scripts/fetch_data.sh p0 # ~1.4 GB of public test data → data/
|
|
||||||
bash scripts/make_oracle_gtcs.sh # builds gtc2vcf, writes oracle GTCs
|
|
||||||
bash scripts/make_oracle_qc.sh # locus-summary oracle (BeadArrayFiles, separate venv)
|
|
||||||
bash scripts/fetch_data.sh p6 # GRCh38 FASTA (~0.9 GB download, 3.1 GB unpacked)
|
|
||||||
bash scripts/make_oracle_vcf.sh # gtc2vcf oracle VCF for the P6 tests
|
|
||||||
uv run pytest tests/oracle # real-data acceptance tests (add -m "not slow" to skip the long ones)
|
|
||||||
uv run simurg inspect data/p0/gsa_v4_pgx/idats_Demo_36/idats_Demo_36/207895980019/207895980019_R03C01_Grn.idat
|
|
||||||
bash examples/gsa_demo.sh results/gsa_demo 6 # end-to-end run on 6 demo samples
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Vendor data files are downloaded for personal research use only and are never committed. See `THIRD_PARTY_NOTICES.md`.
|
The demo writes GTCs, a sample summary, an HTML QC report, per sample VCFs and a cohort BCF, PLINK files, bedGraph
|
||||||
|
tracks and a final report to `results/gsa_demo/`. On a Raspberry Pi 5 the whole demo for all 36 samples (genotyping, QC report, VCFs and exports) takes about ten minutes with two workers.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Every command prints its options with `simurg COMMAND --help`. Global options on every command: `--quiet`,
|
||||||
|
`--log-level`, `--log-json` (JSON Lines on stderr) and `--debug`.
|
||||||
|
|
||||||
|
### Look inside files
|
||||||
|
|
||||||
|
```bash
|
||||||
|
simurg inspect idats/204112350001_R01C01_Grn.idat GSA.bpm GSA.egt
|
||||||
|
simurg inspect run/gtc/samples/S1/S1.gtc --json
|
||||||
|
```
|
||||||
|
|
||||||
|
### Genotype: IDAT → GTC
|
||||||
|
|
||||||
|
```bash
|
||||||
|
simurg genotype --bpm GSA.bpm --egt GSA.egt --csv GSA.csv \
|
||||||
|
--idats idats/ --sheet SampleSheet.csv --out run/gtc --threads 0
|
||||||
|
```
|
||||||
|
|
||||||
|
* `--threads 0` uses every core. On an 8 GB machine keep it at 2 or 3.
|
||||||
|
* `--preset current` (default) behaves like the current vendor software; `--preset autocall-1.6.2` reproduces
|
||||||
|
the legacy AutoCall GTCs. `--cutoff` sets the GenCall no call threshold (0.15).
|
||||||
|
* Writes one GTC per sample, `sample_summary.tsv`, control probe QC (`controls_qc.tsv`), relatedness, and
|
||||||
|
`run_manifest.json` with every version, option and input checksum.
|
||||||
|
|
||||||
|
### Quality control
|
||||||
|
|
||||||
|
```bash
|
||||||
|
simurg qc report --data run/gtc --out run/qc_report --output-format both # HTML report + xlsx/csv table
|
||||||
|
simurg qc samples --bpm GSA.bpm --gtcs run/gtc --out run/qc
|
||||||
|
simurg qc contamination --bpm GSA.bpm --gtcs run/gtc --out run/qc
|
||||||
|
simurg qc relatedness --bpm GSA.bpm --gtcs run/gtc --sheet SampleSheet.csv --out run/qc
|
||||||
|
simurg qc loci --bpm GSA.bpm --egt GSA.egt --gtcs run/gtc --out run/qc
|
||||||
|
simurg qc controls --array-type genotyping --idats idats/ --out run/controls # no genotyping needed
|
||||||
|
simurg qc suggest-thresholds --data run/gtc --out thresholds.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
The HTML report is a single file you can share: linked views, a thresholds editor, chip and plate heatmaps, trend
|
||||||
|
plots and a PCA card. Use `--no-metadata` or `--drop-metadata COL` before sharing reports with sample sheet columns.
|
||||||
|
|
||||||
|
### VCF and exports
|
||||||
|
|
||||||
|
```bash
|
||||||
|
simurg gtc-to-vcf --bpm GSA.bpm --csv GSA.csv --fasta GRCh38.fa --gtcs run/gtc --out run/vcf # per sample
|
||||||
|
simurg gtc-to-vcf --bpm GSA.bpm --csv GSA.csv --fasta GRCh38.fa --gtcs run/gtc --out run/bcf --merge # one cohort BCF
|
||||||
|
simurg export plink --vcfs run/vcf --gtcs run/gtc --out run/plink --format both # .bed/.bim/.fam + .pgen/.pvar/.psam
|
||||||
|
simurg export bedgraph --bpm GSA.bpm --gtcs run/gtc --out run/tracks --chrom-style ucsc
|
||||||
|
simurg export finalreport --bpm GSA.bpm --csv GSA.csv --egt GSA.egt --gtcs run/gtc --out run/report # --matrix for loci × samples
|
||||||
|
```
|
||||||
|
|
||||||
|
Useful `gtc-to-vcf` options: `--info-fields`, `--extra-format`, `--merge-snv-indel`, `--auxiliary-loci`,
|
||||||
|
`--filter-gs`, `--drop-ambiguous`, `--ploidy-policy sex-aware|diploid`, `--include-loci` and `--exclude-loci`.
|
||||||
|
|
||||||
|
### Train your own cluster file (ArrayTrain)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
simurg train --gtcs cohort_gtc --bpm GSA.bpm --out mycohort.egt # at least 100 GTCs
|
||||||
|
simurg genotype --bpm GSA.bpm --egt mycohort.egt --idats new_idats/ --out run2/gtc
|
||||||
|
```
|
||||||
|
|
||||||
|
Training reads raw intensities, not genotypes, so it does not matter which cluster file the cohort was first
|
||||||
|
called with. Samples are chosen by sex for X and Y loci. See `docs/validation/V2_arraytrain.md`.
|
||||||
|
|
||||||
|
### Copy number, LOH and mosaicism
|
||||||
|
|
||||||
|
```bash
|
||||||
|
simurg cn build-model --bpm GSA.bpm --fasta GRCh38.fa --egt GSA.egt --reference-gtcs normals/ --out gsa.simurg-cyto
|
||||||
|
simurg cn call --bpm GSA.bpm --model gsa.simurg-cyto --gtcs run/gtc --fasta GRCh38.fa --out run/cn
|
||||||
|
simurg cn annotate --vcfs run/cn
|
||||||
|
```
|
||||||
|
|
||||||
|
Build the model once per manifest and batch from at least 24 normal samples. Each sample gets a CNV VCF,
|
||||||
|
a segments file and, after `annotate`, ISCN strings with cytobands and genes.
|
||||||
|
|
||||||
|
### Pharmacogenomics (GRCh38)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bash scripts/pgx/fetch_sources.sh # CPIC, PharmVar, ClinPGx → data/pgx/sources
|
||||||
|
simurg pgx db build --sources data/pgx/sources --fasta GRCh38.fa --manifests GSA_PGx.bpm --csv GSA_PGx.csv --out pgxdb/
|
||||||
|
simurg pgx coverage --bpm GSA_PGx.bpm --db pgxdb/pgx_db.sqlite # which alleles this array can call
|
||||||
|
simurg pgx copy-number train --gtcs cohort/ --bpm GSA_PGx.bpm --csv GSA_PGx.csv --fasta GRCh38.fa --out cnmodel/
|
||||||
|
simurg pgx copy-number call --gtcs run/gtc --model cnmodel/GSA_PGx.simurg-pgxcn --fasta GRCh38.fa --out run/vcf
|
||||||
|
simurg gtc-to-vcf --gtcs run/gtc --bpm GSA_PGx.bpm --csv GSA_PGx.csv --fasta GRCh38.fa --out run/vcf
|
||||||
|
simurg pgx star-allele call --vcfs run/vcf --db pgxdb/pgx_db.sqlite --out run/pgx
|
||||||
|
simurg pgx phenotype --calls run/pgx --db pgxdb/pgx_db.sqlite --guideline cpic # or dpwg
|
||||||
|
```
|
||||||
|
|
||||||
|
`pgx db build` names the database after its content hash (`pgx_db-1-<sha12>.sqlite`); use that file name.
|
||||||
|
Copy number training needs at least 96 samples. Outputs per sample: diplotypes, supporting and missing variants,
|
||||||
|
alternative diplotypes the array cannot tell apart, and a JSON report with phenotype and evidence.
|
||||||
|
|
||||||
|
### Methylation arrays
|
||||||
|
|
||||||
|
```bash
|
||||||
|
simurg methyl qc --manifest EPIC_manifest.csv --idats idats/ --sheet SampleSheet.csv --out run/methyl --profile auto
|
||||||
|
simurg methyl convert-manifest --manifest EPIC_manifest.csv --out manifest_tables/
|
||||||
|
```
|
||||||
|
|
||||||
|
### Compare two runs
|
||||||
|
|
||||||
|
```bash
|
||||||
|
simurg compare runA/gtc runB/gtc --out compare_report --fail-on-discrepancy
|
||||||
|
```
|
||||||
|
|
||||||
|
Every field of every GTC or VCF pair is compared. `compare_report/dashboard.html` shows the result and
|
||||||
|
`discrepancies.tsv.gz` lists every difference.
|
||||||
|
|
||||||
|
### Exit codes
|
||||||
|
|
||||||
|
`0` success · `1` internal error · `2` usage or validation error (nothing processed) · `3` some samples failed, or
|
||||||
|
`compare --fail-on-discrepancy` found differences · `4` no sample succeeded · `130`/`143` interrupted.
|
||||||
|
Every error and warning has a stable code (`E_…`, `W_…`) listed in `docs/messages.md`.
|
||||||
|
|
||||||
|
## Outputs at a glance
|
||||||
|
|
||||||
|
| Step | Main files |
|
||||||
|
|---|---|
|
||||||
|
| `genotype` | `samples/<id>/<id>.gtc`, `sample_summary.tsv`, `controls_qc.tsv`, `relatedness.tsv`, `run_manifest.json` |
|
||||||
|
| `qc samples` | `sample_qc.tsv`, `contamination.tsv`, `relatedness.tsv` (+ `mendel.tsv` with parents in the sheet) |
|
||||||
|
| `qc report` | `qc_report_<date>.html`, `qc_table_<date>.xlsx` |
|
||||||
|
| `gtc-to-vcf` | `<id>.snv.vcf.gz` + `.tbi`, or `cohort.snv.bcf` + `.csi` |
|
||||||
|
| `export plink` | `.bed/.bim/.fam`, `.pgen/.pvar/.psam` |
|
||||||
|
| `cn call` | `<id>.cyto.cnv.vcf.gz`, `<id>.cn_segments.parquet`, `cn_sample_summary.tsv` |
|
||||||
|
| `pgx phenotype` | `<id>.pgx.json`, `diplotype_summary.tsv`, `diplotype_annotations.tsv` |
|
||||||
|
| `train` | `<name>.egt`, `<name>.egt.json` |
|
||||||
|
|
||||||
|
Every HTML report carries the software version and a checksum of the data it shows.
|
||||||
|
|
||||||
|
## Performance and memory
|
||||||
|
|
||||||
|
* With the kernels a GSA sample takes about 1.1 s on one Raspberry Pi 5 core (3.4 s pure Python) and a server core
|
||||||
|
handles about 80 samples a minute (`docs/validation/P9.md`).
|
||||||
|
* Loading a manifest is a fixed cost per command: about 4 s for GSA and 18 s for Omni2.5 on a Pi with the kernels.
|
||||||
|
* Cohort QC steps grow with samples × loci. On small machines use `--threads 2`, and `--no-cohort-qc` on very
|
||||||
|
large `genotype` runs, then run the `qc` commands separately.
|
||||||
|
* `simurg train` needs about 2 GB for 120 GSA samples and takes about 70 minutes on a Pi.
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
```bash
|
||||||
|
uv venv && uv pip install -e ".[dev]"
|
||||||
|
uv run ruff check . && uv run ruff format --check .
|
||||||
|
uv run mypy
|
||||||
|
uv run pytest tests/unit # no downloads needed
|
||||||
|
```
|
||||||
|
|
||||||
|
Oracle tests compare against reference tools on real public data:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bash scripts/bootstrap_refs.sh # reference open source repositories → refs/
|
||||||
|
bash scripts/fetch_data.sh p0 # public test data → data/
|
||||||
|
bash scripts/make_oracle_gtcs.sh # builds gtc2vcf and writes oracle GTCs
|
||||||
|
bash scripts/make_oracle_qc.sh # locus summary oracle (BeadArrayFiles)
|
||||||
|
bash scripts/fetch_data.sh p6 && bash scripts/make_oracle_vcf.sh
|
||||||
|
uv run pytest tests/oracle # add -m "not slow" to skip the long ones
|
||||||
|
```
|
||||||
|
|
||||||
|
Before publishing text with numbers, `python scripts/docs/check_claims.py FILES` checks every claim against the
|
||||||
|
validation reports (see `CONTRIBUTING.md`).
|
||||||
|
|
||||||
|
CI runs lint, type checks, a secret scan and the unit tests with and without the Rust kernels on Python 3.12 and
|
||||||
|
3.13 for every push. `scripts/nightly.py` reruns the differential tests against the oracles.
|
||||||
|
|
||||||
|
## Repository layout
|
||||||
|
|
||||||
|
```
|
||||||
|
src/simurg/ the package: formats, signal, genotype, qc, harmonize, cn, pgx, train, pipeline, cli
|
||||||
|
rust/simurg-core/ optional compiled kernels (PyO3)
|
||||||
|
tests/ unit and oracle tests
|
||||||
|
scripts/ data fetchers, oracle builders, validation and cloud helpers, brand and blog image scripts
|
||||||
|
docs/ user guide, messages, validation reports, known unknowns
|
||||||
|
examples/ end to end demo
|
||||||
|
branding/ logo, icons, templates and the brand guide
|
||||||
|
blog/ five posts about the project, with featured images
|
||||||
|
packaging/ conda recipes (plus Dockerfile at the root)
|
||||||
|
.gitea/ CI workflow, issue and pull request templates
|
||||||
|
```
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
* [`docs/user_guide.md`](docs/user_guide.md): every command in detail, presets, QC, outputs, accuracy, limits, troubleshooting
|
||||||
|
* [`SIMURGARRAY_FUNCTIONAL_SPEC.md`](SIMURGARRAY_FUNCTIONAL_SPEC.md): 416 numbered requirements (CLI, inputs, outputs, QC, CN, PGx, methylation, edge cases)
|
||||||
|
* [`SIMURGARRAY_MASTER_PLAN.md`](SIMURGARRAY_MASTER_PLAN.md): architecture, algorithms with their sources, roadmap
|
||||||
|
* [`docs/validation/`](docs/validation/): one report per phase and module
|
||||||
|
* [`docs/known_unknowns.md`](docs/known_unknowns.md): every difference from reference tools, with dates and explanations
|
||||||
|
* [`docs/messages.md`](docs/messages.md): all error and warning codes
|
||||||
|
* [`CONTRIBUTING.md`](CONTRIBUTING.md), [`SECURITY.md`](SECURITY.md), [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md)
|
||||||
|
* [`branding/README.md`](branding/README.md) and [`blog/`](blog/)
|
||||||
|
|
||||||
|
## Feedback and support
|
||||||
|
|
||||||
|
Bug reports and feature requests go to the [issue tracker](https://gitea.yaylali.uk/kemal/SimurgArray/issues), using
|
||||||
|
the templates. Questions, feedback and anything that should not be public, such as security reports, go to
|
||||||
|
**[email protected]**.
|
||||||
|
|
||||||
|
## Citing
|
||||||
|
|
||||||
|
If SimurgArray helps your research, please cite it using [`CITATION.cff`](CITATION.cff) (version 2.0.0, 2026).
|
||||||
|
|
||||||
|
## Licence, data and trademarks
|
||||||
|
|
||||||
|
SimurgArray is released under the [MIT licence](LICENSE). Code adapted from MIT, BSD and Apache licensed projects
|
||||||
|
is credited in [`THIRD_PARTY_NOTICES.md`](THIRD_PARTY_NOTICES.md); GPL tools are only run as separate programs for
|
||||||
|
comparison. Brand artwork is CC BY 4.0.
|
||||||
|
|
||||||
|
Vendor manifests, cluster files and scan data are downloaded by each user for their own research and are never
|
||||||
|
part of this repository. PGx sources keep their own terms (CPIC CC0, PharmVar terms of use, ClinPGx CC BY SA 4.0);
|
||||||
|
SimurgArray ships the database builder, not the database.
|
||||||
|
|
||||||
|
Illumina, Infinium, GenCall, GenTrain and GenomeStudio are trademarks of Illumina, Inc. SimurgArray is an
|
||||||
|
independent project, not affiliated with or endorsed by Illumina.
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
# Security policy
|
||||||
|
|
||||||
|
## Supported versions
|
||||||
|
|
||||||
|
Security fixes go into the latest release. Older releases are not patched; upgrade to the newest version.
|
||||||
|
|
||||||
|
## Reporting a vulnerability
|
||||||
|
|
||||||
|
Please do not open a public issue for a security problem. Write privately to **[email protected]** and include:
|
||||||
|
|
||||||
|
* the SimurgArray version (`simurg --version`),
|
||||||
|
* what an attacker could do and under which conditions,
|
||||||
|
* the smallest input or command that shows the problem, without real genetic data.
|
||||||
|
|
||||||
|
You will get an answer within a week. Once a fix is released, the report is credited in `CHANGELOG.md` unless you
|
||||||
|
prefer otherwise.
|
||||||
|
|
||||||
|
## What counts
|
||||||
|
|
||||||
|
SimurgArray reads files that users download from third parties. Problems worth reporting include:
|
||||||
|
|
||||||
|
* crafted IDAT, BPM, CSV, EGT, GTC, VCF or sample sheet files that crash the reader in an unsafe way, write outside
|
||||||
|
the output folder, or execute code;
|
||||||
|
* HTML reports that run script from their input data (reports are meant to be safe to open and share);
|
||||||
|
* anything that could leak sample sheet metadata or genetic data beyond what the user chose to include.
|
||||||
|
|
||||||
|
## Handling genetic data
|
||||||
|
|
||||||
|
Genotype data are personal data. SimurgArray never sends data anywhere: it has no network access at run time and
|
||||||
|
its reports embed everything they need. Users are responsible for storing and sharing outputs according to their
|
||||||
|
consent and data protection rules. The QC report offers `--no-metadata`, `--drop-metadata` and `--keep-metadata` to
|
||||||
|
control what it contains.
|
||||||
@@ -2435,6 +2435,23 @@ about **algorithms or numerics**, the plan wins. Each such conflict found during
|
|||||||
|
|
||||||
Each yields valid, possibly empty, VCF and JSON output (EDGE-024). (src: E-35)
|
Each yields valid, possibly empty, VCF and JSON output (EDGE-024). (src: E-35)
|
||||||
|
|
||||||
|
- **CYTO-041** `§10.3 · v2` **MF refinements [OURS].** Two refinements of CYTO-018, from real-data validation
|
||||||
|
(docs/validation/V2_cn.md, K-027):
|
||||||
|
- *noise-corrected split:* per-probe expected noise σ_i = the reference's heterozygous BAF spread of the probe ×
|
||||||
|
the sample's scale (median |BAF − 0.5| / spread over autosomal heterozygous calls, ÷ 0.6745; the sample's
|
||||||
|
heterozygous BAF SD without a reference spread). Over the event's heterozygous calls, m = median(|BAF − 0.5| /
|
||||||
|
σ_i); the split in σ units δ solves Φ(m − δ) − Φ(−m − δ) = ½ (δ = 0 when m ≤ 0.6745) and d = median(σ_i)·δ.
|
||||||
|
Without this, noise alone gave MF ≈ 0.1–0.3 and genomic waves were called as mosaic losses.
|
||||||
|
- *complete loss:* a mosaic loss whose called genotypes hold fewer than a quarter of the heterozygotes the PFB
|
||||||
|
predicts (Σ 2p(1−p) ≥ 3) has MF = 1. With the default `--max-mosaic-fraction 1.0` it is therefore promoted
|
||||||
|
(CYTO-020) to a constitutional DEL with `HIGHFRACTION`. This catches constitutional deletions whose LRR is
|
||||||
|
compressed towards the mosaic states.
|
||||||
|
|
||||||
|
- **CYTO-042** `§10.2 · v2` **Per-probe LRR noise [OURS].** A model built with `--reference-gtcs` stores each
|
||||||
|
probe's robust LRR SD across the reference (1.4826·MAD after removing each sample's median and the probe's
|
||||||
|
reference median). `cn call` scales the sample's LRR emission SD per probe by that spread relative to the autosomal
|
||||||
|
median spread, clipped to [0.5, 3]. Without the column, or with `--no-probe-lrr-sd`, every probe uses the sample SD.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 7. Targeted PGx copy number (v2)
|
## 7. Targeted PGx copy number (v2)
|
||||||
@@ -2742,7 +2759,10 @@ about **algorithms or numerics**, the plan wins. Each such conflict found during
|
|||||||
|
|
||||||
In a region whose CN is n ≠ 2, the variant copy number `k ∈ {0..n}` is the maximum-likelihood value under the
|
In a region whose CN is n ≠ 2, the variant copy number `k ∈ {0..n}` is the maximum-likelihood value under the
|
||||||
observed BAF ~ N(k/n, σ²), with σ estimated per batch from AB clusters. It is reported as `variant_copy_number`.
|
observed BAF ~ N(k/n, σ²), with σ estimated per batch from AB clusters. It is reported as `variant_copy_number`.
|
||||||
GS enters as a per-call error rate: ε(GS) = 0.5·(1 − GS)², clipped to [1e-4, 0.25] [OURS]. (src: B-30, E-41)
|
GS enters as a per-call error rate: ε = 1e-3 for GS ≥ 0.15 and 0.05 below [OURS, calibrated: after probe masking
|
||||||
|
(PGX-010), 0 of 9 740 GSA v4 PGx calls at DB variants disagreed with 1000G 30x in any GS bin, so errors are
|
||||||
|
probe-specific and belong in the mask; the earlier ε(GS) = 0.5·(1 − GS)² made correct low-GS calls such as
|
||||||
|
CYP2C9 rs1799853 at GS 0.16 lose to the prior; K-029]. (src: B-30, E-41)
|
||||||
|
|
||||||
- **PGX-013** `§11 · v2` **Candidate enumeration [DIFF: solver-free].**
|
- **PGX-013** `§11 · v2` **Candidate enumeration [DIFF: solver-free].**
|
||||||
- For each gene, SimurgArray enumerates diplotypes from the gene's haplotypes: star alleles, `*0`, duplications
|
- For each gene, SimurgArray enumerates diplotypes from the gene's haplotypes: star alleles, `*0`, duplications
|
||||||
@@ -3710,6 +3730,8 @@ Generated from the item tags (`build.py`). Phases: P0–P10 as in plan §18; `v2
|
|||||||
| CYTO-038 | Model building | §10 | v2 | A-G52 |
|
| CYTO-038 | Model building | §10 | v2 | A-G52 |
|
||||||
| CYTO-039 | Batch scale | §10, §19 | v2 | D-9, E-35 |
|
| CYTO-039 | Batch scale | §10, §19 | v2 | D-9, E-35 |
|
||||||
| CYTO-040 | Degenerate samples | §10 | v2 | E-35 |
|
| CYTO-040 | Degenerate samples | §10 | v2 | E-35 |
|
||||||
|
| CYTO-041 | MF refinements | §10.3 | v2 | K-027 |
|
||||||
|
| CYTO-042 | Per-probe LRR noise | §10.2 | v2 | K-027 |
|
||||||
| PCN-001 | Region catalogue | §11 | v2 | B-23, C-G25, D-10 |
|
| PCN-001 | Region catalogue | §11 | v2 | B-23, C-G25, D-10 |
|
||||||
| PCN-002 | Genotype every region [EMU] | §11 | v2 | B-23 |
|
| PCN-002 | Genotype every region [EMU] | §11 | v2 | B-23 |
|
||||||
| PCN-003 | Inputs | §11 | v2 | A-G37 |
|
| PCN-003 | Inputs | §11 | v2 | A-G37 |
|
||||||
|
|||||||
@@ -136,8 +136,6 @@ curl -LsSf https://astral.sh/uv/install.sh | sh
|
|||||||
uv python install 3.12
|
uv python install 3.12
|
||||||
# Rust (Phase 9)
|
# Rust (Phase 9)
|
||||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
||||||
# GitHub CLI (authenticate to avoid API rate limits)
|
|
||||||
sudo apt install -y gh && gh auth login
|
|
||||||
# Reference/oracle tools (subprocess only)
|
# Reference/oracle tools (subprocess only)
|
||||||
# gtc2vcf plugins for bcftools: build from https://github.com/freeseek/gtc2vcf (instructions in its README)
|
# gtc2vcf plugins for bcftools: build from https://github.com/freeseek/gtc2vcf (instructions in its README)
|
||||||
# plink2: https://www.cog-genomics.org/plink/2.0/
|
# plink2: https://www.cog-genomics.org/plink/2.0/
|
||||||
@@ -162,7 +160,7 @@ sudo apt install -y gh && gh auth login
|
|||||||
| maturin + PyO3 (Phase 9) | Rust extension |
|
| maturin + PyO3 (Phase 9) | Rust extension |
|
||||||
|
|
||||||
### 3.5 Moving the project
|
### 3.5 Moving the project
|
||||||
The canonical repository is the private Gitea repo **https://gitea.yaylali.uk/kemal/SimurgArray**.
|
The canonical repository is the Gitea repo **https://gitea.yaylali.uk/kemal/SimurgArray**.
|
||||||
```bash
|
```bash
|
||||||
# on the new machine
|
# on the new machine
|
||||||
git clone https://gitea.yaylali.uk/kemal/SimurgArray.git && cd SimurgArray
|
git clone https://gitea.yaylali.uk/kemal/SimurgArray.git && cd SimurgArray
|
||||||
@@ -218,7 +216,6 @@ simurg/
|
|||||||
├── tests/
|
├── tests/
|
||||||
│ ├── unit/ property/ integration/ regression/ oracle/ perf/
|
│ ├── unit/ property/ integration/ regression/ oracle/ perf/
|
||||||
│ └── fixtures/ # ONLY redistributable data (Bioconductor Artistic-2.0 files, synthetic)
|
│ └── fixtures/ # ONLY redistributable data (Bioconductor Artistic-2.0 files, synthetic)
|
||||||
├── bench/
|
|
||||||
├── docs/ # user guide, algorithm notes, validation reports
|
├── docs/ # user guide, algorithm notes, validation reports
|
||||||
├── refs/ # (git-ignored) cloned third-party repos
|
├── refs/ # (git-ignored) cloned third-party repos
|
||||||
└── data/ # (git-ignored) downloaded datasets
|
└── data/ # (git-ignored) downloaded datasets
|
||||||
|
|||||||
@@ -12,7 +12,15 @@ used only as external subprocess oracles and are not copied or linked.
|
|||||||
| [klib `ksort.h`](https://github.com/attractivechaos/klib) as shipped in htslib — Copyright (c) 2008, 2012-2013, 2017-2019 Genome Research Ltd | MIT | Quickselect `ks_ksmall` partition order, ported to `simurg/qc/contamination.py` (`ks_ksmall`) to reproduce BAFregress medians |
|
| [klib `ksort.h`](https://github.com/attractivechaos/klib) as shipped in htslib — Copyright (c) 2008, 2012-2013, 2017-2019 Genome Research Ltd | MIT | Quickselect `ks_ksmall` partition order, ported to `simurg/qc/contamination.py` (`ks_ksmall`) to reproduce BAFregress medians |
|
||||||
| [Illumina GTCtoVCF](https://github.com/Illumina/GTCtoVCF) — Copyright Illumina, Inc. | Apache-2.0 | Indel source-sequence handling ported to `simurg/harmonize/sites.py` (design-strand orientation, left shift, IUPAC flank matching, deletion/insertion context score); multi-probe consistency idea in `simurg/harmonize/combine.py`; test oracle (run under Python 3 with two local compatibility patches, never shipped) |
|
| [Illumina GTCtoVCF](https://github.com/Illumina/GTCtoVCF) — Copyright Illumina, Inc. | Apache-2.0 | Indel source-sequence handling ported to `simurg/harmonize/sites.py` (design-strand orientation, left shift, IUPAC flank matching, deletion/insertion context score); multi-probe consistency idea in `simurg/harmonize/combine.py`; test oracle (run under Python 3 with two local compatibility patches, never shipped) |
|
||||||
| [Picard `picard.arrays`](https://github.com/broadinstitute/picard) | MIT | Second format reference |
|
| [Picard `picard.arrays`](https://github.com/broadinstitute/picard) | MIT | Second format reference |
|
||||||
|
| [PyO3](https://github.com/PyO3/pyo3), [rust-numpy](https://github.com/PyO3/rust-numpy), [ndarray](https://github.com/rust-ndarray/ndarray) and their Rust dependencies | MIT / Apache-2.0 / BSD-2-Clause | Compiled into the optional `simurg_core` extension (`rust/simurg-core`); list with `cargo tree` |
|
||||||
|
| [UCSC Genome Browser](https://genome.ucsc.edu/) `cytoBand` tables (hg38, hg19) and `ncbiRefSeq` (RefSeq transcripts, NCBI) | Free for all uses (UCSC data terms; RefSeq is public domain) | `simurg/cn/data/cytoBand_GRCh3{7,8}.txt.gz` and the derived centromere/acrocentric mask BEDs are shipped; `scripts/build_annotation_bundle.sh` downloads cytoBand + ncbiRefSeq for gene lists; `simurg/pgx/data/pgx_cn_regions.GRCh38.v1.bed` is derived from ncbiRefSeq exon coordinates (`scripts/pgx/build_cn_regions.py`) |
|
||||||
| [illuminaio](https://github.com/HenrikBengtsson/illuminaio) | GPL-2 | Documentation of IDAT field codes only; oracle via subprocess |
|
| [illuminaio](https://github.com/HenrikBengtsson/illuminaio) | GPL-2 | Documentation of IDAT field codes only; oracle via subprocess |
|
||||||
|
| [CPIC](https://cpicpgx.org) database via the CPIC API (allele definitions, allele function, diplotype→phenotype tables) | CC0 1.0 | downloaded by `scripts/pgx/fetch_sources.sh` into `data/` (never committed); `simurg pgx db build` derives the local PGx DB from it; source version and file hashes are recorded in the DB `meta` table |
|
||||||
|
| [PharmVar](https://www.pharmvar.org) haplotype definitions (Gaedigk et al. 2018 CPT 103:399) | PharmVar terms of use (attribution) | per-gene zips downloaded by `scripts/pgx/fetch_sources.sh` into `data/` (never committed); `simurg pgx db build` derives core-allele definitions for genes CPIC does not define |
|
||||||
|
| [GeT-RM](https://www.cdc.gov/lab-quality/php/get-rm/reference-materials.html) consolidated PGx/HLA table (CDC) | US government work | validation truth only (`scripts/pgx/getrm_truth.py`), not redistributed |
|
||||||
|
| [ClinPGx](https://www.clinpgx.org) (formerly PharmGKB) clinical-annotation variants | CC BY-SA 4.0 (attribution: ClinPGx, https://www.clinpgx.org/page/citingClinpgx) | `clinicalVariants.zip` downloaded by `scripts/pgx/fetch_sources.sh` into `data/` (never committed); rsIDs become genotype-only variant-based genes in the local PGx DB |
|
||||||
|
| [Noto Sans, Noto Sans Mono](https://fonts.google.com/noto) — Copyright 2022 The Noto Project Authors | SIL Open Font License 1.1 | Glyph outlines of the wordmark in `branding/logo/` (converted to SVG paths by `scripts/brand/make_brand.py`); named in report CSS but never bundled |
|
||||||
|
| Okabe and Ito colour-universal-design palette (Okabe & Ito 2008, *Color Universal Design*) | free to use (cited) | Chart colours in `simurg/core/brand.py` and the HTML reports |
|
||||||
|
|
||||||
## BSD-2-Clause (BeadArrayFiles, verbatim from its README)
|
## BSD-2-Clause (BeadArrayFiles, verbatim from its README)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
# Why SimurgArray should exist
|
||||||
|
|
||||||
|
*Part 1 of 5. Kemal Yaylali, September 2026*
|
||||||
|
|
||||||
|
Every genotyping array tells a small story before it tells you anything about DNA. A glass slide goes into a scanner, the scanner writes two IDAT files per sample (one red, one green), and a few hundred thousand bead intensities wait for someone to turn them into genotypes. That someone is almost always a piece of closed software. You click, it thinks, and out come the calls.
|
||||||
|
|
||||||
|
For most people this is perfectly fine. The calls are good. The labs are busy. Nobody has time to ask how a pair of numbers became "AB".
|
||||||
|
|
||||||
|
I had the time, and I had the question. SimurgArray is the answer I ended up writing.
|
||||||
|
|
||||||
|
## The black box in the middle
|
||||||
|
|
||||||
|
Illumina Infinium arrays are everywhere. Biobanks use them, consumer genetics companies use them, research groups use them because they are cheap per sample and wonderfully boring in the best sense: they work. Hundreds of millions of people have been genotyped this way.
|
||||||
|
|
||||||
|
The pipeline is conceptually simple:
|
||||||
|
|
||||||
|
1. Read the raw intensities from the IDAT files.
|
||||||
|
2. Normalize them, because the red and green channels never quite agree with each other.
|
||||||
|
3. Compare each sample to a cluster file (an EGT) that says where AA, AB and BB usually sit.
|
||||||
|
4. Call genotypes, give each call a score, and write everything to a GTC file.
|
||||||
|
5. Turn that into something the rest of the world reads, usually a VCF.
|
||||||
|
|
||||||
|
Steps 1 to 4 are where the interesting decisions live, and they have historically been done by software you can run but cannot read. Good open tools exist around the edges, and I will talk about them in the next post, but I could not find one place where the whole chain was open, tested against the vendor's own outputs, and documented well enough that a stranger could check every step.
|
||||||
|
|
||||||
|
So I built that place.
|
||||||
|
|
||||||
|
## What SimurgArray actually is
|
||||||
|
|
||||||
|
SimurgArray is a personal research toolkit that takes IDAT files all the way to QC reports, VCF and PLINK files, and then keeps going:
|
||||||
|
|
||||||
|
* Genotype calling that reproduces the vendor's GTC files byte for byte in 2138 of 2141 public 1000 Genomes Omni2.5 samples. The last three are documented, not hidden.
|
||||||
|
* Sample and control QC with an HTML report you can actually click around in.
|
||||||
|
* Copy number, loss of heterozygosity and mosaicism calling across the genome.
|
||||||
|
* Pharmacogenomics: targeted copy number for genes like CYP2D6, star allele diplotypes and CPIC phenotypes.
|
||||||
|
* Methylation array control QC.
|
||||||
|
* ArrayTrain, which builds your own cluster file from your own cohort, so you are not forever borrowing someone else's.
|
||||||
|
|
||||||
|
Everything is specified item by item in a functional spec with 416 numbered requirements, and every algorithm points to where it came from: a paper, a public technical note, an expired patent, or an open source project with a compatible license. When our numbers differ from a reference tool, the difference goes into a file called `known_unknowns.md` with a date and an explanation. Thirty entries so far. Some of them are my favorite reading.
|
||||||
|
|
||||||
|
## Reason one: you should be able to check
|
||||||
|
|
||||||
|
Science has a slightly awkward relationship with tools it cannot inspect. We publish methods sections that say "genotypes were called with the manufacturer's software, default settings", and everybody nods, because what else would you say?
|
||||||
|
|
||||||
|
The problem shows up later. A cluster file that does not match your chips. A normalization version that changed between releases. A sex check that disagrees with the pedigree in 12 samples out of two thousand. With a black box you can only shrug. With open code you can open the file, find the line, and write down what happened.
|
||||||
|
|
||||||
|
SimurgArray was built around that idea. It has a differential testing harness that compares our outputs with reference tools field by field and labels each difference as exact, near, discrepancy or unknown. A nightly job runs it again at 02:30, when the Raspberry Pi has nothing better to do and the rest of the house is asleep.
|
||||||
|
|
||||||
|
## Reason two: the cluster file problem
|
||||||
|
|
||||||
|
Here is something that surprised me more than it should have. Genotype calls depend heavily on the cluster file, and the cluster file was trained by someone else, on samples you have never seen, possibly for a slightly different version of your chip.
|
||||||
|
|
||||||
|
On a public dataset of 360 GSA arrays I worked with, the only public cluster file available was made for a sibling chip. It works, mostly. The quality metrics politely complain the whole time.
|
||||||
|
|
||||||
|
With ArrayTrain you can train a cluster file from your own cohort. On that dataset, a cluster file trained from 120 arrays gave 99.44 % concordance with 30x whole genome sequencing, against 99.46 % for the vendor's file, while calling more genotypes. That is not a victory lap. It is a proof that the dependency is optional, which is a different and, I think, more useful thing.
|
||||||
|
|
||||||
|
## Reason three: it should run on a small computer
|
||||||
|
|
||||||
|
A lot of genomics software quietly assumes a server room. SimurgArray was developed and mostly validated on a Raspberry Pi 5 with 8 GB of memory. Heavy jobs run inside a memory guard, because I learned the hard way what happens when the kernel has to choose between my test suite and my web browser. The browser lost. So did the test suite, actually.
|
||||||
|
|
||||||
|
With the optional Rust kernels a GSA sample takes about a second on a single Pi core. On a cloud server core it is roughly 80 samples a minute. The few cloud validation runs I needed cost a few dollars in total, and every one of them was set to switch itself off and was checked afterwards to make sure nothing kept billing quietly in the background.
|
||||||
|
|
||||||
|
I care about this because the people who would benefit most from open array analysis are often the ones with the least infrastructure. More on that in part 3.
|
||||||
|
|
||||||
|
## Reason four: understanding is a feature
|
||||||
|
|
||||||
|
There is a kind of knowledge you only get by rebuilding something. I now know why the normalization uses the exact float operations it uses, why a median of an even number of values is not always the median you expect, and why a NaN can have a sign depending on which processor produced it. None of this is glamorous. All of it matters if you want two programs to agree to the last bit.
|
||||||
|
|
||||||
|
That understanding is now written down, in code and in documents, where it can outlive my own memory of it. Given how my memory works, that is a real advantage.
|
||||||
|
|
||||||
|
## What it is not
|
||||||
|
|
||||||
|
SimurgArray is a research tool. It is not a medical device, it is not for diagnosis, and its pharmacogenomics output is not a prescription. I say this plainly because PGx reports look very official, and a well formatted table can be more convincing than it deserves to be.
|
||||||
|
|
||||||
|
It also does not use anything it should not. No decompiled binaries, no vendor data in the repository, no copied GPL code. Tools under the GPL are only ever called as separate programs to compare against. When I borrowed from MIT, BSD or Apache licensed projects, the credit is in `THIRD_PARTY_NOTICES.md`, word for word.
|
||||||
|
|
||||||
|
## The short version
|
||||||
|
|
||||||
|
SimurgArray exists because array genotyping is too widely used to be understood by only one company, because cluster files should be something you can make yourself, and because a curious person with a small computer should be able to follow every number from the scanner to the VCF.
|
||||||
|
|
||||||
|
In the next post I will look at what else is out there, which is quite a lot, and why I still decided to write my own. The honest answer involves both good reasons and a certain amount of stubbornness.
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
# Are there alternatives? Yes. Why build it anyway?
|
||||||
|
|
||||||
|
*Part 2 of 5. Kemal Yaylali, September 2026*
|
||||||
|
|
||||||
|
Whenever someone tells me they are writing their own genotype caller, my first instinct is to ask whether they have looked around. So it is only fair that I answer the same question about myself.
|
||||||
|
|
||||||
|
I did look around. There is a lot of good work out there. Some of it I admire, some of it I depend on, and some of it is the reason SimurgArray can check its own answers at all.
|
||||||
|
|
||||||
|
## What the vendor gives you
|
||||||
|
|
||||||
|
The array manufacturer offers its own software, and it is good at what it does.
|
||||||
|
|
||||||
|
**GenomeStudio** is the classic. A desktop application for Windows where you load a project, look at cluster plots, fix the loci that look strange and export reports. Generations of lab scientists learned arrays on it. It is free to use after registering, but it is closed, it wants a graphical desktop, and it does not scale nicely to tens of thousands of samples.
|
||||||
|
|
||||||
|
**The command line tools** (the array analysis platform and its predecessors) turn IDATs into GTC files without the graphical part. They are fast and they are the reference: when I say SimurgArray matches the vendor byte for byte, these are the outputs I mean. They are also closed, so when something looks odd you can only guess why.
|
||||||
|
|
||||||
|
**The vendor's newer analysis software** does genotyping, copy number and pharmacogenomics in one package, locally or in the cloud. I studied its public documentation closely, because it describes a sensible feature set and a clear list of outputs. It is still closed, and its licensing and platform assumptions are aimed at institutions, not at a person with a Raspberry Pi and a free evening.
|
||||||
|
|
||||||
|
None of this is a complaint. A company building good closed tools for paying customers is a normal thing. It just leaves a gap.
|
||||||
|
|
||||||
|
## What the open source world gives you
|
||||||
|
|
||||||
|
This is where it gets interesting, because several people have already done a lot of the hard work in the open.
|
||||||
|
|
||||||
|
**gtc2vcf** by Giulio Genovese is a bcftools plugin that converts GTC files (and IDATs, via an open reimplementation of the calling) into VCF. It is careful, fast and MIT licensed. SimurgArray uses it as an oracle all the time, and it helped me understand several details that the public documentation leaves out. If you only need GTC to VCF, you may not need anything else.
|
||||||
|
|
||||||
|
**MoChA**, from the same author, detects mosaic chromosomal alterations using phased BAF. It is the right tool for mosaicism in large cohorts, and it is the reason I know my own mosaic caller has a hard limit below about 20 % cell fraction without phasing.
|
||||||
|
|
||||||
|
**BeadArrayFiles** and **GTCtoVCF**, both from the vendor's own open source repositories, read the file formats and write VCF. Old, a bit dusty (GTCtoVCF needed two small patches to run on Python 3), and extremely useful as references.
|
||||||
|
|
||||||
|
**illuminaio** in Bioconductor reads IDAT files. It is GPL licensed, so SimurgArray only runs it as a separate program to compare results and never reuses its code.
|
||||||
|
|
||||||
|
**crlmm** and **Illuminus** are academic callers from the late 2000s with a real statistical model behind them. Their papers shaped how ArrayTrain thinks about clusters.
|
||||||
|
|
||||||
|
**PennCNV** and **QuantiSNP** are the long standing tools for copy number from LRR and BAF.
|
||||||
|
|
||||||
|
**PharmCAT**, **Stargazer**, **Aldy** and friends call star alleles, mostly from sequencing data or from VCFs you already have.
|
||||||
|
|
||||||
|
**sesame** and **minfi** handle methylation arrays in R, and SimurgArray's methylation QC is checked against sesame.
|
||||||
|
|
||||||
|
**PLINK 2** does everything downstream of a VCF, better than I ever would, and I would not dream of replacing it.
|
||||||
|
|
||||||
|
## So why build another one?
|
||||||
|
|
||||||
|
Because none of these, alone or together, gave me the thing I wanted: one open pipeline from raw IDAT to final report, bit exact with the vendor where that is possible, tested against every one of the tools above, and honest about where it differs.
|
||||||
|
|
||||||
|
Here are the specific reasons, in the order they occurred to me.
|
||||||
|
|
||||||
|
**The chain was broken in the middle.** You can read IDATs with one tool, convert GTCs with another, call CNVs with a third and PGx with a fourth. Each hands off to the next with its own conventions for strand, allele order, missing values and sample names. SimurgArray keeps one data model from start to finish, and every hand off is tested.
|
||||||
|
|
||||||
|
**Nobody promised to agree with the vendor to the last bit.** Close is usually fine. But close means you cannot tell a real difference from a rounding difference. Once normalization, calling and GTC writing are identical down to the byte, any remaining difference is information instead of noise. Getting there required reproducing float32 quirks, a particular median that is not quite a median, and the sign of a NaN. I am unreasonably proud of that last one.
|
||||||
|
|
||||||
|
**Cluster files were a dependency without an exit.** Every open caller I found needs a cluster file from the vendor. ArrayTrain removes that requirement. For a cohort whose ancestry is not well represented in the samples the vendor trained on, that might matter a lot. I will come back to this.
|
||||||
|
|
||||||
|
**I wanted it to run on small hardware.** Most pipelines assume a cluster or at least a workstation. SimurgArray was written on a Raspberry Pi and validated there as much as possible, with the cloud used only when a dataset simply did not fit, and even then for minutes at a time.
|
||||||
|
|
||||||
|
**I wanted a specification, not just code.** The functional spec lists 416 behaviours with IDs, from command line options to edge cases like an empty sample name column in the vendor's own template sheet. Tests cite those IDs. It sounds bureaucratic. It is actually liberating, because "is this a bug?" becomes a question with an answer.
|
||||||
|
|
||||||
|
**I wanted to learn it properly.** Reading code teaches you how something works. Reproducing it teaches you why. Several of the most interesting facts about arrays that I know now came from a test failing by one unit in the last place.
|
||||||
|
|
||||||
|
## And the stubbornness
|
||||||
|
|
||||||
|
I should be honest: there is also a bit of "how hard can it be". The answer, as usual, was "harder than that, but not impossible". The first estimate for normalization was a few weeks. The first version that matched the vendor bit for bit took longer, and taught me more about floating point contraction on ARM processors than I had planned to know.
|
||||||
|
|
||||||
|
It helped that the expired patents on the core normalization and clustering methods are public, that the technical notes are public, and that people like the authors above wrote their work down in the open. SimurgArray stands on all of that. It does not replace any of it.
|
||||||
|
|
||||||
|
## Where it fits
|
||||||
|
|
||||||
|
If you want a mature graphical tool with support, use the vendor's software. If you only need GTC to VCF, use gtc2vcf. If you want mosaicism in a biobank, use MoChA. If you want PGx from sequencing, use PharmCAT or Aldy.
|
||||||
|
|
||||||
|
If you want to go from a folder of IDAT files to genotypes, QC, CNVs, PGx and your own cluster file, on hardware you own, with every step open and every disagreement written down, SimurgArray is the tool I wish I had found when I started.
|
||||||
|
|
||||||
|
Next time: why I think this is useful beyond my own curiosity, and who might actually benefit.
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
# What good could it do?
|
||||||
|
|
||||||
|
*Part 3 of 5. Kemal Yaylali, September 2026*
|
||||||
|
|
||||||
|
"Benefit to humanity" is a big phrase for a tool that mostly reads binary files. I will try to keep this post the right size. SimurgArray will not cure anything. What it can do is lower a few barriers that currently decide who gets to do genetics research and how much of it they can trust.
|
||||||
|
|
||||||
|
Here is where I think it helps, roughly from the most certain to the most hopeful.
|
||||||
|
|
||||||
|
## 1. Reproducible science
|
||||||
|
|
||||||
|
Array genotypes feed genome wide association studies, polygenic scores, ancestry analyses and a great deal of population genetics. A lot of that work rests on a sentence like "calls were produced with the manufacturer's software". If someone wants to rerun the analysis five years later, with a different version of that software, the numbers may shift, and nobody can say exactly why.
|
||||||
|
|
||||||
|
With SimurgArray every run writes a manifest: software version, normalization version, cluster file checksum, command line, even which backend (Python or Rust) was used. The same inputs give the same bytes. And because the pipeline reproduces the vendor's GTC files exactly on public data, an old analysis can be rebuilt and compared field by field, instead of "roughly".
|
||||||
|
|
||||||
|
This is the least exciting benefit and probably the most important one.
|
||||||
|
|
||||||
|
## 2. Research where budgets are small
|
||||||
|
|
||||||
|
Genotyping arrays are the cheapest way to look at hundreds of thousands of variants in a person. That makes them the natural choice for biobanks and studies in countries where sequencing everyone is not realistic. Ironically, the analysis side is where those projects often struggle: licenses, servers, specialist staff, and software that assumes all three.
|
||||||
|
|
||||||
|
SimurgArray runs on a Raspberry Pi. I do not recommend running a national biobank on one (I did find its limits, usually around midnight), but a single ordinary server core handles about 80 GSA samples a minute. A modest machine can process a large study in an afternoon, and the software costs nothing.
|
||||||
|
|
||||||
|
The pipeline also produces the things a small team needs to trust its data without a bioinformatics department: control probe QC, sample QC, contamination estimates, relatedness, sex checks, and an HTML report that a lab person can open in a browser and actually understand.
|
||||||
|
|
||||||
|
## 3. Better calls for underrepresented populations
|
||||||
|
|
||||||
|
This is the part I find most hopeful.
|
||||||
|
|
||||||
|
A cluster file encodes where the genotype clouds sit for each SNP. It is trained on a set of samples, and those samples have ancestries. If your cohort comes from a population that was thin or absent in that training set, rare alleles that are common in your population may never have had a proper cluster. The caller then does its best with an imputed guess.
|
||||||
|
|
||||||
|
ArrayTrain lets a group train cluster files on their own samples. On public data, a cluster file trained from 120 arrays already matched the vendor's accuracy against whole genome sequencing within 0.02 percentage points, while calling more genotypes. I have only tested one cohort so far, so I will not claim more than that. But the direction is clear: the people who own the samples can own the clusters too.
|
||||||
|
|
||||||
|
## 4. Pharmacogenomics research that is open to inspection
|
||||||
|
|
||||||
|
A growing number of arrays include pharmacogenomic content, because a handful of genes (CYP2D6, CYP2C19, CYP2C9, SLCO1B1, DPYD and others) influence how people respond to common drugs. Calling star alleles from an array is tricky. CYP2D6 in particular has deletions, duplications and hybrid genes that a SNP array can only see indirectly.
|
||||||
|
|
||||||
|
SimurgArray builds its PGx database from open sources (CPIC, PharmVar, ClinPGx), calls targeted copy number, and reports diplotypes together with everything that went into them: which variants were seen, which were missing, which alternative diplotypes the array cannot tell apart. On public reference samples it agreed with the GeT RM consensus in 154 of 168 comparable gene calls, and the misses are listed and explained.
|
||||||
|
|
||||||
|
I want to be very clear here. This is research software. It is not for choosing a drug or a dose. But openness matters even for research: when an algorithm says someone is a poor metabolizer, a researcher should be able to see why, and disagree.
|
||||||
|
|
||||||
|
## 5. Copy number for rare disease research
|
||||||
|
|
||||||
|
Large deletions and duplications cause many rare diseases, and arrays are still a common first look. SimurgArray calls CNVs, loss of heterozygosity and mosaic events across the genome and writes them with ISCN style annotation.
|
||||||
|
|
||||||
|
Its honest numbers: on 360 public arrays compared with 30x sequencing, constitutional deletion calls were right far more often than mosaic ones, and rare deletions were found about 30 % of the time at the size and probe density we tested. Common CNVs are mostly invisible to the method by design, because the reference batch absorbs them. For rare disease research, rare events are the interesting ones, so that is the right trade, but it is a trade and it is written down.
|
||||||
|
|
||||||
|
## 6. Teaching
|
||||||
|
|
||||||
|
I learned more about arrays by rebuilding the pipeline than from any course. The code is written to be read. Every algorithm names its source. Every oddity the vendor has, and every place we deliberately behave differently, is documented with a date and a reason.
|
||||||
|
|
||||||
|
A student who wants to know how a genotype call happens can follow one sample through normalization, clustering and scoring, print intermediate values, and compare them with the reference tools. That used to require either a job at the company or a lot of guessing.
|
||||||
|
|
||||||
|
## 7. Keeping the ecosystem honest
|
||||||
|
|
||||||
|
Open alternatives are good for everyone, including the vendor. When a public tool can reproduce outputs exactly, differences become bug reports instead of mysteries. Several findings in `known_unknowns.md` are small documentation errors or version quirks that anyone using the official tools would benefit from knowing about.
|
||||||
|
|
||||||
|
## What it will not do
|
||||||
|
|
||||||
|
It will not replace clinical laboratories, their validated pipelines, or the people who sign reports. It will not make arrays as informative as sequencing. It will not replace the excellent open tools it builds on. And it will not make genetic data less sensitive: people who run it are responsible for handling their data properly, which the software supports with privacy options in its reports but cannot enforce.
|
||||||
|
|
||||||
|
## The small version of a big claim
|
||||||
|
|
||||||
|
If SimurgArray helps one underfunded study get cleaner genotypes, one student understand what a cluster file is, or one reviewer ask "which version of the normalization did you use?", it has done its job. The bird in its name is known for bringing many small travellers to one clear place. I will be happy if it brings a few people to a clearer view of their data.
|
||||||
|
|
||||||
|
Next time: what it would take to make SimurgArray public properly, and a realistic calendar for doing it.
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
# Going public: what it takes, and a calendar
|
||||||
|
|
||||||
|
*Part 4 of 5. Kemal Yaylali, September 2026*
|
||||||
|
|
||||||
|
Right now SimurgArray lives in a private repository on my own Git server. It has a license, a changelog, a user guide, wheels, a Docker image and a version number that just became 2.0.0. In other words, it looks public. It is not, yet.
|
||||||
|
|
||||||
|
Publishing code is easy. Publishing it responsibly is a checklist. This post is that checklist, followed by a calendar I intend to keep, give or take the usual week.
|
||||||
|
|
||||||
|
## What "public" means here
|
||||||
|
|
||||||
|
By public I mean four things:
|
||||||
|
|
||||||
|
1. The source code on my own Gitea server, open to everyone, with issues and pull requests open.
|
||||||
|
2. Installable packages: a Python wheel, the optional Rust kernel wheels, a container image and a conda recipe.
|
||||||
|
3. Documentation someone can follow without asking me anything.
|
||||||
|
4. A citable record: a DOI for each release and a short preprint describing the methods and the validation.
|
||||||
|
|
||||||
|
## The checklist
|
||||||
|
|
||||||
|
### Licensing
|
||||||
|
|
||||||
|
SimurgArray is MIT licensed. Code borrowed from other projects came only from MIT, BSD and Apache licensed sources, and their license texts sit in `THIRD_PARTY_NOTICES.md` exactly as the authors wrote them. GPL tools are only ever run as separate programs for comparison, never copied.
|
||||||
|
|
||||||
|
Before going public I will do one more pass over every file to confirm that each ported function names its origin, and that nothing slipped in during the late night sessions. Late night sessions are when things slip in.
|
||||||
|
|
||||||
|
### Data that must never be published
|
||||||
|
|
||||||
|
The repository must not contain vendor manifests, cluster files, IDATs or GTCs. The `.gitignore` has blocked them from the start, and the test fixtures are Bioconductor example files under the Artistic 2.0 license plus synthetic data. Still, "we never committed it" is a claim, and a claim deserves a check. I will scan the complete Git history, not just the current tree, for large binaries and for file types that should not be there.
|
||||||
|
|
||||||
|
The same goes for secrets. The cloud scripts use credentials from the local environment, never from files in the repository, but a full history scan for keys is cheap and embarrassment is expensive. The cloud account credentials used during development will be rotated before the switch, as a matter of principle.
|
||||||
|
|
||||||
|
### Names and trademarks
|
||||||
|
|
||||||
|
The software reads file formats defined by Illumina and reproduces the behaviour of Illumina's algorithms from public documents and expired patents. Illumina, Infinium, GenCall, GenTrain and GenomeStudio are their trademarks. The documentation will say clearly that SimurgArray is independent and not affiliated with or endorsed by the vendor, and it will use those names only to describe compatibility.
|
||||||
|
|
||||||
|
The name needed a check on the Python package index, conda channels and container registries before anything is uploaded. It turned out `simurg` on the Python package index already belongs to someone else, so the package is called `simurgarray` while the command stays `simurg`. I was sad for about an hour, which is less than I had budgeted.
|
||||||
|
|
||||||
|
### Third party data sources
|
||||||
|
|
||||||
|
The PGx database is built on the user's machine from public sources:
|
||||||
|
|
||||||
|
* CPIC (CC0),
|
||||||
|
* PharmVar (their own terms),
|
||||||
|
* ClinPGx (CC BY SA).
|
||||||
|
|
||||||
|
SimurgArray ships the builder, not the database, so each source keeps its own terms and attribution. The documentation will list those terms next to the download commands, so nobody has to find them in a footnote.
|
||||||
|
|
||||||
|
### Scope and safety language
|
||||||
|
|
||||||
|
Every README, report header and PGx output will state that the software is for research, not for diagnosis or treatment decisions. The PGx JSON already carries the database version and the evidence behind each call. That transparency is the main safety feature, but it is not a substitute for saying the obvious out loud.
|
||||||
|
|
||||||
|
### Engineering hygiene
|
||||||
|
|
||||||
|
* Continuous integration on my own Gitea runner: lint, type checks, a secret scan, and unit tests with and without the compiled kernels.
|
||||||
|
* Oracle tests that need large public datasets stay opt in, with a script that downloads everything with checksums.
|
||||||
|
* Issue templates that ask for the command, the software version and the run manifest, because "it gave a wrong genotype" is hard to debug without them.
|
||||||
|
* A contributing guide, a code of conduct and a security policy.
|
||||||
|
* A short description of the release process, so that it is not only in my head.
|
||||||
|
|
||||||
|
### Documentation
|
||||||
|
|
||||||
|
The user guide covers every command. What is missing is a gentle path for newcomers: a tutorial that starts from public IDATs (the Bioconductor fixtures and the GEO dataset used in validation), runs the whole pipeline on a laptop, and explains each output. I also want one page per validation report written for people who do not want to read a JSON file. Most people.
|
||||||
|
|
||||||
|
### Citation
|
||||||
|
|
||||||
|
Each tagged release will get a DOI through Zenodo, and the repository will carry a citation file. A preprint on bioRxiv will describe the design, the bit exact reproduction, ArrayTrain, the CN and PGx modules, and every known limitation. If it is going to be cited, it should be cited for what it actually does.
|
||||||
|
|
||||||
|
## The calendar
|
||||||
|
|
||||||
|
The weeks start on Mondays. Everything below costs nothing except time, apart from an optional domain for the documentation site.
|
||||||
|
|
||||||
|
**Week of October 5, 2026: audit**
|
||||||
|
Full history scan for vendor files and secrets. Credential rotation. Provenance pass over ported code. Trademark and disclaimer text in README, user guide and report templates.
|
||||||
|
|
||||||
|
**Week of October 12: public repository**
|
||||||
|
Open the repository to everyone on my own Gitea server, where it has lived since the first commit, with continuous integration, issue templates, a contributing guide, a code of conduct and a security policy. No mirror elsewhere: one home is easier to keep honest.
|
||||||
|
|
||||||
|
**Week of October 19: packages**
|
||||||
|
Check name availability. Upload version 2.0.0 wheels to the Python package index, the image to a public container registry, and submit the conda recipe for review.
|
||||||
|
|
||||||
|
**Weeks of October 26 and November 2: tutorial and docs site**
|
||||||
|
End to end tutorial on public data, validation summaries rewritten for humans, documentation site generated from the repository.
|
||||||
|
|
||||||
|
**Week of November 16: soft launch**
|
||||||
|
Announce to a few people who work with arrays and will not be polite about problems. Collect issues. Fix the embarrassing ones quietly and the interesting ones loudly.
|
||||||
|
|
||||||
|
**Weeks of November 30 and December 14: preprint**
|
||||||
|
Write the methods paper, rerun every validation from a clean checkout so the numbers in the paper come from the public code, deposit data summaries, submit to bioRxiv.
|
||||||
|
|
||||||
|
**Week of January 11, 2027: version 2.1**
|
||||||
|
First release shaped by other people's feedback. Likely candidates: a second cohort for ArrayTrain validation, iterative CN references for better rare event sensitivity, and anything the soft launch reveals.
|
||||||
|
|
||||||
|
After that, a steady rhythm: a minor release every two or three months, a DOI for each, and a public changelog that keeps the habit of writing down what changed and why.
|
||||||
|
|
||||||
|
## What could delay it
|
||||||
|
|
||||||
|
* **A name clash.** Solvable, mildly annoying.
|
||||||
|
* **An unexpected license question about a source.** Solvable, possibly slow.
|
||||||
|
* **Real life.** Unavoidable, frequently scheduled.
|
||||||
|
|
||||||
|
## Why announce a calendar at all
|
||||||
|
|
||||||
|
Because a public date is the best cure for "just one more feature". The software is already more complete than I planned when I started. What it needs now is other people using it, finding its mistakes and telling me which of its choices were wrong.
|
||||||
|
|
||||||
|
Next time, the last post: what using SimurgArray actually looks like, from a folder of IDATs to a report, and what the name and the bird are about.
|
||||||
@@ -0,0 +1,158 @@
|
|||||||
|
# Using SimurgArray, and the bird behind the name
|
||||||
|
|
||||||
|
*Part 5 of 5. Kemal Yaylali, September 2026*
|
||||||
|
|
||||||
|
Four posts of reasons are enough. This one is about what it looks like when you actually use the thing, and about the name, which people ask about more often than they ask about normalization. Fair enough.
|
||||||
|
|
||||||
|
One small note first. The command examples below use the usual command line options, and those start with two little lines. The prose around them does not. That is a personal style choice and I am sticking to it.
|
||||||
|
|
||||||
|
## Installing
|
||||||
|
|
||||||
|
On any Linux or macOS machine with Python 3.12:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
uv venv && uv pip install simurgarray-2.0.0-py3-none-any.whl
|
||||||
|
simurg --help
|
||||||
|
```
|
||||||
|
|
||||||
|
If you have a C compiler and Rust, you can add the optional kernels, which make the heavy steps about three times faster and produce exactly the same bytes:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
uv pip install ./rust/simurg-core
|
||||||
|
python -c "from simurg._core import backend; print(backend())"
|
||||||
|
```
|
||||||
|
|
||||||
|
There is also a Docker image and a conda recipe. The user guide covers all of them.
|
||||||
|
|
||||||
|
## A first look at your files
|
||||||
|
|
||||||
|
Before running anything, it helps to know what you have. `simurg inspect` reads any IDAT, manifest, cluster file, GTC or sample sheet and prints what is inside:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
simurg inspect idats/204112350001_R01C01_Grn.idat
|
||||||
|
simurg inspect GSA.bpm GSA.egt --json
|
||||||
|
```
|
||||||
|
|
||||||
|
This is surprisingly useful. It will tell you, for instance, that your cluster file was made for a different manifest version than your chips, which is the kind of thing you would rather know on day one.
|
||||||
|
|
||||||
|
## From IDAT to genotypes
|
||||||
|
|
||||||
|
The main event. One command reads the IDATs, normalizes them, calls genotypes against the cluster file, writes a GTC per sample, and runs the sample and control QC:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
simurg genotype --bpm GSA.bpm --egt GSA.egt --csv GSA.csv \
|
||||||
|
--idats idats/ --sheet SampleSheet.csv --out run/gtc --threads 0
|
||||||
|
```
|
||||||
|
|
||||||
|
`threads 0` means "use every core". On a Raspberry Pi 5 that is four, which is plenty for a few dozen samples while you make tea.
|
||||||
|
|
||||||
|
What you get:
|
||||||
|
|
||||||
|
* one GTC file per sample, identical to what the vendor's command line tool would produce with the same inputs,
|
||||||
|
* `sample_summary.tsv` with call rates, LogR deviation, sex estimates and flags,
|
||||||
|
* control probe metrics, contamination estimates and a relatedness table for the batch,
|
||||||
|
* a `run_manifest.json` that records every version, checksum and option used.
|
||||||
|
|
||||||
|
## Looking at the QC
|
||||||
|
|
||||||
|
```bash
|
||||||
|
simurg qc report --data run/gtc --out run/qc_report --output-format both
|
||||||
|
```
|
||||||
|
|
||||||
|
This writes a single HTML file you can email to a colleague, plus a spreadsheet. The report has linked views: select an odd looking sample in the call rate plot and it lights up in the control metrics, the sex check and the chip layout. There is a thresholds editor, so you can move a cutoff and see which samples fail before you commit to it.
|
||||||
|
|
||||||
|
My favorite part is the chip heatmap. When a whole row of a BeadChip fails together, you stop blaming the DNA and start asking about the scanner.
|
||||||
|
|
||||||
|
## To VCF and beyond
|
||||||
|
|
||||||
|
```bash
|
||||||
|
simurg gtc-to-vcf --bpm GSA.bpm --csv GSA.csv --fasta GRCh38.fa --gtcs run/gtc --out run/vcf
|
||||||
|
simurg export plink --vcfs run/vcf --gtcs run/gtc --out run/plink --format both
|
||||||
|
```
|
||||||
|
|
||||||
|
The VCFs are on the plus strand, validated with bcftools, and agree with gtc2vcf and GTCtoVCF apart from a documented list of cases where one of them cannot resolve an insertion or deletion probe. PLINK 1 and PLINK 2 files come out identical to what plink2 itself produces from the same VCFs.
|
||||||
|
|
||||||
|
## Copy number, LOH and mosaicism
|
||||||
|
|
||||||
|
Build a model once per chip and batch, from at least 24 normal samples, then call:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
simurg cn build-model --bpm GSA.bpm --fasta GRCh38.fa --egt GSA.egt \
|
||||||
|
--reference-gtcs normals/ --out gsa.simurg-cyto
|
||||||
|
simurg cn call --bpm GSA.bpm --model gsa.simurg-cyto --gtcs run/gtc --fasta GRCh38.fa --out run/cn
|
||||||
|
simurg cn annotate --vcfs run/cn
|
||||||
|
```
|
||||||
|
|
||||||
|
Each sample gets a CNV VCF with deletions, duplications, LOH and mosaic events, a segments file, and ISCN style descriptions with cytobands and genes. The sample summary flags arrays with far too many events. On the public validation set, exactly one array raised that flag, and it deserved it.
|
||||||
|
|
||||||
|
## Pharmacogenomics
|
||||||
|
|
||||||
|
Build the database from open sources, check what your array can actually see, then call:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bash scripts/pgx/fetch_sources.sh
|
||||||
|
simurg pgx db build --sources data/pgx/sources --fasta GRCh38.fa \
|
||||||
|
--manifests GSA_PGx.bpm --csv GSA_PGx.csv --out pgxdb/
|
||||||
|
simurg pgx coverage --bpm GSA_PGx.bpm --db pgxdb/pgx_db.sqlite
|
||||||
|
simurg pgx copy-number call --gtcs run/gtc --model cnmodel/GSA_PGx.simurg-pgxcn --fasta GRCh38.fa --out run/vcf
|
||||||
|
simurg pgx star-allele call --vcfs run/vcf --db pgxdb/pgx_db.sqlite --out run/pgx
|
||||||
|
simurg pgx phenotype --calls run/pgx --db pgxdb/pgx_db.sqlite
|
||||||
|
```
|
||||||
|
|
||||||
|
The coverage step is the one I would not skip. It tells you, before you look at a single sample, which alleles your array can distinguish and which it cannot. A lot of confusion about array PGx comes from asking a chip a question it was never able to answer.
|
||||||
|
|
||||||
|
For each sample you get a diplotype summary, the supporting variants, the variants that were not covered, alternative diplotypes the array cannot tell apart, and a JSON file with the phenotype and the evidence. For research, as always.
|
||||||
|
|
||||||
|
## Training your own cluster file
|
||||||
|
|
||||||
|
```bash
|
||||||
|
simurg train --gtcs cohort_gtc --bpm GSA.bpm --out mycohort.egt
|
||||||
|
simurg genotype --bpm GSA.bpm --egt mycohort.egt --idats new_idats/ --out run2/gtc
|
||||||
|
```
|
||||||
|
|
||||||
|
A hundred samples is the minimum. Training reads raw intensities, not genotypes, so it does not matter which cluster file your cohort was first called with. On the Pi, 120 GSA samples take a bit over an hour. I usually start it and go to bed, which is also how most of this project got done.
|
||||||
|
|
||||||
|
## Checking one run against another
|
||||||
|
|
||||||
|
```bash
|
||||||
|
simurg compare run/gtc other_run/gtc --out compare_report
|
||||||
|
```
|
||||||
|
|
||||||
|
Every field of every GTC or VCF is compared and labelled EXACT, NEAR, DISCREPANCY or UNKNOWN, with an HTML dashboard. This is the tool I used to build everything else, and it is the one I would miss most.
|
||||||
|
|
||||||
|
## About the name
|
||||||
|
|
||||||
|
In Persian and Turkic mythology the Simurg (Simurgh, Simorgh, depending on who is telling the story) is a great bird, old and wise, that lives on a mountain at the edge of the world. In Attar's twelfth century poem *The Conference of the Birds*, the birds of the world set out to find the Simurg and make it their king. Most give up along the way. When the survivors finally arrive, there are thirty of them, and they discover that "si murg" means "thirty birds". The Simurg they were looking for was themselves, together.
|
||||||
|
|
||||||
|
I liked the name because an array is exactly that: hundreds of thousands of tiny beads that only make sense once you look at them together. Then something happened that I did not plan. The public demo dataset I used for the pharmacogenomics validation was sold as 36 samples. When I checked identities against 1000 Genomes, it turned out to be 30 individuals.
|
||||||
|
|
||||||
|
Thirty birds. I took it as a sign that I had picked the right name, or at least a sign that I should stop looking for signs and get back to work.
|
||||||
|
|
||||||
|
## Branding
|
||||||
|
|
||||||
|
A tool for researchers does not need a marketing department, but it does need to be recognizable and consistent. Here is what I have settled on.
|
||||||
|
|
||||||
|
**Name.** SimurgArray in writing, `simurg` on the command line. Short to type, hard to mistype, and it does not collide with any genomics tool I know of.
|
||||||
|
|
||||||
|
**Tagline.** "Thirty birds, one picture." It is the whole idea in four words: many small signals, one honest result.
|
||||||
|
|
||||||
|
**Logo.** A bird in flight drawn only with dots on a square grid, the way beads sit on a BeadChip. The dots use the two scanner channels, red and green, and where they overlap the bird turns gold. It should work at 16 pixels as a favicon and at poster size, and it should look a little like a genotype cluster plot if you squint. People who work with arrays will squint.
|
||||||
|
|
||||||
|
**Colors.**
|
||||||
|
* Channel red #C8453A
|
||||||
|
* Channel green #2F8F5B
|
||||||
|
* Simurg gold #D4A017 for highlights and the bird
|
||||||
|
* Night indigo #1E2240 for backgrounds, because most of the work happened at night
|
||||||
|
* Paper #F7F5EF for documents
|
||||||
|
|
||||||
|
**Type.** A clean sans serif for text and a monospace font for anything you might paste into a terminal. Numbers in reports always use tabular figures, so columns of call rates line up.
|
||||||
|
|
||||||
|
**Voice.** Plain, exact and a little dry. Say what the software does, show the number, name the limitation in the same paragraph. No "revolutionary", no "AI powered", no promises about medicine. If a result has a caveat, the caveat goes next to the result, not in a footnote.
|
||||||
|
|
||||||
|
**Reports.** Every HTML report carries the small dotted bird in the corner, the software version and the run manifest checksum. The bird is there for recognition. The checksum is there because the bird cannot prove anything on its own.
|
||||||
|
|
||||||
|
## Thank you
|
||||||
|
|
||||||
|
If you have read all five posts, you now know more about SimurgArray than most of the machines it has run on. The code goes public on the calendar from the previous post. Until then, if you work with arrays and want to try it, or want to tell me which of my choices are wrong, I would be glad to hear from you at support@yaylali.uk.
|
||||||
|
|
||||||
|
The birds made it to the mountain. Now the interesting part starts.
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# SimurgArray blog
|
||||||
|
|
||||||
|
Five posts about why SimurgArray exists and where it is going.
|
||||||
|
|
||||||
|
1. [Why SimurgArray should exist](01_why_simurgarray_should_exist.md)
|
||||||
|
2. [Are there alternatives? Yes. Why build it anyway?](02_alternatives_and_why_i_built_it_anyway.md)
|
||||||
|
3. [What good could it do?](03_what_good_it_could_do.md)
|
||||||
|
4. [Going public: what it takes, and a calendar](04_going_public_plan_and_calendar.md)
|
||||||
|
5. [Using SimurgArray, and the bird behind the name](05_using_simurgarray_and_the_bird_behind_the_name.md)
|
||||||
|
|
||||||
|
Featured images (1200 x 630 JPEG, about 90 KB each) are in `images/`, one per post with the same file name.
|
||||||
|
They are drawn by `scripts/blog/make_featured_images.py` (Pillow), so they can be regenerated or restyled.
|
||||||
|
`branding_prompt.md` is a brief for designing the full brand identity.
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
# Branding brief for SimurgArray
|
||||||
|
|
||||||
|
Copy everything below the line into a branding agent. The identity it asks for now exists in `branding/`; this brief is kept for future refinements.
|
||||||
|
|
||||||
|
________________________________________________________________________________
|
||||||
|
|
||||||
|
You are a senior brand and visual identity designer. Build a complete, small, practical brand identity for an open source scientific software project called **SimurgArray**. Work carefully, explain your choices briefly, and deliver production ready files.
|
||||||
|
|
||||||
|
## The project in one paragraph
|
||||||
|
|
||||||
|
SimurgArray is a personal, non commercial research toolkit for Illumina Infinium genotyping arrays. It turns raw scanner files (IDATs) into genotype calls, quality control reports, VCF and PLINK files, and goes on to copy number, loss of heterozygosity, mosaicism, pharmacogenomics and training its own cluster files. It reproduces the vendor's genotype files byte for byte on public data, runs on a Raspberry Pi, and documents every place where it differs from reference tools. It is MIT licensed and about to go public. It is a research tool, never a medical or diagnostic product.
|
||||||
|
|
||||||
|
## The name and the story
|
||||||
|
|
||||||
|
In Persian and Turkic mythology the Simurg is a great, wise bird. In Attar's twelfth century poem *The Conference of the Birds*, thirty birds travel to find the Simurg and discover that "si murg" means "thirty birds": the Simurg was all of them together. An array works the same way: hundreds of thousands of tiny beads only mean something when read together. By coincidence, the public demo dataset used in validation turned out to be exactly thirty people. The brand should carry this idea quietly, never explain it loudly.
|
||||||
|
|
||||||
|
Tagline: **"Thirty birds, one picture."**
|
||||||
|
|
||||||
|
## Audience
|
||||||
|
|
||||||
|
Bioinformaticians, genetic epidemiologists, lab scientists running arrays, students, biobanks with small budgets. They are skeptical, detail oriented and allergic to marketing. They trust numbers, clear limitations and good documentation.
|
||||||
|
|
||||||
|
## Personality
|
||||||
|
|
||||||
|
Precise, calm, honest, a little dry, quietly clever. Think of a well made scientific instrument with a small smile engraved somewhere nobody asked for one. Not corporate, not playful, not futuristic, not "AI".
|
||||||
|
|
||||||
|
## Existing visual direction (keep and refine it, do not replace it)
|
||||||
|
|
||||||
|
The identity already exists in `branding/` (guide: `branding/README.md`). Treat it as the starting point.
|
||||||
|
|
||||||
|
* **Core motif:** a simurg seen from the front, wings raised in a V with three feathers each, a three dot crown, drawn only with round dots on a square grid like beads on a BeadChip. Three drawings: detailed (31 x 27 dots), simple (11 x 10) and micro (7 x 7).
|
||||||
|
* **Channel colours:** the body, wings and crown are gold, "where the two channels meet". Three tail plumes: red on the left (red channel), gold in the middle, green on the right (green channel), each ending in a round peacock eye.
|
||||||
|
* **Palette:** night indigo #1E2240, paper #F7F5EF, simurg gold #D4A017, gold deep #A87A00 (the bird on light backgrounds), gold ink #8C6500 (accent text on light), channel red #C8453A, channel green #2F8F5B, muted #A3A7C9 on dark and #5A5E7E on light. Charts use the Okabe and Ito colours with shapes.
|
||||||
|
* **Type:** Noto Sans (wordmark in SemiBold, "Array" in the accent colour) and Noto Sans Mono.
|
||||||
|
* The five blog featured images, the README banner, the social preview, the avatar and the HTML report header band already use it.
|
||||||
|
|
||||||
|
## Deliverables
|
||||||
|
|
||||||
|
1. **Logo system**
|
||||||
|
* Primary mark: the dotted bird, redrawn so it reads clearly as a bird at every size. Provide a detailed version (roughly 30 to 40 dots across) and a simplified version (roughly 8 to 12 dots across).
|
||||||
|
* Wordmark "SimurgArray" and a lockup of mark plus wordmark, horizontal and stacked.
|
||||||
|
* Favicon and app icon: 16, 32, 48, 180 and 512 px. At 16 px the bird may become an abstract cluster of dots, but it must still feel like the same family.
|
||||||
|
* Versions for dark background, light background, single color gold, single color black and single color white.
|
||||||
|
* Formats: SVG (clean, no embedded bitmaps, dots as circles) and PNG exports.
|
||||||
|
2. **Color system:** final hex values, usage ratios, and a contrast table showing that text colors meet WCAG AA on indigo and on paper. Include a rule for charts: red and green are the channel colors, so every chart must also be readable for red green color blind viewers (use shape, position or a blue alternative, and say how).
|
||||||
|
3. **Typography:** confirm or replace Noto Sans and Noto Sans Mono with free, open licensed fonts. Give sizes and weights for headings, body text, code and report tables (tabular figures for numbers).
|
||||||
|
4. **Dot grid system:** the grid spacing, dot sizes and rules for building new illustrations from dots, so other people can draw consistent images later.
|
||||||
|
5. **Templates**
|
||||||
|
* WordPress featured image, 1200 x 630.
|
||||||
|
* Social avatar, square, readable when shown as a circle.
|
||||||
|
* GitHub README banner, around 1280 x 320.
|
||||||
|
* Social preview for the repository, 1280 x 640.
|
||||||
|
* A small corner mark for HTML QC reports, together with the rule that the software version and a run checksum always appear next to it.
|
||||||
|
* An optional ASCII or Unicode banner for the command line, at most 6 lines and 60 columns, that still looks good in a plain terminal.
|
||||||
|
6. **Short brand guide** (two to four pages, Markdown or PDF): the story in three sentences, voice rules, do and do not examples for the logo, color and type specs, and how to build a new featured image.
|
||||||
|
|
||||||
|
## Voice rules for any text you write
|
||||||
|
|
||||||
|
* Plain, exact English. Short sentences. Numbers instead of adjectives.
|
||||||
|
* Every claim sits next to its limitation.
|
||||||
|
* Humor is allowed only as a faint smile, never as a joke that needs explaining.
|
||||||
|
* **Do not use em dashes, en dashes or hyphens in prose.** Rephrase instead ("open source", "non commercial", "step by step"). Hyphens inside code, file names and command options are fine.
|
||||||
|
* Never use: "revolutionary", "cutting edge", "AI powered", "next generation", "seamless", "unlock".
|
||||||
|
|
||||||
|
## Hard constraints
|
||||||
|
|
||||||
|
* Do not use, imitate or reference the logos, colors or product names of Illumina or any other genomics company. Illumina and Infinium may appear only as plain words describing compatibility, never as visual elements.
|
||||||
|
* Do not name or allude to the vendor's commercial analysis software products.
|
||||||
|
* No medical imagery: no crosses, pills, stethoscopes or DNA helices used as clinical symbols. A double helix, if used at all, must be abstract and secondary. The bird is the hero.
|
||||||
|
* No stock photos, no gradients that mimic "tech startup" style, no 3D renders.
|
||||||
|
* Everything must be original and free to publish under the project's MIT license or CC BY 4.0 for artwork. List any fonts or assets you use with their licenses.
|
||||||
|
* Files must be small: SVGs clean and optimized, PNG and JPEG exports under 150 KB each where possible.
|
||||||
|
|
||||||
|
## Acceptance checks (report on each)
|
||||||
|
|
||||||
|
1. The mark is recognizable as a bird at 48 px and still distinctive at 16 px.
|
||||||
|
2. Dark and light versions both pass WCAG AA for any text.
|
||||||
|
3. A red green color blind simulation of the logo and one chart example still reads well.
|
||||||
|
4. The five existing featured images and your new templates look like one family when placed side by side.
|
||||||
|
5. No prose you wrote contains an em dash, en dash or hyphen.
|
||||||
|
|
||||||
|
Start by restating the brief in five bullet points, list any questions you would normally ask a client (and the assumption you will make for each), then produce the deliverables.
|
||||||
|
After Width: | Height: | Size: 96 KiB |
|
After Width: | Height: | Size: 104 KiB |
|
After Width: | Height: | Size: 102 KiB |
|
After Width: | Height: | Size: 93 KiB |
|
After Width: | Height: | Size: 103 KiB |
@@ -0,0 +1,171 @@
|
|||||||
|
# SimurgArray brand guide
|
||||||
|
|
||||||
|
Everything here is generated by `scripts/brand/make_brand.py` (logos, icons, templates, checks) and
|
||||||
|
`scripts/blog/make_featured_images.py` (blog images). The mark geometry lives in one place,
|
||||||
|
`scripts/brand/simurg_mark.py`, so every file shows exactly the same dots. Artwork is released under CC BY 4.0; the
|
||||||
|
fonts are Noto Sans and Noto Sans Mono (SIL Open Font License 1.1).
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## The story in three sentences
|
||||||
|
|
||||||
|
In Attar's *Conference of the Birds*, thirty birds search for the Simurg and find that "si murg" means thirty birds:
|
||||||
|
the Simurg was all of them together. A genotyping array is the same idea, hundreds of thousands of small beads that
|
||||||
|
only mean something when read together. SimurgArray is the tool that reads them together, openly.
|
||||||
|
|
||||||
|
Tagline: **Thirty birds, one picture.**
|
||||||
|
|
||||||
|
## The mark
|
||||||
|
|
||||||
|
A simurg seen from the front, wings raised, drawn only with round dots on a square grid, the way beads sit on a
|
||||||
|
BeadChip.
|
||||||
|
|
||||||
|
* **Gold body, wings and crown.** Gold is what you get when the two scanner channels meet.
|
||||||
|
* **Three tail plumes:** red on the left (the red channel), gold in the middle, green on the right (the green
|
||||||
|
channel). Each ends in a round peacock eye.
|
||||||
|
* **Three dots on the head** form a small crown. Nobody has to notice it.
|
||||||
|
|
||||||
|
Three drawings of the same bird, chosen by size:
|
||||||
|
|
||||||
|
* `mark` (31 x 27 dots): 100 px and larger, banners, lockups, print.
|
||||||
|
* `mark_simple` (11 x 10 dots): 24 to 100 px, report corners, small UI.
|
||||||
|
* `mark_micro` (7 x 7 dots): 16 px favicon only.
|
||||||
|
|
||||||
|
Colour versions of each, in `logo/` as SVG and in `logo/png/` as PNG:
|
||||||
|
|
||||||
|
* `dark`: gold #D4A017 with red and green plumes, for indigo or other dark backgrounds.
|
||||||
|
* `light`: deep gold #A87A00 with red and green plumes, for paper or white.
|
||||||
|
* `gold`, `black`, `white`: single colour, for stamps, embossing, merchandise, fax machines that still exist.
|
||||||
|
|
||||||
|
The SVGs contain only circles, no embedded images and no fonts, so they render the same everywhere.
|
||||||
|
|
||||||
|
### Wordmark and lockups
|
||||||
|
|
||||||
|
"Simurg" in the text colour and "Array" in the accent colour, Noto Sans SemiBold, outlined to paths so no font is
|
||||||
|
needed. On dark backgrounds the accent is gold #D4A017, on light backgrounds gold ink #8C6500.
|
||||||
|
|
||||||
|
* `lockup_horizontal_*`: mark left, wordmark right. The default.
|
||||||
|
* `lockup_stacked_*`: mark above, wordmark centred below. For square spaces.
|
||||||
|
|
||||||
|
Clear space around any lockup: at least the height of the mark's head (about three dot rows) on every side.
|
||||||
|
|
||||||
|
### Do
|
||||||
|
|
||||||
|
* Keep the dots round and on their grid.
|
||||||
|
* Keep the red plume on the left and the green plume on the right.
|
||||||
|
* Use the light version on light backgrounds; plain gold on paper is too faint (contrast 2.18).
|
||||||
|
* Scale the whole mark; pick the simple or micro drawing when the dots would get smaller than about 2 px.
|
||||||
|
|
||||||
|
### Do not
|
||||||
|
|
||||||
|
* Recolour the plumes, add gradients, shadows, glows or outlines.
|
||||||
|
* Turn dots into squares or connect them with lines.
|
||||||
|
* Rotate, mirror or stretch the mark.
|
||||||
|
* Put the mark on busy photos.
|
||||||
|
* Combine it with DNA helices, crosses, pills or any clinical imagery. SimurgArray is a research tool.
|
||||||
|
* Use the logos, colours or product names of any genomics company as visual elements. Illumina and Infinium appear
|
||||||
|
only as plain words describing compatibility.
|
||||||
|
|
||||||
|
## Colour
|
||||||
|
|
||||||
|
Brand colours:
|
||||||
|
|
||||||
|
* **Night indigo** #1E2240: backgrounds (most of the work happened at night). Deep indigo #12142A for gradients.
|
||||||
|
* **Paper** #F7F5EF: light backgrounds and text on dark.
|
||||||
|
* **Simurg gold** #D4A017: the bird, accents on dark.
|
||||||
|
* **Gold deep** #A87A00: the bird on light backgrounds.
|
||||||
|
* **Gold ink** #8C6500: accent text on light backgrounds.
|
||||||
|
* **Channel red** #C8453A and **channel green** #2F8F5B: the plumes and the bead grid only. Never for text.
|
||||||
|
* **Muted on dark** #A3A7C9 and **muted on light** #5A5E7E: secondary text.
|
||||||
|
|
||||||
|
Rough proportions on a dark page: indigo 80, paper 10, gold 7, red and green 3 together.
|
||||||
|
|
||||||
|
Every text colour passes WCAG AA (4.5) and every graphic colour passes 3.0 on its background. The full table with
|
||||||
|
the computed ratios is in `checks/contrast.md`.
|
||||||
|
|
||||||
|
### Charts
|
||||||
|
|
||||||
|
Red against green is exactly the pair that red green colour blind readers cannot separate, and in genotyping it is
|
||||||
|
also the most tempting pair. So charts never use the channel colours to tell data apart. Use the Okabe and Ito
|
||||||
|
palette with a second cue:
|
||||||
|
|
||||||
|
* AA: vermillion #D55E00, circles.
|
||||||
|
* AB: bluish green #009E73, triangles.
|
||||||
|
* BB: blue #0072B2, squares.
|
||||||
|
|
||||||
|
Always add shape, position or a direct label as well as colour. `checks/colour_vision_check.png` shows the mark and
|
||||||
|
an example cluster plot under simulated protanopia and deuteranopia (Machado et al. 2009). The bird stays readable
|
||||||
|
because its shape carries it; the two coloured plumes become similar but keep their left and right positions; the
|
||||||
|
chart stays readable because of the shapes.
|
||||||
|
|
||||||
|
## Type
|
||||||
|
|
||||||
|
* **Noto Sans** for everything people read. Headings SemiBold or Bold, body Regular.
|
||||||
|
* **Noto Sans Mono** for anything a user might paste into a terminal, file names, and small labels such as
|
||||||
|
"PART 3".
|
||||||
|
* Numbers in tables use tabular figures (`font-variant-numeric: tabular-nums`), so columns of call rates line up.
|
||||||
|
|
||||||
|
Suggested sizes for the web: body 17 px with 1.6 line height, H1 40 px, H2 28 px, H3 21 px, code 15 px, table text
|
||||||
|
15 px. Reports: 13 px tables, 12 px captions.
|
||||||
|
|
||||||
|
## The dot grid
|
||||||
|
|
||||||
|
New illustrations are built from the same material as the logo.
|
||||||
|
|
||||||
|
* Background grid: dots every 18 px (at 1200 px width), radius 1.6 px, alternating red and green at 14 % opacity
|
||||||
|
over the indigo gradient.
|
||||||
|
* Foreground dots: radius 40 % of the cell, so neighbours never touch.
|
||||||
|
* Colour by meaning: gold for the subject, red and green only for things that come from the two channels, dimmed
|
||||||
|
gold or indigo mixes for "background" subjects.
|
||||||
|
* Motion is suggested with trails of shrinking, fading dots, never with lines.
|
||||||
|
* One subject per image. Empty space is part of the grid.
|
||||||
|
|
||||||
|
## Templates
|
||||||
|
|
||||||
|
In `templates/`:
|
||||||
|
|
||||||
|
* `featured_template_1200x630.jpg`: WordPress featured image and social preview for posts. Title on the left in Noto
|
||||||
|
Sans Bold (58 px, shrinks to fit a 540 px column), "PART N" above it in gold mono, footer with three dots, the name
|
||||||
|
and the tagline. The five blog images in `blog/images/` follow this layout, each with its own small motif.
|
||||||
|
* `social_preview_1280x640.png`: the repository preview image.
|
||||||
|
* `readme_banner_1280x320.png`: the top of the README.
|
||||||
|
* `avatar_512.png`: square avatar; the mark sits inside the central circle, so round crops are safe.
|
||||||
|
* `report_corner_mark.svg` and `report_corner_mark.html`: the small mark for HTML QC reports. It is always shown with
|
||||||
|
the software version and the first 12 characters of the run manifest checksum. The bird is for recognition; the
|
||||||
|
checksum is what actually proves anything.
|
||||||
|
* `cli_banner.txt`: six lines, 46 columns, plain ASCII, for `simurg --version` or a first run.
|
||||||
|
|
||||||
|
Icons in `icons/`: `favicon.ico` (16, 32, 48), PNGs at 16, 32, 48, 180 (Apple touch) and 512, all on a rounded
|
||||||
|
indigo tile. `checks/icon_sizes.png` shows them side by side.
|
||||||
|
|
||||||
|
## Making a new featured image
|
||||||
|
|
||||||
|
1. Add the post to `POSTS` in `scripts/blog/make_featured_images.py`: file stem, "Part N", the title with `\n`
|
||||||
|
where lines should break, and a motif.
|
||||||
|
2. Reuse a motif or write a new one: draw the mark with `draw_mark`, add at most one supporting element.
|
||||||
|
3. Run `python3 scripts/blog/make_featured_images.py`. Files come out at 1200 x 630 and about 100 KB.
|
||||||
|
|
||||||
|
## Voice
|
||||||
|
|
||||||
|
* Plain, exact English. Short sentences. Numbers instead of adjectives.
|
||||||
|
* Every claim sits next to its limitation, in the same paragraph.
|
||||||
|
* Humour only as a faint smile.
|
||||||
|
* No em dashes, en dashes or hyphens in prose; rephrase instead. Hyphens in code, file names and options are fine.
|
||||||
|
* Never: revolutionary, cutting edge, AI powered, next generation, seamless, unlock.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
* Yes: "Concordance with 30x sequencing was 99.44 %, against 99.46 % for the vendor's cluster file."
|
||||||
|
* No: "Best in class accuracy that rivals commercial solutions."
|
||||||
|
* Yes: "Research use only. The PGx report shows the evidence behind every call."
|
||||||
|
* No: "Personalised medicine, unlocked."
|
||||||
|
|
||||||
|
## Acceptance checks
|
||||||
|
|
||||||
|
1. **Recognisable at 48 px, distinctive at 16 px:** see `checks/icon_sizes.png`. The simple and micro drawings were
|
||||||
|
drawn by hand for these sizes instead of scaling the detailed one down.
|
||||||
|
2. **Contrast:** all text pairs pass AA, all graphic pairs pass 3.0 (`checks/contrast.md`); plain gold on paper is
|
||||||
|
the one pair that fails, and the guide forbids it.
|
||||||
|
3. **Colour vision:** `checks/colour_vision_check.png`.
|
||||||
|
4. **One family:** `checks/family.jpg` puts the five blog images and the templates side by side.
|
||||||
|
5. **No dashes in prose:** this guide and all generated text were checked for em dashes, en dashes and hyphens.
|
||||||
|
After Width: | Height: | Size: 84 KiB |
@@ -0,0 +1,14 @@
|
|||||||
|
| colour | on | use | contrast | AA text (4.5) | graphics (3.0) |
|
||||||
|
|---|---|---|---|---|---|
|
||||||
|
| paper #F7F5EF | indigo #1E2240 | text on dark | 14.18 | yes | yes |
|
||||||
|
| muted_dark #A3A7C9 | indigo #1E2240 | secondary text on dark | 6.57 | yes | yes |
|
||||||
|
| gold #D4A017 | indigo #1E2240 | accent text on dark | 6.51 | yes | yes |
|
||||||
|
| indigo #1E2240 | paper #F7F5EF | text on light | 14.18 | yes | yes |
|
||||||
|
| muted_light #5A5E7E | paper #F7F5EF | secondary text on light | 5.77 | yes | yes |
|
||||||
|
| gold_ink #8C6500 | paper #F7F5EF | accent text on light | 4.84 | yes | yes |
|
||||||
|
| red #C8453A | indigo #1E2240 | graphics on dark | 3.22 | no | yes |
|
||||||
|
| green #2F8F5B | indigo #1E2240 | graphics on dark | 3.83 | no | yes |
|
||||||
|
| gold_deep #A87A00 | paper #F7F5EF | graphics on light | 3.54 | no | yes |
|
||||||
|
| red #C8453A | paper #F7F5EF | graphics on light | 4.41 | no | yes |
|
||||||
|
| green #2F8F5B | paper #F7F5EF | graphics on light | 3.70 | no | yes |
|
||||||
|
| gold #D4A017 | paper #F7F5EF | never for text or small marks | 2.18 | no | no |
|
||||||
|
After Width: | Height: | Size: 115 KiB |
|
After Width: | Height: | Size: 8.6 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 304 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8 8" width="8" height="8" role="img" aria-label="SimurgArray"><title>SimurgArray</title><rect width="8" height="8" rx="1.44" fill="#1E2240"/><g fill="#D4A017"><circle cx="1.000" cy="1.000" r="0.420"/><circle cx="7.000" cy="1.000" r="0.420"/><circle cx="1.000" cy="2.000" r="0.420"/><circle cx="2.000" cy="2.000" r="0.420"/><circle cx="4.000" cy="2.000" r="0.420"/><circle cx="6.000" cy="2.000" r="0.420"/><circle cx="7.000" cy="2.000" r="0.420"/><circle cx="2.000" cy="3.000" r="0.420"/><circle cx="3.000" cy="3.000" r="0.420"/><circle cx="4.000" cy="3.000" r="0.420"/><circle cx="5.000" cy="3.000" r="0.420"/><circle cx="6.000" cy="3.000" r="0.420"/><circle cx="3.000" cy="4.000" r="0.420"/><circle cx="4.000" cy="4.000" r="0.420"/><circle cx="5.000" cy="4.000" r="0.420"/><circle cx="4.000" cy="5.000" r="0.420"/><circle cx="4.000" cy="6.000" r="0.420"/><circle cx="4.000" cy="7.000" r="0.420"/></g><g fill="#C8453A"><circle cx="2.000" cy="6.000" r="0.420"/><circle cx="1.000" cy="7.000" r="0.420"/></g><g fill="#2F8F5B"><circle cx="6.000" cy="6.000" r="0.420"/><circle cx="7.000" cy="7.000" r="0.420"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 949 B |
|
After Width: | Height: | Size: 59 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 34 34" width="34" height="34" role="img" aria-label="SimurgArray"><title>SimurgArray</title><rect width="34" height="34" rx="6.12" fill="#1E2240"/><g fill="#D4A017"><circle cx="3.000" cy="4.000" r="0.400"/><circle cx="4.000" cy="4.000" r="0.400"/><circle cx="30.000" cy="4.000" r="0.400"/><circle cx="31.000" cy="4.000" r="0.400"/><circle cx="3.000" cy="5.000" r="0.400"/><circle cx="4.000" cy="5.000" r="0.400"/><circle cx="5.000" cy="5.000" r="0.400"/><circle cx="15.000" cy="5.000" r="0.400"/><circle cx="17.000" cy="5.000" r="0.400"/><circle cx="19.000" cy="5.000" r="0.400"/><circle cx="29.000" cy="5.000" r="0.400"/><circle cx="30.000" cy="5.000" r="0.400"/><circle cx="31.000" cy="5.000" r="0.400"/><circle cx="3.000" cy="6.000" r="0.400"/><circle cx="4.000" cy="6.000" r="0.400"/><circle cx="5.000" cy="6.000" r="0.400"/><circle cx="6.000" cy="6.000" r="0.400"/><circle cx="7.000" cy="6.000" r="0.400"/><circle cx="15.000" cy="6.000" r="0.400"/><circle cx="16.000" cy="6.000" r="0.400"/><circle cx="17.000" cy="6.000" r="0.400"/><circle cx="18.000" cy="6.000" r="0.400"/><circle cx="19.000" cy="6.000" r="0.400"/><circle cx="27.000" cy="6.000" r="0.400"/><circle cx="28.000" cy="6.000" r="0.400"/><circle cx="29.000" cy="6.000" r="0.400"/><circle cx="30.000" cy="6.000" r="0.400"/><circle cx="31.000" cy="6.000" r="0.400"/><circle cx="5.000" cy="7.000" r="0.400"/><circle cx="6.000" cy="7.000" r="0.400"/><circle cx="7.000" cy="7.000" r="0.400"/><circle cx="8.000" cy="7.000" r="0.400"/><circle cx="9.000" cy="7.000" r="0.400"/><circle cx="15.000" cy="7.000" r="0.400"/><circle cx="16.000" cy="7.000" r="0.400"/><circle cx="17.000" cy="7.000" r="0.400"/><circle cx="18.000" cy="7.000" r="0.400"/><circle cx="19.000" cy="7.000" r="0.400"/><circle cx="25.000" cy="7.000" r="0.400"/><circle cx="26.000" cy="7.000" r="0.400"/><circle cx="27.000" cy="7.000" r="0.400"/><circle cx="28.000" cy="7.000" r="0.400"/><circle cx="29.000" cy="7.000" r="0.400"/><circle cx="6.000" cy="8.000" r="0.400"/><circle cx="7.000" cy="8.000" r="0.400"/><circle cx="8.000" cy="8.000" r="0.400"/><circle cx="9.000" cy="8.000" r="0.400"/><circle cx="10.000" cy="8.000" r="0.400"/><circle cx="15.000" cy="8.000" r="0.400"/><circle cx="16.000" cy="8.000" r="0.400"/><circle cx="17.000" cy="8.000" r="0.400"/><circle cx="18.000" cy="8.000" r="0.400"/><circle cx="19.000" cy="8.000" r="0.400"/><circle cx="24.000" cy="8.000" r="0.400"/><circle cx="25.000" cy="8.000" r="0.400"/><circle cx="26.000" cy="8.000" r="0.400"/><circle cx="27.000" cy="8.000" r="0.400"/><circle cx="28.000" cy="8.000" r="0.400"/><circle cx="3.000" cy="9.000" r="0.400"/><circle cx="8.000" cy="9.000" r="0.400"/><circle cx="9.000" cy="9.000" r="0.400"/><circle cx="10.000" cy="9.000" r="0.400"/><circle cx="11.000" cy="9.000" r="0.400"/><circle cx="15.000" cy="9.000" r="0.400"/><circle cx="16.000" cy="9.000" r="0.400"/><circle cx="17.000" cy="9.000" r="0.400"/><circle cx="18.000" cy="9.000" r="0.400"/><circle cx="19.000" cy="9.000" r="0.400"/><circle cx="23.000" cy="9.000" r="0.400"/><circle cx="24.000" cy="9.000" r="0.400"/><circle cx="25.000" cy="9.000" r="0.400"/><circle cx="26.000" cy="9.000" r="0.400"/><circle cx="31.000" cy="9.000" r="0.400"/><circle cx="2.000" cy="10.000" r="0.400"/><circle cx="3.000" cy="10.000" r="0.400"/><circle cx="4.000" cy="10.000" r="0.400"/><circle cx="5.000" cy="10.000" r="0.400"/><circle cx="6.000" cy="10.000" r="0.400"/><circle cx="10.000" cy="10.000" r="0.400"/><circle cx="11.000" cy="10.000" r="0.400"/><circle cx="12.000" cy="10.000" r="0.400"/><circle cx="13.000" cy="10.000" r="0.400"/><circle cx="16.000" cy="10.000" r="0.400"/><circle cx="17.000" cy="10.000" r="0.400"/><circle cx="18.000" cy="10.000" r="0.400"/><circle cx="21.000" cy="10.000" r="0.400"/><circle cx="22.000" cy="10.000" r="0.400"/><circle cx="23.000" cy="10.000" r="0.400"/><circle cx="24.000" cy="10.000" r="0.400"/><circle cx="28.000" cy="10.000" r="0.400"/><circle cx="29.000" cy="10.000" r="0.400"/><circle cx="30.000" cy="10.000" r="0.400"/><circle cx="31.000" cy="10.000" r="0.400"/><circle cx="32.000" cy="10.000" r="0.400"/><circle cx="2.000" cy="11.000" r="0.400"/><circle cx="3.000" cy="11.000" r="0.400"/><circle cx="4.000" cy="11.000" r="0.400"/><circle cx="5.000" cy="11.000" r="0.400"/><circle cx="6.000" cy="11.000" r="0.400"/><circle cx="7.000" cy="11.000" r="0.400"/><circle cx="8.000" cy="11.000" r="0.400"/><circle cx="9.000" cy="11.000" r="0.400"/><circle cx="10.000" cy="11.000" r="0.400"/><circle cx="11.000" cy="11.000" r="0.400"/><circle cx="12.000" cy="11.000" r="0.400"/><circle cx="13.000" cy="11.000" r="0.400"/><circle cx="14.000" cy="11.000" r="0.400"/><circle cx="16.000" cy="11.000" r="0.400"/><circle cx="17.000" cy="11.000" r="0.400"/><circle cx="18.000" cy="11.000" r="0.400"/><circle cx="20.000" cy="11.000" r="0.400"/><circle cx="21.000" cy="11.000" r="0.400"/><circle cx="22.000" cy="11.000" r="0.400"/><circle cx="23.000" cy="11.000Line truncated
|
||||||
|
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 662.866 200" width="662.866" height="200" role="img" aria-label="SimurgArray"><title>SimurgArray</title><g fill="#111111"><circle cx="46.667" cy="42.222" r="1.778"/><circle cx="51.111" cy="42.222" r="1.778"/><circle cx="166.667" cy="42.222" r="1.778"/><circle cx="171.111" cy="42.222" r="1.778"/><circle cx="46.667" cy="46.667" r="1.778"/><circle cx="51.111" cy="46.667" r="1.778"/><circle cx="55.556" cy="46.667" r="1.778"/><circle cx="100.000" cy="46.667" r="1.778"/><circle cx="108.889" cy="46.667" r="1.778"/><circle cx="117.778" cy="46.667" r="1.778"/><circle cx="162.222" cy="46.667" r="1.778"/><circle cx="166.667" cy="46.667" r="1.778"/><circle cx="171.111" cy="46.667" r="1.778"/><circle cx="46.667" cy="51.111" r="1.778"/><circle cx="51.111" cy="51.111" r="1.778"/><circle cx="55.556" cy="51.111" r="1.778"/><circle cx="60.000" cy="51.111" r="1.778"/><circle cx="64.444" cy="51.111" r="1.778"/><circle cx="100.000" cy="51.111" r="1.778"/><circle cx="104.444" cy="51.111" r="1.778"/><circle cx="108.889" cy="51.111" r="1.778"/><circle cx="113.333" cy="51.111" r="1.778"/><circle cx="117.778" cy="51.111" r="1.778"/><circle cx="153.333" cy="51.111" r="1.778"/><circle cx="157.778" cy="51.111" r="1.778"/><circle cx="162.222" cy="51.111" r="1.778"/><circle cx="166.667" cy="51.111" r="1.778"/><circle cx="171.111" cy="51.111" r="1.778"/><circle cx="55.556" cy="55.556" r="1.778"/><circle cx="60.000" cy="55.556" r="1.778"/><circle cx="64.444" cy="55.556" r="1.778"/><circle cx="68.889" cy="55.556" r="1.778"/><circle cx="73.333" cy="55.556" r="1.778"/><circle cx="100.000" cy="55.556" r="1.778"/><circle cx="104.444" cy="55.556" r="1.778"/><circle cx="108.889" cy="55.556" r="1.778"/><circle cx="113.333" cy="55.556" r="1.778"/><circle cx="117.778" cy="55.556" r="1.778"/><circle cx="144.444" cy="55.556" r="1.778"/><circle cx="148.889" cy="55.556" r="1.778"/><circle cx="153.333" cy="55.556" r="1.778"/><circle cx="157.778" cy="55.556" r="1.778"/><circle cx="162.222" cy="55.556" r="1.778"/><circle cx="60.000" cy="60.000" r="1.778"/><circle cx="64.444" cy="60.000" r="1.778"/><circle cx="68.889" cy="60.000" r="1.778"/><circle cx="73.333" cy="60.000" r="1.778"/><circle cx="77.778" cy="60.000" r="1.778"/><circle cx="100.000" cy="60.000" r="1.778"/><circle cx="104.444" cy="60.000" r="1.778"/><circle cx="108.889" cy="60.000" r="1.778"/><circle cx="113.333" cy="60.000" r="1.778"/><circle cx="117.778" cy="60.000" r="1.778"/><circle cx="140.000" cy="60.000" r="1.778"/><circle cx="144.444" cy="60.000" r="1.778"/><circle cx="148.889" cy="60.000" r="1.778"/><circle cx="153.333" cy="60.000" r="1.778"/><circle cx="157.778" cy="60.000" r="1.778"/><circle cx="46.667" cy="64.444" r="1.778"/><circle cx="68.889" cy="64.444" r="1.778"/><circle cx="73.333" cy="64.444" r="1.778"/><circle cx="77.778" cy="64.444" r="1.778"/><circle cx="82.222" cy="64.444" r="1.778"/><circle cx="100.000" cy="64.444" r="1.778"/><circle cx="104.444" cy="64.444" r="1.778"/><circle cx="108.889" cy="64.444" r="1.778"/><circle cx="113.333" cy="64.444" r="1.778"/><circle cx="117.778" cy="64.444" r="1.778"/><circle cx="135.556" cy="64.444" r="1.778"/><circle cx="140.000" cy="64.444" r="1.778"/><circle cx="144.444" cy="64.444" r="1.778"/><circle cx="148.889" cy="64.444" r="1.778"/><circle cx="171.111" cy="64.444" r="1.778"/><circle cx="42.222" cy="68.889" r="1.778"/><circle cx="46.667" cy="68.889" r="1.778"/><circle cx="51.111" cy="68.889" r="1.778"/><circle cx="55.556" cy="68.889" r="1.778"/><circle cx="60.000" cy="68.889" r="1.778"/><circle cx="77.778" cy="68.889" r="1.778"/><circle cx="82.222" cy="68.889" r="1.778"/><circle cx="86.667" cy="68.889" r="1.778"/><circle cx="91.111" cy="68.889" r="1.778"/><circle cx="104.444" cy="68.889" r="1.778"/><circle cx="108.889" cy="68.889" r="1.778"/><circle cx="113.333" cy="68.889" r="1.778"/><circle cx="126.667" cy="68.889" r="1.778"/><circle cx="131.111" cy="68.889" r="1.778"/><circle cx="135.556" cy="68.889" r="1.778"/><circle cx="140.000" cy="68.889" r="1.778"/><circle cx="157.778" cy="68.889" r="1.778"/><circle cx="162.222" cy="68.889" r="1.778"/><circle cx="166.667" cy="68.889" r="1.778"/><circle cx="171.111" cy="68.889" r="1.778"/><circle cx="175.556" cy="68.889" r="1.778"/><circle cx="42.222" cy="73.333" r="1.778"/><circle cx="46.667" cy="73.333" r="1.778"/><circle cx="51.111" cy="73.333" r="1.778"/><circle cx="55.556" cy="73.333" r="1.778"/><circle cx="60.000" cy="73.333" r="1.778"/><circle cx="64.444" cy="73.333" r="1.778"/><circle cx="68.889" cy="73.333" r="1.778"/><circle cx="73.333" cy="73.333" r="1.778"/><circle cx="77.778" cy="73.333" r="1.778"/><circle cx="82.222" cy="73.333" r="1.778"/><circle cx="86.667" cy="73.333" r="1.778"/><circle cx="91.111" cy="73.333" r="1.778"/><circle cx="95.556" cy="73.333" r="1.778"/><circle cx="104.444" cy="73.333" r="1.778"/><circle cx="108.889" cy="73.333" r="1.778"/><circle cx="113.333" cy="73.333" r="1.778"/><circle cx="122.222" cy="73.333Line truncated
|
||||||
|
After Width: | Height: | Size: 23 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 662.866 200" width="662.866" height="200" role="img" aria-label="SimurgArray"><title>SimurgArray</title><rect width="662.865777777778" height="200" fill="#1E2240"/><g fill="#D4A017"><circle cx="46.667" cy="42.222" r="1.778"/><circle cx="51.111" cy="42.222" r="1.778"/><circle cx="166.667" cy="42.222" r="1.778"/><circle cx="171.111" cy="42.222" r="1.778"/><circle cx="46.667" cy="46.667" r="1.778"/><circle cx="51.111" cy="46.667" r="1.778"/><circle cx="55.556" cy="46.667" r="1.778"/><circle cx="100.000" cy="46.667" r="1.778"/><circle cx="108.889" cy="46.667" r="1.778"/><circle cx="117.778" cy="46.667" r="1.778"/><circle cx="162.222" cy="46.667" r="1.778"/><circle cx="166.667" cy="46.667" r="1.778"/><circle cx="171.111" cy="46.667" r="1.778"/><circle cx="46.667" cy="51.111" r="1.778"/><circle cx="51.111" cy="51.111" r="1.778"/><circle cx="55.556" cy="51.111" r="1.778"/><circle cx="60.000" cy="51.111" r="1.778"/><circle cx="64.444" cy="51.111" r="1.778"/><circle cx="100.000" cy="51.111" r="1.778"/><circle cx="104.444" cy="51.111" r="1.778"/><circle cx="108.889" cy="51.111" r="1.778"/><circle cx="113.333" cy="51.111" r="1.778"/><circle cx="117.778" cy="51.111" r="1.778"/><circle cx="153.333" cy="51.111" r="1.778"/><circle cx="157.778" cy="51.111" r="1.778"/><circle cx="162.222" cy="51.111" r="1.778"/><circle cx="166.667" cy="51.111" r="1.778"/><circle cx="171.111" cy="51.111" r="1.778"/><circle cx="55.556" cy="55.556" r="1.778"/><circle cx="60.000" cy="55.556" r="1.778"/><circle cx="64.444" cy="55.556" r="1.778"/><circle cx="68.889" cy="55.556" r="1.778"/><circle cx="73.333" cy="55.556" r="1.778"/><circle cx="100.000" cy="55.556" r="1.778"/><circle cx="104.444" cy="55.556" r="1.778"/><circle cx="108.889" cy="55.556" r="1.778"/><circle cx="113.333" cy="55.556" r="1.778"/><circle cx="117.778" cy="55.556" r="1.778"/><circle cx="144.444" cy="55.556" r="1.778"/><circle cx="148.889" cy="55.556" r="1.778"/><circle cx="153.333" cy="55.556" r="1.778"/><circle cx="157.778" cy="55.556" r="1.778"/><circle cx="162.222" cy="55.556" r="1.778"/><circle cx="60.000" cy="60.000" r="1.778"/><circle cx="64.444" cy="60.000" r="1.778"/><circle cx="68.889" cy="60.000" r="1.778"/><circle cx="73.333" cy="60.000" r="1.778"/><circle cx="77.778" cy="60.000" r="1.778"/><circle cx="100.000" cy="60.000" r="1.778"/><circle cx="104.444" cy="60.000" r="1.778"/><circle cx="108.889" cy="60.000" r="1.778"/><circle cx="113.333" cy="60.000" r="1.778"/><circle cx="117.778" cy="60.000" r="1.778"/><circle cx="140.000" cy="60.000" r="1.778"/><circle cx="144.444" cy="60.000" r="1.778"/><circle cx="148.889" cy="60.000" r="1.778"/><circle cx="153.333" cy="60.000" r="1.778"/><circle cx="157.778" cy="60.000" r="1.778"/><circle cx="46.667" cy="64.444" r="1.778"/><circle cx="68.889" cy="64.444" r="1.778"/><circle cx="73.333" cy="64.444" r="1.778"/><circle cx="77.778" cy="64.444" r="1.778"/><circle cx="82.222" cy="64.444" r="1.778"/><circle cx="100.000" cy="64.444" r="1.778"/><circle cx="104.444" cy="64.444" r="1.778"/><circle cx="108.889" cy="64.444" r="1.778"/><circle cx="113.333" cy="64.444" r="1.778"/><circle cx="117.778" cy="64.444" r="1.778"/><circle cx="135.556" cy="64.444" r="1.778"/><circle cx="140.000" cy="64.444" r="1.778"/><circle cx="144.444" cy="64.444" r="1.778"/><circle cx="148.889" cy="64.444" r="1.778"/><circle cx="171.111" cy="64.444" r="1.778"/><circle cx="42.222" cy="68.889" r="1.778"/><circle cx="46.667" cy="68.889" r="1.778"/><circle cx="51.111" cy="68.889" r="1.778"/><circle cx="55.556" cy="68.889" r="1.778"/><circle cx="60.000" cy="68.889" r="1.778"/><circle cx="77.778" cy="68.889" r="1.778"/><circle cx="82.222" cy="68.889" r="1.778"/><circle cx="86.667" cy="68.889" r="1.778"/><circle cx="91.111" cy="68.889" r="1.778"/><circle cx="104.444" cy="68.889" r="1.778"/><circle cx="108.889" cy="68.889" r="1.778"/><circle cx="113.333" cy="68.889" r="1.778"/><circle cx="126.667" cy="68.889" r="1.778"/><circle cx="131.111" cy="68.889" r="1.778"/><circle cx="135.556" cy="68.889" r="1.778"/><circle cx="140.000" cy="68.889" r="1.778"/><circle cx="157.778" cy="68.889" r="1.778"/><circle cx="162.222" cy="68.889" r="1.778"/><circle cx="166.667" cy="68.889" r="1.778"/><circle cx="171.111" cy="68.889" r="1.778"/><circle cx="175.556" cy="68.889" r="1.778"/><circle cx="42.222" cy="73.333" r="1.778"/><circle cx="46.667" cy="73.333" r="1.778"/><circle cx="51.111" cy="73.333" r="1.778"/><circle cx="55.556" cy="73.333" r="1.778"/><circle cx="60.000" cy="73.333" r="1.778"/><circle cx="64.444" cy="73.333" r="1.778"/><circle cx="68.889" cy="73.333" r="1.778"/><circle cx="73.333" cy="73.333" r="1.778"/><circle cx="77.778" cy="73.333" r="1.778"/><circle cx="82.222" cy="73.333" r="1.778"/><circle cx="86.667" cy="73.333" r="1.778"/><circle cx="91.111" cy="73.333" r="1.778"/><circle cx="95.556" cy="73.333" r="1.778"/><circle cx="104.444" cy="73.333" r="1.778"/><circle cx="108.889" cy="73.333" r="1.778"/><circle cx="113Line truncated
|
||||||
|
After Width: | Height: | Size: 23 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 662.866 200" width="662.866" height="200" role="img" aria-label="SimurgArray"><title>SimurgArray</title><rect width="662.865777777778" height="200" fill="#F7F5EF"/><g fill="#A87A00"><circle cx="46.667" cy="42.222" r="1.778"/><circle cx="51.111" cy="42.222" r="1.778"/><circle cx="166.667" cy="42.222" r="1.778"/><circle cx="171.111" cy="42.222" r="1.778"/><circle cx="46.667" cy="46.667" r="1.778"/><circle cx="51.111" cy="46.667" r="1.778"/><circle cx="55.556" cy="46.667" r="1.778"/><circle cx="100.000" cy="46.667" r="1.778"/><circle cx="108.889" cy="46.667" r="1.778"/><circle cx="117.778" cy="46.667" r="1.778"/><circle cx="162.222" cy="46.667" r="1.778"/><circle cx="166.667" cy="46.667" r="1.778"/><circle cx="171.111" cy="46.667" r="1.778"/><circle cx="46.667" cy="51.111" r="1.778"/><circle cx="51.111" cy="51.111" r="1.778"/><circle cx="55.556" cy="51.111" r="1.778"/><circle cx="60.000" cy="51.111" r="1.778"/><circle cx="64.444" cy="51.111" r="1.778"/><circle cx="100.000" cy="51.111" r="1.778"/><circle cx="104.444" cy="51.111" r="1.778"/><circle cx="108.889" cy="51.111" r="1.778"/><circle cx="113.333" cy="51.111" r="1.778"/><circle cx="117.778" cy="51.111" r="1.778"/><circle cx="153.333" cy="51.111" r="1.778"/><circle cx="157.778" cy="51.111" r="1.778"/><circle cx="162.222" cy="51.111" r="1.778"/><circle cx="166.667" cy="51.111" r="1.778"/><circle cx="171.111" cy="51.111" r="1.778"/><circle cx="55.556" cy="55.556" r="1.778"/><circle cx="60.000" cy="55.556" r="1.778"/><circle cx="64.444" cy="55.556" r="1.778"/><circle cx="68.889" cy="55.556" r="1.778"/><circle cx="73.333" cy="55.556" r="1.778"/><circle cx="100.000" cy="55.556" r="1.778"/><circle cx="104.444" cy="55.556" r="1.778"/><circle cx="108.889" cy="55.556" r="1.778"/><circle cx="113.333" cy="55.556" r="1.778"/><circle cx="117.778" cy="55.556" r="1.778"/><circle cx="144.444" cy="55.556" r="1.778"/><circle cx="148.889" cy="55.556" r="1.778"/><circle cx="153.333" cy="55.556" r="1.778"/><circle cx="157.778" cy="55.556" r="1.778"/><circle cx="162.222" cy="55.556" r="1.778"/><circle cx="60.000" cy="60.000" r="1.778"/><circle cx="64.444" cy="60.000" r="1.778"/><circle cx="68.889" cy="60.000" r="1.778"/><circle cx="73.333" cy="60.000" r="1.778"/><circle cx="77.778" cy="60.000" r="1.778"/><circle cx="100.000" cy="60.000" r="1.778"/><circle cx="104.444" cy="60.000" r="1.778"/><circle cx="108.889" cy="60.000" r="1.778"/><circle cx="113.333" cy="60.000" r="1.778"/><circle cx="117.778" cy="60.000" r="1.778"/><circle cx="140.000" cy="60.000" r="1.778"/><circle cx="144.444" cy="60.000" r="1.778"/><circle cx="148.889" cy="60.000" r="1.778"/><circle cx="153.333" cy="60.000" r="1.778"/><circle cx="157.778" cy="60.000" r="1.778"/><circle cx="46.667" cy="64.444" r="1.778"/><circle cx="68.889" cy="64.444" r="1.778"/><circle cx="73.333" cy="64.444" r="1.778"/><circle cx="77.778" cy="64.444" r="1.778"/><circle cx="82.222" cy="64.444" r="1.778"/><circle cx="100.000" cy="64.444" r="1.778"/><circle cx="104.444" cy="64.444" r="1.778"/><circle cx="108.889" cy="64.444" r="1.778"/><circle cx="113.333" cy="64.444" r="1.778"/><circle cx="117.778" cy="64.444" r="1.778"/><circle cx="135.556" cy="64.444" r="1.778"/><circle cx="140.000" cy="64.444" r="1.778"/><circle cx="144.444" cy="64.444" r="1.778"/><circle cx="148.889" cy="64.444" r="1.778"/><circle cx="171.111" cy="64.444" r="1.778"/><circle cx="42.222" cy="68.889" r="1.778"/><circle cx="46.667" cy="68.889" r="1.778"/><circle cx="51.111" cy="68.889" r="1.778"/><circle cx="55.556" cy="68.889" r="1.778"/><circle cx="60.000" cy="68.889" r="1.778"/><circle cx="77.778" cy="68.889" r="1.778"/><circle cx="82.222" cy="68.889" r="1.778"/><circle cx="86.667" cy="68.889" r="1.778"/><circle cx="91.111" cy="68.889" r="1.778"/><circle cx="104.444" cy="68.889" r="1.778"/><circle cx="108.889" cy="68.889" r="1.778"/><circle cx="113.333" cy="68.889" r="1.778"/><circle cx="126.667" cy="68.889" r="1.778"/><circle cx="131.111" cy="68.889" r="1.778"/><circle cx="135.556" cy="68.889" r="1.778"/><circle cx="140.000" cy="68.889" r="1.778"/><circle cx="157.778" cy="68.889" r="1.778"/><circle cx="162.222" cy="68.889" r="1.778"/><circle cx="166.667" cy="68.889" r="1.778"/><circle cx="171.111" cy="68.889" r="1.778"/><circle cx="175.556" cy="68.889" r="1.778"/><circle cx="42.222" cy="73.333" r="1.778"/><circle cx="46.667" cy="73.333" r="1.778"/><circle cx="51.111" cy="73.333" r="1.778"/><circle cx="55.556" cy="73.333" r="1.778"/><circle cx="60.000" cy="73.333" r="1.778"/><circle cx="64.444" cy="73.333" r="1.778"/><circle cx="68.889" cy="73.333" r="1.778"/><circle cx="73.333" cy="73.333" r="1.778"/><circle cx="77.778" cy="73.333" r="1.778"/><circle cx="82.222" cy="73.333" r="1.778"/><circle cx="86.667" cy="73.333" r="1.778"/><circle cx="91.111" cy="73.333" r="1.778"/><circle cx="95.556" cy="73.333" r="1.778"/><circle cx="104.444" cy="73.333" r="1.778"/><circle cx="108.889" cy="73.333" r="1.778"/><circle cx="113Line truncated
|
||||||
|
After Width: | Height: | Size: 23 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 662.866 200" width="662.866" height="200" role="img" aria-label="SimurgArray"><title>SimurgArray</title><g fill="#FFFFFF"><circle cx="46.667" cy="42.222" r="1.778"/><circle cx="51.111" cy="42.222" r="1.778"/><circle cx="166.667" cy="42.222" r="1.778"/><circle cx="171.111" cy="42.222" r="1.778"/><circle cx="46.667" cy="46.667" r="1.778"/><circle cx="51.111" cy="46.667" r="1.778"/><circle cx="55.556" cy="46.667" r="1.778"/><circle cx="100.000" cy="46.667" r="1.778"/><circle cx="108.889" cy="46.667" r="1.778"/><circle cx="117.778" cy="46.667" r="1.778"/><circle cx="162.222" cy="46.667" r="1.778"/><circle cx="166.667" cy="46.667" r="1.778"/><circle cx="171.111" cy="46.667" r="1.778"/><circle cx="46.667" cy="51.111" r="1.778"/><circle cx="51.111" cy="51.111" r="1.778"/><circle cx="55.556" cy="51.111" r="1.778"/><circle cx="60.000" cy="51.111" r="1.778"/><circle cx="64.444" cy="51.111" r="1.778"/><circle cx="100.000" cy="51.111" r="1.778"/><circle cx="104.444" cy="51.111" r="1.778"/><circle cx="108.889" cy="51.111" r="1.778"/><circle cx="113.333" cy="51.111" r="1.778"/><circle cx="117.778" cy="51.111" r="1.778"/><circle cx="153.333" cy="51.111" r="1.778"/><circle cx="157.778" cy="51.111" r="1.778"/><circle cx="162.222" cy="51.111" r="1.778"/><circle cx="166.667" cy="51.111" r="1.778"/><circle cx="171.111" cy="51.111" r="1.778"/><circle cx="55.556" cy="55.556" r="1.778"/><circle cx="60.000" cy="55.556" r="1.778"/><circle cx="64.444" cy="55.556" r="1.778"/><circle cx="68.889" cy="55.556" r="1.778"/><circle cx="73.333" cy="55.556" r="1.778"/><circle cx="100.000" cy="55.556" r="1.778"/><circle cx="104.444" cy="55.556" r="1.778"/><circle cx="108.889" cy="55.556" r="1.778"/><circle cx="113.333" cy="55.556" r="1.778"/><circle cx="117.778" cy="55.556" r="1.778"/><circle cx="144.444" cy="55.556" r="1.778"/><circle cx="148.889" cy="55.556" r="1.778"/><circle cx="153.333" cy="55.556" r="1.778"/><circle cx="157.778" cy="55.556" r="1.778"/><circle cx="162.222" cy="55.556" r="1.778"/><circle cx="60.000" cy="60.000" r="1.778"/><circle cx="64.444" cy="60.000" r="1.778"/><circle cx="68.889" cy="60.000" r="1.778"/><circle cx="73.333" cy="60.000" r="1.778"/><circle cx="77.778" cy="60.000" r="1.778"/><circle cx="100.000" cy="60.000" r="1.778"/><circle cx="104.444" cy="60.000" r="1.778"/><circle cx="108.889" cy="60.000" r="1.778"/><circle cx="113.333" cy="60.000" r="1.778"/><circle cx="117.778" cy="60.000" r="1.778"/><circle cx="140.000" cy="60.000" r="1.778"/><circle cx="144.444" cy="60.000" r="1.778"/><circle cx="148.889" cy="60.000" r="1.778"/><circle cx="153.333" cy="60.000" r="1.778"/><circle cx="157.778" cy="60.000" r="1.778"/><circle cx="46.667" cy="64.444" r="1.778"/><circle cx="68.889" cy="64.444" r="1.778"/><circle cx="73.333" cy="64.444" r="1.778"/><circle cx="77.778" cy="64.444" r="1.778"/><circle cx="82.222" cy="64.444" r="1.778"/><circle cx="100.000" cy="64.444" r="1.778"/><circle cx="104.444" cy="64.444" r="1.778"/><circle cx="108.889" cy="64.444" r="1.778"/><circle cx="113.333" cy="64.444" r="1.778"/><circle cx="117.778" cy="64.444" r="1.778"/><circle cx="135.556" cy="64.444" r="1.778"/><circle cx="140.000" cy="64.444" r="1.778"/><circle cx="144.444" cy="64.444" r="1.778"/><circle cx="148.889" cy="64.444" r="1.778"/><circle cx="171.111" cy="64.444" r="1.778"/><circle cx="42.222" cy="68.889" r="1.778"/><circle cx="46.667" cy="68.889" r="1.778"/><circle cx="51.111" cy="68.889" r="1.778"/><circle cx="55.556" cy="68.889" r="1.778"/><circle cx="60.000" cy="68.889" r="1.778"/><circle cx="77.778" cy="68.889" r="1.778"/><circle cx="82.222" cy="68.889" r="1.778"/><circle cx="86.667" cy="68.889" r="1.778"/><circle cx="91.111" cy="68.889" r="1.778"/><circle cx="104.444" cy="68.889" r="1.778"/><circle cx="108.889" cy="68.889" r="1.778"/><circle cx="113.333" cy="68.889" r="1.778"/><circle cx="126.667" cy="68.889" r="1.778"/><circle cx="131.111" cy="68.889" r="1.778"/><circle cx="135.556" cy="68.889" r="1.778"/><circle cx="140.000" cy="68.889" r="1.778"/><circle cx="157.778" cy="68.889" r="1.778"/><circle cx="162.222" cy="68.889" r="1.778"/><circle cx="166.667" cy="68.889" r="1.778"/><circle cx="171.111" cy="68.889" r="1.778"/><circle cx="175.556" cy="68.889" r="1.778"/><circle cx="42.222" cy="73.333" r="1.778"/><circle cx="46.667" cy="73.333" r="1.778"/><circle cx="51.111" cy="73.333" r="1.778"/><circle cx="55.556" cy="73.333" r="1.778"/><circle cx="60.000" cy="73.333" r="1.778"/><circle cx="64.444" cy="73.333" r="1.778"/><circle cx="68.889" cy="73.333" r="1.778"/><circle cx="73.333" cy="73.333" r="1.778"/><circle cx="77.778" cy="73.333" r="1.778"/><circle cx="82.222" cy="73.333" r="1.778"/><circle cx="86.667" cy="73.333" r="1.778"/><circle cx="91.111" cy="73.333" r="1.778"/><circle cx="95.556" cy="73.333" r="1.778"/><circle cx="104.444" cy="73.333" r="1.778"/><circle cx="108.889" cy="73.333" r="1.778"/><circle cx="113.333" cy="73.333" r="1.778"/><circle cx="122.222" cy="73.333Line truncated
|
||||||
|
After Width: | Height: | Size: 23 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 456.02 360" width="456.02" height="360" role="img" aria-label="SimurgArray"><title>SimurgArray</title><g fill="#111111"><circle cx="124.306" cy="43.704" r="2.963"/><circle cx="131.714" cy="43.704" r="2.963"/><circle cx="324.306" cy="43.704" r="2.963"/><circle cx="331.714" cy="43.704" r="2.963"/><circle cx="124.306" cy="51.111" r="2.963"/><circle cx="131.714" cy="51.111" r="2.963"/><circle cx="139.121" cy="51.111" r="2.963"/><circle cx="213.195" cy="51.111" r="2.963"/><circle cx="228.010" cy="51.111" r="2.963"/><circle cx="242.825" cy="51.111" r="2.963"/><circle cx="316.899" cy="51.111" r="2.963"/><circle cx="324.306" cy="51.111" r="2.963"/><circle cx="331.714" cy="51.111" r="2.963"/><circle cx="124.306" cy="58.519" r="2.963"/><circle cx="131.714" cy="58.519" r="2.963"/><circle cx="139.121" cy="58.519" r="2.963"/><circle cx="146.529" cy="58.519" r="2.963"/><circle cx="153.936" cy="58.519" r="2.963"/><circle cx="213.195" cy="58.519" r="2.963"/><circle cx="220.603" cy="58.519" r="2.963"/><circle cx="228.010" cy="58.519" r="2.963"/><circle cx="235.417" cy="58.519" r="2.963"/><circle cx="242.825" cy="58.519" r="2.963"/><circle cx="302.084" cy="58.519" r="2.963"/><circle cx="309.491" cy="58.519" r="2.963"/><circle cx="316.899" cy="58.519" r="2.963"/><circle cx="324.306" cy="58.519" r="2.963"/><circle cx="331.714" cy="58.519" r="2.963"/><circle cx="139.121" cy="65.926" r="2.963"/><circle cx="146.529" cy="65.926" r="2.963"/><circle cx="153.936" cy="65.926" r="2.963"/><circle cx="161.343" cy="65.926" r="2.963"/><circle cx="168.751" cy="65.926" r="2.963"/><circle cx="213.195" cy="65.926" r="2.963"/><circle cx="220.603" cy="65.926" r="2.963"/><circle cx="228.010" cy="65.926" r="2.963"/><circle cx="235.417" cy="65.926" r="2.963"/><circle cx="242.825" cy="65.926" r="2.963"/><circle cx="287.269" cy="65.926" r="2.963"/><circle cx="294.677" cy="65.926" r="2.963"/><circle cx="302.084" cy="65.926" r="2.963"/><circle cx="309.491" cy="65.926" r="2.963"/><circle cx="316.899" cy="65.926" r="2.963"/><circle cx="146.529" cy="73.333" r="2.963"/><circle cx="153.936" cy="73.333" r="2.963"/><circle cx="161.343" cy="73.333" r="2.963"/><circle cx="168.751" cy="73.333" r="2.963"/><circle cx="176.158" cy="73.333" r="2.963"/><circle cx="213.195" cy="73.333" r="2.963"/><circle cx="220.603" cy="73.333" r="2.963"/><circle cx="228.010" cy="73.333" r="2.963"/><circle cx="235.417" cy="73.333" r="2.963"/><circle cx="242.825" cy="73.333" r="2.963"/><circle cx="279.862" cy="73.333" r="2.963"/><circle cx="287.269" cy="73.333" r="2.963"/><circle cx="294.677" cy="73.333" r="2.963"/><circle cx="302.084" cy="73.333" r="2.963"/><circle cx="309.491" cy="73.333" r="2.963"/><circle cx="124.306" cy="80.741" r="2.963"/><circle cx="161.343" cy="80.741" r="2.963"/><circle cx="168.751" cy="80.741" r="2.963"/><circle cx="176.158" cy="80.741" r="2.963"/><circle cx="183.566" cy="80.741" r="2.963"/><circle cx="213.195" cy="80.741" r="2.963"/><circle cx="220.603" cy="80.741" r="2.963"/><circle cx="228.010" cy="80.741" r="2.963"/><circle cx="235.417" cy="80.741" r="2.963"/><circle cx="242.825" cy="80.741" r="2.963"/><circle cx="272.454" cy="80.741" r="2.963"/><circle cx="279.862" cy="80.741" r="2.963"/><circle cx="287.269" cy="80.741" r="2.963"/><circle cx="294.677" cy="80.741" r="2.963"/><circle cx="331.714" cy="80.741" r="2.963"/><circle cx="116.899" cy="88.148" r="2.963"/><circle cx="124.306" cy="88.148" r="2.963"/><circle cx="131.714" cy="88.148" r="2.963"/><circle cx="139.121" cy="88.148" r="2.963"/><circle cx="146.529" cy="88.148" r="2.963"/><circle cx="176.158" cy="88.148" r="2.963"/><circle cx="183.566" cy="88.148" r="2.963"/><circle cx="190.973" cy="88.148" r="2.963"/><circle cx="198.380" cy="88.148" r="2.963"/><circle cx="220.603" cy="88.148" r="2.963"/><circle cx="228.010" cy="88.148" r="2.963"/><circle cx="235.417" cy="88.148" r="2.963"/><circle cx="257.640" cy="88.148" r="2.963"/><circle cx="265.047" cy="88.148" r="2.963"/><circle cx="272.454" cy="88.148" r="2.963"/><circle cx="279.862" cy="88.148" r="2.963"/><circle cx="309.491" cy="88.148" r="2.963"/><circle cx="316.899" cy="88.148" r="2.963"/><circle cx="324.306" cy="88.148" r="2.963"/><circle cx="331.714" cy="88.148" r="2.963"/><circle cx="339.121" cy="88.148" r="2.963"/><circle cx="116.899" cy="95.556" r="2.963"/><circle cx="124.306" cy="95.556" r="2.963"/><circle cx="131.714" cy="95.556" r="2.963"/><circle cx="139.121" cy="95.556" r="2.963"/><circle cx="146.529" cy="95.556" r="2.963"/><circle cx="153.936" cy="95.556" r="2.963"/><circle cx="161.343" cy="95.556" r="2.963"/><circle cx="168.751" cy="95.556" r="2.963"/><circle cx="176.158" cy="95.556" r="2.963"/><circle cx="183.566" cy="95.556" r="2.963"/><circle cx="190.973" cy="95.556" r="2.963"/><circle cx="198.380" cy="95.556" r="2.963"/><circle cx="205.788" cy="95.556" r="2.963"/><circle cx="220.603" cy="95.556" r="2.963"/><circle cx="228.010" cy="95.556" r="2.963"/><circle cx="235.417" cy="95.55Line truncated
|
||||||
|
After Width: | Height: | Size: 23 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 456.02 360" width="456.02" height="360" role="img" aria-label="SimurgArray"><title>SimurgArray</title><rect width="456.0199999999999" height="360.0" fill="#1E2240"/><g fill="#D4A017"><circle cx="124.306" cy="43.704" r="2.963"/><circle cx="131.714" cy="43.704" r="2.963"/><circle cx="324.306" cy="43.704" r="2.963"/><circle cx="331.714" cy="43.704" r="2.963"/><circle cx="124.306" cy="51.111" r="2.963"/><circle cx="131.714" cy="51.111" r="2.963"/><circle cx="139.121" cy="51.111" r="2.963"/><circle cx="213.195" cy="51.111" r="2.963"/><circle cx="228.010" cy="51.111" r="2.963"/><circle cx="242.825" cy="51.111" r="2.963"/><circle cx="316.899" cy="51.111" r="2.963"/><circle cx="324.306" cy="51.111" r="2.963"/><circle cx="331.714" cy="51.111" r="2.963"/><circle cx="124.306" cy="58.519" r="2.963"/><circle cx="131.714" cy="58.519" r="2.963"/><circle cx="139.121" cy="58.519" r="2.963"/><circle cx="146.529" cy="58.519" r="2.963"/><circle cx="153.936" cy="58.519" r="2.963"/><circle cx="213.195" cy="58.519" r="2.963"/><circle cx="220.603" cy="58.519" r="2.963"/><circle cx="228.010" cy="58.519" r="2.963"/><circle cx="235.417" cy="58.519" r="2.963"/><circle cx="242.825" cy="58.519" r="2.963"/><circle cx="302.084" cy="58.519" r="2.963"/><circle cx="309.491" cy="58.519" r="2.963"/><circle cx="316.899" cy="58.519" r="2.963"/><circle cx="324.306" cy="58.519" r="2.963"/><circle cx="331.714" cy="58.519" r="2.963"/><circle cx="139.121" cy="65.926" r="2.963"/><circle cx="146.529" cy="65.926" r="2.963"/><circle cx="153.936" cy="65.926" r="2.963"/><circle cx="161.343" cy="65.926" r="2.963"/><circle cx="168.751" cy="65.926" r="2.963"/><circle cx="213.195" cy="65.926" r="2.963"/><circle cx="220.603" cy="65.926" r="2.963"/><circle cx="228.010" cy="65.926" r="2.963"/><circle cx="235.417" cy="65.926" r="2.963"/><circle cx="242.825" cy="65.926" r="2.963"/><circle cx="287.269" cy="65.926" r="2.963"/><circle cx="294.677" cy="65.926" r="2.963"/><circle cx="302.084" cy="65.926" r="2.963"/><circle cx="309.491" cy="65.926" r="2.963"/><circle cx="316.899" cy="65.926" r="2.963"/><circle cx="146.529" cy="73.333" r="2.963"/><circle cx="153.936" cy="73.333" r="2.963"/><circle cx="161.343" cy="73.333" r="2.963"/><circle cx="168.751" cy="73.333" r="2.963"/><circle cx="176.158" cy="73.333" r="2.963"/><circle cx="213.195" cy="73.333" r="2.963"/><circle cx="220.603" cy="73.333" r="2.963"/><circle cx="228.010" cy="73.333" r="2.963"/><circle cx="235.417" cy="73.333" r="2.963"/><circle cx="242.825" cy="73.333" r="2.963"/><circle cx="279.862" cy="73.333" r="2.963"/><circle cx="287.269" cy="73.333" r="2.963"/><circle cx="294.677" cy="73.333" r="2.963"/><circle cx="302.084" cy="73.333" r="2.963"/><circle cx="309.491" cy="73.333" r="2.963"/><circle cx="124.306" cy="80.741" r="2.963"/><circle cx="161.343" cy="80.741" r="2.963"/><circle cx="168.751" cy="80.741" r="2.963"/><circle cx="176.158" cy="80.741" r="2.963"/><circle cx="183.566" cy="80.741" r="2.963"/><circle cx="213.195" cy="80.741" r="2.963"/><circle cx="220.603" cy="80.741" r="2.963"/><circle cx="228.010" cy="80.741" r="2.963"/><circle cx="235.417" cy="80.741" r="2.963"/><circle cx="242.825" cy="80.741" r="2.963"/><circle cx="272.454" cy="80.741" r="2.963"/><circle cx="279.862" cy="80.741" r="2.963"/><circle cx="287.269" cy="80.741" r="2.963"/><circle cx="294.677" cy="80.741" r="2.963"/><circle cx="331.714" cy="80.741" r="2.963"/><circle cx="116.899" cy="88.148" r="2.963"/><circle cx="124.306" cy="88.148" r="2.963"/><circle cx="131.714" cy="88.148" r="2.963"/><circle cx="139.121" cy="88.148" r="2.963"/><circle cx="146.529" cy="88.148" r="2.963"/><circle cx="176.158" cy="88.148" r="2.963"/><circle cx="183.566" cy="88.148" r="2.963"/><circle cx="190.973" cy="88.148" r="2.963"/><circle cx="198.380" cy="88.148" r="2.963"/><circle cx="220.603" cy="88.148" r="2.963"/><circle cx="228.010" cy="88.148" r="2.963"/><circle cx="235.417" cy="88.148" r="2.963"/><circle cx="257.640" cy="88.148" r="2.963"/><circle cx="265.047" cy="88.148" r="2.963"/><circle cx="272.454" cy="88.148" r="2.963"/><circle cx="279.862" cy="88.148" r="2.963"/><circle cx="309.491" cy="88.148" r="2.963"/><circle cx="316.899" cy="88.148" r="2.963"/><circle cx="324.306" cy="88.148" r="2.963"/><circle cx="331.714" cy="88.148" r="2.963"/><circle cx="339.121" cy="88.148" r="2.963"/><circle cx="116.899" cy="95.556" r="2.963"/><circle cx="124.306" cy="95.556" r="2.963"/><circle cx="131.714" cy="95.556" r="2.963"/><circle cx="139.121" cy="95.556" r="2.963"/><circle cx="146.529" cy="95.556" r="2.963"/><circle cx="153.936" cy="95.556" r="2.963"/><circle cx="161.343" cy="95.556" r="2.963"/><circle cx="168.751" cy="95.556" r="2.963"/><circle cx="176.158" cy="95.556" r="2.963"/><circle cx="183.566" cy="95.556" r="2.963"/><circle cx="190.973" cy="95.556" r="2.963"/><circle cx="198.380" cy="95.556" r="2.963"/><circle cx="205.788" cy="95.556" r="2.963"/><circle cx="220.603" cy="95.556" r="2.963"/><circle cx=Line truncated
|
||||||
|
After Width: | Height: | Size: 23 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 456.02 360" width="456.02" height="360" role="img" aria-label="SimurgArray"><title>SimurgArray</title><rect width="456.0199999999999" height="360.0" fill="#F7F5EF"/><g fill="#A87A00"><circle cx="124.306" cy="43.704" r="2.963"/><circle cx="131.714" cy="43.704" r="2.963"/><circle cx="324.306" cy="43.704" r="2.963"/><circle cx="331.714" cy="43.704" r="2.963"/><circle cx="124.306" cy="51.111" r="2.963"/><circle cx="131.714" cy="51.111" r="2.963"/><circle cx="139.121" cy="51.111" r="2.963"/><circle cx="213.195" cy="51.111" r="2.963"/><circle cx="228.010" cy="51.111" r="2.963"/><circle cx="242.825" cy="51.111" r="2.963"/><circle cx="316.899" cy="51.111" r="2.963"/><circle cx="324.306" cy="51.111" r="2.963"/><circle cx="331.714" cy="51.111" r="2.963"/><circle cx="124.306" cy="58.519" r="2.963"/><circle cx="131.714" cy="58.519" r="2.963"/><circle cx="139.121" cy="58.519" r="2.963"/><circle cx="146.529" cy="58.519" r="2.963"/><circle cx="153.936" cy="58.519" r="2.963"/><circle cx="213.195" cy="58.519" r="2.963"/><circle cx="220.603" cy="58.519" r="2.963"/><circle cx="228.010" cy="58.519" r="2.963"/><circle cx="235.417" cy="58.519" r="2.963"/><circle cx="242.825" cy="58.519" r="2.963"/><circle cx="302.084" cy="58.519" r="2.963"/><circle cx="309.491" cy="58.519" r="2.963"/><circle cx="316.899" cy="58.519" r="2.963"/><circle cx="324.306" cy="58.519" r="2.963"/><circle cx="331.714" cy="58.519" r="2.963"/><circle cx="139.121" cy="65.926" r="2.963"/><circle cx="146.529" cy="65.926" r="2.963"/><circle cx="153.936" cy="65.926" r="2.963"/><circle cx="161.343" cy="65.926" r="2.963"/><circle cx="168.751" cy="65.926" r="2.963"/><circle cx="213.195" cy="65.926" r="2.963"/><circle cx="220.603" cy="65.926" r="2.963"/><circle cx="228.010" cy="65.926" r="2.963"/><circle cx="235.417" cy="65.926" r="2.963"/><circle cx="242.825" cy="65.926" r="2.963"/><circle cx="287.269" cy="65.926" r="2.963"/><circle cx="294.677" cy="65.926" r="2.963"/><circle cx="302.084" cy="65.926" r="2.963"/><circle cx="309.491" cy="65.926" r="2.963"/><circle cx="316.899" cy="65.926" r="2.963"/><circle cx="146.529" cy="73.333" r="2.963"/><circle cx="153.936" cy="73.333" r="2.963"/><circle cx="161.343" cy="73.333" r="2.963"/><circle cx="168.751" cy="73.333" r="2.963"/><circle cx="176.158" cy="73.333" r="2.963"/><circle cx="213.195" cy="73.333" r="2.963"/><circle cx="220.603" cy="73.333" r="2.963"/><circle cx="228.010" cy="73.333" r="2.963"/><circle cx="235.417" cy="73.333" r="2.963"/><circle cx="242.825" cy="73.333" r="2.963"/><circle cx="279.862" cy="73.333" r="2.963"/><circle cx="287.269" cy="73.333" r="2.963"/><circle cx="294.677" cy="73.333" r="2.963"/><circle cx="302.084" cy="73.333" r="2.963"/><circle cx="309.491" cy="73.333" r="2.963"/><circle cx="124.306" cy="80.741" r="2.963"/><circle cx="161.343" cy="80.741" r="2.963"/><circle cx="168.751" cy="80.741" r="2.963"/><circle cx="176.158" cy="80.741" r="2.963"/><circle cx="183.566" cy="80.741" r="2.963"/><circle cx="213.195" cy="80.741" r="2.963"/><circle cx="220.603" cy="80.741" r="2.963"/><circle cx="228.010" cy="80.741" r="2.963"/><circle cx="235.417" cy="80.741" r="2.963"/><circle cx="242.825" cy="80.741" r="2.963"/><circle cx="272.454" cy="80.741" r="2.963"/><circle cx="279.862" cy="80.741" r="2.963"/><circle cx="287.269" cy="80.741" r="2.963"/><circle cx="294.677" cy="80.741" r="2.963"/><circle cx="331.714" cy="80.741" r="2.963"/><circle cx="116.899" cy="88.148" r="2.963"/><circle cx="124.306" cy="88.148" r="2.963"/><circle cx="131.714" cy="88.148" r="2.963"/><circle cx="139.121" cy="88.148" r="2.963"/><circle cx="146.529" cy="88.148" r="2.963"/><circle cx="176.158" cy="88.148" r="2.963"/><circle cx="183.566" cy="88.148" r="2.963"/><circle cx="190.973" cy="88.148" r="2.963"/><circle cx="198.380" cy="88.148" r="2.963"/><circle cx="220.603" cy="88.148" r="2.963"/><circle cx="228.010" cy="88.148" r="2.963"/><circle cx="235.417" cy="88.148" r="2.963"/><circle cx="257.640" cy="88.148" r="2.963"/><circle cx="265.047" cy="88.148" r="2.963"/><circle cx="272.454" cy="88.148" r="2.963"/><circle cx="279.862" cy="88.148" r="2.963"/><circle cx="309.491" cy="88.148" r="2.963"/><circle cx="316.899" cy="88.148" r="2.963"/><circle cx="324.306" cy="88.148" r="2.963"/><circle cx="331.714" cy="88.148" r="2.963"/><circle cx="339.121" cy="88.148" r="2.963"/><circle cx="116.899" cy="95.556" r="2.963"/><circle cx="124.306" cy="95.556" r="2.963"/><circle cx="131.714" cy="95.556" r="2.963"/><circle cx="139.121" cy="95.556" r="2.963"/><circle cx="146.529" cy="95.556" r="2.963"/><circle cx="153.936" cy="95.556" r="2.963"/><circle cx="161.343" cy="95.556" r="2.963"/><circle cx="168.751" cy="95.556" r="2.963"/><circle cx="176.158" cy="95.556" r="2.963"/><circle cx="183.566" cy="95.556" r="2.963"/><circle cx="190.973" cy="95.556" r="2.963"/><circle cx="198.380" cy="95.556" r="2.963"/><circle cx="205.788" cy="95.556" r="2.963"/><circle cx="220.603" cy="95.556" r="2.963"/><circle cx=Line truncated
|
||||||
|
After Width: | Height: | Size: 23 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 456.02 360" width="456.02" height="360" role="img" aria-label="SimurgArray"><title>SimurgArray</title><g fill="#FFFFFF"><circle cx="124.306" cy="43.704" r="2.963"/><circle cx="131.714" cy="43.704" r="2.963"/><circle cx="324.306" cy="43.704" r="2.963"/><circle cx="331.714" cy="43.704" r="2.963"/><circle cx="124.306" cy="51.111" r="2.963"/><circle cx="131.714" cy="51.111" r="2.963"/><circle cx="139.121" cy="51.111" r="2.963"/><circle cx="213.195" cy="51.111" r="2.963"/><circle cx="228.010" cy="51.111" r="2.963"/><circle cx="242.825" cy="51.111" r="2.963"/><circle cx="316.899" cy="51.111" r="2.963"/><circle cx="324.306" cy="51.111" r="2.963"/><circle cx="331.714" cy="51.111" r="2.963"/><circle cx="124.306" cy="58.519" r="2.963"/><circle cx="131.714" cy="58.519" r="2.963"/><circle cx="139.121" cy="58.519" r="2.963"/><circle cx="146.529" cy="58.519" r="2.963"/><circle cx="153.936" cy="58.519" r="2.963"/><circle cx="213.195" cy="58.519" r="2.963"/><circle cx="220.603" cy="58.519" r="2.963"/><circle cx="228.010" cy="58.519" r="2.963"/><circle cx="235.417" cy="58.519" r="2.963"/><circle cx="242.825" cy="58.519" r="2.963"/><circle cx="302.084" cy="58.519" r="2.963"/><circle cx="309.491" cy="58.519" r="2.963"/><circle cx="316.899" cy="58.519" r="2.963"/><circle cx="324.306" cy="58.519" r="2.963"/><circle cx="331.714" cy="58.519" r="2.963"/><circle cx="139.121" cy="65.926" r="2.963"/><circle cx="146.529" cy="65.926" r="2.963"/><circle cx="153.936" cy="65.926" r="2.963"/><circle cx="161.343" cy="65.926" r="2.963"/><circle cx="168.751" cy="65.926" r="2.963"/><circle cx="213.195" cy="65.926" r="2.963"/><circle cx="220.603" cy="65.926" r="2.963"/><circle cx="228.010" cy="65.926" r="2.963"/><circle cx="235.417" cy="65.926" r="2.963"/><circle cx="242.825" cy="65.926" r="2.963"/><circle cx="287.269" cy="65.926" r="2.963"/><circle cx="294.677" cy="65.926" r="2.963"/><circle cx="302.084" cy="65.926" r="2.963"/><circle cx="309.491" cy="65.926" r="2.963"/><circle cx="316.899" cy="65.926" r="2.963"/><circle cx="146.529" cy="73.333" r="2.963"/><circle cx="153.936" cy="73.333" r="2.963"/><circle cx="161.343" cy="73.333" r="2.963"/><circle cx="168.751" cy="73.333" r="2.963"/><circle cx="176.158" cy="73.333" r="2.963"/><circle cx="213.195" cy="73.333" r="2.963"/><circle cx="220.603" cy="73.333" r="2.963"/><circle cx="228.010" cy="73.333" r="2.963"/><circle cx="235.417" cy="73.333" r="2.963"/><circle cx="242.825" cy="73.333" r="2.963"/><circle cx="279.862" cy="73.333" r="2.963"/><circle cx="287.269" cy="73.333" r="2.963"/><circle cx="294.677" cy="73.333" r="2.963"/><circle cx="302.084" cy="73.333" r="2.963"/><circle cx="309.491" cy="73.333" r="2.963"/><circle cx="124.306" cy="80.741" r="2.963"/><circle cx="161.343" cy="80.741" r="2.963"/><circle cx="168.751" cy="80.741" r="2.963"/><circle cx="176.158" cy="80.741" r="2.963"/><circle cx="183.566" cy="80.741" r="2.963"/><circle cx="213.195" cy="80.741" r="2.963"/><circle cx="220.603" cy="80.741" r="2.963"/><circle cx="228.010" cy="80.741" r="2.963"/><circle cx="235.417" cy="80.741" r="2.963"/><circle cx="242.825" cy="80.741" r="2.963"/><circle cx="272.454" cy="80.741" r="2.963"/><circle cx="279.862" cy="80.741" r="2.963"/><circle cx="287.269" cy="80.741" r="2.963"/><circle cx="294.677" cy="80.741" r="2.963"/><circle cx="331.714" cy="80.741" r="2.963"/><circle cx="116.899" cy="88.148" r="2.963"/><circle cx="124.306" cy="88.148" r="2.963"/><circle cx="131.714" cy="88.148" r="2.963"/><circle cx="139.121" cy="88.148" r="2.963"/><circle cx="146.529" cy="88.148" r="2.963"/><circle cx="176.158" cy="88.148" r="2.963"/><circle cx="183.566" cy="88.148" r="2.963"/><circle cx="190.973" cy="88.148" r="2.963"/><circle cx="198.380" cy="88.148" r="2.963"/><circle cx="220.603" cy="88.148" r="2.963"/><circle cx="228.010" cy="88.148" r="2.963"/><circle cx="235.417" cy="88.148" r="2.963"/><circle cx="257.640" cy="88.148" r="2.963"/><circle cx="265.047" cy="88.148" r="2.963"/><circle cx="272.454" cy="88.148" r="2.963"/><circle cx="279.862" cy="88.148" r="2.963"/><circle cx="309.491" cy="88.148" r="2.963"/><circle cx="316.899" cy="88.148" r="2.963"/><circle cx="324.306" cy="88.148" r="2.963"/><circle cx="331.714" cy="88.148" r="2.963"/><circle cx="339.121" cy="88.148" r="2.963"/><circle cx="116.899" cy="95.556" r="2.963"/><circle cx="124.306" cy="95.556" r="2.963"/><circle cx="131.714" cy="95.556" r="2.963"/><circle cx="139.121" cy="95.556" r="2.963"/><circle cx="146.529" cy="95.556" r="2.963"/><circle cx="153.936" cy="95.556" r="2.963"/><circle cx="161.343" cy="95.556" r="2.963"/><circle cx="168.751" cy="95.556" r="2.963"/><circle cx="176.158" cy="95.556" r="2.963"/><circle cx="183.566" cy="95.556" r="2.963"/><circle cx="190.973" cy="95.556" r="2.963"/><circle cx="198.380" cy="95.556" r="2.963"/><circle cx="205.788" cy="95.556" r="2.963"/><circle cx="220.603" cy="95.556" r="2.963"/><circle cx="228.010" cy="95.556" r="2.963"/><circle cx="235.417" cy="95.55Line truncated
|
||||||
|
After Width: | Height: | Size: 23 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 33 29" width="33" height="29" role="img" aria-label="SimurgArray"><title>SimurgArray</title><g fill="#111111"><circle cx="2.500" cy="1.500" r="0.400"/><circle cx="3.500" cy="1.500" r="0.400"/><circle cx="29.500" cy="1.500" r="0.400"/><circle cx="30.500" cy="1.500" r="0.400"/><circle cx="2.500" cy="2.500" r="0.400"/><circle cx="3.500" cy="2.500" r="0.400"/><circle cx="4.500" cy="2.500" r="0.400"/><circle cx="14.500" cy="2.500" r="0.400"/><circle cx="16.500" cy="2.500" r="0.400"/><circle cx="18.500" cy="2.500" r="0.400"/><circle cx="28.500" cy="2.500" r="0.400"/><circle cx="29.500" cy="2.500" r="0.400"/><circle cx="30.500" cy="2.500" r="0.400"/><circle cx="2.500" cy="3.500" r="0.400"/><circle cx="3.500" cy="3.500" r="0.400"/><circle cx="4.500" cy="3.500" r="0.400"/><circle cx="5.500" cy="3.500" r="0.400"/><circle cx="6.500" cy="3.500" r="0.400"/><circle cx="14.500" cy="3.500" r="0.400"/><circle cx="15.500" cy="3.500" r="0.400"/><circle cx="16.500" cy="3.500" r="0.400"/><circle cx="17.500" cy="3.500" r="0.400"/><circle cx="18.500" cy="3.500" r="0.400"/><circle cx="26.500" cy="3.500" r="0.400"/><circle cx="27.500" cy="3.500" r="0.400"/><circle cx="28.500" cy="3.500" r="0.400"/><circle cx="29.500" cy="3.500" r="0.400"/><circle cx="30.500" cy="3.500" r="0.400"/><circle cx="4.500" cy="4.500" r="0.400"/><circle cx="5.500" cy="4.500" r="0.400"/><circle cx="6.500" cy="4.500" r="0.400"/><circle cx="7.500" cy="4.500" r="0.400"/><circle cx="8.500" cy="4.500" r="0.400"/><circle cx="14.500" cy="4.500" r="0.400"/><circle cx="15.500" cy="4.500" r="0.400"/><circle cx="16.500" cy="4.500" r="0.400"/><circle cx="17.500" cy="4.500" r="0.400"/><circle cx="18.500" cy="4.500" r="0.400"/><circle cx="24.500" cy="4.500" r="0.400"/><circle cx="25.500" cy="4.500" r="0.400"/><circle cx="26.500" cy="4.500" r="0.400"/><circle cx="27.500" cy="4.500" r="0.400"/><circle cx="28.500" cy="4.500" r="0.400"/><circle cx="5.500" cy="5.500" r="0.400"/><circle cx="6.500" cy="5.500" r="0.400"/><circle cx="7.500" cy="5.500" r="0.400"/><circle cx="8.500" cy="5.500" r="0.400"/><circle cx="9.500" cy="5.500" r="0.400"/><circle cx="14.500" cy="5.500" r="0.400"/><circle cx="15.500" cy="5.500" r="0.400"/><circle cx="16.500" cy="5.500" r="0.400"/><circle cx="17.500" cy="5.500" r="0.400"/><circle cx="18.500" cy="5.500" r="0.400"/><circle cx="23.500" cy="5.500" r="0.400"/><circle cx="24.500" cy="5.500" r="0.400"/><circle cx="25.500" cy="5.500" r="0.400"/><circle cx="26.500" cy="5.500" r="0.400"/><circle cx="27.500" cy="5.500" r="0.400"/><circle cx="2.500" cy="6.500" r="0.400"/><circle cx="7.500" cy="6.500" r="0.400"/><circle cx="8.500" cy="6.500" r="0.400"/><circle cx="9.500" cy="6.500" r="0.400"/><circle cx="10.500" cy="6.500" r="0.400"/><circle cx="14.500" cy="6.500" r="0.400"/><circle cx="15.500" cy="6.500" r="0.400"/><circle cx="16.500" cy="6.500" r="0.400"/><circle cx="17.500" cy="6.500" r="0.400"/><circle cx="18.500" cy="6.500" r="0.400"/><circle cx="22.500" cy="6.500" r="0.400"/><circle cx="23.500" cy="6.500" r="0.400"/><circle cx="24.500" cy="6.500" r="0.400"/><circle cx="25.500" cy="6.500" r="0.400"/><circle cx="30.500" cy="6.500" r="0.400"/><circle cx="1.500" cy="7.500" r="0.400"/><circle cx="2.500" cy="7.500" r="0.400"/><circle cx="3.500" cy="7.500" r="0.400"/><circle cx="4.500" cy="7.500" r="0.400"/><circle cx="5.500" cy="7.500" r="0.400"/><circle cx="9.500" cy="7.500" r="0.400"/><circle cx="10.500" cy="7.500" r="0.400"/><circle cx="11.500" cy="7.500" r="0.400"/><circle cx="12.500" cy="7.500" r="0.400"/><circle cx="15.500" cy="7.500" r="0.400"/><circle cx="16.500" cy="7.500" r="0.400"/><circle cx="17.500" cy="7.500" r="0.400"/><circle cx="20.500" cy="7.500" r="0.400"/><circle cx="21.500" cy="7.500" r="0.400"/><circle cx="22.500" cy="7.500" r="0.400"/><circle cx="23.500" cy="7.500" r="0.400"/><circle cx="27.500" cy="7.500" r="0.400"/><circle cx="28.500" cy="7.500" r="0.400"/><circle cx="29.500" cy="7.500" r="0.400"/><circle cx="30.500" cy="7.500" r="0.400"/><circle cx="31.500" cy="7.500" r="0.400"/><circle cx="1.500" cy="8.500" r="0.400"/><circle cx="2.500" cy="8.500" r="0.400"/><circle cx="3.500" cy="8.500" r="0.400"/><circle cx="4.500" cy="8.500" r="0.400"/><circle cx="5.500" cy="8.500" r="0.400"/><circle cx="6.500" cy="8.500" r="0.400"/><circle cx="7.500" cy="8.500" r="0.400"/><circle cx="8.500" cy="8.500" r="0.400"/><circle cx="9.500" cy="8.500" r="0.400"/><circle cx="10.500" cy="8.500" r="0.400"/><circle cx="11.500" cy="8.500" r="0.400"/><circle cx="12.500" cy="8.500" r="0.400"/><circle cx="13.500" cy="8.500" r="0.400"/><circle cx="15.500" cy="8.500" r="0.400"/><circle cx="16.500" cy="8.500" r="0.400"/><circle cx="17.500" cy="8.500" r="0.400"/><circle cx="19.500" cy="8.500" r="0.400"/><circle cx="20.500" cy="8.500" r="0.400"/><circle cx="21.500" cy="8.500" r="0.400"/><circle cx="22.500" cy="8.500" r="0.400"/><circle cx="23.500" cy="8.500" r="0.400"/><circle cx="24.500" cy="8.500" r="0.400"/><ciLine truncated
|
||||||
|
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 33 29" width="33" height="29" role="img" aria-label="SimurgArray"><title>SimurgArray</title><g fill="#D4A017"><circle cx="2.500" cy="1.500" r="0.400"/><circle cx="3.500" cy="1.500" r="0.400"/><circle cx="29.500" cy="1.500" r="0.400"/><circle cx="30.500" cy="1.500" r="0.400"/><circle cx="2.500" cy="2.500" r="0.400"/><circle cx="3.500" cy="2.500" r="0.400"/><circle cx="4.500" cy="2.500" r="0.400"/><circle cx="14.500" cy="2.500" r="0.400"/><circle cx="16.500" cy="2.500" r="0.400"/><circle cx="18.500" cy="2.500" r="0.400"/><circle cx="28.500" cy="2.500" r="0.400"/><circle cx="29.500" cy="2.500" r="0.400"/><circle cx="30.500" cy="2.500" r="0.400"/><circle cx="2.500" cy="3.500" r="0.400"/><circle cx="3.500" cy="3.500" r="0.400"/><circle cx="4.500" cy="3.500" r="0.400"/><circle cx="5.500" cy="3.500" r="0.400"/><circle cx="6.500" cy="3.500" r="0.400"/><circle cx="14.500" cy="3.500" r="0.400"/><circle cx="15.500" cy="3.500" r="0.400"/><circle cx="16.500" cy="3.500" r="0.400"/><circle cx="17.500" cy="3.500" r="0.400"/><circle cx="18.500" cy="3.500" r="0.400"/><circle cx="26.500" cy="3.500" r="0.400"/><circle cx="27.500" cy="3.500" r="0.400"/><circle cx="28.500" cy="3.500" r="0.400"/><circle cx="29.500" cy="3.500" r="0.400"/><circle cx="30.500" cy="3.500" r="0.400"/><circle cx="4.500" cy="4.500" r="0.400"/><circle cx="5.500" cy="4.500" r="0.400"/><circle cx="6.500" cy="4.500" r="0.400"/><circle cx="7.500" cy="4.500" r="0.400"/><circle cx="8.500" cy="4.500" r="0.400"/><circle cx="14.500" cy="4.500" r="0.400"/><circle cx="15.500" cy="4.500" r="0.400"/><circle cx="16.500" cy="4.500" r="0.400"/><circle cx="17.500" cy="4.500" r="0.400"/><circle cx="18.500" cy="4.500" r="0.400"/><circle cx="24.500" cy="4.500" r="0.400"/><circle cx="25.500" cy="4.500" r="0.400"/><circle cx="26.500" cy="4.500" r="0.400"/><circle cx="27.500" cy="4.500" r="0.400"/><circle cx="28.500" cy="4.500" r="0.400"/><circle cx="5.500" cy="5.500" r="0.400"/><circle cx="6.500" cy="5.500" r="0.400"/><circle cx="7.500" cy="5.500" r="0.400"/><circle cx="8.500" cy="5.500" r="0.400"/><circle cx="9.500" cy="5.500" r="0.400"/><circle cx="14.500" cy="5.500" r="0.400"/><circle cx="15.500" cy="5.500" r="0.400"/><circle cx="16.500" cy="5.500" r="0.400"/><circle cx="17.500" cy="5.500" r="0.400"/><circle cx="18.500" cy="5.500" r="0.400"/><circle cx="23.500" cy="5.500" r="0.400"/><circle cx="24.500" cy="5.500" r="0.400"/><circle cx="25.500" cy="5.500" r="0.400"/><circle cx="26.500" cy="5.500" r="0.400"/><circle cx="27.500" cy="5.500" r="0.400"/><circle cx="2.500" cy="6.500" r="0.400"/><circle cx="7.500" cy="6.500" r="0.400"/><circle cx="8.500" cy="6.500" r="0.400"/><circle cx="9.500" cy="6.500" r="0.400"/><circle cx="10.500" cy="6.500" r="0.400"/><circle cx="14.500" cy="6.500" r="0.400"/><circle cx="15.500" cy="6.500" r="0.400"/><circle cx="16.500" cy="6.500" r="0.400"/><circle cx="17.500" cy="6.500" r="0.400"/><circle cx="18.500" cy="6.500" r="0.400"/><circle cx="22.500" cy="6.500" r="0.400"/><circle cx="23.500" cy="6.500" r="0.400"/><circle cx="24.500" cy="6.500" r="0.400"/><circle cx="25.500" cy="6.500" r="0.400"/><circle cx="30.500" cy="6.500" r="0.400"/><circle cx="1.500" cy="7.500" r="0.400"/><circle cx="2.500" cy="7.500" r="0.400"/><circle cx="3.500" cy="7.500" r="0.400"/><circle cx="4.500" cy="7.500" r="0.400"/><circle cx="5.500" cy="7.500" r="0.400"/><circle cx="9.500" cy="7.500" r="0.400"/><circle cx="10.500" cy="7.500" r="0.400"/><circle cx="11.500" cy="7.500" r="0.400"/><circle cx="12.500" cy="7.500" r="0.400"/><circle cx="15.500" cy="7.500" r="0.400"/><circle cx="16.500" cy="7.500" r="0.400"/><circle cx="17.500" cy="7.500" r="0.400"/><circle cx="20.500" cy="7.500" r="0.400"/><circle cx="21.500" cy="7.500" r="0.400"/><circle cx="22.500" cy="7.500" r="0.400"/><circle cx="23.500" cy="7.500" r="0.400"/><circle cx="27.500" cy="7.500" r="0.400"/><circle cx="28.500" cy="7.500" r="0.400"/><circle cx="29.500" cy="7.500" r="0.400"/><circle cx="30.500" cy="7.500" r="0.400"/><circle cx="31.500" cy="7.500" r="0.400"/><circle cx="1.500" cy="8.500" r="0.400"/><circle cx="2.500" cy="8.500" r="0.400"/><circle cx="3.500" cy="8.500" r="0.400"/><circle cx="4.500" cy="8.500" r="0.400"/><circle cx="5.500" cy="8.500" r="0.400"/><circle cx="6.500" cy="8.500" r="0.400"/><circle cx="7.500" cy="8.500" r="0.400"/><circle cx="8.500" cy="8.500" r="0.400"/><circle cx="9.500" cy="8.500" r="0.400"/><circle cx="10.500" cy="8.500" r="0.400"/><circle cx="11.500" cy="8.500" r="0.400"/><circle cx="12.500" cy="8.500" r="0.400"/><circle cx="13.500" cy="8.500" r="0.400"/><circle cx="15.500" cy="8.500" r="0.400"/><circle cx="16.500" cy="8.500" r="0.400"/><circle cx="17.500" cy="8.500" r="0.400"/><circle cx="19.500" cy="8.500" r="0.400"/><circle cx="20.500" cy="8.500" r="0.400"/><circle cx="21.500" cy="8.500" r="0.400"/><circle cx="22.500" cy="8.500" r="0.400"/><circle cx="23.500" cy="8.500" r="0.400"/><circle cx="24.500" cy="8.500" r="0.400"/><ciLine truncated
|
||||||
|
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 33 29" width="33" height="29" role="img" aria-label="SimurgArray"><title>SimurgArray</title><g fill="#D4A017"><circle cx="2.500" cy="1.500" r="0.400"/><circle cx="3.500" cy="1.500" r="0.400"/><circle cx="29.500" cy="1.500" r="0.400"/><circle cx="30.500" cy="1.500" r="0.400"/><circle cx="2.500" cy="2.500" r="0.400"/><circle cx="3.500" cy="2.500" r="0.400"/><circle cx="4.500" cy="2.500" r="0.400"/><circle cx="14.500" cy="2.500" r="0.400"/><circle cx="16.500" cy="2.500" r="0.400"/><circle cx="18.500" cy="2.500" r="0.400"/><circle cx="28.500" cy="2.500" r="0.400"/><circle cx="29.500" cy="2.500" r="0.400"/><circle cx="30.500" cy="2.500" r="0.400"/><circle cx="2.500" cy="3.500" r="0.400"/><circle cx="3.500" cy="3.500" r="0.400"/><circle cx="4.500" cy="3.500" r="0.400"/><circle cx="5.500" cy="3.500" r="0.400"/><circle cx="6.500" cy="3.500" r="0.400"/><circle cx="14.500" cy="3.500" r="0.400"/><circle cx="15.500" cy="3.500" r="0.400"/><circle cx="16.500" cy="3.500" r="0.400"/><circle cx="17.500" cy="3.500" r="0.400"/><circle cx="18.500" cy="3.500" r="0.400"/><circle cx="26.500" cy="3.500" r="0.400"/><circle cx="27.500" cy="3.500" r="0.400"/><circle cx="28.500" cy="3.500" r="0.400"/><circle cx="29.500" cy="3.500" r="0.400"/><circle cx="30.500" cy="3.500" r="0.400"/><circle cx="4.500" cy="4.500" r="0.400"/><circle cx="5.500" cy="4.500" r="0.400"/><circle cx="6.500" cy="4.500" r="0.400"/><circle cx="7.500" cy="4.500" r="0.400"/><circle cx="8.500" cy="4.500" r="0.400"/><circle cx="14.500" cy="4.500" r="0.400"/><circle cx="15.500" cy="4.500" r="0.400"/><circle cx="16.500" cy="4.500" r="0.400"/><circle cx="17.500" cy="4.500" r="0.400"/><circle cx="18.500" cy="4.500" r="0.400"/><circle cx="24.500" cy="4.500" r="0.400"/><circle cx="25.500" cy="4.500" r="0.400"/><circle cx="26.500" cy="4.500" r="0.400"/><circle cx="27.500" cy="4.500" r="0.400"/><circle cx="28.500" cy="4.500" r="0.400"/><circle cx="5.500" cy="5.500" r="0.400"/><circle cx="6.500" cy="5.500" r="0.400"/><circle cx="7.500" cy="5.500" r="0.400"/><circle cx="8.500" cy="5.500" r="0.400"/><circle cx="9.500" cy="5.500" r="0.400"/><circle cx="14.500" cy="5.500" r="0.400"/><circle cx="15.500" cy="5.500" r="0.400"/><circle cx="16.500" cy="5.500" r="0.400"/><circle cx="17.500" cy="5.500" r="0.400"/><circle cx="18.500" cy="5.500" r="0.400"/><circle cx="23.500" cy="5.500" r="0.400"/><circle cx="24.500" cy="5.500" r="0.400"/><circle cx="25.500" cy="5.500" r="0.400"/><circle cx="26.500" cy="5.500" r="0.400"/><circle cx="27.500" cy="5.500" r="0.400"/><circle cx="2.500" cy="6.500" r="0.400"/><circle cx="7.500" cy="6.500" r="0.400"/><circle cx="8.500" cy="6.500" r="0.400"/><circle cx="9.500" cy="6.500" r="0.400"/><circle cx="10.500" cy="6.500" r="0.400"/><circle cx="14.500" cy="6.500" r="0.400"/><circle cx="15.500" cy="6.500" r="0.400"/><circle cx="16.500" cy="6.500" r="0.400"/><circle cx="17.500" cy="6.500" r="0.400"/><circle cx="18.500" cy="6.500" r="0.400"/><circle cx="22.500" cy="6.500" r="0.400"/><circle cx="23.500" cy="6.500" r="0.400"/><circle cx="24.500" cy="6.500" r="0.400"/><circle cx="25.500" cy="6.500" r="0.400"/><circle cx="30.500" cy="6.500" r="0.400"/><circle cx="1.500" cy="7.500" r="0.400"/><circle cx="2.500" cy="7.500" r="0.400"/><circle cx="3.500" cy="7.500" r="0.400"/><circle cx="4.500" cy="7.500" r="0.400"/><circle cx="5.500" cy="7.500" r="0.400"/><circle cx="9.500" cy="7.500" r="0.400"/><circle cx="10.500" cy="7.500" r="0.400"/><circle cx="11.500" cy="7.500" r="0.400"/><circle cx="12.500" cy="7.500" r="0.400"/><circle cx="15.500" cy="7.500" r="0.400"/><circle cx="16.500" cy="7.500" r="0.400"/><circle cx="17.500" cy="7.500" r="0.400"/><circle cx="20.500" cy="7.500" r="0.400"/><circle cx="21.500" cy="7.500" r="0.400"/><circle cx="22.500" cy="7.500" r="0.400"/><circle cx="23.500" cy="7.500" r="0.400"/><circle cx="27.500" cy="7.500" r="0.400"/><circle cx="28.500" cy="7.500" r="0.400"/><circle cx="29.500" cy="7.500" r="0.400"/><circle cx="30.500" cy="7.500" r="0.400"/><circle cx="31.500" cy="7.500" r="0.400"/><circle cx="1.500" cy="8.500" r="0.400"/><circle cx="2.500" cy="8.500" r="0.400"/><circle cx="3.500" cy="8.500" r="0.400"/><circle cx="4.500" cy="8.500" r="0.400"/><circle cx="5.500" cy="8.500" r="0.400"/><circle cx="6.500" cy="8.500" r="0.400"/><circle cx="7.500" cy="8.500" r="0.400"/><circle cx="8.500" cy="8.500" r="0.400"/><circle cx="9.500" cy="8.500" r="0.400"/><circle cx="10.500" cy="8.500" r="0.400"/><circle cx="11.500" cy="8.500" r="0.400"/><circle cx="12.500" cy="8.500" r="0.400"/><circle cx="13.500" cy="8.500" r="0.400"/><circle cx="15.500" cy="8.500" r="0.400"/><circle cx="16.500" cy="8.500" r="0.400"/><circle cx="17.500" cy="8.500" r="0.400"/><circle cx="19.500" cy="8.500" r="0.400"/><circle cx="20.500" cy="8.500" r="0.400"/><circle cx="21.500" cy="8.500" r="0.400"/><circle cx="22.500" cy="8.500" r="0.400"/><circle cx="23.500" cy="8.500" r="0.400"/><circle cx="24.500" cy="8.500" r="0.400"/><ciLine truncated
|
||||||
|
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 33 29" width="33" height="29" role="img" aria-label="SimurgArray"><title>SimurgArray</title><g fill="#A87A00"><circle cx="2.500" cy="1.500" r="0.400"/><circle cx="3.500" cy="1.500" r="0.400"/><circle cx="29.500" cy="1.500" r="0.400"/><circle cx="30.500" cy="1.500" r="0.400"/><circle cx="2.500" cy="2.500" r="0.400"/><circle cx="3.500" cy="2.500" r="0.400"/><circle cx="4.500" cy="2.500" r="0.400"/><circle cx="14.500" cy="2.500" r="0.400"/><circle cx="16.500" cy="2.500" r="0.400"/><circle cx="18.500" cy="2.500" r="0.400"/><circle cx="28.500" cy="2.500" r="0.400"/><circle cx="29.500" cy="2.500" r="0.400"/><circle cx="30.500" cy="2.500" r="0.400"/><circle cx="2.500" cy="3.500" r="0.400"/><circle cx="3.500" cy="3.500" r="0.400"/><circle cx="4.500" cy="3.500" r="0.400"/><circle cx="5.500" cy="3.500" r="0.400"/><circle cx="6.500" cy="3.500" r="0.400"/><circle cx="14.500" cy="3.500" r="0.400"/><circle cx="15.500" cy="3.500" r="0.400"/><circle cx="16.500" cy="3.500" r="0.400"/><circle cx="17.500" cy="3.500" r="0.400"/><circle cx="18.500" cy="3.500" r="0.400"/><circle cx="26.500" cy="3.500" r="0.400"/><circle cx="27.500" cy="3.500" r="0.400"/><circle cx="28.500" cy="3.500" r="0.400"/><circle cx="29.500" cy="3.500" r="0.400"/><circle cx="30.500" cy="3.500" r="0.400"/><circle cx="4.500" cy="4.500" r="0.400"/><circle cx="5.500" cy="4.500" r="0.400"/><circle cx="6.500" cy="4.500" r="0.400"/><circle cx="7.500" cy="4.500" r="0.400"/><circle cx="8.500" cy="4.500" r="0.400"/><circle cx="14.500" cy="4.500" r="0.400"/><circle cx="15.500" cy="4.500" r="0.400"/><circle cx="16.500" cy="4.500" r="0.400"/><circle cx="17.500" cy="4.500" r="0.400"/><circle cx="18.500" cy="4.500" r="0.400"/><circle cx="24.500" cy="4.500" r="0.400"/><circle cx="25.500" cy="4.500" r="0.400"/><circle cx="26.500" cy="4.500" r="0.400"/><circle cx="27.500" cy="4.500" r="0.400"/><circle cx="28.500" cy="4.500" r="0.400"/><circle cx="5.500" cy="5.500" r="0.400"/><circle cx="6.500" cy="5.500" r="0.400"/><circle cx="7.500" cy="5.500" r="0.400"/><circle cx="8.500" cy="5.500" r="0.400"/><circle cx="9.500" cy="5.500" r="0.400"/><circle cx="14.500" cy="5.500" r="0.400"/><circle cx="15.500" cy="5.500" r="0.400"/><circle cx="16.500" cy="5.500" r="0.400"/><circle cx="17.500" cy="5.500" r="0.400"/><circle cx="18.500" cy="5.500" r="0.400"/><circle cx="23.500" cy="5.500" r="0.400"/><circle cx="24.500" cy="5.500" r="0.400"/><circle cx="25.500" cy="5.500" r="0.400"/><circle cx="26.500" cy="5.500" r="0.400"/><circle cx="27.500" cy="5.500" r="0.400"/><circle cx="2.500" cy="6.500" r="0.400"/><circle cx="7.500" cy="6.500" r="0.400"/><circle cx="8.500" cy="6.500" r="0.400"/><circle cx="9.500" cy="6.500" r="0.400"/><circle cx="10.500" cy="6.500" r="0.400"/><circle cx="14.500" cy="6.500" r="0.400"/><circle cx="15.500" cy="6.500" r="0.400"/><circle cx="16.500" cy="6.500" r="0.400"/><circle cx="17.500" cy="6.500" r="0.400"/><circle cx="18.500" cy="6.500" r="0.400"/><circle cx="22.500" cy="6.500" r="0.400"/><circle cx="23.500" cy="6.500" r="0.400"/><circle cx="24.500" cy="6.500" r="0.400"/><circle cx="25.500" cy="6.500" r="0.400"/><circle cx="30.500" cy="6.500" r="0.400"/><circle cx="1.500" cy="7.500" r="0.400"/><circle cx="2.500" cy="7.500" r="0.400"/><circle cx="3.500" cy="7.500" r="0.400"/><circle cx="4.500" cy="7.500" r="0.400"/><circle cx="5.500" cy="7.500" r="0.400"/><circle cx="9.500" cy="7.500" r="0.400"/><circle cx="10.500" cy="7.500" r="0.400"/><circle cx="11.500" cy="7.500" r="0.400"/><circle cx="12.500" cy="7.500" r="0.400"/><circle cx="15.500" cy="7.500" r="0.400"/><circle cx="16.500" cy="7.500" r="0.400"/><circle cx="17.500" cy="7.500" r="0.400"/><circle cx="20.500" cy="7.500" r="0.400"/><circle cx="21.500" cy="7.500" r="0.400"/><circle cx="22.500" cy="7.500" r="0.400"/><circle cx="23.500" cy="7.500" r="0.400"/><circle cx="27.500" cy="7.500" r="0.400"/><circle cx="28.500" cy="7.500" r="0.400"/><circle cx="29.500" cy="7.500" r="0.400"/><circle cx="30.500" cy="7.500" r="0.400"/><circle cx="31.500" cy="7.500" r="0.400"/><circle cx="1.500" cy="8.500" r="0.400"/><circle cx="2.500" cy="8.500" r="0.400"/><circle cx="3.500" cy="8.500" r="0.400"/><circle cx="4.500" cy="8.500" r="0.400"/><circle cx="5.500" cy="8.500" r="0.400"/><circle cx="6.500" cy="8.500" r="0.400"/><circle cx="7.500" cy="8.500" r="0.400"/><circle cx="8.500" cy="8.500" r="0.400"/><circle cx="9.500" cy="8.500" r="0.400"/><circle cx="10.500" cy="8.500" r="0.400"/><circle cx="11.500" cy="8.500" r="0.400"/><circle cx="12.500" cy="8.500" r="0.400"/><circle cx="13.500" cy="8.500" r="0.400"/><circle cx="15.500" cy="8.500" r="0.400"/><circle cx="16.500" cy="8.500" r="0.400"/><circle cx="17.500" cy="8.500" r="0.400"/><circle cx="19.500" cy="8.500" r="0.400"/><circle cx="20.500" cy="8.500" r="0.400"/><circle cx="21.500" cy="8.500" r="0.400"/><circle cx="22.500" cy="8.500" r="0.400"/><circle cx="23.500" cy="8.500" r="0.400"/><circle cx="24.500" cy="8.500" r="0.400"/><ciLine truncated
|
||||||
|
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 9 9" width="9" height="9" role="img" aria-label="SimurgArray"><title>SimurgArray</title><g fill="#111111"><circle cx="1.500" cy="1.500" r="0.400"/><circle cx="7.500" cy="1.500" r="0.400"/><circle cx="1.500" cy="2.500" r="0.400"/><circle cx="2.500" cy="2.500" r="0.400"/><circle cx="4.500" cy="2.500" r="0.400"/><circle cx="6.500" cy="2.500" r="0.400"/><circle cx="7.500" cy="2.500" r="0.400"/><circle cx="2.500" cy="3.500" r="0.400"/><circle cx="3.500" cy="3.500" r="0.400"/><circle cx="4.500" cy="3.500" r="0.400"/><circle cx="5.500" cy="3.500" r="0.400"/><circle cx="6.500" cy="3.500" r="0.400"/><circle cx="3.500" cy="4.500" r="0.400"/><circle cx="4.500" cy="4.500" r="0.400"/><circle cx="5.500" cy="4.500" r="0.400"/><circle cx="4.500" cy="5.500" r="0.400"/><circle cx="4.500" cy="6.500" r="0.400"/><circle cx="4.500" cy="7.500" r="0.400"/></g><g fill="#111111"><circle cx="2.500" cy="6.500" r="0.400"/><circle cx="1.500" cy="7.500" r="0.400"/></g><g fill="#111111"><circle cx="6.500" cy="6.500" r="0.400"/><circle cx="7.500" cy="7.500" r="0.400"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 9 9" width="9" height="9" role="img" aria-label="SimurgArray"><title>SimurgArray</title><g fill="#D4A017"><circle cx="1.500" cy="1.500" r="0.400"/><circle cx="7.500" cy="1.500" r="0.400"/><circle cx="1.500" cy="2.500" r="0.400"/><circle cx="2.500" cy="2.500" r="0.400"/><circle cx="4.500" cy="2.500" r="0.400"/><circle cx="6.500" cy="2.500" r="0.400"/><circle cx="7.500" cy="2.500" r="0.400"/><circle cx="2.500" cy="3.500" r="0.400"/><circle cx="3.500" cy="3.500" r="0.400"/><circle cx="4.500" cy="3.500" r="0.400"/><circle cx="5.500" cy="3.500" r="0.400"/><circle cx="6.500" cy="3.500" r="0.400"/><circle cx="3.500" cy="4.500" r="0.400"/><circle cx="4.500" cy="4.500" r="0.400"/><circle cx="5.500" cy="4.500" r="0.400"/><circle cx="4.500" cy="5.500" r="0.400"/><circle cx="4.500" cy="6.500" r="0.400"/><circle cx="4.500" cy="7.500" r="0.400"/></g><g fill="#C8453A"><circle cx="2.500" cy="6.500" r="0.400"/><circle cx="1.500" cy="7.500" r="0.400"/></g><g fill="#2F8F5B"><circle cx="6.500" cy="6.500" r="0.400"/><circle cx="7.500" cy="7.500" r="0.400"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 9 9" width="9" height="9" role="img" aria-label="SimurgArray"><title>SimurgArray</title><g fill="#D4A017"><circle cx="1.500" cy="1.500" r="0.400"/><circle cx="7.500" cy="1.500" r="0.400"/><circle cx="1.500" cy="2.500" r="0.400"/><circle cx="2.500" cy="2.500" r="0.400"/><circle cx="4.500" cy="2.500" r="0.400"/><circle cx="6.500" cy="2.500" r="0.400"/><circle cx="7.500" cy="2.500" r="0.400"/><circle cx="2.500" cy="3.500" r="0.400"/><circle cx="3.500" cy="3.500" r="0.400"/><circle cx="4.500" cy="3.500" r="0.400"/><circle cx="5.500" cy="3.500" r="0.400"/><circle cx="6.500" cy="3.500" r="0.400"/><circle cx="3.500" cy="4.500" r="0.400"/><circle cx="4.500" cy="4.500" r="0.400"/><circle cx="5.500" cy="4.500" r="0.400"/><circle cx="4.500" cy="5.500" r="0.400"/><circle cx="4.500" cy="6.500" r="0.400"/><circle cx="4.500" cy="7.500" r="0.400"/></g><g fill="#D4A017"><circle cx="2.500" cy="6.500" r="0.400"/><circle cx="1.500" cy="7.500" r="0.400"/></g><g fill="#D4A017"><circle cx="6.500" cy="6.500" r="0.400"/><circle cx="7.500" cy="7.500" r="0.400"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 9 9" width="9" height="9" role="img" aria-label="SimurgArray"><title>SimurgArray</title><g fill="#A87A00"><circle cx="1.500" cy="1.500" r="0.400"/><circle cx="7.500" cy="1.500" r="0.400"/><circle cx="1.500" cy="2.500" r="0.400"/><circle cx="2.500" cy="2.500" r="0.400"/><circle cx="4.500" cy="2.500" r="0.400"/><circle cx="6.500" cy="2.500" r="0.400"/><circle cx="7.500" cy="2.500" r="0.400"/><circle cx="2.500" cy="3.500" r="0.400"/><circle cx="3.500" cy="3.500" r="0.400"/><circle cx="4.500" cy="3.500" r="0.400"/><circle cx="5.500" cy="3.500" r="0.400"/><circle cx="6.500" cy="3.500" r="0.400"/><circle cx="3.500" cy="4.500" r="0.400"/><circle cx="4.500" cy="4.500" r="0.400"/><circle cx="5.500" cy="4.500" r="0.400"/><circle cx="4.500" cy="5.500" r="0.400"/><circle cx="4.500" cy="6.500" r="0.400"/><circle cx="4.500" cy="7.500" r="0.400"/></g><g fill="#C8453A"><circle cx="2.500" cy="6.500" r="0.400"/><circle cx="1.500" cy="7.500" r="0.400"/></g><g fill="#2F8F5B"><circle cx="6.500" cy="6.500" r="0.400"/><circle cx="7.500" cy="7.500" r="0.400"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 9 9" width="9" height="9" role="img" aria-label="SimurgArray"><title>SimurgArray</title><g fill="#FFFFFF"><circle cx="1.500" cy="1.500" r="0.400"/><circle cx="7.500" cy="1.500" r="0.400"/><circle cx="1.500" cy="2.500" r="0.400"/><circle cx="2.500" cy="2.500" r="0.400"/><circle cx="4.500" cy="2.500" r="0.400"/><circle cx="6.500" cy="2.500" r="0.400"/><circle cx="7.500" cy="2.500" r="0.400"/><circle cx="2.500" cy="3.500" r="0.400"/><circle cx="3.500" cy="3.500" r="0.400"/><circle cx="4.500" cy="3.500" r="0.400"/><circle cx="5.500" cy="3.500" r="0.400"/><circle cx="6.500" cy="3.500" r="0.400"/><circle cx="3.500" cy="4.500" r="0.400"/><circle cx="4.500" cy="4.500" r="0.400"/><circle cx="5.500" cy="4.500" r="0.400"/><circle cx="4.500" cy="5.500" r="0.400"/><circle cx="4.500" cy="6.500" r="0.400"/><circle cx="4.500" cy="7.500" r="0.400"/></g><g fill="#FFFFFF"><circle cx="2.500" cy="6.500" r="0.400"/><circle cx="1.500" cy="7.500" r="0.400"/></g><g fill="#FFFFFF"><circle cx="6.500" cy="6.500" r="0.400"/><circle cx="7.500" cy="7.500" r="0.400"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13 12" width="13" height="12" role="img" aria-label="SimurgArray"><title>SimurgArray</title><g fill="#111111"><circle cx="1.500" cy="1.500" r="0.400"/><circle cx="11.500" cy="1.500" r="0.400"/><circle cx="1.500" cy="2.500" r="0.400"/><circle cx="2.500" cy="2.500" r="0.400"/><circle cx="10.500" cy="2.500" r="0.400"/><circle cx="11.500" cy="2.500" r="0.400"/><circle cx="2.500" cy="3.500" r="0.400"/><circle cx="3.500" cy="3.500" r="0.400"/><circle cx="6.500" cy="3.500" r="0.400"/><circle cx="9.500" cy="3.500" r="0.400"/><circle cx="10.500" cy="3.500" r="0.400"/><circle cx="3.500" cy="4.500" r="0.400"/><circle cx="4.500" cy="4.500" r="0.400"/><circle cx="5.500" cy="4.500" r="0.400"/><circle cx="6.500" cy="4.500" r="0.400"/><circle cx="7.500" cy="4.500" r="0.400"/><circle cx="8.500" cy="4.500" r="0.400"/><circle cx="9.500" cy="4.500" r="0.400"/><circle cx="1.500" cy="5.500" r="0.400"/><circle cx="2.500" cy="5.500" r="0.400"/><circle cx="3.500" cy="5.500" r="0.400"/><circle cx="4.500" cy="5.500" r="0.400"/><circle cx="5.500" cy="5.500" r="0.400"/><circle cx="6.500" cy="5.500" r="0.400"/><circle cx="7.500" cy="5.500" r="0.400"/><circle cx="8.500" cy="5.500" r="0.400"/><circle cx="9.500" cy="5.500" r="0.400"/><circle cx="10.500" cy="5.500" r="0.400"/><circle cx="11.500" cy="5.500" r="0.400"/><circle cx="4.500" cy="6.500" r="0.400"/><circle cx="5.500" cy="6.500" r="0.400"/><circle cx="6.500" cy="6.500" r="0.400"/><circle cx="7.500" cy="6.500" r="0.400"/><circle cx="8.500" cy="6.500" r="0.400"/><circle cx="5.500" cy="7.500" r="0.400"/><circle cx="6.500" cy="7.500" r="0.400"/><circle cx="7.500" cy="7.500" r="0.400"/><circle cx="6.500" cy="8.500" r="0.400"/><circle cx="6.500" cy="9.500" r="0.400"/><circle cx="5.500" cy="10.500" r="0.400"/><circle cx="6.500" cy="10.500" r="0.400"/><circle cx="7.500" cy="10.500" r="0.400"/></g><g fill="#111111"><circle cx="4.500" cy="8.500" r="0.400"/><circle cx="3.500" cy="9.500" r="0.400"/><circle cx="2.500" cy="10.500" r="0.400"/><circle cx="3.500" cy="10.500" r="0.400"/></g><g fill="#111111"><circle cx="8.500" cy="8.500" r="0.400"/><circle cx="9.500" cy="9.500" r="0.400"/><circle cx="9.500" cy="10.500" r="0.400"/><circle cx="10.500" cy="10.500" r="0.400"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 2.2 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13 12" width="13" height="12" role="img" aria-label="SimurgArray"><title>SimurgArray</title><g fill="#D4A017"><circle cx="1.500" cy="1.500" r="0.400"/><circle cx="11.500" cy="1.500" r="0.400"/><circle cx="1.500" cy="2.500" r="0.400"/><circle cx="2.500" cy="2.500" r="0.400"/><circle cx="10.500" cy="2.500" r="0.400"/><circle cx="11.500" cy="2.500" r="0.400"/><circle cx="2.500" cy="3.500" r="0.400"/><circle cx="3.500" cy="3.500" r="0.400"/><circle cx="6.500" cy="3.500" r="0.400"/><circle cx="9.500" cy="3.500" r="0.400"/><circle cx="10.500" cy="3.500" r="0.400"/><circle cx="3.500" cy="4.500" r="0.400"/><circle cx="4.500" cy="4.500" r="0.400"/><circle cx="5.500" cy="4.500" r="0.400"/><circle cx="6.500" cy="4.500" r="0.400"/><circle cx="7.500" cy="4.500" r="0.400"/><circle cx="8.500" cy="4.500" r="0.400"/><circle cx="9.500" cy="4.500" r="0.400"/><circle cx="1.500" cy="5.500" r="0.400"/><circle cx="2.500" cy="5.500" r="0.400"/><circle cx="3.500" cy="5.500" r="0.400"/><circle cx="4.500" cy="5.500" r="0.400"/><circle cx="5.500" cy="5.500" r="0.400"/><circle cx="6.500" cy="5.500" r="0.400"/><circle cx="7.500" cy="5.500" r="0.400"/><circle cx="8.500" cy="5.500" r="0.400"/><circle cx="9.500" cy="5.500" r="0.400"/><circle cx="10.500" cy="5.500" r="0.400"/><circle cx="11.500" cy="5.500" r="0.400"/><circle cx="4.500" cy="6.500" r="0.400"/><circle cx="5.500" cy="6.500" r="0.400"/><circle cx="6.500" cy="6.500" r="0.400"/><circle cx="7.500" cy="6.500" r="0.400"/><circle cx="8.500" cy="6.500" r="0.400"/><circle cx="5.500" cy="7.500" r="0.400"/><circle cx="6.500" cy="7.500" r="0.400"/><circle cx="7.500" cy="7.500" r="0.400"/><circle cx="6.500" cy="8.500" r="0.400"/><circle cx="6.500" cy="9.500" r="0.400"/><circle cx="5.500" cy="10.500" r="0.400"/><circle cx="6.500" cy="10.500" r="0.400"/><circle cx="7.500" cy="10.500" r="0.400"/></g><g fill="#C8453A"><circle cx="4.500" cy="8.500" r="0.400"/><circle cx="3.500" cy="9.500" r="0.400"/><circle cx="2.500" cy="10.500" r="0.400"/><circle cx="3.500" cy="10.500" r="0.400"/></g><g fill="#2F8F5B"><circle cx="8.500" cy="8.500" r="0.400"/><circle cx="9.500" cy="9.500" r="0.400"/><circle cx="9.500" cy="10.500" r="0.400"/><circle cx="10.500" cy="10.500" r="0.400"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 2.2 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13 12" width="13" height="12" role="img" aria-label="SimurgArray"><title>SimurgArray</title><g fill="#D4A017"><circle cx="1.500" cy="1.500" r="0.400"/><circle cx="11.500" cy="1.500" r="0.400"/><circle cx="1.500" cy="2.500" r="0.400"/><circle cx="2.500" cy="2.500" r="0.400"/><circle cx="10.500" cy="2.500" r="0.400"/><circle cx="11.500" cy="2.500" r="0.400"/><circle cx="2.500" cy="3.500" r="0.400"/><circle cx="3.500" cy="3.500" r="0.400"/><circle cx="6.500" cy="3.500" r="0.400"/><circle cx="9.500" cy="3.500" r="0.400"/><circle cx="10.500" cy="3.500" r="0.400"/><circle cx="3.500" cy="4.500" r="0.400"/><circle cx="4.500" cy="4.500" r="0.400"/><circle cx="5.500" cy="4.500" r="0.400"/><circle cx="6.500" cy="4.500" r="0.400"/><circle cx="7.500" cy="4.500" r="0.400"/><circle cx="8.500" cy="4.500" r="0.400"/><circle cx="9.500" cy="4.500" r="0.400"/><circle cx="1.500" cy="5.500" r="0.400"/><circle cx="2.500" cy="5.500" r="0.400"/><circle cx="3.500" cy="5.500" r="0.400"/><circle cx="4.500" cy="5.500" r="0.400"/><circle cx="5.500" cy="5.500" r="0.400"/><circle cx="6.500" cy="5.500" r="0.400"/><circle cx="7.500" cy="5.500" r="0.400"/><circle cx="8.500" cy="5.500" r="0.400"/><circle cx="9.500" cy="5.500" r="0.400"/><circle cx="10.500" cy="5.500" r="0.400"/><circle cx="11.500" cy="5.500" r="0.400"/><circle cx="4.500" cy="6.500" r="0.400"/><circle cx="5.500" cy="6.500" r="0.400"/><circle cx="6.500" cy="6.500" r="0.400"/><circle cx="7.500" cy="6.500" r="0.400"/><circle cx="8.500" cy="6.500" r="0.400"/><circle cx="5.500" cy="7.500" r="0.400"/><circle cx="6.500" cy="7.500" r="0.400"/><circle cx="7.500" cy="7.500" r="0.400"/><circle cx="6.500" cy="8.500" r="0.400"/><circle cx="6.500" cy="9.500" r="0.400"/><circle cx="5.500" cy="10.500" r="0.400"/><circle cx="6.500" cy="10.500" r="0.400"/><circle cx="7.500" cy="10.500" r="0.400"/></g><g fill="#D4A017"><circle cx="4.500" cy="8.500" r="0.400"/><circle cx="3.500" cy="9.500" r="0.400"/><circle cx="2.500" cy="10.500" r="0.400"/><circle cx="3.500" cy="10.500" r="0.400"/></g><g fill="#D4A017"><circle cx="8.500" cy="8.500" r="0.400"/><circle cx="9.500" cy="9.500" r="0.400"/><circle cx="9.500" cy="10.500" r="0.400"/><circle cx="10.500" cy="10.500" r="0.400"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 2.2 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13 12" width="13" height="12" role="img" aria-label="SimurgArray"><title>SimurgArray</title><g fill="#A87A00"><circle cx="1.500" cy="1.500" r="0.400"/><circle cx="11.500" cy="1.500" r="0.400"/><circle cx="1.500" cy="2.500" r="0.400"/><circle cx="2.500" cy="2.500" r="0.400"/><circle cx="10.500" cy="2.500" r="0.400"/><circle cx="11.500" cy="2.500" r="0.400"/><circle cx="2.500" cy="3.500" r="0.400"/><circle cx="3.500" cy="3.500" r="0.400"/><circle cx="6.500" cy="3.500" r="0.400"/><circle cx="9.500" cy="3.500" r="0.400"/><circle cx="10.500" cy="3.500" r="0.400"/><circle cx="3.500" cy="4.500" r="0.400"/><circle cx="4.500" cy="4.500" r="0.400"/><circle cx="5.500" cy="4.500" r="0.400"/><circle cx="6.500" cy="4.500" r="0.400"/><circle cx="7.500" cy="4.500" r="0.400"/><circle cx="8.500" cy="4.500" r="0.400"/><circle cx="9.500" cy="4.500" r="0.400"/><circle cx="1.500" cy="5.500" r="0.400"/><circle cx="2.500" cy="5.500" r="0.400"/><circle cx="3.500" cy="5.500" r="0.400"/><circle cx="4.500" cy="5.500" r="0.400"/><circle cx="5.500" cy="5.500" r="0.400"/><circle cx="6.500" cy="5.500" r="0.400"/><circle cx="7.500" cy="5.500" r="0.400"/><circle cx="8.500" cy="5.500" r="0.400"/><circle cx="9.500" cy="5.500" r="0.400"/><circle cx="10.500" cy="5.500" r="0.400"/><circle cx="11.500" cy="5.500" r="0.400"/><circle cx="4.500" cy="6.500" r="0.400"/><circle cx="5.500" cy="6.500" r="0.400"/><circle cx="6.500" cy="6.500" r="0.400"/><circle cx="7.500" cy="6.500" r="0.400"/><circle cx="8.500" cy="6.500" r="0.400"/><circle cx="5.500" cy="7.500" r="0.400"/><circle cx="6.500" cy="7.500" r="0.400"/><circle cx="7.500" cy="7.500" r="0.400"/><circle cx="6.500" cy="8.500" r="0.400"/><circle cx="6.500" cy="9.500" r="0.400"/><circle cx="5.500" cy="10.500" r="0.400"/><circle cx="6.500" cy="10.500" r="0.400"/><circle cx="7.500" cy="10.500" r="0.400"/></g><g fill="#C8453A"><circle cx="4.500" cy="8.500" r="0.400"/><circle cx="3.500" cy="9.500" r="0.400"/><circle cx="2.500" cy="10.500" r="0.400"/><circle cx="3.500" cy="10.500" r="0.400"/></g><g fill="#2F8F5B"><circle cx="8.500" cy="8.500" r="0.400"/><circle cx="9.500" cy="9.500" r="0.400"/><circle cx="9.500" cy="10.500" r="0.400"/><circle cx="10.500" cy="10.500" r="0.400"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 2.2 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13 12" width="13" height="12" role="img" aria-label="SimurgArray"><title>SimurgArray</title><g fill="#FFFFFF"><circle cx="1.500" cy="1.500" r="0.400"/><circle cx="11.500" cy="1.500" r="0.400"/><circle cx="1.500" cy="2.500" r="0.400"/><circle cx="2.500" cy="2.500" r="0.400"/><circle cx="10.500" cy="2.500" r="0.400"/><circle cx="11.500" cy="2.500" r="0.400"/><circle cx="2.500" cy="3.500" r="0.400"/><circle cx="3.500" cy="3.500" r="0.400"/><circle cx="6.500" cy="3.500" r="0.400"/><circle cx="9.500" cy="3.500" r="0.400"/><circle cx="10.500" cy="3.500" r="0.400"/><circle cx="3.500" cy="4.500" r="0.400"/><circle cx="4.500" cy="4.500" r="0.400"/><circle cx="5.500" cy="4.500" r="0.400"/><circle cx="6.500" cy="4.500" r="0.400"/><circle cx="7.500" cy="4.500" r="0.400"/><circle cx="8.500" cy="4.500" r="0.400"/><circle cx="9.500" cy="4.500" r="0.400"/><circle cx="1.500" cy="5.500" r="0.400"/><circle cx="2.500" cy="5.500" r="0.400"/><circle cx="3.500" cy="5.500" r="0.400"/><circle cx="4.500" cy="5.500" r="0.400"/><circle cx="5.500" cy="5.500" r="0.400"/><circle cx="6.500" cy="5.500" r="0.400"/><circle cx="7.500" cy="5.500" r="0.400"/><circle cx="8.500" cy="5.500" r="0.400"/><circle cx="9.500" cy="5.500" r="0.400"/><circle cx="10.500" cy="5.500" r="0.400"/><circle cx="11.500" cy="5.500" r="0.400"/><circle cx="4.500" cy="6.500" r="0.400"/><circle cx="5.500" cy="6.500" r="0.400"/><circle cx="6.500" cy="6.500" r="0.400"/><circle cx="7.500" cy="6.500" r="0.400"/><circle cx="8.500" cy="6.500" r="0.400"/><circle cx="5.500" cy="7.500" r="0.400"/><circle cx="6.500" cy="7.500" r="0.400"/><circle cx="7.500" cy="7.500" r="0.400"/><circle cx="6.500" cy="8.500" r="0.400"/><circle cx="6.500" cy="9.500" r="0.400"/><circle cx="5.500" cy="10.500" r="0.400"/><circle cx="6.500" cy="10.500" r="0.400"/><circle cx="7.500" cy="10.500" r="0.400"/></g><g fill="#FFFFFF"><circle cx="4.500" cy="8.500" r="0.400"/><circle cx="3.500" cy="9.500" r="0.400"/><circle cx="2.500" cy="10.500" r="0.400"/><circle cx="3.500" cy="10.500" r="0.400"/></g><g fill="#FFFFFF"><circle cx="8.500" cy="8.500" r="0.400"/><circle cx="9.500" cy="9.500" r="0.400"/><circle cx="9.500" cy="10.500" r="0.400"/><circle cx="10.500" cy="10.500" r="0.400"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 2.2 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 33 29" width="33" height="29" role="img" aria-label="SimurgArray"><title>SimurgArray</title><g fill="#FFFFFF"><circle cx="2.500" cy="1.500" r="0.400"/><circle cx="3.500" cy="1.500" r="0.400"/><circle cx="29.500" cy="1.500" r="0.400"/><circle cx="30.500" cy="1.500" r="0.400"/><circle cx="2.500" cy="2.500" r="0.400"/><circle cx="3.500" cy="2.500" r="0.400"/><circle cx="4.500" cy="2.500" r="0.400"/><circle cx="14.500" cy="2.500" r="0.400"/><circle cx="16.500" cy="2.500" r="0.400"/><circle cx="18.500" cy="2.500" r="0.400"/><circle cx="28.500" cy="2.500" r="0.400"/><circle cx="29.500" cy="2.500" r="0.400"/><circle cx="30.500" cy="2.500" r="0.400"/><circle cx="2.500" cy="3.500" r="0.400"/><circle cx="3.500" cy="3.500" r="0.400"/><circle cx="4.500" cy="3.500" r="0.400"/><circle cx="5.500" cy="3.500" r="0.400"/><circle cx="6.500" cy="3.500" r="0.400"/><circle cx="14.500" cy="3.500" r="0.400"/><circle cx="15.500" cy="3.500" r="0.400"/><circle cx="16.500" cy="3.500" r="0.400"/><circle cx="17.500" cy="3.500" r="0.400"/><circle cx="18.500" cy="3.500" r="0.400"/><circle cx="26.500" cy="3.500" r="0.400"/><circle cx="27.500" cy="3.500" r="0.400"/><circle cx="28.500" cy="3.500" r="0.400"/><circle cx="29.500" cy="3.500" r="0.400"/><circle cx="30.500" cy="3.500" r="0.400"/><circle cx="4.500" cy="4.500" r="0.400"/><circle cx="5.500" cy="4.500" r="0.400"/><circle cx="6.500" cy="4.500" r="0.400"/><circle cx="7.500" cy="4.500" r="0.400"/><circle cx="8.500" cy="4.500" r="0.400"/><circle cx="14.500" cy="4.500" r="0.400"/><circle cx="15.500" cy="4.500" r="0.400"/><circle cx="16.500" cy="4.500" r="0.400"/><circle cx="17.500" cy="4.500" r="0.400"/><circle cx="18.500" cy="4.500" r="0.400"/><circle cx="24.500" cy="4.500" r="0.400"/><circle cx="25.500" cy="4.500" r="0.400"/><circle cx="26.500" cy="4.500" r="0.400"/><circle cx="27.500" cy="4.500" r="0.400"/><circle cx="28.500" cy="4.500" r="0.400"/><circle cx="5.500" cy="5.500" r="0.400"/><circle cx="6.500" cy="5.500" r="0.400"/><circle cx="7.500" cy="5.500" r="0.400"/><circle cx="8.500" cy="5.500" r="0.400"/><circle cx="9.500" cy="5.500" r="0.400"/><circle cx="14.500" cy="5.500" r="0.400"/><circle cx="15.500" cy="5.500" r="0.400"/><circle cx="16.500" cy="5.500" r="0.400"/><circle cx="17.500" cy="5.500" r="0.400"/><circle cx="18.500" cy="5.500" r="0.400"/><circle cx="23.500" cy="5.500" r="0.400"/><circle cx="24.500" cy="5.500" r="0.400"/><circle cx="25.500" cy="5.500" r="0.400"/><circle cx="26.500" cy="5.500" r="0.400"/><circle cx="27.500" cy="5.500" r="0.400"/><circle cx="2.500" cy="6.500" r="0.400"/><circle cx="7.500" cy="6.500" r="0.400"/><circle cx="8.500" cy="6.500" r="0.400"/><circle cx="9.500" cy="6.500" r="0.400"/><circle cx="10.500" cy="6.500" r="0.400"/><circle cx="14.500" cy="6.500" r="0.400"/><circle cx="15.500" cy="6.500" r="0.400"/><circle cx="16.500" cy="6.500" r="0.400"/><circle cx="17.500" cy="6.500" r="0.400"/><circle cx="18.500" cy="6.500" r="0.400"/><circle cx="22.500" cy="6.500" r="0.400"/><circle cx="23.500" cy="6.500" r="0.400"/><circle cx="24.500" cy="6.500" r="0.400"/><circle cx="25.500" cy="6.500" r="0.400"/><circle cx="30.500" cy="6.500" r="0.400"/><circle cx="1.500" cy="7.500" r="0.400"/><circle cx="2.500" cy="7.500" r="0.400"/><circle cx="3.500" cy="7.500" r="0.400"/><circle cx="4.500" cy="7.500" r="0.400"/><circle cx="5.500" cy="7.500" r="0.400"/><circle cx="9.500" cy="7.500" r="0.400"/><circle cx="10.500" cy="7.500" r="0.400"/><circle cx="11.500" cy="7.500" r="0.400"/><circle cx="12.500" cy="7.500" r="0.400"/><circle cx="15.500" cy="7.500" r="0.400"/><circle cx="16.500" cy="7.500" r="0.400"/><circle cx="17.500" cy="7.500" r="0.400"/><circle cx="20.500" cy="7.500" r="0.400"/><circle cx="21.500" cy="7.500" r="0.400"/><circle cx="22.500" cy="7.500" r="0.400"/><circle cx="23.500" cy="7.500" r="0.400"/><circle cx="27.500" cy="7.500" r="0.400"/><circle cx="28.500" cy="7.500" r="0.400"/><circle cx="29.500" cy="7.500" r="0.400"/><circle cx="30.500" cy="7.500" r="0.400"/><circle cx="31.500" cy="7.500" r="0.400"/><circle cx="1.500" cy="8.500" r="0.400"/><circle cx="2.500" cy="8.500" r="0.400"/><circle cx="3.500" cy="8.500" r="0.400"/><circle cx="4.500" cy="8.500" r="0.400"/><circle cx="5.500" cy="8.500" r="0.400"/><circle cx="6.500" cy="8.500" r="0.400"/><circle cx="7.500" cy="8.500" r="0.400"/><circle cx="8.500" cy="8.500" r="0.400"/><circle cx="9.500" cy="8.500" r="0.400"/><circle cx="10.500" cy="8.500" r="0.400"/><circle cx="11.500" cy="8.500" r="0.400"/><circle cx="12.500" cy="8.500" r="0.400"/><circle cx="13.500" cy="8.500" r="0.400"/><circle cx="15.500" cy="8.500" r="0.400"/><circle cx="16.500" cy="8.500" r="0.400"/><circle cx="17.500" cy="8.500" r="0.400"/><circle cx="19.500" cy="8.500" r="0.400"/><circle cx="20.500" cy="8.500" r="0.400"/><circle cx="21.500" cy="8.500" r="0.400"/><circle cx="22.500" cy="8.500" r="0.400"/><circle cx="23.500" cy="8.500" r="0.400"/><circle cx="24.500" cy="8.500" r="0.400"/><ciLine truncated
|
||||||
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 57 KiB |
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 63 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 63 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 67 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 9.9 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 9.7 KiB |
|
After Width: | Height: | Size: 6.6 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 9.3 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 14 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 630.7 100" width="630.7" height="100" role="img" aria-label="SimurgArray"><title>SimurgArray</title><path fill="#111111" d="M50.800000000000004 58.5Q50.800000000000004 68.0 43.900000000000006 73.5Q37.0 79.0 24.8 79.0Q13.0 79.0 4.800000000000001 75.0V63.0Q9.3 65.0 14.700000000000001 66.65Q20.1 68.3 25.700000000000003 68.3Q32.1 68.3 35.1 65.8Q38.1 63.3 38.1 59.2Q38.1 54.7 34.3 52.1Q30.5 49.5 23.200000000000003 46.4Q18.8 44.5 14.8 41.9Q10.8 39.3 8.200000000000001 35.3Q5.6000000000000005 31.299999999999997 5.6000000000000005 25.099999999999994Q5.6000000000000005 15.899999999999999 12.05 10.749999999999996Q18.5 5.599999999999994 29.3 5.599999999999994Q35.0 5.599999999999994 39.95 6.799999999999997Q44.900000000000006 8.0 49.900000000000006 10.200000000000003L45.800000000000004 20.5Q41.300000000000004 18.599999999999994 37.25 17.499999999999996Q33.2 16.4 28.900000000000002 16.4Q23.700000000000003 16.4 21.0 18.749999999999996Q18.3 21.099999999999994 18.3 24.799999999999997Q18.3 27.799999999999997 19.8 29.799999999999997Q21.3 31.799999999999997 24.450000000000003 33.5Q27.6 35.199999999999996 32.6 37.4Q38.300000000000004 39.9 42.400000000000006 42.599999999999994Q46.5 45.3 48.650000000000006 49.099999999999994Q50.800000000000004 52.9 50.800000000000004 58.5Z M69.9 2.8999999999999915Q72.8 2.8999999999999915 74.85 4.349999999999994Q76.9 5.799999999999997 76.9 9.5Q76.9 13.200000000000003 74.85 14.7Q72.8 16.199999999999996 69.9 16.199999999999996Q67.0 16.199999999999996 64.95 14.7Q62.9 13.200000000000003 62.9 9.5Q62.9 5.799999999999997 64.95 4.349999999999994Q67.0 2.8999999999999915 69.9 2.8999999999999915ZM76.2 23.799999999999997V78.0H63.6V23.799999999999997Z M154.9 22.799999999999997Q164.10000000000002 22.799999999999997 168.75 27.499999999999996Q173.4 32.199999999999996 173.4 42.699999999999996V78.0H160.8V45.1Q160.8 33.0 151.60000000000002 33.0Q145.0 33.0 142.2 37.3Q139.4 41.6 139.4 49.8V78.0H126.80000000000001V45.1Q126.80000000000001 33.0 117.5 33.0Q110.60000000000001 33.0 108.0 37.8Q105.4 42.6 105.4 51.5V78.0H92.8V23.799999999999997H102.5L104.30000000000001 30.9H105.0Q107.4 26.699999999999996 111.75 24.749999999999996Q116.10000000000001 22.799999999999997 120.80000000000001 22.799999999999997Q126.9 22.799999999999997 131.05 24.849999999999998Q135.2 26.9 137.4 31.199999999999996H138.4Q140.9 26.799999999999997 145.4 24.799999999999997Q149.9 22.799999999999997 154.9 22.799999999999997Z M237.8 23.799999999999997V78.0H227.90000000000003L226.20000000000002 71.0H225.60000000000002Q222.90000000000003 75.2 218.35000000000002 77.1Q213.8 79.0 208.70000000000002 79.0Q199.60000000000002 79.0 194.45000000000002 74.3Q189.3 69.6 189.3 59.2V23.799999999999997H201.90000000000003V56.7Q201.90000000000003 68.8 211.90000000000003 68.8Q219.50000000000003 68.8 222.35000000000002 64.05Q225.20000000000002 59.3 225.20000000000002 50.3V23.799999999999997Z M282.8 22.799999999999997Q284.1 22.799999999999997 285.65000000000003 22.9Q287.20000000000005 23.0 288.3 23.299999999999997L287.20000000000005 35.0Q286.20000000000005 34.8 284.80000000000007 34.65Q283.40000000000003 34.5 282.3 34.5Q278.3 34.5 274.8 36.15Q271.3 37.8 269.15 41.25Q267.0 44.699999999999996 267.0 49.9V78.0H254.4V23.799999999999997H264.1L265.90000000000003 33.199999999999996H266.5Q268.90000000000003 28.9 273.1 25.849999999999998Q277.3 22.799999999999997 282.8 22.799999999999997Z M317.00000000000006 22.799999999999997Q327.30000000000007 22.799999999999997 333.1 30.799999999999997H333.6L334.80000000000007 23.799999999999997H345.30000000000007V78.4Q345.30000000000007 90.0 338.75000000000006 96.0Q332.20000000000005 102.0 319.20000000000005 102.0Q313.40000000000003 102.0 308.5 101.25Q303.6 100.5 299.20000000000005 98.7V88.3Q308.50000000000006 92.5 320.00000000000006 92.5Q326.20000000000005 92.5 329.45000000000005 89.05Q332.70000000000005 85.6 332.70000000000005 79.0V77.6Q332.70000000000005 76.1 332.80000000000007 74.1Q332.90000000000003 72.1 333.1 70.9H332.70000000000005Q329.90000000000003 75.1 325.85 77.05Q321.80000000000007 79.0 316.70000000000005 79.0Q306.80000000000007 79.0 301.20000000000005 71.6Q295.6 64.2 295.6 51.0Q295.6 37.8 301.25 30.299999999999997Q306.90000000000003 22.799999999999997 317.00000000000006 22.799999999999997ZM320.30000000000007 33.099999999999994Q308.50000000000006 33.099999999999994 308.50000000000006 51.2Q308.50000000000006 69.0 320.50000000000006 69.0Q327.1 69.0 330.25 65.35Q333.40000000000003 61.7 333.40000000000003 53.0V51.099999999999994Q333.40000000000003 41.5 330.25 37.3Q327.1 33.099999999999994 320.30000000000007 33.099999999999994Z"/><path fill="#111111" d="M409.70000000000005 78.0 403.20000000000005 59.099999999999994H376.30000000000007L369.9000000000001 78.0H356.30000000000007L382.50000000000006 6.299999999999997H397.1000000000001L423.30000000000007 78.0ZM393.70000000000005 29.699999999999996Q393.30000000000007 28.299999999999997 392.50000000000006 25.9Q391.70000000000005 23.5 390.95000000000005 Line truncated
|
||||||
|
After Width: | Height: | Size: 7.8 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 630.7 100" width="630.7" height="100" role="img" aria-label="SimurgArray"><title>SimurgArray</title><path fill="#F7F5EF" d="M50.800000000000004 58.5Q50.800000000000004 68.0 43.900000000000006 73.5Q37.0 79.0 24.8 79.0Q13.0 79.0 4.800000000000001 75.0V63.0Q9.3 65.0 14.700000000000001 66.65Q20.1 68.3 25.700000000000003 68.3Q32.1 68.3 35.1 65.8Q38.1 63.3 38.1 59.2Q38.1 54.7 34.3 52.1Q30.5 49.5 23.200000000000003 46.4Q18.8 44.5 14.8 41.9Q10.8 39.3 8.200000000000001 35.3Q5.6000000000000005 31.299999999999997 5.6000000000000005 25.099999999999994Q5.6000000000000005 15.899999999999999 12.05 10.749999999999996Q18.5 5.599999999999994 29.3 5.599999999999994Q35.0 5.599999999999994 39.95 6.799999999999997Q44.900000000000006 8.0 49.900000000000006 10.200000000000003L45.800000000000004 20.5Q41.300000000000004 18.599999999999994 37.25 17.499999999999996Q33.2 16.4 28.900000000000002 16.4Q23.700000000000003 16.4 21.0 18.749999999999996Q18.3 21.099999999999994 18.3 24.799999999999997Q18.3 27.799999999999997 19.8 29.799999999999997Q21.3 31.799999999999997 24.450000000000003 33.5Q27.6 35.199999999999996 32.6 37.4Q38.300000000000004 39.9 42.400000000000006 42.599999999999994Q46.5 45.3 48.650000000000006 49.099999999999994Q50.800000000000004 52.9 50.800000000000004 58.5Z M69.9 2.8999999999999915Q72.8 2.8999999999999915 74.85 4.349999999999994Q76.9 5.799999999999997 76.9 9.5Q76.9 13.200000000000003 74.85 14.7Q72.8 16.199999999999996 69.9 16.199999999999996Q67.0 16.199999999999996 64.95 14.7Q62.9 13.200000000000003 62.9 9.5Q62.9 5.799999999999997 64.95 4.349999999999994Q67.0 2.8999999999999915 69.9 2.8999999999999915ZM76.2 23.799999999999997V78.0H63.6V23.799999999999997Z M154.9 22.799999999999997Q164.10000000000002 22.799999999999997 168.75 27.499999999999996Q173.4 32.199999999999996 173.4 42.699999999999996V78.0H160.8V45.1Q160.8 33.0 151.60000000000002 33.0Q145.0 33.0 142.2 37.3Q139.4 41.6 139.4 49.8V78.0H126.80000000000001V45.1Q126.80000000000001 33.0 117.5 33.0Q110.60000000000001 33.0 108.0 37.8Q105.4 42.6 105.4 51.5V78.0H92.8V23.799999999999997H102.5L104.30000000000001 30.9H105.0Q107.4 26.699999999999996 111.75 24.749999999999996Q116.10000000000001 22.799999999999997 120.80000000000001 22.799999999999997Q126.9 22.799999999999997 131.05 24.849999999999998Q135.2 26.9 137.4 31.199999999999996H138.4Q140.9 26.799999999999997 145.4 24.799999999999997Q149.9 22.799999999999997 154.9 22.799999999999997Z M237.8 23.799999999999997V78.0H227.90000000000003L226.20000000000002 71.0H225.60000000000002Q222.90000000000003 75.2 218.35000000000002 77.1Q213.8 79.0 208.70000000000002 79.0Q199.60000000000002 79.0 194.45000000000002 74.3Q189.3 69.6 189.3 59.2V23.799999999999997H201.90000000000003V56.7Q201.90000000000003 68.8 211.90000000000003 68.8Q219.50000000000003 68.8 222.35000000000002 64.05Q225.20000000000002 59.3 225.20000000000002 50.3V23.799999999999997Z M282.8 22.799999999999997Q284.1 22.799999999999997 285.65000000000003 22.9Q287.20000000000005 23.0 288.3 23.299999999999997L287.20000000000005 35.0Q286.20000000000005 34.8 284.80000000000007 34.65Q283.40000000000003 34.5 282.3 34.5Q278.3 34.5 274.8 36.15Q271.3 37.8 269.15 41.25Q267.0 44.699999999999996 267.0 49.9V78.0H254.4V23.799999999999997H264.1L265.90000000000003 33.199999999999996H266.5Q268.90000000000003 28.9 273.1 25.849999999999998Q277.3 22.799999999999997 282.8 22.799999999999997Z M317.00000000000006 22.799999999999997Q327.30000000000007 22.799999999999997 333.1 30.799999999999997H333.6L334.80000000000007 23.799999999999997H345.30000000000007V78.4Q345.30000000000007 90.0 338.75000000000006 96.0Q332.20000000000005 102.0 319.20000000000005 102.0Q313.40000000000003 102.0 308.5 101.25Q303.6 100.5 299.20000000000005 98.7V88.3Q308.50000000000006 92.5 320.00000000000006 92.5Q326.20000000000005 92.5 329.45000000000005 89.05Q332.70000000000005 85.6 332.70000000000005 79.0V77.6Q332.70000000000005 76.1 332.80000000000007 74.1Q332.90000000000003 72.1 333.1 70.9H332.70000000000005Q329.90000000000003 75.1 325.85 77.05Q321.80000000000007 79.0 316.70000000000005 79.0Q306.80000000000007 79.0 301.20000000000005 71.6Q295.6 64.2 295.6 51.0Q295.6 37.8 301.25 30.299999999999997Q306.90000000000003 22.799999999999997 317.00000000000006 22.799999999999997ZM320.30000000000007 33.099999999999994Q308.50000000000006 33.099999999999994 308.50000000000006 51.2Q308.50000000000006 69.0 320.50000000000006 69.0Q327.1 69.0 330.25 65.35Q333.40000000000003 61.7 333.40000000000003 53.0V51.099999999999994Q333.40000000000003 41.5 330.25 37.3Q327.1 33.099999999999994 320.30000000000007 33.099999999999994Z"/><path fill="#D4A017" d="M409.70000000000005 78.0 403.20000000000005 59.099999999999994H376.30000000000007L369.9000000000001 78.0H356.30000000000007L382.50000000000006 6.299999999999997H397.1000000000001L423.30000000000007 78.0ZM393.70000000000005 29.699999999999996Q393.30000000000007 28.299999999999997 392.50000000000006 25.9Q391.70000000000005 23.5 390.95000000000005 Line truncated
|
||||||
|
After Width: | Height: | Size: 7.8 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 630.7 100" width="630.7" height="100" role="img" aria-label="SimurgArray"><title>SimurgArray</title><path fill="#D4A017" d="M50.800000000000004 58.5Q50.800000000000004 68.0 43.900000000000006 73.5Q37.0 79.0 24.8 79.0Q13.0 79.0 4.800000000000001 75.0V63.0Q9.3 65.0 14.700000000000001 66.65Q20.1 68.3 25.700000000000003 68.3Q32.1 68.3 35.1 65.8Q38.1 63.3 38.1 59.2Q38.1 54.7 34.3 52.1Q30.5 49.5 23.200000000000003 46.4Q18.8 44.5 14.8 41.9Q10.8 39.3 8.200000000000001 35.3Q5.6000000000000005 31.299999999999997 5.6000000000000005 25.099999999999994Q5.6000000000000005 15.899999999999999 12.05 10.749999999999996Q18.5 5.599999999999994 29.3 5.599999999999994Q35.0 5.599999999999994 39.95 6.799999999999997Q44.900000000000006 8.0 49.900000000000006 10.200000000000003L45.800000000000004 20.5Q41.300000000000004 18.599999999999994 37.25 17.499999999999996Q33.2 16.4 28.900000000000002 16.4Q23.700000000000003 16.4 21.0 18.749999999999996Q18.3 21.099999999999994 18.3 24.799999999999997Q18.3 27.799999999999997 19.8 29.799999999999997Q21.3 31.799999999999997 24.450000000000003 33.5Q27.6 35.199999999999996 32.6 37.4Q38.300000000000004 39.9 42.400000000000006 42.599999999999994Q46.5 45.3 48.650000000000006 49.099999999999994Q50.800000000000004 52.9 50.800000000000004 58.5Z M69.9 2.8999999999999915Q72.8 2.8999999999999915 74.85 4.349999999999994Q76.9 5.799999999999997 76.9 9.5Q76.9 13.200000000000003 74.85 14.7Q72.8 16.199999999999996 69.9 16.199999999999996Q67.0 16.199999999999996 64.95 14.7Q62.9 13.200000000000003 62.9 9.5Q62.9 5.799999999999997 64.95 4.349999999999994Q67.0 2.8999999999999915 69.9 2.8999999999999915ZM76.2 23.799999999999997V78.0H63.6V23.799999999999997Z M154.9 22.799999999999997Q164.10000000000002 22.799999999999997 168.75 27.499999999999996Q173.4 32.199999999999996 173.4 42.699999999999996V78.0H160.8V45.1Q160.8 33.0 151.60000000000002 33.0Q145.0 33.0 142.2 37.3Q139.4 41.6 139.4 49.8V78.0H126.80000000000001V45.1Q126.80000000000001 33.0 117.5 33.0Q110.60000000000001 33.0 108.0 37.8Q105.4 42.6 105.4 51.5V78.0H92.8V23.799999999999997H102.5L104.30000000000001 30.9H105.0Q107.4 26.699999999999996 111.75 24.749999999999996Q116.10000000000001 22.799999999999997 120.80000000000001 22.799999999999997Q126.9 22.799999999999997 131.05 24.849999999999998Q135.2 26.9 137.4 31.199999999999996H138.4Q140.9 26.799999999999997 145.4 24.799999999999997Q149.9 22.799999999999997 154.9 22.799999999999997Z M237.8 23.799999999999997V78.0H227.90000000000003L226.20000000000002 71.0H225.60000000000002Q222.90000000000003 75.2 218.35000000000002 77.1Q213.8 79.0 208.70000000000002 79.0Q199.60000000000002 79.0 194.45000000000002 74.3Q189.3 69.6 189.3 59.2V23.799999999999997H201.90000000000003V56.7Q201.90000000000003 68.8 211.90000000000003 68.8Q219.50000000000003 68.8 222.35000000000002 64.05Q225.20000000000002 59.3 225.20000000000002 50.3V23.799999999999997Z M282.8 22.799999999999997Q284.1 22.799999999999997 285.65000000000003 22.9Q287.20000000000005 23.0 288.3 23.299999999999997L287.20000000000005 35.0Q286.20000000000005 34.8 284.80000000000007 34.65Q283.40000000000003 34.5 282.3 34.5Q278.3 34.5 274.8 36.15Q271.3 37.8 269.15 41.25Q267.0 44.699999999999996 267.0 49.9V78.0H254.4V23.799999999999997H264.1L265.90000000000003 33.199999999999996H266.5Q268.90000000000003 28.9 273.1 25.849999999999998Q277.3 22.799999999999997 282.8 22.799999999999997Z M317.00000000000006 22.799999999999997Q327.30000000000007 22.799999999999997 333.1 30.799999999999997H333.6L334.80000000000007 23.799999999999997H345.30000000000007V78.4Q345.30000000000007 90.0 338.75000000000006 96.0Q332.20000000000005 102.0 319.20000000000005 102.0Q313.40000000000003 102.0 308.5 101.25Q303.6 100.5 299.20000000000005 98.7V88.3Q308.50000000000006 92.5 320.00000000000006 92.5Q326.20000000000005 92.5 329.45000000000005 89.05Q332.70000000000005 85.6 332.70000000000005 79.0V77.6Q332.70000000000005 76.1 332.80000000000007 74.1Q332.90000000000003 72.1 333.1 70.9H332.70000000000005Q329.90000000000003 75.1 325.85 77.05Q321.80000000000007 79.0 316.70000000000005 79.0Q306.80000000000007 79.0 301.20000000000005 71.6Q295.6 64.2 295.6 51.0Q295.6 37.8 301.25 30.299999999999997Q306.90000000000003 22.799999999999997 317.00000000000006 22.799999999999997ZM320.30000000000007 33.099999999999994Q308.50000000000006 33.099999999999994 308.50000000000006 51.2Q308.50000000000006 69.0 320.50000000000006 69.0Q327.1 69.0 330.25 65.35Q333.40000000000003 61.7 333.40000000000003 53.0V51.099999999999994Q333.40000000000003 41.5 330.25 37.3Q327.1 33.099999999999994 320.30000000000007 33.099999999999994Z"/><path fill="#D4A017" d="M409.70000000000005 78.0 403.20000000000005 59.099999999999994H376.30000000000007L369.9000000000001 78.0H356.30000000000007L382.50000000000006 6.299999999999997H397.1000000000001L423.30000000000007 78.0ZM393.70000000000005 29.699999999999996Q393.30000000000007 28.299999999999997 392.50000000000006 25.9Q391.70000000000005 23.5 390.95000000000005 Line truncated
|
||||||
|
After Width: | Height: | Size: 7.8 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 630.7 100" width="630.7" height="100" role="img" aria-label="SimurgArray"><title>SimurgArray</title><path fill="#1E2240" d="M50.800000000000004 58.5Q50.800000000000004 68.0 43.900000000000006 73.5Q37.0 79.0 24.8 79.0Q13.0 79.0 4.800000000000001 75.0V63.0Q9.3 65.0 14.700000000000001 66.65Q20.1 68.3 25.700000000000003 68.3Q32.1 68.3 35.1 65.8Q38.1 63.3 38.1 59.2Q38.1 54.7 34.3 52.1Q30.5 49.5 23.200000000000003 46.4Q18.8 44.5 14.8 41.9Q10.8 39.3 8.200000000000001 35.3Q5.6000000000000005 31.299999999999997 5.6000000000000005 25.099999999999994Q5.6000000000000005 15.899999999999999 12.05 10.749999999999996Q18.5 5.599999999999994 29.3 5.599999999999994Q35.0 5.599999999999994 39.95 6.799999999999997Q44.900000000000006 8.0 49.900000000000006 10.200000000000003L45.800000000000004 20.5Q41.300000000000004 18.599999999999994 37.25 17.499999999999996Q33.2 16.4 28.900000000000002 16.4Q23.700000000000003 16.4 21.0 18.749999999999996Q18.3 21.099999999999994 18.3 24.799999999999997Q18.3 27.799999999999997 19.8 29.799999999999997Q21.3 31.799999999999997 24.450000000000003 33.5Q27.6 35.199999999999996 32.6 37.4Q38.300000000000004 39.9 42.400000000000006 42.599999999999994Q46.5 45.3 48.650000000000006 49.099999999999994Q50.800000000000004 52.9 50.800000000000004 58.5Z M69.9 2.8999999999999915Q72.8 2.8999999999999915 74.85 4.349999999999994Q76.9 5.799999999999997 76.9 9.5Q76.9 13.200000000000003 74.85 14.7Q72.8 16.199999999999996 69.9 16.199999999999996Q67.0 16.199999999999996 64.95 14.7Q62.9 13.200000000000003 62.9 9.5Q62.9 5.799999999999997 64.95 4.349999999999994Q67.0 2.8999999999999915 69.9 2.8999999999999915ZM76.2 23.799999999999997V78.0H63.6V23.799999999999997Z M154.9 22.799999999999997Q164.10000000000002 22.799999999999997 168.75 27.499999999999996Q173.4 32.199999999999996 173.4 42.699999999999996V78.0H160.8V45.1Q160.8 33.0 151.60000000000002 33.0Q145.0 33.0 142.2 37.3Q139.4 41.6 139.4 49.8V78.0H126.80000000000001V45.1Q126.80000000000001 33.0 117.5 33.0Q110.60000000000001 33.0 108.0 37.8Q105.4 42.6 105.4 51.5V78.0H92.8V23.799999999999997H102.5L104.30000000000001 30.9H105.0Q107.4 26.699999999999996 111.75 24.749999999999996Q116.10000000000001 22.799999999999997 120.80000000000001 22.799999999999997Q126.9 22.799999999999997 131.05 24.849999999999998Q135.2 26.9 137.4 31.199999999999996H138.4Q140.9 26.799999999999997 145.4 24.799999999999997Q149.9 22.799999999999997 154.9 22.799999999999997Z M237.8 23.799999999999997V78.0H227.90000000000003L226.20000000000002 71.0H225.60000000000002Q222.90000000000003 75.2 218.35000000000002 77.1Q213.8 79.0 208.70000000000002 79.0Q199.60000000000002 79.0 194.45000000000002 74.3Q189.3 69.6 189.3 59.2V23.799999999999997H201.90000000000003V56.7Q201.90000000000003 68.8 211.90000000000003 68.8Q219.50000000000003 68.8 222.35000000000002 64.05Q225.20000000000002 59.3 225.20000000000002 50.3V23.799999999999997Z M282.8 22.799999999999997Q284.1 22.799999999999997 285.65000000000003 22.9Q287.20000000000005 23.0 288.3 23.299999999999997L287.20000000000005 35.0Q286.20000000000005 34.8 284.80000000000007 34.65Q283.40000000000003 34.5 282.3 34.5Q278.3 34.5 274.8 36.15Q271.3 37.8 269.15 41.25Q267.0 44.699999999999996 267.0 49.9V78.0H254.4V23.799999999999997H264.1L265.90000000000003 33.199999999999996H266.5Q268.90000000000003 28.9 273.1 25.849999999999998Q277.3 22.799999999999997 282.8 22.799999999999997Z M317.00000000000006 22.799999999999997Q327.30000000000007 22.799999999999997 333.1 30.799999999999997H333.6L334.80000000000007 23.799999999999997H345.30000000000007V78.4Q345.30000000000007 90.0 338.75000000000006 96.0Q332.20000000000005 102.0 319.20000000000005 102.0Q313.40000000000003 102.0 308.5 101.25Q303.6 100.5 299.20000000000005 98.7V88.3Q308.50000000000006 92.5 320.00000000000006 92.5Q326.20000000000005 92.5 329.45000000000005 89.05Q332.70000000000005 85.6 332.70000000000005 79.0V77.6Q332.70000000000005 76.1 332.80000000000007 74.1Q332.90000000000003 72.1 333.1 70.9H332.70000000000005Q329.90000000000003 75.1 325.85 77.05Q321.80000000000007 79.0 316.70000000000005 79.0Q306.80000000000007 79.0 301.20000000000005 71.6Q295.6 64.2 295.6 51.0Q295.6 37.8 301.25 30.299999999999997Q306.90000000000003 22.799999999999997 317.00000000000006 22.799999999999997ZM320.30000000000007 33.099999999999994Q308.50000000000006 33.099999999999994 308.50000000000006 51.2Q308.50000000000006 69.0 320.50000000000006 69.0Q327.1 69.0 330.25 65.35Q333.40000000000003 61.7 333.40000000000003 53.0V51.099999999999994Q333.40000000000003 41.5 330.25 37.3Q327.1 33.099999999999994 320.30000000000007 33.099999999999994Z"/><path fill="#8C6500" d="M409.70000000000005 78.0 403.20000000000005 59.099999999999994H376.30000000000007L369.9000000000001 78.0H356.30000000000007L382.50000000000006 6.299999999999997H397.1000000000001L423.30000000000007 78.0ZM393.70000000000005 29.699999999999996Q393.30000000000007 28.299999999999997 392.50000000000006 25.9Q391.70000000000005 23.5 390.95000000000005 Line truncated
|
||||||
|
After Width: | Height: | Size: 7.8 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 630.7 100" width="630.7" height="100" role="img" aria-label="SimurgArray"><title>SimurgArray</title><path fill="#FFFFFF" d="M50.800000000000004 58.5Q50.800000000000004 68.0 43.900000000000006 73.5Q37.0 79.0 24.8 79.0Q13.0 79.0 4.800000000000001 75.0V63.0Q9.3 65.0 14.700000000000001 66.65Q20.1 68.3 25.700000000000003 68.3Q32.1 68.3 35.1 65.8Q38.1 63.3 38.1 59.2Q38.1 54.7 34.3 52.1Q30.5 49.5 23.200000000000003 46.4Q18.8 44.5 14.8 41.9Q10.8 39.3 8.200000000000001 35.3Q5.6000000000000005 31.299999999999997 5.6000000000000005 25.099999999999994Q5.6000000000000005 15.899999999999999 12.05 10.749999999999996Q18.5 5.599999999999994 29.3 5.599999999999994Q35.0 5.599999999999994 39.95 6.799999999999997Q44.900000000000006 8.0 49.900000000000006 10.200000000000003L45.800000000000004 20.5Q41.300000000000004 18.599999999999994 37.25 17.499999999999996Q33.2 16.4 28.900000000000002 16.4Q23.700000000000003 16.4 21.0 18.749999999999996Q18.3 21.099999999999994 18.3 24.799999999999997Q18.3 27.799999999999997 19.8 29.799999999999997Q21.3 31.799999999999997 24.450000000000003 33.5Q27.6 35.199999999999996 32.6 37.4Q38.300000000000004 39.9 42.400000000000006 42.599999999999994Q46.5 45.3 48.650000000000006 49.099999999999994Q50.800000000000004 52.9 50.800000000000004 58.5Z M69.9 2.8999999999999915Q72.8 2.8999999999999915 74.85 4.349999999999994Q76.9 5.799999999999997 76.9 9.5Q76.9 13.200000000000003 74.85 14.7Q72.8 16.199999999999996 69.9 16.199999999999996Q67.0 16.199999999999996 64.95 14.7Q62.9 13.200000000000003 62.9 9.5Q62.9 5.799999999999997 64.95 4.349999999999994Q67.0 2.8999999999999915 69.9 2.8999999999999915ZM76.2 23.799999999999997V78.0H63.6V23.799999999999997Z M154.9 22.799999999999997Q164.10000000000002 22.799999999999997 168.75 27.499999999999996Q173.4 32.199999999999996 173.4 42.699999999999996V78.0H160.8V45.1Q160.8 33.0 151.60000000000002 33.0Q145.0 33.0 142.2 37.3Q139.4 41.6 139.4 49.8V78.0H126.80000000000001V45.1Q126.80000000000001 33.0 117.5 33.0Q110.60000000000001 33.0 108.0 37.8Q105.4 42.6 105.4 51.5V78.0H92.8V23.799999999999997H102.5L104.30000000000001 30.9H105.0Q107.4 26.699999999999996 111.75 24.749999999999996Q116.10000000000001 22.799999999999997 120.80000000000001 22.799999999999997Q126.9 22.799999999999997 131.05 24.849999999999998Q135.2 26.9 137.4 31.199999999999996H138.4Q140.9 26.799999999999997 145.4 24.799999999999997Q149.9 22.799999999999997 154.9 22.799999999999997Z M237.8 23.799999999999997V78.0H227.90000000000003L226.20000000000002 71.0H225.60000000000002Q222.90000000000003 75.2 218.35000000000002 77.1Q213.8 79.0 208.70000000000002 79.0Q199.60000000000002 79.0 194.45000000000002 74.3Q189.3 69.6 189.3 59.2V23.799999999999997H201.90000000000003V56.7Q201.90000000000003 68.8 211.90000000000003 68.8Q219.50000000000003 68.8 222.35000000000002 64.05Q225.20000000000002 59.3 225.20000000000002 50.3V23.799999999999997Z M282.8 22.799999999999997Q284.1 22.799999999999997 285.65000000000003 22.9Q287.20000000000005 23.0 288.3 23.299999999999997L287.20000000000005 35.0Q286.20000000000005 34.8 284.80000000000007 34.65Q283.40000000000003 34.5 282.3 34.5Q278.3 34.5 274.8 36.15Q271.3 37.8 269.15 41.25Q267.0 44.699999999999996 267.0 49.9V78.0H254.4V23.799999999999997H264.1L265.90000000000003 33.199999999999996H266.5Q268.90000000000003 28.9 273.1 25.849999999999998Q277.3 22.799999999999997 282.8 22.799999999999997Z M317.00000000000006 22.799999999999997Q327.30000000000007 22.799999999999997 333.1 30.799999999999997H333.6L334.80000000000007 23.799999999999997H345.30000000000007V78.4Q345.30000000000007 90.0 338.75000000000006 96.0Q332.20000000000005 102.0 319.20000000000005 102.0Q313.40000000000003 102.0 308.5 101.25Q303.6 100.5 299.20000000000005 98.7V88.3Q308.50000000000006 92.5 320.00000000000006 92.5Q326.20000000000005 92.5 329.45000000000005 89.05Q332.70000000000005 85.6 332.70000000000005 79.0V77.6Q332.70000000000005 76.1 332.80000000000007 74.1Q332.90000000000003 72.1 333.1 70.9H332.70000000000005Q329.90000000000003 75.1 325.85 77.05Q321.80000000000007 79.0 316.70000000000005 79.0Q306.80000000000007 79.0 301.20000000000005 71.6Q295.6 64.2 295.6 51.0Q295.6 37.8 301.25 30.299999999999997Q306.90000000000003 22.799999999999997 317.00000000000006 22.799999999999997ZM320.30000000000007 33.099999999999994Q308.50000000000006 33.099999999999994 308.50000000000006 51.2Q308.50000000000006 69.0 320.50000000000006 69.0Q327.1 69.0 330.25 65.35Q333.40000000000003 61.7 333.40000000000003 53.0V51.099999999999994Q333.40000000000003 41.5 330.25 37.3Q327.1 33.099999999999994 320.30000000000007 33.099999999999994Z"/><path fill="#FFFFFF" d="M409.70000000000005 78.0 403.20000000000005 59.099999999999994H376.30000000000007L369.9000000000001 78.0H356.30000000000007L382.50000000000006 6.299999999999997H397.1000000000001L423.30000000000007 78.0ZM393.70000000000005 29.699999999999996Q393.30000000000007 28.299999999999997 392.50000000000006 25.9Q391.70000000000005 23.5 390.95000000000005 Line truncated
|
||||||
|
After Width: | Height: | Size: 7.8 KiB |