#!/usr/bin/env python3 """Deterministic repack of a jar, replicating stripJavaArchivesHook for the penpot backend uberjar. Nix's stripJavaArchivesHook runs strip-nondeterminism, which drives the perl Archive::Zip module. Two problems made it unusable here: * its per-member removeMember/addMember reorder loop is O(n^2) in the entry count (linear member search + full array rebuild per entry), so the 54000-entry, 109 MB penpot jar spent ~32 minutes there; * Archive::Zip derives the DOS timestamps with localtime, so the result depended on the build machine's timezone. This script reproduces the same semantics (jar.pm + zip.pm handlers) with the stdlib zipfile module: read each entry once, sort the entry list, write it in a single pass. The result is byte-identical across runs and timezones, and costs seconds instead of minutes. Semantics replicated from strip-nondeterminism: * entry order: META-INF/ first, then META-INF/MANIFEST.MF, then lexicographic * canonical time: Archive::Zip SAFE_EPOCH (1980-01-01 12:01:00 local), used here as a fixed UTC tuple so the output never depends on $TZ * .clj entries are stamped 2 DOS seconds (1 unix second) earlier, so that Clojure never mistakes a .clj for a stale .class * META-INF/MANIFEST.MF: drop Bnd-LastModified:/Built-By: lines * .html with a `