{"id":51273388,"url":"https://github.com/johnsonjh/lzpack","last_synced_at":"2026-07-18T07:01:26.219Z","repository":{"id":360268361,"uuid":"1249360103","full_name":"johnsonjh/lzpack","owner":"johnsonjh","description":"LZPACK - CP/M-80 (8080 and Z80) executable compressor in ANSI C89","archived":false,"fork":false,"pushed_at":"2026-06-30T16:50:04.000Z","size":11037,"stargazers_count":6,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2026-06-30T18:22:52.612Z","etag":null,"topics":["8080","ansi-c","c89","compression","compressor","cpm","cpm80","cpm86","executable-compressor","executable-packing","lzpack","packer","popcom","stubasm","z80"],"latest_commit_sha":null,"homepage":"https://github.com/johnsonjh/lzpack","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit-0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/johnsonjh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-25T16:06:46.000Z","updated_at":"2026-06-30T16:50:09.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/johnsonjh/lzpack","commit_stats":null,"previous_names":["johnsonjh/lzpack"],"tags_count":50,"template":false,"template_full_name":null,"purl":"pkg:github/johnsonjh/lzpack","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnsonjh%2Flzpack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnsonjh%2Flzpack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnsonjh%2Flzpack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnsonjh%2Flzpack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/johnsonjh","download_url":"https://codeload.github.com/johnsonjh/lzpack/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnsonjh%2Flzpack/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35609254,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-18T02:00:07.223Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["8080","ansi-c","c89","compression","compressor","cpm","cpm80","cpm86","executable-compressor","executable-packing","lzpack","packer","popcom","stubasm","z80"],"created_at":"2026-06-29T20:00:22.554Z","updated_at":"2026-07-18T07:01:26.205Z","avatar_url":"https://github.com/johnsonjh.png","language":"C","funding_links":[],"categories":[":package: Packers"],"sub_categories":["After 2010"],"readme":"\u003c!-- Copyright (c) 2026 Jeffrey H. Johnson \u003cjohnsonjh.dev@gmail.com\u003e --\u003e\n\u003c!-- SPDX-License-Identifier: MIT-0 --\u003e\n\u003c!-- scspell-id: a631c7ac-5d68-11f1-844d-80ee73e9b8e7 --\u003e\n\n# LZPACK\n\n**LZPACK** is an executable compressor for CP/M‑80 binaries.\n\nIt shrinks 8080 and Z80 `.COM` programs, often to half their original size,\nwhile leaving them directly executable: every packed file is a\n*self‑extracting* `.COM` that decompresses itself and runs without any\nseparate unpacker and requires no changes to how the program is invoked.\n\nIt works very much like Yoshihiko Mino's classic CP/M‑80 *PopCom!* utility,\nbut packs tighter by using a better compression engine and decompresses\nfaster by using smaller hand‑optimized decompression stubs.\n\nThe **LZPACK** program and the packed executables it produces can run on a\nwide range of CP/M‑80 machines, including systems with Z80, 8080, 8085, and\nV20 processors, and systems with less than 48K\u0026nbsp;TPA.\n\nRunning the compressor on a system without CP/M‑80's memory constraints (such\nas on MS‑DOS, OS/2, Windows, Linux, or in any UNIX‑like environment) gives\neven better compression results.\n\n[Precompiled binaries for many systems are available for download.](#downloads)\n\n---\n\n\u003c!-- toc --\u003e\n\n- [Overview](#overview)\n- [Details](#details)\n  * [Compression results](#compression-results)\n  * [Decompression stubs](#decompression-stubs)\n  * [Operation](#operation)\n    + [Compressors](#compressors)\n    + [Decompressors](#decompressors)\n    + [Performance](#performance)\n- [Usage](#usage)\n  * [Memory ceiling (`-M`)](#memory-ceiling--m)\n  * [Runtime memory check (`-C`)](#runtime-memory-check--c)\n  * [Runtime memory floor (`-F`)](#runtime-memory-floor--f)\n- [Downloads](#downloads)\n- [Platform notes](#platform-notes)\n- [Building from source](#building-from-source)\n  * [Build targets](#build-targets)\n  * [Developer notes](#developer-notes)\n- [Security](#security)\n- [SAST and linters](#sast-and-linters)\n- [Code statistics](#code-statistics)\n- [License](#license)\n\n\u003c!-- tocstop --\u003e\n\n## Overview\n\n**LZPACK** is a single, ultra‑portable ANSI C89 program.\n\nThe *compressor* runs on just about anything with an ANSI C89 compiler.  You\ncan pack CP/M‑80 programs on any modern UNIX\n(even [**ELKS**](https://github.com/ghaerr/elks)), OS/2, Windows, or MS‑DOS\nsystem without emulation, as well as pack natively on the CP/M‑80 target.\n\nThe *decompressor* that is embedded into each packed executable is\nhand‑written and highly optimized 8080 or Z80 assembly.\n\nPrecompiled binaries are provided for **CP/M‑80** (8080 and Z80),\n**CP/M‑86** (8086/8088), **MS‑DOS** (16‑bit 8086/8088 real‑mode and 32‑bit\n386\u0026nbsp;DPMI), **ELKS** (8086/8088), **OS/2** (32‑bit), **Linux** (32‑bit\ni386, 32‑bit ARMv5, 64‑bit x86‑64, and 64‑bit ARMv8), **Atari\u0026nbsp;ST**\n(TOS/MINT), **AmigaOS** (68K), and **Windows** (both 32‑ and 64‑bit versions).\n\nThe CP/M‑80 builds also run on **MSX‑DOS** (as do the packed executables\n**LZPACK** generates).\n\n## Details\n\n**LZPACK**'s `-R` (restore) and `-L` (list) commands recognize both **LZPACK**\nand *PopCom!*‑packed files (as they use the same container and stream format),\nmaking it simple to decompress (and recompress) already packed executables.\n\n**LZPACK** (and **LZPACK**‑packed binaries) can run on a *plain 8080*, not\njust the Z80.  **LZPACK** analyzes the file to be packed and automatically\ndetects if the program actually uses Z80 instructions, and picks a matching\ndecompression stub.\n\nUsers can also specify `-8` to explicitly use the 8080 stub, or `-Z` to force\nthe Z80 stub, in case the automatic detection gets it wrong (which can happen).\nFor example, the CP/M‑80 **LZPACK** program itself (when built for 8080) is\nmisdetected as a Z80 binary due to the Z80 opcode scanning code embedded in\nthe executable.\n\nWhile packed 8080 programs using the 8080 stub will run on any 8080 (or 8085)\nsystem, they can sometimes be packed smaller by using the Z80 stub, at the\ncost of 8080 compatibility.  If you aren't packing executables for public\ndistribution, you might want to use the Z80 stub unconditionally if you have\na Z80‑powered system.\n\n**LZPACK** also includes a hand‑written and optimized 8086/8088 assembly\ndecompressor used for the `-R` (restore) feature when built for 8086/8088\ntargets such as CP/M‑86, real‑mode MS‑DOS, and ELKS.  This is not only faster\nthan the ANSI C89 version but also smaller, which leaves more memory available\nfor compression.\n\nFor extremely memory‑constrained systems, custom builds can be created that\ncompletely exclude the `-R` decompression code, which might save a few\nprecious bytes.\n\n**LZPACK** should build easily anywhere from source code, and needs only an\nANSI C89‑conforming compiler, without requiring any external assemblers.  The\nsource repository does not include any binary blobs.  Instead, the 8080 and\nZ80 stubs are assembled from their included sources during the build process\nusing an included custom assembler, [**StubASM**](stubasm.c), also written in\nportable C89.\n\nIt may not be the smallest executable packer, nor the most technically\nimpressive, but it is permissively licensed, portable (able to run on machines\nranging from tiny CP/M‑80 systems to current workstations running any\noperating system), and extremely compatible (without depending on undefined\nbehavior or undocumented functionality of any hardware or software).\n\n### Compression results\n\nThe table below compares **LZPACK** against *PopCom!* 1.0 (the most popular\nCP/M‑80 packer) on a few real‑world CP/M‑80 executables.\n\n| Program   | Original |                  PopCom! |                 LZPACK/N |                LZPACK/N+ |                 LZPACK/C |\n|:----------|---------:|-------------------------:|-------------------------:|-------------------------:|-------------------------:|\n| `BLS`     | `19,210` | `12,160`\u0026nbsp;(`‑36.7%`) | `11,890`\u0026nbsp;(`‑38.1%`) | `11,884`\u0026nbsp;(`‑38.1%`) | `11,945`\u0026nbsp;(`‑37.8%`) |\n| `FORTH80` |  `8,136` |  `6,272`\u0026nbsp;(`‑22.9%`) |  `6,094`\u0026nbsp;(`‑25.1%`) |  `6,093`\u0026nbsp;(`‑25.1%`) |  `6,106`\u0026nbsp;(`‑25.0%`) |\n| `M80`     | `20,023` | `13,952`\u0026nbsp;(`‑30.3%`) | `13,711`\u0026nbsp;(`‑31.5%`) | `13,702`\u0026nbsp;(`‑31.6%`) | `13,755`\u0026nbsp;(`‑31.3%`) |\n| `MBASIC`  | `24,313` | `19,456`\u0026nbsp;(`‑20.0%`) | `19,182`\u0026nbsp;(`‑21.1%`) | `19,178`\u0026nbsp;(`‑21.1%`) | `19,239`\u0026nbsp;(`‑20.9%`) |\n| `PILOT`   | `30,902` | `13,184`\u0026nbsp;(`‑57.3%`) | `12,798`\u0026nbsp;(`‑58.6%`) | `12,792`\u0026nbsp;(`‑58.6%`) | `12,876`\u0026nbsp;(`‑58.3%`) |\n| `SARGON`  | `14,592` |  `8,704`\u0026nbsp;(`‑40.4%`) |  `8,598`\u0026nbsp;(`‑41.1%`) |  `8,593`\u0026nbsp;(`‑41.1%`) |  `8,619`\u0026nbsp;(`‑40.9%`) |\n| `VDT1398` | `17,443` | `13,056`\u0026nbsp;(`‑25.2%`) | `12,876`\u0026nbsp;(`‑26.2%`) | `12,874`\u0026nbsp;(`‑26.2%`) | `12,914`\u0026nbsp;(`‑26.0%`) |\n| `VDT139Z` | `16,485` | `12,544`\u0026nbsp;(`‑23.9%`) | `12,333`\u0026nbsp;(`‑25.2%`) | `12,325`\u0026nbsp;(`‑25.2%`) | `12,371`\u0026nbsp;(`‑25.0%`) |\n| `VDT232Z` | `24,304` | `18,688`\u0026nbsp;(`‑23.1%`) | `18,437`\u0026nbsp;(`‑24.1%`) | `18,430`\u0026nbsp;(`‑24.2%`) | `18,500`\u0026nbsp;(`‑23.9%`) |\n| `WS30`    | `15,872` | `11,648`\u0026nbsp;(`‑26.6%`) | `11,427`\u0026nbsp;(`‑28.0%`) | `11,425`\u0026nbsp;(`‑28.0%`) | `11,455`\u0026nbsp;(`‑27.8%`) |\n| `ZORK1`   |  `8,426` |  `5,376`\u0026nbsp;(`‑36.2%`) |  `5,280`\u0026nbsp;(`‑37.3%`) |  `5,276`\u0026nbsp;(`‑37.4%`) |  `5,297`\u0026nbsp;(`‑37.1%`) |\n\n* The \"**/N**\" builds are native Linux x86_64; the \"**/C**\" builds are CP/M‑80.\n\n* **LZPACK** beats *PopCom!* on **every** file in **every** configuration.\n\n* The \"**/N+**\" column is the **extra compression** mode.  On a memory‑rich\n  host, it parses the whole file at once and usually beats the standard\n  mode by at least a few bytes (**/N+`-E`** vs. **/N**).\n\n* The **/C** figures were measured under `tnylpo` (with a \\~**63K** TPA).\n  On CP/M‑80 (or any other memory‑constrained system), the window sizes and\n  compression ratio scale with the available memory: a small TPA means a\n  small compression window and somewhat larger output.  Currently any Z80\n  system with \\~**48.5K**\u0026nbsp;TPA or any 8080 system with \\~**51K**\u0026nbsp;TPA\n  is able to run the *\"full strength\"* (8K window) compressor.  See the\n  following table for compression window size vs. available TPA:\n\n  |   System |               1K‑window |               2K‑window |               4K‑window |               8K‑window |\n  |---------:|------------------------:|------------------------:|------------------------:|------------------------:|\n  |  **Z80** | `28,095`\u0026nbsp;(`27.4K`) | `31,167`\u0026nbsp;(`30.4K`) | `37,311`\u0026nbsp;(`36.4K`) | `49,599`\u0026nbsp;(`48.4K`) |\n  | **8080** | `30,737`\u0026nbsp;(`30.0K`) | `33,809`\u0026nbsp;(`33.0K`) | `39,953`\u0026nbsp;(`39.0K`) | `52,241`\u0026nbsp;(`51.0K`) |\n\n* The test files were \"trimmed\" to their \"near‑exact\" length on the Linux\n  host system used for testing (determined by discarding up to, but *not*\n  including, the final `0x00` or `0x1A` bytes in the last 128‑byte \"record\").\n\n* On CP/M\u0026nbsp;2.2 systems, files do not have exact lengths but instead occupy\n  fixed‑size records of 1024 bits (128 bytes).  When **LZPACK** is operating\n  on CP/M‑Plus (CP/M‑80 or CP/M‑86\u0026nbsp;3+) or DOS‑PLUS (CP/M‑86\u0026nbsp;4+), the\n  [LRBC](https://www.seasip.info/Cpm/bytelen.html) (Last Record Byte Count)\n  metadata is used to determine how many bytes of the final record should be\n  packed.  On CP/M\u0026nbsp;2.2 systems, all bytes in the final record are packed.\n  *PopCom!* does not support sizing via the LRBC and compresses all records.\n\n* Because the [`tnylpo`](https://gitlab.com/gbrein/tnylpo) and\n  [`cpm`](https://github.com/jhallen/cpm) emulators used for testing do *not*\n  emulate CP/M‑Plus (and thus do not provide LRBC metadata), any file not\n  ending at an exact record boundary would be automatically padded to the size\n  of the next full record.\n\n### Decompression stubs\n\nBecause every packed program must include a copy of the decompression stub,\nit is vital that the code be as small (and fast) as possible.  The table below\ncompares the **LZPACK** decompression stubs against those from the\n*PopCom!* packer.\n\n|      CPU |         PopCom! | LZPACK          |\n|---------:|----------------:|:----------------|\n| **Z80**  | **`230` bytes** | **`180` bytes** |\n| **8080** | (*Unsupported*) | **`238` bytes** |\n\n* **LZPACK**'s Z80 code is just **180 bytes** (including setup code) versus\n  *PopCom!*'s **230 bytes**, over **21% smaller**.\n* *PopCom!* has no 8080 support at all, while **LZPACK**'s pure 8080\n  decompressor weighs in at only **\\~3%** larger than the *PopCom!* Z80 code.\n\n### Operation\n\nWhen a packed program is invoked, the CP/M loader places it at `0x100` and a\n`JP` at the entry redirects control to the decompression stub, which then:\n\n1. Restores the 16 original header bytes the packer has saved,\n2. Relocates the compressed payload and the decompression stub into the high\n   end of the TPA, so the stub can run without overwriting itself,\n3. Decompresses in‑place into the TPA, writing output from `0x110` upward, and\n4. Jumps back to `0x100` to run the unpacked executable image.\n\n* This scheme does **not** currently support CP/M‑Plus / CP/M‑3+\n  `GENCOM`‑processed executables which use pre‑initialization code or have\n  attached RSXs.  Such images carry a one‑page header whose first byte is\n  `0C9h` (a `RET`, harmless on CP/M\u0026nbsp;2.2); **LZPACK** detects this marker\n  and refuses to pack them with a `GENCOM unsupported` error.  You can use the\n  `GENCOM` utility to convert executables to standard CP/M binary images if\n  possible (without the `GENCOM` header, pre‑init code, or RSXs) before using\n  **LZPACK**.\n* Support for some `GENCOM`‑processed CP/M‑Plus executables may be added in\n  a future **LZPACK** release.\n\n#### Compressors\n\n**LZPACK** compresses using a cost‑optimal shortest‑path parser and includes\n**two implementations**:\n\n1. The **in‑memory** implementation loads the entire file into RAM and finds\n   matches with a hash‑chain over the entire file.  It is used by native,\n   32‑bit and 64‑bit Windows, 32‑bit OS/2, and 386 DPMI MS‑DOS builds.\n\n2. The **streaming** implementation reads the input through a sliding window\n   and writes the output to a temporary file, so its working memory is\n   independent of the file size.  This lets memory‑constrained systems\n   (*e.g.*, CP/M‑80, CP/M‑86, real‑mode MS‑DOS, and ELKS) pack arbitrarily\n   large executables.\n\nEach implementation has **two modes**, which trade memory for size:\n\n1. The **standard compression** mode uses a small parse block, keeping its\n   working set tiny and leaving the most room for a large match window.\n\n2. The **extra compression** mode (`-E`) enlarges the block for the tightest\n   possible parse.\n\nOn a memory‑rich host, using `-E` trims down files by at least a few more\nbytes.  On CP/M‑80 systems, due to memory constraints, the `-E` option is\nnot available.\n\n#### Decompressors\n\n**LZPACK** includes **four** independent (but equivalent) **decompression**\nengines, differing in execution speed, code size, and memory usage:\n\n1. The **standard** portable decompression engine is written in pure ANSI C89.\n\n2. The **8080** assembly‑language decompression engine (built by **StubASM**).\n\n3. The **Z80** assembly‑language decompression engine (also built\n   by **StubASM**).\n\n4. The **8086** assembly‑language decompression engine, used for\n   the `-R` restore option on 8086/8088 systems (*i.e.*, CP/M‑86, MS‑DOS,\n   and ELKS).\n\nThe 8086 decompression engine source code is automatically generated by the\nbuild system, which works by transforming a shared assembly routine into the\nproper dialect for the target, currently **GNU\u0026nbsp;`as`**,\n**Watcom\u0026nbsp;`wasm`**, or **Aztec `#asm`**, so no additional cross‑assemblers\nor tools are required when cross‑compiling.\n\n#### Performance\n\n* While **LZPACK**‑generated executables are often smaller, more compatible,\n  and always *decompress* faster than those produced by *PopCom!*, the\n  **LZPACK** *compressor* is ***much*** slower than *PopCom!*'s, especially on\n  vintage hardware: *PopCom!* uses hand‑written Z80 assembly, whereas\n  **LZPACK** uses portable ANSI C89 to implement a cost‑optimal parser that\n  does far more work per byte.\n\n* **LZPACK** prioritizes the smallest output with the fastest possible\n  *unpacking*, because decompression happens *every time the packed program\n  is run*, while packing happens rarely (especially on vintage systems) and\n  can be done on modern hardware (which almost everyone has now, in the\n  year 2026).\n\n## Usage\n\n```\nLZPACK v1.07 - CP/M-80 (8080 and Z80) executable compressor\nCopyright (c) 2026 Jeffrey H. Johnson \u003cjohnsonjh.dev@gmail.com\u003e\n\nUsage:\n  lzpack [-E] [-8|-Z] \u003cfile\u003e  compress (-E: extra, -8/-Z: force 8080/Z80 stub)\n  lzpack -R \u003cfile\u003e            restore (decompress)\n  lzpack -L \u003cfile\u003e            list stored sizes\n  lzpack -O \u003cname\u003e            set output name\n  lzpack -M \u003ctop\u003e             set memory top (default 48K)\n  lzpack -C                   stub verifies memory at run time\n  lzpack -F \u003cfloor\u003e           require memory top \u003e= floor (implies -C)\n  lzpack -V                   show LZPACK information\n```\n\nThe **CP/M‑80** version of **LZPACK** is split into two utilities:\n  * `LZPACK.COM` for compression only, and\n  * `LZUNPACK.COM` for decompression and listing.\n\nOn all other platforms, a single `lzpack` tool is provided, as shown above.\n\n### Memory ceiling (`-M`)\n\nAs a packed program decompresses in place on the target machine, the image\nexpands to its full original size at `0x100` with the relocated decompressor\nsitting above it.  At packing time, **LZPACK** verifies that everything fits\nbelow a memory ceiling (*MEMTOP*), and will refuse to produce an output file\notherwise.  The default is at `0xBDFF`, so all packed programs are guaranteed\nto run on any **48K\u0026nbsp;TPA** system, but the `-M` option can be used to\noverride this:\n\n* Use `-M 64` to pack programs too large for **48K\u0026nbsp;TPA**, but the result\n  *requires* a correspondingly larger TPA at run time.\n* Use `-M 32` (or less) to guarantee the output runs on smaller systems, or\n  to keep the unpacker away from any resident driver that might have stolen\n  the top of the TPA, or to enforce a maximum image size while developing new\n  software.\n\nThe `-M` option accepts an argument in three formats:\n\n|              Format | Example                    | Description                    |\n|--------------------:|:---------------------------|:-------------------------------|\n| KB size (≤64)       | `-M 32` (or `-M 32K`)      | kilobytes (48 is default)      |\n| hex address         | `-M 0x7DFF`                | literal *MEMTOP* address       |\n| decimal address     | `-M 65023`                 | literal *MEMTOP* address (\u003e64) |\n\nValues below `0x1190` (**4K**) or above `0xFFFF` (**64K**) are rejected.\n\n### Runtime memory check (`-C`)\n\nThe packing‑time checks cannot know the details of the machine the packed\nprogram will eventually run on; for example, it might have a much smaller TPA\nthan the one running the packer, or it might have a resident driver that\nlowers the BDOS pointer at `0x0006`, which could be silently overwritten\nduring decompression.  The `-C` option enhances the stub with a small\n(48‑byte) runtime check.  It verifies that the highest address the unpacker\nwill write to lies below the BDOS base and that at least 24 bytes are clear\nof the live inherited stack.  If the program does not fit, it prints `No room`\nand aborts.\n\nBecause this check adds an extra 48 bytes to every packed executable, it is\ndisabled by default.  Enabling it does **not** consume any high memory, and it\nis never relocated, so it will not change what fits with any given\n`-M` setting.\n\n### Runtime memory floor (`-F`)\n\nThe `-F` option is mostly useful to developers of CP/M‑80 software and\nnot end‑users.\n\n\u003cdetails\u003e\n \u003csummary\u003e\u003cb\u003e\u003ci\u003eExpand this section for further details.\u003c/i\u003e\u003c/b\u003e\u003c/summary\u003e\n\n\u003cbr\u003e\n\nThe `-C` option adds a check that refuses a TPA that the *unpacker* would\noverrun, but a packed program almost always needs more memory to actually\n*run* than it does to simply unpack.  With a TPA that sits between those\ntwo bounds, the program unpacks successfully but then crashes (or silently\ncorrupts memory) during its own startup (which would still happen even in\nthe absence of any executable compression).\n\nWhen the packer is informed of the actual program runtime memory requirements\nvia the `-F` option, the check/verification stub (normally emitted with `-C`)\ncan cleanly refuse to run on a machine whose memory top lies below the\nspecified floor.  The argument accepts the same formats as `-M` (and\nimplies `-C`).\n\nMost CP/M users wishing to save space on their disks will be packing existing\nprograms and will never need to use `-F`.  Developers who are creating CP/M\nsoftware (who ship packed executables), especially when working with compiled\nlanguages, can greatly benefit.  A compiled `.COM` usually understates its\nruntime footprint: uninitialized data (BSS) is not necessarily stored in the\nfile at all, and the language's runtime and startup code carves its stack and\nheap out of high memory *before* the first line of user code (*e.g.*,\n`main()`) runs.\n\nBecause the trouble happens early, no in‑program check can catch this sort\nof shortfall.  By the time the `main()` function could test anything, the\nruntime has already cleared BSS across the BDOS or planted a heap with a\nwrapped size, or simply crashed without any useful messages displayed at all.\n\nFinding the floor value to use is an extra step at release: read the end of\nstatic storage from the linker's map and add the runtime's stack reserve, or\nif you are cross‑developing, simply measure the value empirically by using an\nemulator that can dynamically shrink the TPA.\n\nIt is hoped that the **LZPACK** build can serve as an example of this process,\nsince the shipped CP/M‑80 binaries (`LZPACK.COM` and `LZUNPACK.COM`) are\npacked with a floor derived from each tool's own map plus the stack reserve,\nso on any system with a TPA large enough for them to *unpack* but too small\nfor them to fully *initialize*, they simply print `No room` and exit cleanly,\nwhich would be impossible to achieve using C code alone.\n\nThe `-L` (list) command reads the check block back out of a packed file.\nIt reports `no -C check` for files packed without `-C` and the enforced\nfloor for checked files (`-C check; floor 0xBDFF`).  The size line also\ntags the self‑extractor's architecture (`[Z80]` or `[8080]`), recognized\nfrom the stub bytes themselves; files whose stub is not recognized (foreign\ntools, or other **LZPACK** versions) simply list untagged.  On **CP/M‑80**\nsystems the list option is part of `LZUNPACK.COM`, so the embedded floor of\nany packed program can be inspected on the target machine itself.\n\n\u003c/details\u003e\n\n## Downloads\n\n|                                                                                          File  | Size        | Platform                              |\n|-----------------------------------------------------------------------------------------------:|------------:|:--------------------------------------|\n| [LZPCKI80.ARC](https://github.com/johnsonjh/lzpack/raw/refs/heads/master/bindist/LZPCKI80.ARC) | 20\u0026nbsp;KiB | **CP/M‑80**\u0026nbsp;(8080)               |\n| [LZPCKZ80.ARC](https://github.com/johnsonjh/lzpack/raw/refs/heads/master/bindist/LZPCKZ80.ARC) | 24\u0026nbsp;KiB | **CP/M‑80**\u0026nbsp;(Z80)                |\n| [LZPCK86C.ARC](https://github.com/johnsonjh/lzpack/raw/refs/heads/master/bindist/LZPCK86C.ARC) | 20\u0026nbsp;KiB | **CP/M‑86**\u0026nbsp;(8086/8088)          |\n| [LZPCKELK.Z](https://github.com/johnsonjh/lzpack/raw/refs/heads/master/bindist/LZPCKELK.Z)     | 16\u0026nbsp;KiB | **ELKS**\u0026nbsp;(8086/8088)             |\n| [LZPCK86R.ZIP](https://github.com/johnsonjh/lzpack/raw/refs/heads/master/bindist/LZPCK86R.ZIP) | 20\u0026nbsp;KiB | **MS‑DOS**\u0026nbsp;(8086/8088)           |\n| [LZPCK86P.ZIP](https://github.com/johnsonjh/lzpack/raw/refs/heads/master/bindist/LZPCK86P.ZIP) | 76\u0026nbsp;KiB | **MS‑DOS**\u0026nbsp;(80386\u0026nbsp;DPMI)     |\n| [LZPACKST.LZH](https://github.com/johnsonjh/lzpack/raw/refs/heads/master/bindist/LZPACKST.LZH) | 132\u0026nbsp;KiB | **Atari\u0026nbsp;ST**\u0026nbsp;(TOS/MINT)    |\n| [LZPACKAM.LHA](https://github.com/johnsonjh/lzpack/raw/refs/heads/master/bindist/LZPACKAM.LHA) | 40\u0026nbsp;KiB | **AmigaOS**\u0026nbsp;(68K)                |\n| [LZPCKOS2.ZIP](https://github.com/johnsonjh/lzpack/raw/refs/heads/master/bindist/LZPCKOS2.ZIP) | 20\u0026nbsp;KiB | **OS/2**\u0026nbsp;(32‑bit\u0026nbsp;i386)      |\n| [LZPCKW32.ZIP](https://github.com/johnsonjh/lzpack/raw/refs/heads/master/bindist/LZPCKW32.ZIP) | 36\u0026nbsp;KiB | **Windows**\u0026nbsp;(32‑bit\u0026nbsp;MSVCRT) |\n| [LZPCKW64.ZIP](https://github.com/johnsonjh/lzpack/raw/refs/heads/master/bindist/LZPCKW64.ZIP) | 24\u0026nbsp;KiB | **Windows**\u0026nbsp;(64‑bit\u0026nbsp;UCRT)   |\n| [LZPCKA32.gz](https://github.com/johnsonjh/lzpack/raw/refs/heads/master/bindist/LZPCKA32.gz)   | 32\u0026nbsp;KiB | **Linux**\u0026nbsp;(32‑bit\u0026nbsp;ARMv5)    |\n| [LZPCKA64.gz](https://github.com/johnsonjh/lzpack/raw/refs/heads/master/bindist/LZPCKA64.gz)   | 36\u0026nbsp;KiB | **Linux**\u0026nbsp;(64‑bit\u0026nbsp;ARMv8)    |\n| [LZPCKL32.gz](https://github.com/johnsonjh/lzpack/raw/refs/heads/master/bindist/LZPCKL32.gz)   | 16\u0026nbsp;KiB | **Linux**\u0026nbsp;(32‑bit\u0026nbsp;i386)     |\n| [LZPCKL64.gz](https://github.com/johnsonjh/lzpack/raw/refs/heads/master/bindist/LZPCKL64.gz)   | 40\u0026nbsp;KiB | **Linux**\u0026nbsp;(64‑bit\u0026nbsp;x86‑64)   |\n\n\u003e If you need a CP/M ARC utility, `UNARC` is available for\n[8080](https://github.com/johnsonjh/lzpack/raw/refs/heads/master/..utils/unarca.com)\nand [Z80](https://github.com/johnsonjh/lzpack/raw/refs/heads/master/.utils/unarcz.com)\nCP/M‑80, and `ARCCPM`\nfor [CP/M‑86](https://github.com/johnsonjh/lzpack/raw/refs/heads/master/.utils/arccpm.cmd).\n\n\u003e If you need an Atari\u0026nbsp;ST LHA/LZH utility, `LHarc` is available for\n[TOS/MINT](https://github.com/johnsonjh/lzpack/raw/refs/heads/master/.utils/lharc.ttp).\n\n## Platform notes\n\nThe CP/M‑86 version of **LZPACK** supports wildcard expansion, checking\nagainst the current drive's directory.  Any drive letter specified in the\npattern is ignored and the current drive is always searched.\n\nTo keep CP/M‑80 versions as small as possible, wildcard expansion is disabled\nby default, but can be enabled in custom builds using `-DLZPACK_WILDCARD=1`.\n\nThe 386\u0026nbsp;DPMI\u0026nbsp;MS‑DOS and Windows versions also support wildcard\nexpansion.  The real‑mode MS‑DOS version does not expand wildcards.\n\n## Building from source\n\n**LZPACK** needs **only an ANSI C89 compiler** to build on any\nUNIX‑like system.\n\n* To build a native binary, just run `make` (or `gmake`), which builds\n  **StubASM**, assembles the stubs, and then compiles `lzpack`:\n\n  ```sh\n  make\n  ```\n\n* You can also explicitly set `CC`, `CFLAGS`, `LDFLAGS`, etc.  For example, to\n  build an optimized 64‑bit binary on IBM AIX using the IBM XL C/C++ compiler\n  and AIX `make`:\n\n  ```sh\n  make CC=xlc CFLAGS=\"-O3 -q64\" LDFLAGS=\"-Wl,-b64\"\n  ```\n\n* To build a native binary on Windows using the Microsoft Visual Studio C/C++\n  compiler, from a **Developer Command Prompt for Visual Studio** window, run:\n\n  ```sh\n  msvcbuild.bat\n  ```\n\nThe GNU GCC, LLVM Clang, PCC, NVIDIA HPC SDK C/C++, Oracle Studio C/C++, DMD\nImportC, CompCert C, Open64, PathScale EKOPath, IBM XL C/C++, DJGPP, Vbcc, Ack,\nIBM Open XL C/C++, МЦСТ LCC, and Microsoft Visual C/C++ compilers are\nregularly tested.\n\n### Build targets\n\nThe following targets build various `lzpack` binaries.\n\nMost users will only be interested in the native binary build.\n\n| Make Target | Description                        | Toolchain                                                                                                                   |\n|------------:|:-----------------------------------|:----------------------------------------------------------------------------------------------------------------------------|\n| `all`       | Native\u0026nbsp;binary                 | ANSI\u0026nbsp;C89\u0026nbsp;compiler\u0026nbsp;(*e.g.*,\u0026nbsp;`c89`,\u0026nbsp;`gcc`,\u0026nbsp;`clang`)                                             |\n| `cpm`       | CP/M‑80\u0026nbsp;8080\u0026nbsp;+\u0026nbsp;Z80  | [z88dk](https://z88dk.org/)\u0026nbsp;(**2026‑07‑10+**)\u0026nbsp;and\u0026nbsp;[patched](tnylpo.diff)\u0026nbsp;`tnylpo`                       |\n| `cpm86`     | CP/M‑86\u0026nbsp;8086/8088             | [cross‑Aztec\u0026nbsp;C86\u0026nbsp;v4.2](https://github.com/tsupplis/cpm86-crossdev)\u0026nbsp;([tsupplis](https://github.com/tsupplis)) |\n| `os2`       | OS/2\u0026nbsp;i386                     | [Open\u0026nbsp;Watcom\u0026nbsp;V2.0](https://github.com/open-watcom/open-watcom-v2)                                                 |\n| `msdos`     | MS‑DOS\u0026nbsp;8086/8088              | [Open\u0026nbsp;Watcom\u0026nbsp;V2.0](https://github.com/open-watcom/open-watcom-v2)                                                 |\n| `djgpp`     | MS‑DOS\u0026nbsp;80386                  | [DJGPP](https://www.delorie.com/djgpp/)\u0026nbsp;and\u0026nbsp;[CWSDPMI](https://sandmann.dotster.com/cwsdpmi/)                      |\n| `elks`      | ELKS\u0026nbsp;8086/8088                | [IA16‑GCC](https://gitlab.com/tkchia/build-ia16)                                                                            |\n| `atari`     | Atari\u0026nbsp;ST\u0026nbsp;TOS/MINT        | [Crossmint](https://tho-otto.de/crossmint.php)                                                                              |\n| `amiga`     | AmigaOS\u0026nbsp;68K                   | [Vbcc](http://www.compilers.de/vbcc.html)                                                                                   |\n| `windows`   | Windows\u0026nbsp;32/64‑bit             | [MinGW‑w64](https://www.mingw-w64.org/)\u0026nbsp;[GCC](https://gcc.gnu.org/)                                                    |\n\nThe following targets will likely only be of interest to developers:\n\n| Make Target | Description                                                                                      |\n|------------:|:-------------------------------------------------------------------------------------------------|\n| `stubs`     | Builds\u0026nbsp;only\u0026nbsp;StubASM\u0026nbsp;and\u0026nbsp;the\u0026nbsp;8080\u0026nbsp;+\u0026nbsp;Z80\u0026nbsp;stubs             |\n| `test`      | Runs\u0026nbsp;a\u0026nbsp;comprehensive\u0026nbsp;end‑to‑end\u0026nbsp;multiplatform\u0026nbsp;test\u0026nbsp;suite           |\n| `lint`      | Source‑code\u0026nbsp;quality\u0026nbsp;checks\u0026nbsp;(linting\u0026nbsp;and\u0026nbsp;static\u0026nbsp;analysis)           |\n| `tags`      | Builds\u0026nbsp;source\u0026nbsp;code\u0026nbsp;tags\u0026nbsp;(`etags`,\u0026nbsp;`ctags`,\u0026nbsp;`gtags`,\u0026nbsp;`cscope`) |\n\nThe CP/M‑80 build targets support running **z88dk** in the usual way or via\nDocker.  Setting the environment variable `CPM_BACKEND=local` forces a\nstandard build and setting `CPM_BACKEND=docker` forces the Docker‑ized build.\nIf the `CPM_BACKEND` environment variable is unset, a proper **z88dk**\ninvocation will be automatically determined by the build system.\n\nOther build targets are available; review the [`Makefile`](Makefile) for\ncomplete details.\n\nNOTE: The *complete* CP/M‑80 build (which automatically sets and verifies the\n`-M` and `-F` values) requires a [patched](tnylpo.diff) version of\n*Georg Brein*'s [`tnylpo`](https://gitlab.com/gbrein/tnylpo) emulator\navailable in your `PATH`.\n\n### Developer notes\n\n* `make lint` needs only a POSIX shell to run (plus whichever linters and\n  static analysis tools it invokes).  You'll be informed of any missing\n  prerequisites as well as any optional tools when you invoke `make lint`.\n\n* `make test` requires `python3`, several emulators, and many cross‑toolchains\n  installed if you want to run *all* the tests (of which there are several\n  hundred).  At a minimum, you need a [patched](tnylpo.diff) version of\n  *Georg Brein*'s [`tnylpo`](https://gitlab.com/gbrein/tnylpo) emulator and\n  *Joe Hallen*'s [`cpm`](https://github.com/jhallen/cpm) emulator installed.\n  You should build these with full optimizations enabled, as the test suite\n  is extensive with a lengthy runtime.\n\n* If you would like to contribute to **LZPACK** development, it is *extremely*\n  *important* that you have ***all*** of the optional linters, static analysis\n  tools, emulators, and cross‑toolchains installed, and that **both**\n  `make lint` and `make test` pass completely clean, as this is a\n  prerequisite for any change.  Every linter has, at some point, caught real\n  bugs in the code.\n\n* Usage of AI (artificial intelligence) tools by contributors is currently\n  permitted, subject to the same terms and conditions as the\n  [LLVM AI Tool Use Policy](https://llvm.org/docs/AIToolPolicy.html), but\n  this permission may be withdrawn at any time and without notice.\n\n## Security\n\n* The canonical home of this software is\n  [`https://github.com/johnsonjh/lzpack`](https://github.com/johnsonjh/lzpack),\n  with a mirror at\n  [`https://gitlab.com/johnsonjh/lzpack`](https://gitlab.com/johnsonjh/lzpack).\n* This software is intended to be **secure** 🛡️.\n* If you find any security‑related problems, please don't hesitate to\n  [open a GitHub Issue](https://github.com/johnsonjh/lzpack/issues/new).\n\n## SAST and linters\n\nThe following static analysis and dynamic verification tools are used as part\nof the comprehensive **LZPACK** testing process (with many invoked\nautomatically via the [`make lint`](.lint.sh) target):\n\n| Tool | Usage |\n|-----:|:------|\n| [**PVS‑Studio**](https://pvs-studio.com/pvs-studio/?utm_source=website\u0026utm_medium=github\u0026utm_campaign=open_source) | Static analysis tool for C, C++, C#, and Java code                                 |\n| [Clang\u0026nbsp;Analyzer](https://clang-analyzer.llvm.org/),\u0026nbsp;[Sanitizers](https://github.com/google/sanitizers)   | Static and dynamic analysis tools for C, C++, and Objective‑C code                 |\n| [Cppcheck](https://cppchecksolutions.com/)                                                                         | Static analysis tool for C and C++ code                                            |\n| [Dr.\u0026nbsp;Memory](https://drmemory.org/)                                                                           | Memory debugging tool for Windows, Linux, macOS, and Android                       |\n| [DUMA](https://github.com/johnsonjh/duma)                                                                          | Detect Unintended Memory Access, a memory debugger                                 |\n| [Flawfinder](https://dwheeler.com/flawfinder/)                                                                     | Scans C and C++ source code for potential security weaknesses                      |\n| [Funcheck](https://github.com/tmatis/funcheck)                                                                     | A tool for checking function call return protections                               |\n| [GCC\u0026nbsp;Static\u0026nbsp;Analyzer](https://gcc.gnu.org/onlinedocs/gcc/Static-Analyzer-Options.html)                   | Coverage‑guided symbolic execution static analyzer for C code                      |\n| [GNU\u0026nbsp;Global](https://www.gnu.org/software/global/)                                                            | Source code indexing and tagging system                                            |\n| [GNU\u0026nbsp;Cppi](https://www.gnu.org/software/cppi/)                                                                | C preprocessor directive linting, indenting, and regularization                    |\n| [IBM\u0026nbsp;AIX\u0026nbsp;lint](https://www.ibm.com/docs/en/aix/7.3.0?topic=l-lint-command)                               | Checks C and C++ language programs for potential problems                          |\n| [NetBSD\u0026nbsp;lint(1)](https://man.netbsd.org/lint.1)                                                               | A C (C90/C99/C11/C17/C23) program verifier                                         |\n| [Oracle\u0026nbsp;Developer\u0026nbsp;Studio](https://www.oracle.com/application-development/developerstudio/)               | Performance, security, and thread analysis tools for C, C++, and FORTRAN           |\n| [PurifyPlus](https://www.teamblue.unicomsi.com/products/purifyplus/)                                               | Run‑time analysis tools for application reliability and performance                |\n| [REUSE](https://reuse.software/)                                                                                   | Verifies compliance with the REUSE software licensing guidelines                   |\n| [Semgrep](https://semgrep.dev/)                                                                                    | A fast, open-source, static analysis engine for many languages                     |\n| [ShellCheck](https://www.shellcheck.net/)                                                                          | A static analysis tool for Unix shell scripts                                      |\n| [Smatch](https://repo.or.cz/w/smatch.git)                                                                          | Smatch (Source Matcher) is a static analysis tool for C code                       |\n| [SoftIntegration Ch](https://www.softintegration.com/)                                                             | C/C++ interpreter and interactive platform for scientific computing                |\n| [Valgrind](https://valgrind.org/)                                                                                  | Tools for memory debugging, memory leak detection, and profiling                   |\n| [Visual\u0026nbsp;Studio\u0026nbsp;Code\u0026nbsp;Analyzer](https://learn.microsoft.com/en-us/cpp/code-quality/)                  | Tools to analyze and improve C/C++ source code quality                             |\n\n## Code statistics\n\nCode statistics 📈 generated by [`scc`](https://github.com/boyter/scc):\n\n\u003c!-- scc-start --\u003e\n\u003ctable id=\"scc-table\"\u003e\n        \u003cthead\u003e\u003ctr\u003e\n                \u003cth\u003eLanguage\u003c/th\u003e\n                \u003cth\u003eFiles\u003c/th\u003e\n                \u003cth\u003eLines\u003c/th\u003e\n                \u003cth\u003eBlank\u003c/th\u003e\n                \u003cth\u003eComment\u003c/th\u003e\n                \u003cth\u003eCode\u003c/th\u003e\n                \u003cth\u003eComplexity\u003c/th\u003e\n                \u003cth\u003eBytes\u003c/th\u003e\n                \u003cth\u003eUloc\u003c/th\u003e\n        \u003c/tr\u003e\u003c/thead\u003e\n        \u003ctbody\u003e\u003ctr\u003e\n                \u003cth\u003eC\u003c/th\u003e\n                \u003cth\u003e5\u003c/th\u003e\n                \u003cth\u003e8938\u003c/th\u003e\n                \u003cth\u003e1881\u003c/th\u003e\n                \u003cth\u003e720\u003c/th\u003e\n                \u003cth\u003e6337\u003c/th\u003e\n                \u003cth\u003e1362\u003c/th\u003e\n                \u003cth\u003e203531\u003c/th\u003e\n                \u003cth\u003e3558\u003c/th\u003e\n        \u003c/tr\u003e\u003ctr\u003e\n                \u003cth\u003eShell\u003c/th\u003e\n                \u003cth\u003e8\u003c/th\u003e\n                \u003cth\u003e4017\u003c/th\u003e\n                \u003cth\u003e581\u003c/th\u003e\n                \u003cth\u003e594\u003c/th\u003e\n                \u003cth\u003e2842\u003c/th\u003e\n                \u003cth\u003e497\u003c/th\u003e\n                \u003cth\u003e116467\u003c/th\u003e\n                \u003cth\u003e1414\u003c/th\u003e\n        \u003c/tr\u003e\u003ctr\u003e\n                \u003cth\u003ePython\u003c/th\u003e\n                \u003cth\u003e2\u003c/th\u003e\n                \u003cth\u003e1307\u003c/th\u003e\n                \u003cth\u003e110\u003c/th\u003e\n                \u003cth\u003e232\u003c/th\u003e\n                \u003cth\u003e965\u003c/th\u003e\n                \u003cth\u003e342\u003c/th\u003e\n                \u003cth\u003e51970\u003c/th\u003e\n                \u003cth\u003e920\u003c/th\u003e\n        \u003c/tr\u003e\u003ctr\u003e\n                \u003cth\u003eMakefile\u003c/th\u003e\n                \u003cth\u003e3\u003c/th\u003e\n                \u003cth\u003e1143\u003c/th\u003e\n                \u003cth\u003e187\u003c/th\u003e\n                \u003cth\u003e234\u003c/th\u003e\n                \u003cth\u003e722\u003c/th\u003e\n                \u003cth\u003e214\u003c/th\u003e\n                \u003cth\u003e40929\u003c/th\u003e\n                \u003cth\u003e647\u003c/th\u003e\n        \u003c/tr\u003e\u003ctr\u003e\n                \u003cth\u003eAssembly\u003c/th\u003e\n                \u003cth\u003e8\u003c/th\u003e\n                \u003cth\u003e1052\u003c/th\u003e\n                \u003cth\u003e87\u003c/th\u003e\n                \u003cth\u003e280\u003c/th\u003e\n                \u003cth\u003e685\u003c/th\u003e\n                \u003cth\u003e0\u003c/th\u003e\n                \u003cth\u003e42866\u003c/th\u003e\n                \u003cth\u003e608\u003c/th\u003e\n        \u003c/tr\u003e\u003ctr\u003e\n                \u003cth\u003ePatch\u003c/th\u003e\n                \u003cth\u003e1\u003c/th\u003e\n                \u003cth\u003e212\u003c/th\u003e\n                \u003cth\u003e8\u003c/th\u003e\n                \u003cth\u003e0\u003c/th\u003e\n                \u003cth\u003e204\u003c/th\u003e\n                \u003cth\u003e0\u003c/th\u003e\n                \u003cth\u003e6070\u003c/th\u003e\n                \u003cth\u003e174\u003c/th\u003e\n        \u003c/tr\u003e\u003ctr\u003e\n                \u003cth\u003eC Header\u003c/th\u003e\n                \u003cth\u003e1\u003c/th\u003e\n                \u003cth\u003e72\u003c/th\u003e\n                \u003cth\u003e15\u003c/th\u003e\n                \u003cth\u003e27\u003c/th\u003e\n                \u003cth\u003e30\u003c/th\u003e\n                \u003cth\u003e1\u003c/th\u003e\n                \u003cth\u003e1869\u003c/th\u003e\n                \u003cth\u003e39\u003c/th\u003e\n        \u003c/tr\u003e\u003ctr\u003e\n                \u003cth\u003eMessages\u003c/th\u003e\n                \u003cth\u003e1\u003c/th\u003e\n                \u003cth\u003e67\u003c/th\u003e\n                \u003cth\u003e0\u003c/th\u003e\n                \u003cth\u003e0\u003c/th\u003e\n                \u003cth\u003e67\u003c/th\u003e\n                \u003cth\u003e0\u003c/th\u003e\n                \u003cth\u003e6229\u003c/th\u003e\n                \u003cth\u003e67\u003c/th\u003e\n        \u003c/tr\u003e\u003ctr\u003e\n                \u003cth\u003eBatch\u003c/th\u003e\n                \u003cth\u003e1\u003c/th\u003e\n                \u003cth\u003e33\u003c/th\u003e\n                \u003cth\u003e7\u003c/th\u003e\n                \u003cth\u003e17\u003c/th\u003e\n                \u003cth\u003e9\u003c/th\u003e\n                \u003cth\u003e0\u003c/th\u003e\n                \u003cth\u003e994\u003c/th\u003e\n                \u003cth\u003e27\u003c/th\u003e\n        \u003c/tr\u003e\u003c/tbody\u003e\n        \u003ctfoot\u003e\u003ctr\u003e\n                \u003cth\u003eTotal\u003c/th\u003e\n                \u003cth\u003e30\u003c/th\u003e\n                \u003cth\u003e16841\u003c/th\u003e\n                \u003cth\u003e2876\u003c/th\u003e\n                \u003cth\u003e2104\u003c/th\u003e\n                \u003cth\u003e11861\u003c/th\u003e\n                \u003cth\u003e2416\u003c/th\u003e\n                \u003cth\u003e470925\u003c/th\u003e\n                \u003cth\u003e7400\u003c/th\u003e\n        \u003c/tr\u003e\u003c/tfoot\u003e\u003c/table\u003e\n\u003c!-- scc-end --\u003e\n\n## License\n\nThis software is distributed under the terms of the permissive\n[**MIT\u0026nbsp;No\u0026nbsp;Attribution\u0026nbsp;(MIT‑0) License**](LICENSE).\n\n\u003c!--\nLocal Variables:\nmode: markdown\nindent-tabs-mode: nil\nfill-column: 80\neval: (setq-local display-fill-column-indicator-column 80)\neval: (display-fill-column-indicator-mode 1)\nEnd:\n--\u003e\n\n\u003c!-- vim: set ft=markdown expandtab cc=80 : --\u003e\n\u003c!-- EOF --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnsonjh%2Flzpack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjohnsonjh%2Flzpack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnsonjh%2Flzpack/lists"}