{"_id":"@carabennemsi/plasmid","_rev":"2-30e4686a2d9b2f8289be48d37f38a8e7","name":"@carabennemsi/plasmid","dist-tags":{"latest":"0.1.3"},"versions":{"0.1.2":{"name":"@carabennemsi/plasmid","version":"0.1.2","keywords":["plasmid","dna","svg","bioinformatics","genbank","fasta","molecular-biology","visualization"],"author":{"name":"cara"},"license":"MIT","_id":"@carabennemsi/plasmid@0.1.2","maintainers":[{"name":"carabennemsi","email":"mail@severinfink.de"}],"homepage":"https://github.com/cara/plasmid#readme","bugs":{"url":"https://github.com/cara/plasmid/issues"},"dist":{"shasum":"a06d09b6862bd553d37b80b91c0aaf3e4882ee94","tarball":"https://registry.npmjs.org/@carabennemsi/plasmid/-/plasmid-0.1.2.tgz","fileCount":29,"integrity":"sha512-CRiZp7aIzYQrAja/73DqUlHdFkql87WtiIcFOQreWQ5lJ8/0lvcFnS9Q6Kw/jbPcjbH51Rq8AHYllOGOhzy8GQ==","signatures":[{"sig":"MEUCIG4B06sUQ6hm3PiFP+poVUiO5pu56DS+LEUq6+ZXpAMVAiEAzaR36Ncfnx3ln1PFDqqPmmY/QRzUcMD5L310TMCzwY4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":112968},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"6c3499d4de1205ad11e651320dd26cf5c9fdfa5b","scripts":{"test":"vitest run","build":"node build.mjs","typecheck":"tsc -p tsconfig.build.json --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"carabennemsi","email":"mail@severinfink.de"},"repository":{"url":"git+https://github.com/cara/plasmid.git","type":"git"},"_npmVersion":"11.6.1","description":"Dependency-free plasmid map renderer — turn a DNA sequence or FASTA/GenBank file into a standalone circular-map SVG. Runs in Node and the browser.","directories":{},"sideEffects":false,"_nodeVersion":"24.9.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.18","esbuild":"^0.21.5","typescript":"^5.4.0"},"_npmOperationalInternal":{"tmp":"tmp/plasmid_0.1.2_1784876049132_0.2711763148174515","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@carabennemsi/plasmid","version":"0.1.3","description":"Dependency-free plasmid map renderer — turn a DNA sequence or FASTA/GenBank file into a standalone circular-map SVG. Runs in Node and the browser.","keywords":["plasmid","dna","svg","bioinformatics","genbank","fasta","molecular-biology","visualization"],"license":"MIT","author":{"name":"cara"},"repository":{"type":"git","url":"git+https://github.com/cara/plasmid.git"},"type":"module","sideEffects":false,"main":"./dist/index.js","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"build":"node build.mjs","typecheck":"tsc -p tsconfig.build.json --noEmit","test":"vitest run","prepublishOnly":"npm run build"},"devDependencies":{"esbuild":"^0.21.5","typescript":"^5.4.0","vitest":"^4.0.18"},"engines":{"node":">=18"},"publishConfig":{"access":"public"},"gitHead":"4aa543aa3ca83cfa03ad1d5a8d49b99c4f193f31","_id":"@carabennemsi/plasmid@0.1.3","bugs":{"url":"https://github.com/cara/plasmid/issues"},"homepage":"https://github.com/cara/plasmid#readme","_nodeVersion":"24.9.0","_npmVersion":"11.6.1","dist":{"integrity":"sha512-ejirmx/tssQDTKCX+AvKVQm5jDDIc424719FjUuviFr906TDT56Uy3q+ZAQDuHwqcYv4VzVb0x5n75ZvNsdr7A==","shasum":"e1f40ac28c46e1a41aff40b51a163263205215df","tarball":"https://registry.npmjs.org/@carabennemsi/plasmid/-/plasmid-0.1.3.tgz","fileCount":29,"unpackedSize":115172,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCICX2LArqs15ppHBGDrAyzDVt6ceN/f0AXeRl9O4ni+MPAiEA73dYxMt1uJ/xDUl74kpq+mrVv0OjRLciiDWzUFHIWFY="}]},"_npmUser":{"name":"carabennemsi","email":"mail@severinfink.de"},"directories":{},"maintainers":[{"name":"carabennemsi","email":"mail@severinfink.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/plasmid_0.1.3_1784877168400_0.022687614872916484"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-24T06:54:08.362Z","modified":"2026-07-24T07:12:48.706Z","0.1.2":"2026-07-24T06:54:09.276Z","0.1.3":"2026-07-24T07:12:48.543Z"},"bugs":{"url":"https://github.com/cara/plasmid/issues"},"author":{"name":"cara"},"license":"MIT","homepage":"https://github.com/cara/plasmid#readme","keywords":["plasmid","dna","svg","bioinformatics","genbank","fasta","molecular-biology","visualization"],"repository":{"type":"git","url":"git+https://github.com/cara/plasmid.git"},"description":"Dependency-free plasmid map renderer — turn a DNA sequence or FASTA/GenBank file into a standalone circular-map SVG. Runs in Node and the browser.","maintainers":[{"name":"carabennemsi","email":"mail@severinfink.de"}],"readme":"# @carabennemsi/plasmid\n\n> Dependency-free plasmid map renderer — turn a DNA sequence or FASTA/GenBank file into a standalone circular-map SVG. Runs in Node and the browser.\n\n`@carabennemsi/plasmid` takes a nucleotide sequence (or a parsed FASTA / GenBank record) and returns a complete, self-contained `<svg>…</svg>` string: a circular plasmid map with feature arrows, restriction cut sites, a base-pair ruler, and a centered name/length label. Everything is a pure function — no DOM, no canvas, no runtime dependencies — so the same code path works on a server (static pre-render) and in the browser.\n\n**[▶ Live demo](https://cara.github.io/plasmid/)** — render the sample vectors below, or paste your own sequence. Everything runs client-side.\n\nFor a searchable database of 200 k+ published vectors built on this renderer, see **[plasmid.cloudlab.bio](https://plasmid.cloudlab.bio)**.\n\n## Features\n\n- **Circular-map SVG in one call** — `renderPlasmidSVG(record)` returns a full standalone `<svg>` string you can write to disk, inline into HTML, or rasterize.\n- **Zero runtime dependencies**, ESM-only, and isomorphic (Node + browser). No DOM required.\n- **Parsers included** — FASTA, GenBank, and raw sequence, with automatic format detection.\n- **Smart layout** — features are auto-assigned to non-overlapping lanes and drawn as arcs/arrows; wide features get curved on-arc labels, narrow ones get external leader labels.\n- **Restriction analysis** — find sites on both strands (with origin wrap for circular molecules) and draw unique cutters from a built-in type-II enzyme panel.\n- **Automatic annotation** — when a record has no features, a bundled common-feature panel (AmpR, KanR, common origins/promoters/primers) is exact-matched on both strands.\n- **Deterministic colors** — well-known feature classes get conventional colors; everything else is hashed to a stable hue.\n\n## Install\n\n```sh\nnpm i @carabennemsi/plasmid\n```\n\nRequires Node ≥ 18 (or any modern browser). The package is ESM-only.\n\n## Quick start (Node)\n\nParse a FASTA or GenBank string, render it, and write the SVG to disk:\n\n```ts\nimport { readFileSync, writeFileSync } from 'node:fs';\nimport { parsePlasmid, renderPlasmidSVG } from '@carabennemsi/plasmid';\n\nconst text = readFileSync('pUC19.gb', 'utf8');\nconst record = parsePlasmid(text); // format auto-detected (GenBank / FASTA / raw)\n\nconst svg = renderPlasmidSVG(record);\nwriteFileSync('plasmid.svg', svg);\n```\n\nOr build a `PlasmidRecord` by hand:\n\n```ts\nimport { writeFileSync } from 'node:fs';\nimport { renderPlasmidSVG, type PlasmidRecord } from '@carabennemsi/plasmid';\n\nconst record: PlasmidRecord = {\n  name: 'my-plasmid',\n  sequence: 'ATGCGT...ACGT', // your nucleotide sequence\n  circular: true,\n  features: [\n    { name: 'AmpR', type: 'CDS', start: 100, end: 960, strand: 1 },\n    { name: 'ori', type: 'rep_origin', start: 1200, end: 1788, strand: -1 },\n    // A feature that wraps the origin has start > end:\n    { name: 'cassette', type: 'misc_feature', start: 2600, end: 40, strand: 1 },\n  ],\n};\n\nwriteFileSync('plasmid.svg', renderPlasmidSVG(record));\n```\n\nWith no `features` supplied and `detectFeatures` on (the default), the renderer auto-detects common features for you:\n\n```ts\nconst svg = renderPlasmidSVG({ name: 'unknown', sequence });\n```\n\n## Rasterize to PNG\n\n`@carabennemsi/plasmid` only produces SVG strings — it has no rendering dependency. To get a PNG, pipe the SVG through any SVG rasterizer of your choice. [`@resvg/resvg-js`](https://github.com/thx/resvg-js) is a good pure-Rust option (install it yourself; it is **not** a dependency of this package):\n\n```ts\nimport { writeFileSync } from 'node:fs';\nimport { Resvg } from '@resvg/resvg-js';\nimport { parsePlasmid, renderPlasmidSVG } from '@carabennemsi/plasmid';\n\nconst svg = renderPlasmidSVG(parsePlasmid(fastaText));\nconst png = new Resvg(svg).render().asPng();\nwriteFileSync('plasmid.png', png);\n```\n\n## Browser usage\n\n`renderPlasmidSVG` returns a plain string, so inlining it is just an `innerHTML` assignment — no DOM APIs are touched inside the library:\n\n```js\nimport { renderPlasmidSVG } from '@carabennemsi/plasmid';\n\nconst record = { name: 'my-plasmid', sequence };\ndocument.querySelector('#map').innerHTML = renderPlasmidSVG(record);\n```\n\n## How it looks\n\nThe default output is an 800×800 SVG (`viewBox=\"0 0 800 800\"`) containing:\n\n- a circular backbone with a base-pair ruler and evenly spaced ticks,\n- feature arrows/arcs colored by class, placed on auto-assigned lanes so they never overlap,\n- on-arc curved labels for wide features and external leader-line labels for narrow ones,\n- unique restriction cut sites (from the enzyme panel) marked around the circle,\n- the plasmid name and length (in bp) centered in the middle.\n\n## Example: a Sleeping Beauty transposon vector\n\n`pT2 BN SVPuro CAG EGFP` — 8,150 bp, 27 annotated features — rendered straight from its GenBank record with no manual layout:\n\n<p align=\"center\">\n  <img\n    src=\"https://raw.githubusercontent.com/cara/plasmid/main/docs/media/pT2-BN-SVPuro-CAG-EGFP.png\"\n    alt=\"Circular map of pT2 BN SVPuro CAG EGFP: 8,150 bp with IR/DR left and right flanking a CAG-driven EGFP cassette and an SV40-driven PuroR cassette, plus AmpR, ori and f1 ori on the backbone.\"\n    width=\"720\"\n  />\n</p>\n\n```ts\nimport { readFileSync, writeFileSync } from 'node:fs';\nimport { parsePlasmid, renderPlasmidSVG } from '@carabennemsi/plasmid';\n\nconst record = parsePlasmid(readFileSync('pT2-BN-SVPuro-CAG-EGFP.gb', 'utf8'));\nwriteFileSync('map.svg', renderPlasmidSVG(record, { size: 900 }));\n```\n\nThe IR/DR left and right repeats delimit the mobile transposon; everything the SB100X transposase excises sits between them, while `AmpR`, `ori` and `f1 ori` stay behind on the donor backbone.\n\nSeven more vectors from the same set — the SB100X transposase helper, the empty pT2/pT2B backbones, and the tTR/KRAB repressor constructs — are on the **[live demo](https://cara.github.io/plasmid/)**, with their GenBank files in [`docs/samples/`](https://github.com/cara/plasmid/tree/main/docs/samples).\n\n> **Sample vector sequences** © Severin Fink, from the dissertation **[DOI:10.25972/OPUS-24979](https://doi.org/10.25972/OPUS-24979)** (Julius-Maximilians-Universität Würzburg), reproduced with permission of the author. They are included as demonstration data and are **not** covered by this package's MIT licence. The pT2/pT2B transposon backbones and the SB100X transposase derive from the published Sleeping Beauty system and remain the work of their original authors.\n\n## API reference\n\nAll exports are pure functions and data — importing the package has no side effects.\n\n### `renderPlasmidSVG(record, opts?) => string`\n\n```ts\nfunction renderPlasmidSVG(record: PlasmidRecord, opts?: RenderOptions): string;\n```\n\nRenders `record` to a complete, standalone `<svg>…</svg>` string. Non-ACGT characters in `record.sequence` are ignored when computing length and drawing. If `record.features` is empty and `opts.detectFeatures` is on (default), common features are auto-detected first. See [`RenderOptions`](#renderoptions) for all knobs.\n\n### `parsePlasmid(text, format?) => PlasmidRecord`\n\n```ts\nfunction parsePlasmid(text: string, format?: 'genbank' | 'fasta' | 'raw'): PlasmidRecord;\n```\n\nParses `text` into a `PlasmidRecord`. When `format` is omitted the format is auto-detected via [`detectFormat`](#detectformattext--genbank--fasta--raw).\n\n### `parseFasta(text) => PlasmidRecord`\n\nParses a FASTA record.\n\n### `parseGenBank(text) => PlasmidRecord`\n\nParses a GenBank record, including its features and `DEFINITION`.\n\n### `parseRaw(text, name?) => PlasmidRecord`\n\nWraps a bare nucleotide string in a `PlasmidRecord`, using the optional `name` as the display name.\n\n### `detectFormat(text) => 'genbank' | 'fasta' | 'raw'`\n\nSniffs `text` and returns the detected input format. (The `'genbank' | 'fasta' | 'raw'` union is also exported as the `InputFormat` type.)\n\n### `findSites(sequence, site, circular) => number[]`\n\n```ts\nfunction findSites(sequence: string, site: string, circular: boolean): number[];\n```\n\nReturns the 0-based start indices of every occurrence of `site` on **both** strands. When `circular` is true, matches that span the origin are included (the sequence is treated as a loop).\n\n### `findCutters(sequence, circular, enzymes?, maxCutFrequency?) => { enzyme: string; positions: number[] }[]`\n\n```ts\nfunction findCutters(\n  sequence: string,\n  circular: boolean,\n  enzymes?: EnzymeSpec[],\n  maxCutFrequency?: number,\n): { enzyme: string; positions: number[] }[];\n```\n\nScans `sequence` for each enzyme's site (defaults to [`DEFAULT_ENZYMES`](#default_enzymes-enzymespec)) and returns the cut positions per enzyme. `maxCutFrequency` filters by cut count — e.g. `1` keeps only unique cutters, `0` disables the filter.\n\n### `reverseComplement(seq) => string`\n\n```ts\nfunction reverseComplement(seq: string): string;\n```\n\nReturns the reverse complement of a nucleotide string.\n\n### `DEFAULT_ENZYMES: EnzymeSpec[]`\n\nA built-in panel of common type-II restriction enzymes (EcoRI, BamHI, HindIII, XhoI, NotI, …). Use it as-is, or pass your own array to `findCutters` / `RenderOptions.enzymes`.\n\n### `detectCommonFeatures(sequence, circular?) => Feature[]`\n\n```ts\nfunction detectCommonFeatures(sequence: string, circular?: boolean): Feature[];\n```\n\nExact-matches the bundled common-feature panel (AmpR, KanR, common origins/promoters/primers) against `sequence` on both strands and returns the hits as `Feature`s (with correct `strand` and origin-wrapping coordinates when `circular`).\n\n### `COMMON_FEATURES`\n\nThe bundled common-feature panel data used by `detectCommonFeatures`.\n\n### `featureColor(name, type?) => { fill: string; border: string }`\n\n```ts\nfunction featureColor(name: string, type?: string): { fill: string; border: string };\n```\n\nReturns the deterministic `fill`/`border` colors for a feature. Well-known classes get conventional colors; anything else is hashed to a stable hue, so the same feature always renders the same color.\n\n## Types\n\n### `Strand`\n\n```ts\ntype Strand = 1 | -1 | 0;\n```\n\n`1` = forward (sense), `-1` = reverse, `0`/`undefined` = unstranded.\n\n### `Feature`\n\n```ts\ninterface Feature {\n  name: string;      // label drawn on the map\n  type?: string;     // feature class, e.g. \"CDS\", \"promoter\", \"rep_origin\"; drives color\n  start: number;     // 1-based inclusive start\n  end: number;       // 1-based inclusive end (may be < start — see below)\n  strand?: Strand;\n}\n```\n\n> **Coordinate convention.** `start` and `end` are **1-based and inclusive**, following the GenBank / SnapGene convention. A feature that **wraps the origin** of a circular molecule has **`start > end`** (it runs from `start` to the end of the sequence and continues from position 1 to `end`).\n\n### `PlasmidRecord`\n\n```ts\ninterface PlasmidRecord {\n  name: string;        // display name, drawn in the center of the map\n  sequence: string;    // raw nucleotide sequence; non-ACGT chars are ignored for rendering\n  circular?: boolean;  // circular (plasmid) vs linear — default true\n  features?: Feature[]; // known annotations; auto-detected when empty and detectFeatures is on\n  definition?: string; // free-text description (e.g. GenBank DEFINITION); carried through, not drawn\n}\n```\n\n### `EnzymeSpec`\n\n```ts\ninterface EnzymeSpec {\n  name: string; // e.g. \"EcoRI\"\n  site: string; // recognition site on the sense strand, e.g. \"GAATTC\"\n}\n```\n\n### `RenderOptions`\n\n```ts\ninterface RenderOptions {\n  size?: number;\n  showCutters?: boolean;\n  maxCutFrequency?: number;\n  enzymes?: EnzymeSpec[];\n  showFeatures?: boolean;\n  showTicks?: boolean;\n  detectFeatures?: boolean;\n  title?: string;\n}\n```\n\n| Option | Type | Default | Description |\n| --- | --- | --- | --- |\n| `size` | `number` | `800` | SVG viewport size (square); sets `viewBox=\"0 0 size size\"`. |\n| `showCutters` | `boolean` | `true` | Draw restriction cut sites. |\n| `maxCutFrequency` | `number` | `1` | Only draw enzymes that cut exactly this many times (`1` = unique cutters read best). `0` = no filter. |\n| `enzymes` | `EnzymeSpec[]` | `DEFAULT_ENZYMES` | Enzymes to scan for. |\n| `showFeatures` | `boolean` | `true` | Draw feature arrows/arcs. |\n| `showTicks` | `boolean` | `true` | Draw the base-pair tick ruler. |\n| `detectFeatures` | `boolean` | `true` | When the record has no features, auto-detect the bundled common-feature panel. |\n| `title` | `string` | `record.name` | Title override drawn in the center. |\n\n## How detection works\n\n- **Restriction sites** — for each enzyme site, the sequence is scanned on **both strands**. For circular molecules, matches that **span the origin** are found as well (the sequence is treated as a loop). Cut counts are then filtered by `maxCutFrequency` so, by default, only unique cutters are drawn.\n- **Common features** — the bundled panel (AmpR, KanR, common origins/promoters/primers) is matched by **exact sequence** on both strands. Matches become `Feature`s with the correct strand and, on circular molecules, origin-wrapping coordinates (`start > end`).\n\nBecause everything is exact-match, detection is deterministic and reproducible: the same input always yields the same features, colors, and layout.\n\n## License\n\nMIT © cara — the renderer, its parsers and the demo site.\n\nThe Sleeping Beauty vector sequences under [`docs/samples/`](https://github.com/cara/plasmid/tree/main/docs/samples) are **not** MIT-licensed: they are © Severin Fink, from the dissertation [DOI:10.25972/OPUS-24979](https://doi.org/10.25972/OPUS-24979), included as demonstration data with the author's permission.\n","readmeFilename":"README.md"}