{"_id":"@nauticana/sail","_rev":"55-458d109b35a9dc1f7c7e21f2bc8cb614","name":"@nauticana/sail","dist-tags":{"latest":"1.1.26"},"versions":{"0.5.0":{"name":"@nauticana/sail","version":"0.5.0","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@0.5.0","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"89ad0da6c6964bbaca9c9d3c2f3c106cf2866adb","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-0.5.0.tgz","fileCount":70,"integrity":"sha512-bKcOaXSCekwI4E0eZBQ/zgq4KorVVLQga1xrj0MhT9Iruyck0D2sHPfxxi0QEKcU5avtxOsvL0bjHw+POFhSUg==","signatures":[{"sig":"MEUCICcWR0OvbqBvrAXpHYMXVLCpzot7MvT4LF0NxFMCGMsJAiEA4lhtuTPHDhW4nPcs+U5aQ0Jy3VN9YgkYesCjLI15ebE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@0.5.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":234683},"main":"src/index.ts","gitHead":"c24e9f67311366c50c0761a470918f6eeb1b9202","_npmUser":{"name":"nauticana","email":"nauticana@daxoom.com"},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.11.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing.","directories":{},"_nodeVersion":"24.14.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.2","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_0.5.0_1777525724098_0.03426808245375046","host":"s3://npm-registry-packages-npm-production"}},"0.5.1":{"name":"@nauticana/sail","version":"0.5.1","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@0.5.1","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"ab220f901a68ddaf0967a2bd03d79488a1f96c12","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-0.5.1.tgz","fileCount":70,"integrity":"sha512-hFsPIetYtdfZL8ph2exCihbpZLktqomS+LDJFRwizWfskYhULeMEb4997STFmMfrSGoxtzSgGhCuLH4HpQu7kA==","signatures":[{"sig":"MEUCIF9j0czh1nk44rcOQ80FerhPO3KL93+8Iyg34tp/mI7bAiEA2mhQB3JhDirzsbpTfB0iJicilDywUqxY9vNC3i5GqAU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@0.5.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":235740},"main":"src/index.ts","gitHead":"10040e587eefd015032f89dba7321c30e5743ab6","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.11.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing.","directories":{},"_nodeVersion":"24.14.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.2","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_0.5.1_1777823995719_0.12337182693073534","host":"s3://npm-registry-packages-npm-production"}},"0.5.2":{"name":"@nauticana/sail","version":"0.5.2","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@0.5.2","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"dca43c0e6cbe94e41ec7a9904f389df8737ae3e7","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-0.5.2.tgz","fileCount":70,"integrity":"sha512-Ut/tEJvB+IPEiltBPtlit9ImggTU6NY26W59t8UQlfl0ECzFT/L/B7yZri98yQaZKAKHQr+0yPvs3dSUlolBSw==","signatures":[{"sig":"MEQCIGVjVQeCcVjuhUxlbbbTLY76PFImlSjv7mKOua2Uh2pGAiAVnYMNXTkOtcBOiW0HK6NX9CbG0xN8Gr7j15ULBSeIzA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@0.5.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":236877},"main":"src/index.ts","gitHead":"5f058b9069316c250b39f456912b18bcc656247b","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.11.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing.","directories":{},"_nodeVersion":"24.14.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.2","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_0.5.2_1777919750698_0.6467181856317326","host":"s3://npm-registry-packages-npm-production"}},"0.5.3":{"name":"@nauticana/sail","version":"0.5.3","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@0.5.3","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"3e809ca281ac87ec3eaa840363c3831cb6a8c904","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-0.5.3.tgz","fileCount":72,"integrity":"sha512-nylYzEIX3tnmAXJ47m8IQc47uXNanTmXSNTWBVa801jB2l97PeBFXoH8udnqirB1io+rFdePx/EYDC5p13v3fQ==","signatures":[{"sig":"MEUCIQCA1KUDpMalKW02rHM5rudKJQbYKT5gh0gh/o48Y1+FcgIgd7kqHfdELYIvVJH4iKD6Vjk4E5skCKnyd0GvscuulUM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@0.5.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":241676},"main":"src/index.ts","gitHead":"3254808be3fbff113a056a692bd2b4ec31e5a8d9","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.11.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing.","directories":{},"_nodeVersion":"24.14.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.2","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_0.5.3_1777933316636_0.510491193757403","host":"s3://npm-registry-packages-npm-production"}},"0.5.4":{"name":"@nauticana/sail","version":"0.5.4","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@0.5.4","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"df76b8a24226c362f36e86773b9587ede301358e","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-0.5.4.tgz","fileCount":72,"integrity":"sha512-IIEPr6loYLHGXYUWyqSKtHEh3zFyqquKHpGJRO0ytunVlX6yrSs47x3PKRgzwBBSh8GPQK5Vxc3bw830wphJIg==","signatures":[{"sig":"MEUCID/IqzL9FdT7zg7vQ9GnnaX2MmdqlsM16Cbpk2hfIwRbAiEAsdgN94cIEXyssXr2ppmJ/hmC4eMUKLcgMI15ERmjr6I=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@0.5.4","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":242060},"main":"src/index.ts","gitHead":"bd76fed5b02940303455feb9498ba3c7d87dc3b2","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.11.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing.","directories":{},"_nodeVersion":"24.14.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.2","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_0.5.4_1777959043465_0.6652815863709061","host":"s3://npm-registry-packages-npm-production"}},"0.5.5":{"name":"@nauticana/sail","version":"0.5.5","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@0.5.5","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"82d7d2fe971aac731f51a38542b8fe778077de0c","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-0.5.5.tgz","fileCount":72,"integrity":"sha512-DwYfqPyPFtCC4sV8bKWRP52iyfSu8AB6dG1iatYU7Qr09tQX1UFhhiSuYcz+cO8RpWuYbVlYkPuKINMQya8S+A==","signatures":[{"sig":"MEQCIAV/BFjQXzk52BtAaR5qUkgU4gDSge6gMewXTKrpmjq/AiBsvkpvgRtiEE/bIixpaONh3s4XUvHbpLUoNk1dO7VC/Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@0.5.5","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":247282},"main":"src/index.ts","gitHead":"de998480da4f4d79b5e22ce6fb6f54cfbad49080","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.11.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing.","directories":{},"_nodeVersion":"24.14.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.2","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_0.5.5_1777964199550_0.6613862624896449","host":"s3://npm-registry-packages-npm-production"}},"0.5.6":{"name":"@nauticana/sail","version":"0.5.6","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@0.5.6","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"c702c78f2b62c2f9b64df666be885259a727812d","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-0.5.6.tgz","fileCount":72,"integrity":"sha512-4v3PBKdtIwc0L4GSFVT1U1xT7hynj/oNqvWsR+3L4AQg08AlMko7BOqtHYYYOiIqLfpHppbXjjIC7lPAi6uYpQ==","signatures":[{"sig":"MEUCIH6DkTiILblRR12F9oyM+zzaxvhGOuE5RzWk0wJ92grTAiEAmiqzQQxy8/L7YBqobo2FlYd4hwwa5StU7iun5zr/bzE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@0.5.6","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":247948},"main":"src/index.ts","gitHead":"01520c8eac6c21ce90756fc48d7f71135cb9cb93","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.11.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing.","directories":{},"_nodeVersion":"24.14.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.2","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_0.5.6_1778383158006_0.5957636701378637","host":"s3://npm-registry-packages-npm-production"}},"0.5.7":{"name":"@nauticana/sail","version":"0.5.7","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@0.5.7","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"5a157e56418bdd4b61eb9d846fcf657943a43bfe","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-0.5.7.tgz","fileCount":72,"integrity":"sha512-O70tERRp39rbBSG55w+4YwA/HeSQ3kEv3ktX+hHFUl4Yh+q7FJ6wHy0zKbKv3Hs0hxpEb9+USNLD8jSsyb1NXA==","signatures":[{"sig":"MEYCIQDrwYqFrAIBG1NKALtCGBjWoliWCcUadfn/9Mi2MAAG5QIhAMf9zXl7PQJ4qblI0y9GK1t9WD3gc3osgO4tHVMWDRAr","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@0.5.7","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":248592},"main":"src/index.ts","gitHead":"5130f7f3c63fb253889b47fb8a888774bd32febb","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.11.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing.","directories":{},"_nodeVersion":"24.14.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.2","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_0.5.7_1778391835702_0.953912494193609","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@nauticana/sail","version":"0.6.0","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@0.6.0","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"8fafbad83d36205d55e2cafdf3b86c28ab4ef519","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-0.6.0.tgz","fileCount":75,"integrity":"sha512-Kbggi5Y09inq+n6NsQ4c4ASF1hvvV1lal4JhPyRcoIG2aPKNar1wANB9krpWZC3Ia6fnhGv0Pd8iGVUFoXDlzw==","signatures":[{"sig":"MEYCIQDifhkNQ92ifdUEk5e7dMfC8Q8YkXoRcOg3jN9AG6RhlQIhAI8sKaI4CyoaYPFxfRYCqPSlV3hueIJb8GKweH7GvSkS","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@0.6.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":268562},"main":"src/index.ts","gitHead":"2659875e79200bc199d9806eab1e8c5707fb3a4e","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.11.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.14.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.2","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_0.6.0_1778621547002_0.5674899914503082","host":"s3://npm-registry-packages-npm-production"}},"0.6.1":{"name":"@nauticana/sail","version":"0.6.1","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@0.6.1","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"681ebc6c62e310661f94021d8e46c15821cf670b","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-0.6.1.tgz","fileCount":77,"integrity":"sha512-MYjptFGgcXouyn6ID1SbqRDmKqb443mmFspsDRCRaIaWnDbZ8nzAbwesy0lLTv9JZGMMEWSvAKLU8MKcucwM0Q==","signatures":[{"sig":"MEYCIQCvGU97Z4lKcZGVfUvGRuqn4x2lJb3OlvSAWmmzFsjf/gIhAN4ue8DKJ/LOdo5v7bX5j5RK9p6RS78XgzixdNlJQKSU","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@0.6.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":277922},"main":"src/index.ts","gitHead":"81f57f3fae9c9f6cceae6908dcce9d974a5bac99","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.11.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.14.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.2","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_0.6.1_1778623453156_0.28271857555600954","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"name":"@nauticana/sail","version":"0.7.0","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@0.7.0","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"9b72aafba9faa552e1b4c5a8c8ab0bbf01738177","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-0.7.0.tgz","fileCount":77,"integrity":"sha512-6ERrS08+tWECLL9MX/WV8RooI1SuS8UWpUms1mzwj0FSA7dRXmpC3W7NEysoopI1FI2f77cl0i6fjlijKo1GXg==","signatures":[{"sig":"MEQCIG2MJeSgY+Ln6R30bMMOVd93e9YOBCglAJagI7pWhzhiAiBUUWRj2MFjZrz/PdtnGP+EbUwJ4lwQqinjazFG17jLeA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@0.7.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":287974},"main":"src/index.ts","gitHead":"e6d5744e94de9628d4ed0929bd6ca3875c837a3f","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.11.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.14.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.2","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_0.7.0_1778629585099_0.2907825442202119","host":"s3://npm-registry-packages-npm-production"}},"0.8.0":{"name":"@nauticana/sail","version":"0.8.0","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@0.8.0","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"68744f2796f63d7e04552d202f584cad4918048a","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-0.8.0.tgz","fileCount":80,"integrity":"sha512-TJZcmFqApxcLRrMMBtFaVit61GjNmDA2X+qpPiyDWrhxSq7QCfg49ogQP6sUNZGlhh+LvZDuHj+qvkAAmXMIbA==","signatures":[{"sig":"MEUCIQDekBQ94tcxs878x/Yl8YKfyOBY7bkQkJl37+8w1xDAKAIgArM1DhDzHcWuqFH/98x35aGdY8JsWhYahTS21kGWgGE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@0.8.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":306180},"main":"src/index.ts","gitHead":"16e7eaf4bc5c12cb65c0bc0114a08eb7d0d213fb","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.11.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.14.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~6.0.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_0.8.0_1778633126791_0.5491600198193636","host":"s3://npm-registry-packages-npm-production"}},"0.8.1":{"name":"@nauticana/sail","version":"0.8.1","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@0.8.1","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"55121a27a4a020527220b742ea25a5d3340eff8c","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-0.8.1.tgz","fileCount":82,"integrity":"sha512-2KIWHfxPk2PvaNYFZ3xk4oYZqh4pSe2Ox2bpGWzmnq3YWE3dhm0ZTkEUvRUYoC+S71xEPCl5EaKLvnxYZbW9Ow==","signatures":[{"sig":"MEYCIQC976Mn406cjBF7ESS4MZO7QHz3UfxqZVqy6nsrVnXsxQIhANPzEoj3Efg6K7/c98eiiIxkBrfLTs27D5ew8/WcoF9l","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@0.8.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":318175},"main":"src/index.ts","gitHead":"27c9ad2ac4eedc10d08f1b559730b1e1f6d32db7","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.11.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.14.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_0.8.1_1778648541779_0.0836639548107938","host":"s3://npm-registry-packages-npm-production"}},"0.8.3":{"name":"@nauticana/sail","version":"0.8.3","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@0.8.3","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"30057e8cd383b86d8838b180644561002f860f1b","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-0.8.3.tgz","fileCount":82,"integrity":"sha512-Rl1rGsUyXnXT01ljq/CvyKi/tUCu2sC+Cp0xVOFA08P8TRN831MGuOrr+A60TDWICYtNVmdLvcUYZf0/6PF9CQ==","signatures":[{"sig":"MEQCIEBEWe6+FRUSdQEhXXFey8FS7qGDDDSbT0o/L6v3+ACsAiBwvdSg0RHn/wBDJNB1pAEvYMoLBk9zRc5Mh9/FO2au7g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@0.8.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":319982},"main":"src/index.ts","gitHead":"14f8c431e1513864b2e4cae78d52ac80c35fc8c6","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.11.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.14.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_0.8.3_1778703469079_0.8838206974133302","host":"s3://npm-registry-packages-npm-production"}},"0.8.4":{"name":"@nauticana/sail","version":"0.8.4","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@0.8.4","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"75e12e54ec4b85fffc1a53e24d49075e03ea5622","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-0.8.4.tgz","fileCount":82,"integrity":"sha512-fYX6VLrA2UTQRCLe4FtbtjY2L8rjqNJtupNiA8e5c6goM6ZcL6aafwbgDGPTTEmYUcaJ3i8j8BNRIzxJYy2veg==","signatures":[{"sig":"MEUCIQCUowp6AGj5UgBYTV3bfLlL32DVNuT0MpfbqxVOu/CxSwIgE3yWH+o+1iXB3ChMBq+CAlMgummZJoVg1cErCAlFox0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@0.8.4","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":323379},"main":"src/index.ts","gitHead":"16e84259a6acd8be969cca8be9edd6bcf78200d5","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.12.1","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.15.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_0.8.4_1778904654762_0.6185184800373489","host":"s3://npm-registry-packages-npm-production"}},"0.9.0":{"name":"@nauticana/sail","version":"0.9.0","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@0.9.0","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"6822512759ddeb741856743709c81ed90dbcd29a","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-0.9.0.tgz","fileCount":82,"integrity":"sha512-ZDdx4ZM2w8q02KCjOSsp+UNC3PFZX5/IfggBQoOHtK5+mptBSK6YVRPxathSF28VzMD7B2aFw2IBE1yoqOKgPA==","signatures":[{"sig":"MEQCIBCHxaXwEoZMLdX9zFe3BJf4HHjl/50cRXIC9ywGMl+lAiALriP8XX088McitSFX33LnzPxqfb2E+Gnhc4UOO1zDsA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@0.9.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":333533},"main":"src/index.ts","gitHead":"3824adca11455795390822cfc80be3237c3a18c1","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.13.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_0.9.0_1780274035650_0.18518292806856773","host":"s3://npm-registry-packages-npm-production"}},"0.9.1":{"name":"@nauticana/sail","version":"0.9.1","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@0.9.1","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"3e35f1b6475765c9d4fbc8e796465cfef4a1bc9c","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-0.9.1.tgz","fileCount":82,"integrity":"sha512-QoVM8uE+Z++7zuwqwdMQmTZceMnxOZvkcaJFhSYZUKKqMTRDhXUCH9EDvT2tY/JuCTecPvOzSalhEHvB93Q1IA==","signatures":[{"sig":"MEYCIQDtXpxfDuIQ+7MEO8aRp3pI0Z8H+lbwrWJSGMyNTYshxAIhALefZUeNqbvsViL7ywmVIGEmgYfVSeH1qfX0C9IKtAG/","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@0.9.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":333267},"main":"src/index.ts","gitHead":"ca3af6fd8e1fd04ef1f5afe46246002560a4ad7d","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.13.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_0.9.1_1780358769638_0.8086752146838776","host":"s3://npm-registry-packages-npm-production"}},"0.9.2":{"name":"@nauticana/sail","version":"0.9.2","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@0.9.2","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"65581c84c45449e05cbc825fa97be0df147016d0","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-0.9.2.tgz","fileCount":82,"integrity":"sha512-PVL8QugvdtjlRgOhXnUgd/aRqp3LO6DKwbz7BRz/UOcKP06SKaaiJ9xKOQ+n9unW2AKFwsmamVUzXu6/SN+C6w==","signatures":[{"sig":"MEYCIQDIsQNNZYVGy2N+UG3iROvO34qkh9/Y0kv8QiUeQC46zgIhANzTYrzR92v0M8oMDKA/IZFZLr+O9vrMpdXjRiifX8V5","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@0.9.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":333974},"main":"src/index.ts","gitHead":"89ddeacfbcce60668c3cfdac05a34d7a68744d83","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.13.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_0.9.2_1780362498354_0.3144784349949099","host":"s3://npm-registry-packages-npm-production"}},"0.9.3":{"name":"@nauticana/sail","version":"0.9.3","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@0.9.3","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"35d79ea46ea0af0ba875161a6959968ef820f322","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-0.9.3.tgz","fileCount":82,"integrity":"sha512-MdW7sAm7Efg9yL338A3TQ3sKbncNOVj/H8y7oDhPji/+cDyPAHus4ZQ8gIyg0QyVgSbzdGIvIYlzgwQ/Wv+GdQ==","signatures":[{"sig":"MEYCIQDX5e9cq5BfjYwFEznU3mbODFCASb7OAl1+G5/pL3coswIhANgmhmv2NxZ2G6Eft7ajkwqdADU0ACUgYIGipIcvZiJx","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@0.9.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":336089},"main":"src/index.ts","gitHead":"049d34c1833268c93dd4fbd226408a5be605bc8e","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.13.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_0.9.3_1780686461468_0.22641387244069855","host":"s3://npm-registry-packages-npm-production"}},"0.9.4":{"name":"@nauticana/sail","version":"0.9.4","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@0.9.4","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"3668c697f2fc826f886d0d81a1f226dd81dee548","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-0.9.4.tgz","fileCount":82,"integrity":"sha512-7k420/XMpEf8vsx5635H3EBJ9txFsnFV1S9pXzGHTB69ZK1digrhd0Viq3oRC3+lEwm/U/k/sZ2hJN4Phtocjw==","signatures":[{"sig":"MEYCIQCw4tDzBf8X6dnRNvNo9dZhZ2wtzEQFk9UDNrUjXiqXOAIhAPq7xVEHXngqzwYDaHK2Gl7IQBtjeO34UJYqhluS86/K","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@0.9.4","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":338578},"main":"src/index.ts","gitHead":"478ba8b5b5a64c0b669d301427b01cddf78ed57b","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.13.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_0.9.4_1780731687461_0.5584816499403971","host":"s3://npm-registry-packages-npm-production"}},"0.9.5":{"name":"@nauticana/sail","version":"0.9.5","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@0.9.5","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"8eccfa1ccea7613c4487cc75be88379b9a61c561","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-0.9.5.tgz","fileCount":82,"integrity":"sha512-bxZ9jfcKI0yo3qbTHLkiWxCvKQeUO9u61xp0xNDt8+mDYsM45/CFLy+2aF30Q55Gze/7qza/tfVJhx8hjBwagQ==","signatures":[{"sig":"MEQCIDmBlRl5i1O3TlE2ryeziy21gti++R1DneEYspzxcQ0cAiBvGwgqL5eo62GRcPIiAvXLdqcu8EwpwNntYlt//IFe1A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@0.9.5","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":338921},"main":"src/index.ts","gitHead":"ea111b80820b96bdddd18defc206795f2339cab3","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.13.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_0.9.5_1780774185121_0.9536885557854493","host":"s3://npm-registry-packages-npm-production"}},"0.9.6":{"name":"@nauticana/sail","version":"0.9.6","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@0.9.6","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"4e9e81d408e1d0ab5d4f8e5b450c3e42ef5e89c1","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-0.9.6.tgz","fileCount":82,"integrity":"sha512-rR4Db8pSmIUxiIF3b3h84jadJGFlGj3ux5Xq1gPqXqR72ZuyO3vYLE1pE/1r1+r/R332fvMcx28LB1BWVx2W/A==","signatures":[{"sig":"MEQCICcl4sIN4cbUIfa4FApi5rjpWVzFmNKUWvyWILCB84a2AiBsVaX8WvHdFmAFN5Uu+rfKSEwUsvMGDc+ceb6gE7IQYQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@0.9.6","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":339203},"main":"src/index.ts","gitHead":"967f2516558695874a75ebf04820e57b3c2adea3","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.13.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_0.9.6_1780817100683_0.3156617296100843","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@nauticana/sail","version":"1.0.0","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@1.0.0","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"cd066c6f14ddd01cfc2af86697c10edde47a5c5a","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.0.0.tgz","fileCount":86,"integrity":"sha512-btflhPLUXrlptwqgLDwhsR82ewA9Ov7U8nbIQx/5wr4m9Ic5JvbsWjhrJXbQxHLCr6RA6DAU2sMF13i7jbU7Og==","signatures":[{"sig":"MEYCIQC6NKHt4yidK/cejJ74SY0xbwaoQLf58AYOLbLbYXnosgIhAKC+4LyBGaprvWWQjunnj2SIjLX5lUjOa1Pqv3zyXj70","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.0.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":347329},"main":"src/index.ts","gitHead":"2940718a07862e0a8605b114773d1a25b44bc790","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.13.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_1.0.0_1780896911966_0.27944488312176885","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@nauticana/sail","version":"1.0.1","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@1.0.1","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"e14c3691835dcf131a1a09ea48c5f850b3ee01ee","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.0.1.tgz","fileCount":94,"integrity":"sha512-hn8lW4fNH1RuhPLcZg9ZpXRtpsIh36cr8McFSK3Scf5EfUa8HXcF0wsQ6yVUjdFbaZlT+74JIkLv5sFm52nimA==","signatures":[{"sig":"MEYCIQCywhB9hjab9CPH6rRDoPx4hhkQFInNLfyc/pa4TuMQDAIhAMMxH+D8n/9D6aDvzJUORBP7SeAruIWCgoJLTVnw2IDZ","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.0.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":359378},"main":"src/index.ts","gitHead":"b34bbf9830ed206aadb721ec526d191d7bd50d80","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.13.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_1.0.1_1780950909252_0.31205191232651797","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@nauticana/sail","version":"1.0.2","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@1.0.2","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"809fa59bce83b292e18363d0edb7e8f8c5e33f56","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.0.2.tgz","fileCount":97,"integrity":"sha512-PX7oaeLnq31TNCJAAehxCfduzcZzKGMZB9vTiFdHHrAm2XivsHaQzwCgEHV7XaDghioGGXGLO3URjp2uDsD2uw==","signatures":[{"sig":"MEUCIQDN/Q0SWIJkZ4WR+08G7CwMxyR+kNBd9iv/ZFhj+lgOqgIgT/F5g1jakoLJKL0JcUDLvAUsEPXckJSwK29JUYGjsdo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.0.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":367985},"main":"src/index.ts","gitHead":"c61c46c70ff5efd22196840fe354f711aebcdd80","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.13.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_1.0.2_1780962789991_0.707757773592022","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@nauticana/sail","version":"1.0.3","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@1.0.3","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"c7114b948bc6bc14480e1624605e6569650a8a7a","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.0.3.tgz","fileCount":100,"integrity":"sha512-3h/sJQS537VcOQI6FD9lQhVqhTdt5FuagA40Vhkg0dGERBW8aBu8Fw/jZft3+pLGt2KOi11Dv0GmYTFg8gmStw==","signatures":[{"sig":"MEYCIQCAbHyEp19/kV7z9S9dYGS6TfCeTRoHofx8l6e6BB0LiAIhAMeyhodr1AjrtbDvAh4K5XM8BawfDXk0iDhRXmxjgPnD","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.0.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":376337},"main":"src/index.ts","gitHead":"a8a670c44e6464c73865ff84243ba2f7bf709b43","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.13.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_1.0.3_1780984541722_0.15827648465768562","host":"s3://npm-registry-packages-npm-production"}},"1.0.7":{"name":"@nauticana/sail","version":"1.0.7","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@1.0.7","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"e6324fb2c4f164c1a0bebe68582dcdf5860cc05f","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.0.7.tgz","fileCount":100,"integrity":"sha512-eQ4UYGXVeO7NX5Lg7Wmy9Gf2arrAszVHuIUPqqwuLZzfroyeB5UTqji/aFb23VzBB6mJnKBaUWNUru/V9lBBRQ==","signatures":[{"sig":"MEQCIAQjnSNPxrPWqu4YAHEYDZ/9p3T/nEGpKok/lhpGvtQSAiAotZljm6vb0A3oXrSZbN/iWi11S8hVHutdWHcUrv+ktA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.0.7","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":382525},"main":"src/index.ts","gitHead":"96e130948cc8a051abaf5d3e63a65b60f5d78f86","scripts":{"check":"npm run typecheck && npm run check:templates","typecheck":"tsc --noEmit","check:templates":"ngc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.13.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/compiler-cli":"^21.2.8","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_1.0.7_1781393204691_0.0634032810460825","host":"s3://npm-registry-packages-npm-production"}},"1.0.8":{"name":"@nauticana/sail","version":"1.0.8","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@1.0.8","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"de170b51ded9b550c6822a3e5b4d97ae3afd8a77","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.0.8.tgz","fileCount":100,"integrity":"sha512-f5Ywhz8N8mn7inFYfyUgjgnJk7DoA0tzeTp1yCptB5b47idE4Hl8OBJLpSgFBkmufiWfbCsBOHatbMTXIrgHxg==","signatures":[{"sig":"MEMCH1FN0eWA37mziYeqz5PA7b6l6hNRXtFMvbwIr8NTR7MCIB25ZjpYWi53/HTtwpT3TpXSbGxJ+0MoG+14QG/PFNNH","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.0.8","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":383874},"main":"src/index.ts","gitHead":"2ecd51608450750eb3a656e2c3191b23b23a0126","scripts":{"check":"npm run typecheck && npm run check:templates","typecheck":"tsc --noEmit","check:templates":"ngc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.13.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/compiler-cli":"^21.2.8","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_1.0.8_1781502560506_0.29038425105430266","host":"s3://npm-registry-packages-npm-production"}},"1.0.9":{"name":"@nauticana/sail","version":"1.0.9","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@1.0.9","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"cf4d5b036d893d747fdf1135d3ceb760f875e084","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.0.9.tgz","fileCount":100,"integrity":"sha512-WJZX0a9AxiuAyIvx25u4PiFM6Ie3pYRis9iFvextjpAfb1KqQY1PEcHpyzX27yWHeIY5kxcI20Dsx8ev1NWFfQ==","signatures":[{"sig":"MEUCIQDpZrh6i1mzV2nd40TvSLoXEbqUEhnXj1JiJlIfx/hXrAIgYX5pXr2rr5uIb0iUDaOgGBQNziUiPtlZFWMGTFhdvDQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.0.9","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":385189},"main":"src/index.ts","gitHead":"93cd1b50c918f309cf1930751dce9fde0fda7ca9","scripts":{"check":"npm run typecheck && npm run check:templates","typecheck":"tsc --noEmit","check:templates":"ngc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.13.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/compiler-cli":"^21.2.8","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_1.0.9_1781536320745_0.5317798947751635","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@nauticana/sail","version":"1.1.0","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@1.1.0","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"3c6e107d784092a7a3aef26c7b47a18b52d644f1","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.1.0.tgz","fileCount":104,"integrity":"sha512-ualnypx6zsQjaTxMgU9/hYAbePhLagZS2dROB1oqcLBd+rONez4MA85FhKkhvQ/7QT/0j2MmH3pO/jNeHEVq7w==","signatures":[{"sig":"MEQCIDG3aJ1FH07Kkgx7tdp6MdUYEsVXp7h/vTZwGoV/wz2CAiBGg0lASkIYWMyhre8Hnr3tvxnPRhv9b1f65nboTE6++Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":397100},"main":"src/index.ts","gitHead":"c9fbdc5e3b170c5206e300de2cb2affeca64016c","scripts":{"check":"npm run typecheck && npm run check:templates","typecheck":"tsc --noEmit","check:templates":"ngc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.13.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/compiler-cli":"^21.2.8","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_1.1.0_1781811242906_0.9261157616302886","host":"s3://npm-registry-packages-npm-production"}},"1.1.1":{"name":"@nauticana/sail","version":"1.1.1","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@1.1.1","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"5bffac9cc1ff8164cd7b4f0de66810a69c031cd7","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.1.1.tgz","fileCount":106,"integrity":"sha512-Mwhs0j6vCRE1O2UyTGYTmyOTyorOB/ZzdWXr/F0O4E8wAP95pv9QMT+hS8p1PLP0e9ywG8S8UeD01ne4ZN6sKA==","signatures":[{"sig":"MEUCIQDsgtMIl7lYMwhVmGPlUJBiBNrAzBzN1WursiFGOG0FMwIgRQyRgWN80bN5aQQEvNsRc0aqWUj3iTA+Sk1dYk6F+30=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.1.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":399239},"main":"src/index.ts","gitHead":"2a89cb89fd8c94274aff4cd996729b390360aec2","scripts":{"check":"npm run typecheck && npm run check:templates","typecheck":"tsc --noEmit","check:templates":"ngc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.13.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/compiler-cli":"^21.2.8","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_1.1.1_1781924062363_0.3295835672610399","host":"s3://npm-registry-packages-npm-production"}},"1.1.2":{"name":"@nauticana/sail","version":"1.1.2","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@1.1.2","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"80542f2cda02f4cf6d2ee99a8f7c2ae7269ac893","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.1.2.tgz","fileCount":106,"integrity":"sha512-lWKDgdaJWYQEcOwCIKvhusGH8ffmRv+Cw7ut4g3sFnMMUnbks7y9ARJBIzErUDIXFUQpD0u68eF+RzR4yqgvXg==","signatures":[{"sig":"MEYCIQDXJsHHpRHZChUPoJvWguuA11tUTXqiqxyyI4Nc7AwUlAIhAIkmafz2UaexrsTBeP9YIG97oqCShIYQYeYkUgK9eH+U","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.1.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":401771},"main":"src/index.ts","gitHead":"b651e55ebf7b9a98c7637f2bf30267ce3b72c805","scripts":{"check":"npm run typecheck && npm run check:templates","typecheck":"tsc --noEmit","check:templates":"ngc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.13.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/compiler-cli":"^21.2.8","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_1.1.2_1782026167620_0.45491137275936167","host":"s3://npm-registry-packages-npm-production"}},"1.1.3":{"name":"@nauticana/sail","version":"1.1.3","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@1.1.3","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"c050c3903f0ee3a8f1d929cd4b928e7a64b8474f","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.1.3.tgz","fileCount":106,"integrity":"sha512-i7P/w9Hzldmh3uqQeOOOM/qWigY2Gx+KGIy7F6zQyzEWSlI2n+bD8GjGQdGaADHSHFogSjIqSOt8Cxb3UtzTFQ==","signatures":[{"sig":"MEUCIQCtDvTqY50B+Lt/4UQJnj8T+wCMfFHLZqBrkveRznwDnwIgPwl3zjFR1zzz70jOAozwJwiNxbxkjCb7Qmmw5JXu1Jw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.1.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":403690},"main":"src/index.ts","gitHead":"0965b9aac54309ba6450ed4152a7bae57b9fab3a","scripts":{"check":"npm run typecheck && npm run check:templates","typecheck":"tsc --noEmit","check:templates":"ngc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.13.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/compiler-cli":"^21.2.8","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_1.1.3_1782057598936_0.36973441693036","host":"s3://npm-registry-packages-npm-production"}},"1.1.4":{"name":"@nauticana/sail","version":"1.1.4","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@1.1.4","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"2926e2dc055abe7c12a2adb3ea6143dc8450836a","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.1.4.tgz","fileCount":106,"integrity":"sha512-LGDbtuS73NFM23U7Azu1EHmgdoZJPvETypUimLGW21kdGbySqRYUatZhwLDZwHGIpYLuq5ImFiJpP7BRVAvjuA==","signatures":[{"sig":"MEYCIQDFax3WXrxZEvOCdm1U2uJMIUMFZEzNbJ1QiYP8/UoFcgIhAMZj1soR9Hi7aikBqwP+ho8bBnc08GoW6I2jOfdM5XQg","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.1.4","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":404961},"main":"src/index.ts","gitHead":"0efaa3efc68407a860841cc3bee5a83e55170d2a","scripts":{"check":"npm run typecheck && npm run check:templates","typecheck":"tsc --noEmit","check:templates":"ngc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.13.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.17.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/compiler-cli":"^21.2.8","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_1.1.4_1782537263321_0.13695121427503554","host":"s3://npm-registry-packages-npm-production"}},"1.1.5":{"name":"@nauticana/sail","version":"1.1.5","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@1.1.5","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"f09c8773ee078cd7c41ab6030f7955eab903b18a","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.1.5.tgz","fileCount":106,"integrity":"sha512-Bt/DkpRVVJeze68EnLsdi1b90tvdU2RD+tEdLOp6j+gLqN/90eXamxZHbdaiJ0F5diJIHtceOBlXWEFDb94t6w==","signatures":[{"sig":"MEUCIFHsP58nGTudUm8kGl3DMTrJVBwB1/cXu3dS9BtYOi37AiEArYNP2Jw/aV0iTj7hc29sEVeXECL/58MTc01AvbeCB8g=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.1.5","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":405613},"main":"src/index.ts","gitHead":"95a004bca69589c51b0902fe9ac6f79eb90711ee","scripts":{"check":"npm run typecheck && npm run check:templates","typecheck":"tsc --noEmit","check:templates":"ngc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.13.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.17.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/compiler-cli":"^21.2.8","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_1.1.5_1782686780443_0.2618089550651388","host":"s3://npm-registry-packages-npm-production"}},"1.1.6":{"name":"@nauticana/sail","version":"1.1.6","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@1.1.6","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"1e79331941eaebca226de06ee41c4eea1cbac23a","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.1.6.tgz","fileCount":106,"integrity":"sha512-uvotkL6ysZSwtJ0+FdritS5HB/px9XSe5FbhWl4NMNB//1Qcgv+M2u3f8auMOR2yKzd/meeTrp6/ht2IINJAIA==","signatures":[{"sig":"MEYCIQDnymS07CbPs8sg2Vh3JDlUycdf1hYOycoPYwufU7/cCgIhAL4Shc7gHTNwnqYepnwGFtjpvOfZmWDdBVq15oWv0alD","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.1.6","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":407097},"main":"src/index.ts","gitHead":"55e55819c77fad9baae5673c8b0ced995929bdf1","scripts":{"check":"npm run typecheck && npm run check:templates","typecheck":"tsc --noEmit","check:templates":"ngc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.13.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.17.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/compiler-cli":"^21.2.8","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_1.1.6_1782764149081_0.8647636444799254","host":"s3://npm-registry-packages-npm-production"}},"1.1.7":{"name":"@nauticana/sail","version":"1.1.7","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@1.1.7","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"644d58b9d10a825c41c37e6748470653abfa7db3","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.1.7.tgz","fileCount":119,"integrity":"sha512-qIOqdSS6ApbPmRvJucgAQ4SCJ+JfTbBn6um5KmxrCWo2N1Wn9vOzeLcZfoL77/yVHGz9LpVn9a4A05D3evw5EA==","signatures":[{"sig":"MEUCIQCxuxrzvgUp9nXsGeYPFH5gjfwuvzkh2Hn4dv9DXIlYOgIgNPN+SjSMtvy/f7ccdmcXHY9i+bNiEBBXfZUvxJ7MItc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.1.7","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":424260},"main":"src/index.ts","gitHead":"66068f01b605518728c0957a255e65cd024aec0e","scripts":{"check":"npm run typecheck && npm run check:templates","typecheck":"tsc --noEmit","check:templates":"ngc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.13.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.17.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/compiler-cli":"^21.2.8","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_1.1.7_1782797131074_0.7250128983153104","host":"s3://npm-registry-packages-npm-production"}},"1.1.8":{"name":"@nauticana/sail","version":"1.1.8","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@1.1.8","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"f08d97ba2ff67637149b57e5a464e4753dcf35d4","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.1.8.tgz","fileCount":119,"integrity":"sha512-+C1lzYSlZ3NpNbQdABhI0ys1vFZnNN2QNIA80yh2Rc1wpzvjkN8wieX8IQXfPY0TLE+6M0aQWpkf/fZ2ltRE+g==","signatures":[{"sig":"MEUCIQCYmJbF6MxvVNmd67inVZA9NLouAReMOPblS1omkAkYOwIgco/hB1NlBo0xe0MnQdhq95y1z118BQosKA8YvNurkDY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.1.8","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":428833},"main":"src/index.ts","gitHead":"8d3a8ad1c2fd4a959fb452cb2a9ae9198e3b9fc8","scripts":{"check":"npm run typecheck && npm run check:templates","typecheck":"tsc --noEmit","check:templates":"ngc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.13.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.17.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/compiler-cli":"^21.2.8","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_1.1.8_1782910217427_0.7169658878010226","host":"s3://npm-registry-packages-npm-production"}},"1.1.9":{"name":"@nauticana/sail","version":"1.1.9","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@1.1.9","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"24746d0cd36c3009567f995a9d398b6c9dce8e13","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.1.9.tgz","fileCount":123,"integrity":"sha512-AJ9vDta6cdrLfsHkZ5Hnrp6GmFLbSxxbwUZB/djqG9yWmcPiL9BqYdIpkCZPHTw2yyZMX/rZd97ee1zqJYYHKQ==","signatures":[{"sig":"MEQCIGes5htOorqRwvznuyyHdJOvbA/YQ962SDmwPboFm9h+AiBIMKQmJpL6K+keaLpLAadv11LxKco1TZ1AXp00DiM/Lg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.1.9","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":447080},"main":"src/index.ts","gitHead":"b92fa9ef617183b891530f75083a9fb6d33bec68","scripts":{"check":"npm run typecheck && npm run check:templates","typecheck":"tsc --noEmit","check:templates":"ngc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.16.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/compiler-cli":"^21.2.8","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_1.1.9_1783175069345_0.32009008746905243","host":"s3://npm-registry-packages-npm-production"}},"1.1.10":{"name":"@nauticana/sail","version":"1.1.10","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@1.1.10","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"7bff06021fc395c7fff1a0e75392c2b610ec662e","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.1.10.tgz","fileCount":124,"integrity":"sha512-RIfUX9RXEATor0UaUl3dkQIPYo0uM/bDQ+/++NlQmKLqHR8R77wZ5JvaUwd7EreR+eyQaQChk+dU2lKMZG+J8g==","signatures":[{"sig":"MEQCIHdUEYvao2VzNA7/LyGKGFsp0R19a2pVkAajGZcLVJpTAiBD3pYDgPqEsIizgJnXx4yOo9K3/w6/ekDVcdD9Ok3T3g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.1.10","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":475026},"main":"src/index.ts","gitHead":"faa82f04c1511dbd25ac010911dcbf3d370e714f","scripts":{"check":"npm run typecheck && npm run check:templates","typecheck":"tsc --noEmit","check:templates":"ngc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.16.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.18.0","dependencies":{"qrcode":"^1.5.4","@types/qrcode":"^1.5.6"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/compiler-cli":"^21.2.8","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_1.1.10_1783456066874_0.1137556192098157","host":"s3://npm-registry-packages-npm-production"}},"1.1.11":{"name":"@nauticana/sail","version":"1.1.11","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@1.1.11","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"27856d943831f658045b78c10f3f410dc6343686","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.1.11.tgz","fileCount":126,"integrity":"sha512-RSuAdmHC0zis9+5I+BJmswM3KdmndshOaWm3QewckbMtDygC3k/vsHdK9ttF9+OooqUglf+4/1JZ4+u3miTMmw==","signatures":[{"sig":"MEUCIQCeeMIKlD6AuW+5Ifc1MXXaIuB8vtbk56YbULmga37MaQIga8rCL7w7mVdlJlQc4jxQRdAPiqlyVPvcISjHRKv+Uxg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.1.11","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":477938},"main":"src/index.ts","gitHead":"4b4a76f892c1930a8d1998ddccb81696930a6893","scripts":{"check":"npm run typecheck && npm run check:templates","typecheck":"tsc --noEmit","check:templates":"ngc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.16.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.18.0","dependencies":{"qrcode":"^1.5.4","@types/qrcode":"^1.5.6"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/compiler-cli":"^21.2.8","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_1.1.11_1783725423502_0.5521958565605762","host":"s3://npm-registry-packages-npm-production"}},"1.1.12":{"name":"@nauticana/sail","version":"1.1.12","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@1.1.12","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"4597cc92c4bfb3c95d871a686497d15ff6731eca","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.1.12.tgz","fileCount":127,"integrity":"sha512-E2A2372/YHdE3lJxhf4iwvsRcX1F3noN7o0ACbijCdyoaDcKigpmB0a0uoVjQ/IzHcauE94v4OROL+/fz4WTRQ==","signatures":[{"sig":"MEQCIDOcoOJe3PUrF5P/pCPRFRcIdm+jwGMMyjpX4EWD606mAiAUFKfFx2HJ+UTKA4/nKiKTPkWaKapDWuoEfqlIsyGn0g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.1.12","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":483472},"main":"src/index.ts","gitHead":"26d6a8008a9d84afcefe02c9d75b6ad127e2e35e","scripts":{"check":"npm run typecheck && npm run check:templates","typecheck":"tsc --noEmit","check:templates":"ngc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.16.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.18.0","dependencies":{"qrcode":"^1.5.4","@types/qrcode":"^1.5.6"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/compiler-cli":"^21.2.8","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_1.1.12_1784073408953_0.8406826160710312","host":"s3://npm-registry-packages-npm-production"}},"1.1.13":{"name":"@nauticana/sail","version":"1.1.13","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@1.1.13","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"7e95154a779a2fe4799f6a77a5500daa6d9b36f0","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.1.13.tgz","fileCount":127,"integrity":"sha512-vJsBDcuSjbALSuDpRgjHp2b+4LERRdmqHFAHF4UuCtXl0i4Hncy+rALsYblD95HW38E5d0IT40dLSuVT1Gvh1Q==","signatures":[{"sig":"MEYCIQCC2MndpUjF4f7JUXZMtylvq2uR5SMFhvDNMZRJCxz82wIhAPMzzw2ODIYg7T092N9OhCwwohjh9dHsYIt2RMzn7yHX","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.1.13","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":487518},"main":"src/index.ts","gitHead":"af88474f89acc6ee29e4940c5c667583eeb3d5ae","scripts":{"check":"npm run typecheck && npm run check:templates","typecheck":"tsc --noEmit","check:templates":"ngc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.16.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.18.0","dependencies":{"qrcode":"^1.5.4","@types/qrcode":"^1.5.6"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/compiler-cli":"^21.2.8","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_1.1.13_1785279496683_0.5915318156434275","host":"s3://npm-registry-packages-npm-production"}},"1.1.14":{"name":"@nauticana/sail","version":"1.1.14","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@1.1.14","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"e805bfc3adfbe155a9544666530615ca1a381236","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.1.14.tgz","fileCount":143,"integrity":"sha512-QrmdDCTzGmAXPhVVRpf82J/E+bbVaxDW7I39x1/Nz4yZZNxGMaMuZXFpEXvgHaEj3P6pMlmQ+ZaBtFBxrIwE0A==","signatures":[{"sig":"MEQCIHXmTs2NuhBD/MJL0Hcz1zmwsB9dmWajSsmeNiqjETEEAiAQL1OhmpVUyRb7+igyqngzOZbFTnZmo/XZwzkDDTzwKQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.1.14","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":526700},"main":"src/index.ts","gitHead":"70deb9706d8c86cebbdbfcd82bf4f04c2a201baf","scripts":{"check":"npm run typecheck && npm run check:templates","typecheck":"tsc --noEmit","check:templates":"ngc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.16.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.18.0","dependencies":{"qrcode":"^1.5.4","@types/qrcode":"^1.5.6"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/compiler-cli":"^21.2.8","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_1.1.14_1785380808621_0.7595341072860953","host":"s3://npm-registry-packages-npm-production"}},"1.1.16":{"name":"@nauticana/sail","version":"1.1.16","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@1.1.16","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"4032a1f9137d38e28151a456b337e403d9c8971a","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.1.16.tgz","fileCount":143,"integrity":"sha512-CpL4dLwzb3azetOdX6YapQJClAiuH7v0gI69ebskaq3PLKqwGtjOgAZeOAmohj4bpPKOPqAEBmH4jVqUusGSTg==","signatures":[{"sig":"MEYCIQDOkwZLthE13VJlC/VQEFEY7lbsdls+knTHEbBCCOu7MgIhAJ/0Vg8d70zHC1vCs5xyhp2saOKcfTIiv/IntUBuQNdH","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.1.16","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":527896},"main":"src/index.ts","gitHead":"5af35ab7643d093ef63ab54aea3748ccf70c81ab","scripts":{"check":"npm run typecheck && npm run check:templates","typecheck":"tsc --noEmit","check:templates":"ngc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.17.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.19.0","dependencies":{"qrcode":"^1.5.4","@types/qrcode":"^1.5.6"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/compiler-cli":"^21.2.8","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_1.1.16_1787033027031_0.7940998305714013","host":"s3://npm-registry-packages-npm-production"}},"1.1.17":{"name":"@nauticana/sail","version":"1.1.17","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@1.1.17","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"0db2ac3e70c296393e59d4039653c5f856728bde","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.1.17.tgz","fileCount":143,"integrity":"sha512-uKl2tOtvdya0vQbVbs5lXdz8viRSj/4bDLLTA6hxSFXf+6BBXOpEAOIVYa9iGJEU3J4cBw1Dhho8/aQpbfdqXw==","signatures":[{"sig":"MEUCICQfF2U0VZZJmusq4Vo3TDHn0dnuXQqYxZF5cikaH1N+AiEAitu0wMp9tdEWJcTLU3Ci6NhnOQQgdMv7UDuyxb1QgnU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.1.17","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":530829},"main":"src/index.ts","gitHead":"67102050baa9347e1f09e5dc336fb97ad9a8cbb9","scripts":{"check":"npm run typecheck && npm run check:templates","typecheck":"tsc --noEmit","check:templates":"ngc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.17.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.19.0","dependencies":{"qrcode":"^1.5.4","@types/qrcode":"^1.5.6"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/compiler-cli":"^21.2.8","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_1.1.17_1787706277331_0.15118951621462595","host":"s3://npm-registry-packages-npm-production"}},"1.1.18":{"name":"@nauticana/sail","version":"1.1.18","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@1.1.18","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"cb8f6ea95f4dfabb4583e21345d1f828cbdadf29","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.1.18.tgz","fileCount":144,"integrity":"sha512-Hpve1xHd8ZJebKtCtSgsCCCzLZul2TXRAueuPH1NnPB7aEEj+o4CeRMeaPMhrzYVm++FskxK5vr96V1zwO4V3Q==","signatures":[{"sig":"MEUCIQCIwHNiVVVcrfYxqXGBHN34niZilklQC+tqKeXomSbo5gIgLe82xBEf8MJaOyXHI68NPJedyBNqghONM9OC/5coiCs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQCIazqdW/o/9UIlf27aBfX7TQ50qBQ9dCGKLH8LsRQ0tgIhANK4q31UFaqez3Hiaf/gDdp9DadP4n6sgzohEQm/unRR","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.1.18","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":544328},"main":"src/index.ts","gitHead":"a163f932c89ecc0c4a0a42f5e3ac51531f21463a","scripts":{"check":"npm run typecheck && npm run check:templates","typecheck":"tsc --noEmit","check:templates":"ngc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.19.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.20.0","dependencies":{"qrcode":"^1.5.4","@types/qrcode":"^1.5.6"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/compiler-cli":"^21.2.8","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_1.1.18_1788998962333_0.5844980320278597","host":"s3://npm-registry-packages-npm-production"}},"1.1.19":{"name":"@nauticana/sail","version":"1.1.19","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@1.1.19","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"b78aa50e1a3c6f882b95cc977bd1c9ce5dcf5dd9","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.1.19.tgz","fileCount":150,"integrity":"sha512-3OK9JrgU/ulkV95Nwl3Oc2K8QeYDNDa0JIe/zXMFQQVHaHaTfhHucymGcRul0P88DZ7t0f7K/aFNbdoypzBRJg==","signatures":[{"sig":"MEQCICOw1iuO67gZnCXFjWHoa/PGnr1wL2zixUR823+Ak/uPAiA9Q1YeqzIfcIQXS2c0GtU8S5O8F579fGssHxO2C3PC7Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQDhDDlQ1tIf+nJCOUFd6+9oEkeZMD5q10byoWQed1j5qgIga6sdhE+PD8EMglk7JCJDZEq6PeJNpDq0kS/aznZ9+SU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.1.19","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":558192},"main":"src/index.ts","gitHead":"ae65c274540d4164dc34d275b4e78c6b94121d4e","scripts":{"check":"npm run typecheck && npm run check:templates","typecheck":"tsc --noEmit","check:templates":"ngc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.19.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"_nodeVersion":"24.20.0","dependencies":{"qrcode":"^1.5.4","@types/qrcode":"^1.5.6"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/compiler-cli":"^21.2.8","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_1.1.19_1789828510899_0.28229097188994223","host":"s3://npm-registry-packages-npm-production"}},"1.1.20":{"name":"@nauticana/sail","version":"1.1.20","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@1.1.20","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"787585eebec8c6c6a9192eee3c6ebe4fe53f266b","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.1.20.tgz","fileCount":171,"integrity":"sha512-H2Pyp6qJOoIi4DrFbx3VNoQ+GqLH2jDWUEc9wXvZO6vHqjIQYYCF2guVUXRjBVu/t9H9rXgKgXxjY82/TjTpJg==","signatures":[{"sig":"MEQCIDAdqBNwNKGsCReLAhl47LebXMNCSnCHtYmQJxchiLNMAiBLePsqRQrglqXWHgycvxkjR2yoH/LE7z4RaLW1iyOdMw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQCn0BM38QEzD2HHF73egsqakgtxq4JhIf+/XKzQJfZmlQIhAJESQZ2hF/nHCozHiRPycfHwz8AuQYc4RBGswlCq04t3","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.1.20","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":610704},"main":"src/index.ts","exports":{".":"./src/index.ts","./agent":"./src/agent/index.ts","./package.json":"./package.json"},"gitHead":"84efbf927108f05aab09156d435e1c26514b1bc3","scripts":{"check":"npm run typecheck && npm run check:templates","typecheck":"tsc --noEmit","check:templates":"ngc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.19.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"sideEffects":["./src/model/decorator.ts"],"_nodeVersion":"24.20.0","dependencies":{"qrcode":"^1.5.4","@types/qrcode":"^1.5.6"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/compiler-cli":"^21.2.8","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_1.1.20_1789939055106_0.993053462137012","host":"s3://npm-registry-packages-npm-production"}},"1.1.21":{"name":"@nauticana/sail","version":"1.1.21","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@1.1.21","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"ea161b2c209d9bce1d4ca05c1790b3e00a68e7d6","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.1.21.tgz","fileCount":171,"integrity":"sha512-1vM72Jqtn3Kke3KwAkg+QEeoiFFpYbGrKB9/w520ojIunvosPi2792MLEDxNGqexs1znBd7bX1dyH097QMymsg==","signatures":[{"sig":"MEUCIQC8/xYfntNghvJFL5NxweYbamIvAgz66kpNHuQJFj9AigIgE6ed3Qel2Kd1oe1MKFomtiyF/EOW/A2e9vGMsc1CDBc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIDzbKvKl6vPupcoZWYD8nTuu8izHbLYDEWdjOJhlncjcAiBrdZ5JT5jTHJGamT1EkHxn4dPJePQf17nY4KHtA+5QTQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.1.21","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":611426},"main":"src/index.ts","exports":{".":"./src/index.ts","./agent":"./src/agent/index.ts","./package.json":"./package.json"},"gitHead":"6b4902160e0b0e407fa3fb1fbebec1eca793e18b","scripts":{"check":"npm run typecheck && npm run check:templates","typecheck":"tsc --noEmit","check:templates":"ngc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.19.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"sideEffects":["./src/model/decorator.ts"],"_nodeVersion":"24.20.0","dependencies":{"qrcode":"^1.5.4","@types/qrcode":"^1.5.6"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/compiler-cli":"^21.2.8","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_1.1.21_1789953134581_0.7070965828590634","host":"s3://npm-registry-packages-npm-production"}},"1.1.22":{"name":"@nauticana/sail","version":"1.1.22","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@1.1.22","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"df7e6bc7d07a6f2d72bd7809c95a571796354d53","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.1.22.tgz","fileCount":177,"integrity":"sha512-w7DKaj/2lCXKQX0xtTbiVAwwUyPRV8vn8rnUpph6gXtx6//ySMK7e9i6fHem3HpRR41EUnjL+VBRAEhMkepd3w==","signatures":[{"sig":"MEUCIQCqI2SFrfQgaLUNeLRb4/IEOeRF3Y8+OLjUV5BORCP7kQIgJ7WHS9CooUPPlB2Oned1mAIaK1m3+N/HPLsqAW9UBcU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCICuzleJY/RMnOGZxq6/puG/23hY4AC8EAcYVxIWbNiayAiAF7vyheGROVHBsFNUWl6VkE4zvXNpnZ4Wv96Ek+2Nbhg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.1.22","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":634608},"main":"src/index.ts","exports":{".":"./src/index.ts","./agent":"./src/agent/index.ts","./package.json":"./package.json"},"gitHead":"28b59b0c48fa91145d6c16b576c235849ade92be","scripts":{"check":"npm run typecheck && npm run check:templates","typecheck":"tsc --noEmit","check:templates":"ngc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.19.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"sideEffects":["./src/model/decorator.ts"],"_nodeVersion":"24.20.0","dependencies":{"qrcode":"^1.5.4","@types/qrcode":"^1.5.6"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/compiler-cli":"^21.2.8","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_1.1.22_1789962321550_0.23300695147806616","host":"s3://npm-registry-packages-npm-production"}},"1.1.23":{"name":"@nauticana/sail","version":"1.1.23","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@1.1.23","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"750390bcf579e8acb0a60f7d1af4e3a8d99c2262","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.1.23.tgz","fileCount":181,"integrity":"sha512-lLGVztc3IKl1pO7QLtFltyF8mj8RRGIisbtwsnjhpjH4//4EzHYNpVzx59TUkhFoNV+OJhBr2z68tUWI10AWqQ==","signatures":[{"sig":"MEQCIG99zR9kbsOeijSZe8UQ/F7rXeGVvGPwnDS89ebo4UIfAiA9Fyylo8qmkBxnK1a6iYTeBv6AVz19juQGqXQh75thww==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIDHQYtgSN25zS6Af4fG+2f3t/X7ktLzjorTQBkJZz65gAiB+mxCS8uSxRDOeeefJkZoZEBFFYuAXgSuG9CDbW/A5Yg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.1.23","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":647209},"main":"src/index.ts","exports":{".":"./src/index.ts","./agent":"./src/agent/index.ts","./package.json":"./package.json"},"gitHead":"4bf0387ebc08fc2eb87ac87837a2540c784b9159","scripts":{"check":"npm run typecheck && npm run check:templates","typecheck":"tsc --noEmit","check:templates":"ngc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.19.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"sideEffects":["./src/model/decorator.ts"],"_nodeVersion":"24.20.0","dependencies":{"qrcode":"^1.5.4","@types/qrcode":"^1.5.6"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/compiler-cli":"^21.2.8","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_1.1.23_1789996116722_0.07929723633456609","host":"s3://npm-registry-packages-npm-production"}},"1.1.24":{"name":"@nauticana/sail","version":"1.1.24","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@1.1.24","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"73a217648e798dae76b3b41c0405b66f668fbbc5","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.1.24.tgz","fileCount":181,"integrity":"sha512-U8io40iY2hVc7ZmkBGCkCmwzLxP+YiF7IlFRqpG607dcyVbMOZN0VM8TPhYnTtXHZQyKtj2qR57+4a3T6Ti6wQ==","signatures":[{"sig":"MEUCIFxtVlpVU30+ZWyA1voUL/XcbtJSQBEe6e7oEH4hbkA5AiEAiPPWvdAG8qX885LvynVpLRgG03XBYFek+g68LpdB/Dc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIGgRCgsXBWpTtpBkhEfAG970nCOBetuXFmkfDHX85A90AiEA3krcxss9X4QsRvzubJm0AZNKxbCChdBjrNzjpWHCL/U=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.1.24","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":649750},"main":"src/index.ts","exports":{".":"./src/index.ts","./agent":"./src/agent/index.ts","./package.json":"./package.json"},"gitHead":"a4e2ee18fec7ae0ec451ae99a6ca6971cb504b50","scripts":{"check":"npm run typecheck && npm run check:templates","typecheck":"tsc --noEmit","check:templates":"ngc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.19.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"sideEffects":["./src/model/decorator.ts"],"_nodeVersion":"24.20.0","dependencies":{"qrcode":"^1.5.4","@types/qrcode":"^1.5.6"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/compiler-cli":"^21.2.8","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_1.1.24_1790022756366_0.8144998398599861","host":"s3://npm-registry-packages-npm-production"}},"1.1.25":{"name":"@nauticana/sail","version":"1.1.25","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"author":{"name":"Nauticana"},"license":"Apache-2.0","_id":"@nauticana/sail@1.1.25","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"homepage":"https://github.com/nauticana/sail#readme","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"c595c82a9bf87100f77fd3cf1e391b308e7c2689","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.1.25.tgz","fileCount":185,"integrity":"sha512-N/gZthtgUMBKp7WFL7SjfJxagDan8uDVqO+EJc2M+KdLwg+4G0WyOdMbjdkmah4P/AOKZXeNeJFwjTdbaLHicg==","signatures":[{"sig":"MEYCIQCFnIgd45Fbs1Xvrmq4iWGA8vpup8ZMPK0BWkmwRk20hgIhANgbaw9ADvZvV6nyFUgWqwVOuoXQT7JyKPMXiH0dDWDT","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIGErrS+z2XFPTJt11eJzFnwakf+WuW8hCQu3hhB7Kq2zAiA8b+lRfTd7Sk+3tzbD2n6p4wdQKqcXkaujWfqfkYpX1w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.1.25","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":660667},"main":"src/index.ts","exports":{".":"./src/index.ts","./agent":"./src/agent/index.ts","./package.json":"./package.json"},"gitHead":"e18e51228f657d34f53e267b0ed2d6c92e323798","scripts":{"check":"npm run typecheck && npm run check:templates","typecheck":"tsc --noEmit","check:templates":"ngc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.19.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"sideEffects":["./src/model/decorator.ts"],"_nodeVersion":"24.21.0","dependencies":{"qrcode":"^1.5.4","@types/qrcode":"^1.5.6"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/compiler-cli":"^21.2.8","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sail_1.1.25_1790317544309_0.1633755341638381","host":"s3://npm-registry-packages-npm-production"}},"1.1.26":{"_id":"@nauticana/sail@1.1.26","bugs":{"url":"https://github.com/nauticana/sail/issues"},"dist":{"shasum":"3ca46384db052e16d91922a58054db98e313c8cc","tarball":"https://registry.npmjs.org/@nauticana/sail/-/sail-1.1.26.tgz","fileCount":193,"integrity":"sha512-Ekuj6cXmJn0N2XHmste83poUbynIVePGFyvILdW3OreADFSHMeQqE8H7ahhnKk2lBQD4CRc75Hy+Gb6qe4Roiw==","signatures":[{"sig":"MEYCIQC0raDbM0zuP17J94Rv3S6u1I/mQw2bDMFhi5/TyrpmYwIhAIiW0YiITMSUYUcUC7cecHhoMPyrGbq8ocniI37QXnCK","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQD74uV9+CDMRaqdhYbU7Mj1zBM/ftRvNBgDIZDikE0PtwIgCC+/Sd2Has/DA/jX7kXu1IWR9INec4dpoOiZFInOBu0="}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nauticana%2fsail@1.1.26","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":687118},"main":"src/index.ts","name":"@nauticana/sail","author":{"name":"Nauticana"},"exports":{".":"./src/index.ts","./agent":"./src/agent/index.ts","./package.json":"./package.json"},"gitHead":"d30fab2773d293cab3d3baf14d7c6bb04e8692ee","license":"Apache-2.0","scripts":{"check":"npm run typecheck && npm run check:templates","typecheck":"tsc --noEmit","check:templates":"ngc -p tsconfig.json"},"version":"1.1.26","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d8de0223-4c3d-47b0-b7b8-0875ea6a49bf"}},"homepage":"https://github.com/nauticana/sail#readme","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"_npmVersion":"11.19.0","description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","directories":{},"maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"sideEffects":["./src/model/decorator.ts"],"_nodeVersion":"24.21.0","dependencies":{"qrcode":"^1.5.4","@types/qrcode":"^1.5.6"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"~7.8.0","typescript":"~5.9.3","@angular/cdk":"^21.2.6","@angular/core":"^21.2.8","@angular/forms":"^21.2.8","@angular/common":"^21.2.8","@angular/router":"^21.2.8","class-validator":"^0.15.1","@angular/compiler":"^21.2.8","@angular/material":"^21.2.6","@angular/compiler-cli":"^21.2.8","@angular/platform-browser":"^21.2.8"},"peerDependencies":{"rxjs":"~7.8.0","@angular/cdk":"^21.0.0","@angular/core":"^21.0.0","@angular/forms":"^21.0.0","@angular/common":"^21.0.0","@angular/router":"^21.0.0","class-validator":"^0.15.1","@angular/material":"^21.0.0","@angular/platform-browser":"^21.0.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sail_1.1.26_1790574401604_0.4174015412290375"}}},"time":{"created":"2026-04-30T05:08:43.988Z","modified":"2026-09-28T05:46:42.032Z","0.5.0":"2026-04-30T05:08:44.267Z","0.5.1":"2026-05-03T15:59:55.853Z","0.5.2":"2026-05-04T18:35:50.869Z","0.5.3":"2026-05-04T22:21:56.789Z","0.5.4":"2026-05-05T05:30:43.616Z","0.5.5":"2026-05-05T06:56:39.730Z","0.5.6":"2026-05-10T03:19:18.158Z","0.5.7":"2026-05-10T05:43:55.850Z","0.6.0":"2026-05-12T21:32:27.250Z","0.6.1":"2026-05-12T22:04:13.321Z","0.7.0":"2026-05-12T23:46:25.296Z","0.8.0":"2026-05-13T00:45:26.963Z","0.8.1":"2026-05-13T05:02:21.930Z","0.8.3":"2026-05-13T20:17:49.246Z","0.8.4":"2026-05-16T04:10:54.944Z","0.9.0":"2026-06-01T00:33:55.809Z","0.9.1":"2026-06-02T00:06:09.850Z","0.9.2":"2026-06-02T01:08:18.521Z","0.9.3":"2026-06-05T19:07:41.603Z","0.9.4":"2026-06-06T07:41:27.724Z","0.9.5":"2026-06-06T19:29:45.270Z","0.9.6":"2026-06-07T07:25:00.823Z","1.0.0":"2026-06-08T05:35:12.133Z","1.0.1":"2026-06-08T20:35:09.384Z","1.0.2":"2026-06-08T23:53:10.144Z","1.0.3":"2026-06-09T05:55:41.869Z","1.0.7":"2026-06-13T23:26:44.832Z","1.0.8":"2026-06-15T05:49:20.638Z","1.0.9":"2026-06-15T15:12:00.985Z","1.1.0":"2026-06-18T19:34:03.042Z","1.1.1":"2026-06-20T02:54:22.550Z","1.1.2":"2026-06-21T07:16:07.787Z","1.1.3":"2026-06-21T15:59:59.096Z","1.1.4":"2026-06-27T05:14:23.462Z","1.1.5":"2026-06-28T22:46:20.575Z","1.1.6":"2026-06-29T20:15:49.245Z","1.1.7":"2026-06-30T05:25:31.229Z","1.1.8":"2026-07-01T12:50:17.571Z","1.1.9":"2026-07-04T14:24:29.486Z","1.1.10":"2026-07-07T20:27:47.068Z","1.1.11":"2026-07-10T23:17:03.657Z","1.1.12":"2026-07-14T23:56:49.118Z","1.1.13":"2026-07-28T22:58:16.829Z","1.1.14":"2026-07-30T03:06:48.774Z","1.1.16":"2026-08-18T06:03:47.239Z","1.1.17":"2026-08-26T01:04:37.605Z","1.1.18":"2026-09-10T00:09:22.473Z","1.1.19":"2026-09-19T14:35:10.987Z","1.1.20":"2026-09-20T21:17:35.216Z","1.1.21":"2026-09-21T01:12:14.686Z","1.1.22":"2026-09-21T03:45:21.650Z","1.1.23":"2026-09-21T13:08:36.847Z","1.1.24":"2026-09-21T20:32:36.455Z","1.1.25":"2026-09-25T06:25:44.399Z","1.1.26":"2026-09-28T05:46:41.705Z"},"bugs":{"url":"https://github.com/nauticana/sail/issues"},"author":{"name":"Nauticana"},"license":"Apache-2.0","homepage":"https://github.com/nauticana/sail#readme","keywords":["angular","angular-library","crud","admin","keel","nauticana","metadata-driven","material","auth","2fa","otp"],"repository":{"url":"git+https://github.com/nauticana/sail.git","type":"git"},"description":"Metadata-driven Angular component library for CRUD admin frontends backed by the keel Go backend. Tables, forms, navigation, OTP/2FA/social auth, billing, payout onboarding.","maintainers":[{"name":"nauticana","email":"nauticana@daxoom.com"}],"readme":"# @nauticana/sail\n\nA shared Angular component library for building CRUD-based admin frontends. Provides table management, form handling, navigation, authentication, two-factor authentication, and trusted device management — all driven by metadata from a [keel](https://github.com/nauticana/keel) Go backend.\n\n> **Compatibility:** sail and keel are versioned in lock-step. The current line is **sail v1.1.x ↔ keel v1.2.x**; sail v1.1.18 adopts keel v1.2.58 (refresh-token rotation, `/public/logout`, setup intents, the realtime hub), the agency components in sail v1.1.14 require keel v1.2.41 (sail v1.1.9 needs keel v1.2.16 for the OAuth-connect layer). Earlier lines: **sail v0.5.x ↔ keel v0.5.x**, **sail v0.6.x / v0.7.x ↔ keel v0.7.x**, **sail v0.8.x ↔ keel v0.8.x**, **sail v0.9.x ↔ keel v0.9.x**. Newer sail releases extend the contract — older keel servers reject unknown endpoints with HTTP 404 / 400. The v0.8.x line additionally ships the `table_action` framework (per-table custom buttons surfaced in `TableList` / `TableSearch` / `TableEdit` / `TableDetail`); see the [Migrating to v0.7.0 §5 — TableAction](#migrating-to-v070--payout-user-payment-methods-table-actions) section for the seed shape (basis `table_action` + `authorization_object` + `authorization_object_action` rows) and the [keel/README Table Actions](https://github.com/nauticana/keel#table-actions) section for backend wiring via `handler.WrapTableAction`.\n\n**Recent additions:** `BaseAuthService.acceptToken(jwt)` — adopt an externally-minted JWT (registration / SSO-handoff flows) and run the full post-login sequence (store under the canonical `jwt` key, load appdata, init routes); apps must use this instead of writing `localStorage` directly. `BaseRestService.analytic<T>(endpoint, params?)` — GET a keel `analytic/<endpoint>` report and return its rows. `passwordPolicyValidator` + `BaseAuthService.ensurePasswordPolicy()` — validate passwords against keel's policy (via `SailGuiConfig.passwordPolicyUrl`); see Configuration reference.\n\n> **v1.1.10 is a breaking release.** The base classes migrated to signals (`records()`, `editableRecord()`, `isNew()` …), `login()`/`loginWithGoogle()` now return Observables, CRUD errors are typed `SailApiError`, `BaseView` split into read-only `BaseView` + `AbstractEditableView`, the decorators are renamed `IsSailString`/`IsSailNumeric`, and `configureRestUrls()` is finally safe to call from a subclass constructor. The complete old→new mapping is machine-readable in [`migration_guide.json`](migration_guide.json). Consumers must fully migrate before pushing to test or prod.\n\n## What it provides\n\n| Category | Exports |\n|----------|---------|\n| **Table components** | `TableList`, `TableSearch`, `TableEdit`, `TableDetail`, `TableLookup`, `TableReport` |\n| **Form components** | `DynamicField`, `RecordForm`, `TableForm` |\n| **Navigation** | `Navigation` (sidenav + toolbar with menu, responsive) |\n| **Login** | `LoginComponent`, `RegisterComponent`, `ChpassComponent`, `ConfirmRegisterComponent`, `ConfirmChpassComponent` |\n| **Security** | `TwoFactorSetupComponent`, `TwoFactorVerifyComponent`, `TrustedDevicesComponent`, `AccountDeletionComponent` |\n| **Account** | `MyAccountComponent` (self-service hub), `ProfileEditorComponent` (name/locale immediate; email/phone verify-before-apply) |\n| **Auth** | `ConsentGateComponent`, `OtpInputComponent`, `SocialLoginComponent` |\n| **Billing** | `PlanSelectorComponent`, `PriceSelectorComponent`, `CheckoutButtonComponent`, `PaymentMethodsComponent`, `PortalButtonComponent`, `UsageMeterComponent`, `StatusChipComponent`, `TrialBannerComponent`, `SeatSelectorComponent`, `DunningBannerComponent` |\n| **Dashboard** | `DashboardShellComponent`, `DataCardComponent`, `StatTileComponent`, `LockedOverlayComponent`, `ActionCenterComponent`, `EntitySelectorComponent`, `VerificationFlowComponent` |\n| **Payout** | `PayoutProviderOnboardingComponent`, `PayoutBankInfoFormComponent` |\n| **Agency** | `AgencyClientsComponent`, `AgencyStatusBannerComponent`, `AgencyAcceptComponent`, `AgencyEarningsSummaryComponent`, `CommissionLedgerComponent`, `AgencyPayoutHistoryComponent`, `AgencyPayoutProfileComponent` |\n| **Notifications** | `NotificationCenterComponent`, `NotificationInboxService` |\n| **Documents** | `DocumentUploadComponent`, `PartnerDocumentsComponent`, `DocumentReviewQueueComponent`, `PartnerDocumentService` |\n| **Payments / SCA** | `UserPaymentMethodsComponent`, `ScaConfirmComponent`, `ScaConfirmer` (port), `SCA_CONFIRMER` (token) |\n| **Services** | `BaseAuthService` (OTP / social / push / deleteAccount / logoutEverywhere / profile: `getProfile`, `updateProfile`, `request`+`confirmEmailChange`, `request`+`confirmPhoneChange`), `BillingService`, `AgencyService`, `BackendService`, `PayoutService`, `UserPaymentMethodService`, `PartnerDocumentService`, `NotificationInboxService`, `loadScript()`, `authInterceptor`, `apiResponseInterceptor` |\n| **Abstracts** | `BaseTable`, `BaseForm`, `BaseView`, `AbstractEditableView`, `BaseAsync`, `BaseRestService` |\n| **Config** | `SAIL_GUI_CONFIG`, `SailGuiConfig`, `configureRestUrls()` |\n| **Models** | `ApplicationData`, `TableDefinition`, `SiudAction`, `ApplicationMenu`, `ConstantValue`, `UserAccount`, `RestReport`, `ReportParam`, `TrustedDevice`, `PublicPlan`, `PlanPrice`, `PaymentMethod`, `Subscription`, `Invoice`, `CheckoutRequest`/`CheckoutResponse`, `PortalResponse`, `UsageMeter`, `ChargeResult`, `UserPaymentMethod`, `TableAction`, `TableActionParameter`, `ReusableAccount`, `PayoutOnboardingSession`, `BankInfoFormValue`, `CountryProfile`, `OtpRequest`/`OtpResponse`, `SignupConsent`, `ConsentState`, `ConsentOption`, `SocialProvider`, `PushPlatform`, `InboxMessage`/`InboxPage`, `PartnerDocument`/`DocumentUploadRequest`, 2FA types, etc. |\n| **Decorators** | `@IsSailString()`, `@IsSailNumeric()` (class-validator based) |\n| **Utils** | `titleCase()`, `fromPriceLabel()`, `formatMinorCurrency()` |\n\n## Quick start\n\n### 1. Install\n\nsail is published on the public npm registry — no `.npmrc` or registry override needed:\n\n```bash\nnpm install @nauticana/sail class-validator\n```\n\nThis adds the following to your `package.json`:\n\n```json\n\"dependencies\": {\n  \"@nauticana/sail\": \"^1.0.0\",\n  \"class-validator\": \"^0.15.1\"\n}\n```\n\n### 2. Configure tsconfig paths\n\nSince sail ships raw TypeScript source, you need a path mapping so the Angular compiler can resolve and compile it. Add to your `tsconfig.json`:\n\n```json\n\"paths\": {\n  \"@nauticana/sail\": [\"./node_modules/@nauticana/sail/src/index\"]\n}\n```\n\nApps that use the agent entry point (see [Agent UI](#agent-ui-v1120)) add a second mapping, `\"@nauticana/sail/agent\": [\"./node_modules/@nauticana/sail/src/agent/index\"]`. The package exposes only these two entry points; deep imports such as `@nauticana/sail/service/...` are not supported.\n\n> **Note:** If your tsconfig has `\"baseUrl\": \"src\"`, use `\"../node_modules/@nauticana/sail/src/index\"` instead (paths resolve relative to `baseUrl`).\n\nSuppress class-validator CommonJS warnings in `angular.json`:\n```json\n\"build\": {\n  \"options\": {\n    \"allowedCommonJsDependencies\": [\"class-validator\"]\n  }\n}\n```\n\n### 3. Create your AuthService\n\n```typescript\n// src/service/auth.service.ts\nimport { Injectable } from '@angular/core';\nimport { BaseAuthService, configureRestUrls } from '@nauticana/sail';\nimport { environment } from '../environment/environment';\n\n@Injectable({ providedIn: 'root' })\nexport class AuthService extends BaseAuthService {\n  constructor() {\n    super();\n    configureRestUrls(environment.httphost);\n  }\n\n  // Add project-specific auth methods here (e.g., loginWithGoogle override, OTP, etc.)\n}\n```\n\n### 4. Bootstrap your app\n\n```typescript\n// src/main.ts\nimport { bootstrapApplication } from '@angular/platform-browser';\nimport { provideZonelessChangeDetection } from '@angular/core';\nimport { provideRouter } from '@angular/router';\nimport { provideHttpClient, withInterceptors } from '@angular/common/http';\nimport { SAIL_GUI_CONFIG, BaseAuthService, authInterceptor, apiResponseInterceptor, TwoFactorVerifyComponent } from '@nauticana/sail';\nimport { AuthService } from './service/auth.service';\nimport { DashUser } from './component/dashboard/dash_user';\nimport { App } from './app/app';\n\nbootstrapApplication(App, {\n  providers: [\n    provideZonelessChangeDetection(),\n    provideHttpClient(withInterceptors([apiResponseInterceptor, authInterceptor])),\n    provideRouter([]),\n    { provide: BaseAuthService, useExisting: AuthService },\n    {\n      provide: SAIL_GUI_CONFIG,\n      useValue: {\n        opField: 'op_code',\n        hiddenFields: ['op_code', 'PartnerId'],\n        appTitle: 'My App',\n        appLogoUrl: 'logo.png',\n        dashboardComponent: DashUser,\n        publicRoutes: [\n          { path: 'login/local', loadComponent: () => import('@nauticana/sail').then(m => m.LoginComponent) },\n          { path: 'login/register', loadComponent: () => import('@nauticana/sail').then(m => m.RegisterComponent) },\n          { path: 'login/chpass', loadComponent: () => import('@nauticana/sail').then(m => m.ChpassComponent) },\n          { path: 'login/2fa', component: TwoFactorVerifyComponent },\n          { path: 'confirm/register', loadComponent: () => import('@nauticana/sail').then(m => m.ConfirmRegisterComponent) },\n          { path: 'confirm/password', loadComponent: () => import('@nauticana/sail').then(m => m.ConfirmChpassComponent) },\n        ],\n        publicRouteLinks: [\n          { label: 'Login', routerLink: '/login/local' },\n          { label: 'Register', routerLink: '/login/register' },\n        ],\n        // Shown in the toolbar before Logout when logged in. Mount the matching\n        // authenticated route to MyAccountComponent (its links expect\n        // /account/2fa, /account/devices, /account/delete, /login/chpass).\n        accountLink: { label: 'My Account', routerLink: '/account' },\n        loginFooterLinks: [\n          { label: 'Sign in with Google', routerLink: '/login/google' },\n        ],\n        // Map backend menu items to custom components\n        menuItemRouteOverrides: {\n          // 'external_connection': SocialConnectionComponent,\n          // 'analytic/*': TableReport,\n        },\n      },\n    },\n  ],\n});\n```\n\n> **Auth-loop breaker.** `authInterceptor` carries a built-in circuit breaker: after 5 `401`s on token-bearing keel API calls within 10s it opens for 30s and refuses those requests **locally** (never sent), so a stale/rejected session can't drive the app to hammer the API and the edge/CDN. Only `401` counts — a `403` is a legitimate permission denial, not a session failure. A later success **or accepting a new token** (login) closes it, so a freshly authenticated session is never blocked. No wiring needed beyond registering `authInterceptor`.\n\n> **Phone-number change (opt-in).** `ProfileEditorComponent` and `MyAccountComponent` gate phone change behind a `phoneChangeEnabled` input (default `false`, since it needs an SMS provider — keel returns 503 without `Notify`). Enable it once your backend has SMS wired: `<sail-my-account [phoneChangeEnabled]=\"true\" />` or `<sail-profile-editor [phoneChangeEnabled]=\"true\" />`.\n\n### 5. Create the root component\n\n```typescript\n// src/app/app.ts\nimport { Component, ChangeDetectionStrategy } from '@angular/core';\nimport { Navigation } from '@nauticana/sail';\n\n@Component({\n  selector: 'app-root',\n  changeDetection: ChangeDetectionStrategy.OnPush,\n  imports: [Navigation],\n  template: `<sail-navigation><span toolbar-title>My App</span></sail-navigation>`,\n})\nexport class App {}\n```\n\nPlace the application logo in the consumer's `public/` directory (for example,\n`public/logo.png`) and set the same public URL in `appLogoUrl`. Sail displays it\nin the sidenav toolbar as a link to `/`. When `appLogoUrl` is omitted, the link\nfalls back to `appTitle`, then to a home icon, so home navigation remains\navailable without requiring a library-owned brand asset. The consuming app may\nalso reuse that asset as its favicon:\n\n```html\n<link rel=\"icon\" type=\"image/png\" href=\"logo.png\">\n```\n\n### 6. Provide global styles\n\nAll sail components use `ViewEncapsulation.None` — they ship no CSS. Your project must provide a global stylesheet covering sail selectors.\n\n**Required structural styles** (without these, the sidenav collapses and gets cut off). Add to your `src/styles.css`:\n\n```css\n.sidenav-container { height: 100vh; }\n.sidenav { width: 250px; }\n```\n\nKey CSS classes used by components:\n\n```\n/* Layout */\n.auth-container, .auth-card, .auth-header, .auth-title, .auth-form,\n.auth-actions, .auth-footer, .auth-app-title, .auth-checkbox,\n.auth-section-label, .auth-instructions, .form-row, .register-card,\n.sail-navigation-home, .sail-navigation-logo, .sail-navigation-home-title\n\n/* Feedback */\n.auth-error, .auth-success, .geocode-status, .geocode-loading,\n.geocode-success, .geocode-error\n\n/* Tables */\n.edit-container, .actions-bar, .tab-content, .empty-state,\n.detail-actions, .search-actions, .select-btn, .form-container\n\n/* Navigation */\n.sidenav-container, .sidenav, .toolbar-spacer\n\n/* State classes */\n.deleted-record, .updated-record, .new-record\n\n/* Buttons (replace deprecated Material color attributes) */\n.primary, .accent, .warn, .current-device-badge\n\n/* Security */\n.twofactor-qr, .twofactor-backup, .backup-code-list,\n.trusted-devices-table\n```\n\n## How it works\n\nsail follows a **metadata-driven** architecture. On login, the backend returns `ApplicationData` containing:\n\n- **MainMenu** — menu structure with pages and permissions\n- **Permissions** — role-based access control entries\n- **TableDefinitions** — column metadata, types, validation rules, foreign keys\n- **Apis** — REST endpoint mappings per table\n- **ConstantCache / TableCache** — dropdown/lookup values\n\n`BaseAuthService.initRoutes()` dynamically builds Angular routes from this metadata. Each menu item automatically gets a `TableSearch` or `TableList` route with the correct API endpoint and table metadata. Custom components can override specific menu items via `menuItemRouteOverrides` in the config.\n\n## List pagination\n\nkeel REST list responses are paginated:\n\n```json\n{ \"items\": [...], \"limit\": 100, \"offset\": 0, \"total\": 12345 }\n```\n\n`BackendService.list<T>()` continues to return `Observable<T[]>` — sail unwraps `items` for you. Both list methods accept a typed `PageRequest` after the filter map. To access the metadata, use `listPaginated<T>()`:\n\n```typescript\nthis.backend.listPaginated<MyRow>('orders', { Status: 'open' }, {\n    limit: 50,\n    offset: 0,\n    orderBy: 'created_at DESC',\n})\n    .subscribe((page) => {\n      this.rows.set(page.items);\n      this.total.set(page.total);   // total rows matching the filter\n    });\n```\n\nDefault page size is 100, capped at 1000 server-side. Sail maps `limit`, `offset`, and `orderBy` to keel's `_limit`, `_offset`, and `_order` query controls. Existing callers that put those string controls in the filter map remain compatible; explicit `PageRequest` values take precedence.\n\n## Backend-driven constant captions\n\n`LabelService` loads one keel `constant_value` domain from the backend-provided `ApplicationData.ConstantCache` and caches its value-to-caption map. The domain is the backend `constant_id` (for example `ride_type`), not a locale: keel's constant catalogue does not contain a language column. It does not call generic `constant_value` CRUD, which is normally restricted to administrative roles.\n\n```typescript\nthis.labels.loadLabels('ride_type').subscribe(() => {\n  this.rideTypeCaption.set(this.labels.getLabel('ride_type', ride.type));\n});\n```\n\nConcurrent loads share one application-data subscription, completed domains stay cached, and application-data failures can be retried. `getLabel` falls back to the raw key; `requireLabel` throws instead, for values that must not render as a raw code. `options(domain)` returns every `{code, caption}` of a loaded domain, sorted by caption, for picklists.\n\n## Status-filtered API errors\n\nPass an optional status allowlist when backend detail is safe to show only for selected responses. Other HTTP statuses return the caller's generic fallback:\n\n```typescript\nerrorDetail(error, 'Could not save.', [400, 409]);\n```\n\n## Configuration reference\n\n```typescript\ninterface SailGuiConfig {\n  opField: string;                    // Operation field name (default: 'op_code')\n  hiddenFields: string[];             // Fields hidden from forms (default: ['op_code', 'PartnerId'])\n  appTitle?: string;                  // Shown on login pages\n  appLogoUrl?: string;                // Public logo URL used by the navigation home link\n  googleMapsApiKey?: string;          // For RegisterComponent geocoding\n  dashboardComponent?: Type<any>;     // Component for /dashboard route\n  publicRoutes?: Routes;              // Routes available before login\n  publicRouteLinks?: RouteLink[];     // Links shown in toolbar when logged out\n  loginFooterLinks?: RouteLink[];     // Extra links below login form\n  extraRoutes?: (data) => Routes;     // Dynamic routes from ApplicationData\n  menuItemRouteOverrides?: {          // Map RestUri to custom component\n    [restUriPattern: string]: Type<unknown>;  // Supports 'exact' and 'prefix/*'\n  };\n\n  // Social / consent / account-deletion config\n  googleClientId?: string;            // Google Identity Services client ID\n  appleServiceId?: string;            // Apple Services ID\n  appleRedirectUri?: string;          // Apple Sign-In redirect URI\n  privacyPolicyUrl?: string;          // Linked from ConsentGateComponent and the login footer\n  termsUrl?: string;                  // Linked from the SMS-consent disclosure and the login footer\n  defaultPolicyVersion?: string;      // Content hash of the deployed policy\n  defaultPolicyLanguage?: string;     // ISO 639-1 fallback language\n  accountDeletedRoute?: string;       // Route after account deletion (default '/login/local')\n  passwordPolicyUrl?: string;         // Public route serving keel's password policy (see below)\n}\n```\n\n### Password-policy validation\n\nSet `passwordPolicyUrl` to the app's public route for keel's `PublicHandler.GetPasswordPolicy`\n(e.g. `'/public/v1/auth/password/policy'`). `BaseAuthService.ensurePasswordPolicy()` fetches it\nonce into the `passwordRules` signal, and `passwordPolicyValidator(() => auth.passwordRules())`\nvalidates new-password inputs against the real policy before submit (`passwordPolicyHint(rules)`\nbuilds the matching hint text). Built into `chpass` / `confirm-chpass`; reuse in app signup forms.\nOmit the URL to skip client-side policy checks. The server stays the authoritative gate.\n\n## Backend endpoints (keel v1.0)\n\n| Endpoint | Purpose |\n|----------|---------|\n| `POST /public/login/local` | Username/password login with 2FA + trusted-device support |\n| `POST /public/login/google` | Gmail OAuth-code login (legacy; prefer `/public/login/social`) |\n| `POST /public/login/social` | ID-token social login (Google, Apple) |\n| `POST /public/otp/send` | Send OTP code to phone or email; returns opaque `otpToken` |\n| `POST /public/otp/verify` | Verify OTP code with `otpToken`, returns JWT |\n| `POST /public/otp/resend` | Re-issue OTP for an existing `otpToken` |\n| `POST /public/2fa/verify` | Login-time TOTP verification (uses `loginToken`) |\n| `POST /public/2fa/backup-verify` | Login-time backup-code verification |\n| `POST /public/token/refresh` | Rotate `{refreshToken}` → new `{token, refreshToken}`; 401 ends the session |\n| `POST /public/logout` | Revoke `{refreshToken}` (called by `BaseAuthService.logout()`) |\n| `GET /public/ws` | keel realtime hub handshake (`RealtimeService`; JWT via `?token=`) |\n| `GET /api/config/appdata` | Metadata (menus, permissions, table definitions) |\n| `POST/GET/DELETE /api/{version}/{table}/list\\|get\\|post\\|delete` | CRUD operations (paginated `list`) |\n| `POST /api/user/2fa/setup` | Generate TOTP secret, QR URI, and backup codes — **requires re-auth** |\n| `POST /api/user/2fa/verify` | Confirm 2FA setup by verifying TOTP code |\n| `POST /api/user/2fa/disable` | Disable 2FA — **requires password + current TOTP code** |\n| `GET /api/user/trusted-device/list` | List trusted devices |\n| `POST /api/user/trusted-device/revoke` | Revoke a trusted device |\n| `POST /api/user/logout-everywhere` | Sign out of all devices — **requires re-auth** |\n| `DELETE /api/user/account` | Soft-delete the caller's account — **requires re-auth** |\n| `GET /api/notifications` | Notification inbox page — `?before=<id>&limit=<n>`, newest first (keel v1.2.71) |\n| `POST /api/notifications/mark_read` | Mark one message read — `{\"id\": \"<id>\"}` |\n| `POST /api/notifications/mark_all_read` | Mark the caller's whole inbox read |\n| `POST /api/push/register` | Register an FCM / APNs token |\n| `POST /api/push/revoke` | Revoke an FCM / APNs token |\n| `POST /api/billing/checkout` | Create provider-hosted checkout session — **JWT-gated, allowlist-validated** |\n| `POST /api/billing/setup-intent` | Provider setup intent for on-device card capture (`BillingService.createSetupIntent()`) |\n| `GET /public/plans` | Subscription plan catalog (unauthenticated) |\n| `GET /api/billing/subscription` | Active subscription for the partner |\n| `POST /api/billing/subscription/cancel` | Cancel auto-renew |\n| `GET /api/billing/invoices` | Invoice history |\n| `GET /api/billing/payment-methods` | Saved payment methods |\n\nDevice registration happens within `/public/2fa/verify` when `trustDevice=true`. Since **keel v0.9 / sail v0.9.0**, the trusted-device credential is a server-minted `keel_td` cookie (HttpOnly + Secure + SameSite=Strict) — not a client-supplied fingerprint. sail sets `withCredentials: true` on the login and 2FA-verify calls so the cookie round-trips; see [Enabling 2FA → Cross-origin cookie requirement](#cross-origin-cookie-requirement) below.\n\n## Enabling 2FA in your project\n\nAdd the 2FA verification route to your `publicRoutes` config:\n```typescript\nimport { TwoFactorVerifyComponent, TwoFactorSetupComponent, TrustedDevicesComponent } from '@nauticana/sail';\n\n// In publicRoutes:\n{ path: 'login/2fa', component: TwoFactorVerifyComponent }\n\n// In extraRoutes or authenticated routes (optional — for user self-service):\n{ path: 'security/2fa', component: TwoFactorSetupComponent }\n{ path: 'security/devices', component: TrustedDevicesComponent }\n```\n\nThe login flow handles 2FA automatically: when the backend returns `twoFactorRequired: true`, sail redirects to `/login/2fa`. No other code changes needed.\n\n### Cross-origin cookie requirement\n\nThe \"trust this device\" feature (keel v0.9+) is backed by a server-set HttpOnly cookie named `keel_td`. The lifecycle is entirely server-driven:\n\n1. On `POST /public/2fa/verify` with `trustDevice: true`, keel mints a 32-byte secret, stores its SHA-256, and returns the raw secret to the browser **only** as a `Set-Cookie: keel_td=…` header (never in the JSON body).\n2. On the next `POST /public/login/local` (or `/public/login/gmail`), the browser sends the `keel_td` cookie back, keel hashes it, finds the matching row, and **skips the 2FA prompt**.\n\nFor the browser to store and resend that cookie, the requests must be credentialed. sail already sets `withCredentials: true` on `login()`, `loginWithGoogle()`, `verify2FALogin()`, and `verifyBackupCode()` — **you do not add this in your app code**. But the keel backend must permit credentialed CORS, or the browser drops the cookie and every login re-prompts for 2FA:\n\n- **Same-origin** deployments (SPA served from the same host as the API) work with no extra config — credentialed same-origin requests are always allowed.\n- **Cross-origin** deployments (SPA on a different host/port than the API) require the keel `HttpBackend` to set:\n  - `AllowCredentials: true` → emits `Access-Control-Allow-Credentials: true`\n  - `Origin` = the **exact** SPA origin (e.g. `https://app.example.com`). A wildcard `*` is rejected by the browser for credentialed responses — keel's CORS layer enforces this.\n\nIf \"trust this device\" appears to do nothing (user is 2FA-prompted on every login despite checking the box), the cause is almost always a missing `AllowCredentials` / wildcard-origin on the backend — open devtools and confirm the `keel_td` cookie is actually set after a successful verify.\n\n### Session token storage\n\nThe session JWT, the refresh token, and the short-lived `loginToken` are kept in `localStorage` (the trusted-device secret is the only HttpOnly cookie). This is a deliberate trade-off for a token-based SPA, but it means any XSS in the consuming app can read the session token. Harden accordingly: ship a strict `Content-Security-Policy`, keep third-party script surface minimal, and prefer short JWT lifetimes on the keel side — refresh rotation makes short lifetimes free for the user.\n\n### Refresh-token rotation\n\nEvery keel login response (keel v1.2.57+) carries `refreshToken` beside `token`; `completeLogin` stores both. When an authenticated call answers 401, `authInterceptor` calls `BaseAuthService.refreshSession()` — one shared `POST /public/token/refresh` per burst — stores the rotated pair and replays the request with the new JWT. A 401 from the refresh itself (revoked, expired, already rotated) clears the session and lands on `login?sessionExpired=true`; any other refresh failure keeps the session and lets the 401 count toward the circuit breaker. `logout()` posts the refresh token to `/public/logout` before clearing local state. `acceptToken(token, refreshToken?)` accepts the pair for handoff flows. No wiring beyond registering `authInterceptor`.\n\n### Realtime\n\n`RealtimeService` (root-provided) is the client for keel's `realtime.Hub`. `connect()` opens `RestURL.realtimeURL` (`/public/ws`) on the configured backend host with the stored JWT, reconnects with backoff, and re-subscribes every channel after a reconnect. `channel<T>(name)` returns the payloads keel broadcasts on that channel; `userFrames<T>()` returns payloads addressed to the user, including keel's `{op: \"notification\"}` frames; `send(frame)` forwards an application frame to the hub's `OnMessage`. A subscription keel's `CanSubscribe` rejects is logged and exposed on `lastError`. Channel names and payload shapes are app-owned.\n\n## Billing\n\nsail ships a shared `BillingService` and ten billing components backed by keel's payment endpoints (see [keel/SHARED_PAYMENT.md](https://github.com/nauticana/keel/blob/main/SHARED_PAYMENT.md) for the provider contract — Stripe by default, pluggable).\n\n### Service\n\n```typescript\nimport { BillingService } from '@nauticana/sail';\n\n@Component({ /* ... */ })\nexport class PricingPage {\n  private billing = inject(BillingService);\n\n  readonly plans = toSignal(this.billing.listPlans(), { initialValue: [] });\n  readonly sub   = toSignal(this.billing.getSubscription());\n}\n```\n\n| Method | Endpoint | Returns |\n|--------|----------|---------|\n| `listPlans()` | `GET /public/plans` | `Observable<PublicPlan[]>` |\n| `createCheckout(req)` | `POST /api/billing/checkout` | `Observable<CheckoutResponse>` |\n| `getSubscription()` | `GET /api/billing/subscription` | `Observable<Subscription>` |\n| `cancelSubscription()` | `POST /api/billing/subscription/cancel` | `Observable<void>` |\n| `changePlan(planId)` | `POST /api/billing/subscription/change` | `Observable<void>` |\n| `setSeats(seats)` | `POST /api/billing/subscription/seats` | `Observable<void>` |\n| `listInvoices()` | `GET /api/billing/invoices` | `Observable<Invoice[]>` |\n| `listPaymentMethods()` | `GET /api/billing/payment-methods` | `Observable<PaymentMethod[]>` |\n| `createPortalSession()` | `POST /api/billing/portal` | `Observable<PortalResponse>` |\n| `listUsage()` | `GET /api/billing/usage` | `Observable<UsageMeter[]>` |\n\n### Components\n\n**Plan picker** — pure presentational, no API calls:\n```html\n<sail-plan-selector\n    [plans]=\"plans()\"\n    [selected]=\"selectedPlan()\"\n    [features]=\"{ PRO: ['Unlimited users', '24/7 support'] }\"\n    (selectionChange)=\"selectedPlan.set($event)\">\n</sail-plan-selector>\n```\n\n**Offer / price picker (v1.0.5)** — a plan no longer has a single price. keel v1.0.5 sells per-plan **offers** in the `subscription_plan_price` table (billing cycle × commitment term, each with its own `provider_price_id`), surfaced as `PublicPlan.prices: PlanPrice[]`. The customer picks an offer **at checkout**; its `priceId` is what flows to `<sail-checkout-button>`:\n\n```html\n<sail-price-selector\n    [prices]=\"selectedPlan().prices ?? []\"\n    [selected]=\"offer()?.priceId\"\n    (selectionChange)=\"offer.set($event)\">\n</sail-price-selector>\n```\n\n`<sail-price-selector>` is presentational (a `radiogroup` of offers), formats each amount with `Intl` from the offer's currency (so JPY/BHD render with the right number of decimals), and maps PERIOD_TYPE codes to copy via `[cycleLabels]`. It emits the full `PlanPrice` so you keep the chosen terms, not just the id.\n\n> **Migration.** The flat `PublicPlan.priceId` is deprecated (keel v1.0.5 dropped `subscription_plan.provider_price_id`) — read the id from the selected offer (`offer().priceId`). **keel v1.0.7 also removed `PublicPlan.monthlyCost`/`annualCost`** from both `/public/plans` and the billing catalog, so any plan-card code reading them now gets `undefined`. Derive a display price from the offers with `fromPriceLabel(plan.prices)` (used by `<sail-plan-selector>`), or render the per-offer amounts via `<sail-price-selector>`. These fields are removed from sail's `PublicPlan` type so the compiler flags any remaining references.\n\n**Checkout button** — calls `createCheckout()` and redirects to the provider-hosted URL. Feed it the chosen offer's `priceId`:\n```html\n<sail-checkout-button\n    [priceId]=\"offer()!.priceId!\"\n    [mode]=\"'subscription'\"\n    [successUrl]=\"'https://app.example.com/billing/done'\"\n    [cancelUrl]=\"'https://app.example.com/billing'\"\n    [email]=\"userEmail\">\n</sail-checkout-button>\n```\n\nFor one-off charges use `[mode]=\"'payment'\"`. For \"save a card without charging\" (Stripe SetupIntent), use `[mode]=\"'setup'\"` and **omit** `[priceId]` — keel rejects a non-empty `priceId` in setup mode with 400.\n\n> **keel allowlists** — `priceId`, `successUrl`, and `cancelUrl` must each match the server-side `AllowedPriceIDs` / `AllowedRedirectHosts` allowlists; otherwise the request is rejected with 400. Configure these on your keel deployment.\n\n> **`AllowedRedirectHosts` matching** is hostname-only by default — entries without a colon (e.g. `app.example.com`) tolerate any port. Add an explicit port (e.g. `app.example.com:8443`) only when port-strict matching is intentional.\n\n**Metadata stringification.** `CheckoutRequest.metadata` keys and values are typed as strings because that's what providers store. keel stringifies numeric and boolean metadata server-side, so a `partner_id: 42` written in your domain handler arrives back in webhook payloads as `\"42\"`. Stringify on the way in:\n\n```typescript\nmetadata: {\n  partner_id: String(partnerId),\n  source:     'pricing-page',\n}\n```\n\n**Payment methods** — lists saved methods with loading and empty states:\n```html\n<sail-payment-methods></sail-payment-methods>\n```\n\n### Registration → checkout flow\n\nThe registration confirmation (`ConfirmRegisterComponent`) already handles the payment redirect. When the backend returns `paymentRequired: true`, the user is sent to `resp.paymentUrl` (Stripe Checkout) automatically. No extra wiring needed — just select a paid plan during registration.\n\n### `BaseAsync`\n\nBoth `CheckoutButtonComponent` and `PaymentMethodsComponent` extend `BaseAsync` — an abstract class that bundles `loading()`, `errorMessage()`, `successMessage()` signals and a `run(obs, onSuccess, fallbackError)` helper. Reuse it in your own async components:\n\n```typescript\nimport { BaseAsync, BillingService } from '@nauticana/sail';\n\n@Component({ /* ... */ })\nexport class MyWidget extends BaseAsync {\n  private billing = inject(BillingService);\n\n  cancel() {\n    this.run(\n      this.billing.cancelSubscription(),\n      () => this.successMessage.set('Cancelled.'),\n      'Could not cancel.',\n    );\n  }\n}\n```\n\nTemplate:\n```html\n<button (click)=\"cancel()\" [disabled]=\"loading()\">Cancel plan</button>\n@if (errorMessage()) { <div class=\"auth-error\">{{ errorMessage() }}</div> }\n@if (successMessage()) { <div class=\"auth-success\">{{ successMessage() }}</div> }\n```\n\n### Suggested styles for billing components\n\nAdd to `src/styles.css` to match the rest of the library:\n```css\n/* Plan selector */\n.plan-selector { display: flex; gap: 1rem; flex-wrap: wrap; }\n.plan-card { flex: 1 1 220px; padding: 1rem; border: 1px solid #ccc; border-radius: 8px; }\n.plan-selected { border-color: #1976d2; box-shadow: 0 0 0 2px #1976d2; }\n.plan-caption { margin: 0 0 .5rem; }\n.plan-price .plan-amount { font-size: 1.5rem; font-weight: 600; }\n.plan-features { padding-left: 1.2rem; }\n\n/* Payment methods */\n.payment-methods-list { list-style: none; padding: 0; }\n.payment-method { display: flex; justify-content: space-between; padding: .5rem 0; }\n.payment-default-badge { font-size: .75rem; background: #e0e0e0; padding: 2px 8px; border-radius: 12px; }\n\n/* Checkout button */\n.checkout-button { display: flex; flex-direction: column; gap: .5rem; }\n```\n\n### Customer portal (v1.0.0)\n\n`createPortalSession()` + `<sail-portal-button>` mirror checkout — POST `/api/billing/portal`, then redirect to the provider-hosted customer portal where the partner manages their payment method / subscription:\n\n```html\n<sail-portal-button [label]=\"'Manage billing'\"></sail-portal-button>\n```\n\n### Usage meters (v1.0.0)\n\n`listUsage()` returns `UsageMeter[]` (`{ resource, used, limit }`, matching keel's `UsageItem`); `<sail-usage-meter>` renders one progress bar per resource (a `limit < 0` shows \"Unlimited\"):\n\n```typescript\nreadonly meters = toSignal(this.billing.listUsage(), { initialValue: [] });\n```\n```html\n<sail-usage-meter [meters]=\"meters()\"></sail-usage-meter>\n```\n\n### Redirect-action (v1.0.0)\n\nA `TableAction` with `kind: 'R'` (redirect — the `constant_value` code) makes `BaseTable.executeAction` POST and then follow the returned `{ url }` instead of refreshing — so checkout / portal / any provider-hosted handoff can be declared as a basis `table_action` row with **no bespoke component**. The backend action handler returns `{ \"url\": \"https://…\" }`.\n\n> **Response-shape contract.** The generic redirect-action path reads a bare `url` because it's polymorphic — one dispatch for checkout / portal / export / etc., where the action's identity lives in the metadata, not the payload. keel's `WrapTableAction` enforces no shape; your inner handler must return `{ url }`. The *typed* billing endpoints keep specific names instead (`createCheckout()` → `checkoutUrl`, `createPortalSession()` → `portalUrl`). So the same portal concept has two response shapes depending on the path: wire it as `<sail-portal-button>` (typed → `portalUrl`) **or** as a `table_action` redirect (generic → `url`), not both.\n\n### Action parameters (v1.1.25)\n\nAn action with `parameters` (keel v1.2.75 `table_action_parameter`) opens a dialog before posting: one field per parameter, typed by `dataType` (`boolean` checkbox, numeric, `date`, `timestamp`, `file`, otherwise text), or a dropdown when `lookupTable` names a table in the client cache (a `foreign_key_lookup` dropdown table); a numeric `dataType` still posts the chosen key as a number. The dialog shows `confirmMessage` in place of the native prompt and posts `{...primaryKeyValues(record), ...values}`; empty optional values are left out. A `file` parameter turns the post into `multipart/form-data`, so a table-level `upload` action whose parameters are `file`, `document_type` (lookup `document_type`), `title`, … posts straight to keel's `DocumentHandler.Upload`. An action without parameters behaves as before.\n\n### Status chip (v1.0.1)\n\n`<sail-status-chip>` resolves a code to its caption from the client-cache `constant_value` dictionary — no per-app `@switch`. It defaults to the `SUBSCRIPTION_STATUS` domain (so `T` trialing / `X` past-due render with no app code) and works for any constant domain via `[domain]`. The code is exposed as `[attr.data-status]` so the app can colour the chip:\n\n```html\n<sail-status-chip [value]=\"sub()?.status\"></sail-status-chip>\n<sail-status-chip [value]=\"invoice.status\" domain=\"INVOICE_STATUS\"></sail-status-chip>\n```\n\n> Replaces a downstream app's hardcoded status `@switch` (e.g. seo's): captions are backend-authoritative — when a dictionary row is absent the raw code shows, never a fabricated label.\n\n### Trial banner (v1.0.1)\n\n`<sail-trial-banner>` shows \"Trial ends in N days\" from `Subscription.trialEnd`; it renders nothing when the value is empty, unparseable, or already past, so it can sit unconditionally in the template:\n\n```html\n<sail-trial-banner [trialEnd]=\"sub()?.trialEnd\"></sail-trial-banner>\n```\n\n### Seat selector (v1.0.1)\n\n`<sail-seat-selector>` is a presentational quantity stepper seeded from `Subscription.seats`. Feed the result into checkout (`[quantity]` / metadata) for new subs, or `BillingService.setSeats()` for an existing one:\n\n```html\n<sail-seat-selector [seats]=\"sub()?.seats ?? 1\" [min]=\"1\" (seatsChange)=\"seats.set($event)\"></sail-seat-selector>\n```\n\n### Plan change vs first-time checkout (v1.0.1)\n\nFirst-time checkout uses `<sail-checkout-button>` (provider-hosted). For an **existing** subscription, upgrade/downgrade is a distinct path — `BillingService.changePlan(planId)` routes to keel's `SubscriptionLifecycle.ChangePlan` via an endpoint the app exposes. Wire the picker's selection to whichever path applies:\n\n```typescript\nonPlanPicked(planId: string) {\n  this.sub() ? this.billing.changePlan(planId).subscribe() : this.startCheckout(planId);\n}\n```\n\n`<sail-plan-selector>` varies its CTA copy by `PublicPlan.activationMode` (\"Start trial\" for `T`, \"Subscribe\" for `P`, \"Activate\" for `F`); override or extend via `[ctaLabels]=\"{ S: 'Add seats' }\"`.\n\n### Dunning banner (v1.0.1)\n\n`<sail-dunning-banner>` shows only when `Subscription.status === 'X'` (past-due / keel `SetDunningState`), prompting the partner to update their card and deep-linking to the provider portal via an embedded `<sail-portal-button>`:\n\n```html\n<sail-dunning-banner [status]=\"sub()?.status\"></sail-dunning-banner>\n```\n\n### Compose a full Billing screen\n\nA complete screen is the pieces above assembled over `BillingService` — no metadata CRUD (billing data is partner-scoped, read-mostly, money-formatted, with an external-redirect action, which `TableList`/`TableEdit` don't model):\n\n```html\n<sail-dunning-banner [status]=\"sub()?.status\"></sail-dunning-banner>\n<sail-trial-banner [trialEnd]=\"sub()?.trialEnd\"></sail-trial-banner>\n<sail-status-chip [value]=\"sub()?.status\"></sail-status-chip>\n<sail-plan-selector [plans]=\"plans()\" [selected]=\"sub()?.planId\" (selectionChange)=\"onPlanPicked($event)\"></sail-plan-selector>\n<sail-price-selector [prices]=\"selectedPlan()?.prices ?? []\" [selected]=\"offer()?.priceId\" (selectionChange)=\"offer.set($event)\"></sail-price-selector>\n<sail-seat-selector [seats]=\"sub()?.seats ?? 1\" (seatsChange)=\"seats.set($event)\"></sail-seat-selector>\n<sail-checkout-button [priceId]=\"offer()!.priceId!\" [quantity]=\"seats()\" [successUrl]=\"okUrl\" [cancelUrl]=\"backUrl\"></sail-checkout-button>\n<sail-usage-meter [meters]=\"usage()\"></sail-usage-meter>\n<sail-payment-methods></sail-payment-methods>\n<sail-portal-button></sail-portal-button>\n<!-- invoices: render listInvoices() rows directly -->\n```\n\n## Agent UI (v1.1.20)\n\nAgent Studio and agent-conversation UI live in a secondary entry point, `@nauticana/sail/agent`. Nothing in it is exported from `@nauticana/sail`, so an app that never imports it bundles none of it. It needs no additional peer dependency.\n\n```ts\nimport { AgentStudioService, PromptLanguageEditorComponent, TurnStream } from '@nauticana/sail/agent';\n```\n\n| Export | Purpose |\n|---|---|\n| `AgentStudioService` | Client for the thirteen `studio-v2` routes under `/api/agent-studio/` (fixed, unversioned paths). Models mirror the backend's JSON names. |\n| `studioConflictCause(err)` | `'revision'` (reload the draft), `'sealed'` (a layer sits under a sealed one) or `'other'` for a `409`. |\n| `studioFieldErrors(err)` / `retryAfterSeconds(err)` | Field errors of a `400`; `Retry-After` of a `429`/`503`. |\n| `sail-prompt-language-editor` | One language's prompt sections. Emits the whole language on every edit — a save must send every layer back, because an editable layer missing from the request ends its binding. Emits `resetRequested` with the scope, section, and language to reset. |\n| `sail-prompt-section-editor` | One section's layers in server order. Read-only layers render as text; editable ones edit `instruction`, `output`, `merge_mode`, `sealed`. A sealed layer locks every layer below it. Effective text is shown as received, never merged client-side; after a save, replace the whole draft with the response. |\n| `sail-release-sections` | Frozen sections of a release with the layer (`source`) that decided each. |\n| `sail-turn-event-list` | Renders typed turn events in frame order; proposal, result, effect, and approval of one call meet by `call_id`. Effect status `unknown` is its own state. Unknown kinds are ignored; `extension` events render only through `[extensionTemplate]`. |\n| `TurnStream` | Per-turn stream state: `accept(frame)` accepts Scout's zero-based frames and drops frames already rendered, `cursor()` is the next sequence wanted for inclusive replay, a suspension frame (`approval_pending`, even when marked final) sets `awaiting_approval` without advancing the cursor so the resumed frame at the same sequence is accepted, `markReplayExpired()` + `acceptStoredResult(frame)` handle an expired replay window, `markCancelRequested()` holds `cancelling` until the final frame. |\n| `sail-turn-stream-view` | `TurnStream` + event list + status + cancel button (`cancelRequested`). |\n| `sail-decision-timeline` | Read-only decision chain of one request, grouped by category. |\n| `ConversationService` | Transport for Scout's conversation bridge: `submit`, `stream(requestId, turnStream)`, `cancel`. Mount point injected through `CONVERSATION_BASE_PATH`. |\n| `SseParser` | Incremental `text/event-stream` parser: `push(chunk)` returns whole events out of chunks that split anywhere, including between the CR and LF of a CRLF; `finish()` flushes what the closing body left pending. |\n\nMap your audit rows onto `DecisionRecord` to feed the timeline. Style the `.prompt-*`, `.release-*`, `.turn-*`, and `.decision-*` class hooks.\n\n### Conversation transport (v1.1.22)\n\nScout `v0.7.1` fixed the wire contract, so the transport is no longer app-specific.\n`ConversationService` speaks it and feeds a `TurnStream`; the app supplies the mount\npoint, the turn `input` payload, and its own renderers.\n\n```ts\nproviders: [{ provide: CONVERSATION_BASE_PATH, useValue: '/api/wingmate/' }]\n```\n\n```ts\nconst stream = new TurnStream(requestId);\nthis.conversation.submit({ request_id: requestId, conversation_id: conversationId, agent_id: 'wingmate', input })\n  .pipe(switchMap(() => this.conversation.stream(requestId, stream)), takeUntilDestroyed())\n  .subscribe({ error: (err) => this.onStreamError(err) });\n```\n\n| Method | Wire |\n|---|---|\n| `submit(request)` | `POST {base}turn` → `202 {request_id}`. Goes through `HttpClient`, so the interceptors apply. |\n| `stream(requestId, turnStream)` | `GET {base}turn/stream?request_id=&cursor=` as SSE. Reads from `turnStream.cursor()`, feeds every `event: turn` frame in, and emits the ones the stream accepted. Completes when the server closes the delivery; unsubscribing aborts the request. |\n| `cancel(requestId, reason?)` | `POST {base}turn/cancel` → `202`. Cancel is a request — call `turnStream.markCancelRequested()` and wait for the final frame. |\n\nNotes that decide whether an adoption is correct:\n\n- **The stream carries its own bearer.** `EventSource` cannot send an `Authorization`\n  header, so this is a `fetch` body reader. It reads the same `jwt` key the interceptor\n  reads and, on a `401`, rotates once through `BaseAuthService.refreshSession()` — the\n  shared, de-duplicated rotation — then retries. The interceptor's auth-loop circuit\n  breaker does **not** cover the stream.\n- **Reconnect is the same call.** `stream()` re-read from `stream.cursor()` resumes\n  exactly where the last accepted frame left off. A suspension frame\n  (`approval_pending`) does not advance the cursor, so reconnecting after the approval is\n  decided picks up the resumed frame at the same sequence.\n- **`410` is an expired replay window under a still-running turn.** No stored result\n  exists yet, which is why it is an error and not a frame. The service calls\n  `markReplayExpired()` and errors with a `ConversationStreamFailure` carrying status\n  `410`; calling `stream()` again later self-heals, because once the turn is terminal the\n  backend answers the same expired cursor with the stored final frame — delivered as an\n  ordinary `event: turn`, carrying the cursor it was asked with, so `accept()` takes it.\n- **`event: error`** carries `ConversationStreamError` (`status`, `detail`, `request_id`) —\n  a failure raised after the stream's `200` was committed. It surfaces as the same\n  `ConversationStreamFailure`.\n- Unknown `TurnEvent` kinds are dropped at the transport, and a frame missing\n  `request_id`, `sequence` or `events` is ignored rather than fed in.\n\n## Agency / reseller UI (v1.1.14)\n\nsail v1.1.14 supplies composable, unstyled agency components over keel v1.2.41.\nThe app owns routes, route guards, brand copy, global CSS, and any columns that\nrefer to an app-specific managed entity.\n\n`AgencyService` covers profile enrollment, invitation staging/acceptance,\ndelegation/revocation, per-client referral/wholesale selection, earnings, and\npayout-profile selection. Its DTOs use the upstream names\n`agency_client_invitation`, `agency_client_delegation`, and\n`agency_client_rate`; there is no client-side rule-schedule model.\nThe enrollment method is `enroll()`; downstream `enrollReferral()` calls must\nbe renamed when adopting this release.\n\nCompose an agency page from the pieces you need:\n\n```html\n<sail-agency-clients\n  [extraColumns]=\"clientColumns\"\n  [showBillingModelControls]=\"true\" />\n<sail-agency-earnings-summary [earnings]=\"earnings()\" [activeClients]=\"activeClients()\" />\n<sail-commission-ledger [entries]=\"earnings()?.entries ?? []\" />\n<sail-agency-payout-history [payouts]=\"earnings()?.payouts ?? []\" />\n<sail-agency-payout-profile />\n```\n\n`AgencyClientsComponent` renders status values through the shared\n`StatusChipComponent` and backend constant catalogues. It accepts app-specific\ncolumns rather than assuming the managed entity. Accepted clients begin in\nreferral mode; wholesale controls appear only when the profile permits them and\nthe app opts in with `showBillingModelControls`.\n\nLoad keel's v1.2.40 basis seed so status chips receive these canonical domains:\n\n| Domain | Values |\n|---|---|\n| `agency_client_status` | `S` Staged, `I` Invited, `V` Client, `X` Cancelled |\n| `agency_billing_model` | `R` Referral, `W` Wholesale |\n| `agency_commission_status` | `H` Held, `P` Payable, `R` Reserved, `D` Paid, `O` Offset |\n| `agency_payout_status` | `C` Created, `P` Processing, `D` Paid, `F` Failed, `R` Returned, `V` Reversed, `M` Manual review |\n\nDo not substitute app-local domain names such as `billing_model` or\n`commission_status`; a missing canonical domain deliberately renders the raw\ncode so configuration drift remains visible.\n\n`AgencyAcceptComponent` keeps consent explicit and persists an invitation token\nwhen the authenticated user still needs to create a business partner. Consumers\nhandle its navigation outputs and route back after business setup. Other 409\nconflicts, such as an existing delegation or self-delegation, remain on the\ninvitation screen as errors instead of entering the business-setup flow. The\nbranch uses keel's stable RFC 7807 `code: \"agency_no_partner\"` (keel v1.2.41),\nnot error prose.\n\nThe payout-profile component composes the existing provider-onboarding surface\nand only allows a fully onboarded destination returned by keel. Mount it only\nfor an approved, non-suspended agency; keel intentionally rejects its GET for a\npending profile. The ledger and payout-history components show default empty\nmessages; pass `[emptyMessage]=\"''\"` when a composed page should omit empty\nregions entirely.\n\nAll accounting values are integer minor units. `formatMinorCurrency()` uses the\ncurrency exponent reported by `Intl.NumberFormat`, so zero- and three-decimal\ncurrencies render correctly; earnings stay separated by currency rather than\nbeing summed into a misleading total.\n\nThe agency URL defaults use `/api/v1/agency/*`. Apps mounting Keel elsewhere\nmust override the `RestURL.agency*URL` values with `configureRestUrls()`.\n\n## Off-session SCA / 3DS confirmation (v1.0.x; refusals v1.1.24)\n\nWhen an app charges a rider's **vaulted** card off-session (keel `payment.ChargeClient` / `StripeChargeClient`), the cardholder may have to complete a Strong Customer Authentication (3DS) challenge. keel reports two distinct outcomes on `ChargeResult`, and they need different client operations:\n\n| `status` | What happened | Client operation |\n|---|---|---|\n| `requires_action` | The PaymentIntent carries a `next_action` to run. | Run it — `actionUrl` redirect, or `confirm(clientSecret)`. |\n| `authentication_required` | The issuer refused the off-session confirmation. The intent is back at `requires_payment_method` with **no `next_action`**. | Re-confirm the same intent on-session with the refused method — `confirmWithMethod(clientSecret, paymentMethodId)`. |\n\nsail stays provider-agnostic: it ships **no payment-provider SDK** and **no default confirmer**. It provides a port (`ScaConfirmer`), the `SCA_CONFIRMER` injection token, and `<sail-sca-confirm>`, which dispatches on the status:\n\n- `authentication_required` → `SCA_CONFIRMER.confirmWithMethod`; else\n- `actionUrl` present → redirect (provider-hosted challenge — no SDK needed); else\n- inline `clientSecret` → `SCA_CONFIRMER.confirm`.\n\n### Backend contract (app-owned)\n\nOff-session charging is a worker/handler concern, so the **app** owns the charge endpoint. Have it call keel's `ChargeClient.Charge` and return the normalized result as camelCase JSON matching sail's `ChargeResult`:\n\n```jsonc\n// POST /api/<app>/charge  →  200\n{ \"status\": \"requires_action\", \"clientSecret\": \"pi_..._secret_...\", \"actionUrl\": \"\" }\n// or { \"status\": \"authentication_required\", \"clientSecret\": \"pi_..._secret_...\", \"paymentMethodId\": \"pm_...\" }\n// or { \"status\": \"succeeded\", \"providerChargeId\": \"pi_...\" }\n// or { \"status\": \"failed\", \"error\": \"card_declined\" }\n```\n\n> `ChargeRequest.Metadata` (keel v1.0.4) carries `ride_id` / `user_id` / `tip_amount` through to the settled charge's `PaymentEvent.Metadata`, so the webhook can correlate and split the fare — set it on the backend, not the client.\n\n### Frontend adoption (downstream projects)\n\n**1. Implement the provider confirmer** (Stripe shown; lives in the app, behind an *optional* `@stripe/stripe-js` peer dep — non-Stripe apps skip it):\n\n```typescript\nimport { Injectable } from '@angular/core';\nimport { loadStripe } from '@stripe/stripe-js';\nimport { ScaConfirmer, ScaResult } from '@nauticana/sail';\n\n@Injectable({ providedIn: 'root' })\nexport class StripeScaConfirmer implements ScaConfirmer {\n  async confirm(clientSecret: string): Promise<ScaResult> {\n    const stripe = await loadStripe(/* publishable key from backend cache */);\n    if (!stripe) return { outcome: 'failed', error: 'Stripe.js failed to load' };\n    const { error } = await stripe.handleNextAction({ clientSecret });\n    return error ? { outcome: 'failed', error: error.message } : { outcome: 'succeeded' };\n  }\n\n  async confirmWithMethod(clientSecret: string, paymentMethodId: string): Promise<ScaResult> {\n    const stripe = await loadStripe(/* publishable key from backend cache */);\n    if (!stripe) return { outcome: 'failed', error: 'Stripe.js failed to load' };\n    const { error } = await stripe.confirmCardPayment(clientSecret, { payment_method: paymentMethodId });\n    return error ? { outcome: 'failed', error: error.message } : { outcome: 'succeeded' };\n  }\n}\n```\n\n**2. Register it at composition time** (`app.config.ts` / `main.ts`):\n\n```typescript\nimport { SCA_CONFIRMER } from '@nauticana/sail';\n\nproviders: [\n  { provide: SCA_CONFIRMER, useExisting: StripeScaConfirmer },\n]\n```\n\n**3. Drop the component into the post-charge flow** — bind the charge response and react to the outcome:\n\n```html\n<sail-sca-confirm\n    [result]=\"charge()\"\n    (confirmed)=\"onPaid()\"\n    (failed)=\"onScaFailed($event)\">\n</sail-sca-confirm>\n```\n\n`<sail-sca-confirm>` renders nothing for `succeeded`, the decline message for `failed`, and a confirm button for both action states. The publishable key is backend-authoritative — read it from the auth/app-data cache, never hardcode a fallback.\n\n## Consent capture\n\n`ConsentGateComponent` is a reusable signup-consent primitive that mirrors keel's `user.SignupConsent` structure. It always renders two required checkboxes (`privacy_policy`, `cross_border`) and lets you declare any number of optional consents.\n\n```typescript\nimport { ConsentGateComponent, ConsentOption, ConsentState, ConsentType } from '@nauticana/sail';\n\n@Component({\n  imports: [ConsentGateComponent],\n  template: `\n    <sail-consent-gate\n        [policyVersion]=\"'v1'\"\n        [policyLanguage]=\"'en'\"\n        [optionalConsents]=\"extras\"\n        (consentStateChange)=\"onConsent($event)\">\n    </sail-consent-gate>\n  `,\n})\nexport class SignupPage {\n  readonly extras: ConsentOption[] = [\n    { id: ConsentType.VIDEO_OPT_IN, label: 'Record my trips on video', hint: 'Optional; change in settings later.' },\n    { id: ConsentType.MARKETING,    label: 'Email me product updates' },\n  ];\n\n  onConsent(state: ConsentState) {\n    // state.consents is Record<string, boolean>, state.valid is false until\n    // both required checkboxes are ticked.\n  }\n}\n```\n\nThe component relies on `config.privacyPolicyUrl`, `config.defaultPolicyVersion`, and `config.defaultPolicyLanguage` as fallbacks when the inputs are omitted.\n\n## Phone / email OTP login\n\nkeel issues an opaque server-side `otpToken` from `sendOtp()` (32 random bytes, base64-URL, bound to the user_id in cache for ~5 min). Echo it back verbatim to `verifyOtp()` / `resendOtp()`. The login fall-through still returns 200 with a token on unknown contacts (no SMS dispatched), so the response shape never leaks which numbers are registered.\n\n`BaseAuthService` provides `sendOtp()`, `resendOtp()`, and `verifyOtp()`. Pair them with the presentational `OtpInputComponent` for a complete OTP screen:\n\n```typescript\n// src/page/otp_confirm.ts\nimport { Component, inject, signal } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { BaseAuthService, OtpInputComponent } from '@nauticana/sail';\n\n@Component({\n  imports: [OtpInputComponent],\n  template: `\n    <sail-otp-input\n        [contact]=\"contact()\"\n        [length]=\"6\"\n        (codeComplete)=\"onVerify($event)\"\n        (resend)=\"onResend()\">\n    </sail-otp-input>\n    @if (error()) { <div class=\"auth-error\">{{ error() }}</div> }\n  `,\n})\nexport class OtpConfirmPage {\n  private auth = inject(BaseAuthService);\n  private router = inject(Router);\n  readonly contact = signal('+1 (416) 555-1234');\n  readonly otpToken = signal('');\n  readonly error = signal('');\n\n  onVerify(code: string) {\n    this.auth.verifyOtp({ otpToken: this.otpToken(), code }).subscribe({\n      next: () => this.router.navigate(['/dashboard']),\n      error: (err) => this.error.set(err.error?.message ?? 'Invalid code.'),\n    });\n  }\n\n  onResend() {\n    this.auth.resendOtp(this.otpToken()).subscribe();\n  }\n}\n```\n\nOverride `verifyOtp()` in your own `AuthService extends BaseAuthService` when you need role routing.\n\n| Endpoint | Service method |\n|----------|---------------|\n| `POST /public/otp/send` | `sendOtp(req)` — returns `{ otpToken }` |\n| `POST /public/otp/resend` | `resendOtp(otpToken, purpose?)` |\n| `POST /public/otp/verify` | `verifyOtp({ otpToken, code })` — auto-completes login on success |\n\n## Social login\n\n`SocialLoginComponent` renders Google / Apple buttons using each provider's official SDK. It loads the SDKs dynamically via `loadScript()` — nothing is bundled into your app.\n\n```html\n<sail-social-login\n    [providers]=\"['google', 'apple']\"\n    [consent]=\"consentState\"\n    (loginSuccess)=\"onSuccess($event)\"\n    (loginError)=\"onError($event)\">\n</sail-social-login>\n```\n\nConfig required in `SAIL_GUI_CONFIG`:\n\n```typescript\n{\n  googleClientId: 'xxxxx.apps.googleusercontent.com',\n  appleServiceId: 'com.example.app.web',\n  appleRedirectUri: 'https://example.com/login',  // must match Apple Services ID\n}\n```\n\nUnder the hood, the component calls `BaseAuthService.loginSocial(provider, idToken, consent)` → `POST /public/login/social` and emits `loginSuccess: LoginResponseSocial`. The session is completed automatically (token stored, app data loaded, routes initialized).\n\nFor backward compatibility, the older OAuth-code flow `BaseAuthService.loginWithGoogle(code)` (hits `/public/login/google`) is still supported; prefer `loginSocial` for new code.\n\n## Dashboard components\n\nHorizontal building blocks for an entitlement-aware dashboard. All are presentational (signals in, events out) and ship no CSS — the app styles the documented class hooks and supplies the metric data, chart, and action logic.\n\n- **`DashboardShellComponent`** (`sail-dashboard-shell`) — responsive card-grid layout. `[heading]` + a `[dashboardActions]` projection slot for the header; project cards into the default slot. Styles: `.dashboard-shell` / `.dashboard-header` / `.dashboard-grid`.\n- **`DataCardComponent`** (`sail-data-card`) — card chrome for one visualization with `[state]` ∈ `loading | ready | empty | error | locked | no-source`. The chart is supplied as an `<ng-template>` and instantiated **only** in `ready`, so during loading/error/locked/no-source it never exists (no hidden canvas). `description` (required) is the screen-reader text alternative; `[tableHeaders]`/`[tableRows]` render a visually-hidden (`.sr-only`) data table. Emits `upgrade`, `connect`, and `retry`. `[connectLabel]=\"''\"` renders the `no-source` state without a button — a source whose collector does not exist yet has nothing to connect.\n- **`LockedOverlayComponent`** (`sail-locked-overlay`) — entitlement gate. Wraps protected content given as an `<ng-template>`; when `[locked]` the template is never instantiated, so **no data exists behind the gate** (DOM, canvas, or network) — the strict free-tier rule. Emits `upgrade`.\n- **`NoSourceOverlayComponent`** (`sail-no-source-overlay`) — source-readiness gate. Takes `[sourceName]` and emits `connect`; while `[unavailable]`, its protected `<ng-template>` is never instantiated. Use this for included features whose provider is not connected or whose collector is unavailable—never show an upgrade prompt for this state. Set `[ctaLabel]=\"''\"` when there is nothing to connect, and no button renders.\n- **`StatTileComponent`** (`sail-stat-tile`) — one number: `label`, `value`, optional `target`, `progress` (0..1, a `role=\"progressbar\"`), `delta` with `deltaGood` (`true | false | null`, the `.good` / `.bad` hook) and `trend` (`number[]`, a decorative sparkline, hidden under two points). Values are preformatted strings; the tile does no formatting. Styles: `.stat-tile` / `-label` / `-value` / `-target` / `-delta` / `-progress` / `-progress-fill` / `-trend`.\n- **`ActionCenterComponent`** (`sail-action-center`) — prioritized next-best-action list from `[actions]: ActionItem[]` (sorted by `priority`, done items show a check). Emits `act`.\n- **`EntitySelectorComponent`** (`sail-entity-selector`) — scope dropdown over `[entities]: EntityOption[]`; resolves `[selected]` or the first active entity and emits `selectionChange`.\n- **`VerificationFlowComponent`** (`sail-verification-flow`) — self-service request → enter-code → verified UI (a 2FA sibling), backend-agnostic: emits `requestVerification` / `confirmCode`, driven by `[step]` + `[errorMessage]` the host feeds back. `[resendAfterSeconds]` holds `Resend code` for a cooldown and `[codeExpiresInSeconds]` blocks `Confirm` once the issued code expires; both default to `0`, which keeps the button always enabled and shows no expiry. Both countdowns restart when the component emits `requestVerification`. `[disabled]` blocks all actions while the host is processing one. `[errorMessage]` also renders in the `idle` step, so a failed send is reported where it happened.\n\n```html\n<sail-data-card heading=\"Trends\" [state]=\"state()\" description=\"Weekly visibility trend\" (upgrade)=\"goUpgrade()\">\n  <ng-template><canvas baseChart [data]=\"chartData()\" [type]=\"'line'\"></canvas></ng-template>\n</sail-data-card>\n```\n\nModels: `DataCardState`, `ActionItem`, `EntityOption`, `VerificationStep`.\n\nAnalytics clients that need this distinction can call the protected\n`analyticWithStatus<T>()` on `BaseRestService`. It returns\n`{ rows, source: { status, id } }`, populated from `X-Data-Source-Status` and\n`X-Data-Source`; the existing `analytic<T>()` remains `Observable<T[]>`.\n\n`sourceState(result, sourceName, connectLabel?)` maps an analytic result to\n`{ state, message, cta }` for `[state]`, `[noSourceMessage]`, and `[connectLabel]`.\n`NOT_CONNECTED` offers Connect; `NOT_COLLECTED` explains that collection is not\nlive and leaves the CTA empty; `READY` or no header yields `ready` / `empty` from\nthe rows. The caller supplies the source name and handles\nthe click route.\n\nWhen the app and its API are on different origins the browser hides both headers\nunless the backend sends\n`Access-Control-Expose-Headers: X-Data-Source-Status, X-Data-Source`; without it\n`source.status` is `null` and a missing source is indistinguishable from an\nempty result.\n\n## Domain verification (v1.1.22)\n\n`DomainVerificationComponent` (`sail-domain-verification`) is the send-code → confirm\nflow for proving ownership of a domain: the domain field, the two steps, the resend\ncooldown, the expiry state and the errors. Every app that verifies a domain renders\nthe same thing, so only the endpoints stay downstream.\n\nThe endpoints reach it through the `DOMAIN_VERIFIER` port — sail ships no\nimplementation and knows none of the paths:\n\n```ts\nexport interface DomainVerifier {\n  requestVerification(domain: string): Observable<unknown>;\n  confirm(domain: string, code: string): Observable<unknown>;\n}\n```\n\n```ts\n// app config — any service with those two methods satisfies the port\nproviders: [{ provide: DOMAIN_VERIFIER, useExisting: RegistrationService }]\n```\n\n```html\n<sail-domain-verification\n  [domain]=\"domainUrl()\"\n  [resendAfterSeconds]=\"60\"\n  [codeExpiresInSeconds]=\"900\"\n  (domainChange)=\"form.controls.domainUrl.setValue($event)\"\n  (verified)=\"domainVerified.set(true)\" />\n```\n\n| Input / output | Meaning |\n|---|---|\n| `[domain]` | Initial value; the component keeps its own editable copy. |\n| `[label]` | Field label, default `Domain`. |\n| `[resendAfterSeconds]` | Resend cooldown, default `60`. |\n| `[codeExpiresInSeconds]` | Code lifetime; `0` (default) shows no expiry. Pass the backend's TTL when it publishes one. |\n| `(domainChange)` | Every edit, so the host form stays in sync. |\n| `(verified)` | Fires once with the proven domain. |\n\nEditing the domain returns the flow to `idle`: a code is bound to the domain it was\nissued for. The component is unstyled — style `.domain-verification`,\n`.domain-verification-field`, `.domain-verification-verified` and the\n`.verification-*` hooks of the step UI it composes.\n\n## Notification inbox (v1.1.23)\n\n`NotificationInboxService` is the stateful client for keel's `InboxHandler` (keel\n**v1.2.71+**). `NotificationCenterComponent` (`sail-notification-center`) renders it;\nthe app handles what each message means through `(selected)`.\n\nThe default routes match keel. Override the three `notifications*URL` values through\n`configureRestUrls` only when the handler is mounted elsewhere.\n\n```ts\nconst inbox = inject(NotificationInboxService);\ninbox.load().subscribe();          // newest page, replaces the cache\ninbox.loadMore().subscribe();      // the page older than the last cached message\ninbox.markRead(id).subscribe();\ninbox.markAllRead().subscribe();\ninbox.reset();                     // on logout — the cache is per-session\n```\n\n```ts\nreadonly unread = inject(NotificationInboxService).unreadCount;   // Signal<number>\n```\n\n| Member | Meaning |\n|---|---|\n| `messages` | `Signal<InboxMessage[]>`, newest first. |\n| `unreadCount` | `Signal<number>` across the whole inbox, not just the loaded page. |\n| `hasMore` | `Signal<boolean>` — the last page came back full, so older messages may exist. |\n| `load(limit)` / `loadMore(limit)` | Default 20; keel caps a page at 100 and the client clamps to match. |\n\nMessage ids are server-side `BIGINT`s serialized as strings. Both mark-read routes\nreturn `204`, so the service updates its cache locally. After the first successful `load()`, each\n`{op: \"notification\"}` frame from keel's `realtime.UserDispatcher` (v1.2.79+) on a\nconnected `RealtimeService` re-fetches the newest page into the cache. Call `reset()`\non logout.\n\n```html\n<sail-notification-center\n  heading=\"Notifications\"\n  [pageSize]=\"20\"\n  (selected)=\"open($event)\" />\n```\n\n| Input / output | Meaning |\n|---|---|\n| `[pageSize]` | Messages per request, default 20. |\n| `[heading]` | Rendered as an `<h2>` with the unread count; empty ","readmeFilename":"README.md"}