lodash/lodash
Two distinct flows exist. At library runtime, data enters as plain JS values through method arguments, is normalized by `castPath`/`toKey`/`baseIteratee`, mutated or cloned by `base*` internals, and exits either as a new value or — in chain mode — as a `LazyWrapper`/`lodash` wrapper holding `__wrapped__` and an `__actions__` queue that is only drained on `.value()`. At build time, the input boundary is `lodash.js` plus `fp/_mapping.js`; transforms are `fs.copy`, `uglify.minify`, `webpack`, `docdown` and `_.template`-compiled `.jst` files; the output boundary is the filesystem (`dist/`, `doc/`, or an arbitrary `target` from `process.argv`). The FP path is unusual: `_mapping.js` is pure data that is read three times — by `_baseConvert` at runtime, by `build-modules.js` to decide which template to emit, and by `build-doc.js` to render the wiki.
- Property paths are the main untrusted input boundary: `castPath` converts strings/arrays to key arrays and `toKey` normalizes each segment before any read or write in `baseGet`/`baseSet`/`baseUnset`.
- Writes funnel through `assignValue` → `baseAssignValue`, which special-cases the key `__proto__` by using `Object.defineProperty` with an own data descriptor rather than plain assignment, so it lands on the object instead of the prototype.
- Deep merge reads go through `safeGet`, which returns `undefined` for `__proto__` and for `constructor` when it resolves to a function — cutting the read side of the pollution chain.
- Chain state lives on the wrapper instance: `mixin` installs prototype methods that clone `__actions__` via `copyArray`, push `{func, args, thisArg}`, carry `__chain__` forward, and defer execution until `.value()`.
- In `_baseConvert`, each method flows through a fixed transform pipeline — immutability wrapper → `castFixed` (arity cap or `flatSpread`) → `castRearg` (argument permutation) → `castCap` (iteratee arity cap) → `castCurry` — with `methodSpread[name].afterRearg` deciding whether fixed or rearg runs first.
- The FP converter owns two state sources: a `pristine = func.runInContext()` snapshot used so `.convert()` re-derives from unconverted methods, and a `defaultHolder` placeholder that is stamped onto both the wrapped and original function as `.placeholder`.
- Conversion output is assembled as `pairs` of `[name, wrappedFn]` — first for every name in `mapping.aryMethod[1..4]`, then for remaining own function keys — and only then assigned back onto `_`, deliberately leaving `_.prototype` untouched so chaining still works.
- `_.set`-family immutability in FP is achieved by `cloneByPath`, which walks the resolved path cloning each level but skipping values that are functions, errors or WeakMaps.
- Build data flows from `fp/_mapping.js` → `lib/common/mapping.js` (null-prototype Hash) → `lib/fp/build-modules.js`, where `_.union(mapping.aryMethod[1..4])` forms `aryMethods` and drives the `isThru` decision for every emitted module.
- `.jst` templates are compiled to functions at require time by `file.globTemplate`, which globs `*.jst`, keys them by basename, and runs each through `_.template` — so `template.module`, `template.alias`, `template.wiki` are lodash templates executed with `{name, mapping}` data.
- The doc HTML flow mutates markdown through five ordered regex rewrites (uncommenting docdown HTML hints, converting `[source]`/`[npm package]` links after `<h3>`) before Cheerio DOM passes `autoLink`, `renameLodashId`, `removeHorizontalRules`, `removeMarkyAttributes`, `repairMarkyHeaders`, `tidyHighlights`.
- The site build derives its output filename from the document itself — it removes the first `<h1>`, reads the version out of its `<span>`, and writes `doc/<version>.html`; if that span is missing the front matter records `version: null`.
- In the browser harness, the build path is a URL query parameter: `test-ui.js` parses `?build=` and `?loader=`, maps them to file paths, and `test/index.html` `document.write`s those paths as script tags — the page loads whatever path the URL names, including a full remote URL (`ui.isForeign`).
- Web Worker coverage round-trips the build path: `test.js` posts `ui.buildPath` to `test/asset/worker.js`, which `importScripts` it and posts back `_.VERSION` (or the caught error message stuffed into a fake `VERSION`), landing in `_._VERSION`.