Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • pagedjs/pagedjs-cli
  • math712b/pagedjs-cli
  • valentin.schabschneider/pagedjs-cli
3 results
Show changes
Commits on Source (78)
Showing
with 192 additions and 281 deletions
.git
*Dockerfile*
*docker-compose*
node_modules
dist
lib
module.exports = {
{
"env": {
"browser": true,
"commonjs": true,
"es6": true,
"node": true,
"browser": true
"jest": true,
"es2022": true
},
"extends": "eslint:recommended",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"extends": "eslint:recommended",
"parserOptions": {
"ecmaVersion": 2018
"sourceType": "module",
"ecmaVersion": 2020
},
"rules": {
"indent": [
"error",
"tab",
{
"VariableDeclarator": { "var": 2, "let": 2, "const": 3 },
"SwitchCase" : 1
}
],
"linebreak-style": [
"error",
"unix"
......@@ -26,8 +35,7 @@ module.exports = {
"error",
"always"
],
"no-unused-vars" : ["warn"],
"no-console" : ["error", { allow: ["log", "warn", "error"] }],
"no-console" : ["error", { "allow": ["warn", "error"] }],
"no-unused-vars": [
"error",
{ "vars": "all", "args": "none" }
......@@ -35,4 +43,4 @@ module.exports = {
"no-mixed-spaces-and-tabs": ["error", "smart-tabs"],
"valid-jsdoc": ["warn"]
}
};
}
node_modules
dist
output
samples
test
\ No newline at end of file
......@@ -3,6 +3,11 @@
# https://hub.docker.com/r/library/node/tags/
image: node:latest
stages:
- test
- deploy
- publish
# This folder is cached between builds
# http://docs.gitlab.com/ce/ci/yaml/README.html#cache
cache:
......@@ -22,4 +27,20 @@ pack:
- npm pack
artifacts:
paths:
- ./*.tgz
\ No newline at end of file
- ./*.tgz
# This job requires to setup GitLab the following way:
# 1. On https://www.npmjs.com/settings/tokens/create
# create a new read/write token (the logged in user must have write access for the `pagedjs` package)
# 2. On https://gitlab.pagedmedia.org/tools/pagedjs/-/settings/ci_cd#js-cicd-variables-settings
# add a new variable named `NPM_TOKEN`, and toggle on _Protected_ and _Masked_
npm-publish:
stage: publish
before_script:
- 'echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc'
- npm install
- npm publish --public --dry-run
script:
- npm publish --public
only:
- tags
\ No newline at end of file
FROM node:12-stretch
FROM ubuntu:jammy
# Application parameters and variables
ENV NODE_ENV=development
ENV PORT=9090
ENV DIRECTORY /home/node/pagedjs-cli
ARG DEBIAN_FRONTEND=noninteractive
ARG TZ=America/Los_Angeles
# Configuration for Chrome
ENV CONNECTION_TIMEOUT=60000
ENV CHROME_PATH=/usr/bin/google-chrome
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
curl \
software-properties-common \
wget \
xvfb \
libxss1 \
dbus \
dbus-x11 \
git \
openssh-client \
&& rm -rf /var/lib/apt/lists/*
# Configuration for GS4JS
ENV GS4JS_HOME=/usr/lib/x86_64-linux-gnu
# Install ghostscript
RUN apt-get update && \
apt-get install -y build-essential make gcc g++ && \
apt-get -y install ghostscript && apt-get clean && \
apt-get install -y libgs-dev && \
rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y \
build-essential make gcc g++ \
python3 \
ghostscript \
libgs-dev \
&& rm -rf /var/lib/apt/lists/*
# See https://github.com/GoogleChrome/puppeteer/blob/master/.ci/node12/Dockerfile.linux
RUN apt-get update && \
apt-get -y install xvfb gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 \
libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 \
libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 \
libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 \
libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget && \
rm -rf /var/lib/apt/lists/*
# Update Freetype
COPY docker-font.conf /etc/fonts/local.conf
ENV FREETYPE_PROPERTIES="truetype:interpreter-version=35"
RUN apt-get update \
&& sh -c 'echo "deb http://http.us.debian.org/debian stable main contrib non-free" >> /etc/apt/sources.list' \
&& apt-get update \
&& apt-get install -y ttf-mscorefonts-installer \
--no-install-recommends \
&& rm -rf /var/lib/apt/lists/*
# Install latest chrome dev package and fonts to support major charsets (Chinese, Japanese, Arabic, Hebrew, Thai and a few others)
# Note: this installs the necessary libs to make the bundled version of Chromium that Puppeteer
# installs, work.
RUN apt-get update && apt-get install -y wget --no-install-recommends \
&& wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
&& sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome-unstable.list' \
&& apt-get update \
&& apt-get install -y google-chrome-unstable fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst ttf-freefont \
--no-install-recommends \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get purge --auto-remove -y curl \
&& rm -rf /src/*.deb
# helps prevent zombie chrome processes.
ADD https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64 /usr/local/bin/dumb-init
RUN chmod +x /usr/local/bin/dumb-init
# Install fonts
# from https://github.com/browserless/browserless/blob/main/docker/chrome/Dockerfile#L11-L27
RUN echo "ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true" | debconf-set-selections && \
apt-get -y -qq install software-properties-common &&\
apt-add-repository "deb http://archive.canonical.com/ubuntu $(lsb_release -sc) partner" && \
apt-get -y -qq --no-install-recommends install \
fontconfig \
fonts-freefont-ttf \
fonts-gfs-neohellenic \
fonts-indic \
fonts-ipafont-gothic \
fonts-kacst \
fonts-liberation \
fonts-noto-cjk \
fonts-noto-color-emoji \
fonts-roboto \
fonts-thai-tlwg \
fonts-ubuntu \
fonts-wqy-zenhei \
&& rm -rf /var/lib/apt/lists/*
ENV NODE_ENV=development
# Install Node.js
RUN apt-get update && \
apt-get install -y vim && \
rm -rf /var/lib/apt/lists/*
mkdir -p /etc/apt/keyrings && \
curl -sL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >> /etc/apt/sources.list.d/nodesource.list && \
apt-get update && \
apt-get install -y nodejs && \
rm -rf /var/lib/apt/lists/*
# Add user so we don't need --no-sandbox.
RUN groupadd --gid 999 node \
&& useradd --uid 999 --gid node --shell /bin/bash --create-home node \
&& adduser node audio \
&& adduser node video
RUN npm install npm@latest -g
RUN npm install -g node-gyp
ENV CONNECTION_TIMEOUT=60000
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
ENV PLAYWRIGHT_BROWSERS_PATH=/usr/local/bin/chromium-browsers
# Revision from https://github.com/microsoft/playwright/blob/main/packages/playwright-core/browsers.json#L6
ENV BROWSER_REVISION=1097
ENV PUPPETEER_EXECUTABLE_PATH="$PLAYWRIGHT_BROWSERS_PATH/chromium-$BROWSER_REVISION/chrome-linux/chrome"
RUN npm install playwright@1.41.1 --location=global
RUN playwright install --with-deps chromium
RUN mkdir -p $DIRECTORY
RUN npm install node-gyp --location=global
# Add user so we don't need --no-sandbox.
# RUN groupadd -r node && useradd -r -g node -G audio,video node \
RUN adduser node audio \
&& adduser node video \
&& mkdir -p /home/node/Downloads \
&& chown -R node:node /home/node \
&& chown -R node:node /usr/lib \
&& chown -R node:node $DIRECTORY
ENV DBUS_SESSION_BUS_ADDRESS autolaunch:
RUN service dbus start
# Run everything after as non-privileged user.
USER node
ENV DIRECTORY /home/node/pagedjs-cli
RUN mkdir -p $DIRECTORY
WORKDIR $DIRECTORY
COPY --chown=node:node package.json $DIRECTORY
COPY --chown=node:node package.json package-lock.json rollup.config.js src/browser.js $DIRECTORY/
COPY --chown=node:node src/browser.js $DIRECTORY/src/
RUN npm install
RUN npm install ghostscript4js
RUN GS4JS_HOME="/usr/lib/$(gcc -dumpmachine)" npm install ghostscript4js
COPY --chown=node:node . $DIRECTORY
EXPOSE $PORT
ENTRYPOINT ["dumb-init", "--"]
CMD ["./bin/paged"]
CMD ["./src/cli.js"]
......@@ -17,42 +17,42 @@ pagedjs-cli ./path/to/index.html -o result.pdf
## Options
```
-V, --version output the version number
-i, --inputs [inputs] Inputs
-o, --output [output] Output
-d, --debug Debug
-l, --landscape Landscape printing (default: false)
-s, --page-size [size] Print to Page Size [size]
-w, --width [size] Print to Page Width [width] in MM
-h --height [size] Print to Page Height [weight] in MM
-t, --timeout [ms] Set a max timeout of [ms]
-x, --html output html file
-b, --blockLocal Disallow access to filesystem for local files
-r, --blockRemote Disallow requests to remote servers
--allowedPath [allowedPaths] Only allow access to given filesystem paths, repeatable. (default: [])
--allowedDomain [allowedDomains] Only allow access to given remote domains, repeatable (default: [])
--outline-tags [tags] Specifies that an outline should be generated for the resulting PDF
document. [tags] specifies which HTML tags should be considered for that
outline. "h1,h2" will trigger an outline with "h1" tags as root elements
and "h2" elements as their childs.
--additional-script <script> Additional script tags which are added to the HTML document before
rendering. This is useful for adding custom pagedjs handlers. The option
can be repeated. (default: [])
--browserEndpoint Use a remote Chrome server with browserWSEndpoint
-i, --inputs [inputs] Inputs
-o, --output [output] Output
-d, --debug Debug
-l, --landscape Landscape printing (default: false)
-s, --page-size [size] Print to Page Size [size]
-w, --width [size] Print to Page Width [width] in MM
-h --height [size] Print to Page Height [weight] in MM
--forceTransparentBackground Print with transparent background
-t, --timeout [ms] Set a max timeout of [ms]
-x, --html output html file
-b, --blockLocal Disallow access to filesystem for local files
-r, --blockRemote Disallow requests to remote servers
--allowedPath [allowedPaths] Only allow access to given filesystem paths,
repeatable. (default: [])
--allowedDomain [allowedDomains] Only allow access to given remote domains, repeatable
(default: [])
--outline-tags [tags] Specifies that an outline should be generated for the
resulting PDF document. [tags] specifies which HTML
tags should be considered for that outline. "h1,h2"
will trigger an outline with "h1" tags as root
elements and "h2" elements as their childs.
--additional-script <script> Additional script tags which are added to the HTML
document before rendering. This is useful for adding
custom pagedjs handlers. The option can be repeated.
(default: [])
--browserEndpoint <browserEndpoint> Use a remote Chrome server with browserWSEndpoint
--browserArgs <browserArgs> Launch Chrome with comma separated args
--media [media] Emulate "print" or "screen" media, defaults to print.
--style <style> Path to CSS stylesheets to be added before rendering
(default: [])
--warn Enable warning logs
--extra-header <header:value> Header to be added to the page request. (default: [])
--help display help for command
--disable-script-injection Disable in injection of the polyphill script.
```
## Hyphenation
HTML can be pre-processed with soft hyphens by the [Hypher](https://github.com/bramstein/hypher) library.
Pass the abbreviation a language code (such as `en-us` or `de`) when calling the renderer. You can install languages beyond those included the package.json using npm.
```
pagedjs-cli ./path/to/index.html --hyphenate en-us --output
```
## Development
Link and build the JS
```
......@@ -90,5 +90,5 @@ docker build -t pagedmedia/pagedjs-cli .
Run the Docker image
```bash
docker run -it --security-opt 'seccomp=seccomp.json' pagedmedia/pagedjs-cli bash
docker run -it --init --security-opt 'seccomp=seccomp.json' pagedmedia/pagedjs-cli bash
```
#!/usr/bin/env node
const program = require("commander");
const ora = require("ora");
const Printer = require("../");
const path = require("path");
const fs = require("fs");
// const { promisify } = require("util");
// const writeFileAsync = promisify(fs.writeFile);
const replaceExt = require("replace-ext");
program
.version(require("../package.json").version)
.arguments("[inputPath]")
.option("-i, --inputs [inputs]", "Inputs")
.option("-o, --output [output]", "Output")
.option("-d, --debug", "Debug")
.option("-l, --landscape", "Landscape printing", false)
.option("-s, --page-size [size]", "Print to Page Size [size]")
.option("-w, --width [size]", "Print to Page Width [width] in MM")
.option("-h --height [size]", "Print to Page Height [weight] in MM")
.option("--forceTransparentBackground", "Print with transparent background")
// .option("-m, --page-margin [margin]", "Print with margin [margin]")
// .option("-n, --hyphenate [lang]", "Hyphenate with language [language], defaults to "en-us"")
// .option("-hi, --hypher_ignore [str]", "Ignore passed element selectors, such as ".class_to_ignore, h1"")
// .option("-ho, --hypher_only [str]", "Only hyphenate passed elements selector, such as ".hyphenate, aside"")
// .option("-e, --encoding [type]", "Set the encoding of the input html, defaults to "utf-8"")
.option("-t, --timeout [ms]", "Set a max timeout of [ms]")
.option("-x, --html", "output html file")
.option("-b, --blockLocal", "Disallow access to filesystem for local files")
.option("-r, --blockRemote", "Disallow requests to remote servers")
.option("--allowedPath [allowedPaths]", "Only allow access to given filesystem paths, repeatable.", collect, [])
.option("--allowedDomain [allowedDomains]", "Only allow access to given remote domains, repeatable", collect, [])
.option("--outline-tags [tags]", "Specifies that an outline should be " +
"generated for the resulting PDF document. [tags] specifies which " +
"HTML tags should be considered for that outline. " +
"\"h1,h2\" will trigger an outline with \"h1\" tags as root elements " +
"and \"h2\" elements as their childs.")
.option("--additional-script <script>", "Additional script tags which are " +
"added to the HTML document before rendering. This is useful for " +
"adding custom pagedjs handlers. The option can be repeated.",
collect, [])
.option("--browserEndpoint <browserEndpoint>", "Use a remote Chrome server with browserWSEndpoint")
.parse(process.argv);
function collect(value, previous) {
return previous.concat(value);
}
let input = program.inputs || program.args[0];
let dir = process.cwd();
let relativePath;
let allowLocal;
try {
let uri = new URL(input);
allowLocal = false;
} catch (error) {
relativePath = path.resolve(dir, input);
allowLocal = !program.blockLocal;
}
let output;
let headless = typeof program.debug === "undefined";
// var hyphenator;
// var hyphenateOptions;
if (!input) {
console.error("You must include an input path");
return process.exit(1);
}
if (relativePath) {
if ([".html", ".xhtml"].indexOf(path.extname(relativePath)) === -1) {
console.error("Must pass a html or xhtml file as input");
return process.exit(1);
}
try {
fs.accessSync(relativePath, fs.F_OK);
} catch (e) {
console.error("Input cannot be found", e);
return process.exit(1);
}
}
if (typeof(program.output) === "string") {
output = path.resolve(dir, program.output);
} else if (typeof(program.output) !== "undefined") {
output = "./" + replaceExt(path.basename(input), ".pdf");
} else {
output = "output.pdf";
}
const spinner = ora({
spinner: "circleQuarters"
});
if (typeof input === "string") {
spinner.start("Loading: " + input);
} else {
spinner.start("Loading");
}
(async () => {
const printerOptions = {
headless: headless,
allowLocal: allowLocal,
allowRemote: !program.blockRemote,
allowedPaths: program.allowedPaths,
allowedDomains: program.allowedDomains,
additionalScripts: program.additionalScript,
browserEndpoint: program.browserEndpoint,
timeout: program.timeout,
};
if (program.forceTransparentBackground) {
printerOptions.overrideDefaultBackgroundColor = { r: 0, g: 0, b: 0, a: 0 }; // Workaround to get a transparent background in the resulting PDF. See https://bugs.chromium.org/p/chromium/issues/detail?id=498892 for more information.
}
let printer = new Printer(printerOptions);
printer.on("page", (page) => {
if (page.position === 0) {
spinner.succeed("Loaded");
spinner.start("Rendering: Page " + (page.position + 1));
} else {
spinner.text = "Rendering: Page " + (page.position + 1);
}
});
printer.on("rendered", (msg) => {
spinner.succeed(msg);
spinner.start("Generating");
});
printer.on("postprocessing", (msg) => {
spinner.succeed("Generated");
spinner.start("Processing");
});
let file;
if (headless) {
let options = {};
if (program.html) {
file = await printer.html(input, options);
output = replaceExt(output, ".html");
} else {
options.outlineTags = !program.outlineTags ? [] : program.outlineTags.split(",");
file = await printer.pdf(input, options);
}
} else {
printer.preview(input);
}
spinner.succeed("Processed");
if (file) {
fs.writeFile(output, file, (err) => {
if (err) throw err;
spinner.succeed("Saved to " + output);
process.exit(0);
});
}
})();
// Copyright 2015 The Chromium Authors. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
[{"description":"treehash per file","signed_content":{"payload":"eyJjb250ZW50X2hhc2hlcyI6W3siYmxvY2tfc2l6ZSI6NDA5NiwiZGlnZXN0Ijoic2hhMjU2IiwiZmlsZXMiOlt7InBhdGgiOiJMSUNFTlNFIiwicm9vdF9oYXNoIjoiUGIwc2tBVUxaUzFqWldTQnctV0hIRkltRlhVcExiZDlUcVkwR2ZHSHBWcyJ9LHsicGF0aCI6ImtleXMuanNvbiIsInJvb3RfaGFzaCI6ImU4ZmRzZkhXM2V5cEhRS2EzSnAtZDJ5bXZQSEtwX25oVE5rMjRncW5ZY2MifSx7InBhdGgiOiJtYW5pZmVzdC5qc29uIiwicm9vdF9oYXNoIjoiMk9UXzVQQk9feHJVWTlUdHRvZzBfc0dhOUlnUzN3RmhkRUxPNEY0SlZ5YyJ9XSwiZm9ybWF0IjoidHJlZWhhc2giLCJoYXNoX2Jsb2NrX3NpemUiOjQwOTZ9XSwiaXRlbV9pZCI6ImtpYWJoYWJqZGJramRwamJwaWdmb2RiZGptYmdsY29vIiwiaXRlbV92ZXJzaW9uIjoiMjAyNC4xLjIuMSIsInByb3RvY29sX3ZlcnNpb24iOjF9","signatures":[{"header":{"kid":"publisher"},"protected":"eyJhbGciOiJSUzI1NiJ9","signature":"ZqT-E1rZFwqZkFRK8YyDzFPUKKWvG3GNPm9wjhrZw8Po8fbFTaOgqoTS0u8IoqhP2_0wfCquBTZqBv1nagpto_E_3Nvsy52ZmtAiv87BqzPpIu4h_5jiCmS9SUl8wcmYON4Meh5sh0QuOctl8Sjc4DOZNztiNw6UCFFo-t9PI8wM5RTZUCPfX7MpuSIqHKuV3eJPTau1_pg7aRrXUPM_kVqOLHh4ci-_6qjwtYaIPLZBybUnli8xzqTvAMZf4bmF1heU5BHaVh5qjOYKGhxhvQlE0qXI0mnOo9fQ1SZavEvY-BkmSFJLdQ8vh7vV2UjIny-lzlc0BGBbeLWKKwfitWh1V1XIhVTqcQSomlw3gYjcaag6ZVO2v0JpNFLm41XkQ9cVvJryZSPH3K09Pd7NE_XIFR2lZ804KEpjSs1g6_gHOlm73mMUxcNI9Rx6KOnQGcZq53bjLL05BoJsGFjdQyZg5BQihlXJ1Qsj0CaiC6OVd4XtwNuU2oUNzCAx1eyLef6S2GUmmr-Z_WUQEpf79YUVLFW4Pr1oQvBMI3vGRfUXGWBP7TXf9xuxWM-AEyWUCiuDtajs4QxuQ-Ti92VIHmSJCsLfHsy-aP_hggd7zegKksaRY622H5cyhR4TCCsBUVqeTU8QkZ5OaHzOENbDX-wuXEVSbWemmSHSqMrsaT0"},{"header":{"kid":"webstore"},"protected":"eyJhbGciOiJSUzI1NiJ9","signature":"CBm85T1S_5zg_gGRZHFwi9PVUEqneLmSq66LGhUHK2gx7riwUryTxqaSD-3Io47nvQsHQstFpJU3sYZHSaP_6hS8xEhZbXngDG6jOnuXizJt4cqMhY10geKduadUUWHBFltrqpRHl36YA5p_N-uk2DQNtEO6DHAM7b2xKe-AmbDFDEUnrrw_yxnaAUl4wv3rchhLh2yEBRQ-Ib_gpO9MVfzrhB4KLQDFvV7SkQXvQzyKV6WYhwNgpk3RD5NClZ6PrsBjGd6tnUZBKfI3c2y7fLc7nNyaAuW21N-FonYO7Atgdea3c92ZXieIC6BtMDn6Rg7Xj32pSJi1gfI3QuVglw"}]}}]
\ No newline at end of file
{"https://issuer.captchafox.com":{"PrivateStateTokenV1VOPRF":{"batchsize":1,"id":1,"keys":{"0":{"Y":"AAAAAQQiyE+SESbq7GU5rTx6tZO4tBOxljp+Oya2mU28O+YoALIyXlLLqnl/h5h95ExYSsOlmMIb8EdsJBTrCaDl/KIZSskrfMbZpjhShG0jwnbXojEHI9WaAxKLkX/A/DkyMEg=","expiry":"1734807628115000"},"1":{"Y":"AAAAAQRNtld+5LLBquS4bEJKJwlLw61tzIyqTNkvMVnUTu+YiphbdGrRCjeDTN9D3p1Tgpfmq0N/OKMBYWzDMEN8Km9p9s49c6N2ph4B1MV1m7Ogdj969MOsTw54Kc849oqDl8s=","expiry":"1734807628115000"},"2":{"Y":"AAAAAQSBWW003A3ORFURCZrWNnbEIH15yzk184DaLSebbGzRdyCYtAM1qhhVmXZyBtWTzh6Bfkk5rLPyE1xdQilofPBizF/QJsdaMU0GYhPW1sOU4xoKbmgd/XrnOoFqA2ETOuc=","expiry":"1734807628115000"},"3":{"Y":"AAAAAQSG/ftGdm5B6iwAmVsHt6s43xx3nRf/Vpx9GdeEt3jSTM8hHvyLE9FAEkinGjt4Fp5EjnkCdE96Cxz10nZJRrMApIrGhG5kAoDu4T8PjJPiFQFyHAOdTG7OJWi2NS/rl1A=","expiry":"1734807628115000"},"4":{"Y":"AAAAAQT36tqe550UP5A+4Eokt8iuPZEuWQc9cGJXd7zUCZzrsqtGu3PMcVbOj5DjC4W+yoyF3HqKOqdtiBWgcMsZOcyln/6jUKqf5tS9AoIHa9CC3kQB8ISQd3lhR5j+qWVY8ms=","expiry":"1734807628115000"},"5":{"Y":"AAAAAQQMjaLNCR8+YpP7wuJc8LswYI6Lofx+FIzgc3YRXAZg1xPVUR0PanCmne8q9vAPJHXrHwpytYAO/p+7wy+7pV9OGY8S3atKypUVBKa/1+jo7pokpuI0OQKFWtEOZBaM0Hw=","expiry":"1734807628115000"}},"protocol_version":"PrivateStateTokenV1VOPRF"}},"https://polyset.xyz":{"PrivateStateTokenV1VOPRF":{"batchsize":1,"id":1,"keys":{"1":{"Y":"AAAAAQQ7W5gOubJT3kTpzNGsekT9RZPXgXGrOMB2+QPw/ZzAuLrM3kc8eyHuTc1KmKjH4sh5+ev5GCI4HVVd46o6rWvNvk0iZQtVuUPhT8X54Ajebng8v5zUnpnPuTjGqlc7+MM=","expiry":"1725389687915000"}},"protocol_version":"PrivateStateTokenV1VOPRF"}},"https://pst-issuer.hcaptcha.com":{"PrivateStateTokenV1VOPRF":{"batchsize":1,"id":1,"keys":{"0":{"Y":"AAAAAAQn0iKkl4Xm6zKsIwQxrjdWuG5y1Dx/HhjZEzg5gzHs/bMzXRC4YqKI8JtrTOg1kzZLcQT4hDYmeuEnGZRSS4ZBtEVwnbk72AH9CB3041g+A2Y8AvXdrBZyBJaswydxU70=","expiry":"1691836104000000"},"102":{"Y":"AAAAZgStKBZhkdiDfCd2M72lOVQEm/8Gs8OokCr6q689DfraBUy2OAqS3fT3CRtHcIFsHHWTmFKfYNYbhDV9lOTeJiwGh/o2c5kSPczpgca9LEoJoNvCttwUfhzApxRQipTktSs=","expiry":"1699612104000000"},"118":{"Y":"AAAAdgTPJ4DSXNbDsSzd0lau1l+PDvS7j7rvWaXeb8Dq+bVbsHi49gWgtAmOvEhrx7qqlsMbowW9oFp+8hpMz0iPetfzNlpZ/rgchHMVGA2mAcUUD6hZpLFwi/WzzjPNzNjghiU=","expiry":"1694428104000000"},"134":{"Y":"AAAAhgQdOOxzj3+ff1GYbZKKas301vAlY5T1+HuRLecI7+aSpZHiJDLBId96+sYqFQ9Lw2v5ZL2XrdNsIjcJQeZjMNeoKzRIU2+twrJx15zOsAS7UYrnwmwcKUNaIvK5z+ofVao=","expiry":"1697020104000000"},"135":{"Y":"AAAAhwQ7lqyWJhRd1vwnfh9CTyEwAfvtHx8aM3kUzK4t1yjAde2H6ncqmaeSt0wCDHWQXRf+1t4qDjHDaVA6SsKUEmWNZrJ++q07cVNyg586fFJhklASuCAVD8MLgiI0joPbSmQ=","expiry":"1697020104000000"},"165":{"Y":"AAAApQT5FOfKepPac+BaNNEDET5ISLG0gRu76JnhDZgdCE4YGlZslfaxQxo2AB6dqWXUzCxgnidfjlVjDdCOQSYJDPFmE2rRGNMVpvHfZD4dKwwErc+oqvxsf+LIftX3DO1B+zg=","expiry":"1697020104000000"},"171":{"Y":"AAAAqwQ3VONsOHn8vztPDJugYiBknSk2h76L4m9v89gLbfK33SvUKB/D/oj7uIO3WHnOidaxdJ9tqhd4ee+EZ/cj7iV3b3cuBFqFEJPPUcHkNJ+FnU3fQmePRn0ZJGasPUCZNA8=","expiry":"1694428104000000"},"226":{"Y":"AAAA4gSl5pqFtr6FxLm5p9Pn7OjO7fH/rp25nZ/1qX6643BJcuWIC/Q1fc2v19bHZE6PNdLyMeO8ZMkRH5rRi3CX1xg54UWtX0b0/rFOy1ErX2nLDTDXJvSAMrbZZwuCDf/QkfA=","expiry":"1699612104000000"},"253":{"Y":"AAAA/QTFOMQlDqoIjS5e99cmi1xLcbcIyqfvzulldtB0PfoZAza6czULN9fKDfVXud74aOkzIDpDA7Ejx1Zw/2nr477EGpCeMmP9MXAxiaOroKI0kBd38uWTaqCxKmFcd/l16Ic=","expiry":"1699612104000000"},"29":{"Y":"AAAAHQSYqY3WA/Kuzh1J0w+YBfvx8tNECkbuRvKNvTCV/EYQh/O+tZQuROyFVk4M/vr2mw7yPK/dJhyl8FRMUSVvuQ7r/Y59fnNxyvPAdiKNeRlZb8TKs/Ymf0H9RLneFz3rOfM=","expiry":"1691836104000000"},"70":{"Y":"AAAARgT+F/qLdVCJZazqkgDgmbBY7DhDF78vsw6pfT6cGVAMfg4WhdkbQlLQkzKlPMVy0XsqyN2S2tSLa+0hFA4R8+YJpCYf9QJzg/XAw43fZkbu/TX7+q623KsQeWPMiuj9qAs=","expiry":"1694428104000000"},"87":{"Y":"AAAAVwSR0P31+cA6fOgTBHGN545mu5vLETOCgN2+6R8Wa8mmOl8QqvG5QJ8JRp6IiTXzJE8piCaKV9LKWw824abZzkxth/nsBD1zpBngEXq+pV9313owOkkyhfFYop9QBipxj9s=","expiry":"1691836104000000"}},"protocol_version":"PrivateStateTokenV1VOPRF"}},"https://pst.authfy.tech":{"PrivateStateTokenV1VOPRF":{"batchsize":1,"id":1,"keys":{"1":{"Y":"AAAAAQJQtEubLGzouY07DTeBC34YpIgkCrcfp3HEoyuokvhm9s5Nl+YjYIrYMV118xniRk0=","expiry":"1709509052048"},"2":{"Y":"AAAAAgNdfiYuIFDaYfKZOtnrQYsm7+uYNxJlJMpaVl60BxzD7jeHnsM1EpwouzVzxfISnlU=","expiry":"1709994102048"}},"protocol_version":"PrivateStateTokenV1VOPRF"}},"https://trusttoken.dev":{"PrivateStateTokenV1VOPRF":{"batchsize":1,"id":1,"keys":{"0":{"Y":"AAAAAARfsssbDuePtDrNZ3lM/UURh5OQuxpiyHSHc1pdoKOlfZ1EEPEWMyjMs4RUBi04PGIH/2Ydu9DkhJBPOB8L3KvWrGzHY19bBVuYgypnPi1bFWV8FiVS7LTk4bQ6bUELZS8=","expiry":"1767139200000000"},"1":{"Y":"AAAAAQQf7weUF/kePEPj0OSOYXJFl5MtMxr8g0svnv/prKQJK/hXrKqyQCrfxWJaQcKvj0MqtJcAA0CMZUGO2+cEXXgVNsa9Rw3ozo5a69bRrcvwnu+DFfB/qrA+8vqB7HxSRyc=","expiry":"1767139200000000"},"2":{"Y":"AAAAAgQLbdTSLHbxKCt47+OFNTVxvvVenvsWvmB0GQrm0B7+fb+4Cr8DgkZ7O6cJ1XtJBN6pBocANfPtUMINbsFsrUrJILKj9zGuFbtlVUCnNTMxjgk6jhDGtvIrzoT2Tgj/Mqo=","expiry":"1767139200000000"},"3":{"Y":"AAAAAwSTuOrMb7Azhj0tzR0SBazJADihIRGWM3JMfCzAv38M7dAt3PrLa+yKQ2yJiyH43gbZo61I/AThxsw/55Bpo2mOZRfiRgYLiuuUceb5JJ69OLrkOuwAUyDJFsNGNXBy2m4=","expiry":"1767139200000000"},"4":{"Y":"AAAABASWQfNzun5KImUlkOvsg4iud4R4U+sOa2VjlUDMkrWB1S+q1qL/GuD3k687DQF/RfvbIbIeVkJZNyjobNqW7X4TsXU+lako/gxOBRqzl9aHaoMV9gk6EbvibY/XMD5AFDQ=","expiry":"1767139200000000"},"5":{"Y":"AAAABQR38by110bTSikIvk/oYI8eav69TFj3VrUNyc/Cj4dElEUIPqdpGUr2x+zH0vAs8+HD3lagql2JkzqncOEC5o6NX8bzWTTBxyNy7+uj9dYxy23jG0CFRxvJzLCRRTjuFZA=","expiry":"1767139200000000"}},"protocol_version":"PrivateStateTokenV1VOPRF"}}}
\ No newline at end of file
1.4a6508925b2ffec931c1e3931ddeb15ca41d820a8264cd5a962b526e9932bcdf
\ No newline at end of file
{
"manifest_version": 2,
"name": "trustToken",
"version": "2024.1.2.1"
}
\ No newline at end of file
[{"description":"treehash per file","signed_content":{"payload":"eyJjb250ZW50X2hhc2hlcyI6W3siYmxvY2tfc2l6ZSI6NDA5NiwiZGlnZXN0Ijoic2hhMjU2IiwiZmlsZXMiOlt7InBhdGgiOiJoeXBoLWFmLmh5YiIsInJvb3RfaGFzaCI6ImU3S1ZpWjlhODYwT3ZfdHR1dTRDME9JODlGQUNkcjR0Z01lOGhnNU1xVUkifSx7InBhdGgiOiJoeXBoLWFzLmh5YiIsInJvb3RfaGFzaCI6InduaE9NeFdLZ0hFMWhROXhKYWZxcS1SeXM4X0hyN2dzZFBBdHBwNmlVUDQifSx7InBhdGgiOiJoeXBoLWJlLmh5YiIsInJvb3RfaGFzaCI6IlpLdnllRTdIQmlLMktnYjBwRUUzVnotRmZ4RlJoQVNQcUJHeXlCbGtkaDAifSx7InBhdGgiOiJoeXBoLWJnLmh5YiIsInJvb3RfaGFzaCI6ImRaUHdPVkNCNC02eTJGRnRFSFJtQ0tfWUpzXzlUbjQzMVRrMm1UMGdDaE0ifSx7InBhdGgiOiJoeXBoLWJuLmh5YiIsInJvb3RfaGFzaCI6InduaE9NeFdLZ0hFMWhROXhKYWZxcS1SeXM4X0hyN2dzZFBBdHBwNmlVUDQifSx7InBhdGgiOiJoeXBoLWNzLmh5YiIsInJvb3RfaGFzaCI6IklnUndJWmZEOFctRjdYbExMMHJ4TTdkYTVRc3FVQlVwS2F5SkdodlVfRXcifSx7InBhdGgiOiJoeXBoLWN1Lmh5YiIsInJvb3RfaGFzaCI6ImFiWlhPbWx5T0dnSEplVWlHMkhaQURadHA3dlM2QnI3RGh3TUF0eWV4N2sifSx7InBhdGgiOiJoeXBoLWN5Lmh5YiIsInJvb3RfaGFzaCI6Ims5Y1JTUUhCNDNiNlVNaHN6cE5nN3k2cGliTVZGOFJnQjk3MmpQVGNvYkEifSx7InBhdGgiOiJoeXBoLWRhLmh5YiIsInJvb3RfaGFzaCI6IlRMZk92MjdUTFFpSDdWaFNIbDlCblQydDlKSkl1WEpDMWlFWUxRS251bGcifSx7InBhdGgiOiJoeXBoLWRlLTE5MDEuaHliIiwicm9vdF9oYXNoIjoiMHlHekNnc2tpTGI1STJoTC0yc1FCVmJMXzNCekE4VFNwSUZ6aDltd1ZsYyJ9LHsicGF0aCI6Imh5cGgtZGUtMTk5Ni5oeWIiLCJyb290X2hhc2giOiJIMGVZZHhlbDNyZU15UHRqVEt2QUI4RWFzaEFTbGpMUmhZOU83c0ljUFVRIn0seyJwYXRoIjoiaHlwaC1kZS1jaC0xOTAxLmh5YiIsInJvb3RfaGFzaCI6InpMQVlIVGVvc3IwdlBrcTc2VjdJM083b0V1cUI5M3NtSmxqNThibjZuYWMifSx7InBhdGgiOiJoeXBoLWVsLmh5YiIsInJvb3RfaGFzaCI6IjFOazV4S1JiR1ZYVElCUkVIbjB2SFJzU1VNTjZfdDAzdTVtRkwzMEtNN3MifSx7InBhdGgiOiJoeXBoLWVuLWdiLmh5YiIsInJvb3RfaGFzaCI6IlZvR2ZOaHpnajBOQ29qelhscjBQdjFSdnpFTEZJVFJ3MURRTWRUMXZiT0kifSx7InBhdGgiOiJoeXBoLWVuLXVzLmh5YiIsInJvb3RfaGFzaCI6Il94OUFGM2dFMzBLelE0bHFRU1BqLWZXWnl0bnNqLURWQVgzdDRqZEVUVXMifSx7InBhdGgiOiJoeXBoLWVzLmh5YiIsInJvb3RfaGFzaCI6IjBmdWc0YWVadDc0Z19XbEVyNUtsY1JHWkVkMzJXZFEtWFptSkxZX2xuRWsifSx7InBhdGgiOiJoeXBoLWV0Lmh5YiIsInJvb3RfaGFzaCI6ImxkUFIwUm14R3EyZ3EzNFF1Ylp6LXRlRGtvWFFibmg4VjM2bjIyRkNxY0EifSx7InBhdGgiOiJoeXBoLWV1Lmh5YiIsInJvb3RfaGFzaCI6IjRuZUtUOGU0OEdTaksycEV2Q254RGlaTm5XSVV1TzI0NjlIMTl0YU9MckkifSx7InBhdGgiOiJoeXBoLWZyLmh5YiIsInJvb3RfaGFzaCI6IjFudGF1Nm9FVUtQbWV2SFJKSkwydEc5c1FYQmxOcHFSZFJxYlZpMnJZeDAifSx7InBhdGgiOiJoeXBoLWdhLmh5YiIsInJvb3RfaGFzaCI6ImxGLVlGb3VwcUItempfM1ZadFc0aEw4Uk51Ql9YREpna0p2N1VMMFJFc1kifSx7InBhdGgiOiJoeXBoLWdsLmh5YiIsInJvb3RfaGFzaCI6IlJBU1hfb0MxVzFDUmtOYURETC0xZVoxYnYyS0c0Y2hfWE1jUEU4cXRpY1kifSx7InBhdGgiOiJoeXBoLWd1Lmh5YiIsInJvb3RfaGFzaCI6InJ3N2JaOElobTRBOFByYkIzdWJ5MUJvXzRBUm9xZHFMNk85UVZ0Y0JxX00ifSx7InBhdGgiOiJoeXBoLWhpLmh5YiIsInJvb3RfaGFzaCI6IjlOOGlUVVdmMFJGcGpkV2hOaFBGdV9EdEVmQkNlTllDTU5Bb0FRNnNERUkifSx7InBhdGgiOiJoeXBoLWhyLmh5YiIsInJvb3RfaGFzaCI6IjFmQm1wV1ZfSFh3NTBGT1ZiZklFdDVKdlFOTC1UMmxYT3ZDZGtKQm00bXcifSx7InBhdGgiOiJoeXBoLWh1Lmh5YiIsInJvb3RfaGFzaCI6InExWmRIaTR3VElWbFFiSHhVdW5NVEJaaEMya29JWTg1d3pUTnE0aUhTVlEifSx7InBhdGgiOiJoeXBoLWh5Lmh5YiIsInJvb3RfaGFzaCI6Im16VGZ5b1hMSjFSb0tmRUU4VGQxZnZzblNUVEI2ZFNaSDFXdFZrbGlwMm8ifSx7InBhdGgiOiJoeXBoLWl0Lmh5YiIsInJvb3RfaGFzaCI6Ii1jQW4xXzFFc0J6VjRjMzRBdUlNWTFZR2N3bUs4WXZxQ1RDNm12TTA0UGMifSx7InBhdGgiOiJoeXBoLWthLmh5YiIsInJvb3RfaGFzaCI6IlZoTFVGQnBOSDg5RDU2WXVPRmx4dnRqTTBJcjZfVTRLMUJacXB6NzVmaTAifSx7InBhdGgiOiJoeXBoLWtuLmh5YiIsInJvb3RfaGFzaCI6Iks1bWRDaFV2Z0VZQnFvODRfdzA2YmxsSmwzdngycWR2cUlpc3JpRlNZb2MifSx7InBhdGgiOiJoeXBoLWxhLmh5YiIsInJvb3RfaGFzaCI6Il9VdHZOaE5jMDdreTQxRHNJQmZmMkowdU5xd2liMVRreVBMa3ZHMndXVDAifSx7InBhdGgiOiJoeXBoLWx0Lmh5YiIsInJvb3RfaGFzaCI6Il9pbnpod2o5ZEtMZ3NOeDdVOHV1TGE4WVlXZUFnZVZQb2pVVUJ2eVZPUkUifSx7InBhdGgiOiJoeXBoLWx2Lmh5YiIsInJvb3RfaGFzaCI6Imtkc0Ytd1FuNHpQQzNySW83ekw0UUZLNlJ4NkNZVjZmVkhzd3dBM0tDV2MifSx7InBhdGgiOiJoeXBoLW1sLmh5YiIsInJvb3RfaGFzaCI6ImtGY3R1UFNiQWV4cUVDY3l6ZkZQd19COU5qeS1EU1lSQS1XREJERms2SWcifSx7InBhdGgiOiJoeXBoLW1uLWN5cmwuaHliIiwicm9vdF9oYXNoIjoiMm5yb3g2UFNHU19XQ1FZWUk3SnZ0cWwxMlhjUHVTd3UxMk1aS2VMT1QzayJ9LHsicGF0aCI6Imh5cGgtbXIuaHliIiwicm9vdF9oYXNoIjoiOU44aVRVV2YwUkZwamRXaE5oUEZ1X0R0RWZCQ2VOWUNNTkFvQVE2c0RFSSJ9LHsicGF0aCI6Imh5cGgtbXVsLWV0aGkuaHliIiwicm9vdF9oYXNoIjoiOHZyQnZRYWZfbHpSRVMyVXpERVRmdE9LR3hZUWstelhUSndXaUVLTGFJcyJ9LHsicGF0aCI6Imh5cGgtbmIuaHliIiwicm9vdF9oYXNoIjoidW1oN2VNX0ptaVRpdVdjeUNSU2Y0eGVnT085aDZaczZxcl9XeHdtQk9IdyJ9LHsicGF0aCI6Imh5cGgtbmwuaHliIiwicm9vdF9oYXNoIjoiMWNMSjEtZ0J3UkhNMDlhVExINVZZOWpXeGY2cUpqYjgydFdSX0tsRlg5ZyJ9LHsicGF0aCI6Imh5cGgtbm4uaHliIiwicm9vdF9oYXNoIjoiVVRNblpKaGR0LW51UGEwSGRBMmpqeE9yUU9CMTZ4UVk3ZFo1b2dKeVB2MCJ9LHsicGF0aCI6Imh5cGgtb3IuaHliIiwicm9vdF9oYXNoIjoiVHB6VEFycl94T28tbGxJeWZxSkFjdXZ6ZTF4UHdIR1NrcjJzRUtxdFpscyJ9LHsicGF0aCI6Imh5cGgtcGEuaHliIiwicm9vdF9oYXNoIjoiUndNcDBvLXFTRS1VWFhqXzc3RjIzTGJ5QXl4MVBpVzhBVUVHclNTeXhvbyJ9LHsicGF0aCI6Imh5cGgtcHQuaHliIiwicm9vdF9oYXNoIjoiOXZ2eHZMSmd6SVlsYjhTVTg0ajNzbjBRaGwtX2oyRlJmZTRscjAxWTF1ZyJ9LHsicGF0aCI6Imh5cGgtcnUuaHliIiwicm9vdF9oYXNoIjoicXN2dk9SNU5oUWlrYV8zVXU5N3QwQ0tWU2o2RFhPSVFFMVVXbWRmR1VRdyJ9LHsicGF0aCI6Imh5cGgtc2suaHliIiwicm9vdF9oYXNoIjoiN2Z4MDBSMHQtYjVscVVlX3hGNy1pVThuNkZUTzJrVjNmYy1odGdEQVZlYyJ9LHsicGF0aCI6Imh5cGgtc2wuaHliIiwicm9vdF9oYXNoIjoiT1hDWTBsMS0wYzZ2eVk4YmpURTBObEJBSnlvUVl5YmFfOVp0WVN0UF83byJ9LHsicGF0aCI6Imh5cGgtc3EuaHliIiwicm9vdF9oYXNoIjoidkNuSlFCenBVa0ZNdXV2RnlPNGRKOEZ3Ykc5M2dIdGY5eFBpRWtRNHM4byJ9LHsicGF0aCI6Imh5cGgtc3YuaHliIiwicm9vdF9oYXNoIjoiR1hhQU9rUmRyWE5ac1FLbHBKX3lCd1doZUNpRzhjZFNzREZ4OWc3MnJwOCJ9LHsicGF0aCI6Imh5cGgtdGEuaHliIiwicm9vdF9oYXNoIjoiUVAycFNGYW9id1pkNkxxbUdFNm1QYzJ3RWU1TXBKaW53ZjdrVEpreFRHYyJ9LHsicGF0aCI6Imh5cGgtdGUuaHliIiwicm9vdF9oYXNoIjoiVVctcFpVLWpycXEwZ05RT3IyclhqOEE1Q0d2WTdjRkV2ajFaVWw3Y3JDayJ9LHsicGF0aCI6Imh5cGgtdGsuaHliIiwicm9vdF9oYXNoIjoiZF8ydTBwdllRcXFwZHF0LS1CdGhlaFhBb3RIcjBSWWNHX0pyZWFFSXRjMCJ9LHsicGF0aCI6Imh5cGgtdWsuaHliIiwicm9vdF9oYXNoIjoieWxjVXUzT05ZS3N1LW9pS3R5VWNSak1PQnhwZzBMdjdMNENvZHpsUW5zayJ9LHsicGF0aCI6Imh5cGgtdW5kLWV0aGkuaHliIiwicm9vdF9oYXNoIjoiSGVnOHQ0ZmZyMVA3Zm02TnM2cmxBSXJTVHIzU2ktQWdNVEJ1cWVuejRvVSJ9LHsicGF0aCI6Im1hbmlmZXN0Lmpzb24iLCJyb290X2hhc2giOiIxWEh2TTdEbkIxY2ZFTHMzdVpwZ2ZXOURyLU1fVTlGYlE1V3hidlA5cG1VIn1dLCJmb3JtYXQiOiJ0cmVlaGFzaCIsImhhc2hfYmxvY2tfc2l6ZSI6NDA5Nn1dLCJpdGVtX2lkIjoiamFtaGNubmtpaGlubWRsa2Fra2FvcGJqYmJjbmdmbGMiLCJpdGVtX3ZlcnNpb24iOiIxMjAuMC42MDUwLjAiLCJwcm90b2NvbF92ZXJzaW9uIjoxfQ","signatures":[{"header":{"kid":"publisher"},"protected":"eyJhbGciOiJSUzI1NiJ9","signature":"ud33uh3_3o_eTIMSj_MKboC9-GzBxQ-Bu6XS31wn7JB3ntcoVSUfAgMjTBCsIYEEgqVfKJlf92wgl3SbjJWaT-_XfV8sMFwZtuAT0qJV0p9gammnprPP0OmUwJdJB-kK1MO8ESwSyeGKCEeIXGDqAVdQHkYD-oKzYS-zKhe9KVnU-WtJ6mtG80ybhjxJDM1aLyS6_ocXKYBmcB9av0IY-saDVR7hkVNjc-iR9lhYI1682VbDmlQ9-uueCkK4YsqmO1mOSgYcQ-Hm56zQxhGrMHbGokIX667-8yHRbxjoag7eNxHrY5VQI-te17pDKE9G9cz87qvGSMPUi9QGdyt7a1652KWPXe6bDEOjIoaHUq9juOd7r8SxYCv8tqhAx5nxhqkaq9oHSfiYrrcddaSdtdCOYo7hyqVQV1562x0NZiNrGH9sU5V-e_5DAmPVqBMA1yjY3ZQEWWyTdQ_Wtw5qbs3m5qh5Grut8RtIb7yGJJsamDN3LG73jcrtXZ1cMynqN3LysksG8Y73RfO3joVhy3gw5Y1X6ES1gvQi4n1hxvOCCXoGIbIJwIZGjTlcuh2J_eweLo0hm1IeXK_lAB9P1RiruKfEc0P75CY4V_LDziEdFHxIpFS6PjH94n1aAj0F3ba6opqyjgXs6n8uuhoJvdq5GwnAuwsOzs771p8mWl0"},{"header":{"kid":"webstore"},"protected":"eyJhbGciOiJSUzI1NiJ9","signature":"fLFplPrKe8OWo-G7YhCQxsnj2MHPUqYvWL9ACSCD1WuA4K5c0pOFNMZ10w0Po0lgprE7LTCjWTk3pKKvyTxojWAyAg-c75DU2kfnntDabBEn9ooCiBcWJIuOkJMdcLYBbfe-t-JO0KPKm-2mGi59MkO9xir2MMwAqtITGdrH4WXjHTIB6guYQMtre_Bp_zqvZnGQKqZI0Cdq8QVqd7z69_j63fvv0CjXuZ-6F1RNElS75H3FzJ1OrVMCOjEOaKyk1DD-aqgr-6lUq2er1XWrf9JxtAmAawpnh3RAEi_1VoGtbga92USt_0ZLiapoC4PlWSloLuX-_NYFg9gtPJNS9w"}]}}]
\ No newline at end of file
File added
File added
File added
File added
File added
File added
File added