Skip to content

release: 1.2.0#297

Merged
ashleythedeveloper merged 26 commits into
mainfrom
release/1.2.0
May 1, 2026
Merged

release: 1.2.0#297
ashleythedeveloper merged 26 commits into
mainfrom
release/1.2.0

Conversation

@ashleythedeveloper

Copy link
Copy Markdown
Contributor

This PR ships the work accumulated on next since 1.1.0, releasing vckit 1.2.0. Highlights: a new DATABASE_SSL env var on the agent template, a hardened Docker entrypoint that fails loudly on did import errors (with SEED_DID=false opt-out), basePath derivation from API_DOMAIN, proper exit codes on all did CLI subcommands, and a @digitalcredentials/jsonld upgrade to 9.0.0.

See the CHANGELOG for the full list and ADRs 0001-0003 in docs/adr/ for the deployment-fix decisions.

Test plan

  • All feature PRs merged into next passed their individual CI runs
  • Release-please changelog PR (chore(release/1.2.0): release 1.2.0 #296) regenerated correctly after main was merged into the release branch (1.1.0 tag now in ancestry)
  • CI on this PR runs pnpm build:agent and pnpm test:packages cleanly
  • Release workflow tags 1.2.0 and creates the GitHub release after merge to main

ldhyen99 and others added 26 commits March 11, 2025 16:42
<!--
  For Work In Progress Pull Requests, please use the Draft PR feature,
see https://github.blog/2019-02-14-introducing-draft-pull-requests/ for
further details.
  
  For a timely review/response, please avoid force-pushing additional
  commits if your PR already received reviews or comments.
  
Before submitting a Pull Request, please ensure you've done the
following:
- 📖 Read the [Contributing
Guide](https://github.com/uncefact/project-vckit/blob/main/CONTRIBUTING.md).
- 📖 Read the [Code of
Conduct](https://github.com/uncefact/project-vckit/blob/main/CODE_OF_CONDUCT.md).
  - 👷‍♀️ Create small PRs. In most cases, this will be possible.
  - ✅ Provide tests for your changes.
- 📝 Use descriptive commit messages following [conventional
commits](https://www.conventionalcommits.org/en/v1.0.0/).
- 📗 Update any related documentation and include any relevant
screenshots.
-->

## What type of PR is this? (check all applicable)

- [ ] 🍕 Feature
- [ ] 🐛 Bug Fix
- [ ] 📝 Documentation Update
- [ ] 🎨 Style
- [ ] 🧑‍💻 Code Refactor
- [ ] 🔥 Performance Improvements
- [ ] ✅ Test
- [ ] 🤖 Build
- [ ] 🔁 CI
- [ ] 📦 Chore (Release)
- [ ] ⏩ Revert

## Description

<!-- 
Please do not leave this blank 
This PR [adds/removes/fixes/replaces] the [feature/bug/etc]. 
-->

## Related Tickets & Documents
<!-- 
Please use this format link issue numbers: Fixes #123

https://docs.github.com/en/free-pro-team@latest/github/managing-your-work-on-github/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword
-->

## Mobile & Desktop Screenshots/Recordings

<!-- Visual changes require screenshots -->


## Added tests?

- [ ] 👍 yes
- [ ] 🙅 no, because they aren't needed
- [ ] 🙋 no, because I need help

## Added to documentation?

- [ ] 📜 README.md
- [ ] 📓 [vc-kit doc site](https://uncefact.github.io/vckit/)
- [ ] 📕 storybook
- [ ] 🙅 no documentation needed

## [optional] Are there any post-deployment tasks we need to perform?


<!-- note: PRs with deleted sections will be marked invalid -->

---------

Co-authored-by: Huy Nguyen <huy.nguyenkim.h@gmail.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Ashley Harwood <60303491+ashleythedeveloper@users.noreply.github.com>
## What type of PR is this? (check all applicable)

- [ ] 🍕 Feature
- [x] 🐛 Bug Fix
- [ ] 📝 Documentation Update
- [ ] 🎨 Style
- [ ] 🧑‍💻 Code Refactor
- [ ] 🔥 Performance Improvements
- [ ] ✅ Test
- [ ] 🤖 Build
- [ ] 🔁 CI
- [ ] 📦 Chore (Release)
- [ ] ⏩ Revert

## Description

The pull request addresses an issue in the `extractData` method of the
`WebRenderingTemplate2022` and `RenderTemplate2024` providers, where it
failed to extract the `template` or `url` due to an incorrect IRI. Refer
to issue [#334](uncefact/spec-untp#334) for
more details.

The change updates the IRI prefix from
`https://www.w3.org/2018/credentials#renderMethod` to
`https://w3id.org/vc/render-method` for both `template` and `url`.


## Mobile & Desktop Screenshots/Recordings
**Before the fix**

```json
[
    {
        "type": "https://test.uncefact.org/vocabulary/untp/core/0/WebRenderingTemplate2022",
        "renderedTemplate": ""
    }
]
```
<img width="1659" alt="Screenshot 2025-05-21 at 4 37 01 pm"
src="https://github.com/user-attachments/assets/06d85628-edd7-45b4-92cc-034b8bd5c6fa"
/>

**After the fix**
```json
[
    {
        "type": "https://test.uncefact.org/vocabulary/untp/core/0/WebRenderingTemplate2022",
        "renderedTemplate": "PCFET0NUWVBFIGh0bWw+PGh0bWwgbGFuZz0iZW4iPjxoZWFkPiA8bWV0YSBjaGFyc2V0PSJVVEYtOCIgLz4gPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjAiIC8+IDxsaW5rIGhyZWY9Imh0dHBzOi8vZm9udHMuZ29vZ2xlYXBpcy5jb20vY3NzMj9mYW1pbHk9TGF0bzppdGFsLHdnaHRAMCwxMDA7MCwzMDA7MCw0MDA7MCw3MDA7MCw5MDA7MSwxMDA7MSwzMDA7MSw0MDA7MSw3MDA7MSw5MDAmZGlzcGxheT1zd2FwIiByZWw9InN0eWxlc2hlZXQiPiA8dGl0bGU+RGlnaXRhbCBGYWNpbGl0eSBSZWNvcmQ8L3RpdGxlPiA8c3R5bGU+IDpyb290IHsgLyogQnJhbmQgQ29sb3JzICovIC0tY29sb3ItcHJpbWFyeTogcmdiYSgzNSwgNDYsIDYxLCAxKTsgLyogSGVhZGVycywgdGl0bGVzOyBEZWZhdWx0OiByZ2JhKDM1LCA0NiwgNjEsIDEpICovIC0tY29sb3Itc2Vjb25kYXJ5OiByZ2JhKDMxLCA5MCwgMTQ5LCAxKTsgLyogRXZpZGVuY2UgdGl0bGVzOyBEZWZhdWx0OiByZ2JhKDMxLCA5MCwgMTQ5LCAxKSAqLyAvKiBOZXV0cmFscyAqLyAtLWNvbG9yLXdoaXRlOiByZ2JhKDI1NSwgMjU1LCAyNTUsIDEpOyAvKiBUZXh0LCBiYWNrZ3JvdW5kczsgRGVmYXVsdDogcmdiYSgyNTUsIDI1NSwgMjU1LCAxKSAqLyAtLWNvbG9yLWJsYWNrOiByZ2JhKDAsIDAsIDAsIDEpOyAvKiBUZXh0OyBEZWZhdWx0OiByZ2JhKDAsIDAsIDAsIDEpICovIC0tY29sb3ItZ3JheS03MDA6IHJnYmEoMzUsIDQ2LCA2MSwgMSk7IC8qIFRleHQsIG1hdGNoZXMgcHJpbWFyeTsgRGVmYXVsdDogcmdiYSgzNSwgNDYsIDYxLCAxKSAqLyAtLWNvbG9yLWdyYXktNjAwOiByZ2JhKDg1LCA5NiwgMTEwLCAxKTsgLyogQmFja2dyb3VuZHMsIHRleHQ7IERlZmF1bHQ6IHJnYmEoODUsIDk2LCAxMTAsIDEpICovIC0tY29sb3ItZ3JheS01MDA6IHJnYmEoMTY5LCAxNzcsIDE4MywgMSk7IC8qIEJvcmRlcnM7IERlZmF1bHQ6IHJnYmEoMTY5LCAxNzcsIDE4MywgMSkgKi8gLS1jb2xvci1ncmF5LTQwMDogcmdiYSgyMTIsIDIxNCwgMjE2LCAxKTsgLyogQm9yZGVyczsgRGVmYXVsdDogcmdiYSgyMTIsIDIxNCwgMjE2LCAxKSAqLyAtLWNvbG9yLWdyYXktMzAwOiByZ2JhKDIzNywgMjM5LCAyNDAsIDEpOyAvKiBCYWNrZ3JvdW5kcywgdGV4dDsgRGVmYXVsdDogcmdiYSgyMzcsIDIzOSwgMjQwLCAxKSAqLyAvKiBTZW1hbnRpYyAoRnVuY3Rpb25hbCkgQ29sb3JzICovIC0tY29sb3Itc3VjY2Vzcy1iZzogcmdiYSgxODQsIDIzNiwgMTgyLCAxKTsgLyogU3VjY2VzcyBiYWRnZSBiYWNrZ3JvdW5kOyBEZWZhdWx0OiByZ2JhKDE4NCwgMjM2LCAxODIsIDEpICovIC0tY29sb3Itc3VjY2Vzcy10ZXh0OiByZ2JhKDgsIDUwLCAwLCAxKTsgLyogU3VjY2VzcyBiYWRnZSB0ZXh0OyBEZWZhdWx0OiByZ2JhKDgsIDUwLCAwLCAxKSAqLyAtLWNvbG9yLWVycm9yLWJnOiByZ2JhKDI1NSwgMTg4LCAxODMsIDEpOyAvKiBFcnJvciBiYWRnZSBiYWNrZ3JvdW5kOyBEZWZhdWx0OiByZ2JhKDI1NSwgMTg4LCAxODMsIDEpICovIC0tY29sb3ItZXJyb3ItdGV4dDogcmdiYSg1MCwgMCwgMCwgMSk7IC8qIEVycm9yIGJhZGdlIHRleHQ7IERlZmF1bHQ6IHJnYmEoNTAsIDAsIDAsIDEpICovIC0tY29sb3ItbGluay11bmRlcmxpbmUtZGFyazogcmdiYSg3OSwgMTQ5LCAyMjEsIDEpOyAvKiBMaW5rIHVuZGVybGluZXM7IERlZmF1bHQ6IHJnYmEoNzksIDE0OSwgMjIxLCAxKSAqLyAtLWNvbG9yLWxpbmstdW5kZXJsaW5lLWxpZ2h0OiByZ2JhKDE0OCwgMTk2LCAyNDUsIDEpOyAvKiBMaW5rIHVuZGVybGluZXM7IERlZmF1bHQ6IHJnYmEoMTQ4LCAxOTYsIDI0NSwgMSkgKi8gLS1jb2xvci1pY29uOiAjMUY1QTk1OyAvKiBTVkcgZmlsbCwgc3Ryb2tlOyBEZWZhdWx0OiAjMUY1QTk1ICovIC8qIEZvbnQgVmFyaWFibGVzICovIC0tZm9udC1mYW1pbHk6ICJMYXRvIiwgc2Fucy1zZXJpZjsgLyogQWxsIHRleHQ7IERlZmF1bHQ6IExhdG8gZm9udCAqLyAvKiBGb250IFdlaWdodCBWYXJpYWJsZXMgKi8gLS1mb250LXdlaWdodC1yZWd1bGFyOiA0MDA7IC8qIFN0YW5kYXJkIHRleHQ7IERlZmF1bHQ6IDQwMCAqLyAtLWZvbnQtd2VpZ2h0LW1lZGl1bTogNTAwOyAvKiBUaXRsZXMsIGVtcGhhc2l6ZWQgdGV4dDsgRGVmYXVsdDogNTAwICovIC0tZm9udC13ZWlnaHQtc2VtaS1ib2xkOiA2MDA7IC8qIEJhZGdlczsgRGVmYXVsdDogNjAwICovIC0tZm9udC13ZWlnaHQtYm9sZDogNzAwOyAvKiBIZWFkaW5nczsgRGVmYXVsdDogNzAwICovIC0tZm9udC13ZWlnaHQtYmxhY2s6IDkwMDsgLyogTWFpbiB0aXRsZXM7IERlZmF1bHQ6IDkwMCAqLyB9IC8qIEdsb2JhbHMgQ1NTICovICogeyBtYXJnaW46IDA7IGJveC1zaXppbmc6IGJvcmRlci1ib3g7IH0gYm9keSB7IGZvbnQtZmFtaWx5OiB2YXIoLS1mb250LWZhbWlseSk7IH0gc2VjdGlvbiB7IHBhZGRpbmc6IDAgMTZweCAwIDE2cHg7IH0gYSB7IHRleHQtZGVjb3JhdGlvbjogbm9uZTsgfSAuZmFjaWxpdHktcmVjb3JkIHsgd2lkdGg6IDEwMCU7IG1hcmdpbjogMCBhdXRvOyBkaXNwbGF5OiBmbGV4OyBmbGV4LWRpcmVjdGlvbjogY29sdW1uOyBnYXA6IDMycHg7IH0gLmZhY2lsaXR5LXJlY29yZC1oZWFkZXIgeyBkaXNwbGF5OiBmbGV4OyBmbGV4LWRpcmVjdGlvbjogY29sdW1uOyB3aWR0aDogMTAwJTsgYWxpZ24taXRlbXM6IGNlbnRlcjsgfSAuZmFjaWxpdHktaGVhZGVyIHsgZGlzcGxheTogZmxleDsgZmxleC1kaXJlY3Rpb246IGNvbHVtbjsgd2lkdGg6IDEwMCU7IGFsaWduLWl0ZW1zOiBmbGV4LXN0YXJ0OyBnYXA6IDEycHg7IHBhZGRpbmc6IDMycHggMTZweCAyMHB4IDE2cHg7IGJhY2tncm91bmQtY29sb3I6IHZhcigtLWNvbG9yLXByaW1hcnkpOyB9IC5mYWNpbGl0eS1yZWNvcmQgLmZhY2lsaXR5LXRpdGxlIHsgd2lkdGg6IDEwMCU7IGZvbnQtd2VpZ2h0OiB2YXIoLS1mb250LXdlaWdodC1tZWRpdW0pOyBjb2xvcjogdmFyKC0tY29sb3Itd2hpdGUpOyBmb250LXNpemU6IDE2cHg7IGxpbmUtaGVpZ2h0OiAyMnB4OyB0ZXh0LXRyYW5zZm9ybTogdXBwZXJjYXNlOyB9IC5mYWNpbGl0eS1yZWNvcmQgLm5hbWUtZGVzY3JpcHRpb24geyBkaXNwbGF5OiBmbGV4OyBmbGV4LWRpcmVjdGlvbjogY29sdW1uOyBnYXA6IDhweDsgfSAuZmFjaWxpdHktcmVjb3JkIC5uYW1lLWRlc2NyaXB0aW9uIGgxIHsgZm9udC13ZWlnaHQ6IHZhcigtLWZvbnQtd2VpZ2h0LWJsYWNrKTsgY29sb3I6IHZhcigtLWNvbG9yLXdoaXRlKTsgZm9udC1zaXplOiAzMHB4OyBsaW5lLWhlaWdodDogMzIuNXB4OyB9IC5mYWNpbGl0eS1yZWNvcmQgLm5hbWUtZGVzY3JpcHRpb24gcCB7IGZvbnQtd2VpZ2h0OiB2YXIoLS1mb250LXdlaWdodC1tZWRpdW0pOyBjb2xvcjogdmFyKC0tY29sb3Itd2hpdGUpOyBmb250LXNpemU6IDE2cHg7IGxpbmUtaGVpZ2h0OiAxNy40cHg7IH0gLmZhY2lsaXR5LXJlY29yZCAuZmFjaWxpdHktZGV0YWlscy1zZWN0aW9uIHsgcGFkZGluZzogMHB4IDE2cHggMTZweDsgYWxpZ24tc2VsZjogc3RyZXRjaDsgd2lkdGg6IDEwMCU7IGRpc3BsYXk6IGZsZXg7IGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47IGFsaWduLWl0ZW1zOiBmbGV4LXN0YXJ0OyBnYXA6IDRweDsgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tY29sb3ItZ3JheS02MDApOyB9IC5mYWNpbGl0eS1yZWNvcmQgLmdyaWQtcm93IHsgZGlzcGxheTogZ3JpZDsgZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zOiAxZnIgMmZyOyBnYXA6IDE2cHg7IHBhZGRpbmc6IDEwcHggMHB4IDEycHg7IHdpZHRoOiAxMDAlOyBib3JkZXItYm90dG9tLXdpZHRoOiAxcHg7IGJvcmRlci1ib3R0b20tc3R5bGU6IHNvbGlkOyB9IC5mYWNpbGl0eS1yZWNvcmQgLmdyaWQtcm93Omxhc3QtY2hpbGQgeyBib3JkZXItYm90dG9tOiBub25lOyB9IC5mYWNpbGl0eS1yZWNvcmQgLmRlY2xhcmF0aW9ucyB7IGRpc3BsYXk6IGZsZXg7IGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47IGdhcDogMTJweDsgcGFkZGluZzogMHB4IDE2cHg7IHdpZHRoOiAxMDAlOyB9IC5mYWNpbGl0eS1yZWNvcmQgLmRlY2xhcmF0aW9uLXRpdGxlIHsgZm9udC1zaXplOiAyMHB4OyBmb250LXdlaWdodDogdmFyKC0tZm9udC13ZWlnaHQtYm9sZCk7IGxpbmUtaGVpZ2h0OiAyMS44cHg7IGNvbG9yOiB2YXIoLS1jb2xvci1ncmF5LTcwMCk7IH0gLmZhY2lsaXR5LXJlY29yZCAuY29uZm9ybWl0aWVzLWxpc3QgeyBkaXNwbGF5OiBmbGV4OyBmbGV4LWRpcmVjdGlvbjogY29sdW1uOyBnYXA6IDhweDsgfSAuZmFjaWxpdHktcmVjb3JkIC5jb25mb3JtaXR5LWNhcmQgeyBkaXNwbGF5OiBmbGV4OyBmbGV4LWRpcmVjdGlvbjogY29sdW1uOyBhbGlnbi1pdGVtczogZmxleC1zdGFydDsgZ2FwOiA4cHg7IG1pbi13aWR0aDogMzM2cHg7IHBhZGRpbmc6IDE2cHggMThweCAxNnB4IDE2cHg7IHBvc2l0aW9uOiByZWxhdGl2ZTsgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tY29sb3Itd2hpdGUpOyBib3JkZXItcmFkaXVzOiA0cHg7IGJvcmRlcjogMXB4IHNvbGlkOyBib3JkZXItY29sb3I6IHZhcigtLWNvbG9yLWdyYXktNDAwKTsgfSAuZmFjaWxpdHktcmVjb3JkIC5jb25mb3JtYW5jZS1oZWFkZXIgeyBkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47IHBvc2l0aW9uOiByZWxhdGl2ZTsgYWxpZ24tc2VsZjogc3RyZXRjaDsgd2lkdGg6IDEwMCU7IGZsZXg6IDAgMCBhdXRvOyB9IC5mYWNpbGl0eS1yZWNvcmQgLmNvbmZvcm1hbmNlLXN0YXR1cyB7IGRpc3BsYXk6IGlubGluZS1mbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDRweDsgcG9zaXRpb246IHJlbGF0aXZlOyBmbGV4OiAwIDAgYXV0bzsgfSAuZmFjaWxpdHktcmVjb3JkIC5jb25mb3JtYW5jZS1sYWJlbCB7IHBvc2l0aW9uOiByZWxhdGl2ZTsgd2lkdGg6IGZpdC1jb250ZW50OyBmb250LXdlaWdodDogdmFyKC0tZm9udC13ZWlnaHQtcmVndWxhcik7IGNvbG9yOiB2YXIoLS1jb2xvci1ncmF5LTYwMCk7IGZvbnQtc2l6ZTogMTRweDsgbGluZS1oZWlnaHQ6IDE5LjJweDsgfSAuZmFjaWxpdHktcmVjb3JkIC50YWdzLVZDLWJhZGdlLXJlZCB7IGRpc3BsYXk6IGlubGluZS1mbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjsgZ2FwOiAxMHB4OyBwYWRkaW5nOiA0cHggOHB4OyBmbGV4OiAwIDAgYXV0bzsgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tY29sb3ItZXJyb3ItYmcpOyBjb2xvcjogdmFyKC0tY29sb3ItZXJyb3ItdGV4dCk7IGJvcmRlci1yYWRpdXM6IDhweDsgb3ZlcmZsb3c6IGhpZGRlbjsgfSAuZmFjaWxpdHktcmVjb3JkIC50YWdzLVZDLWJhZGdlLWdyZWVuIHsgZGlzcGxheTogaW5saW5lLWZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGp1c3RpZnktY29udGVudDogY2VudGVyOyBnYXA6IDEwcHg7IHBhZGRpbmc6IDRweCA4cHg7IGZsZXg6IDAgMCBhdXRvOyBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1jb2xvci1zdWNjZXNzLWJnKTsgY29sb3I6IHZhcigtLWNvbG9yLXN1Y2Nlc3MtdGV4dCk7IGJvcmRlci1yYWRpdXM6IDhweDsgb3ZlcmZsb3c6IGhpZGRlbjsgfSAuZmFjaWxpdHktcmVjb3JkIC52ZXJpZmlhYmxlIHsgd2lkdGg6IGZpdC1jb250ZW50OyBmb250LXdlaWdodDogdmFyKC0tZm9udC13ZWlnaHQtc2VtaS1ib2xkKTsgZm9udC1zaXplOiAxNHB4OyBsaW5lLWhlaWdodDogMTUuM3B4OyB9IC5mYWNpbGl0eS1yZWNvcmQgLmV2aWRlbmNlLWRldGFpbHMgeyBkaXNwbGF5OiBmbGV4OyBmbGV4LWRpcmVjdGlvbjogY29sdW1uOyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDRweDsgcG9zaXRpb246IHJlbGF0aXZlOyBhbGlnbi1zZWxmOiBzdHJldGNoOyB3aWR0aDogMTAwJTsgZmxleDogMCAwIGF1dG87IH0gLmZhY2lsaXR5LXJlY29yZCAuZmFjaWxpdHktbmFtZSB7IHBvc2l0aW9uOiByZWxhdGl2ZTsgYWxpZ24tc2VsZjogc3RyZXRjaDsgbWFyZ2luLXRvcDogLTFweDsgZm9udC13ZWlnaHQ6IHZhcigtLWZvbnQtd2VpZ2h0LXJlZ3VsYXIpOyBjb2xvcjogdmFyKC0tY29sb3Itc2Vjb25kYXJ5KTsgZm9udC1zaXplOiAxOHB4OyBsaW5lLWhlaWdodDogMjEuMnB4OyB9IC5mYWNpbGl0eS1yZWNvcmQgLnJlZ3VsYXRpb24tZGV0YWlscyB7IGNvbG9yOiB2YXIoLS1jb2xvci1ncmF5LTYwMCk7IGZvbnQtc2l6ZTogMTRweDsgbGluZS1oZWlnaHQ6IDE5LjJweDsgYWxpZ24tc2VsZjogc3RyZXRjaDsgZm9udC13ZWlnaHQ6IHZhcigtLWZvbnQtd2VpZ2h0LXJlZ3VsYXIpOyB9IC5mYWNpbGl0eS1yZWNvcmQgLnJlZ3VsYXRpb24tZGV0YWlscy10ZXh0IHsgZm9udC13ZWlnaHQ6IHZhcigtLWZvbnQtd2VpZ2h0LXJlZ3VsYXIpOyBmb250LXNpemU6IDE0cHg7IGxpbmUtaGVpZ2h0OiAxOS4ycHg7IH0gLmZhY2lsaXR5LXJlY29yZCAucmVndWxhdGlvbi1saW5rIHsgY29sb3I6IHZhcigtLWNvbG9yLWdyYXktNjAwKTsgfSAuZmFjaWxpdHktcmVjb3JkIC5ncmF5LWJvdHRvbS1saW5lIHsgYm9yZGVyLWJvdHRvbTogMXB4IHZhcigtLWNvbG9yLWdyYXktNjAwKSBzb2xpZDsgd2lkdGg6IGZpdC1jb250ZW50OyB0ZXh0LWRlY29yYXRpb246IG5vbmU7IH0gLmZhY2lsaXR5LXJlY29yZCAubWV0cmljcy1saXN0IHsgZGlzcGxheTogZmxleDsgZmxleC1kaXJlY3Rpb246IGNvbHVtbjsgYWxpZ24taXRlbXM6IGZsZXgtc3RhcnQ7IGp1c3RpZnktY29udGVudDogZmxleC1lbmQ7IGdhcDogOHB4OyBhbGlnbi1zZWxmOiBzdHJldGNoOyB3aWR0aDogMTAwJTsgfSAuZmFjaWxpdHktcmVjb3JkIC5tZXRyaWMtaXRlbSB7IGRpc3BsYXk6IGZsZXg7IGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47IGFsaWduLWl0ZW1zOiBmbGV4LXN0YXJ0OyBnYXA6IDhweDsgZmxleDogMTsgZmxleC1ncm93OiAxOyB9IC5mYWNpbGl0eS1yZWNvcmQgLnR5cG9ncmFwaHktaGVhZGluZyB7IGRpc3BsYXk6IGlubGluZS1mbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjsgZ2FwOiAxMHB4OyB9IC5mYWNpbGl0eS1yZWNvcmQgLm1ldHJpYy12YWx1ZSB7IGZsZXg6IDE7IGNvbG9yOiB2YXIoLS1jb2xvci1ncmF5LTcwMCk7IGZvbnQtc2l6ZTogMTZweDsgZm9udC13ZWlnaHQ6IHZhcigtLWZvbnQtd2VpZ2h0LXJlZ3VsYXIpOyBsaW5lLWhlaWdodDogMTcuNDRweDsgfSAuZmFjaWxpdHktcmVjb3JkIC5tZXRyaWMtc2NvcmUgeyBmbGV4OiAxOyBmb250LXdlaWdodDogdmFyKC0tZm9udC13ZWlnaHQtcmVndWxhcik7IGNvbG9yOiB2YXIoLS1jb2xvci1ncmF5LTYwMCk7IGZvbnQtc2l6ZTogMTRweDsgbGluZS1oZWlnaHQ6IDE5LjJweDsgfSAuZmFjaWxpdHktcmVjb3JkIC5ldmlkZW5jZS1saW5rLWNvbnRhaW5lciB7IGRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjsgcGFkZGluZzogOHB4IDBweDsgcG9zaXRpb246IHJlbGF0aXZlOyBhbGlnbi1zZWxmOiBzdHJldGNoOyB3aWR0aDogMTAwJTsgZmxleDogMCAwIGF1dG87IGJvcmRlci1yYWRpdXM6IDRweDsgfSAuZmFjaWxpdHktcmVjb3JkIC5ldmlkZW5jZS1saW5rIHsgZGlzcGxheTogaW5saW5lLWZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGdhcDogOHB4OyBwb3NpdGlvbjogcmVsYXRpdmU7IGZsZXg6IDAgMCBhdXRvOyB9IC5mYWNpbGl0eS1yZWNvcmQgLmV2aWRlbmNlLWxhYmVsLXdyYXBwZXIgeyBkaXNwbGF5OiBmbGV4OyBmbGV4LWRpcmVjdGlvbjogY29sdW1uOyB3aWR0aDogMjYwcHg7IGFsaWduLWl0ZW1zOiBmbGV4LXN0YXJ0OyBnYXA6IDRweDsgfSAuZmFjaWxpdHktcmVjb3JkIC5ldmlkZW5jZS10ZXh0IHsgY29sb3I6IHZhcigtLWNvbG9yLWJsYWNrKTsgZm9udC1zaXplOiAxNnB4OyBsaW5lLWhlaWdodDogMTcuNHB4OyBhbGlnbi1zZWxmOiBzdHJldGNoOyBmb250LXdlaWdodDogdmFyKC0tZm9udC13ZWlnaHQtcmVndWxhcik7IH0gLmZhY2lsaXR5LXJlY29yZCAuaXNzdWluZy1kZXRhaWxzIHsgd2lkdGg6IDEwMCU7IHBhZGRpbmc6IDI0cHggMTZweCAzNnB4OyBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1jb2xvci1ncmF5LTMwMCk7IGRpc3BsYXk6IGZsZXg7IGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47IGFsaWduLWl0ZW1zOiBmbGV4LXN0YXJ0OyBnYXA6IDRweDsgfSAuZmFjaWxpdHktcmVjb3JkIC50eXBvZ3JhcGh5LWhlYWRpbmcgeyBkaXNwbGF5OiBpbmxpbmUtZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsganVzdGlmeS1jb250ZW50OiBjZW50ZXI7IGdhcDogMTBweDsgfSAuZmFjaWxpdHktcmVjb3JkIC5pc3N1aW5nLXRpdGxlIHsgd2lkdGg6IGZpdC1jb250ZW50OyBmb250LXdlaWdodDogdmFyKC0tZm9udC13ZWlnaHQtYm9sZCk7IGNvbG9yOiB2YXIoLS1jb2xvci1ibGFjayk7IGZvbnQtc2l6ZTogMjBweDsgbGluZS1oZWlnaHQ6IDIxLjhweDsgfSAuZmFjaWxpdHktcmVjb3JkIC5mYWNpbGl0eS1kZXRhaWxzIHsgZGlzcGxheTogaW5saW5lLWZsZXg7IGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47IGFsaWduLWl0ZW1zOiBmbGV4LXN0YXJ0OyB3aWR0aDogMTAwJTsgfSAuZmFjaWxpdHktcmVjb3JkIC5ncmlkLXJvdy1hbHQgeyBkaXNwbGF5OiBncmlkOyBncmlkLXRlbXBsYXRlLWNvbHVtbnM6IDEuNGZyIDNmcjsgZ2FwOiAxNnB4OyBwYWRkaW5nOiAxMHB4IDBweCAxMnB4OyB3aWR0aDogMTAwJTsgYm9yZGVyLWJvdHRvbS13aWR0aDogMXB4OyBib3JkZXItYm90dG9tLXN0eWxlOiBzb2xpZDsgfSAuZmFjaWxpdHktcmVjb3JkIC5ib3JkZXItYm90dG9tLWdyYXktNDAwIHsgYm9yZGVyLWNvbG9yOiB2YXIoLS1jb2xvci1ncmF5LTQwMCk7IH0gLmZhY2lsaXR5LXJlY29yZCAuYm9yZGVyLWJvdHRvbS1ncmF5LTUwMCB7IGJvcmRlci1jb2xvcjogdmFyKC0tY29sb3ItZ3JheS01MDApOyB9IC5mYWNpbGl0eS1yZWNvcmQgLmxhYmVsIHsgZm9udC13ZWlnaHQ6IHZhcigtLWZvbnQtd2VpZ2h0LXJlZ3VsYXIpOyBjb2xvcjogdmFyKC0tY29sb3ItZ3JheS0zMDApOyBmb250LXNpemU6IDE2cHg7IGxpbmUtaGVpZ2h0OiAyMnB4OyB9IC5mYWNpbGl0eS1yZWNvcmQgLmxhYmVsLWFsdCB7IGZvbnQtd2VpZ2h0OiB2YXIoLS1mb250LXdlaWdodC1yZWd1bGFyKTsgY29sb3I6IHZhcigtLWNvbG9yLWdyYXktNjAwKTsgZm9udC1zaXplOiAxNnB4OyBsaW5lLWhlaWdodDogMjJweDsgfSAuZmFjaWxpdHktcmVjb3JkIC5ncmlkLXZhbHVlLWxpbmsgeyBmbGV4LWRpcmVjdGlvbjogY29sdW1uOyBhbGlnbi1pdGVtczogZmxleC1zdGFydDsgZ2FwOiA2cHg7IGFsaWduLXNlbGY6IHN0cmV0Y2g7IGRpc3BsYXk6IGZsZXg7IGZsZXg6IDE7IGZsZXgtZ3JvdzogMTsgfSAuZmFjaWxpdHktcmVjb3JkIC5kaXYtd3JhcHBlciB7IGdhcDogMTBweDsgZGlzcGxheTogaW5saW5lLWZsZXg7IGFsaWduLWl0ZW1zOiBmbGV4LXN0YXJ0OyB0ZXh0LWRlY29yYXRpb246IHVuZGVybGluZTsgdGV4dC1kZWNvcmF0aW9uLXRoaWNrbmVzczogMnB4OyB0ZXh0LWRlY29yYXRpb24tY29sb3I6IHZhcigtLWNvbG9yLWxpbmstdW5kZXJsaW5lLWRhcmspOyB0ZXh0LXVuZGVybGluZS1vZmZzZXQ6IDNweDsgfSAuZmFjaWxpdHktcmVjb3JkIC5tYXAtbGluayB7IGRpc3BsYXk6IGlubGluZS1mbGV4OyBhbGlnbi1pdGVtczogZmxleC1zdGFydDsgZ2FwOiAxMHB4OyBib3JkZXItYm90dG9tLXdpZHRoOiAycHg7IGJvcmRlci1ib3R0b20tc3R5bGU6IHNvbGlkOyBib3JkZXItY29sb3I6IHZhcigtLWNvbG9yLWxpbmstdW5kZXJsaW5lLWxpZ2h0KTsgfSAuZmFjaWxpdHktcmVjb3JkIC5tYXAtbGluay10ZXh0IHsgd2lkdGg6IGZpdC1jb250ZW50OyBmb250LXdlaWdodDogdmFyKC0tZm9udC13ZWlnaHQtbWVkaXVtKTsgY29sb3I6IHZhcigtLWNvbG9yLXdoaXRlKTsgZm9udC1zaXplOiAxNnB4OyBsaW5lLWhlaWdodDogMTcuNHB4OyB9IC5mYWNpbGl0eS1yZWNvcmQgLmlzc3Vlci1saW5rIHsgd2lkdGg6IGZpdC1jb250ZW50OyBmb250LXdlaWdodDogdmFyKC0tZm9udC13ZWlnaHQtbWVkaXVtKTsgY29sb3I6IHZhcigtLWNvbG9yLWdyYXktNzAwKTsgZm9udC1zaXplOiAxNnB4OyBsaW5lLWhlaWdodDogMjJweDsgfSAuZmFjaWxpdHktcmVjb3JkIC5tYXAtbGluay13cmFwcGVyIHsgZGlzcGxheTogaW5saW5lLWZsZXg7IGFsaWduLWl0ZW1zOiBmbGV4LXN0YXJ0OyBnYXA6IDEwcHg7IGJvcmRlci1ib3R0b20td2lkdGg6IDJweDsgYm9yZGVyLWJvdHRvbS1zdHlsZTogc29saWQ7IGJvcmRlci1jb2xvcjogdmFyKC0tY29sb3ItbGluay11bmRlcmxpbmUtZGFyayk7IH0gLmZhY2lsaXR5LXJlY29yZCAuZ3JpZC12YWx1ZSB7IGRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGdhcDogMTBweDsgYWxpZ24tc2VsZjogc3RyZXRjaDsgZmxleC1ncm93OiAxOyBmbGV4OiAxOyB9IC5mYWNpbGl0eS1yZWNvcmQgLmdyaWQtdmFsdWUtbGlzdCB7IGRpc3BsYXk6IGZsZXg7IGZsZXgtd3JhcDogd3JhcDsgcm93LWdhcDogNHB4OyBtYXgtd2lkdGg6IDEwMCU7IH0gLmZhY2lsaXR5LXJlY29yZCAuZ3JpZC12YWx1ZS1saXN0IGEgeyBtYXJnaW4tcmlnaHQ6IDEwcHg7IH0gLmZhY2lsaXR5LXJlY29yZCAuZ3JpZC12YWx1ZS10ZXh0IHsgZmxleDogMTsgZm9udC13ZWlnaHQ6IHZhcigtLWZvbnQtd2VpZ2h0LW1lZGl1bSk7IGNvbG9yOiB2YXIoLS1jb2xvci13aGl0ZSk7IGZvbnQtc2l6ZTogMTZweDsgbGluZS1oZWlnaHQ6IDE3LjRweDsgfSAuZmFjaWxpdHktcmVjb3JkIC5ncmlkLXZhbHVlLXRleHQtYWx0IHsgZm9udC13ZWlnaHQ6IHZhcigtLWZvbnQtd2VpZ2h0LW1lZGl1bSk7IGNvbG9yOiB2YXIoLS1jb2xvci1ncmF5LTcwMCk7IGZvbnQtc2l6ZTogMTZweDsgbGluZS1oZWlnaHQ6IDE3LjRweDsgZmxleDogMTsgfSAuYmx1ZS1ib3R0b20tbGluZS0yLCAuYmx1ZS1ib3R0b20tbGluZS0yOmxpbmsgeyB3aWR0aDogZml0LWNvbnRlbnQ7IGNvbG9yOiB2YXIoLS1jb2xvci13aGl0ZSk7IHRleHQtZGVjb3JhdGlvbjogdW5kZXJsaW5lOyB0ZXh0LWRlY29yYXRpb24tdGhpY2tuZXNzOiAycHg7IHRleHQtZGVjb3JhdGlvbi1jb2xvcjogdmFyKC0tY29sb3ItbGluay11bmRlcmxpbmUtbGlnaHQpOyB0ZXh0LXVuZGVybGluZS1vZmZzZXQ6IDNweDsgfSAud2hpdGUtdGV4dCB7IGNvbG9yOiB2YXIoLS1jb2xvci13aGl0ZSk7IH0gLyogTWVkaWEgUXVlcmllcyBmb3IgRGVza3RvcHMgKi8gQG1lZGlhIChtaW4td2lkdGg6IDEyMDBweCkgeyAuZmFjaWxpdHktcmVjb3JkIHsgbWF4LXdpZHRoOiAxMjAwcHg7IH0gfSA8L3N0eWxlPjwvaGVhZD48Ym9keT4gPGRpdiBjbGFzcz0iZmFjaWxpdHktcmVjb3JkIj4gPGRpdiBjbGFzcz0iZmFjaWxpdHktcmVjb3JkLWhlYWRlciI+IDxoZWFkZXIgY2xhc3M9ImZhY2lsaXR5LWhlYWRlciI+IDxkaXYgY2xhc3M9ImZhY2lsaXR5LXRpdGxlIj5GQUNJTElUWSBSRUNPUkQ8L2Rpdj4gPGRpdiBjbGFzcz0ibmFtZS1kZXNjcmlwdGlvbiI+IDxoMT5FY29DaGFyZ2UgU3lkbmV5IE1hbnVmYWN0dXJpbmcgUGxhbnQ8L2gxPiAgPHA+U3RhdGUtb2YtdGhlLWFydCBsaXRoaXVtLWlvbiBiYXR0ZXJ5IG1hbnVmYWN0dXJpbmcgZmFjaWxpdHk8L3A+ICA8L2Rpdj4gPC9oZWFkZXI+IDxzZWN0aW9uIGNsYXNzPSJmYWNpbGl0eS1kZXRhaWxzLXNlY3Rpb24iPiA8ZGl2IGNsYXNzPSJmYWNpbGl0eS1kZXRhaWxzIj4gIDxkaXYgY2xhc3M9ImdyaWQtcm93IGJvcmRlci1ib3R0b20tZ3JheS01MDAiPiA8ZGl2IGNsYXNzPSJsYWJlbCI+T3BlcmF0b3I8L2Rpdj4gPGRpdiBjbGFzcz0iZ3JpZC12YWx1ZSI+IDxhIGhyZWY9Imh0dHBzOi8vaWRyLnVudHAuc2hvd3RoZXRoaW5nLmNvbS9hdG8vYWJuLzIyMTMzODQwMzIyNjU5P2xpbmtUeXBlJiN4M0Q7YXRvOmNlcnRpZmljYXRpb25JbmZvIiBjbGFzcz0iYmx1ZS1ib3R0b20tbGluZS0yIiBhcmlhLWxhYmVsPSJWaXNpdCBFY29DaGFyZ2UgQmF0dGVyeSBTeXN0ZW1zIFB0eSBMdGQiPkVjb0NoYXJnZSBCYXR0ZXJ5IFN5c3RlbXMgUHR5IEx0ZDwvYT4gPC9kaXY+IDwvZGl2PiAgIDxkaXYgY2xhc3M9ImdyaWQtcm93IGJvcmRlci1ib3R0b20tZ3JheS01MDAiPiA8ZGl2IGNsYXNzPSJsYWJlbCI+Q291bnRyeTwvZGl2PiA8ZGl2IGNsYXNzPSJncmlkLXZhbHVlIj4gPGRpdiBjbGFzcz0iZ3JpZC12YWx1ZS10ZXh0Ij5BVTwvZGl2PiA8L2Rpdj4gPC9kaXY+ICAgPGRpdiBjbGFzcz0iZ3JpZC1yb3cgYm9yZGVyLWJvdHRvbS1ncmF5LTUwMCI+IDxkaXYgY2xhc3M9ImxhYmVsIj5BZGRyZXNzPC9kaXY+IDxkaXYgY2xhc3M9ImdyaWQtdmFsdWUiPiAgPGEgaHJlZj0iaHR0cHM6Ly9wbHVzLmNvZGVzLzRSUkg0Nko1K0ZQIiBjbGFzcz0iYmx1ZS1ib3R0b20tbGluZS0yIiBhcmlhLWxhYmVsPSJWaWV3IDEyMyBJbmR1c3RyaWFsIERyaXZlIFN5ZG5leSBvbiBtYXAiIHRhcmdldD0iX2JsYW5rIj4gIDEyMyBJbmR1c3RyaWFsIERyaXZlICAgU3lkbmV5ICAgTlNXICAgMjAwMCAgPC9hPiAgPC9kaXY+IDwvZGl2PiAgIDxkaXYgY2xhc3M9ImdyaWQtcm93IGJvcmRlci1ib3R0b20tZ3JheS01MDAiPiA8ZGl2IGNsYXNzPSJsYWJlbCI+UHJvY2Vzc2VzPC9kaXY+IDxkaXYgY2xhc3M9ImdyaWQtdmFsdWUiPiA8ZGl2IGNsYXNzPSJncmlkLXZhbHVlLWxpc3QiPiAgPGEgaHJlZj0iaHR0cHM6Ly91bnN0YXRzLnVuLm9yZy91bnNkL2NsYXNzaWZpY2F0aW9ucy9FY29uL2lzaWMvMjcyMCIgY2xhc3M9ImJsdWUtYm90dG9tLWxpbmUtMiIgYXJpYS1sYWJlbD0iVmlzaXQgTWFudWZhY3R1cmUgb2YgYmF0dGVyaWVzIGFuZCBhY2N1bXVsYXRvcnMiPk1hbnVmYWN0dXJlIG9mIGJhdHRlcmllcyBhbmQgYWNjdW11bGF0b3JzPC9hPiAgPC9kaXY+IDwvZGl2PiA8L2Rpdj4gICAgIDxkaXYgY2xhc3M9ImdyaWQtcm93IGJvcmRlci1ib3R0b20tZ3JheS01MDAiPiA8ZGl2IGNsYXNzPSJsYWJlbCI+R2VvbG9jYXRpb248L2Rpdj4gPGEgaHJlZj0iaHR0cHM6Ly93d3cuZ29vZ2xlLmNvbS9tYXBzP3E9LTMzLjg2ODgsMTUxLjIwOTMiIGNsYXNzPSJncmlkLXZhbHVlLWxpbmsiIGFyaWEtbGFiZWw9IlZpZXcgZ2VvbG9jYXRpb24gb24gbWFwIiB0YXJnZXQ9Il9ibGFuayI+IDxkaXYgY2xhc3M9Im1hcC1saW5rLXdyYXBwZXIiPiA8ZGl2IGNsYXNzPSJtYXAtbGluay10ZXh0Ij5TaG93IG9uIG1hcDwvZGl2PiA8L2Rpdj4gPC9hPiA8L2Rpdj4gICAgPC9kaXY+IDwvc2VjdGlvbj4gPC9kaXY+ICA8c2VjdGlvbiBjbGFzcz0iZGVjbGFyYXRpb25zIj4gPGgyIGNsYXNzPSJkZWNsYXJhdGlvbi10aXRsZSI+RGVjbGFyYXRpb25zPC9oMj4gPGRpdiBjbGFzcz0iY29uZm9ybWl0aWVzLWxpc3QiPiAgPGFydGljbGUgY2xhc3M9ImNvbmZvcm1pdHktY2FyZCI+IDxoZWFkZXIgY2xhc3M9ImNvbmZvcm1hbmNlLWhlYWRlciI+IDxkaXYgY2xhc3M9ImNvbmZvcm1hbmNlLXN0YXR1cyI+IDxkaXYgY2xhc3M9ImNvbmZvcm1hbmNlLWxhYmVsIj5Db25mb3JtYW5jZTo8L2Rpdj4gPGRpdiBjbGFzcz0idGFncy1WQy1iYWRnZS1ncmVlbiI+IDxkaXYgY2xhc3M9InZlcmlmaWFibGUiPlllczwvZGl2PiA8L2Rpdj4gPC9kaXY+ICA8ZGl2IGNsYXNzPSJjb25mb3JtYW5jZS1sYWJlbCI+QXNzZXNzZWQ6IDIwMjQtMDEtMTU8L2Rpdj4gIDwvaGVhZGVyPiA8ZGl2IGNsYXNzPSJldmlkZW5jZS1kZXRhaWxzIj4gICA8ZGl2IGNsYXNzPSJmYWNpbGl0eS1uYW1lIj5JU08gMTQwMDE6MjAxNSBDZXJ0aWZpY2F0ZTwvZGl2PiAgICAgPHAgY2xhc3M9InJlZ3VsYXRpb24tZGV0YWlscyI+IDxzcGFuIGNsYXNzPSJyZWd1bGF0aW9uLWRldGFpbHMtdGV4dCI+ICBJU08gMTQwMDE6MjAxNSBFbnZpcm9ubWVudGFsIG1hbmFnZW1lbnQgc3lzdGVtcyBpc3N1ZWQgYnkgIDwvc3Bhbj4gPGEgaHJlZj0iaHR0cHM6Ly9pc28ub3JnIiBjbGFzcz0icmVndWxhdGlvbi1saW5rIGdyYXktYm90dG9tLWxpbmUiIGFyaWEtbGFiZWw9IlZpc2l0IEludGVybmF0aW9uYWwgT3JnYW5pemF0aW9uIGZvciBTdGFuZGFyZGl6YXRpb24iPiBJbnRlcm5hdGlvbmFsIE9yZ2FuaXphdGlvbiBmb3IgU3RhbmRhcmRpemF0aW9uIDwvYT4gPC9wPiAgPC9kaXY+ICAgIDxhIGhyZWY9Imh0dHBzOi8vYmF0dGVyeS1tYW51ZmFjdHVyZXIuZXhhbXBsZS5jb20vZXZpZGVuY2UvaXNvMTQwMDEtY2VydGlmaWNhdGUucGRmIiBjbGFzcz0iZXZpZGVuY2UtbGluay1jb250YWluZXIiIGFyaWEtbGFiZWw9IlZpZXcgZXZpZGVuY2UgZm9yICBJU08gMTQwMDE6MjAxNSBFbnZpcm9ubWVudGFsIG1hbmFnZW1lbnQgc3lzdGVtcyI+IDxkaXYgY2xhc3M9ImV2aWRlbmNlLWxpbmsiPiA8c3ZnIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPiA8cGF0aCBkPSJNNSAyMUM0LjQ1IDIxIDMuOTc5MzMgMjAuODA0MyAzLjU4OCAyMC40MTNDMy4xOTY2NyAyMC4wMjE3IDMuMDAwNjcgMTkuNTUwNyAzIDE5VjVDMyA0LjQ1IDMuMTk2IDMuOTc5MzMgMy41ODggMy41ODhDMy45OCAzLjE5NjY3IDQuNDUwNjcgMy4wMDA2NyA1IDNIMTlDMTkuNTUgMyAyMC4wMjEgMy4xOTYgMjAuNDEzIDMuNTg4QzIwLjgwNSAzLjk4IDIxLjAwMDcgNC40NTA2NyAyMSA1VjE5QzIxIDE5LjU1IDIwLjgwNDMgMjAuMDIxIDIwLjQxMyAyMC40MTNDMjAuMDIxNyAyMC44MDUgMTkuNTUwNyAyMS4wMDA3IDE5IDIxSDVaTTUgNVYxOUgxOVY1SDE3VjEyTDE0LjUgMTAuNUwxMiAxMlY1SDVaIiBmaWxsPSJ2YXIoLS1jb2xvci1pY29uKSI+PC9wYXRoPiA8L3N2Zz4gPGRpdiBjbGFzcz0iZXZpZGVuY2UtbGFiZWwtd3JhcHBlciI+IDxkaXYgY2xhc3M9ImV2aWRlbmNlLXRleHQiPkV2aWRlbmNlPC9kaXY+IDwvZGl2PiA8L2Rpdj4gPHN2ZyB3aWR0aD0iMTAiIGhlaWdodD0iMTUiIHZpZXdCb3g9IjAgMCAxMCAxNSIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4gPHBhdGggZD0iTTEgMUw4IDhMMSAxNSIgc3Ryb2tlPSJ2YXIoLS1jb2xvci1pY29uKSIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjwvcGF0aD4gPC9zdmc+IDwvYT4gICA8L2FydGljbGU+ICA8YXJ0aWNsZSBjbGFzcz0iY29uZm9ybWl0eS1jYXJkIj4gPGhlYWRlciBjbGFzcz0iY29uZm9ybWFuY2UtaGVhZGVyIj4gPGRpdiBjbGFzcz0iY29uZm9ybWFuY2Utc3RhdHVzIj4gPGRpdiBjbGFzcz0iY29uZm9ybWFuY2UtbGFiZWwiPkNvbmZvcm1hbmNlOjwvZGl2PiA8ZGl2IGNsYXNzPSJ0YWdzLVZDLWJhZGdlLWdyZWVuIj4gPGRpdiBjbGFzcz0idmVyaWZpYWJsZSI+WWVzPC9kaXY+IDwvZGl2PiA8L2Rpdj4gIDxkaXYgY2xhc3M9ImNvbmZvcm1hbmNlLWxhYmVsIj5Bc3Nlc3NlZDogMjAyNC0wMS0wMTwvZGl2PiAgPC9oZWFkZXI+IDxkaXYgY2xhc3M9ImV2aWRlbmNlLWRldGFpbHMiPiAgIDxkaXYgY2xhc3M9ImZhY2lsaXR5LW5hbWUiPkVtaXNzaW9ucyBSZXBvcnQ8L2Rpdj4gICAgPHAgY2xhc3M9InJlZ3VsYXRpb24tZGV0YWlscyI+IDxzcGFuIGNsYXNzPSJyZWd1bGF0aW9uLWRldGFpbHMtdGV4dCI+ICBOYXRpb25hbCBHcmVlbmhvdXNlIGFuZCBFbmVyZ3kgUmVwb3J0aW5nIChNZWFzdXJlbWVudCkgRGV0ZXJtaW5hdGlvbiAgIGFkbWluaXN0ZXJlZCBpbiBBVSAgYnkgPC9zcGFuPiA8YSBocmVmPSJodHRwczovL3d3dy5kY2NlZXcuZ292LmF1IiBjbGFzcz0icmVndWxhdGlvbi1saW5rIGdyYXktYm90dG9tLWxpbmUiIGFyaWEtbGFiZWw9IlZpc2l0IERlcGFydG1lbnQgb2YgQ2xpbWF0ZSBDaGFuZ2UsIEVuZXJneSwgdGhlIEVudmlyb25tZW50IGFuZCBXYXRlciI+RGVwYXJ0bWVudCBvZiBDbGltYXRlIENoYW5nZSwgRW5lcmd5LCB0aGUgRW52aXJvbm1lbnQgYW5kIFdhdGVyPC9hPiA8L3A+ICAgPC9kaXY+ICA8ZGl2IGNsYXNzPSJtZXRyaWNzLWxpc3QiPiAgPGRpdiBjbGFzcz0ibWV0cmljLWl0ZW0iPiA8ZGl2IGNsYXNzPSJ0eXBvZ3JhcGh5LWhlYWRpbmciPiA8cCBjbGFzcz0ibWV0cmljLXZhbHVlIj5Bbm51YWwgQ08yIEVtaXNzaW9ucyBpcyA1MDAwVE5FPC9wPiA8L2Rpdj4gIDxkaXYgY2xhc3M9InR5cG9ncmFwaHktaGVhZGluZyI+IDxwIGNsYXNzPSJtZXRyaWMtc2NvcmUiPiBTY29yZTogQiAgfCBBY2N1cmFjeSAwLjk1ICA8L3A+IDwvZGl2PiAgPC9kaXY+ICA8L2Rpdj4gICAgPGEgaHJlZj0iaHR0cHM6Ly9iYXR0ZXJ5LW1hbnVmYWN0dXJlci5leGFtcGxlLmNvbS9ldmlkZW5jZS9lbWlzc2lvbnMtcmVwb3J0LnBkZiIgY2xhc3M9ImV2aWRlbmNlLWxpbmstY29udGFpbmVyIiBhcmlhLWxhYmVsPSJWaWV3IGV2aWRlbmNlIGZvciBOYXRpb25hbCBHcmVlbmhvdXNlIGFuZCBFbmVyZ3kgUmVwb3J0aW5nIChNZWFzdXJlbWVudCkgRGV0ZXJtaW5hdGlvbiAiPiA8ZGl2IGNsYXNzPSJldmlkZW5jZS1saW5rIj4gPHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4gPHBhdGggZD0iTTUgMjFDNC40NSAyMSAzLjk3OTMzIDIwLjgwNDMgMy41ODggMjAuNDEzQzMuMTk2NjcgMjAuMDIxNyAzLjAwMDY3IDE5LjU1MDcgMyAxOVY1QzMgNC40NSAzLjE5NiAzLjk3OTMzIDMuNTg4IDMuNTg4QzMuOTggMy4xOTY2NyA0LjQ1MDY3IDMuMDAwNjcgNSAzSDE5QzE5LjU1IDMgMjAuMDIxIDMuMTk2IDIwLjQxMyAzLjU4OEMyMC44MDUgMy45OCAyMS4wMDA3IDQuNDUwNjcgMjEgNVYxOUMyMSAxOS41NSAyMC44MDQzIDIwLjAyMSAyMC40MTMgMjAuNDEzQzIwLjAyMTcgMjAuODA1IDE5LjU1MDcgMjEuMDAwNyAxOSAyMUg1Wk01IDVWMTlIMTlWNUgxN1YxMkwxNC41IDEwLjVMMTIgMTJWNUg1WiIgZmlsbD0idmFyKC0tY29sb3ItaWNvbikiPjwvcGF0aD4gPC9zdmc+IDxkaXYgY2xhc3M9ImV2aWRlbmNlLWxhYmVsLXdyYXBwZXIiPiA8ZGl2IGNsYXNzPSJldmlkZW5jZS10ZXh0Ij5FdmlkZW5jZTwvZGl2PiA8L2Rpdj4gPC9kaXY+IDxzdmcgd2lkdGg9IjEwIiBoZWlnaHQ9IjE1IiB2aWV3Qm94PSIwIDAgMTAgMTUiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+IDxwYXRoIGQ9Ik0xIDFMOCA4TDEgMTUiIHN0cm9rZT0idmFyKC0tY29sb3ItaWNvbikiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj48L3BhdGg+IDwvc3ZnPiA8L2E+ICAgPC9hcnRpY2xlPiAgPC9kaXY+IDwvc2VjdGlvbj4gIDxzZWN0aW9uIGNsYXNzPSJpc3N1aW5nLWRldGFpbHMiPiA8ZGl2IGNsYXNzPSJ0eXBvZ3JhcGh5LWhlYWRpbmciPiA8aDIgY2xhc3M9Imlzc3VpbmctdGl0bGUiPklzc3VpbmcgZGV0YWlsczwvaDI+IDwvZGl2PiA8ZGl2IGNsYXNzPSJmYWNpbGl0eS1kZXRhaWxzIj4gPGRpdiBjbGFzcz0iZ3JpZC1yb3ctYWx0IGJvcmRlci1ib3R0b20tZ3JheS00MDAiPiA8ZGl2IGNsYXNzPSJsYWJlbC1hbHQiPklzc3VlZCBieTwvZGl2PiA8ZGl2IGNsYXNzPSJncmlkLXZhbHVlLWxpbmsiPiA8ZGl2IGNsYXNzPSJkaXYtd3JhcHBlciI+IDxhIGhyZWY9ImRpZDp3ZWI6dW5jZWZhY3QuZ2l0aHViLmlvOnByb2plY3QtdmNraXQ6dGVzdC1hbmQtZGV2ZWxvcG1lbnQiIGNsYXNzPSJpc3N1ZXItbGluayIgYXJpYS1sYWJlbD0iVmlzaXQgRWNvQ2hhcmdlIEJhdHRlcnkgU3lzdGVtcyBQdHkgTHRkIj5FY29DaGFyZ2UgQmF0dGVyeSBTeXN0ZW1zIFB0eSBMdGQ8L2E+IDwvZGl2PiA8L2Rpdj4gPC9kaXY+ICA8ZGl2IGNsYXNzPSJncmlkLXJvdy1hbHQgYm9yZGVyLWJvdHRvbS1ncmF5LTQwMCI+IDxkaXYgY2xhc3M9ImxhYmVsLWFsdCI+VmFsaWQgZnJvbTwvZGl2PiA8ZGl2IGNsYXNzPSJncmlkLXZhbHVlIj4gPGRpdiBjbGFzcz0iZ3JpZC12YWx1ZS10ZXh0LWFsdCI+MjAyNS0wNS0yMVQwNTowODozMy44NzFaPC9kaXY+IDwvZGl2PiA8L2Rpdj4gICA8L2Rpdj4gPC9zZWN0aW9uPiA8L2Rpdj48L2JvZHk+PC9odG1sPg=="
    }
]
```
<img width="1512" alt="Screenshot 2025-05-21 at 4 35 43 pm"
src="https://github.com/user-attachments/assets/f9f312a0-0a90-4589-835c-f2945f06d5e1"
/>


## Added tests?

- [x] 👍 yes
- [ ] 🙅 no, because they aren't needed
- [ ] 🙋 no, because I need help

## Added to documentation?

- [x] 📜 README.md
- [ ] 📓 [vc-kit doc site](https://uncefact.github.io/vckit/)
- [ ] 📕 storybook
- [ ] 🙅 no documentation needed

<!-- note: PRs with deleted sections will be marked invalid -->
…mplate

Adds ssl: ${DATABASE_SSL} to all four TypeORM DataSource connections
(dbConnection, dbConnectionEncrypted, dbConnectionRevocationList,
dbConnectionBitstringStatusList) so managed PostgreSQL providers can
enable SSL via environment variable.

Closes #284
Replace :${PORT} and hardcoded :3332 in basePath with ${BASEPATH_PORT},
which is computed from API_DOMAIN in entrypoint.sh. This prevents the
internal container port from leaking into OpenAPI URLs when deployed
behind a reverse proxy.

Closes #285
- Compute BASEPATH_PORT from API_DOMAIN for correct basePaths behind proxy
- Add DATABASE_SSL and BASEPATH_PORT to envsubst variable list
- Guard DID seeding with SEED_DID env var (default: true)
- Hard fail (exit 1) if did import fails instead of silent success
- Distinct log messages for disabled/skipped/failed seed scenarios

Closes #282
Closes #283
DATABASE_SSL defaults to empty (no SSL) for local development.
SEED_DID defaults to true (backward compatible).
Verifies BASEPATH_PORT extraction from various API_DOMAIN values
and SEED_DID guard behaviour for disabled/skipped/seed scenarios.
Verifies BASEPATH_PORT extraction from various API_DOMAIN values
and SEED_DID guard behaviour for disabled/skipped/seed scenarios.

Also hardens the BASEPATH_PORT case statement to handle IPv6 bracket
notation (e.g. [::1]) without producing garbage output.
The Docker entrypoint now fails hard on DID seed errors instead of
silently continuing. Document the SEED_DID env var for opting out.
Adds documentation for the ssl property on database connections,
including safe values and the custom CA cert limitation.
Updates the Docker note to explain the SEED_DID env var and that
seed failures now cause the container to exit.
- Remove hardcoded v1.2.0 version from breaking change notice in README
  (actual version will be set at release time)
- Change test shebang from #!/bin/sh to #!/bin/bash since the test
  uses the `local` keyword which is not POSIX sh
- local.env: add trailing newline (POSIX text file requirement)
- tests: update run comment from sh to bash to match shebang
- README: clarify SEED_DID=false is exact, case-sensitive match
- entrypoint: note API_DOMAIN must be host or host:port (no path)
- tests: add cases documenting case-sensitivity of SEED_DID check
- Split cat|node pipeline into two steps so cat failures are caught
  independently (pipeline exit code only reflects the last command)
- Add error checking to envsubst template generation
- Include exit code in DID import error message for debugging
- ADR-0001: DATABASE_SSL as simple boolean (rejecting CA cert option)
- ADR-0002: Derive basePath port from API_DOMAIN (rejecting EXTERNAL_PORT)
- ADR-0003: Hard fail on DID seed error with SEED_DID opt-out
- Exclude docs/adr/ from .gitignore
An empty DATABASE_SSL renders as "ssl:" in YAML, which TypeORM
interprets as truthy, enabling SSL. This breaks local dev against
PostgreSQL instances that don't support SSL.

The entrypoint now defaults DATABASE_SSL to "false" when unset or
empty, producing "ssl: false" in YAML which TypeORM correctly
treats as disabled.
All did subcommands (create, delete, import, export, resolve,
add-service, remove-service, add-key, remove-key) caught errors
and logged them but exited with code 0. This made it impossible
for callers to detect failures.

Uses process.exitCode = 1 (not process.exit(1)) to allow Node.js
to finish gracefully while still signalling failure. This matches
the existing pattern in dev.ts.

Only affects CLI usage. The API server invokes agent methods
directly and is unaffected.

Closes #293
- Bump version to 1.2.0
- Soften README "Breaking change" callout to "Behaviour change" since
  affected deployments were already broken (silent did import failures)
Release-As: 1.2.0
# Conflicts:
#	documentation/versioned_docs/version-1.0.1/vckit-plugins/renderer.md
#	package.json
#	version.json
Release-As: 1.2.0
…se/1.2.0

chore(release/1.2.0): release 1.2.0

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements several Docker deployment improvements, including deriving the OpenAPI basePath port from API_DOMAIN to support reverse proxies, adding a DATABASE_SSL environment variable for managed PostgreSQL, and hardening the DID seeding process with a SEED_DID toggle and mandatory error checking. It also updates the renderer package to use standardized IRIs and upgrades the jsonld dependency. Feedback focuses on improving the efficiency of the entrypoint script using shell redirection and adding safety checks when extracting template and URL data from JSON-LD structures to prevent potential runtime crashes.

Comment thread entrypoint.sh
Comment on lines +42 to +43
SEED_DATA=$(cat did-web-identifier.json) || { echo "ERROR: Failed to read did-web-identifier.json"; exit 1; }
printf '%s' "$SEED_DATA" | node packages/cli/build/cli.js did import || { echo "ERROR: DID import failed (exit code $?)"; exit 1; }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Reading the entire seed file into a shell variable and then piping it via printf is inefficient and can hit shell variable size limits for large DID documents. Using direct redirection is more robust and idiomatic.

Suggested change
SEED_DATA=$(cat did-web-identifier.json) || { echo "ERROR: Failed to read did-web-identifier.json"; exit 1; }
printf '%s' "$SEED_DATA" | node packages/cli/build/cli.js did import || { echo "ERROR: DID import failed (exit code $?)"; exit 1; }
node packages/cli/build/cli.js did import < did-web-identifier.json || { echo "ERROR: DID import failed (exit code $?)"; exit 1; }

Comment on lines +101 to +102
const template = data[TEMPLATE_IRI]
? (data[TEMPLATE_IRI] as { '@value': string }[])[0]['@value']

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current extraction logic will throw an error if data[TEMPLATE_IRI] is an empty array (which can happen in some JSON-LD expansion scenarios), as it attempts to access [0]['@value'] without checking if the element exists. Using optional chaining or a length check is safer.

Suggested change
const template = data[TEMPLATE_IRI]
? (data[TEMPLATE_IRI] as { '@value': string }[])[0]['@value']
const template = (data[TEMPLATE_IRI] as { '@value': string }[])?.[0]
? (data[TEMPLATE_IRI] as { '@value': string }[])[0]['@value']

Comment on lines +105 to +106
const url = data[URL_IRI]
? (data[URL_IRI] as { '@value': string }[])[0]['@value']

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Similar to the template extraction, this will crash if data[URL_IRI] is an empty array. A safety check for the first element should be added.

Suggested change
const url = data[URL_IRI]
? (data[URL_IRI] as { '@value': string }[])[0]['@value']
const url = (data[URL_IRI] as { '@value': string }[])?.[0]
? (data[URL_IRI] as { '@value': string }[])[0]['@value']

Comment on lines +40 to +41
const template = data[TEMPLATE_IRI]
? (data[TEMPLATE_IRI] as { '@value': string }[])[0]['@value']

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This extraction logic is vulnerable to a crash if data[TEMPLATE_IRI] is an empty array. It should be hardened to check for the existence of the first element before accessing its properties.

Suggested change
const template = data[TEMPLATE_IRI]
? (data[TEMPLATE_IRI] as { '@value': string }[])[0]['@value']
const template = (data[TEMPLATE_IRI] as { '@value': string }[])?.[0]
? (data[TEMPLATE_IRI] as { '@value': string }[])[0]['@value']

@ashleythedeveloper ashleythedeveloper merged commit 7f9e8fe into main May 1, 2026
2 checks passed
@ashleythedeveloper ashleythedeveloper deleted the release/1.2.0 branch May 1, 2026 03:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants