{"version":3,"sources":["../src/types.ts","../src/canonical.ts"],"names":["r"],"mappings":";;;;;AAkBO,IAAM,qBAAA,GAAwD,OAAO,MAAA,CAAO;AAAA,EAC/E,aAAA;AAAA,EACA,oBAAA;AAAA,EACA,oBAAA;AAAA,EACA,iBAAA;AAAA,EACA,eAAA;AAAA,EACA,YAAA;AAAA,EACA;AACJ,CAAC,CAAA;;;AC2BD,IAAM,aAAA,GAAgB,cAAA;AACtB,IAAM,cAAA,GAAiB,sBAAA;AACvB,IAAM,kBAAA,GAAqB,0BAAA;AAEpB,SAAS,uBAAuB,KAAA,EAAqC;AACxE,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,KAAA,CAAM,KAAK,aAAa,CAAA;AACxB,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,SAAA,EAAY,KAAA,CAAM,OAAO,CAAA,CAAE,CAAA;AACtC,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,aAAA,EAAgB,KAAA,CAAM,WAAW,CAAA,CAAE,CAAA;AAC9C,EAAA,KAAA,CAAM,KAAK,aAAa,CAAA;AACxB,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,aAAA,EAAgB,KAAA,CAAM,UAAA,CAAW,SAAS,CAAA,CAAE,CAAA;AACvD,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,SAAA,EAAY,KAAA,CAAM,UAAA,CAAW,KAAK,CAAA,CAAE,CAAA;AAC/C,EAAA,KAAA,CAAM,KAAK,cAAc,CAAA;AACzB,EAAA,KAAA,CAAM,KAAK,CAAA,EAAA,EAAK,cAAA,CAAe,KAAA,CAAM,WAAW,CAAC,CAAA,CAAE,CAAA;AACnD,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,YAAA,EAAe,KAAA,CAAM,UAAU,CAAA,CAAE,CAAA;AAC5C,EAAA,KAAA,CAAM,KAAK,OAAO,CAAA;AAClB,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,kBAAA,EAAqB,KAAA,CAAM,IAAA,CAAK,cAAc,CAAA,CAAE,CAAA;AAC3D,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,YAAA,EAAe,KAAA,CAAM,IAAA,CAAK,QAAQ,CAAA,CAAE,CAAA;AAC/C,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,YAAA,EAAe,KAAA,CAAM,IAAA,CAAK,QAAQ,CAAA,CAAE,CAAA;AAC/C,EAAA,KAAA,CAAM,IAAA,CAAK,iBAAiB,KAAA,CAAM,YAAA,KAAiB,OAAO,MAAA,GAAS,KAAA,CAAM,YAAY,CAAA,CAAE,CAAA;AACvF,EAAA,KAAA,CAAM,KAAK,UAAU,CAAA;AACrB,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,aAAA,EAAgB,KAAA,CAAM,OAAA,CAAQ,SAAA,KAAc,OAAO,MAAA,GAAS,KAAA,CAAM,OAAA,CAAQ,SAAS,CAAA,CAAE,CAAA;AAChG,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,UAAA,EAAa,KAAA,CAAM,OAAA,CAAQ,MAAA,KAAW,OAAO,MAAA,GAAS,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,CAAE,CAAA;AACvF,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,aAAA,EAAgB,KAAA,CAAM,WAAW,CAAA,CAAE,CAAA;AAC9C,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,UAAA,EAAa,KAAA,CAAM,QAAQ,CAAA,CAAE,CAAA;AACxC,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,OAAA,EAAU,KAAA,CAAM,KAAK,CAAA,CAAE,CAAA;AAClC,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AAC1B;AAEA,SAAS,eAAeA,EAAAA,EAA6B;AACjD,EAAA,IAAI,MAAA,IAAUA,EAAAA,EAAG,OAAO,CAAA,MAAA,EAASA,GAAE,IAAI,CAAA,CAAA;AACvC,EAAA,OAAO,CAAA,OAAA,EAAUA,GAAE,KAAK,CAAA,CAAA;AAC5B;AAEO,SAAS,4BAA4B,KAAA,EAAyC;AACjF,EAAA,OAAO,IAAI,WAAA,EAAY,CAAE,MAAA,CAAO,sBAAA,CAAuB,KAAK,CAAC,CAAA;AACjE;AAEO,SAAS,gBAAgB,KAAA,EAAqC;AACjE,EAAA,OAAO,SAAA,CAAU,MAAA,CAAO,2BAAA,CAA4B,KAAK,CAAC,CAAC,CAAA;AAC/D;AAkBO,SAAS,wBAAwB,KAAA,EAAsC;AAC1E,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,KAAA,CAAM,KAAK,cAAc,CAAA;AACzB,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,WAAA,EAAc,KAAA,CAAM,SAAS,CAAA,CAAE,CAAA;AAC1C,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,SAAA,EAAY,KAAA,CAAM,OAAO,CAAA,CAAE,CAAA;AACtC,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,aAAA,EAAgB,KAAA,CAAM,WAAW,CAAA,CAAE,CAAA;AAC9C,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,aAAA,EAAgB,KAAA,CAAM,WAAW,CAAA,CAAE,CAAA;AAC9C,EAAA,KAAA,CAAM,KAAK,WAAW,CAAA;AACtB,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,aAAA,EAAgB,KAAA,CAAM,QAAA,CAAS,SAAS,CAAA,CAAE,CAAA;AACrD,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,UAAA,EAAa,KAAA,CAAM,QAAA,CAAS,MAAM,CAAA,CAAE,CAAA;AAC/C,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,WAAA,EAAc,KAAA,CAAM,QAAA,CAAS,OAAO,CAAA,CAAE,CAAA;AACjD,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,wBAAA,EAA2B,KAAA,CAAM,sBAAsB,CAAA,CAAE,CAAA;AACpE,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AAC1B;AAEO,SAAS,6BAA6B,KAAA,EAA0C;AACnF,EAAA,OAAO,IAAI,WAAA,EAAY,CAAE,MAAA,CAAO,uBAAA,CAAwB,KAAK,CAAC,CAAA;AAClE;AAEO,SAAS,iBAAiB,KAAA,EAAsC;AACnE,EAAA,OAAO,SAAA,CAAU,MAAA,CAAO,4BAAA,CAA6B,KAAK,CAAC,CAAC,CAAA;AAChE;AAYO,SAAS,4BAA4B,KAAA,EAA0C;AAClF,EAAA,OAAO;AAAA,IACH,kBAAA;AAAA,IACA,CAAA,WAAA,EAAc,MAAM,SAAS,CAAA,CAAA;AAAA,IAC7B,CAAA,cAAA,EAAiB,MAAM,YAAY,CAAA,CAAA;AAAA,IACnC,CAAA,QAAA,EAAW,MAAM,MAAM,CAAA;AAAA,GAC3B,CAAE,KAAK,IAAI,CAAA;AACf;AAEO,SAAS,iCACZ,KAAA,EACU;AACV,EAAA,OAAO,IAAI,WAAA,EAAY,CAAE,MAAA,CAAO,2BAAA,CAA4B,KAAK,CAAC,CAAA;AACtE;AAEO,SAAS,qBAAqB,KAAA,EAA0C;AAC3E,EAAA,OAAO,SAAA,CAAU,MAAA,CAAO,gCAAA,CAAiC,KAAK,CAAC,CAAC,CAAA;AACpE;AAcA,IAAM,cAAA,GAAiB,wCAAA;AACvB,IAAM,MAAA,GAAS,gBAAA;AACf,IAAM,MAAA,GAAS,gBAAA;AAIR,SAAS,oBAAoB,KAAA,EAA6C;AAC7E,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,IAAW,gBAAgB,IAAA,CAAK,KAAA,CAAM,OAAO,CAAA,EAAG;AACvD,IAAA,OAAO,EAAE,+DAA+D,CAAA;AAAA,EAC5E;AACA,EAAA,IAAI,KAAA,CAAM,YAAY,MAAA,KAAW,CAAA,IAAK,SAAS,IAAA,CAAK,KAAA,CAAM,WAAW,CAAA,EAAG;AACpE,IAAA,OAAO,EAAE,+DAA+D,CAAA;AAAA,EAC5E;AACA,EAAA,IAAI,IAAI,aAAY,CAAE,MAAA,CAAO,MAAM,WAAW,CAAA,CAAE,aAAa,GAAA,EAAK;AAC9D,IAAA,OAAO,EAAE,qCAAqC,CAAA;AAAA,EAClD;AACA,EAAA,IAAI,CAAC,qBAAA,CAAsB,QAAA,CAAS,KAAA,CAAM,UAAA,CAAW,SAAS,CAAA,EAAG;AAC7D,IAAA,OAAO,CAAA;AAAA,MACH,CAAA,sBAAA,EAAyB,KAAA,CAAM,UAAA,CAAW,SAAS,CAAA,gCAAA;AAAA,KACvD;AAAA,EACJ;AACA,EAAA,IAAI,KAAA,CAAM,UAAA,CAAW,KAAA,CAAM,MAAA,KAAW,CAAA,IAAK,SAAS,IAAA,CAAK,KAAA,CAAM,UAAA,CAAW,KAAK,CAAA,EAAG;AAC9E,IAAA,OAAO,EAAE,sDAAsD,CAAA;AAAA,EACnE;AACA,EAAA,IAAI,IAAI,aAAY,CAAE,MAAA,CAAO,MAAM,UAAA,CAAW,KAAK,CAAA,CAAE,UAAA,GAAa,IAAA,EAAM;AACpE,IAAA,OAAO,EAAE,2CAA2C,CAAA;AAAA,EACxD;AACA,EAAA,IAAI,MAAA,IAAU,MAAM,WAAA,EAAa;AAC7B,IAAA,IAAI,CAAC,cAAA,CAAe,IAAA,CAAK,KAAA,CAAM,WAAA,CAAY,IAAI,CAAA,EAAG;AAC9C,MAAA,OAAO,EAAE,2EAA2E,CAAA;AAAA,IACxF;AAAA,EACJ,CAAA,MAAA,IAAW,OAAA,IAAW,KAAA,CAAM,WAAA,EAAa;AACrC,IAAA,IAAI,CAAC,MAAA,CAAO,SAAA,CAAU,KAAA,CAAM,WAAA,CAAY,KAAK,CAAA,IAAK,KAAA,CAAM,WAAA,CAAY,KAAA,GAAQ,CAAA,EAAG;AAC3E,MAAA,OAAO,EAAE,kDAAkD,CAAA;AAAA,IAC/D;AAAA,EACJ,CAAA,MAAO;AACH,IAAA,OAAO,EAAE,2DAA2D,CAAA;AAAA,EACxE;AACA,EAAA,IAAI,CAAC,cAAA,CAAe,IAAA,CAAK,KAAA,CAAM,UAAU,CAAA,EAAG;AACxC,IAAA,OAAO,EAAE,qEAAqE,CAAA;AAAA,EAClF;AACA,EAAA,IAAI,CAAC,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,cAAc,CAAA,EAAG;AACzC,IAAA,OAAO,EAAE,oDAAoD,CAAA;AAAA,EACjE;AACA,EAAA,IAAI,CAAC,MAAA,CAAO,SAAA,CAAU,KAAA,CAAM,IAAA,CAAK,QAAQ,CAAA,IAAK,KAAA,CAAM,IAAA,CAAK,QAAA,GAAW,CAAA,EAAG;AACnE,IAAA,OAAO,EAAE,8CAA8C,CAAA;AAAA,EAC3D;AACA,EAAA,IAAI,CAAC,MAAA,CAAO,SAAA,CAAU,KAAA,CAAM,IAAA,CAAK,QAAQ,CAAA,IAAK,KAAA,CAAM,IAAA,CAAK,QAAA,GAAW,CAAA,EAAG;AACnE,IAAA,OAAO,EAAE,8CAA8C,CAAA;AAAA,EAC3D;AACA,EAAA,IAAI,MAAM,YAAA,KAAiB,IAAA,IAAQ,gBAAgB,IAAA,CAAK,KAAA,CAAM,YAAY,CAAA,EAAG;AACzE,IAAA,OAAO,EAAE,gDAAgD,CAAA;AAAA,EAC7D;AACA,EAAA,IAAI,MAAM,UAAA,CAAW,SAAA,KAAc,oBAAA,IAAwB,KAAA,CAAM,iBAAiB,IAAA,EAAM;AACpF,IAAA,OAAO,EAAE,+EAA+E,CAAA;AAAA,EAC5F;AACA,EAAA,IACI,KAAA,CAAM,OAAA,CAAQ,SAAA,KAAc,IAAA,IAC5B,KAAA,CAAM,OAAA,CAAQ,SAAA,KAAc,eAAA,IAC5B,KAAA,CAAM,OAAA,CAAQ,SAAA,KAAc,cAAA,EAC9B;AACE,IAAA,OAAO,EAAE,oEAAoE,CAAA;AAAA,EACjF;AACA,EAAA,IAAI,KAAA,CAAM,QAAQ,MAAA,KAAW,IAAA,IAAQ,SAAS,IAAA,CAAK,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,EAAG;AACtE,IAAA,OAAO,EAAE,8CAA8C,CAAA;AAAA,EAC3D;AACA,EAAA,IAAI,KAAA,CAAM,gBAAgB,iBAAA,EAAmB;AACzC,IAAA,OAAO,EAAE,kDAAkD,CAAA;AAAA,EAC/D;AACA,EAAA,IAAI,CAAC,cAAA,CAAe,IAAA,CAAK,KAAA,CAAM,QAAQ,CAAA,EAAG;AACtC,IAAA,OAAO,EAAE,mEAAmE,CAAA;AAAA,EAChF;AAEA,EAAA,IAAI,KAAA,CAAM,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG;AAC1B,IAAA,OAAO,EAAE,+DAA4D,CAAA;AAAA,EACzE;AACA,EAAA,IAAI,CAAC,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA,EAAG;AAC3B,IAAA,OAAO,EAAE,2CAA2C,CAAA;AAAA,EACxD;AACA,EAAA,OAAO,EAAE,IAAI,IAAA,EAAK;AACtB;AAEO,SAAS,qBAAqB,KAAA,EAA8C;AAC/E,EAAA,IAAI,CAAC,OAAO,IAAA,CAAK,KAAA,CAAM,SAAS,CAAA,EAAG,OAAO,EAAE,0CAA0C,CAAA;AACtF,EAAA,IAAI,CAAC,CAAC,MAAA,EAAQ,QAAA,EAAU,oBAAA,EAAsB,UAAU,CAAA,CAAE,QAAA,CAAS,KAAA,CAAM,OAAO,CAAA,EAAG;AAC/E,IAAA,OAAO,EAAE,oEAAoE,CAAA;AAAA,EACjF;AACA,EAAA,IAAI,CAAC,cAAA,CAAe,IAAA,CAAK,KAAA,CAAM,WAAW,CAAA,EAAG;AACzC,IAAA,OAAO,EAAE,8CAA8C,CAAA;AAAA,EAC3D;AACA,EAAA,IACI,KAAA,CAAM,WAAA,KAAgB,eAAA,KACrB,CAAC,KAAA,CAAM,eAAe,eAAA,CAAgB,IAAA,CAAK,KAAA,CAAM,WAAW,CAAA,CAAA,EAC/D;AACE,IAAA,OAAO,EAAE,0DAA0D,CAAA;AAAA,EACvE;AACA,EAAA,IAAI,CAAC,qBAAA,CAAsB,QAAA,CAAS,KAAA,CAAM,QAAA,CAAS,SAAS,CAAA,EAAG;AAC3D,IAAA,OAAO,CAAA,CAAE,CAAA,oBAAA,EAAuB,KAAA,CAAM,QAAA,CAAS,SAAS,CAAA,gCAAA,CAA+B,CAAA;AAAA,EAC3F;AACA,EAAA,IAAI,KAAA,CAAM,QAAA,CAAS,MAAA,CAAO,MAAA,KAAW,CAAA,IAAK,SAAS,IAAA,CAAK,KAAA,CAAM,QAAA,CAAS,MAAM,CAAA,EAAG;AAC5E,IAAA,OAAO,EAAE,iDAAiD,CAAA;AAAA,EAC9D;AACA,EAAA,IAAI,KAAA,CAAM,QAAA,CAAS,OAAA,CAAQ,MAAA,KAAW,CAAA,IAAK,SAAS,IAAA,CAAK,KAAA,CAAM,QAAA,CAAS,OAAO,CAAA,EAAG;AAC9E,IAAA,OAAO,EAAE,kDAAkD,CAAA;AAAA,EAC/D;AACA,EAAA,IAAI,CAAC,cAAA,CAAe,IAAA,CAAK,KAAA,CAAM,sBAAsB,CAAA,EAAG;AACpD,IAAA,OAAO,EAAE,yDAAyD,CAAA;AAAA,EACtE;AACA,EAAA,OAAO,EAAE,IAAI,IAAA,EAAK;AACtB;AAEO,SAAS,yBACZ,KAAA,EACc;AACd,EAAA,IAAI,CAAC,OAAO,IAAA,CAAK,KAAA,CAAM,SAAS,CAAA,EAAG,OAAO,EAAE,0CAA0C,CAAA;AACtF,EAAA,IAAI,CAAC,cAAA,CAAe,IAAA,CAAK,KAAA,CAAM,YAAY,CAAA,EAAG;AAC1C,IAAA,OAAO,EAAE,+CAA+C,CAAA;AAAA,EAC5D;AACA,EAAA,IAAI,KAAA,CAAM,OAAO,MAAA,KAAW,CAAA,IAAK,SAAS,IAAA,CAAK,KAAA,CAAM,MAAM,CAAA,EAAG;AAC1D,IAAA,OAAO,EAAE,wCAAwC,CAAA;AAAA,EACrD;AACA,EAAA,IAAI,IAAI,aAAY,CAAE,MAAA,CAAO,MAAM,MAAM,CAAA,CAAE,aAAa,GAAA,EAAK;AACzD,IAAA,OAAO,EAAE,gCAAgC,CAAA;AAAA,EAC7C;AACA,EAAA,OAAO,EAAE,IAAI,IAAA,EAAK;AACtB;AAEA,SAAS,EAAE,MAAA,EAAgC;AACvC,EAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAO;AAC/B;AAkBO,SAAS,aAAa,KAAA,EAA0B;AACnD,EAAA,OAAO,OAAO,KAAK,CAAA;AACvB;AAEO,SAAS,2BAA2B,GAAA,EAA6B;AACpE,EAAA,OAAO,aAAa,GAA2B,CAAA;AACnD;AAEO,SAAS,4BAA4B,GAAA,EAA8B;AACtE,EAAA,OAAO,aAAa,GAA2B,CAAA;AACnD;AAEO,SAAS,gCAAgC,GAAA,EAAkC;AAC9E,EAAA,OAAO,aAAa,GAA2B,CAAA;AACnD;AAEA,SAAS,OAAO,CAAA,EAAsB;AAClC,EAAA,IAAI,CAAA,KAAM,MAAM,OAAO,MAAA;AACvB,EAAA,IAAI,OAAO,CAAA,KAAM,SAAA,EAAW,OAAO,IAAI,MAAA,GAAS,OAAA;AAChD,EAAA,IAAI,OAAO,CAAA,KAAM,QAAA,EAAU,OAAO,aAAa,CAAC,CAAA;AAChD,EAAA,IAAI,OAAO,CAAA,KAAM,QAAA,EAAU,OAAO,aAAa,CAAC,CAAA;AAChD,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,EAAG;AAClB,IAAA,MAAM,QAAkB,EAAC;AACzB,IAAA,KAAA,MAAW,QAAQ,CAAA,EAAG,KAAA,CAAM,IAAA,CAAK,MAAA,CAAO,IAAI,CAAC,CAAA;AAC7C,IAAA,OAAO,GAAA,GAAM,KAAA,CAAM,IAAA,CAAK,GAAG,CAAA,GAAI,GAAA;AAAA,EACnC;AACA,EAAA,IAAI,OAAO,MAAM,QAAA,EAAU;AACvB,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,IAAA,CAAK,CAAC,EAAE,IAAA,EAAK;AACjC,IAAA,MAAM,QAAkB,EAAC;AACzB,IAAA,KAAA,MAAW,KAAK,IAAA,EAAM;AAClB,MAAA,MAAM,KAAA,GAAQ,EAAE,CAAC,CAAA;AACjB,MAAA,IAAI,UAAU,MAAA,EAAW;AACzB,MAAA,KAAA,CAAM,KAAK,YAAA,CAAa,CAAC,IAAI,GAAA,GAAM,MAAA,CAAO,KAAkB,CAAC,CAAA;AAAA,IACjE;AACA,IAAA,OAAO,GAAA,GAAM,KAAA,CAAM,IAAA,CAAK,GAAG,CAAA,GAAI,GAAA;AAAA,EACnC;AACA,EAAA,MAAM,IAAI,KAAA,CAAM,oCAAA,GAAuC,OAAO,CAAC,CAAA;AACnE;AAEA,SAAS,aAAa,CAAA,EAAmB;AACrC,EAAA,IAAI,CAAC,OAAO,QAAA,CAAS,CAAC,GAAG,MAAM,IAAI,MAAM,4CAA4C,CAAA;AACrF,EAAA,IAAI,MAAA,CAAO,EAAA,CAAG,CAAA,EAAG,EAAE,GAAG,OAAO,GAAA;AAC7B,EAAA,IAAI,MAAA,CAAO,UAAU,CAAC,CAAA,IAAK,KAAK,GAAA,CAAI,CAAC,IAAI,IAAA,EAAM;AAC3C,IAAA,OAAO,OAAO,CAAC,CAAA;AAAA,EACnB;AACA,EAAA,OAAO,IAAA,CAAK,UAAU,CAAC,CAAA;AAC3B;AAEA,IAAM,YAAA,GAAuC;AAAA,EACzC,IAAA,EAAM,MAAA;AAAA,EACN,GAAA,EAAK,KAAA;AAAA,EACL,IAAA,EAAM,KAAA;AAAA,EACN,IAAA,EAAM,KAAA;AAAA,EACN,IAAA,EAAM,KAAA;AAAA,EACN,IAAA,EAAM,KAAA;AAAA,EACN,GAAA,EAAM;AACV,CAAA;AAEA,SAAS,aAAa,CAAA,EAAmB;AACrC,EAAA,IAAI,GAAA,GAAM,GAAA;AACV,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,CAAE,QAAQ,CAAA,EAAA,EAAK;AAC/B,IAAA,MAAM,EAAA,GAAK,EAAE,CAAC,CAAA;AACd,IAAA,MAAM,IAAA,GAAO,EAAA,CAAG,UAAA,CAAW,CAAC,CAAA;AAC5B,IAAA,IAAI,YAAA,CAAa,EAAE,CAAA,EAAG;AAClB,MAAA,GAAA,IAAO,aAAa,EAAE,CAAA;AAAA,IAC1B,CAAA,MAAA,IAAW,OAAO,EAAA,EAAM;AACpB,MAAA,GAAA,IAAO,QAAQ,IAAA,CAAK,QAAA,CAAS,EAAE,CAAA,CAAE,QAAA,CAAS,GAAG,GAAG,CAAA;AAAA,IACpD,CAAA,MAAO;AACH,MAAA,GAAA,IAAO,EAAA;AAAA,IACX;AAAA,EACJ;AACA,EAAA,GAAA,IAAO,GAAA;AACP,EAAA,OAAO,GAAA;AACX;AAMA,IAAM,SAAA,GAAY,kBAAA;AAEX,SAAS,UAAU,KAAA,EAA2B;AACjD,EAAA,IAAI,GAAA,GAAM,EAAA;AACV,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACnC,IAAA,MAAM,CAAA,GAAI,MAAM,CAAC,CAAA;AACjB,IAAA,GAAA,IAAO,UAAW,CAAA,IAAK,CAAA,GAAK,EAAI,CAAA,GAAK,SAAA,CAAU,IAAI,EAAI,CAAA;AAAA,EAC3D;AACA,EAAA,OAAO,GAAA;AACX;AAEO,SAAS,UAAU,KAAA,EAA2B;AACjD,EAAA,OAAO,SAAA,CAAU,MAAA,CAAO,KAAK,CAAC,CAAA;AAClC;AAQO,SAAS,aAAA,GAAwB;AACpC,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,EAAE,CAAA;AAC/B,EAAA,MAAM,IAAK,UAAA,CAAmC,MAAA;AAC9C,EAAA,IAAI,CAAC,CAAA,IAAK,OAAO,CAAA,CAAE,oBAAoB,UAAA,EAAY;AAC/C,IAAA,MAAM,IAAI,MAAM,6DAA6D,CAAA;AAAA,EACjF;AACA,EAAA,CAAA,CAAE,gBAAgB,KAAK,CAAA;AACvB,EAAA,OAAO,UAAU,KAAK,CAAA;AAC1B","file":"canonical.mjs","sourcesContent":["// Wire types for OC Pledge v0.1 envelopes. SPEC.md §3, §4, §5.\n\nexport const ENVELOPE_VERSION = 1 as const;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Resolution mechanism — the closed set of seven, plus refusal of self_proof.\n// SPEC §3.4.\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type ResolutionMechanism =\n    | 'chain_state'\n    | 'counterparty_signs'\n    | 'nostr_event_exists'\n    | 'stamp_published'\n    | 'http_get_hash'\n    | 'dns_record'\n    | 'vote_resolves';\n\nexport const RESOLUTION_MECHANISMS: readonly ResolutionMechanism[] = Object.freeze([\n    'chain_state',\n    'counterparty_signs',\n    'nostr_event_exists',\n    'stamp_published',\n    'http_get_hash',\n    'dns_record',\n    'vote_resolves',\n]);\n\nexport type DisputeMechanism = 'vote_resolves' | 'named_oracle';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Pledge envelope (SPEC §3.3)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface PledgeResolution {\n    mechanism: ResolutionMechanism;\n    /** Single-line query string in the named mechanism's grammar (≤ 1024 UTF-8 bytes). */\n    query: string;\n}\n\n/** `resolves_at` is exactly one of `time` or `block`. SPEC §3.1. */\nexport type PledgeResolvesAt = { time: string } | { block: number };\n\nexport interface PledgeBond {\n    /** SHA-256 hex of an OrangeCheck attestation canonical message. */\n    attestation_id: string;\n    /** Non-negative integer. */\n    min_sats: number;\n    /** Non-negative integer. */\n    min_days: number;\n}\n\nexport interface PledgeDispute {\n    mechanism: DisputeMechanism | null;\n    /** Single-line params string in the named dispute mechanism's grammar, or null. */\n    params: string | null;\n}\n\nexport interface PledgeSwearer {\n    address: string;\n    alg: 'bip322';\n}\n\nexport interface PledgeSignature {\n    alg: 'bip322';\n    /**\n     * MUST equal swearer.address when via_delegation is absent;\n     * MUST equal agent_address when via_delegation is present.\n     */\n    pubkey: string;\n    /** base64 BIP-322 signature over the lowercase-hex pledge id. */\n    value: string;\n}\n\nexport interface PledgeEnvelope {\n    v: typeof ENVELOPE_VERSION;\n    kind: 'pledge';\n    /** 64-hex of sha256(canonical_message). */\n    id: string;\n\n    swearer: PledgeSwearer;\n    proposition: string;\n    resolution: PledgeResolution;\n    resolves_at: PledgeResolvesAt;\n    expires_at: string;\n    bond: PledgeBond;\n    counterparty: string | null;\n    dispute: PledgeDispute;\n    /** Fixed at \"breach_recorded\" in v0.1. */\n    remediation: 'breach_recorded';\n    sworn_at: string;\n    /** 32 lowercase hex chars (16 random bytes). MUST be non-empty. */\n    nonce: string;\n\n    /** Optional — present iff the pledge was signed by an agent under OC Agent delegation. */\n    via_delegation?: string;\n    /** Optional — Bitcoin address of the agent. Required iff via_delegation is present. */\n    agent_address?: string;\n\n    sig: PledgeSignature;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Outcome envelope (SPEC §4.2)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type OutcomeKind = 'kept' | 'broken' | 'expired_unresolved' | 'disputed';\n\nexport interface OutcomeEvidence {\n    /** Same mechanism string as the referenced pledge's resolution.mechanism. */\n    mechanism: ResolutionMechanism;\n    /** Single-line canonical result string. */\n    result: string;\n    /** Single-line canonical witness string (mechanism-specific shape — see SPEC §4.1). */\n    witness: string;\n}\n\nexport interface OutcomeSignature {\n    alg: 'bip322';\n    /** Equals the resolved_by address. */\n    pubkey: string;\n    /** base64 BIP-322 over the lowercase-hex outcome id. */\n    value: string;\n}\n\nexport interface OutcomeEnvelope {\n    v: typeof ENVELOPE_VERSION;\n    kind: 'pledge-outcome';\n    /** 64-hex of sha256(canonical_message). */\n    id: string;\n\n    pledge_id: string;\n    outcome: OutcomeKind;\n    resolved_at: string;\n    /**\n     * Either a Bitcoin address (when the resolver is a real party — i.e.\n     * counterparty_signs) or the literal string \"deterministic\" for any of\n     * the deterministic mechanisms.\n     */\n    resolved_by: string;\n\n    evidence: OutcomeEvidence;\n    dispute_window_ends_at: string;\n\n    /**\n     * null for deterministic mechanisms (resolved_by === \"deterministic\");\n     * required for counterparty_signs (resolved_by === counterparty.address).\n     */\n    sig: OutcomeSignature | null;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Abandonment envelope (SPEC §5.2)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface AbandonmentSignature {\n    alg: 'bip322';\n    /** MUST equal the original pledge's swearer.address. Agents MUST NOT sign abandonments in v0.1. */\n    pubkey: string;\n    /** base64 BIP-322 over the lowercase-hex abandonment id. */\n    value: string;\n}\n\nexport interface AbandonmentEnvelope {\n    v: typeof ENVELOPE_VERSION;\n    kind: 'pledge-abandonment';\n    /** 64-hex of sha256(canonical_message). */\n    id: string;\n\n    pledge_id: string;\n    abandoned_at: string;\n    /** Single-line UTF-8 string, ≤ 280 bytes. Informational only. */\n    reason: string;\n\n    sig: AbandonmentSignature;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Canonical-message inputs — exact field set covered by the BIP-322 signature.\n// `via_delegation` and `agent_address` are NOT in the canonical message\n// (SPEC §3.1) — they're envelope-only claims the verifier reconciles via the\n// OC Agent delegation registry.\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface PledgeCanonicalInput {\n    swearer: string;\n    proposition: string;\n    resolution: PledgeResolution;\n    resolves_at: PledgeResolvesAt;\n    expires_at: string;\n    bond: PledgeBond;\n    counterparty: string | null;\n    dispute: PledgeDispute;\n    remediation: 'breach_recorded';\n    sworn_at: string;\n    nonce: string;\n}\n\nexport interface OutcomeCanonicalInput {\n    pledge_id: string;\n    outcome: OutcomeKind;\n    resolved_at: string;\n    resolved_by: string;\n    evidence: OutcomeEvidence;\n    dispute_window_ends_at: string;\n}\n\nexport interface AbandonmentCanonicalInput {\n    pledge_id: string;\n    abandoned_at: string;\n    reason: string;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Create-side inputs — what callers pass to createPledge / createOutcome /\n// createAbandonment. The SDK fills sig.value from the supplied signer adapter\n// and computes the id.\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * A signer adapter — the caller wires their wallet of choice. Returns a\n * base64 BIP-322 signature over the UTF-8 bytes of the supplied message.\n * `address` is the Bitcoin address the wallet signs for.\n */\nexport interface Bip322Signer {\n    address: string;\n    signMessage: (msg: string) => Promise<string>;\n}\n\nexport interface CreatePledgeInput extends Omit<PledgeCanonicalInput, 'sworn_at' | 'nonce' | 'remediation'> {\n    /** Defaults to \"now\" (truncated to seconds, ISO 8601 UTC, Z-terminated). */\n    swornAt?: Date | string;\n    /**\n     * 32 lowercase hex chars (16 random bytes). If omitted, a fresh random\n     * nonce is generated via crypto.getRandomValues. Pass an explicit value\n     * for test-vector reproduction.\n     */\n    nonce?: string;\n    /** Defaults to \"breach_recorded\" (the only legal value in v0.1). */\n    remediation?: 'breach_recorded';\n    swearerSigner: Bip322Signer;\n    /**\n     * If present, pledge is signed by this agent under an OC Agent delegation.\n     * `via_delegation` (the delegation id) and `agent_address` (the agent's\n     * address) appear in the envelope but are NOT in the canonical message.\n     */\n    viaDelegation?: { delegation_id: string; agent_signer: Bip322Signer };\n}\n\nexport interface CreateOutcomeInput extends OutcomeCanonicalInput {\n    /**\n     * Required when resolved_by !== \"deterministic\" (i.e. counterparty_signs).\n     * For deterministic mechanisms, omit and the SDK leaves sig = null.\n     */\n    signer?: Bip322Signer;\n}\n\nexport interface CreateAbandonmentInput extends AbandonmentCanonicalInput {\n    swearerSigner: Bip322Signer;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Verify-side inputs and results.\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Caller-supplied BIP-322 verifier. Returns true iff the signature verifies\n * under the named address over the UTF-8 bytes of `msg`.\n */\nexport type VerifyBip322 = (\n    msg: string,\n    signatureB64: string,\n    address: string,\n) => Promise<boolean>;\n\nexport interface VerifyPledgeInput {\n    envelope: PledgeEnvelope;\n    /** Optional — omit to skip BIP-322 verification (e.g. for test vectors with placeholder sigs). */\n    verifyBip322?: VerifyBip322;\n    /** Default false. Set true to bypass BIP-322 entirely. */\n    skipSignatureVerification?: boolean;\n    /**\n     * Optional — when present AND envelope.via_delegation is set, verifyPledge\n     * runs SPEC §7.3 steps 1–5: resolve the delegation, confirm\n     * principal == swearer, agent == agent_address, expires_at > sworn_at,\n     * and that scopes contain a `pledge:create(...)` whose constraints fit\n     * the pledge's bond / mechanism / counterparty.\n     *\n     * Without this hook, agent-delegated pledges still verify at the\n     * envelope-shape + BIP-322 layer (§7.3 step 6), but the §7.3 1–5 chain\n     * is skipped. Surface a delegationLookup adapter (e.g. one that uses\n     * `@orangecheck/agent-core`'s `verifyDelegation`) for full scope\n     * enforcement.\n     */\n    delegationLookup?: DelegationLookup;\n}\n\n/**\n * Caller-supplied delegation resolver. Returns the resolved delegation\n * fields (principal, agent, scope strings, expires_at) or null if the\n * delegation cannot be resolved or its signature does not verify.\n *\n * The adapter is responsible for fetching the delegation envelope from\n * wherever it lives (typically Nostr kind 30083 with d-tag\n * `oc-agent-del:<delegation_id>`) and running OC Agent's full\n * verifyDelegation check before returning the typed shape. pledge-core\n * trusts the adapter's output for the §7.3 1–5 logic.\n */\nexport type DelegationLookup = (\n    delegationId: string,\n    nowIso: string,\n) => Promise<DelegationLookupResult | null>;\n\nexport interface DelegationLookupResult {\n    /** delegation.principal_address */\n    principal: string;\n    /** delegation.agent_address */\n    agent: string;\n    /**\n     * Raw scope strings as registered in the delegation (e.g.\n     * `[\"pledge:create(max_bond_sats=2000000)\", \"stamp:sign(mime=*)\"]`).\n     * pledge-core scans for an entry whose product:verb is `pledge:create`.\n     */\n    scopes: string[];\n    /** delegation.expires_at, ISO 8601 UTC. */\n    expires_at: string;\n}\n\nexport interface VerifyOutcomeInput {\n    envelope: OutcomeEnvelope;\n    /**\n     * Required when the outcome envelope's mechanism requires a signature\n     * (counterparty_signs). For deterministic outcomes, sig === null and\n     * BIP-322 is not consulted.\n     */\n    verifyBip322?: VerifyBip322;\n    skipSignatureVerification?: boolean;\n}\n\nexport interface VerifyAbandonmentInput {\n    envelope: AbandonmentEnvelope;\n    verifyBip322?: VerifyBip322;\n    skipSignatureVerification?: boolean;\n}\n\nexport type PledgeErrorCode =\n    | 'E_UNSUPPORTED_VERSION'\n    | 'E_PLEDGE_MALFORMED'\n    | 'E_PLEDGE_BAD_ID'\n    | 'E_PLEDGE_BAD_SIG'\n    | 'E_RESOLUTION_UNKNOWN'\n    | 'E_RESOLUTION_NONDETERMINISTIC'\n    | 'E_BOND_NOT_FOUND'\n    | 'E_BOND_ADDRESS_MISMATCH'\n    | 'E_BOND_SPENT'\n    | 'E_BOND_INSUFFICIENT_SATS'\n    | 'E_BOND_INSUFFICIENT_DAYS'\n    | 'E_OUTCOME_MALFORMED'\n    | 'E_OUTCOME_BAD_ID'\n    | 'E_OUTCOME_BAD_SIG'\n    | 'E_OUTCOME_EVIDENCE_MISMATCH'\n    | 'E_OUTCOME_RESOLVER_UNAUTHORIZED'\n    | 'E_ABANDONMENT_MALFORMED'\n    | 'E_ABANDONMENT_BAD_ID'\n    | 'E_ABANDONMENT_BAD_SIG'\n    | 'E_DELEGATION_NOT_FOUND'\n    | 'E_DELEGATION_SCOPE_VIOLATED'\n    | 'E_DELEGATION_EXPIRED';\n\nexport interface VerifyPledgeOk {\n    ok: true;\n    envelope: PledgeEnvelope;\n    canonicalMessage: string;\n    id: string;\n}\n\nexport interface VerifyOutcomeOk {\n    ok: true;\n    envelope: OutcomeEnvelope;\n    canonicalMessage: string;\n    id: string;\n}\n\nexport interface VerifyAbandonmentOk {\n    ok: true;\n    envelope: AbandonmentEnvelope;\n    canonicalMessage: string;\n    id: string;\n}\n\nexport interface VerifyErr {\n    ok: false;\n    code: PledgeErrorCode;\n    message: string;\n}\n\nexport type VerifyPledgeResult = VerifyPledgeOk | VerifyErr;\nexport type VerifyOutcomeResult = VerifyOutcomeOk | VerifyErr;\nexport type VerifyAbandonmentResult = VerifyAbandonmentOk | VerifyErr;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// State machine (SPEC §4.4)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type PledgeState =\n    | 'pending'\n    | 'resolvable'\n    | 'kept'\n    | 'broken'\n    | 'disputed'\n    | 'expired_unresolved';\n\nexport interface ClassifyStateInput {\n    pledge: PledgeEnvelope;\n    outcome: OutcomeEnvelope | null;\n    abandonment: AbandonmentEnvelope | null;\n    /** ISO 8601 UTC. */\n    now: string;\n    /**\n     * Optional — block-height resolutions need a wall-clock timestamp for the\n     * resolves_at.block. If the block isn't yet mined or no chain state is\n     * supplied, the SDK treats resolves_at as +infinity.\n     */\n    chain?: {\n        /** Highest seen block height. */\n        tip_height: number;\n        /** Wall-clock ISO 8601 UTC of `tip_height`. */\n        tip_time: string;\n        /** Optional override mapping a specific block to its mined-time. */\n        blockTimes?: Record<number, string>;\n    };\n    /**\n     * Optional list of additional outcome envelopes from authorized resolvers\n     * (e.g. swearer + counterparty in a bilateral pledge). Used to detect\n     * contradictory outcomes → `disputed`.\n     */\n    contradictoryOutcomes?: OutcomeEnvelope[];\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Bond verification (SPEC §8) — the SDK ships the algorithm; the chain\n// accessor is injected by the caller.\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface AttestationLookupResult {\n    /**\n     * Bitcoin address the attestation was signed by — the OrangeCheck\n     * attestation's canonical-message `address` field.\n     */\n    address: string;\n    /**\n     * Sats currently bonded by the named UTXOs at the verifier's clock.\n     * Computed by the caller's chain accessor.\n     */\n    sats_bonded: number;\n    /** Days the named UTXOs have been unspent at the verifier's clock. */\n    days_unspent: number;\n    /** True if the named UTXO has been spent at or before `now`. */\n    utxo_spent_at_or_before_now: boolean;\n}\n\n/**\n * Caller-supplied lookup that resolves an OrangeCheck attestation id against\n * live Bitcoin chain state. Returns null if the attestation can't be found.\n *\n * The SDK does not bundle a Bitcoin RPC client by design — the caller (CLI,\n * web, server) wires their accessor of choice (Esplora, mempool.space,\n * bitcoind RPC, oc-attest sdk).\n */\nexport type AttestationLookup = (\n    attestationId: string,\n    nowIso: string,\n) => Promise<AttestationLookupResult | null>;\n\nexport interface VerifyBondInput {\n    pledge: PledgeEnvelope;\n    /** ISO 8601 UTC. */\n    now: string;\n    lookup: AttestationLookup;\n}\n\nexport interface VerifyBondOk {\n    ok: true;\n    sats_bonded: number;\n    days_unspent: number;\n}\n\nexport interface VerifyBondErr {\n    ok: false;\n    code: Extract<\n        PledgeErrorCode,\n        'E_BOND_NOT_FOUND' | 'E_BOND_ADDRESS_MISMATCH' | 'E_BOND_SPENT' | 'E_BOND_INSUFFICIENT_SATS' | 'E_BOND_INSUFFICIENT_DAYS'\n    >;\n    message: string;\n}\n\nexport type VerifyBondResult = VerifyBondOk | VerifyBondErr;\n","// Canonical messages + RFC 8785 envelope canonicalization for OC Pledge.\n//\n// Three independent canonical-message builders (one per envelope kind) and a\n// single RFC 8785 JSON canonicalizer reused across all three envelope wires.\n//\n// The canonical-message builders are the load-bearing pieces of this SDK —\n// they MUST produce byte-identical output across implementations for identical\n// inputs (SPEC §11.8). Every committed test vector in oc-pledge-protocol/\n// test-vectors/ pins the exact bytes.\n\nimport { sha256 } from '@noble/hashes/sha256';\n\nimport type {\n    AbandonmentCanonicalInput,\n    AbandonmentEnvelope,\n    OutcomeCanonicalInput,\n    OutcomeEnvelope,\n    PledgeCanonicalInput,\n    PledgeEnvelope,\n    PledgeResolvesAt,\n} from './types.js';\nimport { RESOLUTION_MECHANISMS } from './types.js';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Pledge canonical message — SPEC §3.1\n//\n// Layout (LF-separated, no trailing LF):\n//   oc-pledge/v1\n//   swearer: <btc_address>\n//   proposition: <single line>\n//   resolution:\n//     mechanism: <one of the seven>\n//     query: <single line>\n//   resolves_at:\n//     time: <ISO> | block: <integer>\n//   expires_at: <ISO>\n//   bond:\n//     attestation_id: <64-hex>\n//     min_sats: <integer>\n//     min_days: <integer>\n//   counterparty: <btc_address | null>\n//   dispute:\n//     mechanism: <vote_resolves | named_oracle | null>\n//     params: <string | null>\n//   remediation: breach_recorded\n//   sworn_at: <ISO>\n//   nonce: <32-hex>\n//\n// Sub-blocks (resolution, resolves_at, bond, dispute) are introduced by a\n// label-only line (\"foo:\") followed by 2-space-indented sub-fields. The\n// `null` token is the literal four-character string, not a quoted string.\n// ─────────────────────────────────────────────────────────────────────────────\n\nconst PLEDGE_DOMAIN = 'oc-pledge/v1';\nconst OUTCOME_DOMAIN = 'oc-pledge-outcome/v1';\nconst ABANDONMENT_DOMAIN = 'oc-pledge-abandonment/v1';\n\nexport function canonicalPledgeMessage(input: PledgeCanonicalInput): string {\n    const lines: string[] = [];\n    lines.push(PLEDGE_DOMAIN);\n    lines.push(`swearer: ${input.swearer}`);\n    lines.push(`proposition: ${input.proposition}`);\n    lines.push('resolution:');\n    lines.push(`  mechanism: ${input.resolution.mechanism}`);\n    lines.push(`  query: ${input.resolution.query}`);\n    lines.push('resolves_at:');\n    lines.push(`  ${resolvesAtLine(input.resolves_at)}`);\n    lines.push(`expires_at: ${input.expires_at}`);\n    lines.push('bond:');\n    lines.push(`  attestation_id: ${input.bond.attestation_id}`);\n    lines.push(`  min_sats: ${input.bond.min_sats}`);\n    lines.push(`  min_days: ${input.bond.min_days}`);\n    lines.push(`counterparty: ${input.counterparty === null ? 'null' : input.counterparty}`);\n    lines.push('dispute:');\n    lines.push(`  mechanism: ${input.dispute.mechanism === null ? 'null' : input.dispute.mechanism}`);\n    lines.push(`  params: ${input.dispute.params === null ? 'null' : input.dispute.params}`);\n    lines.push(`remediation: ${input.remediation}`);\n    lines.push(`sworn_at: ${input.sworn_at}`);\n    lines.push(`nonce: ${input.nonce}`);\n    return lines.join('\\n');\n}\n\nfunction resolvesAtLine(r: PledgeResolvesAt): string {\n    if ('time' in r) return `time: ${r.time}`;\n    return `block: ${r.block}`;\n}\n\nexport function canonicalPledgeMessageBytes(input: PledgeCanonicalInput): Uint8Array {\n    return new TextEncoder().encode(canonicalPledgeMessage(input));\n}\n\nexport function computePledgeId(input: PledgeCanonicalInput): string {\n    return hexEncode(sha256(canonicalPledgeMessageBytes(input)));\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Outcome canonical message — SPEC §4.1\n//\n// Layout:\n//   oc-pledge-outcome/v1\n//   pledge_id: <64-hex>\n//   outcome: <kept | broken | expired_unresolved | disputed>\n//   resolved_at: <ISO>\n//   resolved_by: <addr | \"deterministic\">\n//   evidence:\n//     mechanism: <same as pledge>\n//     result: <single line>\n//     witness: <single line>\n//   dispute_window_ends_at: <ISO>\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport function canonicalOutcomeMessage(input: OutcomeCanonicalInput): string {\n    const lines: string[] = [];\n    lines.push(OUTCOME_DOMAIN);\n    lines.push(`pledge_id: ${input.pledge_id}`);\n    lines.push(`outcome: ${input.outcome}`);\n    lines.push(`resolved_at: ${input.resolved_at}`);\n    lines.push(`resolved_by: ${input.resolved_by}`);\n    lines.push('evidence:');\n    lines.push(`  mechanism: ${input.evidence.mechanism}`);\n    lines.push(`  result: ${input.evidence.result}`);\n    lines.push(`  witness: ${input.evidence.witness}`);\n    lines.push(`dispute_window_ends_at: ${input.dispute_window_ends_at}`);\n    return lines.join('\\n');\n}\n\nexport function canonicalOutcomeMessageBytes(input: OutcomeCanonicalInput): Uint8Array {\n    return new TextEncoder().encode(canonicalOutcomeMessage(input));\n}\n\nexport function computeOutcomeId(input: OutcomeCanonicalInput): string {\n    return hexEncode(sha256(canonicalOutcomeMessageBytes(input)));\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Abandonment canonical message — SPEC §5.1\n//\n// Layout:\n//   oc-pledge-abandonment/v1\n//   pledge_id: <64-hex>\n//   abandoned_at: <ISO>\n//   reason: <single line, ≤ 280 UTF-8 bytes>\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport function canonicalAbandonmentMessage(input: AbandonmentCanonicalInput): string {\n    return [\n        ABANDONMENT_DOMAIN,\n        `pledge_id: ${input.pledge_id}`,\n        `abandoned_at: ${input.abandoned_at}`,\n        `reason: ${input.reason}`,\n    ].join('\\n');\n}\n\nexport function canonicalAbandonmentMessageBytes(\n    input: AbandonmentCanonicalInput,\n): Uint8Array {\n    return new TextEncoder().encode(canonicalAbandonmentMessage(input));\n}\n\nexport function computeAbandonmentId(input: AbandonmentCanonicalInput): string {\n    return hexEncode(sha256(canonicalAbandonmentMessageBytes(input)));\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Field validation — runs before any of the canonical-message builders so a\n// caller can preview validity without producing a malformed signed envelope.\n// SPEC §3.6, §4.2 (table), §5.3 (table).\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * SPEC §0: ISO 8601 UTC means YYYY-MM-DDTHH:MM:SSZ — no fractional seconds,\n * no offsets other than the literal capital-Z suffix. Stricter than stamp's\n * ISO regex; pledge canonical bytes must reject `+00:00`, lowercase `z`, and\n * any fractional-second form.\n */\nconst ISO_UTC_STRICT = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$/;\nconst HEX_64 = /^[0-9a-f]{64}$/;\nconst HEX_32 = /^[0-9a-f]{32}$/;\n\nexport type ValidateResult = { ok: true } | { ok: false; reason: string };\n\nexport function validatePledgeInput(input: PledgeCanonicalInput): ValidateResult {\n    if (!input.swearer || /[\\s\\x00-\\x1f]/.test(input.swearer)) {\n        return r('swearer must be non-empty with no whitespace or control chars');\n    }\n    if (input.proposition.length === 0 || /[\\n\\r]/.test(input.proposition)) {\n        return r('proposition must be non-empty and a single line (no LF or CR)');\n    }\n    if (new TextEncoder().encode(input.proposition).byteLength > 512) {\n        return r('proposition exceeds 512 UTF-8 bytes');\n    }\n    if (!RESOLUTION_MECHANISMS.includes(input.resolution.mechanism)) {\n        return r(\n            `resolution.mechanism \"${input.resolution.mechanism}\" is not in the SPEC §3.4 set`,\n        );\n    }\n    if (input.resolution.query.length === 0 || /[\\n\\r]/.test(input.resolution.query)) {\n        return r('resolution.query must be non-empty and a single line');\n    }\n    if (new TextEncoder().encode(input.resolution.query).byteLength > 1024) {\n        return r('resolution.query exceeds 1024 UTF-8 bytes');\n    }\n    if ('time' in input.resolves_at) {\n        if (!ISO_UTC_STRICT.test(input.resolves_at.time)) {\n            return r('resolves_at.time must be ISO 8601 UTC ending in Z (no fractional seconds)');\n        }\n    } else if ('block' in input.resolves_at) {\n        if (!Number.isInteger(input.resolves_at.block) || input.resolves_at.block < 0) {\n            return r('resolves_at.block must be a non-negative integer');\n        }\n    } else {\n        return r('resolves_at must contain exactly one of {time} or {block}');\n    }\n    if (!ISO_UTC_STRICT.test(input.expires_at)) {\n        return r('expires_at must be ISO 8601 UTC ending in Z (no fractional seconds)');\n    }\n    if (!HEX_64.test(input.bond.attestation_id)) {\n        return r('bond.attestation_id must be 64 lowercase hex chars');\n    }\n    if (!Number.isInteger(input.bond.min_sats) || input.bond.min_sats < 0) {\n        return r('bond.min_sats must be a non-negative integer');\n    }\n    if (!Number.isInteger(input.bond.min_days) || input.bond.min_days < 0) {\n        return r('bond.min_days must be a non-negative integer');\n    }\n    if (input.counterparty !== null && /[\\s\\x00-\\x1f]/.test(input.counterparty)) {\n        return r('counterparty must be a Bitcoin address or null');\n    }\n    if (input.resolution.mechanism === 'counterparty_signs' && input.counterparty === null) {\n        return r('counterparty MUST be non-null when resolution.mechanism == counterparty_signs');\n    }\n    if (\n        input.dispute.mechanism !== null &&\n        input.dispute.mechanism !== 'vote_resolves' &&\n        input.dispute.mechanism !== 'named_oracle'\n    ) {\n        return r('dispute.mechanism must be null, \"vote_resolves\", or \"named_oracle\"');\n    }\n    if (input.dispute.params !== null && /[\\n\\r]/.test(input.dispute.params)) {\n        return r('dispute.params must be a single line or null');\n    }\n    if (input.remediation !== 'breach_recorded') {\n        return r('remediation must equal \"breach_recorded\" in v0.1');\n    }\n    if (!ISO_UTC_STRICT.test(input.sworn_at)) {\n        return r('sworn_at must be ISO 8601 UTC ending in Z (no fractional seconds)');\n    }\n    // Empty nonce is the test-vector v28 path — must reject.\n    if (input.nonce.length === 0) {\n        return r('nonce MUST be non-empty (E_PLEDGE_MALFORMED per SPEC §3.1)');\n    }\n    if (!HEX_32.test(input.nonce)) {\n        return r('nonce must be 32 lowercase hex characters');\n    }\n    return { ok: true };\n}\n\nexport function validateOutcomeInput(input: OutcomeCanonicalInput): ValidateResult {\n    if (!HEX_64.test(input.pledge_id)) return r('pledge_id must be 64 lowercase hex chars');\n    if (!['kept', 'broken', 'expired_unresolved', 'disputed'].includes(input.outcome)) {\n        return r('outcome must be one of: kept, broken, expired_unresolved, disputed');\n    }\n    if (!ISO_UTC_STRICT.test(input.resolved_at)) {\n        return r('resolved_at must be ISO 8601 UTC ending in Z');\n    }\n    if (\n        input.resolved_by !== 'deterministic' &&\n        (!input.resolved_by || /[\\s\\x00-\\x1f]/.test(input.resolved_by))\n    ) {\n        return r('resolved_by must be \"deterministic\" or a Bitcoin address');\n    }\n    if (!RESOLUTION_MECHANISMS.includes(input.evidence.mechanism)) {\n        return r(`evidence.mechanism \"${input.evidence.mechanism}\" is not in the SPEC §3.4 set`);\n    }\n    if (input.evidence.result.length === 0 || /[\\n\\r]/.test(input.evidence.result)) {\n        return r('evidence.result must be a non-empty single line');\n    }\n    if (input.evidence.witness.length === 0 || /[\\n\\r]/.test(input.evidence.witness)) {\n        return r('evidence.witness must be a non-empty single line');\n    }\n    if (!ISO_UTC_STRICT.test(input.dispute_window_ends_at)) {\n        return r('dispute_window_ends_at must be ISO 8601 UTC ending in Z');\n    }\n    return { ok: true };\n}\n\nexport function validateAbandonmentInput(\n    input: AbandonmentCanonicalInput,\n): ValidateResult {\n    if (!HEX_64.test(input.pledge_id)) return r('pledge_id must be 64 lowercase hex chars');\n    if (!ISO_UTC_STRICT.test(input.abandoned_at)) {\n        return r('abandoned_at must be ISO 8601 UTC ending in Z');\n    }\n    if (input.reason.length === 0 || /[\\n\\r]/.test(input.reason)) {\n        return r('reason must be a non-empty single line');\n    }\n    if (new TextEncoder().encode(input.reason).byteLength > 280) {\n        return r('reason exceeds 280 UTF-8 bytes');\n    }\n    return { ok: true };\n}\n\nfunction r(reason: string): ValidateResult {\n    return { ok: false, reason };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Envelope canonicalization — SPEC §6 (RFC 8785)\n//\n// Same encoder as stamp-core: keys sorted, no insignificant whitespace,\n// integers serialized without exponents, control chars `\\uXXXX`-escaped.\n// `undefined` keys are dropped (used for optional via_delegation / agent_address).\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type JsonValue =\n    | null\n    | boolean\n    | number\n    | string\n    | JsonValue[]\n    | { [key: string]: JsonValue };\n\nexport function canonicalize(value: JsonValue): string {\n    return encode(value);\n}\n\nexport function canonicalizePledgeEnvelope(env: PledgeEnvelope): string {\n    return canonicalize(env as unknown as JsonValue);\n}\n\nexport function canonicalizeOutcomeEnvelope(env: OutcomeEnvelope): string {\n    return canonicalize(env as unknown as JsonValue);\n}\n\nexport function canonicalizeAbandonmentEnvelope(env: AbandonmentEnvelope): string {\n    return canonicalize(env as unknown as JsonValue);\n}\n\nfunction encode(v: JsonValue): string {\n    if (v === null) return 'null';\n    if (typeof v === 'boolean') return v ? 'true' : 'false';\n    if (typeof v === 'number') return encodeNumber(v);\n    if (typeof v === 'string') return encodeString(v);\n    if (Array.isArray(v)) {\n        const parts: string[] = [];\n        for (const item of v) parts.push(encode(item));\n        return '[' + parts.join(',') + ']';\n    }\n    if (typeof v === 'object') {\n        const keys = Object.keys(v).sort();\n        const parts: string[] = [];\n        for (const k of keys) {\n            const inner = v[k];\n            if (inner === undefined) continue;\n            parts.push(encodeString(k) + ':' + encode(inner as JsonValue));\n        }\n        return '{' + parts.join(',') + '}';\n    }\n    throw new Error('cannot canonicalize value of type ' + typeof v);\n}\n\nfunction encodeNumber(n: number): string {\n    if (!Number.isFinite(n)) throw new Error('non-finite number not JSON-canonicalizable');\n    if (Object.is(n, -0)) return '0';\n    if (Number.isInteger(n) && Math.abs(n) < 1e21) {\n        return String(n);\n    }\n    return JSON.stringify(n);\n}\n\nconst ESCAPE_TABLE: Record<string, string> = {\n    '\\\\': '\\\\\\\\',\n    '\"': '\\\\\"',\n    '\\b': '\\\\b',\n    '\\f': '\\\\f',\n    '\\n': '\\\\n',\n    '\\r': '\\\\r',\n    '\\t': '\\\\t',\n};\n\nfunction encodeString(s: string): string {\n    let out = '\"';\n    for (let i = 0; i < s.length; i++) {\n        const ch = s[i]!;\n        const code = ch.charCodeAt(0);\n        if (ESCAPE_TABLE[ch]) {\n            out += ESCAPE_TABLE[ch];\n        } else if (code < 0x20) {\n            out += '\\\\u' + code.toString(16).padStart(4, '0');\n        } else {\n            out += ch;\n        }\n    }\n    out += '\"';\n    return out;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Small utilities\n// ─────────────────────────────────────────────────────────────────────────────\n\nconst HEX_TABLE = '0123456789abcdef';\n\nexport function hexEncode(bytes: Uint8Array): string {\n    let out = '';\n    for (let i = 0; i < bytes.length; i++) {\n        const b = bytes[i]!;\n        out += HEX_TABLE[(b >> 4) & 0x0f]! + HEX_TABLE[b & 0x0f]!;\n    }\n    return out;\n}\n\nexport function sha256Hex(bytes: Uint8Array): string {\n    return hexEncode(sha256(bytes));\n}\n\n/**\n * Generate a 32-char-hex random nonce (16 random bytes). Uses globalThis.crypto\n * which is available in Node 20+ and every browser. Throws if the runtime\n * lacks a crypto source; callers wanting deterministic test fixtures pass an\n * explicit nonce instead.\n */\nexport function generateNonce(): string {\n    const bytes = new Uint8Array(16);\n    const c = (globalThis as { crypto?: Crypto }).crypto;\n    if (!c || typeof c.getRandomValues !== 'function') {\n        throw new Error('no crypto.getRandomValues available; pass an explicit nonce');\n    }\n    c.getRandomValues(bytes);\n    return hexEncode(bytes);\n}\n"]}