summaryrefslogtreecommitdiffhomepage
path: root/vhosts/blog/public
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2025-06-27 23:39:31 +0900
committernsfisis <nsfisis@gmail.com>2025-06-27 23:39:31 +0900
commit674fe965550444db87edc7937ff6932e1a918d9d (patch)
treee8a80dd958d3e082485286bf5785a7992b6e6b0e /vhosts/blog/public
parentfe4d1d625b53796c5f20399790e5ff8c7a7e1608 (diff)
downloadnsfisis.dev-674fe965550444db87edc7937ff6932e1a918d9d.tar.gz
nsfisis.dev-674fe965550444db87edc7937ff6932e1a918d9d.tar.zst
nsfisis.dev-674fe965550444db87edc7937ff6932e1a918d9d.zip
feat(meta): rename vhosts/ directory to services/
Diffstat (limited to 'vhosts/blog/public')
-rw-r--r--vhosts/blog/public/404.html51
-rw-r--r--vhosts/blog/public/about/index.html156
-rw-r--r--vhosts/blog/public/atom.xml603
-rw-r--r--vhosts/blog/public/favicon.svg61
-rw-r--r--vhosts/blog/public/index.html77
-rw-r--r--vhosts/blog/public/my-icon.js151
-rw-r--r--vhosts/blog/public/pdf.min.mjs21
-rw-r--r--vhosts/blog/public/pdf.worker.min.mjs21
-rw-r--r--vhosts/blog/public/posts/2/index.html222
-rw-r--r--vhosts/blog/public/posts/2021-03-05/my-first-post/index.html245
-rw-r--r--vhosts/blog/public/posts/2021-03-30/phperkaigi-2021/index.html215
-rw-r--r--vhosts/blog/public/posts/2021-10-02/cpp-you-can-use-keywords-in-attributes/index.html193
-rw-r--r--vhosts/blog/public/posts/2021-10-02/python-unbound-local-error/index.html132
-rw-r--r--vhosts/blog/public/posts/2021-10-02/ruby-detect-running-implementation/index.html135
-rw-r--r--vhosts/blog/public/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html290
-rw-r--r--vhosts/blog/public/posts/2021-10-02/rust-where-are-primitive-types-from/index.html252
-rw-r--r--vhosts/blog/public/posts/2021-10-02/vim-difference-between-autocmd-bufwrite-and-bufwritepre/index.html234
-rw-r--r--vhosts/blog/public/posts/2021-10-02/vim-swap-order-of-selected-lines/index.html244
-rw-r--r--vhosts/blog/public/posts/2022-04-09/phperkaigi-2022-tokens/index.html572
-rw-r--r--vhosts/blog/public/posts/2022-04-24/term-banner-write-tool-showing-banner-in-terminal/index.html157
-rw-r--r--vhosts/blog/public/posts/2022-04-24/term-banner-write-tool-showing-banner-in-terminal/screenshot.pngbin27573 -> 0 bytes
-rw-r--r--vhosts/blog/public/posts/2022-05-01/phperkaigi-2022/index.html248
-rw-r--r--vhosts/blog/public/posts/2022-08-27/php-conference-okinawa-code-golf/index.html178
-rw-r--r--vhosts/blog/public/posts/2022-08-31/support-for-communty-is-employee-benefits/index.html108
-rw-r--r--vhosts/blog/public/posts/2022-09-29/write-fizzbuzz-in-php-2-letters-per-line/index.html704
-rw-r--r--vhosts/blog/public/posts/2022-10-23/phperkaigi-2023-unused-token-quiz-1/index.html207
-rw-r--r--vhosts/blog/public/posts/2022-10-28/setup-server-for-this-site/index.html316
-rw-r--r--vhosts/blog/public/posts/2022-11-19/phperkaigi-2023-unused-token-quiz-2/index.html215
-rw-r--r--vhosts/blog/public/posts/2023-01-10/phperkaigi-2023-unused-token-quiz-3/index.html394
-rw-r--r--vhosts/blog/public/posts/2023-03-10/rewrite-this-blog-generator/index.html148
-rw-r--r--vhosts/blog/public/posts/2023-04-01/implementation-of-minimal-png-image-encoder/index.html699
-rw-r--r--vhosts/blog/public/posts/2023-04-04/phperkaigi-2023-report/index.html264
-rw-r--r--vhosts/blog/public/posts/2023-06-25/phpconfuk-2023-report/index.html155
-rw-r--r--vhosts/blog/public/posts/2023-10-02/compile-php-runtime-to-wasm/index.html401
-rw-r--r--vhosts/blog/public/posts/2023-10-13/i-entered-the-open-university-of-japan/index.html79
-rw-r--r--vhosts/blog/public/posts/2023-12-03/isucon-13/index.html149
-rw-r--r--vhosts/blog/public/posts/2023-12-31/2023-reflections/index.html183
-rw-r--r--vhosts/blog/public/posts/2024-01-10/neovim-insert-namespace-declaration-to-empty-php-file/index.html280
-rw-r--r--vhosts/blog/public/posts/2024-02-03/install-wireguard-on-personal-server/index.html211
-rw-r--r--vhosts/blog/public/posts/2024-02-10/yapcjapan-2024-report/index.html123
-rw-r--r--vhosts/blog/public/posts/2024-02-22/phpkansai-2024-report/index.html120
-rw-r--r--vhosts/blog/public/posts/2024-03-17/phperkaigi-2024-report/index.html176
-rw-r--r--vhosts/blog/public/posts/2024-03-20/my-bucket-list/index.html129
-rw-r--r--vhosts/blog/public/posts/2024-04-14/phpcon-odawara-2024-report/index.html172
-rw-r--r--vhosts/blog/public/posts/2024-04-21/pipefail-option-in-gitlab-ci-cd/index.html221
-rw-r--r--vhosts/blog/public/posts/2024-04-29/zsh-file-completion-for-composer-custom-commands/index.html147
-rw-r--r--vhosts/blog/public/posts/2024-05-11/phpconkagawa-2024-report/index.html163
-rw-r--r--vhosts/blog/public/posts/2024-06-19/scalamatsuri-2024-report/index.html126
-rw-r--r--vhosts/blog/public/posts/2024-07-19/reparojson-fix-only-json-formatter/index.html205
-rw-r--r--vhosts/blog/public/posts/2024-08-19/go-template-access-outer-scope-pipeline-within-with-or-range/index.html184
-rw-r--r--vhosts/blog/public/posts/2024-09-28/mncore-challenge-1/index.html104
-rw-r--r--vhosts/blog/public/posts/2024-12-04/cohackpp-report/index.html266
-rw-r--r--vhosts/blog/public/posts/2024-12-04/cohackpp-report/lt.pngbin43816 -> 0 bytes
-rw-r--r--vhosts/blog/public/posts/2024-12-33/2024-reflections/index.html198
-rw-r--r--vhosts/blog/public/posts/2025-01-08/phperkaigi-2023-tokens-q1/Q1.pngbin68173 -> 0 bytes
-rw-r--r--vhosts/blog/public/posts/2025-01-08/phperkaigi-2023-tokens-q1/index.html471
-rw-r--r--vhosts/blog/public/posts/2025-01-26/yaml-breaking-changes-between-v1-1-and-v1-2/index.html135
-rw-r--r--vhosts/blog/public/posts/2025-02-24/phpcon-nagoya-2025-report/index.html121
-rw-r--r--vhosts/blog/public/posts/2025-03-27/zip-function-like-command-paste-command/index.html153
-rw-r--r--vhosts/blog/public/posts/2025-03-28/http-1-1-send-multiple-same-headers/index.html171
-rw-r--r--vhosts/blog/public/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/index.html285
-rw-r--r--vhosts/blog/public/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/screenshot.pngbin142365 -> 0 bytes
-rw-r--r--vhosts/blog/public/posts/2025-04-24/composer-patches-v2-does-not-require-gnu-patch-even-on-macos/index.html153
-rw-r--r--vhosts/blog/public/posts/2025-05-05/make-tiny-self-hosted-c-compiler/index.html541
-rw-r--r--vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_ADVENTURERS.jpegbin77310 -> 0 bytes
-rw-r--r--vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_BABA_IS_YOU.jpegbin40865 -> 0 bytes
-rw-r--r--vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_BOOBY_TRAP.jpegbin78417 -> 0 bytes
-rw-r--r--vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_BOTTLENECK.jpegbin60078 -> 0 bytes
-rw-r--r--vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_CONCRETE_GOALS.jpegbin85782 -> 0 bytes
-rw-r--r--vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_CRUSHERS.jpegbin64850 -> 0 bytes
-rw-r--r--vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_DUNGEON.jpegbin75946 -> 0 bytes
-rw-r--r--vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_FRAGILE_EXISTENCE.jpegbin48729 -> 0 bytes
-rw-r--r--vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_FURTHER_FIELDS.jpegbin74284 -> 0 bytes
-rw-r--r--vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_GETTING_TOGETHER.jpegbin48172 -> 0 bytes
-rw-r--r--vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_HEAVY_CLOUD.jpegbin65076 -> 0 bytes
-rw-r--r--vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_INSULATION.jpegbin65286 -> 0 bytes
-rw-r--r--vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_LOCK_THE_DOOR.jpegbin64481 -> 0 bytes
-rw-r--r--vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_METEOR_STRIKE.jpegbin82630 -> 0 bytes
-rw-r--r--vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_OUT_AT_SEA.jpegbin88212 -> 0 bytes
-rw-r--r--vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_PARADE.jpegbin85388 -> 0 bytes
-rw-r--r--vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_PRISON.jpegbin77274 -> 0 bytes
-rw-r--r--vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_SCENIC_POND.jpegbin81383 -> 0 bytes
-rw-r--r--vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_SEEKING_ACCEPTANCE.jpegbin115155 -> 0 bytes
-rw-r--r--vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_STARDROP.jpegbin76510 -> 0 bytes
-rw-r--r--vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_SUBMERGED_RUINS.jpegbin66087 -> 0 bytes
-rw-r--r--vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_SUNKEN_TEMPLE.jpegbin69803 -> 0 bytes
-rw-r--r--vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_THE_BOX.jpegbin47665 -> 0 bytes
-rw-r--r--vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_THE_RETURN_OF_SCENIC_POND.jpegbin80124 -> 0 bytes
-rw-r--r--vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_ULTIMATE_MAZE.jpegbin94757 -> 0 bytes
-rw-r--r--vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_VIP_AREA.jpegbin59069 -> 0 bytes
-rw-r--r--vhosts/blog/public/posts/2025-06-14/baba-is-you/index.html577
-rw-r--r--vhosts/blog/public/posts/3/index.html222
-rw-r--r--vhosts/blog/public/posts/4/index.html222
-rw-r--r--vhosts/blog/public/posts/5/index.html222
-rw-r--r--vhosts/blog/public/posts/6/index.html100
-rw-r--r--vhosts/blog/public/posts/atom.xml427
-rw-r--r--vhosts/blog/public/posts/index.html220
-rw-r--r--vhosts/blog/public/slide.js60
-rw-r--r--vhosts/blog/public/slides/2023-01-18/phpstudy-tokyo-148/index.html82
-rw-r--r--vhosts/blog/public/slides/2023-01-18/phpstudy-tokyo-148/slide.pdfbin204408 -> 0 bytes
-rw-r--r--vhosts/blog/public/slides/2023-02-15/phpstudy-tokyo-149/index.html82
-rw-r--r--vhosts/blog/public/slides/2023-02-15/phpstudy-tokyo-149/slide.pdfbin214504 -> 0 bytes
-rw-r--r--vhosts/blog/public/slides/2023-03-15/phpstudy-tokyo-150/index.html85
-rw-r--r--vhosts/blog/public/slides/2023-03-15/phpstudy-tokyo-150/slide.pdfbin248257 -> 0 bytes
-rw-r--r--vhosts/blog/public/slides/2023-03-24/phperkaigi-2023/index.html85
-rw-r--r--vhosts/blog/public/slides/2023-03-24/phperkaigi-2023/slide.pdfbin321814 -> 0 bytes
-rw-r--r--vhosts/blog/public/slides/2023-03-25/phperkaigi-2023-tokens/index.html85
-rw-r--r--vhosts/blog/public/slides/2023-03-25/phperkaigi-2023-tokens/slide.pdfbin753400 -> 0 bytes
-rw-r--r--vhosts/blog/public/slides/2023-04-12/phpstudy-tokyo-151/index.html82
-rw-r--r--vhosts/blog/public/slides/2023-04-12/phpstudy-tokyo-151/slide.pdfbin202360 -> 0 bytes
-rw-r--r--vhosts/blog/public/slides/2023-06-21/phpstudy-tokyo-153/index.html82
-rw-r--r--vhosts/blog/public/slides/2023-06-21/phpstudy-tokyo-153/slide.pdfbin179888 -> 0 bytes
-rw-r--r--vhosts/blog/public/slides/2023-06-23/phpconfuk-2023-eve/index.html82
-rw-r--r--vhosts/blog/public/slides/2023-06-23/phpconfuk-2023-eve/slide.pdfbin194763 -> 0 bytes
-rw-r--r--vhosts/blog/public/slides/2023-07-26/phpstudy-tokyo-154/index.html82
-rw-r--r--vhosts/blog/public/slides/2023-07-26/phpstudy-tokyo-154/slide.pdfbin243063 -> 0 bytes
-rw-r--r--vhosts/blog/public/slides/2023-08-24/phpstudy-tokyo-155/index.html82
-rw-r--r--vhosts/blog/public/slides/2023-08-24/phpstudy-tokyo-155/slide.pdfbin176356 -> 0 bytes
-rw-r--r--vhosts/blog/public/slides/2023-10-25/phpstudy-tokyo-157/index.html82
-rw-r--r--vhosts/blog/public/slides/2023-10-25/phpstudy-tokyo-157/slide.pdfbin220650 -> 0 bytes
-rw-r--r--vhosts/blog/public/slides/2024-01-24/phpstudy-tokyo-160/index.html82
-rw-r--r--vhosts/blog/public/slides/2024-01-24/phpstudy-tokyo-160/slide.pdfbin143632 -> 0 bytes
-rw-r--r--vhosts/blog/public/slides/2024-03-08/phperkaigi-2024/index.html88
-rw-r--r--vhosts/blog/public/slides/2024-03-08/phperkaigi-2024/slide.pdfbin188791 -> 0 bytes
-rw-r--r--vhosts/blog/public/slides/2024-03-15/ya8-2024/index.html85
-rw-r--r--vhosts/blog/public/slides/2024-03-15/ya8-2024/slide.pdfbin1128697 -> 0 bytes
-rw-r--r--vhosts/blog/public/slides/2024-04-13/phpcon-odawara-2024/index.html85
-rw-r--r--vhosts/blog/public/slides/2024-04-13/phpcon-odawara-2024/slide.pdfbin255381 -> 0 bytes
-rw-r--r--vhosts/blog/public/slides/2024-04-25/phpstudy-tokyo-163/index.html82
-rw-r--r--vhosts/blog/public/slides/2024-04-25/phpstudy-tokyo-163/slide.pdfbin204495 -> 0 bytes
-rw-r--r--vhosts/blog/public/slides/2024-07-18/phpstudy-tokyo-166/index.html82
-rw-r--r--vhosts/blog/public/slides/2024-07-18/phpstudy-tokyo-166/slide.pdfbin267279 -> 0 bytes
-rw-r--r--vhosts/blog/public/slides/2024-10-30/phpstudy-tokyo-169/index.html82
-rw-r--r--vhosts/blog/public/slides/2024-10-30/phpstudy-tokyo-169/slide.pdfbin281149 -> 0 bytes
-rw-r--r--vhosts/blog/public/slides/2024-11-30/cohackpp/index.html82
-rw-r--r--vhosts/blog/public/slides/2024-11-30/cohackpp/slides.pdfbin581643 -> 0 bytes
-rw-r--r--vhosts/blog/public/slides/2025-02-22/phpcon-nagoya-2025/index.html85
-rw-r--r--vhosts/blog/public/slides/2025-02-22/phpcon-nagoya-2025/slides.pdfbin466281 -> 0 bytes
-rw-r--r--vhosts/blog/public/slides/2025-03-23/phperkaigi-2025/index.html85
-rw-r--r--vhosts/blog/public/slides/2025-03-23/phperkaigi-2025/slides.pdfbin330673 -> 0 bytes
-rw-r--r--vhosts/blog/public/slides/2025-04-12/phpcon-odawara-2025/index.html85
-rw-r--r--vhosts/blog/public/slides/2025-04-12/phpcon-odawara-2025/slides.pdfbin253371 -> 0 bytes
-rw-r--r--vhosts/blog/public/slides/atom.xml187
-rw-r--r--vhosts/blog/public/slides/index.html380
-rw-r--r--vhosts/blog/public/style.css365
-rw-r--r--vhosts/blog/public/tags/c/atom.xml19
-rw-r--r--vhosts/blog/public/tags/c/index.html66
-rw-r--r--vhosts/blog/public/tags/ci-cd/atom.xml19
-rw-r--r--vhosts/blog/public/tags/ci-cd/index.html66
-rw-r--r--vhosts/blog/public/tags/cohackpp/atom.xml27
-rw-r--r--vhosts/blog/public/tags/cohackpp/index.html81
-rw-r--r--vhosts/blog/public/tags/composer/atom.xml27
-rw-r--r--vhosts/blog/public/tags/composer/index.html81
-rw-r--r--vhosts/blog/public/tags/conference/atom.xml195
-rw-r--r--vhosts/blog/public/tags/conference/index.html396
-rw-r--r--vhosts/blog/public/tags/cpp/atom.xml19
-rw-r--r--vhosts/blog/public/tags/cpp/index.html66
-rw-r--r--vhosts/blog/public/tags/cpp17/atom.xml19
-rw-r--r--vhosts/blog/public/tags/cpp17/index.html66
-rw-r--r--vhosts/blog/public/tags/game/atom.xml19
-rw-r--r--vhosts/blog/public/tags/game/index.html66
-rw-r--r--vhosts/blog/public/tags/gitlab/atom.xml19
-rw-r--r--vhosts/blog/public/tags/gitlab/index.html66
-rw-r--r--vhosts/blog/public/tags/go/atom.xml19
-rw-r--r--vhosts/blog/public/tags/go/index.html66
-rw-r--r--vhosts/blog/public/tags/http/atom.xml19
-rw-r--r--vhosts/blog/public/tags/http/index.html66
-rw-r--r--vhosts/blog/public/tags/index.html489
-rw-r--r--vhosts/blog/public/tags/isucon/atom.xml19
-rw-r--r--vhosts/blog/public/tags/isucon/index.html66
-rw-r--r--vhosts/blog/public/tags/macos/atom.xml19
-rw-r--r--vhosts/blog/public/tags/macos/index.html66
-rw-r--r--vhosts/blog/public/tags/mncore-challenge/atom.xml19
-rw-r--r--vhosts/blog/public/tags/mncore-challenge/index.html66
-rw-r--r--vhosts/blog/public/tags/neovim/atom.xml27
-rw-r--r--vhosts/blog/public/tags/neovim/index.html81
-rw-r--r--vhosts/blog/public/tags/note-to-self/atom.xml35
-rw-r--r--vhosts/blog/public/tags/note-to-self/index.html96
-rw-r--r--vhosts/blog/public/tags/ouj/atom.xml19
-rw-r--r--vhosts/blog/public/tags/ouj/index.html66
-rw-r--r--vhosts/blog/public/tags/perl/atom.xml19
-rw-r--r--vhosts/blog/public/tags/perl/index.html66
-rw-r--r--vhosts/blog/public/tags/php/atom.xml347
-rw-r--r--vhosts/blog/public/tags/php/index.html681
-rw-r--r--vhosts/blog/public/tags/phpcon-nagoya/atom.xml27
-rw-r--r--vhosts/blog/public/tags/phpcon-nagoya/index.html81
-rw-r--r--vhosts/blog/public/tags/phpcon-odawara/atom.xml35
-rw-r--r--vhosts/blog/public/tags/phpcon-odawara/index.html96
-rw-r--r--vhosts/blog/public/tags/phpconfuk/atom.xml27
-rw-r--r--vhosts/blog/public/tags/phpconfuk/index.html81
-rw-r--r--vhosts/blog/public/tags/phpconkagawa/atom.xml19
-rw-r--r--vhosts/blog/public/tags/phpconkagawa/index.html66
-rw-r--r--vhosts/blog/public/tags/phpconokinawa/atom.xml19
-rw-r--r--vhosts/blog/public/tags/phpconokinawa/index.html66
-rw-r--r--vhosts/blog/public/tags/phperkaigi/atom.xml115
-rw-r--r--vhosts/blog/public/tags/phperkaigi/index.html246
-rw-r--r--vhosts/blog/public/tags/phpkansai/atom.xml19
-rw-r--r--vhosts/blog/public/tags/phpkansai/index.html66
-rw-r--r--vhosts/blog/public/tags/phpstudy-tokyo/atom.xml107
-rw-r--r--vhosts/blog/public/tags/phpstudy-tokyo/index.html231
-rw-r--r--vhosts/blog/public/tags/piet/atom.xml19
-rw-r--r--vhosts/blog/public/tags/piet/index.html66
-rw-r--r--vhosts/blog/public/tags/python/atom.xml19
-rw-r--r--vhosts/blog/public/tags/python/index.html66
-rw-r--r--vhosts/blog/public/tags/python3/atom.xml19
-rw-r--r--vhosts/blog/public/tags/python3/index.html66
-rw-r--r--vhosts/blog/public/tags/ruby/atom.xml35
-rw-r--r--vhosts/blog/public/tags/ruby/index.html96
-rw-r--r--vhosts/blog/public/tags/ruby3/atom.xml19
-rw-r--r--vhosts/blog/public/tags/ruby3/index.html66
-rw-r--r--vhosts/blog/public/tags/rubykaigi/atom.xml19
-rw-r--r--vhosts/blog/public/tags/rubykaigi/index.html66
-rw-r--r--vhosts/blog/public/tags/rust/atom.xml19
-rw-r--r--vhosts/blog/public/tags/rust/index.html66
-rw-r--r--vhosts/blog/public/tags/scala/atom.xml19
-rw-r--r--vhosts/blog/public/tags/scala/index.html66
-rw-r--r--vhosts/blog/public/tags/scalamatsuri/atom.xml19
-rw-r--r--vhosts/blog/public/tags/scalamatsuri/index.html66
-rw-r--r--vhosts/blog/public/tags/trick/atom.xml19
-rw-r--r--vhosts/blog/public/tags/trick/index.html66
-rw-r--r--vhosts/blog/public/tags/vim/atom.xml35
-rw-r--r--vhosts/blog/public/tags/vim/index.html96
-rw-r--r--vhosts/blog/public/tags/wasm/atom.xml35
-rw-r--r--vhosts/blog/public/tags/wasm/index.html96
-rw-r--r--vhosts/blog/public/tags/wireguard/atom.xml19
-rw-r--r--vhosts/blog/public/tags/wireguard/index.html66
-rw-r--r--vhosts/blog/public/tags/ya8/atom.xml19
-rw-r--r--vhosts/blog/public/tags/ya8/index.html66
-rw-r--r--vhosts/blog/public/tags/yaml/atom.xml19
-rw-r--r--vhosts/blog/public/tags/yaml/index.html66
-rw-r--r--vhosts/blog/public/tags/yapc/atom.xml19
-rw-r--r--vhosts/blog/public/tags/yapc/index.html66
-rw-r--r--vhosts/blog/public/tags/zsh/atom.xml19
-rw-r--r--vhosts/blog/public/tags/zsh/index.html66
234 files changed, 0 insertions, 24703 deletions
diff --git a/vhosts/blog/public/404.html b/vhosts/blog/public/404.html
deleted file mode 100644
index 4ec4d011..00000000
--- a/vhosts/blog/public/404.html
+++ /dev/null
@@ -1,51 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2021 nsfisis">
- <meta name="description" content="リクエストされたページが見つかりません">
- <meta property="og:type" content="article">
- <meta property="og:title" content="Page Not Found|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="リクエストされたページが見つかりません">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>Page Not Found|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article>
- <div class="not-found">
- 404
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/about/index.html b/vhosts/blog/public/about/index.html
deleted file mode 100644
index 82609ac7..00000000
--- a/vhosts/blog/public/about/index.html
+++ /dev/null
@@ -1,156 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2021 nsfisis">
- <meta name="description" content="このサイトの著者について">
- <meta property="og:type" content="article">
- <meta property="og:title" content="About|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="このサイトの著者について">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>About|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">nsfisis</h1>
- <div class="my-icon">
- <div id="myIcon">
- <img src="/favicon.svg">
- </div>
- <script defer src="/my-icon.js?h=206d876c67ce6596bb8a1ae16fc7634b">
- </script>
- </div>
- </header>
- <div class="post-content">
- <section>
- <h2>読み方</h2>
- <p>
- 読み方は決めていません。音にする必要があるときは本名である「いまむら」をお使いください。
- </p>
- </section>
- <section>
- <h2>アカウント</h2>
- <ul>
- <li>
- <a href="https://twitter.com/nsfisis" rel="noreferrer" target="_blank">Twitter (現 𝕏): @nsfisis</a>
- </li>
- <li>
- <a href="https://github.com/nsfisis" rel="noreferrer" target="_blank">GitHub: @nsfisis</a>
- </li>
- </ul>
- </section>
- <section>
- <h2>仕事</h2>
- <ul>
- <li>
- 2021-01~現在: <a href="https://www.dgcircus.com/" rel="noreferrer" target="_blank">デジタルサーカス株式会社</a>
- </li>
- </ul>
- </section>
- <section>
- <h2>登壇</h2>
- <ul>
- <li>
- <a href="/slides/2025-04-12/phpcon-odawara-2025/">2025-04-12: PHP カンファレンス小田原 2025 (レギュラートーク (20分))</a>
- </li>
- <li>
- <a href="/slides/2025-03-23/phperkaigi-2025/">2025-03-23: PHPerKaigi 2025 (レギュラートーク (40分))</a>
- </li>
- <li>
- <a href="/slides/2025-02-22/phpcon-nagoya-2025/">2025-02-22: PHP カンファレンス名古屋 2025 (レギュラートーク (30分))</a>
- </li>
- <li>
- <a href="/slides/2024-11-30/cohackpp/">2024-11-30: 紅白ぺぱ合戦 (LT)</a>
- </li>
- <li>
- <a href="/slides/2024-10-30/phpstudy-tokyo-169/">2024-10-30: PHP 勉強会@東京 第169回 (レギュラートーク (20分))</a>
- </li>
- <li>
- <a href="/slides/2024-07-18/phpstudy-tokyo-166/">2024-07-18: PHP 勉強会@東京 第166回 (レギュラートーク (20分))</a>
- </li>
- <li>
- <a href="/slides/2024-04-25/phpstudy-tokyo-163/">2024-04-25: PHP 勉強会@東京 第163回 (LT)</a>
- </li>
- <li>
- <a href="/slides/2024-04-13/phpcon-odawara-2024/">2024-04-13: PHP カンファレンス小田原 2024 (レギュラートーク (15分))</a>
- </li>
- <li>
- <a href="/slides/2024-03-15/ya8-2024/">2024-03-15: Ya8 2024 (レギュラートーク (60分))</a>
- </li>
- <li>
- <a href="/slides/2024-03-08/phperkaigi-2024/">2024-03-08: PHPerKaigi 2024 (レギュラートーク (40分))</a>
- </li>
- <li>
- <a href="/slides/2024-01-24/phpstudy-tokyo-160/">2024-01-24: PHP 勉強会@東京 第160 回 (レギュラートーク)</a>
- </li>
- <li>
- <a href="/slides/2023-10-25/phpstudy-tokyo-157/">2023-10-25: PHP 勉強会@東京 第157 回 (LT)</a>
- </li>
- <li>
- <a href="/slides/2023-08-24/phpstudy-tokyo-155/">2023-08-24: PHP 勉強会@東京 第155 回 (LT)</a>
- </li>
- <li>
- <a href="/slides/2023-07-26/phpstudy-tokyo-154/">2023-07-26: PHP 勉強会@東京 第154 回 (レギュラートーク)</a>
- </li>
- <li>
- <a href="/slides/2023-06-23/phpconfuk-2023-eve/">2023-06-23: PHP カンファレンス福岡 2023 前夜祭 (非公式) (レギュラートーク)</a>
- </li>
- <li>
- <a href="/slides/2023-06-21/phpstudy-tokyo-153/">2023-06-21: PHP 勉強会@東京 第153 回 (LT)</a>
- </li>
- <li>
- <a href="/slides/2023-04-12/phpstudy-tokyo-151/">2023-04-12: PHP 勉強会@東京 第151 回 (LT)</a>
- </li>
- <li>
- <a href="/slides/2023-03-25/phperkaigi-2023-tokens/">2023-03-25: PHPerKaigi 2023 (トークン解説セッション)</a>
- </li>
- <li>
- <a href="/slides/2023-03-24/phperkaigi-2023/">2023-03-24: PHPerKaigi 2023 (レギュラートーク)</a>
- </li>
- <li>
- <a href="/slides/2023-03-15/phpstudy-tokyo-150/">2023-03-15: PHP 勉強会@東京 第150 回 (LT)</a>
- </li>
- <li>
- <a href="/slides/2023-02-15/phpstudy-tokyo-149/">2023-02-15: PHP 勉強会@東京 第149 回 (LT)</a>
- </li>
- <li>
- <a href="/slides/2023-01-18/phpstudy-tokyo-148/">2023-01-18: PHP 勉強会@東京 第148 回 (LT)</a>
- </li>
- </ul>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/atom.xml b/vhosts/blog/public/atom.xml
deleted file mode 100644
index be5ce941..00000000
--- a/vhosts/blog/public/atom.xml
+++ /dev/null
@@ -1,603 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:all</id>
- <title>REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2025-06-15T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:127019eb-e83f-4c9e-ab54-2021124f1bbb</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-06-14/baba-is-you/"></link>
- <title>最高のパズルゲーム Baba Is You をやれ</title>
- <summary>Baba Is You という最高のパズルゲームをクリアした。是非プレイしてほしい。</summary>
- <published>2025-06-14T00:00:00+09:00</published>
- <updated>2025-06-15T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:64f5e1a6-2f5c-4d5d-b1c8-8346a66c1d40</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-05-05/make-tiny-self-hosted-c-compiler/"></link>
- <title>セルフホスト可能な C コンパイラを作った</title>
- <summary>ゴールデンウィークを使って、セルフホストできる C コンパイラを開発した</summary>
- <published>2025-05-05T00:00:00+09:00</published>
- <updated>2025-05-05T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:087e98f2-743c-48d8-9f67-e9b57e354845</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-04-24/composer-patches-v2-does-not-require-gnu-patch-even-on-macos/"></link>
- <title>【Composer】 composer-patches v2 では macOS でも GNU patch のインストールが不要になる (予定)</title>
- <summary>composer-patches は BSD patch に対応しておらず、一部のパッチの適用に失敗する。現在ベータ版である v2 では patch コマンドに依存しなくなり、macOS で使うときのストレスが解消される見込み。</summary>
- <published>2025-04-24T00:00:00+09:00</published>
- <updated>2025-04-24T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:039b3dff-3b75-46b7-a731-9a3a0ff8e21f</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/"></link>
- <title>RubyKaigi 2025 の TRICK で入賞した</title>
- <summary>RubyKaigi 2025 で開催された TRICK において、『最もRuby on Ruby賞』として審査員賞をいただいた。</summary>
- <published>2025-04-20T00:00:00+09:00</published>
- <updated>2025-04-20T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:c6c7c241-46c1-44b5-95b2-c30c3a500df3</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2025-04-12/phpcon-odawara-2025/"></link>
- <title>PHP 8.x 時代のクラス設計(property promotion から property hooks まで)</title>
- <summary>登壇: PHP カンファレンス小田原 2025 (レギュラートーク (20分))</summary>
- <published>2025-04-12T00:00:00+09:00</published>
- <updated>2025-04-12T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:046e4412-bee8-4ffe-9876-6cbeaa0caf6b</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-03-28/http-1-1-send-multiple-same-headers/"></link>
- <title>【HTTP】HTTP/1.1 で同じヘッダを2回送るとどうなるか</title>
- <summary>HTTP/1.1 で同じヘッダを2回送ったときの挙動について仕様を読んでまとめた。</summary>
- <published>2025-03-28T00:00:00+09:00</published>
- <updated>2025-03-28T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:99111377-27e7-427b-9dc5-a23f621fa826</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-03-27/zip-function-like-command-paste-command/"></link>
- <title>zip 関数のようなコマンド paste</title>
- <summary>zip 関数のような動きをする paste コマンドについてのメモ。</summary>
- <published>2025-03-27T00:00:00+09:00</published>
- <updated>2025-03-27T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:ec7f4462-ae56-4bbf-aac7-cbd32bbbeb29</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2025-03-23/phperkaigi-2025/"></link>
- <title>PHPで作るPHP~セルフホストできる言語処理系を作ろう~</title>
- <summary>登壇: PHPerKaigi 2025 (レギュラートーク (40分))</summary>
- <published>2025-03-23T00:00:00+09:00</published>
- <updated>2025-03-23T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:13174dc7-c1a3-465f-9ba6-14f0bc6f5961</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-02-24/phpcon-nagoya-2025-report/"></link>
- <title>PHP カンファレンス名古屋 2025 参加レポ</title>
- <summary>2025-02-22 に開催された、PHP カンファレンス名古屋 2025 に参加した。</summary>
- <published>2025-02-24T00:00:00+09:00</published>
- <updated>2025-02-24T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:9172fbef-c812-4ade-86f5-eaa12c966708</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2025-02-22/phpcon-nagoya-2025/"></link>
- <title>PHP 処理系の garbage collection を理解する~メモリはいつ解放されるのか~</title>
- <summary>登壇: PHP カンファレンス名古屋 2025 (レギュラートーク (30分))</summary>
- <published>2025-02-22T00:00:00+09:00</published>
- <updated>2025-02-22T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:da2a0cec-74b3-4c5e-b2a2-47fe79ef49f9</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-01-26/yaml-breaking-changes-between-v1-1-and-v1-2/"></link>
- <title>【YAML】YAML 1.1 と YAML 1.2 の主な破壊的変更</title>
- <summary>データ記述言語 YAML におけるバージョン 1.1 と 1.2 の主な破壊的変更をまとめた。</summary>
- <published>2025-01-26T00:00:00+09:00</published>
- <updated>2025-01-26T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:ce8f20e8-c79f-48f8-982d-53edd4d20483</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-01-08/phperkaigi-2023-tokens-q1/"></link>
- <title>PHPerKaigi 2023 トークン問題解説 (1/5)</title>
- <summary>PHPerKaigi 2023 でデジタルサーカス株式会社から出題した問題を解説する。全5問中の第1問。</summary>
- <published>2025-01-08T00:00:00+09:00</published>
- <updated>2025-01-11T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:d7f98354-83fc-4cf1-8769-2784f0ebb6c8</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-12-33/2024-reflections/"></link>
- <title>2024年の振り返り</title>
- <summary>2024年にやったことを振り返る</summary>
- <published>2025-01-02T00:00:00+09:00</published>
- <updated>2025-01-02T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:ea0593d3-691c-4e08-8db4-98b8925717ec</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-12-04/cohackpp-report/"></link>
- <title>紅白ぺぱ合戦に参加&amp;LTしました</title>
- <summary>2024-11-30 に開催された紅白ぺぱ合戦に参加し、ぺ陣営のメンバとして LT しました。</summary>
- <published>2024-12-04T00:00:00+09:00</published>
- <updated>2024-12-05T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:e1ca4664-f6f1-4de2-b4a5-ea2b64006708</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-11-30/cohackpp/"></link>
- <title>プログラミングマナー講座</title>
- <summary>登壇: 紅白ぺぱ合戦 (LT)</summary>
- <published>2024-11-30T00:00:00+09:00</published>
- <updated>2024-11-30T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:a84100cf-8c92-4856-addf-81a7c5547074</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-10-30/phpstudy-tokyo-169/"></link>
- <title>PHP で PHP を作る (縮小版)</title>
- <summary>登壇: PHP 勉強会@東京 第169回 (レギュラートーク (20分))</summary>
- <published>2024-10-30T00:00:00+09:00</published>
- <updated>2024-10-30T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:ee7289ee-ff2e-439d-b343-7f87504192fd</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-09-28/mncore-challenge-1/"></link>
- <title>MN-Core Challenge #1 参加レポ</title>
- <summary>2024-08-28 から 2024-09-24 にかけて開催された MN-Core Challenge #1 に参加した。</summary>
- <published>2024-09-28T00:00:00+09:00</published>
- <updated>2024-09-28T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:eed112e4-3227-4b3f-9991-7e11c288ee2b</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-08-19/go-template-access-outer-scope-pipeline-within-with-or-range/"></link>
- <title>【Go】 text/template の with や range の内側から外側の &quot;.&quot; にアクセスする</title>
- <summary>Go言語の text/template における with や range は &quot;.&quot; を上書きする。これらの内側から外側の &quot;.&quot; にアクセスする方法を調べた。</summary>
- <published>2024-08-19T00:00:00+09:00</published>
- <updated>2024-08-19T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:222488dd-cf07-4961-83aa-a014b05369ff</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-07-19/reparojson-fix-only-json-formatter/"></link>
- <title>reparojson: 文法エラーを直すだけの JSON フォーマッタを作った</title>
- <summary>文法エラーだけを直し、空白の削除や挿入といった整形処理を一切おこなわない JSON フォーマッタを作成した。Neovim と連携させる設定例も紹介する。</summary>
- <published>2024-07-19T00:00:00+09:00</published>
- <updated>2024-07-19T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:eec495b5-45e2-4c6f-a725-e62b1e0a7ad5</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-07-18/phpstudy-tokyo-166/"></link>
- <title>PHPerKaigi 2024 で発表した WebAssembly ランタイムのその後</title>
- <summary>登壇: PHP 勉強会@東京 第166回 (レギュラートーク (20分))</summary>
- <published>2024-07-18T00:00:00+09:00</published>
- <updated>2024-07-18T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:8d6f3690-3da3-4235-a81b-b9707cee22ad</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-06-19/scalamatsuri-2024-report/"></link>
- <title>ScalaMatsuri 2024 参加レポ</title>
- <summary>2024-06-08 から 2024-06-09 にかけて開催された、ScalaMatsuri 2024 に参加した。</summary>
- <published>2024-06-19T00:00:00+09:00</published>
- <updated>2024-06-19T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:f13aa9d6-4533-4a15-872a-c298ab2090db</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-05-11/phpconkagawa-2024-report/"></link>
- <title>PHP カンファレンス香川 2024 参加レポ</title>
- <summary>2024-05-11 に開催された、PHP カンファレンス香川 2024 に参加した。</summary>
- <published>2024-05-11T00:00:00+09:00</published>
- <updated>2024-05-11T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:9b26c1ed-45c3-4cad-9476-cbf2cf2e4de7</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-04-29/zsh-file-completion-for-composer-custom-commands/"></link>
- <title>【Zsh】 Composer のカスタムコマンドに対する Zsh 補完で引数にファイルを補完させる</title>
- <summary>Zsh の Composer に対する補完はカスタムコマンドやその引数を補完しない。カスタムコマンドの引数としてファイルを補完させる方法を調べた。</summary>
- <published>2024-04-29T00:00:00+09:00</published>
- <updated>2024-04-29T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:6cf84106-cc69-4d87-b957-9d58d7e585bb</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-04-25/phpstudy-tokyo-163/"></link>
- <title>Tracing JIT の発動条件</title>
- <summary>登壇: PHP 勉強会@東京 第163回 (LT)</summary>
- <published>2024-04-25T00:00:00+09:00</published>
- <updated>2024-04-25T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:a4c326a6-5ffe-450c-abf2-45833c5efb6a</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-04-21/pipefail-option-in-gitlab-ci-cd/"></link>
- <title>【GitLab】 GitLab CI/CD 上での bash/sh は pipefail が有効になっている</title>
- <summary>GitLab CI/CD で bash/sh スクリプトを動かすと、pipefail オプションが有効になった状態で実行される。</summary>
- <published>2024-04-21T00:00:00+09:00</published>
- <updated>2024-04-21T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:be9c896d-7efa-42dd-a50a-dda5fd3a7f5c</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-04-14/phpcon-odawara-2024-report/"></link>
- <title>PHP カンファレンス小田原 2024 参加レポ</title>
- <summary>2024-04-13 に開催された、PHP カンファレンス小田原 2024 に参加した。</summary>
- <published>2024-04-14T00:00:00+09:00</published>
- <updated>2024-06-01T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:69e1694b-5ddb-41a5-a7f4-138ce82a78b2</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-04-13/phpcon-odawara-2024/"></link>
- <title>来る新 JIT エンジンについて知った気になる</title>
- <summary>登壇: PHP カンファレンス小田原 2024 (レギュラートーク (15分))</summary>
- <published>2024-04-13T00:00:00+09:00</published>
- <updated>2024-04-13T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:6b749793-c760-4597-8a4c-b32d027b7585</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-03-20/my-bucket-list/"></link>
- <title>死ぬまでに作る自作○○一覧あるいは人生の TODO リスト</title>
- <summary>駄文</summary>
- <published>2024-03-20T00:00:00+09:00</published>
- <updated>2024-04-07T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:750be5c8-ca52-4cbd-86fe-5645b06bde95</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-03-17/phperkaigi-2024-report/"></link>
- <title>PHPerKaigi 2024 参加レポ</title>
- <summary>2024-03-07 から 2024-03-09 にかけて開催された、PHPerKaigi 2024 に参加した。</summary>
- <published>2024-03-17T00:00:00+09:00</published>
- <updated>2024-07-07T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:da7b1d5a-70df-4c4a-936c-1b49ca1a7c37</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-03-15/ya8-2024/"></link>
- <title>CLI の PHP プログラムを限界まで高速化してみる</title>
- <summary>登壇: Ya8 2024 (レギュラートーク (60分))</summary>
- <published>2024-03-15T00:00:00+09:00</published>
- <updated>2024-03-15T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:cee40048-f3c5-4043-9ef8-a4ee2ae7cf0e</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-03-08/phperkaigi-2024/"></link>
- <title>WebAssembly を理解する 〜VM の作成を通して〜</title>
- <summary>登壇: PHPerKaigi 2024 (レギュラートーク (40分))</summary>
- <published>2024-03-08T00:00:00+09:00</published>
- <updated>2024-03-08T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:fd8fcb03-8e4d-4ca7-8499-0674accc51a9</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-02-22/phpkansai-2024-report/"></link>
- <title>PHPカンファレンス関西 2024 参加レポ</title>
- <summary>2024-02-11 に開催された、PHPカンファレンス関西 2024 に参加した。</summary>
- <published>2024-02-21T00:00:00+09:00</published>
- <updated>2024-02-21T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:230a0048-93c0-4aac-91ef-bb3108f3e587</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-02-10/yapcjapan-2024-report/"></link>
- <title>YAPC::Hiroshima 2024 参加レポ</title>
- <summary>2024-02-10 に開催された、YAPC::Hiroshima 2024 に参加した。</summary>
- <published>2024-02-10T00:00:00+09:00</published>
- <updated>2024-02-10T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:210673d0-c19e-4195-a280-968a0729dd41</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-02-03/install-wireguard-on-personal-server/"></link>
- <title>【備忘録】 個人用サーバに WireGuard を導入する</title>
- <summary>個人用サービスのセルフホストに使っているサーバに WireGuard を導入する作業をしたメモ</summary>
- <published>2024-02-03T00:00:00+09:00</published>
- <updated>2024-02-17T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:82db7893-983a-4631-8bee-d0725d078252</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-01-24/phpstudy-tokyo-160/"></link>
- <title>PHPStan の力で Algebraic Data Types を実現する</title>
- <summary>登壇: PHP 勉強会@東京 第160 回 (レギュラートーク)</summary>
- <published>2024-01-24T00:00:00+09:00</published>
- <updated>2024-01-24T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:05cb16e1-05bc-4359-bc06-88ac20510740</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-01-10/neovim-insert-namespace-declaration-to-empty-php-file/"></link>
- <title>【Neovim】 空の PHP ファイルに namespace 宣言を挿入する</title>
- <summary>Neovim で空の PHP ファイルを開いたとき、ディレクトリの構造に基づいて自動的に namespace 宣言を挿入するようにする。</summary>
- <published>2024-01-10T00:00:00+09:00</published>
- <updated>2024-01-10T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:bfdeed72-dd32-4d55-887f-ba004701ff4c</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2023-12-31/2023-reflections/"></link>
- <title>2023年の振り返り</title>
- <summary>2023年にやったことを振り返る</summary>
- <published>2023-12-31T00:00:00+09:00</published>
- <updated>2023-12-31T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:d0c404bb-4700-4a6f-9911-621e9872d8c6</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2023-12-03/isucon-13/"></link>
- <title>ISUCON 13 に参加した</title>
- <summary>ISUCON 13 に参加した。チーム名「うつしもゆ」、最終スコア 13,580 点</summary>
- <published>2023-12-03T00:00:00+09:00</published>
- <updated>2023-12-03T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:6c377f3f-6f52-4074-b690-c79d02050562</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-10-25/phpstudy-tokyo-157/"></link>
- <title>PHP コードを隔離された環境で安全に動かす (on WebAssembly)</title>
- <summary>登壇: PHP 勉強会@東京 第157 回 (LT)</summary>
- <published>2023-10-25T00:00:00+09:00</published>
- <updated>2023-10-25T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:78419bf2-a1e6-421f-875b-3d93e777b04f</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2023-10-13/i-entered-the-open-university-of-japan/"></link>
- <title>放送大学に入学しました</title>
- <summary>放送大学に入学しました。頑張ります。</summary>
- <published>2023-10-13T00:00:00+09:00</published>
- <updated>2023-10-13T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:0ed1ccc8-d437-481c-8cca-2131ce800cc0</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2023-10-02/compile-php-runtime-to-wasm/"></link>
- <title>PHP の処理系を Emscripten で WebAssembly にコンパイルする</title>
- <summary>PHP の処理系 (php/php-src) を Emscripten で WebAssembly にコンパイルし、任意のコードを隔離された環境で評価できるようにした。</summary>
- <published>2023-10-02T00:00:00+09:00</published>
- <updated>2025-04-23T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:d6118e00-5fb1-4230-9d94-854260beae04</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-08-24/phpstudy-tokyo-155/"></link>
- <title>PHP 3.0 の処理系のソースを読んでみる</title>
- <summary>登壇: PHP 勉強会@東京 第155 回 (LT)</summary>
- <published>2023-08-24T00:00:00+09:00</published>
- <updated>2023-08-24T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:669de08d-9e02-44c5-ac3f-35972112e706</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-07-26/phpstudy-tokyo-154/"></link>
- <title>言語間で比較するエラーの通知と処理</title>
- <summary>登壇: PHP 勉強会@東京 第154 回 (レギュラートーク)</summary>
- <published>2023-07-26T00:00:00+09:00</published>
- <updated>2023-07-26T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:e1568c4c-9bdd-47b9-8b39-939ade4f3ba0</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2023-06-25/phpconfuk-2023-report/"></link>
- <title>PHP カンファレンス福岡 2023 参加レポ</title>
- <summary>2023-06-24 に開催された、PHP カンファレンス福岡に参加した。</summary>
- <published>2023-06-25T00:00:00+09:00</published>
- <updated>2023-06-25T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:72244d87-4cf0-41c4-a074-bcc37acaa678</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-06-23/phpconfuk-2023-eve/"></link>
- <title>巨大なコードベースへ突撃するために</title>
- <summary>登壇: PHP カンファレンス福岡 2023 前夜祭 (非公式) (レギュラートーク)</summary>
- <published>2023-06-23T00:00:00+09:00</published>
- <updated>2023-06-23T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:6016d501-b9c9-474a-a304-1ec1295e049a</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-06-21/phpstudy-tokyo-153/"></link>
- <title>テキストファイルの末尾には改行コードを入れよう</title>
- <summary>登壇: PHP 勉強会@東京 第153 回 (LT)</summary>
- <published>2023-06-21T00:00:00+09:00</published>
- <updated>2023-06-21T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:fe75bb63-1cd9-457e-8244-c444307cd40a</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-04-12/phpstudy-tokyo-151/"></link>
- <title>list でない array の末尾を探す</title>
- <summary>登壇: PHP 勉強会@東京 第151 回 (LT)</summary>
- <published>2023-04-12T00:00:00+09:00</published>
- <updated>2023-04-12T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:21ce39f0-d613-45f2-a760-89c368892d77</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2023-04-04/phperkaigi-2023-report/"></link>
- <title>PHPerKaigi 2023 参加レポ</title>
- <summary>2023-03-23 から 2023-03-25 にかけて開催された、PHPerKaigi 2023 に参加した。</summary>
- <published>2023-04-04T00:00:00+09:00</published>
- <updated>2023-06-28T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:ed36e185-5bfa-42e1-8358-0b1da9b0a063</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2023-04-01/implementation-of-minimal-png-image-encoder/"></link>
- <title>PNG 画像の最小構成エンコーダを実装する</title>
- <summary>PNG 画像として valid な範囲で最大限手抜きしたエンコーダを書く。</summary>
- <published>2023-04-01T00:00:00+09:00</published>
- <updated>2023-04-01T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:3cce70d8-cee9-4e0e-8b38-6ef1e0a8a278</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-03-25/phperkaigi-2023-tokens/"></link>
- <title>PHPer チャレンジ解説 (デジタルサーカス株式会社)</title>
- <summary>登壇: PHPerKaigi 2023 (トークン解説セッション)</summary>
- <published>2023-03-25T00:00:00+09:00</published>
- <updated>2023-03-25T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:2dce7e27-1eaf-4ca4-8037-e9a3ead18b48</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-03-24/phperkaigi-2023/"></link>
- <title>詳説「参照」PHP の参照を完全に理解する</title>
- <summary>登壇: PHPerKaigi 2023 (レギュラートーク)</summary>
- <published>2023-03-24T00:00:00+09:00</published>
- <updated>2023-03-24T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:9376560b-250a-4697-ac10-0903ad16acee</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-03-15/phpstudy-tokyo-150/"></link>
- <title>明日のあなたの役に立たない PHP コーディング技法~細長い FizzBuzz を書く~</title>
- <summary>登壇: PHP 勉強会@東京 第150 回 (LT)</summary>
- <published>2023-03-15T00:00:00+09:00</published>
- <updated>2023-03-18T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:12512894-05d8-42c6-950e-8f5d60f984d8</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2023-03-10/rewrite-this-blog-generator/"></link>
- <title>このブログのジェネレータを書き直した</title>
- <summary>このブログのジェネレータを書き直したので、やったことを書き記しておく。</summary>
- <published>2023-03-10T00:00:00+09:00</published>
- <updated>2023-03-10T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:f23ea81c-5996-4b7e-aab0-4e9f23b172c2</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-02-15/phpstudy-tokyo-149/"></link>
- <title>PHPerKaigi 2023 のトークン問題でボツにした問題を供養する</title>
- <summary>登壇: PHP 勉強会@東京 第149 回 (LT)</summary>
- <published>2023-02-15T00:00:00+09:00</published>
- <updated>2023-02-15T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:693a4c2e-6f21-4840-b793-4e3644a8ec22</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-01-18/phpstudy-tokyo-148/"></link>
- <title>明日のあなたの役に立たない PHP コーディング技法~polyglot~</title>
- <summary>登壇: PHP 勉強会@東京 第148 回 (LT)</summary>
- <published>2023-01-18T00:00:00+09:00</published>
- <updated>2023-01-18T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:89722cfb-7f4b-4e96-80bc-e0096e5eeef6</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2023-01-10/phperkaigi-2023-unused-token-quiz-3/"></link>
- <title>PHPerKaigi 2023: ボツになったトークン問題 その 3</title>
- <summary>来年の PHPerKaigi 2023 でデジタルサーカス株式会社から出題予定のトークン問題のうち、ボツになった問題を公開する (その 3)。</summary>
- <published>2023-01-10T00:00:00+09:00</published>
- <updated>2023-01-10T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:10fe9c47-7029-4874-82bd-b4dc50e07809</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-11-19/phperkaigi-2023-unused-token-quiz-2/"></link>
- <title>PHPerKaigi 2023: ボツになったトークン問題 その 2</title>
- <summary>来年の PHPerKaigi 2023 でデジタルサーカス株式会社から出題予定のトークン問題のうち、ボツになった問題を公開する (その 2)。</summary>
- <published>2022-11-19T00:00:00+09:00</published>
- <updated>2022-11-19T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:673cb872-af2d-41a3-9fb0-60f1afcedb0d</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-10-28/setup-server-for-this-site/"></link>
- <title>【備忘録】 このサイト用の VPS をセットアップしたときのメモ</title>
- <summary>GitHub Pages でホストしていたこのサイトを VPS へ移行したので、そのときにやったことのメモ。99 % 自分用。</summary>
- <published>2022-10-28T00:00:00+09:00</published>
- <updated>2023-08-30T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:46e0d5db-b17e-464c-a723-8c3e01af7d1d</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-10-23/phperkaigi-2023-unused-token-quiz-1/"></link>
- <title>PHPerKaigi 2023: ボツになったトークン問題 その 1</title>
- <summary>来年の PHPerKaigi 2023 でデジタルサーカス株式会社から出題予定のトークン問題のうち、ボツになった問題を公開する (その 1)。</summary>
- <published>2022-10-23T00:00:00+09:00</published>
- <updated>2022-10-23T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:42f0b29b-1e44-4dbe-9864-69abe3bb1e6e</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-09-29/write-fizzbuzz-in-php-2-letters-per-line/"></link>
- <title>【PHP】 fizzbuzz を書く。1行あたり2文字で。</title>
- <summary>PHP で fizzbuzz を書いた。ただし、1行あたりに使える文字数は2文字まで。</summary>
- <published>2022-09-28T00:00:00+09:00</published>
- <updated>2022-09-29T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:cd16debe-8077-4edf-aec0-b1d45955a0e2</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-08-31/support-for-communty-is-employee-benefits/"></link>
- <title>弊社の PHP Foundation への寄付に寄せて</title>
- <summary>先日、私の勤めるデジタルサーカス株式会社が、PHP Foundation へ寄付をおこないました。本件を社内でしつこく推進した1人として、推進の理由等を書き残しておきます。</summary>
- <published>2022-08-31T00:00:00+09:00</published>
- <updated>2022-08-31T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:bb71bb5d-361b-44cb-9753-81d14583d860</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-08-27/php-conference-okinawa-code-golf/"></link>
- <title>PHP カンファレンス沖縄で出題されたコードゴルフの問題を解いてみた</title>
- <summary>PHP カンファレンス沖縄の懇親会 LT で出題されたコードゴルフの問題を解いてみた。</summary>
- <published>2022-08-27T00:00:00+09:00</published>
- <updated>2022-08-27T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:9211e1fe-bca3-43c4-ba4e-c67d62f3fed0</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-05-01/phperkaigi-2022/"></link>
- <title>PHPerKaigi 2022</title>
- <summary>2022-04-09 から 2022-04-11 にかけて開催された、PHPerKaigi 2022 に参加した。</summary>
- <published>2022-05-01T00:00:00+09:00</published>
- <updated>2022-05-01T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:42cf2829-b897-4748-bc22-80dd734a3c09</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-04-24/term-banner-write-tool-showing-banner-in-terminal/"></link>
- <title>term-banner: ターミナルにバナーを表示するツールを書いた</title>
- <summary>ターミナルに任意の文字のバナーを表示するためのツールを Go で書いた。</summary>
- <published>2022-04-24T00:00:00+09:00</published>
- <updated>2022-04-27T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:f4985d54-0907-4449-8101-0fcd382f9e02</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-04-09/phperkaigi-2022-tokens/"></link>
- <title>PHPerKaigi 2022 トークン問題の解説</title>
- <summary>PHPerKaigi 2022 で私が作成した PHPer チャレンジ問題を解説する。</summary>
- <published>2022-04-09T00:00:00+09:00</published>
- <updated>2022-04-16T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:69863d75-ef21-42db-b743-5958f7c86827</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2021-10-02/cpp-you-can-use-keywords-in-attributes/"></link>
- <title>【C++】 属性構文の属性名にはキーワードが使える</title>
- <summary>C++ の属性構文の属性名には、キーワードが使える。ネタ記事。</summary>
- <published>2021-10-02T00:00:00+09:00</published>
- <updated>2021-10-02T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:e1aff84c-d6d4-4dea-bc45-9c41e6445006</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2021-10-02/python-unbound-local-error/"></link>
- <title>【Python】 クロージャとUnboundLocalError: local variable &apos;x&apos; referenced before assignment</title>
- <summary>Python における UnboundLocalError の理由と対処法。</summary>
- <published>2021-10-02T00:00:00+09:00</published>
- <updated>2021-10-02T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:e1456a50-4fc6-42ef-89f3-8be78e01da13</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2021-10-02/ruby-detect-running-implementation/"></link>
- <title>【Ruby】 自身を実行している処理系の種類を判定する</title>
- <summary>Ruby には複数の実装があるが、自身を実行している処理系の種類をスクリプト上からどのように判定すればよいだろうか。</summary>
- <published>2021-10-02T00:00:00+09:00</published>
- <updated>2021-10-02T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:87455008-fe5b-49bf-af5a-b875264f8326</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2021-10-02/ruby-then-keyword-and-case-in/"></link>
- <title>【Ruby】 then キーワードと case in</title>
- <summary>Ruby 3.0 で追加される case in 構文と、then キーワードについて。</summary>
- <published>2021-10-02T00:00:00+09:00</published>
- <updated>2021-10-02T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:91c61980-c262-4e8d-89b0-4304e7f6d644</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2021-10-02/rust-where-are-primitive-types-from/"></link>
- <title>Rust のプリミティブ型はどこからやって来るか</title>
- <summary>Rust のプリミティブ型は予約語ではなく普通の識別子である。どのようにこれが名前解決されるのかを調べた。</summary>
- <published>2021-10-02T00:00:00+09:00</published>
- <updated>2021-10-02T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:44171f75-c312-4c92-9927-3d260e162175</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2021-10-02/vim-difference-between-autocmd-bufwrite-and-bufwritepre/"></link>
- <title>【Vim】 autocmd events の BufWrite/BufWritePre の違い</title>
- <summary>Vim の autocmd events における BufWrite/BufWritePre がどう違うのかを調べた結果、違いはないことがわかった。</summary>
- <published>2021-10-02T00:00:00+09:00</published>
- <updated>2021-10-02T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:665de47e-0ed6-405e-ad30-81c3c4592d45</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2021-10-02/vim-swap-order-of-selected-lines/"></link>
- <title>Vimで選択した行の順番を入れ替える</title>
- <summary>Vim で選択した行の順番を入れ替える方法。</summary>
- <published>2021-10-02T00:00:00+09:00</published>
- <updated>2021-10-02T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:3fbe0b8c-216e-48f6-b905-c0d361b94542</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2021-03-30/phperkaigi-2021/"></link>
- <title>PHPerKaigi 2021</title>
- <summary>2021-03-26 から 2021-03-28 にかけて開催された、PHPerKaigi 2021 に参加した。</summary>
- <published>2021-03-30T00:00:00+09:00</published>
- <updated>2025-04-09T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:6e9c71fd-bc8d-43ce-99c5-13d9f5b87ed2</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2021-03-05/my-first-post/"></link>
- <title>My First Post</title>
- <summary>これはテスト投稿です。これはテスト投稿です。これはテスト投稿です。</summary>
- <published>2021-03-05T00:00:00+09:00</published>
- <updated>2025-05-12T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/favicon.svg b/vhosts/blog/public/favicon.svg
deleted file mode 100644
index 923d78b1..00000000
--- a/vhosts/blog/public/favicon.svg
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg
- width="100" height="100" viewBox="0 0 100 100"
- xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
->
- <defs>
- <g id="favicon.l">
- <line x1="50" y1="5" x2="50" y2="50" stroke="white" stroke-width="2"/>
- <path d="M 50 10 L 46 5 L 54 5" fill="white"/>
- <path d="M 50 30 L 47 50 L 53 50" fill="white"/>
- </g>
- <g id="favicon.s">
- <rect x="0" y="0" width="10" height="10" fill-opacity="0.75"/>
- </g>
- </defs>
- <circle cx="50" cy="50" r="50" fill="orange"/>
-
- <circle cx="50" cy="50" r="45" fill="transparent" stroke="white" stroke-width="4"/>
- <use xlink:href="#favicon.l" transform="rotate( 0, 50, 50)"/>
- <use xlink:href="#favicon.l" transform="rotate( 36, 50, 50)"/>
- <use xlink:href="#favicon.l" transform="rotate( 72, 50, 50)"/>
- <use xlink:href="#favicon.l" transform="rotate(108, 50, 50)"/>
- <use xlink:href="#favicon.l" transform="rotate(144, 50, 50)"/>
- <use xlink:href="#favicon.l" transform="rotate(180, 50, 50)"/>
- <use xlink:href="#favicon.l" transform="rotate(216, 50, 50)"/>
- <use xlink:href="#favicon.l" transform="rotate(252, 50, 50)"/>
- <use xlink:href="#favicon.l" transform="rotate(288, 50, 50)"/>
- <use xlink:href="#favicon.l" transform="rotate(324, 50, 50)"/>
-
- <use xlink:href="#favicon.s" x="50" y="0" fill="darkorange"/>
- <use xlink:href="#favicon.s" x="50" y="20" fill="gold"/>
- <use xlink:href="#favicon.s" x="50" y="30" fill="orange"/>
- <use xlink:href="#favicon.s" x="50" y="70" fill="orange"/>
- <use xlink:href="#favicon.s" x="50" y="90" fill="gold"/>
- <use xlink:href="#favicon.s" x="60" y="10" fill="orange"/>
- <use xlink:href="#favicon.s" x="60" y="20" fill="orange"/>
- <use xlink:href="#favicon.s" x="60" y="30" fill="gold"/>
- <use xlink:href="#favicon.s" x="60" y="50" fill="gold"/>
- <use xlink:href="#favicon.s" x="60" y="70" fill="gold"/>
- <use xlink:href="#favicon.s" x="60" y="80" fill="gold"/>
- <use xlink:href="#favicon.s" x="70" y="0" fill="#ffcd72"/>
- <use xlink:href="#favicon.s" x="70" y="10" fill="orange"/>
- <use xlink:href="#favicon.s" x="70" y="20" fill="gold"/>
- <use xlink:href="#favicon.s" x="70" y="30" fill="gold"/>
- <use xlink:href="#favicon.s" x="70" y="70" fill="darkorange"/>
- <use xlink:href="#favicon.s" x="70" y="90" fill="#ffcd72"/>
- <use xlink:href="#favicon.s" x="80" y="10" fill="#ffd27f"/>
- <use xlink:href="#favicon.s" x="80" y="20" fill="orange"/>
- <use xlink:href="#favicon.s" x="80" y="40" fill="gold"/>
- <use xlink:href="#favicon.s" x="80" y="60" fill="orange"/>
- <use xlink:href="#favicon.s" x="80" y="70" fill="orange"/>
- <use xlink:href="#favicon.s" x="80" y="80" fill="#ffd27f"/>
- <use xlink:href="#favicon.s" x="90" y="30" fill="#ffc04c"/>
- <use xlink:href="#favicon.s" x="90" y="40" fill="#ffa90c"/>
- <use xlink:href="#favicon.s" x="90" y="60" fill="#ffc04c"/>
- <use xlink:href="#favicon.s" x="90" y="70" fill="#ffe4b2"/>
-
- <rect x="30" y="35" width="6" height="25" rx="2" ry="2" fill="black"/>
- <rect x="64" y="35" width="6" height="25" rx="2" ry="2" fill="black"/>
-</svg>
diff --git a/vhosts/blog/public/index.html b/vhosts/blog/public/index.html
deleted file mode 100644
index 576fdcbd..00000000
--- a/vhosts/blog/public/index.html
+++ /dev/null
@@ -1,77 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2021 nsfisis">
- <meta name="description" content="nsfisis のブログサイト">
- <meta property="og:type" content="article">
- <meta property="og:title" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="nsfisis のブログサイト">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <article class="post-entry">
- <a href="/about/">
- <header class="entry-header">
- <h2>About</h2>
- </header>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/">
- <header class="entry-header">
- <h2>Posts</h2>
- </header>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/">
- <header class="entry-header">
- <h2>Slides</h2>
- </header>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/">
- <header class="entry-header">
- <h2>Tags</h2>
- </header>
- </a>
- </article>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/my-icon.js b/vhosts/blog/public/my-icon.js
deleted file mode 100644
index 48c556da..00000000
--- a/vhosts/blog/public/my-icon.js
+++ /dev/null
@@ -1,151 +0,0 @@
-const init = () => {
- const SIZE = 100;
- const DPR = globalThis.devicePixelRatio || 1;
- const FPS = 15;
-
- const colorBackground = "rgb(255, 255, 255)";
- const color蜜柑の果実 = "rgb(255, 165, 0)";
- const color蜜柑の内果皮 = "rgb(255, 255, 255)";
- const color蜜柑のじょうのう = "rgb(255, 255, 255)";
- const colorMosaic = [
- [255, 165, 0],
- [255, 140, 0],
- [255, 215, 0],
- [255, 205, 114],
- [255, 210, 127],
- [255, 192, 76],
- [255, 169, 12],
- [255, 228, 178],
- ];
- const colorEye = "rgb(0, 0, 0)";
-
- const container = document.getElementById("myIcon");
- const canvas = document.createElement("canvas");
- canvas.width = SIZE * DPR;
- canvas.height = SIZE * DPR;
- canvas.style.width = `${SIZE}px`;
- canvas.style.height = `${SIZE}px`;
- const ctx = canvas.getContext("2d");
- ctx.scale(DPR, DPR);
-
- let frameCount = 0;
-
- function randomChoice(xs) {
- return xs[(Math.random() * xs.length) | 0];
- }
-
- function roundRect(x, y, w, h, r) {
- ctx.beginPath();
- ctx.moveTo(x + r, y);
- ctx.lineTo(x + w - r, y);
- ctx.quadraticCurveTo(x + w, y, x + w, y + r);
- ctx.lineTo(x + w, y + h - r);
- ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
- ctx.lineTo(x + r, y + h);
- ctx.quadraticCurveTo(x, y + h, x, y + h - r);
- ctx.lineTo(x, y + r);
- ctx.quadraticCurveTo(x, y, x + r, y);
- ctx.closePath();
- ctx.fill();
- }
-
- function draw蜜柑() {
- // 果実、外果皮
- ctx.fillStyle = color蜜柑の果実;
- ctx.beginPath();
- ctx.arc(50, 50, 50, 0, Math.PI * 2);
- ctx.fill();
-
- // 内果皮
- ctx.strokeStyle = color蜜柑の内果皮;
- ctx.lineWidth = 4;
- ctx.beginPath();
- ctx.arc(50, 50, 45, 0, Math.PI * 2);
- ctx.stroke();
-
- // じょうのう
- ctx.strokeStyle = color蜜柑のじょうのう;
- ctx.lineWidth = 2;
- for (let t = 0; t < 10; t++) {
- ctx.save();
- ctx.translate(50, 50);
- ctx.rotate((t * Math.PI) / 5);
-
- ctx.beginPath();
- ctx.moveTo(0, -45);
- ctx.lineTo(0, 0);
- ctx.stroke();
-
- ctx.beginPath();
- ctx.moveTo(0, -40);
- ctx.lineTo(-4, -45);
- ctx.lineTo(4, -45);
- ctx.closePath();
- ctx.stroke();
-
- ctx.beginPath();
- ctx.moveTo(0, -20);
- ctx.lineTo(-3, 0);
- ctx.lineTo(3, 0);
- ctx.closePath();
- ctx.stroke();
-
- ctx.restore();
- }
- }
-
- function drawMosaic(f) {
- for (let dy = 0; dy < 10; dy++) {
- for (let dx = 0; dx < 10; dx++) {
- const y = dy * 10;
- const x = dx * 10;
- if (x < 50) {
- continue;
- }
- if ((x - 45) ** 2 + (y - 45) ** 2 > 55 ** 2) {
- continue;
- }
- if (Math.random() < 0.167 * f) {
- continue;
- }
-
- const [r, g, b] = randomChoice(colorMosaic);
- const a = 0.9 - f * 0.05;
- ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;
- ctx.fillRect(x, y, 10, 10);
- }
- }
- }
-
- function drawEyes() {
- ctx.fillStyle = colorEye;
- roundRect(30, 35, 6, 25, 2);
- roundRect(64, 35, 6, 25, 2);
- }
-
- function mainLoop() {
- frameCount++;
- if (4 <= frameCount % 15) {
- setTimeout(mainLoop, 1000 / FPS);
- return;
- }
-
- ctx.fillStyle = colorBackground;
- ctx.fillRect(0, 0, SIZE, SIZE);
- ctx.clearRect(0, 0, SIZE, SIZE);
-
- draw蜜柑();
- drawMosaic(frameCount % 15);
- drawEyes();
-
- setTimeout(mainLoop, 1000 / FPS);
- }
-
- mainLoop();
- while (container.firstChild) {
- container.removeChild(container.firstChild);
- }
- container.appendChild(canvas);
-};
-
-document.addEventListener("DOMContentLoaded", init);
diff --git a/vhosts/blog/public/pdf.min.mjs b/vhosts/blog/public/pdf.min.mjs
deleted file mode 100644
index 414d9b8e..00000000
--- a/vhosts/blog/public/pdf.min.mjs
+++ /dev/null
@@ -1,21 +0,0 @@
-/**
- * @licstart The following is the entire license notice for the
- * JavaScript code in this page
- *
- * Copyright 2023 Mozilla Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @licend The above is the entire license notice for the
- * JavaScript code in this page
- */var t={d:(e,i)=>{for(var s in i)t.o(i,s)&&!t.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:i[s]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)},__webpack_exports__=globalThis.pdfjsLib={};t.d(__webpack_exports__,{AbortException:()=>AbortException,AnnotationEditorLayer:()=>AnnotationEditorLayer,AnnotationEditorParamsType:()=>g,AnnotationEditorType:()=>p,AnnotationEditorUIManager:()=>AnnotationEditorUIManager,AnnotationLayer:()=>AnnotationLayer,AnnotationMode:()=>u,CMapCompressionType:()=>q,ColorPicker:()=>ColorPicker,DOMSVGFactory:()=>DOMSVGFactory,DrawLayer:()=>DrawLayer,FeatureTest:()=>util_FeatureTest,GlobalWorkerOptions:()=>GlobalWorkerOptions,ImageKind:()=>x,InvalidPDFException:()=>InvalidPDFException,MissingPDFException:()=>MissingPDFException,OPS:()=>X,Outliner:()=>Outliner,PDFDataRangeTransport:()=>PDFDataRangeTransport,PDFDateString:()=>PDFDateString,PDFWorker:()=>PDFWorker,PasswordResponses:()=>K,PermissionFlag:()=>m,PixelsPerInch:()=>PixelsPerInch,RenderingCancelledException:()=>RenderingCancelledException,TextLayer:()=>TextLayer,UnexpectedResponseException:()=>UnexpectedResponseException,Util:()=>Util,VerbosityLevel:()=>W,XfaLayer:()=>XfaLayer,build:()=>Yt,createValidAbsoluteUrl:()=>createValidAbsoluteUrl,fetchData:()=>fetchData,getDocument:()=>getDocument,getFilenameFromUrl:()=>getFilenameFromUrl,getPdfFilenameFromUrl:()=>getPdfFilenameFromUrl,getXfaPageViewport:()=>getXfaPageViewport,isDataScheme:()=>isDataScheme,isPdfFile:()=>isPdfFile,noContextMenu:()=>noContextMenu,normalizeUnicode:()=>normalizeUnicode,renderTextLayer:()=>renderTextLayer,setLayerDimensions:()=>setLayerDimensions,shadow:()=>shadow,updateTextLayer:()=>updateTextLayer,version:()=>Kt});const e=!("object"!=typeof process||process+""!="[object process]"||process.versions.nw||process.versions.electron&&process.type&&"browser"!==process.type),i=[1,0,0,1,0,0],s=[.001,0,0,.001,0,0],n=1.35,a=1,r=2,o=4,h=16,l=32,d=64,c=256,u={DISABLE:0,ENABLE:1,ENABLE_FORMS:2,ENABLE_STORAGE:3},p={DISABLE:-1,NONE:0,FREETEXT:3,HIGHLIGHT:9,STAMP:13,INK:15},g={RESIZE:1,CREATE:2,FREETEXT_SIZE:11,FREETEXT_COLOR:12,FREETEXT_OPACITY:13,INK_COLOR:21,INK_THICKNESS:22,INK_OPACITY:23,HIGHLIGHT_COLOR:31,HIGHLIGHT_DEFAULT_COLOR:32,HIGHLIGHT_THICKNESS:33,HIGHLIGHT_FREE:34,HIGHLIGHT_SHOW_ALL:35},m={PRINT:4,MODIFY_CONTENTS:8,COPY:16,MODIFY_ANNOTATIONS:32,FILL_INTERACTIVE_FORMS:256,COPY_FOR_ACCESSIBILITY:512,ASSEMBLE:1024,PRINT_HIGH_QUALITY:2048},f=0,b=1,v=2,A=3,y=3,w=4,x={GRAYSCALE_1BPP:1,RGB_24BPP:2,RGBA_32BPP:3},E=1,_=2,C=3,S=4,T=5,M=6,k=7,P=8,D=9,R=10,F=11,I=12,L=13,O=14,N=15,B=16,H=17,z=20,U=1,j=2,$=3,V=4,G=5,W={ERRORS:0,WARNINGS:1,INFOS:5},q={NONE:0,BINARY:1},X={dependency:1,setLineWidth:2,setLineCap:3,setLineJoin:4,setMiterLimit:5,setDash:6,setRenderingIntent:7,setFlatness:8,setGState:9,save:10,restore:11,transform:12,moveTo:13,lineTo:14,curveTo:15,curveTo2:16,curveTo3:17,closePath:18,rectangle:19,stroke:20,closeStroke:21,fill:22,eoFill:23,fillStroke:24,eoFillStroke:25,closeFillStroke:26,closeEOFillStroke:27,endPath:28,clip:29,eoClip:30,beginText:31,endText:32,setCharSpacing:33,setWordSpacing:34,setHScale:35,setLeading:36,setFont:37,setTextRenderingMode:38,setTextRise:39,moveText:40,setLeadingMoveText:41,setTextMatrix:42,nextLine:43,showText:44,showSpacedText:45,nextLineShowText:46,nextLineSetSpacingShowText:47,setCharWidth:48,setCharWidthAndBounds:49,setStrokeColorSpace:50,setFillColorSpace:51,setStrokeColor:52,setStrokeColorN:53,setFillColor:54,setFillColorN:55,setStrokeGray:56,setFillGray:57,setStrokeRGBColor:58,setFillRGBColor:59,setStrokeCMYKColor:60,setFillCMYKColor:61,shadingFill:62,beginInlineImage:63,beginImageData:64,endInlineImage:65,paintXObject:66,markPoint:67,markPointProps:68,beginMarkedContent:69,beginMarkedContentProps:70,endMarkedContent:71,beginCompat:72,endCompat:73,paintFormXObjectBegin:74,paintFormXObjectEnd:75,beginGroup:76,endGroup:77,beginAnnotation:80,endAnnotation:81,paintImageMaskXObject:83,paintImageMaskXObjectGroup:84,paintImageXObject:85,paintInlineImageXObject:86,paintInlineImageXObjectGroup:87,paintImageXObjectRepeat:88,paintImageMaskXObjectRepeat:89,paintSolidColorImageMask:90,constructPath:91},K={NEED_PASSWORD:1,INCORRECT_PASSWORD:2};let Y=W.WARNINGS;function setVerbosityLevel(t){Number.isInteger(t)&&(Y=t)}function getVerbosityLevel(){return Y}function info(t){Y>=W.INFOS&&console.log(`Info: ${t}`)}function warn(t){Y>=W.WARNINGS&&console.log(`Warning: ${t}`)}function unreachable(t){throw new Error(t)}function assert(t,e){t||unreachable(e)}function createValidAbsoluteUrl(t,e=null,i=null){if(!t)return null;try{if(i&&"string"==typeof t){if(i.addDefaultProtocol&&t.startsWith("www.")){const e=t.match(/\./g);e?.length>=2&&(t=`http://${t}`)}if(i.tryConvertEncoding)try{t=function stringToUTF8String(t){return decodeURIComponent(escape(t))}(t)}catch{}}const s=e?new URL(t,e):new URL(t);if(function _isValidProtocol(t){switch(t?.protocol){case"http:":case"https:":case"ftp:":case"mailto:":case"tel:":return!0;default:return!1}}(s))return s}catch{}return null}function shadow(t,e,i,s=!1){Object.defineProperty(t,e,{value:i,enumerable:!s,configurable:!0,writable:!1});return i}const Q=function BaseExceptionClosure(){function BaseException(t,e){this.constructor===BaseException&&unreachable("Cannot initialize BaseException.");this.message=t;this.name=e}BaseException.prototype=new Error;BaseException.constructor=BaseException;return BaseException}();class PasswordException extends Q{constructor(t,e){super(t,"PasswordException");this.code=e}}class UnknownErrorException extends Q{constructor(t,e){super(t,"UnknownErrorException");this.details=e}}class InvalidPDFException extends Q{constructor(t){super(t,"InvalidPDFException")}}class MissingPDFException extends Q{constructor(t){super(t,"MissingPDFException")}}class UnexpectedResponseException extends Q{constructor(t,e){super(t,"UnexpectedResponseException");this.status=e}}class FormatError extends Q{constructor(t){super(t,"FormatError")}}class AbortException extends Q{constructor(t){super(t,"AbortException")}}function bytesToString(t){"object"==typeof t&&void 0!==t?.length||unreachable("Invalid argument for bytesToString");const e=t.length,i=8192;if(e<i)return String.fromCharCode.apply(null,t);const s=[];for(let n=0;n<e;n+=i){const a=Math.min(n+i,e),r=t.subarray(n,a);s.push(String.fromCharCode.apply(null,r))}return s.join("")}function stringToBytes(t){"string"!=typeof t&&unreachable("Invalid argument for stringToBytes");const e=t.length,i=new Uint8Array(e);for(let s=0;s<e;++s)i[s]=255&t.charCodeAt(s);return i}function objectFromMap(t){const e=Object.create(null);for(const[i,s]of t)e[i]=s;return e}class util_FeatureTest{static get isLittleEndian(){return shadow(this,"isLittleEndian",function isLittleEndian(){const t=new Uint8Array(4);t[0]=1;return 1===new Uint32Array(t.buffer,0,1)[0]}())}static get isEvalSupported(){return shadow(this,"isEvalSupported",function isEvalSupported(){try{new Function("");return!0}catch{return!1}}())}static get isOffscreenCanvasSupported(){return shadow(this,"isOffscreenCanvasSupported","undefined"!=typeof OffscreenCanvas)}static get platform(){return"undefined"!=typeof navigator&&"string"==typeof navigator?.platform?shadow(this,"platform",{isMac:navigator.platform.includes("Mac")}):shadow(this,"platform",{isMac:!1})}static get isCSSRoundSupported(){return shadow(this,"isCSSRoundSupported",globalThis.CSS?.supports?.("width: round(1.5px, 1px)"))}}const J=Array.from(Array(256).keys(),(t=>t.toString(16).padStart(2,"0")));class Util{static makeHexColor(t,e,i){return`#${J[t]}${J[e]}${J[i]}`}static scaleMinMax(t,e){let i;if(t[0]){if(t[0]<0){i=e[0];e[0]=e[2];e[2]=i}e[0]*=t[0];e[2]*=t[0];if(t[3]<0){i=e[1];e[1]=e[3];e[3]=i}e[1]*=t[3];e[3]*=t[3]}else{i=e[0];e[0]=e[1];e[1]=i;i=e[2];e[2]=e[3];e[3]=i;if(t[1]<0){i=e[1];e[1]=e[3];e[3]=i}e[1]*=t[1];e[3]*=t[1];if(t[2]<0){i=e[0];e[0]=e[2];e[2]=i}e[0]*=t[2];e[2]*=t[2]}e[0]+=t[4];e[1]+=t[5];e[2]+=t[4];e[3]+=t[5]}static transform(t,e){return[t[0]*e[0]+t[2]*e[1],t[1]*e[0]+t[3]*e[1],t[0]*e[2]+t[2]*e[3],t[1]*e[2]+t[3]*e[3],t[0]*e[4]+t[2]*e[5]+t[4],t[1]*e[4]+t[3]*e[5]+t[5]]}static applyTransform(t,e){return[t[0]*e[0]+t[1]*e[2]+e[4],t[0]*e[1]+t[1]*e[3]+e[5]]}static applyInverseTransform(t,e){const i=e[0]*e[3]-e[1]*e[2];return[(t[0]*e[3]-t[1]*e[2]+e[2]*e[5]-e[4]*e[3])/i,(-t[0]*e[1]+t[1]*e[0]+e[4]*e[1]-e[5]*e[0])/i]}static getAxialAlignedBoundingBox(t,e){const i=this.applyTransform(t,e),s=this.applyTransform(t.slice(2,4),e),n=this.applyTransform([t[0],t[3]],e),a=this.applyTransform([t[2],t[1]],e);return[Math.min(i[0],s[0],n[0],a[0]),Math.min(i[1],s[1],n[1],a[1]),Math.max(i[0],s[0],n[0],a[0]),Math.max(i[1],s[1],n[1],a[1])]}static inverseTransform(t){const e=t[0]*t[3]-t[1]*t[2];return[t[3]/e,-t[1]/e,-t[2]/e,t[0]/e,(t[2]*t[5]-t[4]*t[3])/e,(t[4]*t[1]-t[5]*t[0])/e]}static singularValueDecompose2dScale(t){const e=[t[0],t[2],t[1],t[3]],i=t[0]*e[0]+t[1]*e[2],s=t[0]*e[1]+t[1]*e[3],n=t[2]*e[0]+t[3]*e[2],a=t[2]*e[1]+t[3]*e[3],r=(i+a)/2,o=Math.sqrt((i+a)**2-4*(i*a-n*s))/2,h=r+o||1,l=r-o||1;return[Math.sqrt(h),Math.sqrt(l)]}static normalizeRect(t){const e=t.slice(0);if(t[0]>t[2]){e[0]=t[2];e[2]=t[0]}if(t[1]>t[3]){e[1]=t[3];e[3]=t[1]}return e}static intersect(t,e){const i=Math.max(Math.min(t[0],t[2]),Math.min(e[0],e[2])),s=Math.min(Math.max(t[0],t[2]),Math.max(e[0],e[2]));if(i>s)return null;const n=Math.max(Math.min(t[1],t[3]),Math.min(e[1],e[3])),a=Math.min(Math.max(t[1],t[3]),Math.max(e[1],e[3]));return n>a?null:[i,n,s,a]}static#t(t,e,i,s,n,a,r,o,h,l){if(h<=0||h>=1)return;const d=1-h,c=h*h,u=c*h,p=d*(d*(d*t+3*h*e)+3*c*i)+u*s,g=d*(d*(d*n+3*h*a)+3*c*r)+u*o;l[0]=Math.min(l[0],p);l[1]=Math.min(l[1],g);l[2]=Math.max(l[2],p);l[3]=Math.max(l[3],g)}static#e(t,e,i,s,n,a,r,o,h,l,d,c){if(Math.abs(h)<1e-12){Math.abs(l)>=1e-12&&this.#t(t,e,i,s,n,a,r,o,-d/l,c);return}const u=l**2-4*d*h;if(u<0)return;const p=Math.sqrt(u),g=2*h;this.#t(t,e,i,s,n,a,r,o,(-l+p)/g,c);this.#t(t,e,i,s,n,a,r,o,(-l-p)/g,c)}static bezierBoundingBox(t,e,i,s,n,a,r,o,h){if(h){h[0]=Math.min(h[0],t,r);h[1]=Math.min(h[1],e,o);h[2]=Math.max(h[2],t,r);h[3]=Math.max(h[3],e,o)}else h=[Math.min(t,r),Math.min(e,o),Math.max(t,r),Math.max(e,o)];this.#e(t,i,n,r,e,s,a,o,3*(3*(i-n)-t+r),6*(t-2*i+n),3*(i-t),h);this.#e(t,i,n,r,e,s,a,o,3*(3*(s-a)-e+o),6*(e-2*s+a),3*(s-e),h);return h}}let Z=null,tt=null;function normalizeUnicode(t){if(!Z){Z=/([\u00a0\u00b5\u037e\u0eb3\u2000-\u200a\u202f\u2126\ufb00-\ufb04\ufb06\ufb20-\ufb36\ufb38-\ufb3c\ufb3e\ufb40-\ufb41\ufb43-\ufb44\ufb46-\ufba1\ufba4-\ufba9\ufbae-\ufbb1\ufbd3-\ufbdc\ufbde-\ufbe7\ufbea-\ufbf8\ufbfc-\ufbfd\ufc00-\ufc5d\ufc64-\ufcf1\ufcf5-\ufd3d\ufd88\ufdf4\ufdfa-\ufdfb\ufe71\ufe77\ufe79\ufe7b\ufe7d]+)|(\ufb05+)/gu;tt=new Map([["ſt","ſt"]])}return t.replaceAll(Z,((t,e,i)=>e?e.normalize("NFKC"):tt.get(i)))}const et="pdfjs_internal_id_",it=0,st=1,nt=2,at=3,rt=4,ot=5,ht=6,lt=7,dt=8;class BaseFilterFactory{constructor(){this.constructor===BaseFilterFactory&&unreachable("Cannot initialize BaseFilterFactory.")}addFilter(t){return"none"}addHCMFilter(t,e){return"none"}addAlphaFilter(t){return"none"}addLuminosityFilter(t){return"none"}addHighlightHCMFilter(t,e,i,s,n){return"none"}destroy(t=!1){}}class BaseCanvasFactory{constructor(){this.constructor===BaseCanvasFactory&&unreachable("Cannot initialize BaseCanvasFactory.")}create(t,e){if(t<=0||e<=0)throw new Error("Invalid canvas size");const i=this._createCanvas(t,e);return{canvas:i,context:i.getContext("2d")}}reset(t,e,i){if(!t.canvas)throw new Error("Canvas is not specified");if(e<=0||i<=0)throw new Error("Invalid canvas size");t.canvas.width=e;t.canvas.height=i}destroy(t){if(!t.canvas)throw new Error("Canvas is not specified");t.canvas.width=0;t.canvas.height=0;t.canvas=null;t.context=null}_createCanvas(t,e){unreachable("Abstract method `_createCanvas` called.")}}class BaseCMapReaderFactory{constructor({baseUrl:t=null,isCompressed:e=!0}){this.constructor===BaseCMapReaderFactory&&unreachable("Cannot initialize BaseCMapReaderFactory.");this.baseUrl=t;this.isCompressed=e}async fetch({name:t}){if(!this.baseUrl)throw new Error('The CMap "baseUrl" parameter must be specified, ensure that the "cMapUrl" and "cMapPacked" API parameters are provided.');if(!t)throw new Error("CMap name must be specified.");const e=this.baseUrl+t+(this.isCompressed?".bcmap":""),i=this.isCompressed?q.BINARY:q.NONE;return this._fetchData(e,i).catch((t=>{throw new Error(`Unable to load ${this.isCompressed?"binary ":""}CMap at: ${e}`)}))}_fetchData(t,e){unreachable("Abstract method `_fetchData` called.")}}class BaseStandardFontDataFactory{constructor({baseUrl:t=null}){this.constructor===BaseStandardFontDataFactory&&unreachable("Cannot initialize BaseStandardFontDataFactory.");this.baseUrl=t}async fetch({filename:t}){if(!this.baseUrl)throw new Error('The standard font "baseUrl" parameter must be specified, ensure that the "standardFontDataUrl" API parameter is provided.');if(!t)throw new Error("Font filename must be specified.");const e=`${this.baseUrl}${t}`;return this._fetchData(e).catch((t=>{throw new Error(`Unable to load font data at: ${e}`)}))}_fetchData(t){unreachable("Abstract method `_fetchData` called.")}}class BaseSVGFactory{constructor(){this.constructor===BaseSVGFactory&&unreachable("Cannot initialize BaseSVGFactory.")}create(t,e,i=!1){if(t<=0||e<=0)throw new Error("Invalid SVG dimensions");const s=this._createSVG("svg:svg");s.setAttribute("version","1.1");if(!i){s.setAttribute("width",`${t}px`);s.setAttribute("height",`${e}px`)}s.setAttribute("preserveAspectRatio","none");s.setAttribute("viewBox",`0 0 ${t} ${e}`);return s}createElement(t){if("string"!=typeof t)throw new Error("Invalid SVG element type");return this._createSVG(t)}_createSVG(t){unreachable("Abstract method `_createSVG` called.")}}const ct="http://www.w3.org/2000/svg";class PixelsPerInch{static CSS=96;static PDF=72;static PDF_TO_CSS_UNITS=this.CSS/this.PDF}async function fetchData(t,e="text"){if(isValidFetchUrl(t,document.baseURI)){const i=await fetch(t);if(!i.ok)throw new Error(i.statusText);switch(e){case"arraybuffer":return i.arrayBuffer();case"blob":return i.blob();case"json":return i.json()}return i.text()}return new Promise(((i,s)=>{const n=new XMLHttpRequest;n.open("GET",t,!0);n.responseType=e;n.onreadystatechange=()=>{if(n.readyState===XMLHttpRequest.DONE)if(200!==n.status&&0!==n.status)s(new Error(n.statusText));else{switch(e){case"arraybuffer":case"blob":case"json":i(n.response);return}i(n.responseText)}};n.send(null)}))}class DOMCMapReaderFactory extends BaseCMapReaderFactory{_fetchData(t,e){return fetchData(t,this.isCompressed?"arraybuffer":"text").then((t=>({cMapData:t instanceof ArrayBuffer?new Uint8Array(t):stringToBytes(t),compressionType:e})))}}class DOMStandardFontDataFactory extends BaseStandardFontDataFactory{_fetchData(t){return fetchData(t,"arraybuffer").then((t=>new Uint8Array(t)))}}class DOMSVGFactory extends BaseSVGFactory{_createSVG(t){return document.createElementNS(ct,t)}}class PageViewport{constructor({viewBox:t,scale:e,rotation:i,offsetX:s=0,offsetY:n=0,dontFlip:a=!1}){this.viewBox=t;this.scale=e;this.rotation=i;this.offsetX=s;this.offsetY=n;const r=(t[2]+t[0])/2,o=(t[3]+t[1])/2;let h,l,d,c,u,p,g,m;(i%=360)<0&&(i+=360);switch(i){case 180:h=-1;l=0;d=0;c=1;break;case 90:h=0;l=1;d=1;c=0;break;case 270:h=0;l=-1;d=-1;c=0;break;case 0:h=1;l=0;d=0;c=-1;break;default:throw new Error("PageViewport: Invalid rotation, must be a multiple of 90 degrees.")}if(a){d=-d;c=-c}if(0===h){u=Math.abs(o-t[1])*e+s;p=Math.abs(r-t[0])*e+n;g=(t[3]-t[1])*e;m=(t[2]-t[0])*e}else{u=Math.abs(r-t[0])*e+s;p=Math.abs(o-t[1])*e+n;g=(t[2]-t[0])*e;m=(t[3]-t[1])*e}this.transform=[h*e,l*e,d*e,c*e,u-h*e*r-d*e*o,p-l*e*r-c*e*o];this.width=g;this.height=m}get rawDims(){const{viewBox:t}=this;return shadow(this,"rawDims",{pageWidth:t[2]-t[0],pageHeight:t[3]-t[1],pageX:t[0],pageY:t[1]})}clone({scale:t=this.scale,rotation:e=this.rotation,offsetX:i=this.offsetX,offsetY:s=this.offsetY,dontFlip:n=!1}={}){return new PageViewport({viewBox:this.viewBox.slice(),scale:t,rotation:e,offsetX:i,offsetY:s,dontFlip:n})}convertToViewportPoint(t,e){return Util.applyTransform([t,e],this.transform)}convertToViewportRectangle(t){const e=Util.applyTransform([t[0],t[1]],this.transform),i=Util.applyTransform([t[2],t[3]],this.transform);return[e[0],e[1],i[0],i[1]]}convertToPdfPoint(t,e){return Util.applyInverseTransform([t,e],this.transform)}}class RenderingCancelledException extends Q{constructor(t,e=0){super(t,"RenderingCancelledException");this.extraDelay=e}}function isDataScheme(t){const e=t.length;let i=0;for(;i<e&&""===t[i].trim();)i++;return"data:"===t.substring(i,i+5).toLowerCase()}function isPdfFile(t){return"string"==typeof t&&/\.pdf$/i.test(t)}function getFilenameFromUrl(t){[t]=t.split(/[#?]/,1);return t.substring(t.lastIndexOf("/")+1)}function getPdfFilenameFromUrl(t,e="document.pdf"){if("string"!=typeof t)return e;if(isDataScheme(t)){warn('getPdfFilenameFromUrl: ignore "data:"-URL for performance reasons.');return e}const i=/[^/?#=]+\.pdf\b(?!.*\.pdf\b)/i,s=/^(?:(?:[^:]+:)?\/\/[^/]+)?([^?#]*)(\?[^#]*)?(#.*)?$/.exec(t);let n=i.exec(s[1])||i.exec(s[2])||i.exec(s[3]);if(n){n=n[0];if(n.includes("%"))try{n=i.exec(decodeURIComponent(n))[0]}catch{}}return n||e}class StatTimer{started=Object.create(null);times=[];time(t){t in this.started&&warn(`Timer is already running for ${t}`);this.started[t]=Date.now()}timeEnd(t){t in this.started||warn(`Timer has not been started for ${t}`);this.times.push({name:t,start:this.started[t],end:Date.now()});delete this.started[t]}toString(){const t=[];let e=0;for(const{name:t}of this.times)e=Math.max(t.length,e);for(const{name:i,start:s,end:n}of this.times)t.push(`${i.padEnd(e)} ${n-s}ms\n`);return t.join("")}}function isValidFetchUrl(t,e){try{const{protocol:i}=e?new URL(t,e):new URL(t);return"http:"===i||"https:"===i}catch{return!1}}function noContextMenu(t){t.preventDefault()}function deprecated(t){console.log("Deprecated API usage: "+t)}let ut;class PDFDateString{static toDateObject(t){if(!t||"string"!=typeof t)return null;ut||=new RegExp("^D:(\\d{4})(\\d{2})?(\\d{2})?(\\d{2})?(\\d{2})?(\\d{2})?([Z|+|-])?(\\d{2})?'?(\\d{2})?'?");const e=ut.exec(t);if(!e)return null;const i=parseInt(e[1],10);let s=parseInt(e[2],10);s=s>=1&&s<=12?s-1:0;let n=parseInt(e[3],10);n=n>=1&&n<=31?n:1;let a=parseInt(e[4],10);a=a>=0&&a<=23?a:0;let r=parseInt(e[5],10);r=r>=0&&r<=59?r:0;let o=parseInt(e[6],10);o=o>=0&&o<=59?o:0;const h=e[7]||"Z";let l=parseInt(e[8],10);l=l>=0&&l<=23?l:0;let d=parseInt(e[9],10)||0;d=d>=0&&d<=59?d:0;if("-"===h){a+=l;r+=d}else if("+"===h){a-=l;r-=d}return new Date(Date.UTC(i,s,n,a,r,o))}}function getXfaPageViewport(t,{scale:e=1,rotation:i=0}){const{width:s,height:n}=t.attributes.style,a=[0,0,parseInt(s),parseInt(n)];return new PageViewport({viewBox:a,scale:e,rotation:i})}function getRGB(t){if(t.startsWith("#")){const e=parseInt(t.slice(1),16);return[(16711680&e)>>16,(65280&e)>>8,255&e]}if(t.startsWith("rgb("))return t.slice(4,-1).split(",").map((t=>parseInt(t)));if(t.startsWith("rgba("))return t.slice(5,-1).split(",").map((t=>parseInt(t))).slice(0,3);warn(`Not a valid color format: "${t}"`);return[0,0,0]}function getCurrentTransform(t){const{a:e,b:i,c:s,d:n,e:a,f:r}=t.getTransform();return[e,i,s,n,a,r]}function getCurrentTransformInverse(t){const{a:e,b:i,c:s,d:n,e:a,f:r}=t.getTransform().invertSelf();return[e,i,s,n,a,r]}function setLayerDimensions(t,e,i=!1,s=!0){if(e instanceof PageViewport){const{pageWidth:s,pageHeight:n}=e.rawDims,{style:a}=t,r=util_FeatureTest.isCSSRoundSupported,o=`var(--scale-factor) * ${s}px`,h=`var(--scale-factor) * ${n}px`,l=r?`round(${o}, 1px)`:`calc(${o})`,d=r?`round(${h}, 1px)`:`calc(${h})`;if(i&&e.rotation%180!=0){a.width=d;a.height=l}else{a.width=l;a.height=d}}s&&t.setAttribute("data-main-rotation",e.rotation)}class EditorToolbar{#i=null;#s=null;#n;#a=null;constructor(t){this.#n=t}render(){const t=this.#i=document.createElement("div");t.className="editToolbar";t.setAttribute("role","toolbar");t.addEventListener("contextmenu",noContextMenu);t.addEventListener("pointerdown",EditorToolbar.#r);const e=this.#a=document.createElement("div");e.className="buttons";t.append(e);const i=this.#n.toolbarPosition;if(i){const{style:e}=t,s="ltr"===this.#n._uiManager.direction?1-i[0]:i[0];e.insetInlineEnd=100*s+"%";e.top=`calc(${100*i[1]}% + var(--editor-toolbar-vert-offset))`}this.#o();return t}static#r(t){t.stopPropagation()}#h(t){this.#n._focusEventsAllowed=!1;t.preventDefault();t.stopPropagation()}#l(t){this.#n._focusEventsAllowed=!0;t.preventDefault();t.stopPropagation()}#d(t){t.addEventListener("focusin",this.#h.bind(this),{capture:!0});t.addEventListener("focusout",this.#l.bind(this),{capture:!0});t.addEventListener("contextmenu",noContextMenu)}hide(){this.#i.classList.add("hidden");this.#s?.hideDropdown()}show(){this.#i.classList.remove("hidden")}#o(){const t=document.createElement("button");t.className="delete";t.tabIndex=0;t.setAttribute("data-l10n-id",`pdfjs-editor-remove-${this.#n.editorType}-button`);this.#d(t);t.addEventListener("click",(t=>{this.#n._uiManager.delete()}));this.#a.append(t)}get#c(){const t=document.createElement("div");t.className="divider";return t}addAltTextButton(t){this.#d(t);this.#a.prepend(t,this.#c)}addColorPicker(t){this.#s=t;const e=t.renderButton();this.#d(e);this.#a.prepend(e,this.#c)}remove(){this.#i.remove();this.#s?.destroy();this.#s=null}}class HighlightToolbar{#a=null;#i=null;#u;constructor(t){this.#u=t}#p(){const t=this.#i=document.createElement("div");t.className="editToolbar";t.setAttribute("role","toolbar");t.addEventListener("contextmenu",noContextMenu);const e=this.#a=document.createElement("div");e.className="buttons";t.append(e);this.#g();return t}#m(t,e){let i=0,s=0;for(const n of t){const t=n.y+n.height;if(t<i)continue;const a=n.x+(e?n.width:0);if(t>i){s=a;i=t}else e?a>s&&(s=a):a<s&&(s=a)}return[e?1-s:s,i]}show(t,e,i){const[s,n]=this.#m(e,i),{style:a}=this.#i||=this.#p();t.append(this.#i);a.insetInlineEnd=100*s+"%";a.top=`calc(${100*n}% + var(--editor-toolbar-vert-offset))`}hide(){this.#i.remove()}#g(){const t=document.createElement("button");t.className="highlightButton";t.tabIndex=0;t.setAttribute("data-l10n-id","pdfjs-highlight-floating-button1");const e=document.createElement("span");t.append(e);e.className="visuallyHidden";e.setAttribute("data-l10n-id","pdfjs-highlight-floating-button-label");t.addEventListener("contextmenu",noContextMenu);t.addEventListener("click",(()=>{this.#u.highlightSelection("floating_button")}));this.#a.append(t)}}function bindEvents(t,e,i){for(const s of i)e.addEventListener(s,t[s].bind(t))}class IdManager{#f=0;get id(){return"pdfjs_internal_editor_"+this.#f++}}class ImageManager{#b=function getUuid(){if("undefined"!=typeof crypto&&"function"==typeof crypto?.randomUUID)return crypto.randomUUID();const t=new Uint8Array(32);if("undefined"!=typeof crypto&&"function"==typeof crypto?.getRandomValues)crypto.getRandomValues(t);else for(let e=0;e<32;e++)t[e]=Math.floor(255*Math.random());return bytesToString(t)}();#f=0;#v=null;static get _isSVGFittingCanvas(){const t=new OffscreenCanvas(1,3).getContext("2d"),e=new Image;e.src='data:image/svg+xml;charset=UTF-8,<svg viewBox="0 0 1 1" width="1" height="1" xmlns="http://www.w3.org/2000/svg"><rect width="1" height="1" style="fill:red;"/></svg>';return shadow(this,"_isSVGFittingCanvas",e.decode().then((()=>{t.drawImage(e,0,0,1,1,0,0,1,3);return 0===new Uint32Array(t.getImageData(0,0,1,1).data.buffer)[0]})))}async#A(t,e){this.#v||=new Map;let i=this.#v.get(t);if(null===i)return null;if(i?.bitmap){i.refCounter+=1;return i}try{i||={bitmap:null,id:`image_${this.#b}_${this.#f++}`,refCounter:0,isSvg:!1};let t;if("string"==typeof e){i.url=e;t=await fetchData(e,"blob")}else t=i.file=e;if("image/svg+xml"===t.type){const e=ImageManager._isSVGFittingCanvas,s=new FileReader,n=new Image,a=new Promise(((t,a)=>{n.onload=()=>{i.bitmap=n;i.isSvg=!0;t()};s.onload=async()=>{const t=i.svgUrl=s.result;n.src=await e?`${t}#svgView(preserveAspectRatio(none))`:t};n.onerror=s.onerror=a}));s.readAsDataURL(t);await a}else i.bitmap=await createImageBitmap(t);i.refCounter=1}catch(t){console.error(t);i=null}this.#v.set(t,i);i&&this.#v.set(i.id,i);return i}async getFromFile(t){const{lastModified:e,name:i,size:s,type:n}=t;return this.#A(`${e}_${i}_${s}_${n}`,t)}async getFromUrl(t){return this.#A(t,t)}async getFromId(t){this.#v||=new Map;const e=this.#v.get(t);if(!e)return null;if(e.bitmap){e.refCounter+=1;return e}return e.file?this.getFromFile(e.file):this.getFromUrl(e.url)}getSvgUrl(t){const e=this.#v.get(t);return e?.isSvg?e.svgUrl:null}deleteId(t){this.#v||=new Map;const e=this.#v.get(t);if(e){e.refCounter-=1;0===e.refCounter&&(e.bitmap=null)}}isValidId(t){return t.startsWith(`image_${this.#b}_`)}}class CommandManager{#y=[];#w=!1;#x;#E=-1;constructor(t=128){this.#x=t}add({cmd:t,undo:e,post:i,mustExec:s,type:n=NaN,overwriteIfSameType:a=!1,keepUndo:r=!1}){s&&t();if(this.#w)return;const o={cmd:t,undo:e,post:i,type:n};if(-1===this.#E){this.#y.length>0&&(this.#y.length=0);this.#E=0;this.#y.push(o);return}if(a&&this.#y[this.#E].type===n){r&&(o.undo=this.#y[this.#E].undo);this.#y[this.#E]=o;return}const h=this.#E+1;if(h===this.#x)this.#y.splice(0,1);else{this.#E=h;h<this.#y.length&&this.#y.splice(h)}this.#y.push(o)}undo(){if(-1===this.#E)return;this.#w=!0;const{undo:t,post:e}=this.#y[this.#E];t();e?.();this.#w=!1;this.#E-=1}redo(){if(this.#E<this.#y.length-1){this.#E+=1;this.#w=!0;const{cmd:t,post:e}=this.#y[this.#E];t();e?.();this.#w=!1}}hasSomethingToUndo(){return-1!==this.#E}hasSomethingToRedo(){return this.#E<this.#y.length-1}destroy(){this.#y=null}}class KeyboardManager{constructor(t){this.buffer=[];this.callbacks=new Map;this.allKeys=new Set;const{isMac:e}=util_FeatureTest.platform;for(const[i,s,n={}]of t)for(const t of i){const i=t.startsWith("mac+");if(e&&i){this.callbacks.set(t.slice(4),{callback:s,options:n});this.allKeys.add(t.split("+").at(-1))}else if(!e&&!i){this.callbacks.set(t,{callback:s,options:n});this.allKeys.add(t.split("+").at(-1))}}}#_(t){t.altKey&&this.buffer.push("alt");t.ctrlKey&&this.buffer.push("ctrl");t.metaKey&&this.buffer.push("meta");t.shiftKey&&this.buffer.push("shift");this.buffer.push(t.key);const e=this.buffer.join("+");this.buffer.length=0;return e}exec(t,e){if(!this.allKeys.has(e.key))return;const i=this.callbacks.get(this.#_(e));if(!i)return;const{callback:s,options:{bubbles:n=!1,args:a=[],checker:r=null}}=i;if(!r||r(t,e)){s.bind(t,...a,e)();if(!n){e.stopPropagation();e.preventDefault()}}}}class ColorManager{static _colorsMapping=new Map([["CanvasText",[0,0,0]],["Canvas",[255,255,255]]]);get _colors(){const t=new Map([["CanvasText",null],["Canvas",null]]);!function getColorValues(t){const e=document.createElement("span");e.style.visibility="hidden";document.body.append(e);for(const i of t.keys()){e.style.color=i;const s=window.getComputedStyle(e).color;t.set(i,getRGB(s))}e.remove()}(t);return shadow(this,"_colors",t)}convert(t){const e=getRGB(t);if(!window.matchMedia("(forced-colors: active)").matches)return e;for(const[t,i]of this._colors)if(i.every(((t,i)=>t===e[i])))return ColorManager._colorsMapping.get(t);return e}getHexCode(t){const e=this._colors.get(t);return e?Util.makeHexColor(...e):t}}class AnnotationEditorUIManager{#C=null;#S=new Map;#T=new Map;#M=null;#k=null;#P=null;#D=new CommandManager;#R=0;#F=new Set;#I=null;#L=null;#O=new Set;#N=!1;#B=null;#H=null;#z=null;#U=!1;#j=null;#$=new IdManager;#V=!1;#G=!1;#W=null;#q=null;#X=null;#K=p.NONE;#Y=new Set;#Q=null;#J=null;#Z=null;#tt=this.blur.bind(this);#et=this.focus.bind(this);#it=this.copy.bind(this);#st=this.cut.bind(this);#nt=this.paste.bind(this);#at=this.keydown.bind(this);#rt=this.keyup.bind(this);#ot=this.onEditingAction.bind(this);#ht=this.onPageChanging.bind(this);#lt=this.onScaleChanging.bind(this);#dt=this.#ct.bind(this);#ut=this.onRotationChanging.bind(this);#pt={isEditing:!1,isEmpty:!0,hasSomethingToUndo:!1,hasSomethingToRedo:!1,hasSelectedEditor:!1,hasSelectedText:!1};#gt=[0,0];#mt=null;#ft=null;#bt=null;static TRANSLATE_SMALL=1;static TRANSLATE_BIG=10;static get _keyboardManager(){const t=AnnotationEditorUIManager.prototype,arrowChecker=t=>t.#ft.contains(document.activeElement)&&"BUTTON"!==document.activeElement.tagName&&t.hasSomethingToControl(),textInputChecker=(t,{target:e})=>{if(e instanceof HTMLInputElement){const{type:t}=e;return"text"!==t&&"number"!==t}return!0},e=this.TRANSLATE_SMALL,i=this.TRANSLATE_BIG;return shadow(this,"_keyboardManager",new KeyboardManager([[["ctrl+a","mac+meta+a"],t.selectAll,{checker:textInputChecker}],[["ctrl+z","mac+meta+z"],t.undo,{checker:textInputChecker}],[["ctrl+y","ctrl+shift+z","mac+meta+shift+z","ctrl+shift+Z","mac+meta+shift+Z"],t.redo,{checker:textInputChecker}],[["Backspace","alt+Backspace","ctrl+Backspace","shift+Backspace","mac+Backspace","mac+alt+Backspace","mac+ctrl+Backspace","Delete","ctrl+Delete","shift+Delete","mac+Delete"],t.delete,{checker:textInputChecker}],[["Enter","mac+Enter"],t.addNewEditorFromKeyboard,{checker:(t,{target:e})=>!(e instanceof HTMLButtonElement)&&t.#ft.contains(e)&&!t.isEnterHandled}],[[" ","mac+ "],t.addNewEditorFromKeyboard,{checker:(t,{target:e})=>!(e instanceof HTMLButtonElement)&&t.#ft.contains(document.activeElement)}],[["Escape","mac+Escape"],t.unselectAll],[["ArrowLeft","mac+ArrowLeft"],t.translateSelectedEditors,{args:[-e,0],checker:arrowChecker}],[["ctrl+ArrowLeft","mac+shift+ArrowLeft"],t.translateSelectedEditors,{args:[-i,0],checker:arrowChecker}],[["ArrowRight","mac+ArrowRight"],t.translateSelectedEditors,{args:[e,0],checker:arrowChecker}],[["ctrl+ArrowRight","mac+shift+ArrowRight"],t.translateSelectedEditors,{args:[i,0],checker:arrowChecker}],[["ArrowUp","mac+ArrowUp"],t.translateSelectedEditors,{args:[0,-e],checker:arrowChecker}],[["ctrl+ArrowUp","mac+shift+ArrowUp"],t.translateSelectedEditors,{args:[0,-i],checker:arrowChecker}],[["ArrowDown","mac+ArrowDown"],t.translateSelectedEditors,{args:[0,e],checker:arrowChecker}],[["ctrl+ArrowDown","mac+shift+ArrowDown"],t.translateSelectedEditors,{args:[0,i],checker:arrowChecker}]]))}constructor(t,e,i,s,n,a,r,o,h){this.#ft=t;this.#bt=e;this.#M=i;this._eventBus=s;this._eventBus._on("editingaction",this.#ot);this._eventBus._on("pagechanging",this.#ht);this._eventBus._on("scalechanging",this.#lt);this._eventBus._on("rotationchanging",this.#ut);this.#vt();this.#At();this.#k=n.annotationStorage;this.#B=n.filterFactory;this.#J=a;this.#z=r||null;this.#N=o;this.#X=h||null;this.viewParameters={realScale:PixelsPerInch.PDF_TO_CSS_UNITS,rotation:0};this.isShiftKeyDown=!1}destroy(){this.#yt();this.#wt();this._eventBus._off("editingaction",this.#ot);this._eventBus._off("pagechanging",this.#ht);this._eventBus._off("scalechanging",this.#lt);this._eventBus._off("rotationchanging",this.#ut);for(const t of this.#T.values())t.destroy();this.#T.clear();this.#S.clear();this.#O.clear();this.#C=null;this.#Y.clear();this.#D.destroy();this.#M?.destroy();this.#j?.hide();this.#j=null;if(this.#H){clearTimeout(this.#H);this.#H=null}if(this.#mt){clearTimeout(this.#mt);this.#mt=null}this.#xt()}async mlGuess(t){return this.#X?.guess(t)||null}get hasMLManager(){return!!this.#X}get hcmFilter(){return shadow(this,"hcmFilter",this.#J?this.#B.addHCMFilter(this.#J.foreground,this.#J.background):"none")}get direction(){return shadow(this,"direction",getComputedStyle(this.#ft).direction)}get highlightColors(){return shadow(this,"highlightColors",this.#z?new Map(this.#z.split(",").map((t=>t.split("=").map((t=>t.trim()))))):null)}get highlightColorNames(){return shadow(this,"highlightColorNames",this.highlightColors?new Map(Array.from(this.highlightColors,(t=>t.reverse()))):null)}setMainHighlightColorPicker(t){this.#q=t}editAltText(t){this.#M?.editAltText(this,t)}onPageChanging({pageNumber:t}){this.#R=t-1}focusMainContainer(){this.#ft.focus()}findParent(t,e){for(const i of this.#T.values()){const{x:s,y:n,width:a,height:r}=i.div.getBoundingClientRect();if(t>=s&&t<=s+a&&e>=n&&e<=n+r)return i}return null}disableUserSelect(t=!1){this.#bt.classList.toggle("noUserSelect",t)}addShouldRescale(t){this.#O.add(t)}removeShouldRescale(t){this.#O.delete(t)}onScaleChanging({scale:t}){this.commitOrRemove();this.viewParameters.realScale=t*PixelsPerInch.PDF_TO_CSS_UNITS;for(const t of this.#O)t.onScaleChanging()}onRotationChanging({pagesRotation:t}){this.commitOrRemove();this.viewParameters.rotation=t}#Et({anchorNode:t}){return t.nodeType===Node.TEXT_NODE?t.parentElement:t}highlightSelection(t=""){const e=document.getSelection();if(!e||e.isCollapsed)return;const{anchorNode:i,anchorOffset:s,focusNode:n,focusOffset:a}=e,r=e.toString(),o=this.#Et(e).closest(".textLayer"),h=this.getSelectionBoxes(o);if(h){e.empty();if(this.#K===p.NONE){this._eventBus.dispatch("showannotationeditorui",{source:this,mode:p.HIGHLIGHT});this.showAllEditors("highlight",!0,!0)}for(const e of this.#T.values())if(e.hasTextLayer(o)){e.createAndAddNewEditor({x:0,y:0},!1,{methodOfCreation:t,boxes:h,anchorNode:i,anchorOffset:s,focusNode:n,focusOffset:a,text:r});break}}}#_t(){const t=document.getSelection();if(!t||t.isCollapsed)return;const e=this.#Et(t).closest(".textLayer"),i=this.getSelectionBoxes(e);if(i){this.#j||=new HighlightToolbar(this);this.#j.show(e,i,"ltr"===this.direction)}}addToAnnotationStorage(t){t.isEmpty()||!this.#k||this.#k.has(t.id)||this.#k.setValue(t.id,t)}#ct(){const t=document.getSelection();if(!t||t.isCollapsed){if(this.#Q){this.#j?.hide();this.#Q=null;this.#Ct({hasSelectedText:!1})}return}const{anchorNode:e}=t;if(e===this.#Q)return;if(this.#Et(t).closest(".textLayer")){this.#j?.hide();this.#Q=e;this.#Ct({hasSelectedText:!0});if(this.#K===p.HIGHLIGHT||this.#K===p.NONE){this.#K===p.HIGHLIGHT&&this.showAllEditors("highlight",!0,!0);this.#U=this.isShiftKeyDown;if(!this.isShiftKeyDown){const pointerup=t=>{if("pointerup"!==t.type||0===t.button){window.removeEventListener("pointerup",pointerup);window.removeEventListener("blur",pointerup);"pointerup"===t.type&&this.#St("main_toolbar")}};window.addEventListener("pointerup",pointerup);window.addEventListener("blur",pointerup)}}}else if(this.#Q){this.#j?.hide();this.#Q=null;this.#Ct({hasSelectedText:!1})}}#St(t=""){this.#K===p.HIGHLIGHT?this.highlightSelection(t):this.#N&&this.#_t()}#vt(){document.addEventListener("selectionchange",this.#dt)}#xt(){document.removeEventListener("selectionchange",this.#dt)}#Tt(){window.addEventListener("focus",this.#et);window.addEventListener("blur",this.#tt)}#wt(){window.removeEventListener("focus",this.#et);window.removeEventListener("blur",this.#tt)}blur(){this.isShiftKeyDown=!1;if(this.#U){this.#U=!1;this.#St("main_toolbar")}if(!this.hasSelection)return;const{activeElement:t}=document;for(const e of this.#Y)if(e.div.contains(t)){this.#W=[e,t];e._focusEventsAllowed=!1;break}}focus(){if(!this.#W)return;const[t,e]=this.#W;this.#W=null;e.addEventListener("focusin",(()=>{t._focusEventsAllowed=!0}),{once:!0});e.focus()}#At(){window.addEventListener("keydown",this.#at);window.addEventListener("keyup",this.#rt)}#yt(){window.removeEventListener("keydown",this.#at);window.removeEventListener("keyup",this.#rt)}#Mt(){document.addEventListener("copy",this.#it);document.addEventListener("cut",this.#st);document.addEventListener("paste",this.#nt)}#kt(){document.removeEventListener("copy",this.#it);document.removeEventListener("cut",this.#st);document.removeEventListener("paste",this.#nt)}addEditListeners(){this.#At();this.#Mt()}removeEditListeners(){this.#yt();this.#kt()}copy(t){t.preventDefault();this.#C?.commitOrRemove();if(!this.hasSelection)return;const e=[];for(const t of this.#Y){const i=t.serialize(!0);i&&e.push(i)}0!==e.length&&t.clipboardData.setData("application/pdfjs",JSON.stringify(e))}cut(t){this.copy(t);this.delete()}paste(t){t.preventDefault();const{clipboardData:e}=t;for(const t of e.items)for(const e of this.#L)if(e.isHandlingMimeForPasting(t.type)){e.paste(t,this.currentLayer);return}let i=e.getData("application/pdfjs");if(!i)return;try{i=JSON.parse(i)}catch(t){warn(`paste: "${t.message}".`);return}if(!Array.isArray(i))return;this.unselectAll();const s=this.currentLayer;try{const t=[];for(const e of i){const i=s.deserialize(e);if(!i)return;t.push(i)}const cmd=()=>{for(const e of t)this.#Pt(e);this.#Dt(t)},undo=()=>{for(const e of t)e.remove()};this.addCommands({cmd,undo,mustExec:!0})}catch(t){warn(`paste: "${t.message}".`)}}keydown(t){this.isShiftKeyDown||"Shift"!==t.key||(this.isShiftKeyDown=!0);this.#K===p.NONE||this.isEditorHandlingKeyboard||AnnotationEditorUIManager._keyboardManager.exec(this,t)}keyup(t){if(this.isShiftKeyDown&&"Shift"===t.key){this.isShiftKeyDown=!1;if(this.#U){this.#U=!1;this.#St("main_toolbar")}}}onEditingAction({name:t}){switch(t){case"undo":case"redo":case"delete":case"selectAll":this[t]();break;case"highlightSelection":this.highlightSelection("context_menu")}}#Ct(t){if(Object.entries(t).some((([t,e])=>this.#pt[t]!==e))){this._eventBus.dispatch("annotationeditorstateschanged",{source:this,details:Object.assign(this.#pt,t)});this.#K===p.HIGHLIGHT&&!1===t.hasSelectedEditor&&this.#Rt([[g.HIGHLIGHT_FREE,!0]])}}#Rt(t){this._eventBus.dispatch("annotationeditorparamschanged",{source:this,details:t})}setEditingState(t){if(t){this.#Tt();this.#Mt();this.#Ct({isEditing:this.#K!==p.NONE,isEmpty:this.#Ft(),hasSomethingToUndo:this.#D.hasSomethingToUndo(),hasSomethingToRedo:this.#D.hasSomethingToRedo(),hasSelectedEditor:!1})}else{this.#wt();this.#kt();this.#Ct({isEditing:!1});this.disableUserSelect(!1)}}registerEditorTypes(t){if(!this.#L){this.#L=t;for(const t of this.#L)this.#Rt(t.defaultPropertiesToUpdate)}}getId(){return this.#$.id}get currentLayer(){return this.#T.get(this.#R)}getLayer(t){return this.#T.get(t)}get currentPageIndex(){return this.#R}addLayer(t){this.#T.set(t.pageIndex,t);this.#V?t.enable():t.disable()}removeLayer(t){this.#T.delete(t.pageIndex)}updateMode(t,e=null,i=!1){if(this.#K!==t){this.#K=t;if(t!==p.NONE){this.setEditingState(!0);this.#It();this.unselectAll();for(const e of this.#T.values())e.updateMode(t);if(e||!i){if(e)for(const t of this.#S.values())if(t.annotationElementId===e){this.setSelected(t);t.enterInEditMode();break}}else this.addNewEditorFromKeyboard()}else{this.setEditingState(!1);this.#Lt()}}}addNewEditorFromKeyboard(){this.currentLayer.canCreateNewEmptyEditor()&&this.currentLayer.addNewEditor()}updateToolbar(t){t!==this.#K&&this._eventBus.dispatch("switchannotationeditormode",{source:this,mode:t})}updateParams(t,e){if(this.#L){switch(t){case g.CREATE:this.currentLayer.addNewEditor();return;case g.HIGHLIGHT_DEFAULT_COLOR:this.#q?.updateColor(e);break;case g.HIGHLIGHT_SHOW_ALL:this._eventBus.dispatch("reporttelemetry",{source:this,details:{type:"editing",data:{type:"highlight",action:"toggle_visibility"}}});(this.#Z||=new Map).set(t,e);this.showAllEditors("highlight",e)}for(const i of this.#Y)i.updateParams(t,e);for(const i of this.#L)i.updateDefaultParams(t,e)}}showAllEditors(t,e,i=!1){for(const i of this.#S.values())i.editorType===t&&i.show(e);(this.#Z?.get(g.HIGHLIGHT_SHOW_ALL)??!0)!==e&&this.#Rt([[g.HIGHLIGHT_SHOW_ALL,e]])}enableWaiting(t=!1){if(this.#G!==t){this.#G=t;for(const e of this.#T.values()){t?e.disableClick():e.enableClick();e.div.classList.toggle("waiting",t)}}}#It(){if(!this.#V){this.#V=!0;for(const t of this.#T.values())t.enable();for(const t of this.#S.values())t.enable()}}#Lt(){this.unselectAll();if(this.#V){this.#V=!1;for(const t of this.#T.values())t.disable();for(const t of this.#S.values())t.disable()}}getEditors(t){const e=[];for(const i of this.#S.values())i.pageIndex===t&&e.push(i);return e}getEditor(t){return this.#S.get(t)}addEditor(t){this.#S.set(t.id,t)}removeEditor(t){if(t.div.contains(document.activeElement)){this.#H&&clearTimeout(this.#H);this.#H=setTimeout((()=>{this.focusMainContainer();this.#H=null}),0)}this.#S.delete(t.id);this.unselect(t);t.annotationElementId&&this.#F.has(t.annotationElementId)||this.#k?.remove(t.id)}addDeletedAnnotationElement(t){this.#F.add(t.annotationElementId);this.addChangedExistingAnnotation(t);t.deleted=!0}isDeletedAnnotationElement(t){return this.#F.has(t)}removeDeletedAnnotationElement(t){this.#F.delete(t.annotationElementId);this.removeChangedExistingAnnotation(t);t.deleted=!1}#Pt(t){const e=this.#T.get(t.pageIndex);if(e)e.addOrRebuild(t);else{this.addEditor(t);this.addToAnnotationStorage(t)}}setActiveEditor(t){if(this.#C!==t){this.#C=t;t&&this.#Rt(t.propertiesToUpdate)}}get#Ot(){let t=null;for(t of this.#Y);return t}updateUI(t){this.#Ot===t&&this.#Rt(t.propertiesToUpdate)}toggleSelected(t){if(this.#Y.has(t)){this.#Y.delete(t);t.unselect();this.#Ct({hasSelectedEditor:this.hasSelection})}else{this.#Y.add(t);t.select();this.#Rt(t.propertiesToUpdate);this.#Ct({hasSelectedEditor:!0})}}setSelected(t){for(const e of this.#Y)e!==t&&e.unselect();this.#Y.clear();this.#Y.add(t);t.select();this.#Rt(t.propertiesToUpdate);this.#Ct({hasSelectedEditor:!0})}isSelected(t){return this.#Y.has(t)}get firstSelectedEditor(){return this.#Y.values().next().value}unselect(t){t.unselect();this.#Y.delete(t);this.#Ct({hasSelectedEditor:this.hasSelection})}get hasSelection(){return 0!==this.#Y.size}get isEnterHandled(){return 1===this.#Y.size&&this.firstSelectedEditor.isEnterHandled}undo(){this.#D.undo();this.#Ct({hasSomethingToUndo:this.#D.hasSomethingToUndo(),hasSomethingToRedo:!0,isEmpty:this.#Ft()})}redo(){this.#D.redo();this.#Ct({hasSomethingToUndo:!0,hasSomethingToRedo:this.#D.hasSomethingToRedo(),isEmpty:this.#Ft()})}addCommands(t){this.#D.add(t);this.#Ct({hasSomethingToUndo:!0,hasSomethingToRedo:!1,isEmpty:this.#Ft()})}#Ft(){if(0===this.#S.size)return!0;if(1===this.#S.size)for(const t of this.#S.values())return t.isEmpty();return!1}delete(){this.commitOrRemove();if(!this.hasSelection)return;const t=[...this.#Y];this.addCommands({cmd:()=>{for(const e of t)e.remove()},undo:()=>{for(const e of t)this.#Pt(e)},mustExec:!0})}commitOrRemove(){this.#C?.commitOrRemove()}hasSomethingToControl(){return this.#C||this.hasSelection}#Dt(t){for(const t of this.#Y)t.unselect();this.#Y.clear();for(const e of t)if(!e.isEmpty()){this.#Y.add(e);e.select()}this.#Ct({hasSelectedEditor:this.hasSelection})}selectAll(){for(const t of this.#Y)t.commit();this.#Dt(this.#S.values())}unselectAll(){if(this.#C){this.#C.commitOrRemove();if(this.#K!==p.NONE)return}if(this.hasSelection){for(const t of this.#Y)t.unselect();this.#Y.clear();this.#Ct({hasSelectedEditor:!1})}}translateSelectedEditors(t,e,i=!1){i||this.commitOrRemove();if(!this.hasSelection)return;this.#gt[0]+=t;this.#gt[1]+=e;const[s,n]=this.#gt,a=[...this.#Y];this.#mt&&clearTimeout(this.#mt);this.#mt=setTimeout((()=>{this.#mt=null;this.#gt[0]=this.#gt[1]=0;this.addCommands({cmd:()=>{for(const t of a)this.#S.has(t.id)&&t.translateInPage(s,n)},undo:()=>{for(const t of a)this.#S.has(t.id)&&t.translateInPage(-s,-n)},mustExec:!1})}),1e3);for(const i of a)i.translateInPage(t,e)}setUpDragSession(){if(this.hasSelection){this.disableUserSelect(!0);this.#I=new Map;for(const t of this.#Y)this.#I.set(t,{savedX:t.x,savedY:t.y,savedPageIndex:t.pageIndex,newX:0,newY:0,newPageIndex:-1})}}endDragSession(){if(!this.#I)return!1;this.disableUserSelect(!1);const t=this.#I;this.#I=null;let e=!1;for(const[{x:i,y:s,pageIndex:n},a]of t){a.newX=i;a.newY=s;a.newPageIndex=n;e||=i!==a.savedX||s!==a.savedY||n!==a.savedPageIndex}if(!e)return!1;const move=(t,e,i,s)=>{if(this.#S.has(t.id)){const n=this.#T.get(s);if(n)t._setParentAndPosition(n,e,i);else{t.pageIndex=s;t.x=e;t.y=i}}};this.addCommands({cmd:()=>{for(const[e,{newX:i,newY:s,newPageIndex:n}]of t)move(e,i,s,n)},undo:()=>{for(const[e,{savedX:i,savedY:s,savedPageIndex:n}]of t)move(e,i,s,n)},mustExec:!0});return!0}dragSelectedEditors(t,e){if(this.#I)for(const i of this.#I.keys())i.drag(t,e)}rebuild(t){if(null===t.parent){const e=this.getLayer(t.pageIndex);if(e){e.changeParent(t);e.addOrRebuild(t)}else{this.addEditor(t);this.addToAnnotationStorage(t);t.rebuild()}}else t.parent.addOrRebuild(t)}get isEditorHandlingKeyboard(){return this.getActive()?.shouldGetKeyboardEvents()||1===this.#Y.size&&this.firstSelectedEditor.shouldGetKeyboardEvents()}isActive(t){return this.#C===t}getActive(){return this.#C}getMode(){return this.#K}get imageManager(){return shadow(this,"imageManager",new ImageManager)}getSelectionBoxes(t){if(!t)return null;const e=document.getSelection();for(let i=0,s=e.rangeCount;i<s;i++)if(!t.contains(e.getRangeAt(i).commonAncestorContainer))return null;const{x:i,y:s,width:n,height:a}=t.getBoundingClientRect();let r;switch(t.getAttribute("data-main-rotation")){case"90":r=(t,e,r,o)=>({x:(e-s)/a,y:1-(t+r-i)/n,width:o/a,height:r/n});break;case"180":r=(t,e,r,o)=>({x:1-(t+r-i)/n,y:1-(e+o-s)/a,width:r/n,height:o/a});break;case"270":r=(t,e,r,o)=>({x:1-(e+o-s)/a,y:(t-i)/n,width:o/a,height:r/n});break;default:r=(t,e,r,o)=>({x:(t-i)/n,y:(e-s)/a,width:r/n,height:o/a})}const o=[];for(let t=0,i=e.rangeCount;t<i;t++){const i=e.getRangeAt(t);if(!i.collapsed)for(const{x:t,y:e,width:s,height:n}of i.getClientRects())0!==s&&0!==n&&o.push(r(t,e,s,n))}return 0===o.length?null:o}addChangedExistingAnnotation({annotationElementId:t,id:e}){(this.#P||=new Map).set(t,e)}removeChangedExistingAnnotation({annotationElementId:t}){this.#P?.delete(t)}renderAnnotationElement(t){const e=this.#P?.get(t.data.id);if(!e)return;const i=this.#k.getRawValue(e);i&&(this.#K!==p.NONE||i.hasBeenModified)&&i.renderAnnotationElement(t)}}class AltText{#Nt="";#Bt=!1;#Ht=null;#zt=null;#Ut=null;#jt=!1;#n=null;static _l10nPromise=null;constructor(t){this.#n=t}static initialize(t){AltText._l10nPromise||=t}async render(){const t=this.#Ht=document.createElement("button");t.className="altText";const e=await AltText._l10nPromise.get("pdfjs-editor-alt-text-button-label");t.textContent=e;t.setAttribute("aria-label",e);t.tabIndex="0";t.addEventListener("contextmenu",noContextMenu);t.addEventListener("pointerdown",(t=>t.stopPropagation()));const onClick=t=>{t.preventDefault();this.#n._uiManager.editAltText(this.#n)};t.addEventListener("click",onClick,{capture:!0});t.addEventListener("keydown",(e=>{if(e.target===t&&"Enter"===e.key){this.#jt=!0;onClick(e)}}));await this.#$t();return t}finish(){if(this.#Ht){this.#Ht.focus({focusVisible:this.#jt});this.#jt=!1}}isEmpty(){return!this.#Nt&&!this.#Bt}get data(){return{altText:this.#Nt,decorative:this.#Bt}}set data({altText:t,decorative:e}){if(this.#Nt!==t||this.#Bt!==e){this.#Nt=t;this.#Bt=e;this.#$t()}}toggle(t=!1){if(this.#Ht){if(!t&&this.#Ut){clearTimeout(this.#Ut);this.#Ut=null}this.#Ht.disabled=!t}}destroy(){this.#Ht?.remove();this.#Ht=null;this.#zt=null}async#$t(){const t=this.#Ht;if(!t)return;if(!this.#Nt&&!this.#Bt){t.classList.remove("done");this.#zt?.remove();return}t.classList.add("done");AltText._l10nPromise.get("pdfjs-editor-alt-text-edit-button-label").then((e=>{t.setAttribute("aria-label",e)}));let e=this.#zt;if(!e){this.#zt=e=document.createElement("span");e.className="tooltip";e.setAttribute("role","tooltip");const i=e.id=`alt-text-tooltip-${this.#n.id}`;t.setAttribute("aria-describedby",i);const s=100;t.addEventListener("mouseenter",(()=>{this.#Ut=setTimeout((()=>{this.#Ut=null;this.#zt.classList.add("show");this.#n._reportTelemetry({action:"alt_text_tooltip"})}),s)}));t.addEventListener("mouseleave",(()=>{if(this.#Ut){clearTimeout(this.#Ut);this.#Ut=null}this.#zt?.classList.remove("show")}))}e.innerText=this.#Bt?await AltText._l10nPromise.get("pdfjs-editor-alt-text-decorative-tooltip"):this.#Nt;e.parentNode||t.append(e);const i=this.#n.getImageForAltText();i?.setAttribute("aria-describedby",e.id)}}class AnnotationEditor{#Vt=null;#Nt=null;#Gt=!1;#Wt=!1;#qt=null;#Xt=null;#Kt=this.focusin.bind(this);#Yt=this.focusout.bind(this);#Qt=null;#Jt="";#Zt=!1;#te=null;#ee=!1;#ie=!1;#se=!1;#ne=null;#ae=0;#re=0;#oe=null;_initialOptions=Object.create(null);_isVisible=!0;_uiManager=null;_focusEventsAllowed=!0;_l10nPromise=null;#he=!1;#le=AnnotationEditor._zIndex++;static _borderLineWidth=-1;static _colorManager=new ColorManager;static _zIndex=1;static _telemetryTimeout=1e3;static get _resizerKeyboardManager(){const t=AnnotationEditor.prototype._resizeWithKeyboard,e=AnnotationEditorUIManager.TRANSLATE_SMALL,i=AnnotationEditorUIManager.TRANSLATE_BIG;return shadow(this,"_resizerKeyboardManager",new KeyboardManager([[["ArrowLeft","mac+ArrowLeft"],t,{args:[-e,0]}],[["ctrl+ArrowLeft","mac+shift+ArrowLeft"],t,{args:[-i,0]}],[["ArrowRight","mac+ArrowRight"],t,{args:[e,0]}],[["ctrl+ArrowRight","mac+shift+ArrowRight"],t,{args:[i,0]}],[["ArrowUp","mac+ArrowUp"],t,{args:[0,-e]}],[["ctrl+ArrowUp","mac+shift+ArrowUp"],t,{args:[0,-i]}],[["ArrowDown","mac+ArrowDown"],t,{args:[0,e]}],[["ctrl+ArrowDown","mac+shift+ArrowDown"],t,{args:[0,i]}],[["Escape","mac+Escape"],AnnotationEditor.prototype._stopResizingWithKeyboard]]))}constructor(t){this.constructor===AnnotationEditor&&unreachable("Cannot initialize AnnotationEditor.");this.parent=t.parent;this.id=t.id;this.width=this.height=null;this.pageIndex=t.parent.pageIndex;this.name=t.name;this.div=null;this._uiManager=t.uiManager;this.annotationElementId=null;this._willKeepAspectRatio=!1;this._initialOptions.isCentered=t.isCentered;this._structTreeParentId=null;const{rotation:e,rawDims:{pageWidth:i,pageHeight:s,pageX:n,pageY:a}}=this.parent.viewport;this.rotation=e;this.pageRotation=(360+e-this._uiManager.viewParameters.rotation)%360;this.pageDimensions=[i,s];this.pageTranslation=[n,a];const[r,o]=this.parentDimensions;this.x=t.x/r;this.y=t.y/o;this.isAttachedToDOM=!1;this.deleted=!1}get editorType(){return Object.getPrototypeOf(this).constructor._type}static get _defaultLineColor(){return shadow(this,"_defaultLineColor",this._colorManager.getHexCode("CanvasText"))}static deleteAnnotationElement(t){const e=new FakeEditor({id:t.parent.getNextId(),parent:t.parent,uiManager:t._uiManager});e.annotationElementId=t.annotationElementId;e.deleted=!0;e._uiManager.addToAnnotationStorage(e)}static initialize(t,e,i){AnnotationEditor._l10nPromise||=new Map(["pdfjs-editor-alt-text-button-label","pdfjs-editor-alt-text-edit-button-label","pdfjs-editor-alt-text-decorative-tooltip","pdfjs-editor-resizer-label-topLeft","pdfjs-editor-resizer-label-topMiddle","pdfjs-editor-resizer-label-topRight","pdfjs-editor-resizer-label-middleRight","pdfjs-editor-resizer-label-bottomRight","pdfjs-editor-resizer-label-bottomMiddle","pdfjs-editor-resizer-label-bottomLeft","pdfjs-editor-resizer-label-middleLeft"].map((e=>[e,t.get(e.replaceAll(/([A-Z])/g,(t=>`-${t.toLowerCase()}`)))])));if(i?.strings)for(const e of i.strings)AnnotationEditor._l10nPromise.set(e,t.get(e));if(-1!==AnnotationEditor._borderLineWidth)return;const s=getComputedStyle(document.documentElement);AnnotationEditor._borderLineWidth=parseFloat(s.getPropertyValue("--outline-width"))||0}static updateDefaultParams(t,e){}static get defaultPropertiesToUpdate(){return[]}static isHandlingMimeForPasting(t){return!1}static paste(t,e){unreachable("Not implemented")}get propertiesToUpdate(){return[]}get _isDraggable(){return this.#he}set _isDraggable(t){this.#he=t;this.div?.classList.toggle("draggable",t)}get isEnterHandled(){return!0}center(){const[t,e]=this.pageDimensions;switch(this.parentRotation){case 90:this.x-=this.height*e/(2*t);this.y+=this.width*t/(2*e);break;case 180:this.x+=this.width/2;this.y+=this.height/2;break;case 270:this.x+=this.height*e/(2*t);this.y-=this.width*t/(2*e);break;default:this.x-=this.width/2;this.y-=this.height/2}this.fixAndSetPosition()}addCommands(t){this._uiManager.addCommands(t)}get currentLayer(){return this._uiManager.currentLayer}setInBackground(){this.div.style.zIndex=0}setInForeground(){this.div.style.zIndex=this.#le}setParent(t){if(null!==t){this.pageIndex=t.pageIndex;this.pageDimensions=t.pageDimensions}else this.#de();this.parent=t}focusin(t){this._focusEventsAllowed&&(this.#Zt?this.#Zt=!1:this.parent.setSelected(this))}focusout(t){if(!this._focusEventsAllowed)return;if(!this.isAttachedToDOM)return;const e=t.relatedTarget;if(!e?.closest(`#${this.id}`)){t.preventDefault();this.parent?.isMultipleSelection||this.commitOrRemove()}}commitOrRemove(){this.isEmpty()?this.remove():this.commit()}commit(){this.addToAnnotationStorage()}addToAnnotationStorage(){this._uiManager.addToAnnotationStorage(this)}setAt(t,e,i,s){const[n,a]=this.parentDimensions;[i,s]=this.screenToPageTranslation(i,s);this.x=(t+i)/n;this.y=(e+s)/a;this.fixAndSetPosition()}#ce([t,e],i,s){[i,s]=this.screenToPageTranslation(i,s);this.x+=i/t;this.y+=s/e;this.fixAndSetPosition()}translate(t,e){this.#ce(this.parentDimensions,t,e)}translateInPage(t,e){this.#te||=[this.x,this.y];this.#ce(this.pageDimensions,t,e);this.div.scrollIntoView({block:"nearest"})}drag(t,e){this.#te||=[this.x,this.y];const[i,s]=this.parentDimensions;this.x+=t/i;this.y+=e/s;if(this.parent&&(this.x<0||this.x>1||this.y<0||this.y>1)){const{x:t,y:e}=this.div.getBoundingClientRect();if(this.parent.findNewParent(this,t,e)){this.x-=Math.floor(this.x);this.y-=Math.floor(this.y)}}let{x:n,y:a}=this;const[r,o]=this.getBaseTranslation();n+=r;a+=o;this.div.style.left=`${(100*n).toFixed(2)}%`;this.div.style.top=`${(100*a).toFixed(2)}%`;this.div.scrollIntoView({block:"nearest"})}get _hasBeenMoved(){return!!this.#te&&(this.#te[0]!==this.x||this.#te[1]!==this.y)}getBaseTranslation(){const[t,e]=this.parentDimensions,{_borderLineWidth:i}=AnnotationEditor,s=i/t,n=i/e;switch(this.rotation){case 90:return[-s,n];case 180:return[s,n];case 270:return[s,-n];default:return[-s,-n]}}get _mustFixPosition(){return!0}fixAndSetPosition(t=this.rotation){const[e,i]=this.pageDimensions;let{x:s,y:n,width:a,height:r}=this;a*=e;r*=i;s*=e;n*=i;if(this._mustFixPosition)switch(t){case 0:s=Math.max(0,Math.min(e-a,s));n=Math.max(0,Math.min(i-r,n));break;case 90:s=Math.max(0,Math.min(e-r,s));n=Math.min(i,Math.max(a,n));break;case 180:s=Math.min(e,Math.max(a,s));n=Math.min(i,Math.max(r,n));break;case 270:s=Math.min(e,Math.max(r,s));n=Math.max(0,Math.min(i-a,n))}this.x=s/=e;this.y=n/=i;const[o,h]=this.getBaseTranslation();s+=o;n+=h;const{style:l}=this.div;l.left=`${(100*s).toFixed(2)}%`;l.top=`${(100*n).toFixed(2)}%`;this.moveInDOM()}static#ue(t,e,i){switch(i){case 90:return[e,-t];case 180:return[-t,-e];case 270:return[-e,t];default:return[t,e]}}screenToPageTranslation(t,e){return AnnotationEditor.#ue(t,e,this.parentRotation)}pageTranslationToScreen(t,e){return AnnotationEditor.#ue(t,e,360-this.parentRotation)}#pe(t){switch(t){case 90:{const[t,e]=this.pageDimensions;return[0,-t/e,e/t,0]}case 180:return[-1,0,0,-1];case 270:{const[t,e]=this.pageDimensions;return[0,t/e,-e/t,0]}default:return[1,0,0,1]}}get parentScale(){return this._uiManager.viewParameters.realScale}get parentRotation(){return(this._uiManager.viewParameters.rotation+this.pageRotation)%360}get parentDimensions(){const{parentScale:t,pageDimensions:[e,i]}=this,s=e*t,n=i*t;return util_FeatureTest.isCSSRoundSupported?[Math.round(s),Math.round(n)]:[s,n]}setDims(t,e){const[i,s]=this.parentDimensions;this.div.style.width=`${(100*t/i).toFixed(2)}%`;this.#Wt||(this.div.style.height=`${(100*e/s).toFixed(2)}%`)}fixDims(){const{style:t}=this.div,{height:e,width:i}=t,s=i.endsWith("%"),n=!this.#Wt&&e.endsWith("%");if(s&&n)return;const[a,r]=this.parentDimensions;s||(t.width=`${(100*parseFloat(i)/a).toFixed(2)}%`);this.#Wt||n||(t.height=`${(100*parseFloat(e)/r).toFixed(2)}%`)}getInitialTranslation(){return[0,0]}#ge(){if(this.#qt)return;this.#qt=document.createElement("div");this.#qt.classList.add("resizers");const t=this._willKeepAspectRatio?["topLeft","topRight","bottomRight","bottomLeft"]:["topLeft","topMiddle","topRight","middleRight","bottomRight","bottomMiddle","bottomLeft","middleLeft"];for(const e of t){const t=document.createElement("div");this.#qt.append(t);t.classList.add("resizer",e);t.setAttribute("data-resizer-name",e);t.addEventListener("pointerdown",this.#me.bind(this,e));t.addEventListener("contextmenu",noContextMenu);t.tabIndex=-1}this.div.prepend(this.#qt)}#me(t,e){e.preventDefault();const{isMac:i}=util_FeatureTest.platform;if(0!==e.button||e.ctrlKey&&i)return;this.#Nt?.toggle(!1);const s=this.#fe.bind(this,t),n=this._isDraggable;this._isDraggable=!1;const a={passive:!0,capture:!0};this.parent.togglePointerEvents(!1);window.addEventListener("pointermove",s,a);window.addEventListener("contextmenu",noContextMenu);const r=this.x,o=this.y,h=this.width,l=this.height,d=this.parent.div.style.cursor,c=this.div.style.cursor;this.div.style.cursor=this.parent.div.style.cursor=window.getComputedStyle(e.target).cursor;const pointerUpCallback=()=>{this.parent.togglePointerEvents(!0);this.#Nt?.toggle(!0);this._isDraggable=n;window.removeEventListener("pointerup",pointerUpCallback);window.removeEventListener("blur",pointerUpCallback);window.removeEventListener("pointermove",s,a);window.removeEventListener("contextmenu",noContextMenu);this.parent.div.style.cursor=d;this.div.style.cursor=c;this.#be(r,o,h,l)};window.addEventListener("pointerup",pointerUpCallback);window.addEventListener("blur",pointerUpCallback)}#be(t,e,i,s){const n=this.x,a=this.y,r=this.width,o=this.height;n===t&&a===e&&r===i&&o===s||this.addCommands({cmd:()=>{this.width=r;this.height=o;this.x=n;this.y=a;const[t,e]=this.parentDimensions;this.setDims(t*r,e*o);this.fixAndSetPosition()},undo:()=>{this.width=i;this.height=s;this.x=t;this.y=e;const[n,a]=this.parentDimensions;this.setDims(n*i,a*s);this.fixAndSetPosition()},mustExec:!0})}#fe(t,e){const[i,s]=this.parentDimensions,n=this.x,a=this.y,r=this.width,o=this.height,h=AnnotationEditor.MIN_SIZE/i,l=AnnotationEditor.MIN_SIZE/s,round=t=>Math.round(1e4*t)/1e4,d=this.#pe(this.rotation),transf=(t,e)=>[d[0]*t+d[2]*e,d[1]*t+d[3]*e],c=this.#pe(360-this.rotation);let u,p,g=!1,m=!1;switch(t){case"topLeft":g=!0;u=(t,e)=>[0,0];p=(t,e)=>[t,e];break;case"topMiddle":u=(t,e)=>[t/2,0];p=(t,e)=>[t/2,e];break;case"topRight":g=!0;u=(t,e)=>[t,0];p=(t,e)=>[0,e];break;case"middleRight":m=!0;u=(t,e)=>[t,e/2];p=(t,e)=>[0,e/2];break;case"bottomRight":g=!0;u=(t,e)=>[t,e];p=(t,e)=>[0,0];break;case"bottomMiddle":u=(t,e)=>[t/2,e];p=(t,e)=>[t/2,0];break;case"bottomLeft":g=!0;u=(t,e)=>[0,e];p=(t,e)=>[t,0];break;case"middleLeft":m=!0;u=(t,e)=>[0,e/2];p=(t,e)=>[t,e/2]}const f=u(r,o),b=p(r,o);let v=transf(...b);const A=round(n+v[0]),y=round(a+v[1]);let w=1,x=1,[E,_]=this.screenToPageTranslation(e.movementX,e.movementY);[E,_]=(C=E/i,S=_/s,[c[0]*C+c[2]*S,c[1]*C+c[3]*S]);var C,S;if(g){const t=Math.hypot(r,o);w=x=Math.max(Math.min(Math.hypot(b[0]-f[0]-E,b[1]-f[1]-_)/t,1/r,1/o),h/r,l/o)}else m?w=Math.max(h,Math.min(1,Math.abs(b[0]-f[0]-E)))/r:x=Math.max(l,Math.min(1,Math.abs(b[1]-f[1]-_)))/o;const T=round(r*w),M=round(o*x);v=transf(...p(T,M));const k=A-v[0],P=y-v[1];this.width=T;this.height=M;this.x=k;this.y=P;this.setDims(i*T,s*M);this.fixAndSetPosition()}altTextFinish(){this.#Nt?.finish()}async addEditToolbar(){if(this.#Qt||this.#ie)return this.#Qt;this.#Qt=new EditorToolbar(this);this.div.append(this.#Qt.render());this.#Nt&&this.#Qt.addAltTextButton(await this.#Nt.render());return this.#Qt}removeEditToolbar(){if(this.#Qt){this.#Qt.remove();this.#Qt=null;this.#Nt?.destroy()}}getClientDimensions(){return this.div.getBoundingClientRect()}async addAltTextButton(){if(!this.#Nt){AltText.initialize(AnnotationEditor._l10nPromise);this.#Nt=new AltText(this);await this.addEditToolbar()}}get altTextData(){return this.#Nt?.data}set altTextData(t){this.#Nt&&(this.#Nt.data=t)}hasAltText(){return!this.#Nt?.isEmpty()}render(){this.div=document.createElement("div");this.div.setAttribute("data-editor-rotation",(360-this.rotation)%360);this.div.className=this.name;this.div.setAttribute("id",this.id);this.div.tabIndex=this.#Gt?-1:0;this._isVisible||this.div.classList.add("hidden");this.setInForeground();this.div.addEventListener("focusin",this.#Kt);this.div.addEventListener("focusout",this.#Yt);const[t,e]=this.parentDimensions;if(this.parentRotation%180!=0){this.div.style.maxWidth=`${(100*e/t).toFixed(2)}%`;this.div.style.maxHeight=`${(100*t/e).toFixed(2)}%`}const[i,s]=this.getInitialTranslation();this.translate(i,s);bindEvents(this,this.div,["pointerdown"]);return this.div}pointerdown(t){const{isMac:e}=util_FeatureTest.platform;if(0!==t.button||t.ctrlKey&&e)t.preventDefault();else{this.#Zt=!0;this._isDraggable?this.#ve(t):this.#Ae(t)}}#Ae(t){const{isMac:e}=util_FeatureTest.platform;t.ctrlKey&&!e||t.shiftKey||t.metaKey&&e?this.parent.toggleSelected(this):this.parent.setSelected(this)}#ve(t){const e=this._uiManager.isSelected(this);this._uiManager.setUpDragSession();let i,s;if(e){this.div.classList.add("moving");i={passive:!0,capture:!0};this.#ae=t.clientX;this.#re=t.clientY;s=t=>{const{clientX:e,clientY:i}=t,[s,n]=this.screenToPageTranslation(e-this.#ae,i-this.#re);this.#ae=e;this.#re=i;this._uiManager.dragSelectedEditors(s,n)};window.addEventListener("pointermove",s,i)}const pointerUpCallback=()=>{window.removeEventListener("pointerup",pointerUpCallback);window.removeEventListener("blur",pointerUpCallback);if(e){this.div.classList.remove("moving");window.removeEventListener("pointermove",s,i)}this.#Zt=!1;this._uiManager.endDragSession()||this.#Ae(t)};window.addEventListener("pointerup",pointerUpCallback);window.addEventListener("blur",pointerUpCallback)}moveInDOM(){this.#ne&&clearTimeout(this.#ne);this.#ne=setTimeout((()=>{this.#ne=null;this.parent?.moveEditorInDOM(this)}),0)}_setParentAndPosition(t,e,i){t.changeParent(this);this.x=e;this.y=i;this.fixAndSetPosition()}getRect(t,e,i=this.rotation){const s=this.parentScale,[n,a]=this.pageDimensions,[r,o]=this.pageTranslation,h=t/s,l=e/s,d=this.x*n,c=this.y*a,u=this.width*n,p=this.height*a;switch(i){case 0:return[d+h+r,a-c-l-p+o,d+h+u+r,a-c-l+o];case 90:return[d+l+r,a-c+h+o,d+l+p+r,a-c+h+u+o];case 180:return[d-h-u+r,a-c+l+o,d-h+r,a-c+l+p+o];case 270:return[d-l-p+r,a-c-h-u+o,d-l+r,a-c-h+o];default:throw new Error("Invalid rotation")}}getRectInCurrentCoords(t,e){const[i,s,n,a]=t,r=n-i,o=a-s;switch(this.rotation){case 0:return[i,e-a,r,o];case 90:return[i,e-s,o,r];case 180:return[n,e-s,r,o];case 270:return[n,e-a,o,r];default:throw new Error("Invalid rotation")}}onceAdded(){}isEmpty(){return!1}enableEditMode(){this.#ie=!0}disableEditMode(){this.#ie=!1}isInEditMode(){return this.#ie}shouldGetKeyboardEvents(){return this.#se}needsToBeRebuilt(){return this.div&&!this.isAttachedToDOM}rebuild(){this.div?.addEventListener("focusin",this.#Kt);this.div?.addEventListener("focusout",this.#Yt)}rotate(t){}serialize(t=!1,e=null){unreachable("An editor must be serializable")}static deserialize(t,e,i){const s=new this.prototype.constructor({parent:e,id:e.getNextId(),uiManager:i});s.rotation=t.rotation;const[n,a]=s.pageDimensions,[r,o,h,l]=s.getRectInCurrentCoords(t.rect,a);s.x=r/n;s.y=o/a;s.width=h/n;s.height=l/a;return s}get hasBeenModified(){return!!this.annotationElementId&&(this.deleted||null!==this.serialize())}remove(){this.div.removeEventListener("focusin",this.#Kt);this.div.removeEventListener("focusout",this.#Yt);this.isEmpty()||this.commit();this.parent?this.parent.remove(this):this._uiManager.removeEditor(this);if(this.#ne){clearTimeout(this.#ne);this.#ne=null}this.#de();this.removeEditToolbar();if(this.#oe){for(const t of this.#oe.values())clearTimeout(t);this.#oe=null}this.parent=null}get isResizable(){return!1}makeResizable(){if(this.isResizable){this.#ge();this.#qt.classList.remove("hidden");bindEvents(this,this.div,["keydown"])}}get toolbarPosition(){return null}keydown(t){if(!this.isResizable||t.target!==this.div||"Enter"!==t.key)return;this._uiManager.setSelected(this);this.#Xt={savedX:this.x,savedY:this.y,savedWidth:this.width,savedHeight:this.height};const e=this.#qt.children;if(!this.#Vt){this.#Vt=Array.from(e);const t=this.#ye.bind(this),i=this.#we.bind(this);for(const e of this.#Vt){const s=e.getAttribute("data-resizer-name");e.setAttribute("role","spinbutton");e.addEventListener("keydown",t);e.addEventListener("blur",i);e.addEventListener("focus",this.#xe.bind(this,s));AnnotationEditor._l10nPromise.get(`pdfjs-editor-resizer-label-${s}`).then((t=>e.setAttribute("aria-label",t)))}}const i=this.#Vt[0];let s=0;for(const t of e){if(t===i)break;s++}const n=(360-this.rotation+this.parentRotation)%360/90*(this.#Vt.length/4);if(n!==s){if(n<s)for(let t=0;t<s-n;t++)this.#qt.append(this.#qt.firstChild);else if(n>s)for(let t=0;t<n-s;t++)this.#qt.firstChild.before(this.#qt.lastChild);let t=0;for(const i of e){const e=this.#Vt[t++].getAttribute("data-resizer-name");AnnotationEditor._l10nPromise.get(`pdfjs-editor-resizer-label-${e}`).then((t=>i.setAttribute("aria-label",t)))}}this.#Ee(0);this.#se=!0;this.#qt.firstChild.focus({focusVisible:!0});t.preventDefault();t.stopImmediatePropagation()}#ye(t){AnnotationEditor._resizerKeyboardManager.exec(this,t)}#we(t){this.#se&&t.relatedTarget?.parentNode!==this.#qt&&this.#de()}#xe(t){this.#Jt=this.#se?t:""}#Ee(t){if(this.#Vt)for(const e of this.#Vt)e.tabIndex=t}_resizeWithKeyboard(t,e){this.#se&&this.#fe(this.#Jt,{movementX:t,movementY:e})}#de(){this.#se=!1;this.#Ee(-1);if(this.#Xt){const{savedX:t,savedY:e,savedWidth:i,savedHeight:s}=this.#Xt;this.#be(t,e,i,s);this.#Xt=null}}_stopResizingWithKeyboard(){this.#de();this.div.focus()}select(){this.makeResizable();this.div?.classList.add("selectedEditor");this.#Qt?this.#Qt?.show():this.addEditToolbar().then((()=>{this.div?.classList.contains("selectedEditor")&&this.#Qt?.show()}))}unselect(){this.#qt?.classList.add("hidden");this.div?.classList.remove("selectedEditor");this.div?.contains(document.activeElement)&&this._uiManager.currentLayer.div.focus({preventScroll:!0});this.#Qt?.hide()}updateParams(t,e){}disableEditing(){}enableEditing(){}enterInEditMode(){}getImageForAltText(){return null}get contentDiv(){return this.div}get isEditing(){return this.#ee}set isEditing(t){this.#ee=t;if(this.parent)if(t){this.parent.setSelected(this);this.parent.setActiveEditor(this)}else this.parent.setActiveEditor(null)}setAspectRatio(t,e){this.#Wt=!0;const i=t/e,{style:s}=this.div;s.aspectRatio=i;s.height="auto"}static get MIN_SIZE(){return 16}static canCreateNewEmptyEditor(){return!0}get telemetryInitialData(){return{action:"added"}}get telemetryFinalData(){return null}_reportTelemetry(t,e=!1){if(e){this.#oe||=new Map;const{action:e}=t;let i=this.#oe.get(e);i&&clearTimeout(i);i=setTimeout((()=>{this._reportTelemetry(t);this.#oe.delete(e);0===this.#oe.size&&(this.#oe=null)}),AnnotationEditor._telemetryTimeout);this.#oe.set(e,i)}else{t.type||=this.editorType;this._uiManager._eventBus.dispatch("reporttelemetry",{source:this,details:{type:"editing",data:t}})}}show(t=this._isVisible){this.div.classList.toggle("hidden",!t);this._isVisible=t}enable(){this.div&&(this.div.tabIndex=0);this.#Gt=!1}disable(){this.div&&(this.div.tabIndex=-1);this.#Gt=!0}renderAnnotationElement(t){let e=t.container.querySelector(".annotationContent");if(e){if("CANVAS"===e.nodeName){const t=e;e=document.createElement("div");e.classList.add("annotationContent",this.editorType);t.before(e)}}else{e=document.createElement("div");e.classList.add("annotationContent",this.editorType);t.container.prepend(e)}return e}resetAnnotationElement(t){const{firstChild:e}=t.container;"DIV"===e.nodeName&&e.classList.contains("annotationContent")&&e.remove()}}class FakeEditor extends AnnotationEditor{constructor(t){super(t);this.annotationElementId=t.annotationElementId;this.deleted=!0}serialize(){return{id:this.annotationElementId,deleted:!0,pageIndex:this.pageIndex}}}const pt=3285377520,gt=4294901760,mt=65535;class MurmurHash3_64{constructor(t){this.h1=t?4294967295&t:pt;this.h2=t?4294967295&t:pt}update(t){let e,i;if("string"==typeof t){e=new Uint8Array(2*t.length);i=0;for(let s=0,n=t.length;s<n;s++){const n=t.charCodeAt(s);if(n<=255)e[i++]=n;else{e[i++]=n>>>8;e[i++]=255&n}}}else{if(!ArrayBuffer.isView(t))throw new Error("Invalid data format, must be a string or TypedArray.");e=t.slice();i=e.byteLength}const s=i>>2,n=i-4*s,a=new Uint32Array(e.buffer,0,s);let r=0,o=0,h=this.h1,l=this.h2;const d=3432918353,c=461845907,u=11601,p=13715;for(let t=0;t<s;t++)if(1&t){r=a[t];r=r*d&gt|r*u&mt;r=r<<15|r>>>17;r=r*c&gt|r*p&mt;h^=r;h=h<<13|h>>>19;h=5*h+3864292196}else{o=a[t];o=o*d&gt|o*u&mt;o=o<<15|o>>>17;o=o*c&gt|o*p&mt;l^=o;l=l<<13|l>>>19;l=5*l+3864292196}r=0;switch(n){case 3:r^=e[4*s+2]<<16;case 2:r^=e[4*s+1]<<8;case 1:r^=e[4*s];r=r*d&gt|r*u&mt;r=r<<15|r>>>17;r=r*c&gt|r*p&mt;1&s?h^=r:l^=r}this.h1=h;this.h2=l}hexdigest(){let t=this.h1,e=this.h2;t^=e>>>1;t=3981806797*t&gt|36045*t&mt;e=4283543511*e&gt|(2950163797*(e<<16|t>>>16)&gt)>>>16;t^=e>>>1;t=444984403*t&gt|60499*t&mt;e=3301882366*e&gt|(3120437893*(e<<16|t>>>16)&gt)>>>16;t^=e>>>1;return(t>>>0).toString(16).padStart(8,"0")+(e>>>0).toString(16).padStart(8,"0")}}const ft=Object.freeze({map:null,hash:"",transfer:void 0});class AnnotationStorage{#_e=!1;#Ce=new Map;constructor(){this.onSetModified=null;this.onResetModified=null;this.onAnnotationEditor=null}getValue(t,e){const i=this.#Ce.get(t);return void 0===i?e:Object.assign(e,i)}getRawValue(t){return this.#Ce.get(t)}remove(t){this.#Ce.delete(t);0===this.#Ce.size&&this.resetModified();if("function"==typeof this.onAnnotationEditor){for(const t of this.#Ce.values())if(t instanceof AnnotationEditor)return;this.onAnnotationEditor(null)}}setValue(t,e){const i=this.#Ce.get(t);let s=!1;if(void 0!==i){for(const[t,n]of Object.entries(e))if(i[t]!==n){s=!0;i[t]=n}}else{s=!0;this.#Ce.set(t,e)}s&&this.#Se();e instanceof AnnotationEditor&&"function"==typeof this.onAnnotationEditor&&this.onAnnotationEditor(e.constructor._type)}has(t){return this.#Ce.has(t)}getAll(){return this.#Ce.size>0?objectFromMap(this.#Ce):null}setAll(t){for(const[e,i]of Object.entries(t))this.setValue(e,i)}get size(){return this.#Ce.size}#Se(){if(!this.#_e){this.#_e=!0;"function"==typeof this.onSetModified&&this.onSetModified()}}resetModified(){if(this.#_e){this.#_e=!1;"function"==typeof this.onResetModified&&this.onResetModified()}}get print(){return new PrintAnnotationStorage(this)}get serializable(){if(0===this.#Ce.size)return ft;const t=new Map,e=new MurmurHash3_64,i=[],s=Object.create(null);let n=!1;for(const[i,a]of this.#Ce){const r=a instanceof AnnotationEditor?a.serialize(!1,s):a;if(r){t.set(i,r);e.update(`${i}:${JSON.stringify(r)}`);n||=!!r.bitmap}}if(n)for(const e of t.values())e.bitmap&&i.push(e.bitmap);return t.size>0?{map:t,hash:e.hexdigest(),transfer:i}:ft}get editorStats(){let t=null;const e=new Map;for(const i of this.#Ce.values()){if(!(i instanceof AnnotationEditor))continue;const s=i.telemetryFinalData;if(!s)continue;const{type:n}=s;e.has(n)||e.set(n,Object.getPrototypeOf(i).constructor);t||=Object.create(null);const a=t[n]||=new Map;for(const[t,e]of Object.entries(s)){if("type"===t)continue;let i=a.get(t);if(!i){i=new Map;a.set(t,i)}const s=i.get(e)??0;i.set(e,s+1)}}for(const[i,s]of e)t[i]=s.computeTelemetryFinalData(t[i]);return t}}class PrintAnnotationStorage extends AnnotationStorage{#Te;constructor(t){super();const{map:e,hash:i,transfer:s}=t.serializable,n=structuredClone(e,s?{transfer:s}:null);this.#Te={map:n,hash:i,transfer:s}}get print(){unreachable("Should not call PrintAnnotationStorage.print")}get serializable(){return this.#Te}}class FontLoader{#Me=new Set;constructor({ownerDocument:t=globalThis.document,styleElement:e=null}){this._document=t;this.nativeFontFaces=new Set;this.styleElement=null;this.loadingRequests=[];this.loadTestFontId=0}addNativeFontFace(t){this.nativeFontFaces.add(t);this._document.fonts.add(t)}removeNativeFontFace(t){this.nativeFontFaces.delete(t);this._document.fonts.delete(t)}insertRule(t){if(!this.styleElement){this.styleElement=this._document.createElement("style");this._document.documentElement.getElementsByTagName("head")[0].append(this.styleElement)}const e=this.styleElement.sheet;e.insertRule(t,e.cssRules.length)}clear(){for(const t of this.nativeFontFaces)this._document.fonts.delete(t);this.nativeFontFaces.clear();this.#Me.clear();if(this.styleElement){this.styleElement.remove();this.styleElement=null}}async loadSystemFont({systemFontInfo:t,_inspectFont:e}){if(t&&!this.#Me.has(t.loadedName)){assert(!this.disableFontFace,"loadSystemFont shouldn't be called when `disableFontFace` is set.");if(this.isFontLoadingAPISupported){const{loadedName:i,src:s,style:n}=t,a=new FontFace(i,s,n);this.addNativeFontFace(a);try{await a.load();this.#Me.add(i);e?.(t)}catch{warn(`Cannot load system font: ${t.baseFontName}, installing it could help to improve PDF rendering.`);this.removeNativeFontFace(a)}}else unreachable("Not implemented: loadSystemFont without the Font Loading API.")}}async bind(t){if(t.attached||t.missingFile&&!t.systemFontInfo)return;t.attached=!0;if(t.systemFontInfo){await this.loadSystemFont(t);return}if(this.isFontLoadingAPISupported){const e=t.createNativeFontFace();if(e){this.addNativeFontFace(e);try{await e.loaded}catch(i){warn(`Failed to load font '${e.family}': '${i}'.`);t.disableFontFace=!0;throw i}}return}const e=t.createFontFaceRule();if(e){this.insertRule(e);if(this.isSyncFontLoadingSupported)return;await new Promise((e=>{const i=this._queueLoadingCallback(e);this._prepareFontLoadEvent(t,i)}))}}get isFontLoadingAPISupported(){return shadow(this,"isFontLoadingAPISupported",!!this._document?.fonts)}get isSyncFontLoadingSupported(){let t=!1;(e||"undefined"!=typeof navigator&&"string"==typeof navigator?.userAgent&&/Mozilla\/5.0.*?rv:\d+.*? Gecko/.test(navigator.userAgent))&&(t=!0);return shadow(this,"isSyncFontLoadingSupported",t)}_queueLoadingCallback(t){const{loadingRequests:e}=this,i={done:!1,complete:function completeRequest(){assert(!i.done,"completeRequest() cannot be called twice.");i.done=!0;for(;e.length>0&&e[0].done;){const t=e.shift();setTimeout(t.callback,0)}},callback:t};e.push(i);return i}get _loadTestFont(){return shadow(this,"_loadTestFont",atob("T1RUTwALAIAAAwAwQ0ZGIDHtZg4AAAOYAAAAgUZGVE1lkzZwAAAEHAAAABxHREVGABQAFQAABDgAAAAeT1MvMlYNYwkAAAEgAAAAYGNtYXABDQLUAAACNAAAAUJoZWFk/xVFDQAAALwAAAA2aGhlYQdkA+oAAAD0AAAAJGhtdHgD6AAAAAAEWAAAAAZtYXhwAAJQAAAAARgAAAAGbmFtZVjmdH4AAAGAAAAAsXBvc3T/hgAzAAADeAAAACAAAQAAAAEAALZRFsRfDzz1AAsD6AAAAADOBOTLAAAAAM4KHDwAAAAAA+gDIQAAAAgAAgAAAAAAAAABAAADIQAAAFoD6AAAAAAD6AABAAAAAAAAAAAAAAAAAAAAAQAAUAAAAgAAAAQD6AH0AAUAAAKKArwAAACMAooCvAAAAeAAMQECAAACAAYJAAAAAAAAAAAAAQAAAAAAAAAAAAAAAFBmRWQAwAAuAC4DIP84AFoDIQAAAAAAAQAAAAAAAAAAACAAIAABAAAADgCuAAEAAAAAAAAAAQAAAAEAAAAAAAEAAQAAAAEAAAAAAAIAAQAAAAEAAAAAAAMAAQAAAAEAAAAAAAQAAQAAAAEAAAAAAAUAAQAAAAEAAAAAAAYAAQAAAAMAAQQJAAAAAgABAAMAAQQJAAEAAgABAAMAAQQJAAIAAgABAAMAAQQJAAMAAgABAAMAAQQJAAQAAgABAAMAAQQJAAUAAgABAAMAAQQJAAYAAgABWABYAAAAAAAAAwAAAAMAAAAcAAEAAAAAADwAAwABAAAAHAAEACAAAAAEAAQAAQAAAC7//wAAAC7////TAAEAAAAAAAABBgAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAD/gwAyAAAAAQAAAAAAAAAAAAAAAAAAAAABAAQEAAEBAQJYAAEBASH4DwD4GwHEAvgcA/gXBIwMAYuL+nz5tQXkD5j3CBLnEQACAQEBIVhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYAAABAQAADwACAQEEE/t3Dov6fAH6fAT+fPp8+nwHDosMCvm1Cvm1DAz6fBQAAAAAAAABAAAAAMmJbzEAAAAAzgTjFQAAAADOBOQpAAEAAAAAAAAADAAUAAQAAAABAAAAAgABAAAAAAAAAAAD6AAAAAAAAA=="))}_prepareFontLoadEvent(t,e){function int32(t,e){return t.charCodeAt(e)<<24|t.charCodeAt(e+1)<<16|t.charCodeAt(e+2)<<8|255&t.charCodeAt(e+3)}function spliceString(t,e,i,s){return t.substring(0,e)+s+t.substring(e+i)}let i,s;const n=this._document.createElement("canvas");n.width=1;n.height=1;const a=n.getContext("2d");let r=0;const o=`lt${Date.now()}${this.loadTestFontId++}`;let h=this._loadTestFont;h=spliceString(h,976,o.length,o);const l=1482184792;let d=int32(h,16);for(i=0,s=o.length-3;i<s;i+=4)d=d-l+int32(o,i)|0;i<o.length&&(d=d-l+int32(o+"XXX",i)|0);h=spliceString(h,16,4,function string32(t){return String.fromCharCode(t>>24&255,t>>16&255,t>>8&255,255&t)}(d));const c=`@font-face {font-family:"${o}";src:${`url(data:font/opentype;base64,${btoa(h)});`}}`;this.insertRule(c);const u=this._document.createElement("div");u.style.visibility="hidden";u.style.width=u.style.height="10px";u.style.position="absolute";u.style.top=u.style.left="0px";for(const e of[t.loadedName,o]){const t=this._document.createElement("span");t.textContent="Hi";t.style.fontFamily=e;u.append(t)}this._document.body.append(u);!function isFontReady(t,e){if(++r>30){warn("Load test font never loaded.");e();return}a.font="30px "+t;a.fillText(".",0,20);a.getImageData(0,0,1,1).data[3]>0?e():setTimeout(isFontReady.bind(null,t,e))}(o,(()=>{u.remove();e.complete()}))}}class FontFaceObject{constructor(t,{disableFontFace:e=!1,inspectFont:i=null}){this.compiledGlyphs=Object.create(null);for(const e in t)this[e]=t[e];this.disableFontFace=!0===e;this._inspectFont=i}createNativeFontFace(){if(!this.data||this.disableFontFace)return null;let t;if(this.cssFontInfo){const e={weight:this.cssFontInfo.fontWeight};this.cssFontInfo.italicAngle&&(e.style=`oblique ${this.cssFontInfo.italicAngle}deg`);t=new FontFace(this.cssFontInfo.fontFamily,this.data,e)}else t=new FontFace(this.loadedName,this.data,{});this._inspectFont?.(this);return t}createFontFaceRule(){if(!this.data||this.disableFontFace)return null;const t=bytesToString(this.data),e=`url(data:${this.mimetype};base64,${btoa(t)});`;let i;if(this.cssFontInfo){let t=`font-weight: ${this.cssFontInfo.fontWeight};`;this.cssFontInfo.italicAngle&&(t+=`font-style: oblique ${this.cssFontInfo.italicAngle}deg;`);i=`@font-face {font-family:"${this.cssFontInfo.fontFamily}";${t}src:${e}}`}else i=`@font-face {font-family:"${this.loadedName}";src:${e}}`;this._inspectFont?.(this,e);return i}getPathGenerator(t,e){if(void 0!==this.compiledGlyphs[e])return this.compiledGlyphs[e];let i;try{i=t.get(this.loadedName+"_path_"+e)}catch(t){warn(`getPathGenerator - ignoring character: "${t}".`)}if(!Array.isArray(i)||0===i.length)return this.compiledGlyphs[e]=function(t,e){};const s=[];for(let t=0,e=i.length;t<e;)switch(i[t++]){case it:{const[e,n,a,r,o,h]=i.slice(t,t+6);s.push((t=>t.bezierCurveTo(e,n,a,r,o,h)));t+=6}break;case st:{const[e,n]=i.slice(t,t+2);s.push((t=>t.moveTo(e,n)));t+=2}break;case nt:{const[e,n]=i.slice(t,t+2);s.push((t=>t.lineTo(e,n)));t+=2}break;case at:{const[e,n,a,r]=i.slice(t,t+4);s.push((t=>t.quadraticCurveTo(e,n,a,r)));t+=4}break;case rt:s.push((t=>t.restore()));break;case ot:s.push((t=>t.save()));break;case ht:assert(2===s.length,"Scale command is only valid at the third position.");break;case lt:{const[e,n,a,r,o,h]=i.slice(t,t+6);s.push((t=>t.transform(e,n,a,r,o,h)));t+=6}break;case dt:{const[e,n]=i.slice(t,t+2);s.push((t=>t.translate(e,n)));t+=2}}return this.compiledGlyphs[e]=function glyphDrawer(t,e){s[0](t);s[1](t);t.scale(e,-e);for(let e=2,i=s.length;e<i;e++)s[e](t)}}}if(e){var bt=Promise.withResolvers(),vt=null;(async()=>{const t=await import("fs"),e=await import("http"),i=await import("https"),s=await import("url");return new Map(Object.entries({fs:t,http:e,https:i,url:s,canvas:undefined,path2d:undefined}))})().then((t=>{vt=t;bt.resolve()}),(t=>{warn(`loadPackages: ${t}`);vt=new Map;bt.resolve()}))}class NodePackages{static get promise(){return bt.promise}static get(t){return vt?.get(t)}}const node_utils_fetchData=function(t){return NodePackages.get("fs").promises.readFile(t).then((t=>new Uint8Array(t)))};const At="Fill",yt="Stroke",wt="Shading";function applyBoundingBox(t,e){if(!e)return;const i=e[2]-e[0],s=e[3]-e[1],n=new Path2D;n.rect(e[0],e[1],i,s);t.clip(n)}class BaseShadingPattern{constructor(){this.constructor===BaseShadingPattern&&unreachable("Cannot initialize BaseShadingPattern.")}getPattern(){unreachable("Abstract method `getPattern` called.")}}class RadialAxialShadingPattern extends BaseShadingPattern{constructor(t){super();this._type=t[1];this._bbox=t[2];this._colorStops=t[3];this._p0=t[4];this._p1=t[5];this._r0=t[6];this._r1=t[7];this.matrix=null}_createGradient(t){let e;"axial"===this._type?e=t.createLinearGradient(this._p0[0],this._p0[1],this._p1[0],this._p1[1]):"radial"===this._type&&(e=t.createRadialGradient(this._p0[0],this._p0[1],this._r0,this._p1[0],this._p1[1],this._r1));for(const t of this._colorStops)e.addColorStop(t[0],t[1]);return e}getPattern(t,e,i,s){let n;if(s===yt||s===At){const a=e.current.getClippedPathBoundingBox(s,getCurrentTransform(t))||[0,0,0,0],r=Math.ceil(a[2]-a[0])||1,o=Math.ceil(a[3]-a[1])||1,h=e.cachedCanvases.getCanvas("pattern",r,o,!0),l=h.context;l.clearRect(0,0,l.canvas.width,l.canvas.height);l.beginPath();l.rect(0,0,l.canvas.width,l.canvas.height);l.translate(-a[0],-a[1]);i=Util.transform(i,[1,0,0,1,a[0],a[1]]);l.transform(...e.baseTransform);this.matrix&&l.transform(...this.matrix);applyBoundingBox(l,this._bbox);l.fillStyle=this._createGradient(l);l.fill();n=t.createPattern(h.canvas,"no-repeat");const d=new DOMMatrix(i);n.setTransform(d)}else{applyBoundingBox(t,this._bbox);n=this._createGradient(t)}return n}}function drawTriangle(t,e,i,s,n,a,r,o){const h=e.coords,l=e.colors,d=t.data,c=4*t.width;let u;if(h[i+1]>h[s+1]){u=i;i=s;s=u;u=a;a=r;r=u}if(h[s+1]>h[n+1]){u=s;s=n;n=u;u=r;r=o;o=u}if(h[i+1]>h[s+1]){u=i;i=s;s=u;u=a;a=r;r=u}const p=(h[i]+e.offsetX)*e.scaleX,g=(h[i+1]+e.offsetY)*e.scaleY,m=(h[s]+e.offsetX)*e.scaleX,f=(h[s+1]+e.offsetY)*e.scaleY,b=(h[n]+e.offsetX)*e.scaleX,v=(h[n+1]+e.offsetY)*e.scaleY;if(g>=v)return;const A=l[a],y=l[a+1],w=l[a+2],x=l[r],E=l[r+1],_=l[r+2],C=l[o],S=l[o+1],T=l[o+2],M=Math.round(g),k=Math.round(v);let P,D,R,F,I,L,O,N;for(let t=M;t<=k;t++){if(t<f){const e=t<g?0:(g-t)/(g-f);P=p-(p-m)*e;D=A-(A-x)*e;R=y-(y-E)*e;F=w-(w-_)*e}else{let e;e=t>v?1:f===v?0:(f-t)/(f-v);P=m-(m-b)*e;D=x-(x-C)*e;R=E-(E-S)*e;F=_-(_-T)*e}let e;e=t<g?0:t>v?1:(g-t)/(g-v);I=p-(p-b)*e;L=A-(A-C)*e;O=y-(y-S)*e;N=w-(w-T)*e;const i=Math.round(Math.min(P,I)),s=Math.round(Math.max(P,I));let n=c*t+4*i;for(let t=i;t<=s;t++){e=(P-t)/(P-I);e<0?e=0:e>1&&(e=1);d[n++]=D-(D-L)*e|0;d[n++]=R-(R-O)*e|0;d[n++]=F-(F-N)*e|0;d[n++]=255}}}function drawFigure(t,e,i){const s=e.coords,n=e.colors;let a,r;switch(e.type){case"lattice":const o=e.verticesPerRow,h=Math.floor(s.length/o)-1,l=o-1;for(a=0;a<h;a++){let e=a*o;for(let a=0;a<l;a++,e++){drawTriangle(t,i,s[e],s[e+1],s[e+o],n[e],n[e+1],n[e+o]);drawTriangle(t,i,s[e+o+1],s[e+1],s[e+o],n[e+o+1],n[e+1],n[e+o])}}break;case"triangles":for(a=0,r=s.length;a<r;a+=3)drawTriangle(t,i,s[a],s[a+1],s[a+2],n[a],n[a+1],n[a+2]);break;default:throw new Error("illegal figure")}}class MeshShadingPattern extends BaseShadingPattern{constructor(t){super();this._coords=t[2];this._colors=t[3];this._figures=t[4];this._bounds=t[5];this._bbox=t[7];this._background=t[8];this.matrix=null}_createMeshCanvas(t,e,i){const s=Math.floor(this._bounds[0]),n=Math.floor(this._bounds[1]),a=Math.ceil(this._bounds[2])-s,r=Math.ceil(this._bounds[3])-n,o=Math.min(Math.ceil(Math.abs(a*t[0]*1.1)),3e3),h=Math.min(Math.ceil(Math.abs(r*t[1]*1.1)),3e3),l=a/o,d=r/h,c={coords:this._coords,colors:this._colors,offsetX:-s,offsetY:-n,scaleX:1/l,scaleY:1/d},u=o+4,p=h+4,g=i.getCanvas("mesh",u,p,!1),m=g.context,f=m.createImageData(o,h);if(e){const t=f.data;for(let i=0,s=t.length;i<s;i+=4){t[i]=e[0];t[i+1]=e[1];t[i+2]=e[2];t[i+3]=255}}for(const t of this._figures)drawFigure(f,t,c);m.putImageData(f,2,2);return{canvas:g.canvas,offsetX:s-2*l,offsetY:n-2*d,scaleX:l,scaleY:d}}getPattern(t,e,i,s){applyBoundingBox(t,this._bbox);let n;if(s===wt)n=Util.singularValueDecompose2dScale(getCurrentTransform(t));else{n=Util.singularValueDecompose2dScale(e.baseTransform);if(this.matrix){const t=Util.singularValueDecompose2dScale(this.matrix);n=[n[0]*t[0],n[1]*t[1]]}}const a=this._createMeshCanvas(n,s===wt?null:this._background,e.cachedCanvases);if(s!==wt){t.setTransform(...e.baseTransform);this.matrix&&t.transform(...this.matrix)}t.translate(a.offsetX,a.offsetY);t.scale(a.scaleX,a.scaleY);return t.createPattern(a.canvas,"no-repeat")}}class DummyShadingPattern extends BaseShadingPattern{getPattern(){return"hotpink"}}const xt=1,Et=2;class TilingPattern{static MAX_PATTERN_SIZE=3e3;constructor(t,e,i,s,n){this.operatorList=t[2];this.matrix=t[3];this.bbox=t[4];this.xstep=t[5];this.ystep=t[6];this.paintType=t[7];this.tilingType=t[8];this.color=e;this.ctx=i;this.canvasGraphicsFactory=s;this.baseTransform=n}createPatternCanvas(t){const e=this.operatorList,i=this.bbox,s=this.xstep,n=this.ystep,a=this.paintType,r=this.tilingType,o=this.color,h=this.canvasGraphicsFactory;info("TilingType: "+r);const l=i[0],d=i[1],c=i[2],u=i[3],p=Util.singularValueDecompose2dScale(this.matrix),g=Util.singularValueDecompose2dScale(this.baseTransform),m=[p[0]*g[0],p[1]*g[1]],f=this.getSizeAndScale(s,this.ctx.canvas.width,m[0]),b=this.getSizeAndScale(n,this.ctx.canvas.height,m[1]),v=t.cachedCanvases.getCanvas("pattern",f.size,b.size,!0),A=v.context,y=h.createCanvasGraphics(A);y.groupLevel=t.groupLevel;this.setFillAndStrokeStyleToContext(y,a,o);let w=l,x=d,E=c,_=u;if(l<0){w=0;E+=Math.abs(l)}if(d<0){x=0;_+=Math.abs(d)}A.translate(-f.scale*w,-b.scale*x);y.transform(f.scale,0,0,b.scale,0,0);A.save();this.clipBbox(y,w,x,E,_);y.baseTransform=getCurrentTransform(y.ctx);y.executeOperatorList(e);y.endDrawing();return{canvas:v.canvas,scaleX:f.scale,scaleY:b.scale,offsetX:w,offsetY:x}}getSizeAndScale(t,e,i){t=Math.abs(t);const s=Math.max(TilingPattern.MAX_PATTERN_SIZE,e);let n=Math.ceil(t*i);n>=s?n=s:i=n/t;return{scale:i,size:n}}clipBbox(t,e,i,s,n){const a=s-e,r=n-i;t.ctx.rect(e,i,a,r);t.current.updateRectMinMax(getCurrentTransform(t.ctx),[e,i,s,n]);t.clip();t.endPath()}setFillAndStrokeStyleToContext(t,e,i){const s=t.ctx,n=t.current;switch(e){case xt:const t=this.ctx;s.fillStyle=t.fillStyle;s.strokeStyle=t.strokeStyle;n.fillColor=t.fillStyle;n.strokeColor=t.strokeStyle;break;case Et:const a=Util.makeHexColor(i[0],i[1],i[2]);s.fillStyle=a;s.strokeStyle=a;n.fillColor=a;n.strokeColor=a;break;default:throw new FormatError(`Unsupported paint type: ${e}`)}}getPattern(t,e,i,s){let n=i;if(s!==wt){n=Util.transform(n,e.baseTransform);this.matrix&&(n=Util.transform(n,this.matrix))}const a=this.createPatternCanvas(e);let r=new DOMMatrix(n);r=r.translate(a.offsetX,a.offsetY);r=r.scale(1/a.scaleX,1/a.scaleY);const o=t.createPattern(a.canvas,"repeat");o.setTransform(r);return o}}function convertBlackAndWhiteToRGBA({src:t,srcPos:e=0,dest:i,width:s,height:n,nonBlackColor:a=4294967295,inverseDecode:r=!1}){const o=util_FeatureTest.isLittleEndian?4278190080:255,[h,l]=r?[a,o]:[o,a],d=s>>3,c=7&s,u=t.length;i=new Uint32Array(i.buffer);let p=0;for(let s=0;s<n;s++){for(const s=e+d;e<s;e++){const s=e<u?t[e]:255;i[p++]=128&s?l:h;i[p++]=64&s?l:h;i[p++]=32&s?l:h;i[p++]=16&s?l:h;i[p++]=8&s?l:h;i[p++]=4&s?l:h;i[p++]=2&s?l:h;i[p++]=1&s?l:h}if(0===c)continue;const s=e<u?t[e++]:255;for(let t=0;t<c;t++)i[p++]=s&1<<7-t?l:h}return{srcPos:e,destPos:p}}const _t=16;class CachedCanvases{constructor(t){this.canvasFactory=t;this.cache=Object.create(null)}getCanvas(t,e,i){let s;if(void 0!==this.cache[t]){s=this.cache[t];this.canvasFactory.reset(s,e,i)}else{s=this.canvasFactory.create(e,i);this.cache[t]=s}return s}delete(t){delete this.cache[t]}clear(){for(const t in this.cache){const e=this.cache[t];this.canvasFactory.destroy(e);delete this.cache[t]}}}function drawImageAtIntegerCoords(t,e,i,s,n,a,r,o,h,l){const[d,c,u,p,g,m]=getCurrentTransform(t);if(0===c&&0===u){const f=r*d+g,b=Math.round(f),v=o*p+m,A=Math.round(v),y=(r+h)*d+g,w=Math.abs(Math.round(y)-b)||1,x=(o+l)*p+m,E=Math.abs(Math.round(x)-A)||1;t.setTransform(Math.sign(d),0,0,Math.sign(p),b,A);t.drawImage(e,i,s,n,a,0,0,w,E);t.setTransform(d,c,u,p,g,m);return[w,E]}if(0===d&&0===p){const f=o*u+g,b=Math.round(f),v=r*c+m,A=Math.round(v),y=(o+l)*u+g,w=Math.abs(Math.round(y)-b)||1,x=(r+h)*c+m,E=Math.abs(Math.round(x)-A)||1;t.setTransform(0,Math.sign(c),Math.sign(u),0,b,A);t.drawImage(e,i,s,n,a,0,0,E,w);t.setTransform(d,c,u,p,g,m);return[E,w]}t.drawImage(e,i,s,n,a,r,o,h,l);return[Math.hypot(d,c)*h,Math.hypot(u,p)*l]}class CanvasExtraState{constructor(t,e){this.alphaIsShape=!1;this.fontSize=0;this.fontSizeScale=1;this.textMatrix=i;this.textMatrixScale=1;this.fontMatrix=s;this.leading=0;this.x=0;this.y=0;this.lineX=0;this.lineY=0;this.charSpacing=0;this.wordSpacing=0;this.textHScale=1;this.textRenderingMode=f;this.textRise=0;this.fillColor="#000000";this.strokeColor="#000000";this.patternFill=!1;this.fillAlpha=1;this.strokeAlpha=1;this.lineWidth=1;this.activeSMask=null;this.transferMaps="none";this.startNewPathAndClipBox([0,0,t,e])}clone(){const t=Object.create(this);t.clipBox=this.clipBox.slice();return t}setCurrentPoint(t,e){this.x=t;this.y=e}updatePathMinMax(t,e,i){[e,i]=Util.applyTransform([e,i],t);this.minX=Math.min(this.minX,e);this.minY=Math.min(this.minY,i);this.maxX=Math.max(this.maxX,e);this.maxY=Math.max(this.maxY,i)}updateRectMinMax(t,e){const i=Util.applyTransform(e,t),s=Util.applyTransform(e.slice(2),t),n=Util.applyTransform([e[0],e[3]],t),a=Util.applyTransform([e[2],e[1]],t);this.minX=Math.min(this.minX,i[0],s[0],n[0],a[0]);this.minY=Math.min(this.minY,i[1],s[1],n[1],a[1]);this.maxX=Math.max(this.maxX,i[0],s[0],n[0],a[0]);this.maxY=Math.max(this.maxY,i[1],s[1],n[1],a[1])}updateScalingPathMinMax(t,e){Util.scaleMinMax(t,e);this.minX=Math.min(this.minX,e[0]);this.minY=Math.min(this.minY,e[1]);this.maxX=Math.max(this.maxX,e[2]);this.maxY=Math.max(this.maxY,e[3])}updateCurvePathMinMax(t,e,i,s,n,a,r,o,h,l){const d=Util.bezierBoundingBox(e,i,s,n,a,r,o,h,l);l||this.updateRectMinMax(t,d)}getPathBoundingBox(t=At,e=null){const i=[this.minX,this.minY,this.maxX,this.maxY];if(t===yt){e||unreachable("Stroke bounding box must include transform.");const t=Util.singularValueDecompose2dScale(e),s=t[0]*this.lineWidth/2,n=t[1]*this.lineWidth/2;i[0]-=s;i[1]-=n;i[2]+=s;i[3]+=n}return i}updateClipFromPath(){const t=Util.intersect(this.clipBox,this.getPathBoundingBox());this.startNewPathAndClipBox(t||[0,0,0,0])}isEmptyClip(){return this.minX===1/0}startNewPathAndClipBox(t){this.clipBox=t;this.minX=1/0;this.minY=1/0;this.maxX=0;this.maxY=0}getClippedPathBoundingBox(t=At,e=null){return Util.intersect(this.clipBox,this.getPathBoundingBox(t,e))}}function putBinaryImageData(t,e){if("undefined"!=typeof ImageData&&e instanceof ImageData){t.putImageData(e,0,0);return}const i=e.height,s=e.width,n=i%_t,a=(i-n)/_t,r=0===n?a:a+1,o=t.createImageData(s,_t);let h,l=0;const d=e.data,c=o.data;let u,p,g,m;if(e.kind===x.GRAYSCALE_1BPP){const e=d.byteLength,i=new Uint32Array(c.buffer,0,c.byteLength>>2),m=i.length,f=s+7>>3,b=4294967295,v=util_FeatureTest.isLittleEndian?4278190080:255;for(u=0;u<r;u++){g=u<a?_t:n;h=0;for(p=0;p<g;p++){const t=e-l;let n=0;const a=t>f?s:8*t-7,r=-8&a;let o=0,c=0;for(;n<r;n+=8){c=d[l++];i[h++]=128&c?b:v;i[h++]=64&c?b:v;i[h++]=32&c?b:v;i[h++]=16&c?b:v;i[h++]=8&c?b:v;i[h++]=4&c?b:v;i[h++]=2&c?b:v;i[h++]=1&c?b:v}for(;n<a;n++){if(0===o){c=d[l++];o=128}i[h++]=c&o?b:v;o>>=1}}for(;h<m;)i[h++]=0;t.putImageData(o,0,u*_t)}}else if(e.kind===x.RGBA_32BPP){p=0;m=s*_t*4;for(u=0;u<a;u++){c.set(d.subarray(l,l+m));l+=m;t.putImageData(o,0,p);p+=_t}if(u<r){m=s*n*4;c.set(d.subarray(l,l+m));t.putImageData(o,0,p)}}else{if(e.kind!==x.RGB_24BPP)throw new Error(`bad image kind: ${e.kind}`);g=_t;m=s*g;for(u=0;u<r;u++){if(u>=a){g=n;m=s*g}h=0;for(p=m;p--;){c[h++]=d[l++];c[h++]=d[l++];c[h++]=d[l++];c[h++]=255}t.putImageData(o,0,u*_t)}}}function putBinaryImageMask(t,e){if(e.bitmap){t.drawImage(e.bitmap,0,0);return}const i=e.height,s=e.width,n=i%_t,a=(i-n)/_t,r=0===n?a:a+1,o=t.createImageData(s,_t);let h=0;const l=e.data,d=o.data;for(let e=0;e<r;e++){const i=e<a?_t:n;({srcPos:h}=convertBlackAndWhiteToRGBA({src:l,srcPos:h,dest:d,width:s,height:i,nonBlackColor:0}));t.putImageData(o,0,e*_t)}}function copyCtxState(t,e){const i=["strokeStyle","fillStyle","fillRule","globalAlpha","lineWidth","lineCap","lineJoin","miterLimit","globalCompositeOperation","font","filter"];for(const s of i)void 0!==t[s]&&(e[s]=t[s]);if(void 0!==t.setLineDash){e.setLineDash(t.getLineDash());e.lineDashOffset=t.lineDashOffset}}function resetCtxToDefault(t){t.strokeStyle=t.fillStyle="#000000";t.fillRule="nonzero";t.globalAlpha=1;t.lineWidth=1;t.lineCap="butt";t.lineJoin="miter";t.miterLimit=10;t.globalCompositeOperation="source-over";t.font="10px sans-serif";if(void 0!==t.setLineDash){t.setLineDash([]);t.lineDashOffset=0}if(!e){const{filter:e}=t;"none"!==e&&""!==e&&(t.filter="none")}}function getImageSmoothingEnabled(t,e){if(e)return!0;const i=Util.singularValueDecompose2dScale(t);i[0]=Math.fround(i[0]);i[1]=Math.fround(i[1]);const s=Math.fround((globalThis.devicePixelRatio||1)*PixelsPerInch.PDF_TO_CSS_UNITS);return i[0]<=s&&i[1]<=s}const Ct=["butt","round","square"],St=["miter","round","bevel"],Tt={},Mt={};class CanvasGraphics{constructor(t,e,i,s,n,{optionalContentConfig:a,markedContentStack:r=null},o,h){this.ctx=t;this.current=new CanvasExtraState(this.ctx.canvas.width,this.ctx.canvas.height);this.stateStack=[];this.pendingClip=null;this.pendingEOFill=!1;this.res=null;this.xobjs=null;this.commonObjs=e;this.objs=i;this.canvasFactory=s;this.filterFactory=n;this.groupStack=[];this.processingType3=null;this.baseTransform=null;this.baseTransformStack=[];this.groupLevel=0;this.smaskStack=[];this.smaskCounter=0;this.tempSMask=null;this.suspendedCtx=null;this.contentVisible=!0;this.markedContentStack=r||[];this.optionalContentConfig=a;this.cachedCanvases=new CachedCanvases(this.canvasFactory);this.cachedPatterns=new Map;this.annotationCanvasMap=o;this.viewportScale=1;this.outputScaleX=1;this.outputScaleY=1;this.pageColors=h;this._cachedScaleForStroking=[-1,0];this._cachedGetSinglePixelWidth=null;this._cachedBitmapsMap=new Map}getObject(t,e=null){return"string"==typeof t?t.startsWith("g_")?this.commonObjs.get(t):this.objs.get(t):e}beginDrawing({transform:t,viewport:e,transparency:i=!1,background:s=null}){const n=this.ctx.canvas.width,a=this.ctx.canvas.height,r=this.ctx.fillStyle;this.ctx.fillStyle=s||"#ffffff";this.ctx.fillRect(0,0,n,a);this.ctx.fillStyle=r;if(i){const t=this.cachedCanvases.getCanvas("transparent",n,a);this.compositeCtx=this.ctx;this.transparentCanvas=t.canvas;this.ctx=t.context;this.ctx.save();this.ctx.transform(...getCurrentTransform(this.compositeCtx))}this.ctx.save();resetCtxToDefault(this.ctx);if(t){this.ctx.transform(...t);this.outputScaleX=t[0];this.outputScaleY=t[0]}this.ctx.transform(...e.transform);this.viewportScale=e.scale;this.baseTransform=getCurrentTransform(this.ctx)}executeOperatorList(t,e,i,s){const n=t.argsArray,a=t.fnArray;let r=e||0;const o=n.length;if(o===r)return r;const h=o-r>10&&"function"==typeof i,l=h?Date.now()+15:0;let d=0;const c=this.commonObjs,u=this.objs;let p;for(;;){if(void 0!==s&&r===s.nextBreakPoint){s.breakIt(r,i);return r}p=a[r];if(p!==X.dependency)this[p].apply(this,n[r]);else for(const t of n[r]){const e=t.startsWith("g_")?c:u;if(!e.has(t)){e.get(t,i);return r}}r++;if(r===o)return r;if(h&&++d>10){if(Date.now()>l){i();return r}d=0}}}#ke(){for(;this.stateStack.length||this.inSMaskMode;)this.restore();this.ctx.restore();if(this.transparentCanvas){this.ctx=this.compositeCtx;this.ctx.save();this.ctx.setTransform(1,0,0,1,0,0);this.ctx.drawImage(this.transparentCanvas,0,0);this.ctx.restore();this.transparentCanvas=null}}endDrawing(){this.#ke();this.cachedCanvases.clear();this.cachedPatterns.clear();for(const t of this._cachedBitmapsMap.values()){for(const e of t.values())"undefined"!=typeof HTMLCanvasElement&&e instanceof HTMLCanvasElement&&(e.width=e.height=0);t.clear()}this._cachedBitmapsMap.clear();this.#Pe()}#Pe(){if(this.pageColors){const t=this.filterFactory.addHCMFilter(this.pageColors.foreground,this.pageColors.background);if("none"!==t){const e=this.ctx.filter;this.ctx.filter=t;this.ctx.drawImage(this.ctx.canvas,0,0);this.ctx.filter=e}}}_scaleImage(t,e){const i=t.width,s=t.height;let n,a,r=Math.max(Math.hypot(e[0],e[1]),1),o=Math.max(Math.hypot(e[2],e[3]),1),h=i,l=s,d="prescale1";for(;r>2&&h>1||o>2&&l>1;){let e=h,i=l;if(r>2&&h>1){e=h>=16384?Math.floor(h/2)-1||1:Math.ceil(h/2);r/=h/e}if(o>2&&l>1){i=l>=16384?Math.floor(l/2)-1||1:Math.ceil(l)/2;o/=l/i}n=this.cachedCanvases.getCanvas(d,e,i);a=n.context;a.clearRect(0,0,e,i);a.drawImage(t,0,0,h,l,0,0,e,i);t=n.canvas;h=e;l=i;d="prescale1"===d?"prescale2":"prescale1"}return{img:t,paintWidth:h,paintHeight:l}}_createMaskCanvas(t){const e=this.ctx,{width:i,height:s}=t,n=this.current.fillColor,a=this.current.patternFill,r=getCurrentTransform(e);let o,h,l,d;if((t.bitmap||t.data)&&t.count>1){const e=t.bitmap||t.data.buffer;h=JSON.stringify(a?r:[r.slice(0,4),n]);o=this._cachedBitmapsMap.get(e);if(!o){o=new Map;this._cachedBitmapsMap.set(e,o)}const i=o.get(h);if(i&&!a){return{canvas:i,offsetX:Math.round(Math.min(r[0],r[2])+r[4]),offsetY:Math.round(Math.min(r[1],r[3])+r[5])}}l=i}if(!l){d=this.cachedCanvases.getCanvas("maskCanvas",i,s);putBinaryImageMask(d.context,t)}let c=Util.transform(r,[1/i,0,0,-1/s,0,0]);c=Util.transform(c,[1,0,0,1,0,-s]);const[u,p,g,m]=Util.getAxialAlignedBoundingBox([0,0,i,s],c),f=Math.round(g-u)||1,b=Math.round(m-p)||1,v=this.cachedCanvases.getCanvas("fillCanvas",f,b),A=v.context,y=u,w=p;A.translate(-y,-w);A.transform(...c);if(!l){l=this._scaleImage(d.canvas,getCurrentTransformInverse(A));l=l.img;o&&a&&o.set(h,l)}A.imageSmoothingEnabled=getImageSmoothingEnabled(getCurrentTransform(A),t.interpolate);drawImageAtIntegerCoords(A,l,0,0,l.width,l.height,0,0,i,s);A.globalCompositeOperation="source-in";const x=Util.transform(getCurrentTransformInverse(A),[1,0,0,1,-y,-w]);A.fillStyle=a?n.getPattern(e,this,x,At):n;A.fillRect(0,0,i,s);if(o&&!a){this.cachedCanvases.delete("fillCanvas");o.set(h,v.canvas)}return{canvas:v.canvas,offsetX:Math.round(y),offsetY:Math.round(w)}}setLineWidth(t){t!==this.current.lineWidth&&(this._cachedScaleForStroking[0]=-1);this.current.lineWidth=t;this.ctx.lineWidth=t}setLineCap(t){this.ctx.lineCap=Ct[t]}setLineJoin(t){this.ctx.lineJoin=St[t]}setMiterLimit(t){this.ctx.miterLimit=t}setDash(t,e){const i=this.ctx;if(void 0!==i.setLineDash){i.setLineDash(t);i.lineDashOffset=e}}setRenderingIntent(t){}setFlatness(t){}setGState(t){for(const[e,i]of t)switch(e){case"LW":this.setLineWidth(i);break;case"LC":this.setLineCap(i);break;case"LJ":this.setLineJoin(i);break;case"ML":this.setMiterLimit(i);break;case"D":this.setDash(i[0],i[1]);break;case"RI":this.setRenderingIntent(i);break;case"FL":this.setFlatness(i);break;case"Font":this.setFont(i[0],i[1]);break;case"CA":this.current.strokeAlpha=i;break;case"ca":this.current.fillAlpha=i;this.ctx.globalAlpha=i;break;case"BM":this.ctx.globalCompositeOperation=i;break;case"SMask":this.current.activeSMask=i?this.tempSMask:null;this.tempSMask=null;this.checkSMaskState();break;case"TR":this.ctx.filter=this.current.transferMaps=this.filterFactory.addFilter(i)}}get inSMaskMode(){return!!this.suspendedCtx}checkSMaskState(){const t=this.inSMaskMode;this.current.activeSMask&&!t?this.beginSMaskMode():!this.current.activeSMask&&t&&this.endSMaskMode()}beginSMaskMode(){if(this.inSMaskMode)throw new Error("beginSMaskMode called while already in smask mode");const t=this.ctx.canvas.width,e=this.ctx.canvas.height,i="smaskGroupAt"+this.groupLevel,s=this.cachedCanvases.getCanvas(i,t,e);this.suspendedCtx=this.ctx;this.ctx=s.context;const n=this.ctx;n.setTransform(...getCurrentTransform(this.suspendedCtx));copyCtxState(this.suspendedCtx,n);!function mirrorContextOperations(t,e){if(t._removeMirroring)throw new Error("Context is already forwarding operations.");t.__originalSave=t.save;t.__originalRestore=t.restore;t.__originalRotate=t.rotate;t.__originalScale=t.scale;t.__originalTranslate=t.translate;t.__originalTransform=t.transform;t.__originalSetTransform=t.setTransform;t.__originalResetTransform=t.resetTransform;t.__originalClip=t.clip;t.__originalMoveTo=t.moveTo;t.__originalLineTo=t.lineTo;t.__originalBezierCurveTo=t.bezierCurveTo;t.__originalRect=t.rect;t.__originalClosePath=t.closePath;t.__originalBeginPath=t.beginPath;t._removeMirroring=()=>{t.save=t.__originalSave;t.restore=t.__originalRestore;t.rotate=t.__originalRotate;t.scale=t.__originalScale;t.translate=t.__originalTranslate;t.transform=t.__originalTransform;t.setTransform=t.__originalSetTransform;t.resetTransform=t.__originalResetTransform;t.clip=t.__originalClip;t.moveTo=t.__originalMoveTo;t.lineTo=t.__originalLineTo;t.bezierCurveTo=t.__originalBezierCurveTo;t.rect=t.__originalRect;t.closePath=t.__originalClosePath;t.beginPath=t.__originalBeginPath;delete t._removeMirroring};t.save=function ctxSave(){e.save();this.__originalSave()};t.restore=function ctxRestore(){e.restore();this.__originalRestore()};t.translate=function ctxTranslate(t,i){e.translate(t,i);this.__originalTranslate(t,i)};t.scale=function ctxScale(t,i){e.scale(t,i);this.__originalScale(t,i)};t.transform=function ctxTransform(t,i,s,n,a,r){e.transform(t,i,s,n,a,r);this.__originalTransform(t,i,s,n,a,r)};t.setTransform=function ctxSetTransform(t,i,s,n,a,r){e.setTransform(t,i,s,n,a,r);this.__originalSetTransform(t,i,s,n,a,r)};t.resetTransform=function ctxResetTransform(){e.resetTransform();this.__originalResetTransform()};t.rotate=function ctxRotate(t){e.rotate(t);this.__originalRotate(t)};t.clip=function ctxRotate(t){e.clip(t);this.__originalClip(t)};t.moveTo=function(t,i){e.moveTo(t,i);this.__originalMoveTo(t,i)};t.lineTo=function(t,i){e.lineTo(t,i);this.__originalLineTo(t,i)};t.bezierCurveTo=function(t,i,s,n,a,r){e.bezierCurveTo(t,i,s,n,a,r);this.__originalBezierCurveTo(t,i,s,n,a,r)};t.rect=function(t,i,s,n){e.rect(t,i,s,n);this.__originalRect(t,i,s,n)};t.closePath=function(){e.closePath();this.__originalClosePath()};t.beginPath=function(){e.beginPath();this.__originalBeginPath()}}(n,this.suspendedCtx);this.setGState([["BM","source-over"],["ca",1],["CA",1]])}endSMaskMode(){if(!this.inSMaskMode)throw new Error("endSMaskMode called while not in smask mode");this.ctx._removeMirroring();copyCtxState(this.ctx,this.suspendedCtx);this.ctx=this.suspendedCtx;this.suspendedCtx=null}compose(t){if(!this.current.activeSMask)return;if(t){t[0]=Math.floor(t[0]);t[1]=Math.floor(t[1]);t[2]=Math.ceil(t[2]);t[3]=Math.ceil(t[3])}else t=[0,0,this.ctx.canvas.width,this.ctx.canvas.height];const e=this.current.activeSMask,i=this.suspendedCtx;this.composeSMask(i,e,this.ctx,t);this.ctx.save();this.ctx.setTransform(1,0,0,1,0,0);this.ctx.clearRect(0,0,this.ctx.canvas.width,this.ctx.canvas.height);this.ctx.restore()}composeSMask(t,e,i,s){const n=s[0],a=s[1],r=s[2]-n,o=s[3]-a;if(0!==r&&0!==o){this.genericComposeSMask(e.context,i,r,o,e.subtype,e.backdrop,e.transferMap,n,a,e.offsetX,e.offsetY);t.save();t.globalAlpha=1;t.globalCompositeOperation="source-over";t.setTransform(1,0,0,1,0,0);t.drawImage(i.canvas,0,0);t.restore()}}genericComposeSMask(t,e,i,s,n,a,r,o,h,l,d){let c=t.canvas,u=o-l,p=h-d;if(a)if(u<0||p<0||u+i>c.width||p+s>c.height){const t=this.cachedCanvases.getCanvas("maskExtension",i,s),e=t.context;e.drawImage(c,-u,-p);if(a.some((t=>0!==t))){e.globalCompositeOperation="destination-atop";e.fillStyle=Util.makeHexColor(...a);e.fillRect(0,0,i,s);e.globalCompositeOperation="source-over"}c=t.canvas;u=p=0}else if(a.some((t=>0!==t))){t.save();t.globalAlpha=1;t.setTransform(1,0,0,1,0,0);const e=new Path2D;e.rect(u,p,i,s);t.clip(e);t.globalCompositeOperation="destination-atop";t.fillStyle=Util.makeHexColor(...a);t.fillRect(u,p,i,s);t.restore()}e.save();e.globalAlpha=1;e.setTransform(1,0,0,1,0,0);"Alpha"===n&&r?e.filter=this.filterFactory.addAlphaFilter(r):"Luminosity"===n&&(e.filter=this.filterFactory.addLuminosityFilter(r));const g=new Path2D;g.rect(o,h,i,s);e.clip(g);e.globalCompositeOperation="destination-in";e.drawImage(c,u,p,i,s,o,h,i,s);e.restore()}save(){if(this.inSMaskMode){copyCtxState(this.ctx,this.suspendedCtx);this.suspendedCtx.save()}else this.ctx.save();const t=this.current;this.stateStack.push(t);this.current=t.clone()}restore(){0===this.stateStack.length&&this.inSMaskMode&&this.endSMaskMode();if(0!==this.stateStack.length){this.current=this.stateStack.pop();if(this.inSMaskMode){this.suspendedCtx.restore();copyCtxState(this.suspendedCtx,this.ctx)}else this.ctx.restore();this.checkSMaskState();this.pendingClip=null;this._cachedScaleForStroking[0]=-1;this._cachedGetSinglePixelWidth=null}}transform(t,e,i,s,n,a){this.ctx.transform(t,e,i,s,n,a);this._cachedScaleForStroking[0]=-1;this._cachedGetSinglePixelWidth=null}constructPath(t,e,i){const s=this.ctx,n=this.current;let a,r,o=n.x,h=n.y;const l=getCurrentTransform(s),d=0===l[0]&&0===l[3]||0===l[1]&&0===l[2],c=d?i.slice(0):null;for(let i=0,u=0,p=t.length;i<p;i++)switch(0|t[i]){case X.rectangle:o=e[u++];h=e[u++];const t=e[u++],i=e[u++],p=o+t,g=h+i;s.moveTo(o,h);if(0===t||0===i)s.lineTo(p,g);else{s.lineTo(p,h);s.lineTo(p,g);s.lineTo(o,g)}d||n.updateRectMinMax(l,[o,h,p,g]);s.closePath();break;case X.moveTo:o=e[u++];h=e[u++];s.moveTo(o,h);d||n.updatePathMinMax(l,o,h);break;case X.lineTo:o=e[u++];h=e[u++];s.lineTo(o,h);d||n.updatePathMinMax(l,o,h);break;case X.curveTo:a=o;r=h;o=e[u+4];h=e[u+5];s.bezierCurveTo(e[u],e[u+1],e[u+2],e[u+3],o,h);n.updateCurvePathMinMax(l,a,r,e[u],e[u+1],e[u+2],e[u+3],o,h,c);u+=6;break;case X.curveTo2:a=o;r=h;s.bezierCurveTo(o,h,e[u],e[u+1],e[u+2],e[u+3]);n.updateCurvePathMinMax(l,a,r,o,h,e[u],e[u+1],e[u+2],e[u+3],c);o=e[u+2];h=e[u+3];u+=4;break;case X.curveTo3:a=o;r=h;o=e[u+2];h=e[u+3];s.bezierCurveTo(e[u],e[u+1],o,h,o,h);n.updateCurvePathMinMax(l,a,r,e[u],e[u+1],o,h,o,h,c);u+=4;break;case X.closePath:s.closePath()}d&&n.updateScalingPathMinMax(l,c);n.setCurrentPoint(o,h)}closePath(){this.ctx.closePath()}stroke(t=!0){const e=this.ctx,i=this.current.strokeColor;e.globalAlpha=this.current.strokeAlpha;if(this.contentVisible)if("object"==typeof i&&i?.getPattern){e.save();e.strokeStyle=i.getPattern(e,this,getCurrentTransformInverse(e),yt);this.rescaleAndStroke(!1);e.restore()}else this.rescaleAndStroke(!0);t&&this.consumePath(this.current.getClippedPathBoundingBox());e.globalAlpha=this.current.fillAlpha}closeStroke(){this.closePath();this.stroke()}fill(t=!0){const e=this.ctx,i=this.current.fillColor;let s=!1;if(this.current.patternFill){e.save();e.fillStyle=i.getPattern(e,this,getCurrentTransformInverse(e),At);s=!0}const n=this.current.getClippedPathBoundingBox();if(this.contentVisible&&null!==n)if(this.pendingEOFill){e.fill("evenodd");this.pendingEOFill=!1}else e.fill();s&&e.restore();t&&this.consumePath(n)}eoFill(){this.pendingEOFill=!0;this.fill()}fillStroke(){this.fill(!1);this.stroke(!1);this.consumePath()}eoFillStroke(){this.pendingEOFill=!0;this.fillStroke()}closeFillStroke(){this.closePath();this.fillStroke()}closeEOFillStroke(){this.pendingEOFill=!0;this.closePath();this.fillStroke()}endPath(){this.consumePath()}clip(){this.pendingClip=Tt}eoClip(){this.pendingClip=Mt}beginText(){this.current.textMatrix=i;this.current.textMatrixScale=1;this.current.x=this.current.lineX=0;this.current.y=this.current.lineY=0}endText(){const t=this.pendingTextPaths,e=this.ctx;if(void 0!==t){e.save();e.beginPath();for(const i of t){e.setTransform(...i.transform);e.translate(i.x,i.y);i.addToPath(e,i.fontSize)}e.restore();e.clip();e.beginPath();delete this.pendingTextPaths}else e.beginPath()}setCharSpacing(t){this.current.charSpacing=t}setWordSpacing(t){this.current.wordSpacing=t}setHScale(t){this.current.textHScale=t/100}setLeading(t){this.current.leading=-t}setFont(t,e){const i=this.commonObjs.get(t),n=this.current;if(!i)throw new Error(`Can't find font for ${t}`);n.fontMatrix=i.fontMatrix||s;0!==n.fontMatrix[0]&&0!==n.fontMatrix[3]||warn("Invalid font matrix for font "+t);if(e<0){e=-e;n.fontDirection=-1}else n.fontDirection=1;this.current.font=i;this.current.fontSize=e;if(i.isType3Font)return;const a=i.loadedName||"sans-serif",r=i.systemFontInfo?.css||`"${a}", ${i.fallbackName}`;let o="normal";i.black?o="900":i.bold&&(o="bold");const h=i.italic?"italic":"normal";let l=e;e<16?l=16:e>100&&(l=100);this.current.fontSizeScale=e/l;this.ctx.font=`${h} ${o} ${l}px ${r}`}setTextRenderingMode(t){this.current.textRenderingMode=t}setTextRise(t){this.current.textRise=t}moveText(t,e){this.current.x=this.current.lineX+=t;this.current.y=this.current.lineY+=e}setLeadingMoveText(t,e){this.setLeading(-e);this.moveText(t,e)}setTextMatrix(t,e,i,s,n,a){this.current.textMatrix=[t,e,i,s,n,a];this.current.textMatrixScale=Math.hypot(t,e);this.current.x=this.current.lineX=0;this.current.y=this.current.lineY=0}nextLine(){this.moveText(0,this.current.leading)}paintChar(t,e,i,s){const n=this.ctx,a=this.current,r=a.font,o=a.textRenderingMode,h=a.fontSize/a.fontSizeScale,l=o&y,d=!!(o&w),c=a.patternFill&&!r.missingFile;let u;(r.disableFontFace||d||c)&&(u=r.getPathGenerator(this.commonObjs,t));if(r.disableFontFace||c){n.save();n.translate(e,i);n.beginPath();u(n,h);s&&n.setTransform(...s);l!==f&&l!==v||n.fill();l!==b&&l!==v||n.stroke();n.restore()}else{l!==f&&l!==v||n.fillText(t,e,i);l!==b&&l!==v||n.strokeText(t,e,i)}if(d){(this.pendingTextPaths||=[]).push({transform:getCurrentTransform(n),x:e,y:i,fontSize:h,addToPath:u})}}get isFontSubpixelAAEnabled(){const{context:t}=this.cachedCanvases.getCanvas("isFontSubpixelAAEnabled",10,10);t.scale(1.5,1);t.fillText("I",0,10);const e=t.getImageData(0,0,10,10).data;let i=!1;for(let t=3;t<e.length;t+=4)if(e[t]>0&&e[t]<255){i=!0;break}return shadow(this,"isFontSubpixelAAEnabled",i)}showText(t){const e=this.current,i=e.font;if(i.isType3Font)return this.showType3Text(t);const s=e.fontSize;if(0===s)return;const n=this.ctx,a=e.fontSizeScale,r=e.charSpacing,o=e.wordSpacing,h=e.fontDirection,l=e.textHScale*h,d=t.length,c=i.vertical,u=c?1:-1,p=i.defaultVMetrics,g=s*e.fontMatrix[0],m=e.textRenderingMode===f&&!i.disableFontFace&&!e.patternFill;n.save();n.transform(...e.textMatrix);n.translate(e.x,e.y+e.textRise);h>0?n.scale(l,-1):n.scale(l,1);let A;if(e.patternFill){n.save();const t=e.fillColor.getPattern(n,this,getCurrentTransformInverse(n),At);A=getCurrentTransform(n);n.restore();n.fillStyle=t}let w=e.lineWidth;const x=e.textMatrixScale;if(0===x||0===w){const t=e.textRenderingMode&y;t!==b&&t!==v||(w=this.getSinglePixelWidth())}else w/=x;if(1!==a){n.scale(a,a);w/=a}n.lineWidth=w;if(i.isInvalidPDFjsFont){const i=[];let s=0;for(const e of t){i.push(e.unicode);s+=e.width}n.fillText(i.join(""),0,0);e.x+=s*g*l;n.restore();this.compose();return}let E,_=0;for(E=0;E<d;++E){const e=t[E];if("number"==typeof e){_+=u*e*s/1e3;continue}let l=!1;const d=(e.isSpace?o:0)+r,f=e.fontChar,b=e.accent;let v,y,w=e.width;if(c){const t=e.vmetric||p,i=-(e.vmetric?t[1]:.5*w)*g,s=t[2]*g;w=t?-t[0]:w;v=i/a;y=(_+s)/a}else{v=_/a;y=0}if(i.remeasure&&w>0){const t=1e3*n.measureText(f).width/s*a;if(w<t&&this.isFontSubpixelAAEnabled){const e=w/t;l=!0;n.save();n.scale(e,1);v/=e}else w!==t&&(v+=(w-t)/2e3*s/a)}if(this.contentVisible&&(e.isInFont||i.missingFile))if(m&&!b)n.fillText(f,v,y);else{this.paintChar(f,v,y,A);if(b){const t=v+s*b.offset.x/a,e=y-s*b.offset.y/a;this.paintChar(b.fontChar,t,e,A)}}_+=c?w*g-d*h:w*g+d*h;l&&n.restore()}c?e.y-=_:e.x+=_*l;n.restore();this.compose()}showType3Text(t){const e=this.ctx,i=this.current,n=i.font,a=i.fontSize,r=i.fontDirection,o=n.vertical?1:-1,h=i.charSpacing,l=i.wordSpacing,d=i.textHScale*r,c=i.fontMatrix||s,u=t.length;let p,g,m,f;if(!(i.textRenderingMode===A)&&0!==a){this._cachedScaleForStroking[0]=-1;this._cachedGetSinglePixelWidth=null;e.save();e.transform(...i.textMatrix);e.translate(i.x,i.y);e.scale(d,r);for(p=0;p<u;++p){g=t[p];if("number"==typeof g){f=o*g*a/1e3;this.ctx.translate(f,0);i.x+=f*d;continue}const s=(g.isSpace?l:0)+h,r=n.charProcOperatorList[g.operatorListId];if(!r){warn(`Type3 character "${g.operatorListId}" is not available.`);continue}if(this.contentVisible){this.processingType3=g;this.save();e.scale(a,a);e.transform(...c);this.executeOperatorList(r);this.restore()}m=Util.applyTransform([g.width,0],c)[0]*a+s;e.translate(m,0);i.x+=m*d}e.restore();this.processingType3=null}}setCharWidth(t,e){}setCharWidthAndBounds(t,e,i,s,n,a){this.ctx.rect(i,s,n-i,a-s);this.ctx.clip();this.endPath()}getColorN_Pattern(t){let e;if("TilingPattern"===t[0]){const i=t[1],s=this.baseTransform||getCurrentTransform(this.ctx),n={createCanvasGraphics:t=>new CanvasGraphics(t,this.commonObjs,this.objs,this.canvasFactory,this.filterFactory,{optionalContentConfig:this.optionalContentConfig,markedContentStack:this.markedContentStack})};e=new TilingPattern(t,i,this.ctx,n,s)}else e=this._getPattern(t[1],t[2]);return e}setStrokeColorN(){this.current.strokeColor=this.getColorN_Pattern(arguments)}setFillColorN(){this.current.fillColor=this.getColorN_Pattern(arguments);this.current.patternFill=!0}setStrokeRGBColor(t,e,i){const s=Util.makeHexColor(t,e,i);this.ctx.strokeStyle=s;this.current.strokeColor=s}setFillRGBColor(t,e,i){const s=Util.makeHexColor(t,e,i);this.ctx.fillStyle=s;this.current.fillColor=s;this.current.patternFill=!1}_getPattern(t,e=null){let i;if(this.cachedPatterns.has(t))i=this.cachedPatterns.get(t);else{i=function getShadingPattern(t){switch(t[0]){case"RadialAxial":return new RadialAxialShadingPattern(t);case"Mesh":return new MeshShadingPattern(t);case"Dummy":return new DummyShadingPattern}throw new Error(`Unknown IR type: ${t[0]}`)}(this.getObject(t));this.cachedPatterns.set(t,i)}e&&(i.matrix=e);return i}shadingFill(t){if(!this.contentVisible)return;const e=this.ctx;this.save();const i=this._getPattern(t);e.fillStyle=i.getPattern(e,this,getCurrentTransformInverse(e),wt);const s=getCurrentTransformInverse(e);if(s){const{width:t,height:i}=e.canvas,[n,a,r,o]=Util.getAxialAlignedBoundingBox([0,0,t,i],s);this.ctx.fillRect(n,a,r-n,o-a)}else this.ctx.fillRect(-1e10,-1e10,2e10,2e10);this.compose(this.current.getClippedPathBoundingBox());this.restore()}beginInlineImage(){unreachable("Should not call beginInlineImage")}beginImageData(){unreachable("Should not call beginImageData")}paintFormXObjectBegin(t,e){if(this.contentVisible){this.save();this.baseTransformStack.push(this.baseTransform);t&&this.transform(...t);this.baseTransform=getCurrentTransform(this.ctx);if(e){const t=e[2]-e[0],i=e[3]-e[1];this.ctx.rect(e[0],e[1],t,i);this.current.updateRectMinMax(getCurrentTransform(this.ctx),e);this.clip();this.endPath()}}}paintFormXObjectEnd(){if(this.contentVisible){this.restore();this.baseTransform=this.baseTransformStack.pop()}}beginGroup(t){if(!this.contentVisible)return;this.save();if(this.inSMaskMode){this.endSMaskMode();this.current.activeSMask=null}const e=this.ctx;t.isolated||info("TODO: Support non-isolated groups.");t.knockout&&warn("Knockout groups not supported.");const i=getCurrentTransform(e);t.matrix&&e.transform(...t.matrix);if(!t.bbox)throw new Error("Bounding box is required.");let s=Util.getAxialAlignedBoundingBox(t.bbox,getCurrentTransform(e));const n=[0,0,e.canvas.width,e.canvas.height];s=Util.intersect(s,n)||[0,0,0,0];const a=Math.floor(s[0]),r=Math.floor(s[1]),o=Math.max(Math.ceil(s[2])-a,1),h=Math.max(Math.ceil(s[3])-r,1);this.current.startNewPathAndClipBox([0,0,o,h]);let l="groupAt"+this.groupLevel;t.smask&&(l+="_smask_"+this.smaskCounter++%2);const d=this.cachedCanvases.getCanvas(l,o,h),c=d.context;c.translate(-a,-r);c.transform(...i);if(t.smask)this.smaskStack.push({canvas:d.canvas,context:c,offsetX:a,offsetY:r,subtype:t.smask.subtype,backdrop:t.smask.backdrop,transferMap:t.smask.transferMap||null,startTransformInverse:null});else{e.setTransform(1,0,0,1,0,0);e.translate(a,r);e.save()}copyCtxState(e,c);this.ctx=c;this.setGState([["BM","source-over"],["ca",1],["CA",1]]);this.groupStack.push(e);this.groupLevel++}endGroup(t){if(!this.contentVisible)return;this.groupLevel--;const e=this.ctx,i=this.groupStack.pop();this.ctx=i;this.ctx.imageSmoothingEnabled=!1;if(t.smask){this.tempSMask=this.smaskStack.pop();this.restore()}else{this.ctx.restore();const t=getCurrentTransform(this.ctx);this.restore();this.ctx.save();this.ctx.setTransform(...t);const i=Util.getAxialAlignedBoundingBox([0,0,e.canvas.width,e.canvas.height],t);this.ctx.drawImage(e.canvas,0,0);this.ctx.restore();this.compose(i)}}beginAnnotation(t,e,i,s,n){this.#ke();resetCtxToDefault(this.ctx);this.ctx.save();this.save();this.baseTransform&&this.ctx.setTransform(...this.baseTransform);if(e){const s=e[2]-e[0],a=e[3]-e[1];if(n&&this.annotationCanvasMap){(i=i.slice())[4]-=e[0];i[5]-=e[1];(e=e.slice())[0]=e[1]=0;e[2]=s;e[3]=a;const[n,r]=Util.singularValueDecompose2dScale(getCurrentTransform(this.ctx)),{viewportScale:o}=this,h=Math.ceil(s*this.outputScaleX*o),l=Math.ceil(a*this.outputScaleY*o);this.annotationCanvas=this.canvasFactory.create(h,l);const{canvas:d,context:c}=this.annotationCanvas;this.annotationCanvasMap.set(t,d);this.annotationCanvas.savedCtx=this.ctx;this.ctx=c;this.ctx.save();this.ctx.setTransform(n,0,0,-r,0,a*r);resetCtxToDefault(this.ctx)}else{resetCtxToDefault(this.ctx);this.ctx.rect(e[0],e[1],s,a);this.ctx.clip();this.endPath()}}this.current=new CanvasExtraState(this.ctx.canvas.width,this.ctx.canvas.height);this.transform(...i);this.transform(...s)}endAnnotation(){if(this.annotationCanvas){this.ctx.restore();this.#Pe();this.ctx=this.annotationCanvas.savedCtx;delete this.annotationCanvas.savedCtx;delete this.annotationCanvas}}paintImageMaskXObject(t){if(!this.contentVisible)return;const e=t.count;(t=this.getObject(t.data,t)).count=e;const i=this.ctx,s=this.processingType3;if(s){void 0===s.compiled&&(s.compiled=function compileType3Glyph(t){const{width:e,height:i}=t;if(e>1e3||i>1e3)return null;const s=new Uint8Array([0,2,4,0,1,0,5,4,8,10,0,8,0,2,1,0]),n=e+1;let a,r,o,h=new Uint8Array(n*(i+1));const l=e+7&-8;let d=new Uint8Array(l*i),c=0;for(const e of t.data){let t=128;for(;t>0;){d[c++]=e&t?0:255;t>>=1}}let u=0;c=0;if(0!==d[c]){h[0]=1;++u}for(r=1;r<e;r++){if(d[c]!==d[c+1]){h[r]=d[c]?2:1;++u}c++}if(0!==d[c]){h[r]=2;++u}for(a=1;a<i;a++){c=a*l;o=a*n;if(d[c-l]!==d[c]){h[o]=d[c]?1:8;++u}let t=(d[c]?4:0)+(d[c-l]?8:0);for(r=1;r<e;r++){t=(t>>2)+(d[c+1]?4:0)+(d[c-l+1]?8:0);if(s[t]){h[o+r]=s[t];++u}c++}if(d[c-l]!==d[c]){h[o+r]=d[c]?2:4;++u}if(u>1e3)return null}c=l*(i-1);o=a*n;if(0!==d[c]){h[o]=8;++u}for(r=1;r<e;r++){if(d[c]!==d[c+1]){h[o+r]=d[c]?4:8;++u}c++}if(0!==d[c]){h[o+r]=4;++u}if(u>1e3)return null;const p=new Int32Array([0,n,-1,0,-n,0,0,0,1]),g=new Path2D;for(a=0;u&&a<=i;a++){let t=a*n;const i=t+e;for(;t<i&&!h[t];)t++;if(t===i)continue;g.moveTo(t%n,a);const s=t;let r=h[t];do{const e=p[r];do{t+=e}while(!h[t]);const i=h[t];if(5!==i&&10!==i){r=i;h[t]=0}else{r=i&51*r>>4;h[t]&=r>>2|r<<2}g.lineTo(t%n,t/n|0);h[t]||--u}while(s!==t);--a}d=null;h=null;return function(t){t.save();t.scale(1/e,-1/i);t.translate(0,-i);t.fill(g);t.beginPath();t.restore()}}(t));if(s.compiled){s.compiled(i);return}}const n=this._createMaskCanvas(t),a=n.canvas;i.save();i.setTransform(1,0,0,1,0,0);i.drawImage(a,n.offsetX,n.offsetY);i.restore();this.compose()}paintImageMaskXObjectRepeat(t,e,i=0,s=0,n,a){if(!this.contentVisible)return;t=this.getObject(t.data,t);const r=this.ctx;r.save();const o=getCurrentTransform(r);r.transform(e,i,s,n,0,0);const h=this._createMaskCanvas(t);r.setTransform(1,0,0,1,h.offsetX-o[4],h.offsetY-o[5]);for(let t=0,l=a.length;t<l;t+=2){const l=Util.transform(o,[e,i,s,n,a[t],a[t+1]]),[d,c]=Util.applyTransform([0,0],l);r.drawImage(h.canvas,d,c)}r.restore();this.compose()}paintImageMaskXObjectGroup(t){if(!this.contentVisible)return;const e=this.ctx,i=this.current.fillColor,s=this.current.patternFill;for(const n of t){const{data:t,width:a,height:r,transform:o}=n,h=this.cachedCanvases.getCanvas("maskCanvas",a,r),l=h.context;l.save();putBinaryImageMask(l,this.getObject(t,n));l.globalCompositeOperation="source-in";l.fillStyle=s?i.getPattern(l,this,getCurrentTransformInverse(e),At):i;l.fillRect(0,0,a,r);l.restore();e.save();e.transform(...o);e.scale(1,-1);drawImageAtIntegerCoords(e,h.canvas,0,0,a,r,0,-1,1,1);e.restore()}this.compose()}paintImageXObject(t){if(!this.contentVisible)return;const e=this.getObject(t);e?this.paintInlineImageXObject(e):warn("Dependent image isn't ready yet")}paintImageXObjectRepeat(t,e,i,s){if(!this.contentVisible)return;const n=this.getObject(t);if(!n){warn("Dependent image isn't ready yet");return}const a=n.width,r=n.height,o=[];for(let t=0,n=s.length;t<n;t+=2)o.push({transform:[e,0,0,i,s[t],s[t+1]],x:0,y:0,w:a,h:r});this.paintInlineImageXObjectGroup(n,o)}applyTransferMapsToCanvas(t){if("none"!==this.current.transferMaps){t.filter=this.current.transferMaps;t.drawImage(t.canvas,0,0);t.filter="none"}return t.canvas}applyTransferMapsToBitmap(t){if("none"===this.current.transferMaps)return t.bitmap;const{bitmap:e,width:i,height:s}=t,n=this.cachedCanvases.getCanvas("inlineImage",i,s),a=n.context;a.filter=this.current.transferMaps;a.drawImage(e,0,0);a.filter="none";return n.canvas}paintInlineImageXObject(t){if(!this.contentVisible)return;const i=t.width,s=t.height,n=this.ctx;this.save();if(!e){const{filter:t}=n;"none"!==t&&""!==t&&(n.filter="none")}n.scale(1/i,-1/s);let a;if(t.bitmap)a=this.applyTransferMapsToBitmap(t);else if("function"==typeof HTMLElement&&t instanceof HTMLElement||!t.data)a=t;else{const e=this.cachedCanvases.getCanvas("inlineImage",i,s).context;putBinaryImageData(e,t);a=this.applyTransferMapsToCanvas(e)}const r=this._scaleImage(a,getCurrentTransformInverse(n));n.imageSmoothingEnabled=getImageSmoothingEnabled(getCurrentTransform(n),t.interpolate);drawImageAtIntegerCoords(n,r.img,0,0,r.paintWidth,r.paintHeight,0,-s,i,s);this.compose();this.restore()}paintInlineImageXObjectGroup(t,e){if(!this.contentVisible)return;const i=this.ctx;let s;if(t.bitmap)s=t.bitmap;else{const e=t.width,i=t.height,n=this.cachedCanvases.getCanvas("inlineImage",e,i).context;putBinaryImageData(n,t);s=this.applyTransferMapsToCanvas(n)}for(const t of e){i.save();i.transform(...t.transform);i.scale(1,-1);drawImageAtIntegerCoords(i,s,t.x,t.y,t.w,t.h,0,-1,1,1);i.restore()}this.compose()}paintSolidColorImageMask(){if(this.contentVisible){this.ctx.fillRect(0,0,1,1);this.compose()}}markPoint(t){}markPointProps(t,e){}beginMarkedContent(t){this.markedContentStack.push({visible:!0})}beginMarkedContentProps(t,e){"OC"===t?this.markedContentStack.push({visible:this.optionalContentConfig.isVisible(e)}):this.markedContentStack.push({visible:!0});this.contentVisible=this.isContentVisible()}endMarkedContent(){this.markedContentStack.pop();this.contentVisible=this.isContentVisible()}beginCompat(){}endCompat(){}consumePath(t){const e=this.current.isEmptyClip();this.pendingClip&&this.current.updateClipFromPath();this.pendingClip||this.compose(t);const i=this.ctx;if(this.pendingClip){e||(this.pendingClip===Mt?i.clip("evenodd"):i.clip());this.pendingClip=null}this.current.startNewPathAndClipBox(this.current.clipBox);i.beginPath()}getSinglePixelWidth(){if(!this._cachedGetSinglePixelWidth){const t=getCurrentTransform(this.ctx);if(0===t[1]&&0===t[2])this._cachedGetSinglePixelWidth=1/Math.min(Math.abs(t[0]),Math.abs(t[3]));else{const e=Math.abs(t[0]*t[3]-t[2]*t[1]),i=Math.hypot(t[0],t[2]),s=Math.hypot(t[1],t[3]);this._cachedGetSinglePixelWidth=Math.max(i,s)/e}}return this._cachedGetSinglePixelWidth}getScaleForStroking(){if(-1===this._cachedScaleForStroking[0]){const{lineWidth:t}=this.current,{a:e,b:i,c:s,d:n}=this.ctx.getTransform();let a,r;if(0===i&&0===s){const i=Math.abs(e),s=Math.abs(n);if(i===s)if(0===t)a=r=1/i;else{const e=i*t;a=r=e<1?1/e:1}else if(0===t){a=1/i;r=1/s}else{const e=i*t,n=s*t;a=e<1?1/e:1;r=n<1?1/n:1}}else{const o=Math.abs(e*n-i*s),h=Math.hypot(e,i),l=Math.hypot(s,n);if(0===t){a=l/o;r=h/o}else{const e=t*o;a=l>e?l/e:1;r=h>e?h/e:1}}this._cachedScaleForStroking[0]=a;this._cachedScaleForStroking[1]=r}return this._cachedScaleForStroking}rescaleAndStroke(t){const{ctx:e}=this,{lineWidth:i}=this.current,[s,n]=this.getScaleForStroking();e.lineWidth=i||1;if(1===s&&1===n){e.stroke();return}const a=e.getLineDash();t&&e.save();e.scale(s,n);if(a.length>0){const t=Math.max(s,n);e.setLineDash(a.map((e=>e/t)));e.lineDashOffset/=t}e.stroke();t&&e.restore()}isContentVisible(){for(let t=this.markedContentStack.length-1;t>=0;t--)if(!this.markedContentStack[t].visible)return!1;return!0}}for(const t in X)void 0!==CanvasGraphics.prototype[t]&&(CanvasGraphics.prototype[X[t]]=CanvasGraphics.prototype[t]);class GlobalWorkerOptions{static#De=null;static#Re="";static get workerPort(){return this.#De}static set workerPort(t){if(!("undefined"!=typeof Worker&&t instanceof Worker)&&null!==t)throw new Error("Invalid `workerPort` type.");this.#De=t}static get workerSrc(){return this.#Re}static set workerSrc(t){if("string"!=typeof t)throw new Error("Invalid `workerSrc` type.");this.#Re=t}}const kt=1,Pt=2,Dt=1,Rt=2,Ft=3,It=4,Lt=5,Ot=6,Nt=7,Bt=8;function wrapReason(t){t instanceof Error||"object"==typeof t&&null!==t||unreachable('wrapReason: Expected "reason" to be a (possibly cloned) Error.');switch(t.name){case"AbortException":return new AbortException(t.message);case"MissingPDFException":return new MissingPDFException(t.message);case"PasswordException":return new PasswordException(t.message,t.code);case"UnexpectedResponseException":return new UnexpectedResponseException(t.message,t.status);case"UnknownErrorException":return new UnknownErrorException(t.message,t.details);default:return new UnknownErrorException(t.message,t.toString())}}class MessageHandler{constructor(t,e,i){this.sourceName=t;this.targetName=e;this.comObj=i;this.callbackId=1;this.streamId=1;this.streamSinks=Object.create(null);this.streamControllers=Object.create(null);this.callbackCapabilities=Object.create(null);this.actionHandler=Object.create(null);this._onComObjOnMessage=t=>{const e=t.data;if(e.targetName!==this.sourceName)return;if(e.stream){this.#Fe(e);return}if(e.callback){const t=e.callbackId,i=this.callbackCapabilities[t];if(!i)throw new Error(`Cannot resolve callback ${t}`);delete this.callbackCapabilities[t];if(e.callback===kt)i.resolve(e.data);else{if(e.callback!==Pt)throw new Error("Unexpected callback case");i.reject(wrapReason(e.reason))}return}const s=this.actionHandler[e.action];if(!s)throw new Error(`Unknown action from worker: ${e.action}`);if(e.callbackId){const t=this.sourceName,n=e.sourceName;new Promise((function(t){t(s(e.data))})).then((function(s){i.postMessage({sourceName:t,targetName:n,callback:kt,callbackId:e.callbackId,data:s})}),(function(s){i.postMessage({sourceName:t,targetName:n,callback:Pt,callbackId:e.callbackId,reason:wrapReason(s)})}))}else e.streamId?this.#Ie(e):s(e.data)};i.addEventListener("message",this._onComObjOnMessage)}on(t,e){const i=this.actionHandler;if(i[t])throw new Error(`There is already an actionName called "${t}"`);i[t]=e}send(t,e,i){this.comObj.postMessage({sourceName:this.sourceName,targetName:this.targetName,action:t,data:e},i)}sendWithPromise(t,e,i){const s=this.callbackId++,n=Promise.withResolvers();this.callbackCapabilities[s]=n;try{this.comObj.postMessage({sourceName:this.sourceName,targetName:this.targetName,action:t,callbackId:s,data:e},i)}catch(t){n.reject(t)}return n.promise}sendWithStream(t,e,i,s){const n=this.streamId++,a=this.sourceName,r=this.targetName,o=this.comObj;return new ReadableStream({start:i=>{const h=Promise.withResolvers();this.streamControllers[n]={controller:i,startCall:h,pullCall:null,cancelCall:null,isClosed:!1};o.postMessage({sourceName:a,targetName:r,action:t,streamId:n,data:e,desiredSize:i.desiredSize},s);return h.promise},pull:t=>{const e=Promise.withResolvers();this.streamControllers[n].pullCall=e;o.postMessage({sourceName:a,targetName:r,stream:Ot,streamId:n,desiredSize:t.desiredSize});return e.promise},cancel:t=>{assert(t instanceof Error,"cancel must have a valid reason");const e=Promise.withResolvers();this.streamControllers[n].cancelCall=e;this.streamControllers[n].isClosed=!0;o.postMessage({sourceName:a,targetName:r,stream:Dt,streamId:n,reason:wrapReason(t)});return e.promise}},i)}#Ie(t){const e=t.streamId,i=this.sourceName,s=t.sourceName,n=this.comObj,a=this,r=this.actionHandler[t.action],o={enqueue(t,a=1,r){if(this.isCancelled)return;const o=this.desiredSize;this.desiredSize-=a;if(o>0&&this.desiredSize<=0){this.sinkCapability=Promise.withResolvers();this.ready=this.sinkCapability.promise}n.postMessage({sourceName:i,targetName:s,stream:It,streamId:e,chunk:t},r)},close(){if(!this.isCancelled){this.isCancelled=!0;n.postMessage({sourceName:i,targetName:s,stream:Ft,streamId:e});delete a.streamSinks[e]}},error(t){assert(t instanceof Error,"error must have a valid reason");if(!this.isCancelled){this.isCancelled=!0;n.postMessage({sourceName:i,targetName:s,stream:Lt,streamId:e,reason:wrapReason(t)})}},sinkCapability:Promise.withResolvers(),onPull:null,onCancel:null,isCancelled:!1,desiredSize:t.desiredSize,ready:null};o.sinkCapability.resolve();o.ready=o.sinkCapability.promise;this.streamSinks[e]=o;new Promise((function(e){e(r(t.data,o))})).then((function(){n.postMessage({sourceName:i,targetName:s,stream:Bt,streamId:e,success:!0})}),(function(t){n.postMessage({sourceName:i,targetName:s,stream:Bt,streamId:e,reason:wrapReason(t)})}))}#Fe(t){const e=t.streamId,i=this.sourceName,s=t.sourceName,n=this.comObj,a=this.streamControllers[e],r=this.streamSinks[e];switch(t.stream){case Bt:t.success?a.startCall.resolve():a.startCall.reject(wrapReason(t.reason));break;case Nt:t.success?a.pullCall.resolve():a.pullCall.reject(wrapReason(t.reason));break;case Ot:if(!r){n.postMessage({sourceName:i,targetName:s,stream:Nt,streamId:e,success:!0});break}r.desiredSize<=0&&t.desiredSize>0&&r.sinkCapability.resolve();r.desiredSize=t.desiredSize;new Promise((function(t){t(r.onPull?.())})).then((function(){n.postMessage({sourceName:i,targetName:s,stream:Nt,streamId:e,success:!0})}),(function(t){n.postMessage({sourceName:i,targetName:s,stream:Nt,streamId:e,reason:wrapReason(t)})}));break;case It:assert(a,"enqueue should have stream controller");if(a.isClosed)break;a.controller.enqueue(t.chunk);break;case Ft:assert(a,"close should have stream controller");if(a.isClosed)break;a.isClosed=!0;a.controller.close();this.#Le(a,e);break;case Lt:assert(a,"error should have stream controller");a.controller.error(wrapReason(t.reason));this.#Le(a,e);break;case Rt:t.success?a.cancelCall.resolve():a.cancelCall.reject(wrapReason(t.reason));this.#Le(a,e);break;case Dt:if(!r)break;new Promise((function(e){e(r.onCancel?.(wrapReason(t.reason)))})).then((function(){n.postMessage({sourceName:i,targetName:s,stream:Rt,streamId:e,success:!0})}),(function(t){n.postMessage({sourceName:i,targetName:s,stream:Rt,streamId:e,reason:wrapReason(t)})}));r.sinkCapability.reject(wrapReason(t.reason));r.isCancelled=!0;delete this.streamSinks[e];break;default:throw new Error("Unexpected stream case")}}async#Le(t,e){await Promise.allSettled([t.startCall?.promise,t.pullCall?.promise,t.cancelCall?.promise]);delete this.streamControllers[e]}destroy(){this.comObj.removeEventListener("message",this._onComObjOnMessage)}}class Metadata{#Oe;#Ne;constructor({parsedData:t,rawData:e}){this.#Oe=t;this.#Ne=e}getRaw(){return this.#Ne}get(t){return this.#Oe.get(t)??null}getAll(){return objectFromMap(this.#Oe)}has(t){return this.#Oe.has(t)}}const Ht=Symbol("INTERNAL");class OptionalContentGroup{#Be=!1;#He=!1;#ze=!1;#Ue=!0;constructor(t,{name:e,intent:i,usage:s}){this.#Be=!!(t&r);this.#He=!!(t&o);this.name=e;this.intent=i;this.usage=s}get visible(){if(this.#ze)return this.#Ue;if(!this.#Ue)return!1;const{print:t,view:e}=this.usage;return this.#Be?"OFF"!==e?.viewState:!this.#He||"OFF"!==t?.printState}_setVisible(t,e,i=!1){t!==Ht&&unreachable("Internal method `_setVisible` called.");this.#ze=i;this.#Ue=e}}class OptionalContentConfig{#je=null;#$e=new Map;#Ve=null;#Ge=null;constructor(t,e=r){this.renderingIntent=e;this.name=null;this.creator=null;if(null!==t){this.name=t.name;this.creator=t.creator;this.#Ge=t.order;for(const i of t.groups)this.#$e.set(i.id,new OptionalContentGroup(e,i));if("OFF"===t.baseState)for(const t of this.#$e.values())t._setVisible(Ht,!1);for(const e of t.on)this.#$e.get(e)._setVisible(Ht,!0);for(const e of t.off)this.#$e.get(e)._setVisible(Ht,!1);this.#Ve=this.getHash()}}#We(t){const e=t.length;if(e<2)return!0;const i=t[0];for(let s=1;s<e;s++){const e=t[s];let n;if(Array.isArray(e))n=this.#We(e);else{if(!this.#$e.has(e)){warn(`Optional content group not found: ${e}`);return!0}n=this.#$e.get(e).visible}switch(i){case"And":if(!n)return!1;break;case"Or":if(n)return!0;break;case"Not":return!n;default:return!0}}return"And"===i}isVisible(t){if(0===this.#$e.size)return!0;if(!t){info("Optional content group not defined.");return!0}if("OCG"===t.type){if(!this.#$e.has(t.id)){warn(`Optional content group not found: ${t.id}`);return!0}return this.#$e.get(t.id).visible}if("OCMD"===t.type){if(t.expression)return this.#We(t.expression);if(!t.policy||"AnyOn"===t.policy){for(const e of t.ids){if(!this.#$e.has(e)){warn(`Optional content group not found: ${e}`);return!0}if(this.#$e.get(e).visible)return!0}return!1}if("AllOn"===t.policy){for(const e of t.ids){if(!this.#$e.has(e)){warn(`Optional content group not found: ${e}`);return!0}if(!this.#$e.get(e).visible)return!1}return!0}if("AnyOff"===t.policy){for(const e of t.ids){if(!this.#$e.has(e)){warn(`Optional content group not found: ${e}`);return!0}if(!this.#$e.get(e).visible)return!0}return!1}if("AllOff"===t.policy){for(const e of t.ids){if(!this.#$e.has(e)){warn(`Optional content group not found: ${e}`);return!0}if(this.#$e.get(e).visible)return!1}return!0}warn(`Unknown optional content policy ${t.policy}.`);return!0}warn(`Unknown group type ${t.type}.`);return!0}setVisibility(t,e=!0){const i=this.#$e.get(t);if(i){i._setVisible(Ht,!!e,!0);this.#je=null}else warn(`Optional content group not found: ${t}`)}setOCGState({state:t,preserveRB:e}){let i;for(const e of t){switch(e){case"ON":case"OFF":case"Toggle":i=e;continue}const t=this.#$e.get(e);if(t)switch(i){case"ON":t._setVisible(Ht,!0);break;case"OFF":t._setVisible(Ht,!1);break;case"Toggle":t._setVisible(Ht,!t.visible)}}this.#je=null}get hasInitialVisibility(){return null===this.#Ve||this.getHash()===this.#Ve}getOrder(){return this.#$e.size?this.#Ge?this.#Ge.slice():[...this.#$e.keys()]:null}getGroups(){return this.#$e.size>0?objectFromMap(this.#$e):null}getGroup(t){return this.#$e.get(t)||null}getHash(){if(null!==this.#je)return this.#je;const t=new MurmurHash3_64;for(const[e,i]of this.#$e)t.update(`${e}:${i.visible}`);return this.#je=t.hexdigest()}}class PDFDataTransportStream{constructor(t,{disableRange:e=!1,disableStream:i=!1}){assert(t,'PDFDataTransportStream - missing required "pdfDataRangeTransport" argument.');const{length:s,initialData:n,progressiveDone:a,contentDispositionFilename:r}=t;this._queuedChunks=[];this._progressiveDone=a;this._contentDispositionFilename=r;if(n?.length>0){const t=n instanceof Uint8Array&&n.byteLength===n.buffer.byteLength?n.buffer:new Uint8Array(n).buffer;this._queuedChunks.push(t)}this._pdfDataRangeTransport=t;this._isStreamingSupported=!i;this._isRangeSupported=!e;this._contentLength=s;this._fullRequestReader=null;this._rangeReaders=[];t.addRangeListener(((t,e)=>{this._onReceiveData({begin:t,chunk:e})}));t.addProgressListener(((t,e)=>{this._onProgress({loaded:t,total:e})}));t.addProgressiveReadListener((t=>{this._onReceiveData({chunk:t})}));t.addProgressiveDoneListener((()=>{this._onProgressiveDone()}));t.transportReady()}_onReceiveData({begin:t,chunk:e}){const i=e instanceof Uint8Array&&e.byteLength===e.buffer.byteLength?e.buffer:new Uint8Array(e).buffer;if(void 0===t)this._fullRequestReader?this._fullRequestReader._enqueue(i):this._queuedChunks.push(i);else{assert(this._rangeReaders.some((function(e){if(e._begin!==t)return!1;e._enqueue(i);return!0})),"_onReceiveData - no `PDFDataTransportStreamRangeReader` instance found.")}}get _progressiveDataLength(){return this._fullRequestReader?._loaded??0}_onProgress(t){void 0===t.total?this._rangeReaders[0]?.onProgress?.({loaded:t.loaded}):this._fullRequestReader?.onProgress?.({loaded:t.loaded,total:t.total})}_onProgressiveDone(){this._fullRequestReader?.progressiveDone();this._progressiveDone=!0}_removeRangeReader(t){const e=this._rangeReaders.indexOf(t);e>=0&&this._rangeReaders.splice(e,1)}getFullReader(){assert(!this._fullRequestReader,"PDFDataTransportStream.getFullReader can only be called once.");const t=this._queuedChunks;this._queuedChunks=null;return new PDFDataTransportStreamReader(this,t,this._progressiveDone,this._contentDispositionFilename)}getRangeReader(t,e){if(e<=this._progressiveDataLength)return null;const i=new PDFDataTransportStreamRangeReader(this,t,e);this._pdfDataRangeTransport.requestDataRange(t,e);this._rangeReaders.push(i);return i}cancelAllRequests(t){this._fullRequestReader?.cancel(t);for(const e of this._rangeReaders.slice(0))e.cancel(t);this._pdfDataRangeTransport.abort()}}class PDFDataTransportStreamReader{constructor(t,e,i=!1,s=null){this._stream=t;this._done=i||!1;this._filename=isPdfFile(s)?s:null;this._queuedChunks=e||[];this._loaded=0;for(const t of this._queuedChunks)this._loaded+=t.byteLength;this._requests=[];this._headersReady=Promise.resolve();t._fullRequestReader=this;this.onProgress=null}_enqueue(t){if(!this._done){if(this._requests.length>0){this._requests.shift().resolve({value:t,done:!1})}else this._queuedChunks.push(t);this._loaded+=t.byteLength}}get headersReady(){return this._headersReady}get filename(){return this._filename}get isRangeSupported(){return this._stream._isRangeSupported}get isStreamingSupported(){return this._stream._isStreamingSupported}get contentLength(){return this._stream._contentLength}async read(){if(this._queuedChunks.length>0){return{value:this._queuedChunks.shift(),done:!1}}if(this._done)return{value:void 0,done:!0};const t=Promise.withResolvers();this._requests.push(t);return t.promise}cancel(t){this._done=!0;for(const t of this._requests)t.resolve({value:void 0,done:!0});this._requests.length=0}progressiveDone(){this._done||(this._done=!0)}}class PDFDataTransportStreamRangeReader{constructor(t,e,i){this._stream=t;this._begin=e;this._end=i;this._queuedChunk=null;this._requests=[];this._done=!1;this.onProgress=null}_enqueue(t){if(!this._done){if(0===this._requests.length)this._queuedChunk=t;else{this._requests.shift().resolve({value:t,done:!1});for(const t of this._requests)t.resolve({value:void 0,done:!0});this._requests.length=0}this._done=!0;this._stream._removeRangeReader(this)}}get isStreamingSupported(){return!1}async read(){if(this._queuedChunk){const t=this._queuedChunk;this._queuedChunk=null;return{value:t,done:!1}}if(this._done)return{value:void 0,done:!0};const t=Promise.withResolvers();this._requests.push(t);return t.promise}cancel(t){this._done=!0;for(const t of this._requests)t.resolve({value:void 0,done:!0});this._requests.length=0;this._stream._removeRangeReader(this)}}function validateRangeRequestCapabilities({getResponseHeader:t,isHttp:e,rangeChunkSize:i,disableRange:s}){const n={allowRangeRequests:!1,suggestedLength:void 0},a=parseInt(t("Content-Length"),10);if(!Number.isInteger(a))return n;n.suggestedLength=a;if(a<=2*i)return n;if(s||!e)return n;if("bytes"!==t("Accept-Ranges"))return n;if("identity"!==(t("Content-Encoding")||"identity"))return n;n.allowRangeRequests=!0;return n}function extractFilenameFromHeader(t){const e=t("Content-Disposition");if(e){let t=function getFilenameFromContentDispositionHeader(t){let e=!0,i=toParamRegExp("filename\\*","i").exec(t);if(i){i=i[1];let t=rfc2616unquote(i);t=unescape(t);t=rfc5987decode(t);t=rfc2047decode(t);return fixupEncoding(t)}i=function rfc2231getparam(t){const e=[];let i;const s=toParamRegExp("filename\\*((?!0\\d)\\d+)(\\*?)","ig");for(;null!==(i=s.exec(t));){let[,t,s,n]=i;t=parseInt(t,10);if(t in e){if(0===t)break}else e[t]=[s,n]}const n=[];for(let t=0;t<e.length&&t in e;++t){let[i,s]=e[t];s=rfc2616unquote(s);if(i){s=unescape(s);0===t&&(s=rfc5987decode(s))}n.push(s)}return n.join("")}(t);if(i)return fixupEncoding(rfc2047decode(i));i=toParamRegExp("filename","i").exec(t);if(i){i=i[1];let t=rfc2616unquote(i);t=rfc2047decode(t);return fixupEncoding(t)}function toParamRegExp(t,e){return new RegExp("(?:^|;)\\s*"+t+'\\s*=\\s*([^";\\s][^;\\s]*|"(?:[^"\\\\]|\\\\"?)+"?)',e)}function textdecode(t,i){if(t){if(!/^[\x00-\xFF]+$/.test(i))return i;try{const s=new TextDecoder(t,{fatal:!0}),n=stringToBytes(i);i=s.decode(n);e=!1}catch{}}return i}function fixupEncoding(t){if(e&&/[\x80-\xff]/.test(t)){t=textdecode("utf-8",t);e&&(t=textdecode("iso-8859-1",t))}return t}function rfc2616unquote(t){if(t.startsWith('"')){const e=t.slice(1).split('\\"');for(let t=0;t<e.length;++t){const i=e[t].indexOf('"');if(-1!==i){e[t]=e[t].slice(0,i);e.length=t+1}e[t]=e[t].replaceAll(/\\(.)/g,"$1")}t=e.join('"')}return t}function rfc5987decode(t){const e=t.indexOf("'");return-1===e?t:textdecode(t.slice(0,e),t.slice(e+1).replace(/^[^']*'/,""))}function rfc2047decode(t){return!t.startsWith("=?")||/[\x00-\x19\x80-\xff]/.test(t)?t:t.replaceAll(/=\?([\w-]*)\?([QqBb])\?((?:[^?]|\?(?!=))*)\?=/g,(function(t,e,i,s){if("q"===i||"Q"===i)return textdecode(e,s=(s=s.replaceAll("_"," ")).replaceAll(/=([0-9a-fA-F]{2})/g,(function(t,e){return String.fromCharCode(parseInt(e,16))})));try{s=atob(s)}catch{}return textdecode(e,s)}))}return""}(e);if(t.includes("%"))try{t=decodeURIComponent(t)}catch{}if(isPdfFile(t))return t}return null}function createResponseStatusError(t,e){return 404===t||0===t&&e.startsWith("file:")?new MissingPDFException('Missing PDF "'+e+'".'):new UnexpectedResponseException(`Unexpected server response (${t}) while retrieving PDF "${e}".`,t)}function validateResponseStatus(t){return 200===t||206===t}function createFetchOptions(t,e,i){return{method:"GET",headers:t,signal:i.signal,mode:"cors",credentials:e?"include":"same-origin",redirect:"follow"}}function createHeaders(t){const e=new Headers;for(const i in t){const s=t[i];void 0!==s&&e.append(i,s)}return e}function getArrayBuffer(t){if(t instanceof Uint8Array)return t.buffer;if(t instanceof ArrayBuffer)return t;warn(`getArrayBuffer - unexpected data format: ${t}`);return new Uint8Array(t).buffer}class PDFFetchStream{constructor(t){this.source=t;this.isHttp=/^https?:/i.test(t.url);this.httpHeaders=this.isHttp&&t.httpHeaders||{};this._fullRequestReader=null;this._rangeRequestReaders=[]}get _progressiveDataLength(){return this._fullRequestReader?._loaded??0}getFullReader(){assert(!this._fullRequestReader,"PDFFetchStream.getFullReader can only be called once.");this._fullRequestReader=new PDFFetchStreamReader(this);return this._fullRequestReader}getRangeReader(t,e){if(e<=this._progressiveDataLength)return null;const i=new PDFFetchStreamRangeReader(this,t,e);this._rangeRequestReaders.push(i);return i}cancelAllRequests(t){this._fullRequestReader?.cancel(t);for(const e of this._rangeRequestReaders.slice(0))e.cancel(t)}}class PDFFetchStreamReader{constructor(t){this._stream=t;this._reader=null;this._loaded=0;this._filename=null;const e=t.source;this._withCredentials=e.withCredentials||!1;this._contentLength=e.length;this._headersCapability=Promise.withResolvers();this._disableRange=e.disableRange||!1;this._rangeChunkSize=e.rangeChunkSize;this._rangeChunkSize||this._disableRange||(this._disableRange=!0);this._abortController=new AbortController;this._isStreamingSupported=!e.disableStream;this._isRangeSupported=!e.disableRange;this._headers=createHeaders(this._stream.httpHeaders);const i=e.url;fetch(i,createFetchOptions(this._headers,this._withCredentials,this._abortController)).then((t=>{if(!validateResponseStatus(t.status))throw createResponseStatusError(t.status,i);this._reader=t.body.getReader();this._headersCapability.resolve();const getResponseHeader=e=>t.headers.get(e),{allowRangeRequests:e,suggestedLength:s}=validateRangeRequestCapabilities({getResponseHeader,isHttp:this._stream.isHttp,rangeChunkSize:this._rangeChunkSize,disableRange:this._disableRange});this._isRangeSupported=e;this._contentLength=s||this._contentLength;this._filename=extractFilenameFromHeader(getResponseHeader);!this._isStreamingSupported&&this._isRangeSupported&&this.cancel(new AbortException("Streaming is disabled."))})).catch(this._headersCapability.reject);this.onProgress=null}get headersReady(){return this._headersCapability.promise}get filename(){return this._filename}get contentLength(){return this._contentLength}get isRangeSupported(){return this._isRangeSupported}get isStreamingSupported(){return this._isStreamingSupported}async read(){await this._headersCapability.promise;const{value:t,done:e}=await this._reader.read();if(e)return{value:t,done:e};this._loaded+=t.byteLength;this.onProgress?.({loaded:this._loaded,total:this._contentLength});return{value:getArrayBuffer(t),done:!1}}cancel(t){this._reader?.cancel(t);this._abortController.abort()}}class PDFFetchStreamRangeReader{constructor(t,e,i){this._stream=t;this._reader=null;this._loaded=0;const s=t.source;this._withCredentials=s.withCredentials||!1;this._readCapability=Promise.withResolvers();this._isStreamingSupported=!s.disableStream;this._abortController=new AbortController;this._headers=createHeaders(this._stream.httpHeaders);this._headers.append("Range",`bytes=${e}-${i-1}`);const n=s.url;fetch(n,createFetchOptions(this._headers,this._withCredentials,this._abortController)).then((t=>{if(!validateResponseStatus(t.status))throw createResponseStatusError(t.status,n);this._readCapability.resolve();this._reader=t.body.getReader()})).catch(this._readCapability.reject);this.onProgress=null}get isStreamingSupported(){return this._isStreamingSupported}async read(){await this._readCapability.promise;const{value:t,done:e}=await this._reader.read();if(e)return{value:t,done:e};this._loaded+=t.byteLength;this.onProgress?.({loaded:this._loaded});return{value:getArrayBuffer(t),done:!1}}cancel(t){this._reader?.cancel(t);this._abortController.abort()}}class NetworkManager{constructor(t,e={}){this.url=t;this.isHttp=/^https?:/i.test(t);this.httpHeaders=this.isHttp&&e.httpHeaders||Object.create(null);this.withCredentials=e.withCredentials||!1;this.currXhrId=0;this.pendingRequests=Object.create(null)}requestRange(t,e,i){const s={begin:t,end:e};for(const t in i)s[t]=i[t];return this.request(s)}requestFull(t){return this.request(t)}request(t){const e=new XMLHttpRequest,i=this.currXhrId++,s=this.pendingRequests[i]={xhr:e};e.open("GET",this.url);e.withCredentials=this.withCredentials;for(const t in this.httpHeaders){const i=this.httpHeaders[t];void 0!==i&&e.setRequestHeader(t,i)}if(this.isHttp&&"begin"in t&&"end"in t){e.setRequestHeader("Range",`bytes=${t.begin}-${t.end-1}`);s.expectedStatus=206}else s.expectedStatus=200;e.responseType="arraybuffer";t.onError&&(e.onerror=function(i){t.onError(e.status)});e.onreadystatechange=this.onStateChange.bind(this,i);e.onprogress=this.onProgress.bind(this,i);s.onHeadersReceived=t.onHeadersReceived;s.onDone=t.onDone;s.onError=t.onError;s.onProgress=t.onProgress;e.send(null);return i}onProgress(t,e){const i=this.pendingRequests[t];i&&i.onProgress?.(e)}onStateChange(t,e){const i=this.pendingRequests[t];if(!i)return;const s=i.xhr;if(s.readyState>=2&&i.onHeadersReceived){i.onHeadersReceived();delete i.onHeadersReceived}if(4!==s.readyState)return;if(!(t in this.pendingRequests))return;delete this.pendingRequests[t];if(0===s.status&&this.isHttp){i.onError?.(s.status);return}const n=s.status||200;if(!(200===n&&206===i.expectedStatus)&&n!==i.expectedStatus){i.onError?.(s.status);return}const a=function network_getArrayBuffer(t){const e=t.response;return"string"!=typeof e?e:stringToBytes(e).buffer}(s);if(206===n){const t=s.getResponseHeader("Content-Range"),e=/bytes (\d+)-(\d+)\/(\d+)/.exec(t);i.onDone({begin:parseInt(e[1],10),chunk:a})}else a?i.onDone({begin:0,chunk:a}):i.onError?.(s.status)}getRequestXhr(t){return this.pendingRequests[t].xhr}isPendingRequest(t){return t in this.pendingRequests}abortRequest(t){const e=this.pendingRequests[t].xhr;delete this.pendingRequests[t];e.abort()}}class PDFNetworkStream{constructor(t){this._source=t;this._manager=new NetworkManager(t.url,{httpHeaders:t.httpHeaders,withCredentials:t.withCredentials});this._rangeChunkSize=t.rangeChunkSize;this._fullRequestReader=null;this._rangeRequestReaders=[]}_onRangeRequestReaderClosed(t){const e=this._rangeRequestReaders.indexOf(t);e>=0&&this._rangeRequestReaders.splice(e,1)}getFullReader(){assert(!this._fullRequestReader,"PDFNetworkStream.getFullReader can only be called once.");this._fullRequestReader=new PDFNetworkStreamFullRequestReader(this._manager,this._source);return this._fullRequestReader}getRangeReader(t,e){const i=new PDFNetworkStreamRangeRequestReader(this._manager,t,e);i.onClosed=this._onRangeRequestReaderClosed.bind(this);this._rangeRequestReaders.push(i);return i}cancelAllRequests(t){this._fullRequestReader?.cancel(t);for(const e of this._rangeRequestReaders.slice(0))e.cancel(t)}}class PDFNetworkStreamFullRequestReader{constructor(t,e){this._manager=t;const i={onHeadersReceived:this._onHeadersReceived.bind(this),onDone:this._onDone.bind(this),onError:this._onError.bind(this),onProgress:this._onProgress.bind(this)};this._url=e.url;this._fullRequestId=t.requestFull(i);this._headersReceivedCapability=Promise.withResolvers();this._disableRange=e.disableRange||!1;this._contentLength=e.length;this._rangeChunkSize=e.rangeChunkSize;this._rangeChunkSize||this._disableRange||(this._disableRange=!0);this._isStreamingSupported=!1;this._isRangeSupported=!1;this._cachedChunks=[];this._requests=[];this._done=!1;this._storedError=void 0;this._filename=null;this.onProgress=null}_onHeadersReceived(){const t=this._fullRequestId,e=this._manager.getRequestXhr(t),getResponseHeader=t=>e.getResponseHeader(t),{allowRangeRequests:i,suggestedLength:s}=validateRangeRequestCapabilities({getResponseHeader,isHttp:this._manager.isHttp,rangeChunkSize:this._rangeChunkSize,disableRange:this._disableRange});i&&(this._isRangeSupported=!0);this._contentLength=s||this._contentLength;this._filename=extractFilenameFromHeader(getResponseHeader);this._isRangeSupported&&this._manager.abortRequest(t);this._headersReceivedCapability.resolve()}_onDone(t){if(t)if(this._requests.length>0){this._requests.shift().resolve({value:t.chunk,done:!1})}else this._cachedChunks.push(t.chunk);this._done=!0;if(!(this._cachedChunks.length>0)){for(const t of this._requests)t.resolve({value:void 0,done:!0});this._requests.length=0}}_onError(t){this._storedError=createResponseStatusError(t,this._url);this._headersReceivedCapability.reject(this._storedError);for(const t of this._requests)t.reject(this._storedError);this._requests.length=0;this._cachedChunks.length=0}_onProgress(t){this.onProgress?.({loaded:t.loaded,total:t.lengthComputable?t.total:this._contentLength})}get filename(){return this._filename}get isRangeSupported(){return this._isRangeSupported}get isStreamingSupported(){return this._isStreamingSupported}get contentLength(){return this._contentLength}get headersReady(){return this._headersReceivedCapability.promise}async read(){if(this._storedError)throw this._storedError;if(this._cachedChunks.length>0){return{value:this._cachedChunks.shift(),done:!1}}if(this._done)return{value:void 0,done:!0};const t=Promise.withResolvers();this._requests.push(t);return t.promise}cancel(t){this._done=!0;this._headersReceivedCapability.reject(t);for(const t of this._requests)t.resolve({value:void 0,done:!0});this._requests.length=0;this._manager.isPendingRequest(this._fullRequestId)&&this._manager.abortRequest(this._fullRequestId);this._fullRequestReader=null}}class PDFNetworkStreamRangeRequestReader{constructor(t,e,i){this._manager=t;const s={onDone:this._onDone.bind(this),onError:this._onError.bind(this),onProgress:this._onProgress.bind(this)};this._url=t.url;this._requestId=t.requestRange(e,i,s);this._requests=[];this._queuedChunk=null;this._done=!1;this._storedError=void 0;this.onProgress=null;this.onClosed=null}_close(){this.onClosed?.(this)}_onDone(t){const e=t.chunk;if(this._requests.length>0){this._requests.shift().resolve({value:e,done:!1})}else this._queuedChunk=e;this._done=!0;for(const t of this._requests)t.resolve({value:void 0,done:!0});this._requests.length=0;this._close()}_onError(t){this._storedError=createResponseStatusError(t,this._url);for(const t of this._requests)t.reject(this._storedError);this._requests.length=0;this._queuedChunk=null}_onProgress(t){this.isStreamingSupported||this.onProgress?.({loaded:t.loaded})}get isStreamingSupported(){return!1}async read(){if(this._storedError)throw this._storedError;if(null!==this._queuedChunk){const t=this._queuedChunk;this._queuedChunk=null;return{value:t,done:!1}}if(this._done)return{value:void 0,done:!0};const t=Promise.withResolvers();this._requests.push(t);return t.promise}cancel(t){this._done=!0;for(const t of this._requests)t.resolve({value:void 0,done:!0});this._requests.length=0;this._manager.isPendingRequest(this._requestId)&&this._manager.abortRequest(this._requestId);this._close()}}const zt=/^file:\/\/\/[a-zA-Z]:\//;class PDFNodeStream{constructor(t){this.source=t;this.url=function parseUrl(t){const e=NodePackages.get("url"),i=e.parse(t);if("file:"===i.protocol||i.host)return i;if(/^[a-z]:[/\\]/i.test(t))return e.parse(`file:///${t}`);i.host||(i.protocol="file:");return i}(t.url);this.isHttp="http:"===this.url.protocol||"https:"===this.url.protocol;this.isFsUrl="file:"===this.url.protocol;this.httpHeaders=this.isHttp&&t.httpHeaders||{};this._fullRequestReader=null;this._rangeRequestReaders=[]}get _progressiveDataLength(){return this._fullRequestReader?._loaded??0}getFullReader(){assert(!this._fullRequestReader,"PDFNodeStream.getFullReader can only be called once.");this._fullRequestReader=this.isFsUrl?new PDFNodeStreamFsFullReader(this):new PDFNodeStreamFullReader(this);return this._fullRequestReader}getRangeReader(t,e){if(e<=this._progressiveDataLength)return null;const i=this.isFsUrl?new PDFNodeStreamFsRangeReader(this,t,e):new PDFNodeStreamRangeReader(this,t,e);this._rangeRequestReaders.push(i);return i}cancelAllRequests(t){this._fullRequestReader?.cancel(t);for(const e of this._rangeRequestReaders.slice(0))e.cancel(t)}}class BaseFullReader{constructor(t){this._url=t.url;this._done=!1;this._storedError=null;this.onProgress=null;const e=t.source;this._contentLength=e.length;this._loaded=0;this._filename=null;this._disableRange=e.disableRange||!1;this._rangeChunkSize=e.rangeChunkSize;this._rangeChunkSize||this._disableRange||(this._disableRange=!0);this._isStreamingSupported=!e.disableStream;this._isRangeSupported=!e.disableRange;this._readableStream=null;this._readCapability=Promise.withResolvers();this._headersCapability=Promise.withResolvers()}get headersReady(){return this._headersCapability.promise}get filename(){return this._filename}get contentLength(){return this._contentLength}get isRangeSupported(){return this._isRangeSupported}get isStreamingSupported(){return this._isStreamingSupported}async read(){await this._readCapability.promise;if(this._done)return{value:void 0,done:!0};if(this._storedError)throw this._storedError;const t=this._readableStream.read();if(null===t){this._readCapability=Promise.withResolvers();return this.read()}this._loaded+=t.length;this.onProgress?.({loaded:this._loaded,total:this._contentLength});return{value:new Uint8Array(t).buffer,done:!1}}cancel(t){this._readableStream?this._readableStream.destroy(t):this._error(t)}_error(t){this._storedError=t;this._readCapability.resolve()}_setReadableStream(t){this._readableStream=t;t.on("readable",(()=>{this._readCapability.resolve()}));t.on("end",(()=>{t.destroy();this._done=!0;this._readCapability.resolve()}));t.on("error",(t=>{this._error(t)}));!this._isStreamingSupported&&this._isRangeSupported&&this._error(new AbortException("streaming is disabled"));this._storedError&&this._readableStream.destroy(this._storedError)}}class BaseRangeReader{constructor(t){this._url=t.url;this._done=!1;this._storedError=null;this.onProgress=null;this._loaded=0;this._readableStream=null;this._readCapability=Promise.withResolvers();const e=t.source;this._isStreamingSupported=!e.disableStream}get isStreamingSupported(){return this._isStreamingSupported}async read(){await this._readCapability.promise;if(this._done)return{value:void 0,done:!0};if(this._storedError)throw this._storedError;const t=this._readableStream.read();if(null===t){this._readCapability=Promise.withResolvers();return this.read()}this._loaded+=t.length;this.onProgress?.({loaded:this._loaded});return{value:new Uint8Array(t).buffer,done:!1}}cancel(t){this._readableStream?this._readableStream.destroy(t):this._error(t)}_error(t){this._storedError=t;this._readCapability.resolve()}_setReadableStream(t){this._readableStream=t;t.on("readable",(()=>{this._readCapability.resolve()}));t.on("end",(()=>{t.destroy();this._done=!0;this._readCapability.resolve()}));t.on("error",(t=>{this._error(t)}));this._storedError&&this._readableStream.destroy(this._storedError)}}function createRequestOptions(t,e){return{protocol:t.protocol,auth:t.auth,host:t.hostname,port:t.port,path:t.path,method:"GET",headers:e}}class PDFNodeStreamFullReader extends BaseFullReader{constructor(t){super(t);const handleResponse=e=>{if(404===e.statusCode){const t=new MissingPDFException(`Missing PDF "${this._url}".`);this._storedError=t;this._headersCapability.reject(t);return}this._headersCapability.resolve();this._setReadableStream(e);const getResponseHeader=t=>this._readableStream.headers[t.toLowerCase()],{allowRangeRequests:i,suggestedLength:s}=validateRangeRequestCapabilities({getResponseHeader,isHttp:t.isHttp,rangeChunkSize:this._rangeChunkSize,disableRange:this._disableRange});this._isRangeSupported=i;this._contentLength=s||this._contentLength;this._filename=extractFilenameFromHeader(getResponseHeader)};this._request=null;if("http:"===this._url.protocol){const e=NodePackages.get("http");this._request=e.request(createRequestOptions(this._url,t.httpHeaders),handleResponse)}else{const e=NodePackages.get("https");this._request=e.request(createRequestOptions(this._url,t.httpHeaders),handleResponse)}this._request.on("error",(t=>{this._storedError=t;this._headersCapability.reject(t)}));this._request.end()}}class PDFNodeStreamRangeReader extends BaseRangeReader{constructor(t,e,i){super(t);this._httpHeaders={};for(const e in t.httpHeaders){const i=t.httpHeaders[e];void 0!==i&&(this._httpHeaders[e]=i)}this._httpHeaders.Range=`bytes=${e}-${i-1}`;const handleResponse=t=>{if(404!==t.statusCode)this._setReadableStream(t);else{const t=new MissingPDFException(`Missing PDF "${this._url}".`);this._storedError=t}};this._request=null;if("http:"===this._url.protocol){const t=NodePackages.get("http");this._request=t.request(createRequestOptions(this._url,this._httpHeaders),handleResponse)}else{const t=NodePackages.get("https");this._request=t.request(createRequestOptions(this._url,this._httpHeaders),handleResponse)}this._request.on("error",(t=>{this._storedError=t}));this._request.end()}}class PDFNodeStreamFsFullReader extends BaseFullReader{constructor(t){super(t);let e=decodeURIComponent(this._url.path);zt.test(this._url.href)&&(e=e.replace(/^\//,""));const i=NodePackages.get("fs");i.promises.lstat(e).then((t=>{this._contentLength=t.size;this._setReadableStream(i.createReadStream(e));this._headersCapability.resolve()}),(t=>{"ENOENT"===t.code&&(t=new MissingPDFException(`Missing PDF "${e}".`));this._storedError=t;this._headersCapability.reject(t)}))}}class PDFNodeStreamFsRangeReader extends BaseRangeReader{constructor(t,e,i){super(t);let s=decodeURIComponent(this._url.path);zt.test(this._url.href)&&(s=s.replace(/^\//,""));const n=NodePackages.get("fs");this._setReadableStream(n.createReadStream(s,{start:e,end:i-1}))}}const Ut=30;class TextLayer{#qe=Promise.withResolvers();#ft=null;#Xe=!1;#Ke=!!globalThis.FontInspector?.enabled;#Ye=null;#Qe=null;#Je=0;#Ze=0;#ti=null;#ei=null;#ii=0;#si=0;#ni=Object.create(null);#ai=[];#ri=null;#oi=[];#hi=new WeakMap;#li=null;static#di=new Map;static#ci=new Map;static#ui=new Set;constructor({textContentSource:t,container:e,viewport:i}){if(t instanceof ReadableStream)this.#ri=t;else{if("object"!=typeof t)throw new Error('No "textContentSource" parameter specified.');this.#ri=new ReadableStream({start(e){e.enqueue(t);e.close()}})}this.#ft=this.#ei=e;this.#si=i.scale*(globalThis.devicePixelRatio||1);this.#ii=i.rotation;this.#Qe={prevFontSize:null,prevFontFamily:null,div:null,properties:null,ctx:null};const{pageWidth:s,pageHeight:n,pageX:a,pageY:r}=i.rawDims;this.#li=[1,0,0,-1,-a,r+n];this.#Ze=s;this.#Je=n;setLayerDimensions(e,i);this.#qe.promise.catch((()=>{})).then((()=>{TextLayer.#ui.delete(this);this.#Qe=null;this.#ni=null}))}render(){const pump=()=>{this.#ti.read().then((({value:t,done:e})=>{if(e)this.#qe.resolve();else{this.#Ye??=t.lang;Object.assign(this.#ni,t.styles);this.#pi(t.items);pump()}}),this.#qe.reject)};this.#ti=this.#ri.getReader();TextLayer.#ui.add(this);pump();return this.#qe.promise}update({viewport:t,onBefore:e=null}){const i=t.scale*(globalThis.devicePixelRatio||1),s=t.rotation;if(s!==this.#ii){e?.();this.#ii=s;setLayerDimensions(this.#ei,{rotation:s})}if(i!==this.#si){e?.();this.#si=i;const t={prevFontSize:null,prevFontFamily:null,div:null,properties:null,ctx:TextLayer.#gi(this.#Ye)};for(const e of this.#oi){t.properties=this.#hi.get(e);t.div=e;this.#mi(t)}}}cancel(){const t=new AbortException("TextLayer task cancelled.");this.#ti?.cancel(t).catch((()=>{}));this.#ti=null;this.#qe.reject(t)}get textDivs(){return this.#oi}get textContentItemsStr(){return this.#ai}#pi(t){if(this.#Xe)return;this.#Qe.ctx||=TextLayer.#gi(this.#Ye);const e=this.#oi,i=this.#ai;for(const s of t){if(e.length>1e5){warn("Ignoring additional textDivs for performance reasons.");this.#Xe=!0;return}if(void 0!==s.str){i.push(s.str);this.#fi(s)}else if("beginMarkedContentProps"===s.type||"beginMarkedContent"===s.type){const t=this.#ft;this.#ft=document.createElement("span");this.#ft.classList.add("markedContent");null!==s.id&&this.#ft.setAttribute("id",`${s.id}`);t.append(this.#ft)}else"endMarkedContent"===s.type&&(this.#ft=this.#ft.parentNode)}}#fi(t){const e=document.createElement("span"),i={angle:0,canvasWidth:0,hasText:""!==t.str,hasEOL:t.hasEOL,fontSize:0};this.#oi.push(e);const s=Util.transform(this.#li,t.transform);let n=Math.atan2(s[1],s[0]);const a=this.#ni[t.fontName];a.vertical&&(n+=Math.PI/2);const r=this.#Ke&&a.fontSubstitution||a.fontFamily,o=Math.hypot(s[2],s[3]),h=o*TextLayer.#bi(r,this.#Ye);let l,d;if(0===n){l=s[4];d=s[5]-h}else{l=s[4]+h*Math.sin(n);d=s[5]-h*Math.cos(n)}const c="calc(var(--scale-factor)*",u=e.style;if(this.#ft===this.#ei){u.left=`${(100*l/this.#Ze).toFixed(2)}%`;u.top=`${(100*d/this.#Je).toFixed(2)}%`}else{u.left=`${c}${l.toFixed(2)}px)`;u.top=`${c}${d.toFixed(2)}px)`}u.fontSize=`${c}${o.toFixed(2)}px)`;u.fontFamily=r;i.fontSize=o;e.setAttribute("role","presentation");e.textContent=t.str;e.dir=t.dir;this.#Ke&&(e.dataset.fontName=a.fontSubstitutionLoadedName||t.fontName);0!==n&&(i.angle=n*(180/Math.PI));let p=!1;if(t.str.length>1)p=!0;else if(" "!==t.str&&t.transform[0]!==t.transform[3]){const e=Math.abs(t.transform[0]),i=Math.abs(t.transform[3]);e!==i&&Math.max(e,i)/Math.min(e,i)>1.5&&(p=!0)}p&&(i.canvasWidth=a.vertical?t.height:t.width);this.#hi.set(e,i);this.#Qe.div=e;this.#Qe.properties=i;this.#mi(this.#Qe);i.hasText&&this.#ft.append(e);if(i.hasEOL){const t=document.createElement("br");t.setAttribute("role","presentation");this.#ft.append(t)}}#mi(t){const{div:e,properties:i,ctx:s,prevFontSize:n,prevFontFamily:a}=t,{style:r}=e;let o="";if(0!==i.canvasWidth&&i.hasText){const{fontFamily:h}=r,{canvasWidth:l,fontSize:d}=i;if(n!==d||a!==h){s.font=`${d*this.#si}px ${h}`;t.prevFontSize=d;t.prevFontFamily=h}const{width:c}=s.measureText(e.textContent);c>0&&(o=`scaleX(${l*this.#si/c})`)}0!==i.angle&&(o=`rotate(${i.angle}deg) ${o}`);o.length>0&&(r.transform=o)}static cleanup(){if(!(this.#ui.size>0)){this.#di.clear();for(const{canvas:t}of this.#ci.values())t.remove();this.#ci.clear()}}static#gi(t=null){let e=this.#ci.get(t||="");if(!e){const i=document.createElement("canvas");i.className="hiddenCanvasElement";i.lang=t;document.body.append(i);e=i.getContext("2d",{alpha:!1});this.#ci.set(t,e)}return e}static#bi(t,e){const i=this.#di.get(t);if(i)return i;const s=this.#gi(e),n=s.font;s.canvas.width=s.canvas.height=Ut;s.font=`30px ${t}`;const a=s.measureText("");let r=a.fontBoundingBoxAscent,o=Math.abs(a.fontBoundingBoxDescent);if(r){const e=r/(r+o);this.#di.set(t,e);s.canvas.width=s.canvas.height=0;s.font=n;return e}s.strokeStyle="red";s.clearRect(0,0,Ut,Ut);s.strokeText("g",0,0);let h=s.getImageData(0,0,Ut,Ut).data;o=0;for(let t=h.length-1-3;t>=0;t-=4)if(h[t]>0){o=Math.ceil(t/4/Ut);break}s.clearRect(0,0,Ut,Ut);s.strokeText("A",0,Ut);h=s.getImageData(0,0,Ut,Ut).data;r=0;for(let t=0,e=h.length;t<e;t+=4)if(h[t]>0){r=Ut-Math.floor(t/4/Ut);break}s.canvas.width=s.canvas.height=0;s.font=n;const l=r?r/(r+o):.8;this.#di.set(t,l);return l}}function renderTextLayer(){deprecated("`renderTextLayer`, please use `TextLayer` instead.");const{textContentSource:t,container:e,viewport:i,...s}=arguments[0],n=Object.keys(s);n.length>0&&warn("Ignoring `renderTextLayer` parameters: "+n.join(", "));const a=new TextLayer({textContentSource:t,container:e,viewport:i}),{textDivs:r,textContentItemsStr:o}=a;return{promise:a.render(),textDivs:r,textContentItemsStr:o}}function updateTextLayer(){deprecated("`updateTextLayer`, please use `TextLayer` instead.")}class XfaText{static textContent(t){const e=[],i={items:e,styles:Object.create(null)};!function walk(t){if(!t)return;let i=null;const s=t.name;if("#text"===s)i=t.value;else{if(!XfaText.shouldBuildText(s))return;t?.attributes?.textContent?i=t.attributes.textContent:t.value&&(i=t.value)}null!==i&&e.push({str:i});if(t.children)for(const e of t.children)walk(e)}(t);return i}static shouldBuildText(t){return!("textarea"===t||"input"===t||"option"===t||"select"===t)}}const jt=65536,$t=e?class NodeCanvasFactory extends BaseCanvasFactory{_createCanvas(t,e){return NodePackages.get("canvas").createCanvas(t,e)}}:class DOMCanvasFactory extends BaseCanvasFactory{constructor({ownerDocument:t=globalThis.document}={}){super();this._document=t}_createCanvas(t,e){const i=this._document.createElement("canvas");i.width=t;i.height=e;return i}},Vt=e?class NodeCMapReaderFactory extends BaseCMapReaderFactory{_fetchData(t,e){return node_utils_fetchData(t).then((t=>({cMapData:t,compressionType:e})))}}:DOMCMapReaderFactory,Gt=e?class NodeFilterFactory extends BaseFilterFactory{}:class DOMFilterFactory extends BaseFilterFactory{#vi;#Ai;#yi;#wi;#xi;#f=0;constructor({docId:t,ownerDocument:e=globalThis.document}={}){super();this.#yi=t;this.#wi=e}get#v(){return this.#vi||=new Map}get#Ei(){return this.#xi||=new Map}get#_i(){if(!this.#Ai){const t=this.#wi.createElement("div"),{style:e}=t;e.visibility="hidden";e.contain="strict";e.width=e.height=0;e.position="absolute";e.top=e.left=0;e.zIndex=-1;const i=this.#wi.createElementNS(ct,"svg");i.setAttribute("width",0);i.setAttribute("height",0);this.#Ai=this.#wi.createElementNS(ct,"defs");t.append(i);i.append(this.#Ai);this.#wi.body.append(t)}return this.#Ai}#Ci(t){if(1===t.length){const e=t[0],i=new Array(256);for(let t=0;t<256;t++)i[t]=e[t]/255;const s=i.join(",");return[s,s,s]}const[e,i,s]=t,n=new Array(256),a=new Array(256),r=new Array(256);for(let t=0;t<256;t++){n[t]=e[t]/255;a[t]=i[t]/255;r[t]=s[t]/255}return[n.join(","),a.join(","),r.join(",")]}addFilter(t){if(!t)return"none";let e=this.#v.get(t);if(e)return e;const[i,s,n]=this.#Ci(t),a=1===t.length?i:`${i}${s}${n}`;e=this.#v.get(a);if(e){this.#v.set(t,e);return e}const r=`g_${this.#yi}_transfer_map_${this.#f++}`,o=`url(#${r})`;this.#v.set(t,o);this.#v.set(a,o);const h=this.#Si(r);this.#Ti(i,s,n,h);return o}addHCMFilter(t,e){const i=`${t}-${e}`,s="base";let n=this.#Ei.get(s);if(n?.key===i)return n.url;if(n){n.filter?.remove();n.key=i;n.url="none";n.filter=null}else{n={key:i,url:"none",filter:null};this.#Ei.set(s,n)}if(!t||!e)return n.url;const a=this.#Mi(t);t=Util.makeHexColor(...a);const r=this.#Mi(e);e=Util.makeHexColor(...r);this.#_i.style.color="";if("#000000"===t&&"#ffffff"===e||t===e)return n.url;const o=new Array(256);for(let t=0;t<=255;t++){const e=t/255;o[t]=e<=.03928?e/12.92:((e+.055)/1.055)**2.4}const h=o.join(","),l=`g_${this.#yi}_hcm_filter`,d=n.filter=this.#Si(l);this.#Ti(h,h,h,d);this.#ki(d);const getSteps=(t,e)=>{const i=a[t]/255,s=r[t]/255,n=new Array(e+1);for(let t=0;t<=e;t++)n[t]=i+t/e*(s-i);return n.join(",")};this.#Ti(getSteps(0,5),getSteps(1,5),getSteps(2,5),d);n.url=`url(#${l})`;return n.url}addAlphaFilter(t){let e=this.#v.get(t);if(e)return e;const[i]=this.#Ci([t]),s=`alpha_${i}`;e=this.#v.get(s);if(e){this.#v.set(t,e);return e}const n=`g_${this.#yi}_alpha_map_${this.#f++}`,a=`url(#${n})`;this.#v.set(t,a);this.#v.set(s,a);const r=this.#Si(n);this.#Pi(i,r);return a}addLuminosityFilter(t){let e,i,s=this.#v.get(t||"luminosity");if(s)return s;if(t){[e]=this.#Ci([t]);i=`luminosity_${e}`}else i="luminosity";s=this.#v.get(i);if(s){this.#v.set(t,s);return s}const n=`g_${this.#yi}_luminosity_map_${this.#f++}`,a=`url(#${n})`;this.#v.set(t,a);this.#v.set(i,a);const r=this.#Si(n);this.#Di(r);t&&this.#Pi(e,r);return a}addHighlightHCMFilter(t,e,i,s,n){const a=`${e}-${i}-${s}-${n}`;let r=this.#Ei.get(t);if(r?.key===a)return r.url;if(r){r.filter?.remove();r.key=a;r.url="none";r.filter=null}else{r={key:a,url:"none",filter:null};this.#Ei.set(t,r)}if(!e||!i)return r.url;const[o,h]=[e,i].map(this.#Mi.bind(this));let l=Math.round(.2126*o[0]+.7152*o[1]+.0722*o[2]),d=Math.round(.2126*h[0]+.7152*h[1]+.0722*h[2]),[c,u]=[s,n].map(this.#Mi.bind(this));d<l&&([l,d,c,u]=[d,l,u,c]);this.#_i.style.color="";const getSteps=(t,e,i)=>{const s=new Array(256),n=(d-l)/i,a=t/255,r=(e-t)/(255*i);let o=0;for(let t=0;t<=i;t++){const e=Math.round(l+t*n),i=a+t*r;for(let t=o;t<=e;t++)s[t]=i;o=e+1}for(let t=o;t<256;t++)s[t]=s[o-1];return s.join(",")},p=`g_${this.#yi}_hcm_${t}_filter`,g=r.filter=this.#Si(p);this.#ki(g);this.#Ti(getSteps(c[0],u[0],5),getSteps(c[1],u[1],5),getSteps(c[2],u[2],5),g);r.url=`url(#${p})`;return r.url}destroy(t=!1){if(!t||0===this.#Ei.size){if(this.#Ai){this.#Ai.parentNode.parentNode.remove();this.#Ai=null}if(this.#vi){this.#vi.clear();this.#vi=null}this.#f=0}}#Di(t){const e=this.#wi.createElementNS(ct,"feColorMatrix");e.setAttribute("type","matrix");e.setAttribute("values","0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.3 0.59 0.11 0 0");t.append(e)}#ki(t){const e=this.#wi.createElementNS(ct,"feColorMatrix");e.setAttribute("type","matrix");e.setAttribute("values","0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0 0 0 1 0");t.append(e)}#Si(t){const e=this.#wi.createElementNS(ct,"filter");e.setAttribute("color-interpolation-filters","sRGB");e.setAttribute("id",t);this.#_i.append(e);return e}#Ri(t,e,i){const s=this.#wi.createElementNS(ct,e);s.setAttribute("type","discrete");s.setAttribute("tableValues",i);t.append(s)}#Ti(t,e,i,s){const n=this.#wi.createElementNS(ct,"feComponentTransfer");s.append(n);this.#Ri(n,"feFuncR",t);this.#Ri(n,"feFuncG",e);this.#Ri(n,"feFuncB",i)}#Pi(t,e){const i=this.#wi.createElementNS(ct,"feComponentTransfer");e.append(i);this.#Ri(i,"feFuncA",t)}#Mi(t){this.#_i.style.color=t;return getRGB(getComputedStyle(this.#_i).getPropertyValue("color"))}},Wt=e?class NodeStandardFontDataFactory extends BaseStandardFontDataFactory{_fetchData(t){return node_utils_fetchData(t)}}:DOMStandardFontDataFactory;function getDocument(t){"string"==typeof t||t instanceof URL?t={url:t}:(t instanceof ArrayBuffer||ArrayBuffer.isView(t))&&(t={data:t});if("object"!=typeof t)throw new Error("Invalid parameter in getDocument, need parameter object.");if(!t.url&&!t.data&&!t.range)throw new Error("Invalid parameter object: need either .data, .range or .url");const i=new PDFDocumentLoadingTask,{docId:s}=i,n=t.url?function getUrlProp(t){if(t instanceof URL)return t.href;try{return new URL(t,window.location).href}catch{if(e&&"string"==typeof t)return t}throw new Error("Invalid PDF url data: either string or URL-object is expected in the url property.")}(t.url):null,a=t.data?function getDataProp(t){if(e&&"undefined"!=typeof Buffer&&t instanceof Buffer)throw new Error("Please provide binary data as `Uint8Array`, rather than `Buffer`.");if(t instanceof Uint8Array&&t.byteLength===t.buffer.byteLength)return t;if("string"==typeof t)return stringToBytes(t);if(t instanceof ArrayBuffer||ArrayBuffer.isView(t)||"object"==typeof t&&!isNaN(t?.length))return new Uint8Array(t);throw new Error("Invalid PDF binary data: either TypedArray, string, or array-like object is expected in the data property.")}(t.data):null,r=t.httpHeaders||null,o=!0===t.withCredentials,h=t.password??null,l=t.range instanceof PDFDataRangeTransport?t.range:null,d=Number.isInteger(t.rangeChunkSize)&&t.rangeChunkSize>0?t.rangeChunkSize:jt;let c=t.worker instanceof PDFWorker?t.worker:null;const u=t.verbosity,p="string"!=typeof t.docBaseUrl||isDataScheme(t.docBaseUrl)?null:t.docBaseUrl,g="string"==typeof t.cMapUrl?t.cMapUrl:null,m=!1!==t.cMapPacked,f=t.CMapReaderFactory||Vt,b="string"==typeof t.standardFontDataUrl?t.standardFontDataUrl:null,v=t.StandardFontDataFactory||Wt,A=!0!==t.stopAtErrors,y=Number.isInteger(t.maxImageSize)&&t.maxImageSize>-1?t.maxImageSize:-1,w=!1!==t.isEvalSupported,x="boolean"==typeof t.isOffscreenCanvasSupported?t.isOffscreenCanvasSupported:!e,E=Number.isInteger(t.canvasMaxAreaInBytes)?t.canvasMaxAreaInBytes:-1,_="boolean"==typeof t.disableFontFace?t.disableFontFace:e,C=!0===t.fontExtraProperties,S=!0===t.enableXfa,T=t.ownerDocument||globalThis.document,M=!0===t.disableRange,k=!0===t.disableStream,P=!0===t.disableAutoFetch,D=!0===t.pdfBug,R=l?l.length:t.length??NaN,F="boolean"==typeof t.useSystemFonts?t.useSystemFonts:!e&&!_,I="boolean"==typeof t.useWorkerFetch?t.useWorkerFetch:f===DOMCMapReaderFactory&&v===DOMStandardFontDataFactory&&g&&b&&isValidFetchUrl(g,document.baseURI)&&isValidFetchUrl(b,document.baseURI),L=t.canvasFactory||new $t({ownerDocument:T}),O=t.filterFactory||new Gt({docId:s,ownerDocument:T});setVerbosityLevel(u);const N={canvasFactory:L,filterFactory:O};if(!I){N.cMapReaderFactory=new f({baseUrl:g,isCompressed:m});N.standardFontDataFactory=new v({baseUrl:b})}if(!c){const t={verbosity:u,port:GlobalWorkerOptions.workerPort};c=t.port?PDFWorker.fromPort(t):new PDFWorker(t);i._worker=c}const B={docId:s,apiVersion:"4.3.136",data:a,password:h,disableAutoFetch:P,rangeChunkSize:d,length:R,docBaseUrl:p,enableXfa:S,evaluatorOptions:{maxImageSize:y,disableFontFace:_,ignoreErrors:A,isEvalSupported:w,isOffscreenCanvasSupported:x,canvasMaxAreaInBytes:E,fontExtraProperties:C,useSystemFonts:F,cMapUrl:I?g:null,standardFontDataUrl:I?b:null}},H={disableFontFace:_,fontExtraProperties:C,ownerDocument:T,pdfBug:D,styleElement:null,loadingParams:{disableAutoFetch:P,enableXfa:S}};c.promise.then((function(){if(i.destroyed)throw new Error("Loading aborted");if(c.destroyed)throw new Error("Worker was destroyed");const t=c.messageHandler.sendWithPromise("GetDocRequest",B,a?[a.buffer]:null);let h;if(l)h=new PDFDataTransportStream(l,{disableRange:M,disableStream:k});else if(!a){h=(t=>{if(e){return function(){return"undefined"!=typeof fetch&&"undefined"!=typeof Response&&"body"in Response.prototype}()&&isValidFetchUrl(t.url)?new PDFFetchStream(t):new PDFNodeStream(t)}return isValidFetchUrl(t.url)?new PDFFetchStream(t):new PDFNetworkStream(t)})({url:n,length:R,httpHeaders:r,withCredentials:o,rangeChunkSize:d,disableRange:M,disableStream:k})}return t.then((t=>{if(i.destroyed)throw new Error("Loading aborted");if(c.destroyed)throw new Error("Worker was destroyed");const e=new MessageHandler(s,t,c.port),n=new WorkerTransport(e,i,h,H,N);i._transport=n;e.send("Ready",null)}))})).catch(i._capability.reject);return i}function isRefProxy(t){return"object"==typeof t&&Number.isInteger(t?.num)&&t.num>=0&&Number.isInteger(t?.gen)&&t.gen>=0}class PDFDocumentLoadingTask{static#yi=0;constructor(){this._capability=Promise.withResolvers();this._transport=null;this._worker=null;this.docId="d"+PDFDocumentLoadingTask.#yi++;this.destroyed=!1;this.onPassword=null;this.onProgress=null}get promise(){return this._capability.promise}async destroy(){this.destroyed=!0;try{this._worker?.port&&(this._worker._pendingDestroy=!0);await(this._transport?.destroy())}catch(t){this._worker?.port&&delete this._worker._pendingDestroy;throw t}this._transport=null;if(this._worker){this._worker.destroy();this._worker=null}}}class PDFDataRangeTransport{constructor(t,e,i=!1,s=null){this.length=t;this.initialData=e;this.progressiveDone=i;this.contentDispositionFilename=s;this._rangeListeners=[];this._progressListeners=[];this._progressiveReadListeners=[];this._progressiveDoneListeners=[];this._readyCapability=Promise.withResolvers()}addRangeListener(t){this._rangeListeners.push(t)}addProgressListener(t){this._progressListeners.push(t)}addProgressiveReadListener(t){this._progressiveReadListeners.push(t)}addProgressiveDoneListener(t){this._progressiveDoneListeners.push(t)}onDataRange(t,e){for(const i of this._rangeListeners)i(t,e)}onDataProgress(t,e){this._readyCapability.promise.then((()=>{for(const i of this._progressListeners)i(t,e)}))}onDataProgressiveRead(t){this._readyCapability.promise.then((()=>{for(const e of this._progressiveReadListeners)e(t)}))}onDataProgressiveDone(){this._readyCapability.promise.then((()=>{for(const t of this._progressiveDoneListeners)t()}))}transportReady(){this._readyCapability.resolve()}requestDataRange(t,e){unreachable("Abstract method PDFDataRangeTransport.requestDataRange")}abort(){}}class PDFDocumentProxy{constructor(t,e){this._pdfInfo=t;this._transport=e}get annotationStorage(){return this._transport.annotationStorage}get filterFactory(){return this._transport.filterFactory}get numPages(){return this._pdfInfo.numPages}get fingerprints(){return this._pdfInfo.fingerprints}get isPureXfa(){return shadow(this,"isPureXfa",!!this._transport._htmlForXfa)}get allXfaHtml(){return this._transport._htmlForXfa}getPage(t){return this._transport.getPage(t)}getPageIndex(t){return this._transport.getPageIndex(t)}getDestinations(){return this._transport.getDestinations()}getDestination(t){return this._transport.getDestination(t)}getPageLabels(){return this._transport.getPageLabels()}getPageLayout(){return this._transport.getPageLayout()}getPageMode(){return this._transport.getPageMode()}getViewerPreferences(){return this._transport.getViewerPreferences()}getOpenAction(){return this._transport.getOpenAction()}getAttachments(){return this._transport.getAttachments()}getJSActions(){return this._transport.getDocJSActions()}getOutline(){return this._transport.getOutline()}getOptionalContentConfig({intent:t="display"}={}){const{renderingIntent:e}=this._transport.getRenderingIntent(t);return this._transport.getOptionalContentConfig(e)}getPermissions(){return this._transport.getPermissions()}getMetadata(){return this._transport.getMetadata()}getMarkInfo(){return this._transport.getMarkInfo()}getData(){return this._transport.getData()}saveDocument(){return this._transport.saveDocument()}getDownloadInfo(){return this._transport.downloadInfoCapability.promise}cleanup(t=!1){return this._transport.startCleanup(t||this.isPureXfa)}destroy(){return this.loadingTask.destroy()}cachedPageNumber(t){return this._transport.cachedPageNumber(t)}get loadingParams(){return this._transport.loadingParams}get loadingTask(){return this._transport.loadingTask}getFieldObjects(){return this._transport.getFieldObjects()}hasJSActions(){return this._transport.hasJSActions()}getCalculationOrderIds(){return this._transport.getCalculationOrderIds()}}class PDFPageProxy{#Fi=null;#Ii=!1;constructor(t,e,i,s=!1){this._pageIndex=t;this._pageInfo=e;this._transport=i;this._stats=s?new StatTimer:null;this._pdfBug=s;this.commonObjs=i.commonObjs;this.objs=new PDFObjects;this._maybeCleanupAfterRender=!1;this._intentStates=new Map;this.destroyed=!1}get pageNumber(){return this._pageIndex+1}get rotate(){return this._pageInfo.rotate}get ref(){return this._pageInfo.ref}get userUnit(){return this._pageInfo.userUnit}get view(){return this._pageInfo.view}getViewport({scale:t,rotation:e=this.rotate,offsetX:i=0,offsetY:s=0,dontFlip:n=!1}={}){return new PageViewport({viewBox:this.view,scale:t,rotation:e,offsetX:i,offsetY:s,dontFlip:n})}getAnnotations({intent:t="display"}={}){const{renderingIntent:e}=this._transport.getRenderingIntent(t);return this._transport.getAnnotations(this._pageIndex,e)}getJSActions(){return this._transport.getPageJSActions(this._pageIndex)}get filterFactory(){return this._transport.filterFactory}get isPureXfa(){return shadow(this,"isPureXfa",!!this._transport._htmlForXfa)}async getXfa(){return this._transport._htmlForXfa?.children[this._pageIndex]||null}render({canvasContext:t,viewport:e,intent:i="display",annotationMode:s=u.ENABLE,transform:n=null,background:a=null,optionalContentConfigPromise:r=null,annotationCanvasMap:h=null,pageColors:l=null,printAnnotationStorage:d=null}){this._stats?.time("Overall");const c=this._transport.getRenderingIntent(i,s,d),{renderingIntent:p,cacheKey:g}=c;this.#Ii=!1;this.#Li();r||=this._transport.getOptionalContentConfig(p);let m=this._intentStates.get(g);if(!m){m=Object.create(null);this._intentStates.set(g,m)}if(m.streamReaderCancelTimeout){clearTimeout(m.streamReaderCancelTimeout);m.streamReaderCancelTimeout=null}const f=!!(p&o);if(!m.displayReadyCapability){m.displayReadyCapability=Promise.withResolvers();m.operatorList={fnArray:[],argsArray:[],lastChunk:!1,separateAnnots:null};this._stats?.time("Page Request");this._pumpOperatorList(c)}const complete=t=>{m.renderTasks.delete(b);(this._maybeCleanupAfterRender||f)&&(this.#Ii=!0);this.#Oi(!f);if(t){b.capability.reject(t);this._abortOperatorList({intentState:m,reason:t instanceof Error?t:new Error(t)})}else b.capability.resolve();if(this._stats){this._stats.timeEnd("Rendering");this._stats.timeEnd("Overall");globalThis.Stats?.enabled&&globalThis.Stats.add(this.pageNumber,this._stats)}},b=new InternalRenderTask({callback:complete,params:{canvasContext:t,viewport:e,transform:n,background:a},objs:this.objs,commonObjs:this.commonObjs,annotationCanvasMap:h,operatorList:m.operatorList,pageIndex:this._pageIndex,canvasFactory:this._transport.canvasFactory,filterFactory:this._transport.filterFactory,useRequestAnimationFrame:!f,pdfBug:this._pdfBug,pageColors:l});(m.renderTasks||=new Set).add(b);const v=b.task;Promise.all([m.displayReadyCapability.promise,r]).then((([t,e])=>{if(this.destroyed)complete();else{this._stats?.time("Rendering");if(!(e.renderingIntent&p))throw new Error("Must use the same `intent`-argument when calling the `PDFPageProxy.render` and `PDFDocumentProxy.getOptionalContentConfig` methods.");b.initializeGraphics({transparency:t,optionalContentConfig:e});b.operatorListChanged()}})).catch(complete);return v}getOperatorList({intent:t="display",annotationMode:e=u.ENABLE,printAnnotationStorage:i=null}={}){const s=this._transport.getRenderingIntent(t,e,i,!0);let n,a=this._intentStates.get(s.cacheKey);if(!a){a=Object.create(null);this._intentStates.set(s.cacheKey,a)}if(!a.opListReadCapability){n=Object.create(null);n.operatorListChanged=function operatorListChanged(){if(a.operatorList.lastChunk){a.opListReadCapability.resolve(a.operatorList);a.renderTasks.delete(n)}};a.opListReadCapability=Promise.withResolvers();(a.renderTasks||=new Set).add(n);a.operatorList={fnArray:[],argsArray:[],lastChunk:!1,separateAnnots:null};this._stats?.time("Page Request");this._pumpOperatorList(s)}return a.opListReadCapability.promise}streamTextContent({includeMarkedContent:t=!1,disableNormalization:e=!1}={}){return this._transport.messageHandler.sendWithStream("GetTextContent",{pageIndex:this._pageIndex,includeMarkedContent:!0===t,disableNormalization:!0===e},{highWaterMark:100,size:t=>t.items.length})}getTextContent(t={}){if(this._transport._htmlForXfa)return this.getXfa().then((t=>XfaText.textContent(t)));const e=this.streamTextContent(t);return new Promise((function(t,i){const s=e.getReader(),n={items:[],styles:Object.create(null),lang:null};!function pump(){s.read().then((function({value:e,done:i}){if(i)t(n);else{n.lang??=e.lang;Object.assign(n.styles,e.styles);n.items.push(...e.items);pump()}}),i)}()}))}getStructTree(){return this._transport.getStructTree(this._pageIndex)}_destroy(){this.destroyed=!0;const t=[];for(const e of this._intentStates.values()){this._abortOperatorList({intentState:e,reason:new Error("Page was destroyed."),force:!0});if(!e.opListReadCapability)for(const i of e.renderTasks){t.push(i.completed);i.cancel()}}this.objs.clear();this.#Ii=!1;this.#Li();return Promise.all(t)}cleanup(t=!1){this.#Ii=!0;const e=this.#Oi(!1);t&&e&&(this._stats&&=new StatTimer);return e}#Oi(t=!1){this.#Li();if(!this.#Ii||this.destroyed)return!1;if(t){this.#Fi=setTimeout((()=>{this.#Fi=null;this.#Oi(!1)}),5e3);return!1}for(const{renderTasks:t,operatorList:e}of this._intentStates.values())if(t.size>0||!e.lastChunk)return!1;this._intentStates.clear();this.objs.clear();this.#Ii=!1;return!0}#Li(){if(this.#Fi){clearTimeout(this.#Fi);this.#Fi=null}}_startRenderPage(t,e){const i=this._intentStates.get(e);if(i){this._stats?.timeEnd("Page Request");i.displayReadyCapability?.resolve(t)}}_renderPageChunk(t,e){for(let i=0,s=t.length;i<s;i++){e.operatorList.fnArray.push(t.fnArray[i]);e.operatorList.argsArray.push(t.argsArray[i])}e.operatorList.lastChunk=t.lastChunk;e.operatorList.separateAnnots=t.separateAnnots;for(const t of e.renderTasks)t.operatorListChanged();t.lastChunk&&this.#Oi(!0)}_pumpOperatorList({renderingIntent:t,cacheKey:e,annotationStorageSerializable:i}){const{map:s,transfer:n}=i,a=this._transport.messageHandler.sendWithStream("GetOperatorList",{pageIndex:this._pageIndex,intent:t,cacheKey:e,annotationStorage:s},n).getReader(),r=this._intentStates.get(e);r.streamReader=a;const pump=()=>{a.read().then((({value:t,done:e})=>{if(e)r.streamReader=null;else if(!this._transport.destroyed){this._renderPageChunk(t,r);pump()}}),(t=>{r.streamReader=null;if(!this._transport.destroyed){if(r.operatorList){r.operatorList.lastChunk=!0;for(const t of r.renderTasks)t.operatorListChanged();this.#Oi(!0)}if(r.displayReadyCapability)r.displayReadyCapability.reject(t);else{if(!r.opListReadCapability)throw t;r.opListReadCapability.reject(t)}}}))};pump()}_abortOperatorList({intentState:t,reason:e,force:i=!1}){if(t.streamReader){if(t.streamReaderCancelTimeout){clearTimeout(t.streamReaderCancelTimeout);t.streamReaderCancelTimeout=null}if(!i){if(t.renderTasks.size>0)return;if(e instanceof RenderingCancelledException){let i=100;e.extraDelay>0&&e.extraDelay<1e3&&(i+=e.extraDelay);t.streamReaderCancelTimeout=setTimeout((()=>{t.streamReaderCancelTimeout=null;this._abortOperatorList({intentState:t,reason:e,force:!0})}),i);return}}t.streamReader.cancel(new AbortException(e.message)).catch((()=>{}));t.streamReader=null;if(!this._transport.destroyed){for(const[e,i]of this._intentStates)if(i===t){this._intentStates.delete(e);break}this.cleanup()}}}get stats(){return this._stats}}class LoopbackPort{#Ni=new Set;#Bi=Promise.resolve();postMessage(t,e){const i={data:structuredClone(t,e?{transfer:e}:null)};this.#Bi.then((()=>{for(const t of this.#Ni)t.call(this,i)}))}addEventListener(t,e){this.#Ni.add(e)}removeEventListener(t,e){this.#Ni.delete(e)}terminate(){this.#Ni.clear()}}const qt={isWorkerDisabled:!1,fakeWorkerId:0};if(e){qt.isWorkerDisabled=!0;GlobalWorkerOptions.workerSrc||="./pdf.worker.mjs"}qt.isSameOrigin=function(t,e){let i;try{i=new URL(t);if(!i.origin||"null"===i.origin)return!1}catch{return!1}const s=new URL(e,i);return i.origin===s.origin};qt.createCDNWrapper=function(t){const e=`await import("${t}");`;return URL.createObjectURL(new Blob([e],{type:"text/javascript"}))};class PDFWorker{static#Hi;constructor({name:t=null,port:e=null,verbosity:i=getVerbosityLevel()}={}){this.name=t;this.destroyed=!1;this.verbosity=i;this._readyCapability=Promise.withResolvers();this._port=null;this._webWorker=null;this._messageHandler=null;if(e){if(PDFWorker.#Hi?.has(e))throw new Error("Cannot use more than one PDFWorker per port.");(PDFWorker.#Hi||=new WeakMap).set(e,this);this._initializeFromPort(e)}else this._initialize()}get promise(){return e?Promise.all([NodePackages.promise,this._readyCapability.promise]):this._readyCapability.promise}get port(){return this._port}get messageHandler(){return this._messageHandler}_initializeFromPort(t){this._port=t;this._messageHandler=new MessageHandler("main","worker",t);this._messageHandler.on("ready",(function(){}));this._readyCapability.resolve();this._messageHandler.send("configure",{verbosity:this.verbosity})}_initialize(){if(!qt.isWorkerDisabled&&!PDFWorker.#zi){let{workerSrc:t}=PDFWorker;try{qt.isSameOrigin(window.location.href,t)||(t=qt.createCDNWrapper(new URL(t,window.location).href));const e=new Worker(t,{type:"module"}),i=new MessageHandler("main","worker",e),terminateEarly=()=>{e.removeEventListener("error",onWorkerError);i.destroy();e.terminate();this.destroyed?this._readyCapability.reject(new Error("Worker was destroyed")):this._setupFakeWorker()},onWorkerError=()=>{this._webWorker||terminateEarly()};e.addEventListener("error",onWorkerError);i.on("test",(t=>{e.removeEventListener("error",onWorkerError);if(this.destroyed)terminateEarly();else if(t){this._messageHandler=i;this._port=e;this._webWorker=e;this._readyCapability.resolve();i.send("configure",{verbosity:this.verbosity})}else{this._setupFakeWorker();i.destroy();e.terminate()}}));i.on("ready",(t=>{e.removeEventListener("error",onWorkerError);if(this.destroyed)terminateEarly();else try{sendTest()}catch{this._setupFakeWorker()}}));const sendTest=()=>{const t=new Uint8Array;i.send("test",t,[t.buffer])};sendTest();return}catch{info("The worker has been disabled.")}}this._setupFakeWorker()}_setupFakeWorker(){if(!qt.isWorkerDisabled){warn("Setting up fake worker.");qt.isWorkerDisabled=!0}PDFWorker._setupFakeWorkerGlobal.then((t=>{if(this.destroyed){this._readyCapability.reject(new Error("Worker was destroyed"));return}const e=new LoopbackPort;this._port=e;const i="fake"+qt.fakeWorkerId++,s=new MessageHandler(i+"_worker",i,e);t.setup(s,e);const n=new MessageHandler(i,i+"_worker",e);this._messageHandler=n;this._readyCapability.resolve();n.send("configure",{verbosity:this.verbosity})})).catch((t=>{this._readyCapability.reject(new Error(`Setting up fake worker failed: "${t.message}".`))}))}destroy(){this.destroyed=!0;if(this._webWorker){this._webWorker.terminate();this._webWorker=null}PDFWorker.#Hi?.delete(this._port);this._port=null;if(this._messageHandler){this._messageHandler.destroy();this._messageHandler=null}}static fromPort(t){if(!t?.port)throw new Error("PDFWorker.fromPort - invalid method signature.");const e=this.#Hi?.get(t.port);if(e){if(e._pendingDestroy)throw new Error("PDFWorker.fromPort - the worker is being destroyed.\nPlease remember to await `PDFDocumentLoadingTask.destroy()`-calls.");return e}return new PDFWorker(t)}static get workerSrc(){if(GlobalWorkerOptions.workerSrc)return GlobalWorkerOptions.workerSrc;throw new Error('No "GlobalWorkerOptions.workerSrc" specified.')}static get#zi(){try{return globalThis.pdfjsWorker?.WorkerMessageHandler||null}catch{return null}}static get _setupFakeWorkerGlobal(){return shadow(this,"_setupFakeWorkerGlobal",(async()=>{if(this.#zi)return this.#zi;return(await import(this.workerSrc)).WorkerMessageHandler})())}}class WorkerTransport{#Ui=new Map;#ji=new Map;#$i=new Map;#Vi=new Map;#Gi=null;constructor(t,e,i,s,n){this.messageHandler=t;this.loadingTask=e;this.commonObjs=new PDFObjects;this.fontLoader=new FontLoader({ownerDocument:s.ownerDocument,styleElement:s.styleElement});this.loadingParams=s.loadingParams;this._params=s;this.canvasFactory=n.canvasFactory;this.filterFactory=n.filterFactory;this.cMapReaderFactory=n.cMapReaderFactory;this.standardFontDataFactory=n.standardFontDataFactory;this.destroyed=!1;this.destroyCapability=null;this._networkStream=i;this._fullReader=null;this._lastProgress=null;this.downloadInfoCapability=Promise.withResolvers();this.setupMessageHandler()}#Wi(t,e=null){const i=this.#Ui.get(t);if(i)return i;const s=this.messageHandler.sendWithPromise(t,e);this.#Ui.set(t,s);return s}get annotationStorage(){return shadow(this,"annotationStorage",new AnnotationStorage)}getRenderingIntent(t,e=u.ENABLE,i=null,s=!1){let n=r,p=ft;switch(t){case"any":n=a;break;case"display":break;case"print":n=o;break;default:warn(`getRenderingIntent - invalid intent: ${t}`)}switch(e){case u.DISABLE:n+=d;break;case u.ENABLE:break;case u.ENABLE_FORMS:n+=h;break;case u.ENABLE_STORAGE:n+=l;p=(n&o&&i instanceof PrintAnnotationStorage?i:this.annotationStorage).serializable;break;default:warn(`getRenderingIntent - invalid annotationMode: ${e}`)}s&&(n+=c);return{renderingIntent:n,cacheKey:`${n}_${p.hash}`,annotationStorageSerializable:p}}destroy(){if(this.destroyCapability)return this.destroyCapability.promise;this.destroyed=!0;this.destroyCapability=Promise.withResolvers();this.#Gi?.reject(new Error("Worker was destroyed during onPassword callback"));const t=[];for(const e of this.#ji.values())t.push(e._destroy());this.#ji.clear();this.#$i.clear();this.#Vi.clear();this.hasOwnProperty("annotationStorage")&&this.annotationStorage.resetModified();const e=this.messageHandler.sendWithPromise("Terminate",null);t.push(e);Promise.all(t).then((()=>{this.commonObjs.clear();this.fontLoader.clear();this.#Ui.clear();this.filterFactory.destroy();TextLayer.cleanup();this._networkStream?.cancelAllRequests(new AbortException("Worker was terminated."));if(this.messageHandler){this.messageHandler.destroy();this.messageHandler=null}this.destroyCapability.resolve()}),this.destroyCapability.reject);return this.destroyCapability.promise}setupMessageHandler(){const{messageHandler:t,loadingTask:e}=this;t.on("GetReader",((t,e)=>{assert(this._networkStream,"GetReader - no `IPDFStream` instance available.");this._fullReader=this._networkStream.getFullReader();this._fullReader.onProgress=t=>{this._lastProgress={loaded:t.loaded,total:t.total}};e.onPull=()=>{this._fullReader.read().then((function({value:t,done:i}){if(i)e.close();else{assert(t instanceof ArrayBuffer,"GetReader - expected an ArrayBuffer.");e.enqueue(new Uint8Array(t),1,[t])}})).catch((t=>{e.error(t)}))};e.onCancel=t=>{this._fullReader.cancel(t);e.ready.catch((t=>{if(!this.destroyed)throw t}))}}));t.on("ReaderHeadersReady",(t=>{const i=Promise.withResolvers(),s=this._fullReader;s.headersReady.then((()=>{if(!s.isStreamingSupported||!s.isRangeSupported){this._lastProgress&&e.onProgress?.(this._lastProgress);s.onProgress=t=>{e.onProgress?.({loaded:t.loaded,total:t.total})}}i.resolve({isStreamingSupported:s.isStreamingSupported,isRangeSupported:s.isRangeSupported,contentLength:s.contentLength})}),i.reject);return i.promise}));t.on("GetRangeReader",((t,e)=>{assert(this._networkStream,"GetRangeReader - no `IPDFStream` instance available.");const i=this._networkStream.getRangeReader(t.begin,t.end);if(i){e.onPull=()=>{i.read().then((function({value:t,done:i}){if(i)e.close();else{assert(t instanceof ArrayBuffer,"GetRangeReader - expected an ArrayBuffer.");e.enqueue(new Uint8Array(t),1,[t])}})).catch((t=>{e.error(t)}))};e.onCancel=t=>{i.cancel(t);e.ready.catch((t=>{if(!this.destroyed)throw t}))}}else e.close()}));t.on("GetDoc",(({pdfInfo:t})=>{this._numPages=t.numPages;this._htmlForXfa=t.htmlForXfa;delete t.htmlForXfa;e._capability.resolve(new PDFDocumentProxy(t,this))}));t.on("DocException",(function(t){let i;switch(t.name){case"PasswordException":i=new PasswordException(t.message,t.code);break;case"InvalidPDFException":i=new InvalidPDFException(t.message);break;case"MissingPDFException":i=new MissingPDFException(t.message);break;case"UnexpectedResponseException":i=new UnexpectedResponseException(t.message,t.status);break;case"UnknownErrorException":i=new UnknownErrorException(t.message,t.details);break;default:unreachable("DocException - expected a valid Error.")}e._capability.reject(i)}));t.on("PasswordRequest",(t=>{this.#Gi=Promise.withResolvers();if(e.onPassword){const updatePassword=t=>{t instanceof Error?this.#Gi.reject(t):this.#Gi.resolve({password:t})};try{e.onPassword(updatePassword,t.code)}catch(t){this.#Gi.reject(t)}}else this.#Gi.reject(new PasswordException(t.message,t.code));return this.#Gi.promise}));t.on("DataLoaded",(t=>{e.onProgress?.({loaded:t.length,total:t.length});this.downloadInfoCapability.resolve(t)}));t.on("StartRenderPage",(t=>{if(this.destroyed)return;this.#ji.get(t.pageIndex)._startRenderPage(t.transparency,t.cacheKey)}));t.on("commonobj",(([e,i,s])=>{if(this.destroyed)return null;if(this.commonObjs.has(e))return null;switch(i){case"Font":const{disableFontFace:n,fontExtraProperties:a,pdfBug:r}=this._params;if("error"in s){const t=s.error;warn(`Error during font loading: ${t}`);this.commonObjs.resolve(e,t);break}const o=r&&globalThis.FontInspector?.enabled?(t,e)=>globalThis.FontInspector.fontAdded(t,e):null,h=new FontFaceObject(s,{disableFontFace:n,inspectFont:o});this.fontLoader.bind(h).catch((()=>t.sendWithPromise("FontFallback",{id:e}))).finally((()=>{!a&&h.data&&(h.data=null);this.commonObjs.resolve(e,h)}));break;case"CopyLocalImage":const{imageRef:l}=s;assert(l,"The imageRef must be defined.");for(const t of this.#ji.values())for(const[,i]of t.objs)if(i?.ref===l){if(!i.dataLen)return null;this.commonObjs.resolve(e,structuredClone(i));return i.dataLen}break;case"FontPath":case"Image":case"Pattern":this.commonObjs.resolve(e,s);break;default:throw new Error(`Got unknown common object type ${i}`)}return null}));t.on("obj",(([t,e,i,s])=>{if(this.destroyed)return;const n=this.#ji.get(e);if(!n.objs.has(t))if(0!==n._intentStates.size)switch(i){case"Image":n.objs.resolve(t,s);s?.dataLen>1e7&&(n._maybeCleanupAfterRender=!0);break;case"Pattern":n.objs.resolve(t,s);break;default:throw new Error(`Got unknown object type ${i}`)}else s?.bitmap?.close()}));t.on("DocProgress",(t=>{this.destroyed||e.onProgress?.({loaded:t.loaded,total:t.total})}));t.on("FetchBuiltInCMap",(t=>this.destroyed?Promise.reject(new Error("Worker was destroyed.")):this.cMapReaderFactory?this.cMapReaderFactory.fetch(t):Promise.reject(new Error("CMapReaderFactory not initialized, see the `useWorkerFetch` parameter."))));t.on("FetchStandardFontData",(t=>this.destroyed?Promise.reject(new Error("Worker was destroyed.")):this.standardFontDataFactory?this.standardFontDataFactory.fetch(t):Promise.reject(new Error("StandardFontDataFactory not initialized, see the `useWorkerFetch` parameter."))))}getData(){return this.messageHandler.sendWithPromise("GetData",null)}saveDocument(){this.annotationStorage.size<=0&&warn("saveDocument called while `annotationStorage` is empty, please use the getData-method instead.");const{map:t,transfer:e}=this.annotationStorage.serializable;return this.messageHandler.sendWithPromise("SaveDocument",{isPureXfa:!!this._htmlForXfa,numPages:this._numPages,annotationStorage:t,filename:this._fullReader?.filename??null},e).finally((()=>{this.annotationStorage.resetModified()}))}getPage(t){if(!Number.isInteger(t)||t<=0||t>this._numPages)return Promise.reject(new Error("Invalid page request."));const e=t-1,i=this.#$i.get(e);if(i)return i;const s=this.messageHandler.sendWithPromise("GetPage",{pageIndex:e}).then((i=>{if(this.destroyed)throw new Error("Transport destroyed");i.refStr&&this.#Vi.set(i.refStr,t);const s=new PDFPageProxy(e,i,this,this._params.pdfBug);this.#ji.set(e,s);return s}));this.#$i.set(e,s);return s}getPageIndex(t){return isRefProxy(t)?this.messageHandler.sendWithPromise("GetPageIndex",{num:t.num,gen:t.gen}):Promise.reject(new Error("Invalid pageIndex request."))}getAnnotations(t,e){return this.messageHandler.sendWithPromise("GetAnnotations",{pageIndex:t,intent:e})}getFieldObjects(){return this.#Wi("GetFieldObjects")}hasJSActions(){return this.#Wi("HasJSActions")}getCalculationOrderIds(){return this.messageHandler.sendWithPromise("GetCalculationOrderIds",null)}getDestinations(){return this.messageHandler.sendWithPromise("GetDestinations",null)}getDestination(t){return"string"!=typeof t?Promise.reject(new Error("Invalid destination request.")):this.messageHandler.sendWithPromise("GetDestination",{id:t})}getPageLabels(){return this.messageHandler.sendWithPromise("GetPageLabels",null)}getPageLayout(){return this.messageHandler.sendWithPromise("GetPageLayout",null)}getPageMode(){return this.messageHandler.sendWithPromise("GetPageMode",null)}getViewerPreferences(){return this.messageHandler.sendWithPromise("GetViewerPreferences",null)}getOpenAction(){return this.messageHandler.sendWithPromise("GetOpenAction",null)}getAttachments(){return this.messageHandler.sendWithPromise("GetAttachments",null)}getDocJSActions(){return this.#Wi("GetDocJSActions")}getPageJSActions(t){return this.messageHandler.sendWithPromise("GetPageJSActions",{pageIndex:t})}getStructTree(t){return this.messageHandler.sendWithPromise("GetStructTree",{pageIndex:t})}getOutline(){return this.messageHandler.sendWithPromise("GetOutline",null)}getOptionalContentConfig(t){return this.#Wi("GetOptionalContentConfig").then((e=>new OptionalContentConfig(e,t)))}getPermissions(){return this.messageHandler.sendWithPromise("GetPermissions",null)}getMetadata(){const t="GetMetadata",e=this.#Ui.get(t);if(e)return e;const i=this.messageHandler.sendWithPromise(t,null).then((t=>({info:t[0],metadata:t[1]?new Metadata(t[1]):null,contentDispositionFilename:this._fullReader?.filename??null,contentLength:this._fullReader?.contentLength??null})));this.#Ui.set(t,i);return i}getMarkInfo(){return this.messageHandler.sendWithPromise("GetMarkInfo",null)}async startCleanup(t=!1){if(!this.destroyed){await this.messageHandler.sendWithPromise("Cleanup",null);for(const t of this.#ji.values()){if(!t.cleanup())throw new Error(`startCleanup: Page ${t.pageNumber} is currently rendering.`)}this.commonObjs.clear();t||this.fontLoader.clear();this.#Ui.clear();this.filterFactory.destroy(!0);TextLayer.cleanup()}}cachedPageNumber(t){if(!isRefProxy(t))return null;const e=0===t.gen?`${t.num}R`:`${t.num}R${t.gen}`;return this.#Vi.get(e)??null}}const Xt=Symbol("INITIAL_DATA");class PDFObjects{#qi=Object.create(null);#Xi(t){return this.#qi[t]||={...Promise.withResolvers(),data:Xt}}get(t,e=null){if(e){const i=this.#Xi(t);i.promise.then((()=>e(i.data)));return null}const i=this.#qi[t];if(!i||i.data===Xt)throw new Error(`Requesting object that isn't resolved yet ${t}.`);return i.data}has(t){const e=this.#qi[t];return!!e&&e.data!==Xt}resolve(t,e=null){const i=this.#Xi(t);i.data=e;i.resolve()}clear(){for(const t in this.#qi){const{data:e}=this.#qi[t];e?.bitmap?.close()}this.#qi=Object.create(null)}*[Symbol.iterator](){for(const t in this.#qi){const{data:e}=this.#qi[t];e!==Xt&&(yield[t,e])}}}class RenderTask{#Ki=null;constructor(t){this.#Ki=t;this.onContinue=null}get promise(){return this.#Ki.capability.promise}cancel(t=0){this.#Ki.cancel(null,t)}get separateAnnots(){const{separateAnnots:t}=this.#Ki.operatorList;if(!t)return!1;const{annotationCanvasMap:e}=this.#Ki;return t.form||t.canvas&&e?.size>0}}class InternalRenderTask{static#Yi=new WeakSet;constructor({callback:t,params:e,objs:i,commonObjs:s,annotationCanvasMap:n,operatorList:a,pageIndex:r,canvasFactory:o,filterFactory:h,useRequestAnimationFrame:l=!1,pdfBug:d=!1,pageColors:c=null}){this.callback=t;this.params=e;this.objs=i;this.commonObjs=s;this.annotationCanvasMap=n;this.operatorListIdx=null;this.operatorList=a;this._pageIndex=r;this.canvasFactory=o;this.filterFactory=h;this._pdfBug=d;this.pageColors=c;this.running=!1;this.graphicsReadyCallback=null;this.graphicsReady=!1;this._useRequestAnimationFrame=!0===l&&"undefined"!=typeof window;this.cancelled=!1;this.capability=Promise.withResolvers();this.task=new RenderTask(this);this._cancelBound=this.cancel.bind(this);this._continueBound=this._continue.bind(this);this._scheduleNextBound=this._scheduleNext.bind(this);this._nextBound=this._next.bind(this);this._canvas=e.canvasContext.canvas}get completed(){return this.capability.promise.catch((function(){}))}initializeGraphics({transparency:t=!1,optionalContentConfig:e}){if(this.cancelled)return;if(this._canvas){if(InternalRenderTask.#Yi.has(this._canvas))throw new Error("Cannot use the same canvas during multiple render() operations. Use different canvas or ensure previous operations were cancelled or completed.");InternalRenderTask.#Yi.add(this._canvas)}if(this._pdfBug&&globalThis.StepperManager?.enabled){this.stepper=globalThis.StepperManager.create(this._pageIndex);this.stepper.init(this.operatorList);this.stepper.nextBreakPoint=this.stepper.getNextBreakPoint()}const{canvasContext:i,viewport:s,transform:n,background:a}=this.params;this.gfx=new CanvasGraphics(i,this.commonObjs,this.objs,this.canvasFactory,this.filterFactory,{optionalContentConfig:e},this.annotationCanvasMap,this.pageColors);this.gfx.beginDrawing({transform:n,viewport:s,transparency:t,background:a});this.operatorListIdx=0;this.graphicsReady=!0;this.graphicsReadyCallback?.()}cancel(t=null,e=0){this.running=!1;this.cancelled=!0;this.gfx?.endDrawing();InternalRenderTask.#Yi.delete(this._canvas);this.callback(t||new RenderingCancelledException(`Rendering cancelled, page ${this._pageIndex+1}`,e))}operatorListChanged(){if(this.graphicsReady){this.stepper?.updateOperatorList(this.operatorList);this.running||this._continue()}else this.graphicsReadyCallback||=this._continueBound}_continue(){this.running=!0;this.cancelled||(this.task.onContinue?this.task.onContinue(this._scheduleNextBound):this._scheduleNext())}_scheduleNext(){this._useRequestAnimationFrame?window.requestAnimationFrame((()=>{this._nextBound().catch(this._cancelBound)})):Promise.resolve().then(this._nextBound).catch(this._cancelBound)}async _next(){if(!this.cancelled){this.operatorListIdx=this.gfx.executeOperatorList(this.operatorList,this.operatorListIdx,this._continueBound,this.stepper);if(this.operatorListIdx===this.operatorList.argsArray.length){this.running=!1;if(this.operatorList.lastChunk){this.gfx.endDrawing();InternalRenderTask.#Yi.delete(this._canvas);this.callback()}}}}}const Kt="4.3.136",Yt="0cec64437";function makeColorComp(t){return Math.floor(255*Math.max(0,Math.min(1,t))).toString(16).padStart(2,"0")}function scaleAndClamp(t){return Math.max(0,Math.min(255,255*t))}class ColorConverters{static CMYK_G([t,e,i,s]){return["G",1-Math.min(1,.3*t+.59*i+.11*e+s)]}static G_CMYK([t]){return["CMYK",0,0,0,1-t]}static G_RGB([t]){return["RGB",t,t,t]}static G_rgb([t]){return[t=scaleAndClamp(t),t,t]}static G_HTML([t]){const e=makeColorComp(t);return`#${e}${e}${e}`}static RGB_G([t,e,i]){return["G",.3*t+.59*e+.11*i]}static RGB_rgb(t){return t.map(scaleAndClamp)}static RGB_HTML(t){return`#${t.map(makeColorComp).join("")}`}static T_HTML(){return"#00000000"}static T_rgb(){return[null]}static CMYK_RGB([t,e,i,s]){return["RGB",1-Math.min(1,t+s),1-Math.min(1,i+s),1-Math.min(1,e+s)]}static CMYK_rgb([t,e,i,s]){return[scaleAndClamp(1-Math.min(1,t+s)),scaleAndClamp(1-Math.min(1,i+s)),scaleAndClamp(1-Math.min(1,e+s))]}static CMYK_HTML(t){const e=this.CMYK_RGB(t).slice(1);return this.RGB_HTML(e)}static RGB_CMYK([t,e,i]){const s=1-t,n=1-e,a=1-i;return["CMYK",s,n,a,Math.min(s,n,a)]}}class XfaLayer{static setupStorage(t,e,i,s,n){const a=s.getValue(e,{value:null});switch(i.name){case"textarea":null!==a.value&&(t.textContent=a.value);if("print"===n)break;t.addEventListener("input",(t=>{s.setValue(e,{value:t.target.value})}));break;case"input":if("radio"===i.attributes.type||"checkbox"===i.attributes.type){a.value===i.attributes.xfaOn?t.setAttribute("checked",!0):a.value===i.attributes.xfaOff&&t.removeAttribute("checked");if("print"===n)break;t.addEventListener("change",(t=>{s.setValue(e,{value:t.target.checked?t.target.getAttribute("xfaOn"):t.target.getAttribute("xfaOff")})}))}else{null!==a.value&&t.setAttribute("value",a.value);if("print"===n)break;t.addEventListener("input",(t=>{s.setValue(e,{value:t.target.value})}))}break;case"select":if(null!==a.value){t.setAttribute("value",a.value);for(const t of i.children)t.attributes.value===a.value?t.attributes.selected=!0:t.attributes.hasOwnProperty("selected")&&delete t.attributes.selected}t.addEventListener("input",(t=>{const i=t.target.options,n=-1===i.selectedIndex?"":i[i.selectedIndex].value;s.setValue(e,{value:n})}))}}static setAttributes({html:t,element:e,storage:i=null,intent:s,linkService:n}){const{attributes:a}=e,r=t instanceof HTMLAnchorElement;"radio"===a.type&&(a.name=`${a.name}-${s}`);for(const[e,i]of Object.entries(a))if(null!=i)switch(e){case"class":i.length&&t.setAttribute(e,i.join(" "));break;case"dataId":break;case"id":t.setAttribute("data-element-id",i);break;case"style":Object.assign(t.style,i);break;case"textContent":t.textContent=i;break;default:(!r||"href"!==e&&"newWindow"!==e)&&t.setAttribute(e,i)}r&&n.addLinkAttributes(t,a.href,a.newWindow);i&&a.dataId&&this.setupStorage(t,a.dataId,e,i)}static render(t){const e=t.annotationStorage,i=t.linkService,s=t.xfaHtml,n=t.intent||"display",a=document.createElement(s.name);s.attributes&&this.setAttributes({html:a,element:s,intent:n,linkService:i});const r="richText"!==n,o=t.div;o.append(a);if(t.viewport){const e=`matrix(${t.viewport.transform.join(",")})`;o.style.transform=e}r&&o.setAttribute("class","xfaLayer xfaFont");const h=[];if(0===s.children.length){if(s.value){const t=document.createTextNode(s.value);a.append(t);r&&XfaText.shouldBuildText(s.name)&&h.push(t)}return{textDivs:h}}const l=[[s,-1,a]];for(;l.length>0;){const[t,s,a]=l.at(-1);if(s+1===t.children.length){l.pop();continue}const o=t.children[++l.at(-1)[1]];if(null===o)continue;const{name:d}=o;if("#text"===d){const t=document.createTextNode(o.value);h.push(t);a.append(t);continue}const c=o?.attributes?.xmlns?document.createElementNS(o.attributes.xmlns,d):document.createElement(d);a.append(c);o.attributes&&this.setAttributes({html:c,element:o,storage:e,intent:n,linkService:i});if(o.children?.length>0)l.push([o,-1,c]);else if(o.value){const t=document.createTextNode(o.value);r&&XfaText.shouldBuildText(d)&&h.push(t);c.append(t)}}for(const t of o.querySelectorAll(".xfaNonInteractive input, .xfaNonInteractive textarea"))t.setAttribute("readOnly",!0);return{textDivs:h}}static update(t){const e=`matrix(${t.viewport.transform.join(",")})`;t.div.style.transform=e;t.div.hidden=!1}}const Qt=1e3,Jt=new WeakSet;function getRectDims(t){return{width:t[2]-t[0],height:t[3]-t[1]}}class AnnotationElementFactory{static create(t){switch(t.data.annotationType){case _:return new LinkAnnotationElement(t);case E:return new TextAnnotationElement(t);case z:switch(t.data.fieldType){case"Tx":return new TextWidgetAnnotationElement(t);case"Btn":return t.data.radioButton?new RadioButtonWidgetAnnotationElement(t):t.data.checkBox?new CheckboxWidgetAnnotationElement(t):new PushButtonWidgetAnnotationElement(t);case"Ch":return new ChoiceWidgetAnnotationElement(t);case"Sig":return new SignatureWidgetAnnotationElement(t)}return new WidgetAnnotationElement(t);case B:return new PopupAnnotationElement(t);case C:return new FreeTextAnnotationElement(t);case S:return new LineAnnotationElement(t);case T:return new SquareAnnotationElement(t);case M:return new CircleAnnotationElement(t);case P:return new PolylineAnnotationElement(t);case O:return new CaretAnnotationElement(t);case N:return new InkAnnotationElement(t);case k:return new PolygonAnnotationElement(t);case D:return new HighlightAnnotationElement(t);case R:return new UnderlineAnnotationElement(t);case F:return new SquigglyAnnotationElement(t);case I:return new StrikeOutAnnotationElement(t);case L:return new StampAnnotationElement(t);case H:return new FileAttachmentAnnotationElement(t);default:return new AnnotationElement(t)}}}class AnnotationElement{#Qi=null;#Ji=!1;#Zi=null;constructor(t,{isRenderable:e=!1,ignoreBorder:i=!1,createQuadrilaterals:s=!1}={}){this.isRenderable=e;this.data=t.data;this.layer=t.layer;this.linkService=t.linkService;this.downloadManager=t.downloadManager;this.imageResourcesPath=t.imageResourcesPath;this.renderForms=t.renderForms;this.svgFactory=t.svgFactory;this.annotationStorage=t.annotationStorage;this.enableScripting=t.enableScripting;this.hasJSActions=t.hasJSActions;this._fieldObjects=t.fieldObjects;this.parent=t.parent;e&&(this.container=this._createContainer(i));s&&this._createQuadrilaterals()}static _hasPopupData({titleObj:t,contentsObj:e,richText:i}){return!!(t?.str||e?.str||i?.str)}get hasPopupData(){return AnnotationElement._hasPopupData(this.data)}updateEdited(t){if(!this.container)return;this.#Qi||={rect:this.data.rect.slice(0)};const{rect:e}=t;e&&this.#ts(e);this.#Zi?.popup.updateEdited(t)}resetEdited(){if(this.#Qi){this.#ts(this.#Qi.rect);this.#Zi?.popup.resetEdited();this.#Qi=null}}#ts(t){const{container:{style:e},data:{rect:i,rotation:s},parent:{viewport:{rawDims:{pageWidth:n,pageHeight:a,pageX:r,pageY:o}}}}=this;i?.splice(0,4,...t);const{width:h,height:l}=getRectDims(t);e.left=100*(t[0]-r)/n+"%";e.top=100*(a-t[3]+o)/a+"%";if(0===s){e.width=100*h/n+"%";e.height=100*l/a+"%"}else this.setRotation(s)}_createContainer(t){const{data:e,parent:{page:i,viewport:s}}=this,n=document.createElement("section");n.setAttribute("data-annotation-id",e.id);this instanceof WidgetAnnotationElement||(n.tabIndex=Qt);const{style:a}=n;a.zIndex=this.parent.zIndex++;e.popupRef&&n.setAttribute("aria-haspopup","dialog");e.alternativeText&&(n.title=e.alternativeText);e.noRotate&&n.classList.add("norotate");if(!e.rect||this instanceof PopupAnnotationElement){const{rotation:t}=e;e.hasOwnCanvas||0===t||this.setRotation(t,n);return n}const{width:r,height:o}=getRectDims(e.rect);if(!t&&e.borderStyle.width>0){a.borderWidth=`${e.borderStyle.width}px`;const t=e.borderStyle.horizontalCornerRadius,i=e.borderStyle.verticalCornerRadius;if(t>0||i>0){const e=`calc(${t}px * var(--scale-factor)) / calc(${i}px * var(--scale-factor))`;a.borderRadius=e}else if(this instanceof RadioButtonWidgetAnnotationElement){const t=`calc(${r}px * var(--scale-factor)) / calc(${o}px * var(--scale-factor))`;a.borderRadius=t}switch(e.borderStyle.style){case U:a.borderStyle="solid";break;case j:a.borderStyle="dashed";break;case $:warn("Unimplemented border style: beveled");break;case V:warn("Unimplemented border style: inset");break;case G:a.borderBottomStyle="solid"}const s=e.borderColor||null;if(s){this.#Ji=!0;a.borderColor=Util.makeHexColor(0|s[0],0|s[1],0|s[2])}else a.borderWidth=0}const h=Util.normalizeRect([e.rect[0],i.view[3]-e.rect[1]+i.view[1],e.rect[2],i.view[3]-e.rect[3]+i.view[1]]),{pageWidth:l,pageHeight:d,pageX:c,pageY:u}=s.rawDims;a.left=100*(h[0]-c)/l+"%";a.top=100*(h[1]-u)/d+"%";const{rotation:p}=e;if(e.hasOwnCanvas||0===p){a.width=100*r/l+"%";a.height=100*o/d+"%"}else this.setRotation(p,n);return n}setRotation(t,e=this.container){if(!this.data.rect)return;const{pageWidth:i,pageHeight:s}=this.parent.viewport.rawDims,{width:n,height:a}=getRectDims(this.data.rect);let r,o;if(t%180==0){r=100*n/i;o=100*a/s}else{r=100*a/i;o=100*n/s}e.style.width=`${r}%`;e.style.height=`${o}%`;e.setAttribute("data-main-rotation",(360-t)%360)}get _commonActions(){const setColor=(t,e,i)=>{const s=i.detail[t],n=s[0],a=s.slice(1);i.target.style[e]=ColorConverters[`${n}_HTML`](a);this.annotationStorage.setValue(this.data.id,{[e]:ColorConverters[`${n}_rgb`](a)})};return shadow(this,"_commonActions",{display:t=>{const{display:e}=t.detail,i=e%2==1;this.container.style.visibility=i?"hidden":"visible";this.annotationStorage.setValue(this.data.id,{noView:i,noPrint:1===e||2===e})},print:t=>{this.annotationStorage.setValue(this.data.id,{noPrint:!t.detail.print})},hidden:t=>{const{hidden:e}=t.detail;this.container.style.visibility=e?"hidden":"visible";this.annotationStorage.setValue(this.data.id,{noPrint:e,noView:e})},focus:t=>{setTimeout((()=>t.target.focus({preventScroll:!1})),0)},userName:t=>{t.target.title=t.detail.userName},readonly:t=>{t.target.disabled=t.detail.readonly},required:t=>{this._setRequired(t.target,t.detail.required)},bgColor:t=>{setColor("bgColor","backgroundColor",t)},fillColor:t=>{setColor("fillColor","backgroundColor",t)},fgColor:t=>{setColor("fgColor","color",t)},textColor:t=>{setColor("textColor","color",t)},borderColor:t=>{setColor("borderColor","borderColor",t)},strokeColor:t=>{setColor("strokeColor","borderColor",t)},rotation:t=>{const e=t.detail.rotation;this.setRotation(e);this.annotationStorage.setValue(this.data.id,{rotation:e})}})}_dispatchEventFromSandbox(t,e){const i=this._commonActions;for(const s of Object.keys(e.detail)){const n=t[s]||i[s];n?.(e)}}_setDefaultPropertiesFromJS(t){if(!this.enableScripting)return;const e=this.annotationStorage.getRawValue(this.data.id);if(!e)return;const i=this._commonActions;for(const[s,n]of Object.entries(e)){const a=i[s];if(a){a({detail:{[s]:n},target:t});delete e[s]}}}_createQuadrilaterals(){if(!this.container)return;const{quadPoints:t}=this.data;if(!t)return;const[e,i,s,n]=this.data.rect;if(1===t.length){const[,{x:a,y:r},{x:o,y:h}]=t[0];if(s===a&&n===r&&e===o&&i===h)return}const{style:a}=this.container;let r;if(this.#Ji){const{borderColor:t,borderWidth:e}=a;a.borderWidth=0;r=["url('data:image/svg+xml;utf8,",'<svg xmlns="http://www.w3.org/2000/svg"',' preserveAspectRatio="none" viewBox="0 0 1 1">',`<g fill="transparent" stroke="${t}" stroke-width="${e}">`];this.container.classList.add("hasBorder")}const o=s-e,h=n-i,{svgFactory:l}=this,d=l.createElement("svg");d.classList.add("quadrilateralsContainer");d.setAttribute("width",0);d.setAttribute("height",0);const c=l.createElement("defs");d.append(c);const u=l.createElement("clipPath"),p=`clippath_${this.data.id}`;u.setAttribute("id",p);u.setAttribute("clipPathUnits","objectBoundingBox");c.append(u);for(const[,{x:i,y:s},{x:a,y:d}]of t){const t=l.createElement("rect"),c=(a-e)/o,p=(n-s)/h,g=(i-a)/o,m=(s-d)/h;t.setAttribute("x",c);t.setAttribute("y",p);t.setAttribute("width",g);t.setAttribute("height",m);u.append(t);r?.push(`<rect vector-effect="non-scaling-stroke" x="${c}" y="${p}" width="${g}" height="${m}"/>`)}if(this.#Ji){r.push("</g></svg>')");a.backgroundImage=r.join("")}this.container.append(d);this.container.style.clipPath=`url(#${p})`}_createPopup(){const{container:t,data:e}=this;t.setAttribute("aria-haspopup","dialog");const i=this.#Zi=new PopupAnnotationElement({data:{color:e.color,titleObj:e.titleObj,modificationDate:e.modificationDate,contentsObj:e.contentsObj,richText:e.richText,parentRect:e.rect,borderStyle:0,id:`popup_${e.id}`,rotation:e.rotation},parent:this.parent,elements:[this]});this.parent.div.append(i.render())}render(){unreachable("Abstract method `AnnotationElement.render` called")}_getElementsByName(t,e=null){const i=[];if(this._fieldObjects){const s=this._fieldObjects[t];if(s)for(const{page:t,id:n,exportValues:a}of s){if(-1===t)continue;if(n===e)continue;const s="string"==typeof a?a:null,r=document.querySelector(`[data-element-id="${n}"]`);!r||Jt.has(r)?i.push({id:n,exportValue:s,domElement:r}):warn(`_getElementsByName - element not allowed: ${n}`)}return i}for(const s of document.getElementsByName(t)){const{exportValue:t}=s,n=s.getAttribute("data-element-id");n!==e&&(Jt.has(s)&&i.push({id:n,exportValue:t,domElement:s}))}return i}show(){this.container&&(this.container.hidden=!1);this.popup?.maybeShow()}hide(){this.container&&(this.container.hidden=!0);this.popup?.forceHide()}getElementsToTriggerPopup(){return this.container}addHighlightArea(){const t=this.getElementsToTriggerPopup();if(Array.isArray(t))for(const e of t)e.classList.add("highlightArea");else t.classList.add("highlightArea")}get _isEditable(){return!1}_editOnDoubleClick(){if(!this._isEditable)return;const{annotationEditorType:t,data:{id:e}}=this;this.container.addEventListener("dblclick",(()=>{this.linkService.eventBus?.dispatch("switchannotationeditormode",{source:this,mode:t,editId:e})}))}}class LinkAnnotationElement extends AnnotationElement{constructor(t,e=null){super(t,{isRenderable:!0,ignoreBorder:!!e?.ignoreBorder,createQuadrilaterals:!0});this.isTooltipOnly=t.data.isTooltipOnly}render(){const{data:t,linkService:e}=this,i=document.createElement("a");i.setAttribute("data-element-id",t.id);let s=!1;if(t.url){e.addLinkAttributes(i,t.url,t.newWindow);s=!0}else if(t.action){this._bindNamedAction(i,t.action);s=!0}else if(t.attachment){this.#es(i,t.attachment,t.attachmentDest);s=!0}else if(t.setOCGState){this.#is(i,t.setOCGState);s=!0}else if(t.dest){this._bindLink(i,t.dest);s=!0}else{if(t.actions&&(t.actions.Action||t.actions["Mouse Up"]||t.actions["Mouse Down"])&&this.enableScripting&&this.hasJSActions){this._bindJSAction(i,t);s=!0}if(t.resetForm){this._bindResetFormAction(i,t.resetForm);s=!0}else if(this.isTooltipOnly&&!s){this._bindLink(i,"");s=!0}}this.container.classList.add("linkAnnotation");s&&this.container.append(i);return this.container}#ss(){this.container.setAttribute("data-internal-link","")}_bindLink(t,e){t.href=this.linkService.getDestinationHash(e);t.onclick=()=>{e&&this.linkService.goToDestination(e);return!1};(e||""===e)&&this.#ss()}_bindNamedAction(t,e){t.href=this.linkService.getAnchorUrl("");t.onclick=()=>{this.linkService.executeNamedAction(e);return!1};this.#ss()}#es(t,e,i=null){t.href=this.linkService.getAnchorUrl("");e.description&&(t.title=e.description);t.onclick=()=>{this.downloadManager?.openOrDownloadData(e.content,e.filename,i);return!1};this.#ss()}#is(t,e){t.href=this.linkService.getAnchorUrl("");t.onclick=()=>{this.linkService.executeSetOCGState(e);return!1};this.#ss()}_bindJSAction(t,e){t.href=this.linkService.getAnchorUrl("");const i=new Map([["Action","onclick"],["Mouse Up","onmouseup"],["Mouse Down","onmousedown"]]);for(const s of Object.keys(e.actions)){const n=i.get(s);n&&(t[n]=()=>{this.linkService.eventBus?.dispatch("dispatcheventinsandbox",{source:this,detail:{id:e.id,name:s}});return!1})}t.onclick||(t.onclick=()=>!1);this.#ss()}_bindResetFormAction(t,e){const i=t.onclick;i||(t.href=this.linkService.getAnchorUrl(""));this.#ss();if(this._fieldObjects)t.onclick=()=>{i?.();const{fields:t,refs:s,include:n}=e,a=[];if(0!==t.length||0!==s.length){const e=new Set(s);for(const i of t){const t=this._fieldObjects[i]||[];for(const{id:i}of t)e.add(i)}for(const t of Object.values(this._fieldObjects))for(const i of t)e.has(i.id)===n&&a.push(i)}else for(const t of Object.values(this._fieldObjects))a.push(...t);const r=this.annotationStorage,o=[];for(const t of a){const{id:e}=t;o.push(e);switch(t.type){case"text":{const i=t.defaultValue||"";r.setValue(e,{value:i});break}case"checkbox":case"radiobutton":{const i=t.defaultValue===t.exportValues;r.setValue(e,{value:i});break}case"combobox":case"listbox":{const i=t.defaultValue||"";r.setValue(e,{value:i});break}default:continue}const i=document.querySelector(`[data-element-id="${e}"]`);i&&(Jt.has(i)?i.dispatchEvent(new Event("resetform")):warn(`_bindResetFormAction - element not allowed: ${e}`))}this.enableScripting&&this.linkService.eventBus?.dispatch("dispatcheventinsandbox",{source:this,detail:{id:"app",ids:o,name:"ResetForm"}});return!1};else{warn('_bindResetFormAction - "resetForm" action not supported, ensure that the `fieldObjects` parameter is provided.');i||(t.onclick=()=>!1)}}}class TextAnnotationElement extends AnnotationElement{constructor(t){super(t,{isRenderable:!0})}render(){this.container.classList.add("textAnnotation");const t=document.createElement("img");t.src=this.imageResourcesPath+"annotation-"+this.data.name.toLowerCase()+".svg";t.setAttribute("data-l10n-id","pdfjs-text-annotation-type");t.setAttribute("data-l10n-args",JSON.stringify({type:this.data.name}));!this.data.popupRef&&this.hasPopupData&&this._createPopup();this.container.append(t);return this.container}}class WidgetAnnotationElement extends AnnotationElement{render(){return this.container}showElementAndHideCanvas(t){if(this.data.hasOwnCanvas){"CANVAS"===t.previousSibling?.nodeName&&(t.previousSibling.hidden=!0);t.hidden=!1}}_getKeyModifier(t){return util_FeatureTest.platform.isMac?t.metaKey:t.ctrlKey}_setEventListener(t,e,i,s,n){i.includes("mouse")?t.addEventListener(i,(t=>{this.linkService.eventBus?.dispatch("dispatcheventinsandbox",{source:this,detail:{id:this.data.id,name:s,value:n(t),shift:t.shiftKey,modifier:this._getKeyModifier(t)}})})):t.addEventListener(i,(t=>{if("blur"===i){if(!e.focused||!t.relatedTarget)return;e.focused=!1}else if("focus"===i){if(e.focused)return;e.focused=!0}n&&this.linkService.eventBus?.dispatch("dispatcheventinsandbox",{source:this,detail:{id:this.data.id,name:s,value:n(t)}})}))}_setEventListeners(t,e,i,s){for(const[n,a]of i)if("Action"===a||this.data.actions?.[a]){"Focus"!==a&&"Blur"!==a||(e||={focused:!1});this._setEventListener(t,e,n,a,s);"Focus"!==a||this.data.actions?.Blur?"Blur"!==a||this.data.actions?.Focus||this._setEventListener(t,e,"focus","Focus",null):this._setEventListener(t,e,"blur","Blur",null)}}_setBackgroundColor(t){const e=this.data.backgroundColor||null;t.style.backgroundColor=null===e?"transparent":Util.makeHexColor(e[0],e[1],e[2])}_setTextStyle(t){const e=["left","center","right"],{fontColor:i}=this.data.defaultAppearanceData,s=this.data.defaultAppearanceData.fontSize||9,a=t.style;let r;const roundToOneDecimal=t=>Math.round(10*t)/10;if(this.data.multiLine){const t=Math.abs(this.data.rect[3]-this.data.rect[1]-2),e=t/(Math.round(t/(n*s))||1);r=Math.min(s,roundToOneDecimal(e/n))}else{const t=Math.abs(this.data.rect[3]-this.data.rect[1]-2);r=Math.min(s,roundToOneDecimal(t/n))}a.fontSize=`calc(${r}px * var(--scale-factor))`;a.color=Util.makeHexColor(i[0],i[1],i[2]);null!==this.data.textAlignment&&(a.textAlign=e[this.data.textAlignment])}_setRequired(t,e){e?t.setAttribute("required",!0):t.removeAttribute("required");t.setAttribute("aria-required",e)}}class TextWidgetAnnotationElement extends WidgetAnnotationElement{constructor(t){super(t,{isRenderable:t.renderForms||t.data.hasOwnCanvas||!t.data.hasAppearance&&!!t.data.fieldValue})}setPropertyOnSiblings(t,e,i,s){const n=this.annotationStorage;for(const a of this._getElementsByName(t.name,t.id)){a.domElement&&(a.domElement[e]=i);n.setValue(a.id,{[s]:i})}}render(){const t=this.annotationStorage,e=this.data.id;this.container.classList.add("textWidgetAnnotation");let i=null;if(this.renderForms){const s=t.getValue(e,{value:this.data.fieldValue});let n=s.value||"";const a=t.getValue(e,{charLimit:this.data.maxLen}).charLimit;a&&n.length>a&&(n=n.slice(0,a));let r=s.formattedValue||this.data.textContent?.join("\n")||null;r&&this.data.comb&&(r=r.replaceAll(/\s+/g,""));const o={userValue:n,formattedValue:r,lastCommittedValue:null,commitKey:1,focused:!1};if(this.data.multiLine){i=document.createElement("textarea");i.textContent=r??n;this.data.doNotScroll&&(i.style.overflowY="hidden")}else{i=document.createElement("input");i.type="text";i.setAttribute("value",r??n);this.data.doNotScroll&&(i.style.overflowX="hidden")}this.data.hasOwnCanvas&&(i.hidden=!0);Jt.add(i);i.setAttribute("data-element-id",e);i.disabled=this.data.readOnly;i.name=this.data.fieldName;i.tabIndex=Qt;this._setRequired(i,this.data.required);a&&(i.maxLength=a);i.addEventListener("input",(s=>{t.setValue(e,{value:s.target.value});this.setPropertyOnSiblings(i,"value",s.target.value,"value");o.formattedValue=null}));i.addEventListener("resetform",(t=>{const e=this.data.defaultFieldValue??"";i.value=o.userValue=e;o.formattedValue=null}));let blurListener=t=>{const{formattedValue:e}=o;null!=e&&(t.target.value=e);t.target.scrollLeft=0};if(this.enableScripting&&this.hasJSActions){i.addEventListener("focus",(t=>{if(o.focused)return;const{target:e}=t;o.userValue&&(e.value=o.userValue);o.lastCommittedValue=e.value;o.commitKey=1;this.data.actions?.Focus||(o.focused=!0)}));i.addEventListener("updatefromsandbox",(i=>{this.showElementAndHideCanvas(i.target);const s={value(i){o.userValue=i.detail.value??"";t.setValue(e,{value:o.userValue.toString()});i.target.value=o.userValue},formattedValue(i){const{formattedValue:s}=i.detail;o.formattedValue=s;null!=s&&i.target!==document.activeElement&&(i.target.value=s);t.setValue(e,{formattedValue:s})},selRange(t){t.target.setSelectionRange(...t.detail.selRange)},charLimit:i=>{const{charLimit:s}=i.detail,{target:n}=i;if(0===s){n.removeAttribute("maxLength");return}n.setAttribute("maxLength",s);let a=o.userValue;if(a&&!(a.length<=s)){a=a.slice(0,s);n.value=o.userValue=a;t.setValue(e,{value:a});this.linkService.eventBus?.dispatch("dispatcheventinsandbox",{source:this,detail:{id:e,name:"Keystroke",value:a,willCommit:!0,commitKey:1,selStart:n.selectionStart,selEnd:n.selectionEnd}})}}};this._dispatchEventFromSandbox(s,i)}));i.addEventListener("keydown",(t=>{o.commitKey=1;let i=-1;"Escape"===t.key?i=0:"Enter"!==t.key||this.data.multiLine?"Tab"===t.key&&(o.commitKey=3):i=2;if(-1===i)return;const{value:s}=t.target;if(o.lastCommittedValue!==s){o.lastCommittedValue=s;o.userValue=s;this.linkService.eventBus?.dispatch("dispatcheventinsandbox",{source:this,detail:{id:e,name:"Keystroke",value:s,willCommit:!0,commitKey:i,selStart:t.target.selectionStart,selEnd:t.target.selectionEnd}})}}));const s=blurListener;blurListener=null;i.addEventListener("blur",(t=>{if(!o.focused||!t.relatedTarget)return;this.data.actions?.Blur||(o.focused=!1);const{value:i}=t.target;o.userValue=i;o.lastCommittedValue!==i&&this.linkService.eventBus?.dispatch("dispatcheventinsandbox",{source:this,detail:{id:e,name:"Keystroke",value:i,willCommit:!0,commitKey:o.commitKey,selStart:t.target.selectionStart,selEnd:t.target.selectionEnd}});s(t)}));this.data.actions?.Keystroke&&i.addEventListener("beforeinput",(t=>{o.lastCommittedValue=null;const{data:i,target:s}=t,{value:n,selectionStart:a,selectionEnd:r}=s;let h=a,l=r;switch(t.inputType){case"deleteWordBackward":{const t=n.substring(0,a).match(/\w*[^\w]*$/);t&&(h-=t[0].length);break}case"deleteWordForward":{const t=n.substring(a).match(/^[^\w]*\w*/);t&&(l+=t[0].length);break}case"deleteContentBackward":a===r&&(h-=1);break;case"deleteContentForward":a===r&&(l+=1)}t.preventDefault();this.linkService.eventBus?.dispatch("dispatcheventinsandbox",{source:this,detail:{id:e,name:"Keystroke",value:n,change:i||"",willCommit:!1,selStart:h,selEnd:l}})}));this._setEventListeners(i,o,[["focus","Focus"],["blur","Blur"],["mousedown","Mouse Down"],["mouseenter","Mouse Enter"],["mouseleave","Mouse Exit"],["mouseup","Mouse Up"]],(t=>t.target.value))}blurListener&&i.addEventListener("blur",blurListener);if(this.data.comb){const t=(this.data.rect[2]-this.data.rect[0])/a;i.classList.add("comb");i.style.letterSpacing=`calc(${t}px * var(--scale-factor) - 1ch)`}}else{i=document.createElement("div");i.textContent=this.data.fieldValue;i.style.verticalAlign="middle";i.style.display="table-cell";this.data.hasOwnCanvas&&(i.hidden=!0)}this._setTextStyle(i);this._setBackgroundColor(i);this._setDefaultPropertiesFromJS(i);this.container.append(i);return this.container}}class SignatureWidgetAnnotationElement extends WidgetAnnotationElement{constructor(t){super(t,{isRenderable:!!t.data.hasOwnCanvas})}}class CheckboxWidgetAnnotationElement extends WidgetAnnotationElement{constructor(t){super(t,{isRenderable:t.renderForms})}render(){const t=this.annotationStorage,e=this.data,i=e.id;let s=t.getValue(i,{value:e.exportValue===e.fieldValue}).value;if("string"==typeof s){s="Off"!==s;t.setValue(i,{value:s})}this.container.classList.add("buttonWidgetAnnotation","checkBox");const n=document.createElement("input");Jt.add(n);n.setAttribute("data-element-id",i);n.disabled=e.readOnly;this._setRequired(n,this.data.required);n.type="checkbox";n.name=e.fieldName;s&&n.setAttribute("checked",!0);n.setAttribute("exportValue",e.exportValue);n.tabIndex=Qt;n.addEventListener("change",(s=>{const{name:n,checked:a}=s.target;for(const s of this._getElementsByName(n,i)){const i=a&&s.exportValue===e.exportValue;s.domElement&&(s.domElement.checked=i);t.setValue(s.id,{value:i})}t.setValue(i,{value:a})}));n.addEventListener("resetform",(t=>{const i=e.defaultFieldValue||"Off";t.target.checked=i===e.exportValue}));if(this.enableScripting&&this.hasJSActions){n.addEventListener("updatefromsandbox",(e=>{const s={value(e){e.target.checked="Off"!==e.detail.value;t.setValue(i,{value:e.target.checked})}};this._dispatchEventFromSandbox(s,e)}));this._setEventListeners(n,null,[["change","Validate"],["change","Action"],["focus","Focus"],["blur","Blur"],["mousedown","Mouse Down"],["mouseenter","Mouse Enter"],["mouseleave","Mouse Exit"],["mouseup","Mouse Up"]],(t=>t.target.checked))}this._setBackgroundColor(n);this._setDefaultPropertiesFromJS(n);this.container.append(n);return this.container}}class RadioButtonWidgetAnnotationElement extends WidgetAnnotationElement{constructor(t){super(t,{isRenderable:t.renderForms})}render(){this.container.classList.add("buttonWidgetAnnotation","radioButton");const t=this.annotationStorage,e=this.data,i=e.id;let s=t.getValue(i,{value:e.fieldValue===e.buttonValue}).value;if("string"==typeof s){s=s!==e.buttonValue;t.setValue(i,{value:s})}if(s)for(const s of this._getElementsByName(e.fieldName,i))t.setValue(s.id,{value:!1});const n=document.createElement("input");Jt.add(n);n.setAttribute("data-element-id",i);n.disabled=e.readOnly;this._setRequired(n,this.data.required);n.type="radio";n.name=e.fieldName;s&&n.setAttribute("checked",!0);n.tabIndex=Qt;n.addEventListener("change",(e=>{const{name:s,checked:n}=e.target;for(const e of this._getElementsByName(s,i))t.setValue(e.id,{value:!1});t.setValue(i,{value:n})}));n.addEventListener("resetform",(t=>{const i=e.defaultFieldValue;t.target.checked=null!=i&&i===e.buttonValue}));if(this.enableScripting&&this.hasJSActions){const s=e.buttonValue;n.addEventListener("updatefromsandbox",(e=>{const n={value:e=>{const n=s===e.detail.value;for(const s of this._getElementsByName(e.target.name)){const e=n&&s.id===i;s.domElement&&(s.domElement.checked=e);t.setValue(s.id,{value:e})}}};this._dispatchEventFromSandbox(n,e)}));this._setEventListeners(n,null,[["change","Validate"],["change","Action"],["focus","Focus"],["blur","Blur"],["mousedown","Mouse Down"],["mouseenter","Mouse Enter"],["mouseleave","Mouse Exit"],["mouseup","Mouse Up"]],(t=>t.target.checked))}this._setBackgroundColor(n);this._setDefaultPropertiesFromJS(n);this.container.append(n);return this.container}}class PushButtonWidgetAnnotationElement extends LinkAnnotationElement{constructor(t){super(t,{ignoreBorder:t.data.hasAppearance})}render(){const t=super.render();t.classList.add("buttonWidgetAnnotation","pushButton");const e=t.lastChild;if(this.enableScripting&&this.hasJSActions&&e){this._setDefaultPropertiesFromJS(e);e.addEventListener("updatefromsandbox",(t=>{this._dispatchEventFromSandbox({},t)}))}return t}}class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement{constructor(t){super(t,{isRenderable:t.renderForms})}render(){this.container.classList.add("choiceWidgetAnnotation");const t=this.annotationStorage,e=this.data.id,i=t.getValue(e,{value:this.data.fieldValue}),s=document.createElement("select");Jt.add(s);s.setAttribute("data-element-id",e);s.disabled=this.data.readOnly;this._setRequired(s,this.data.required);s.name=this.data.fieldName;s.tabIndex=Qt;let n=this.data.combo&&this.data.options.length>0;if(!this.data.combo){s.size=this.data.options.length;this.data.multiSelect&&(s.multiple=!0)}s.addEventListener("resetform",(t=>{const e=this.data.defaultFieldValue;for(const t of s.options)t.selected=t.value===e}));for(const t of this.data.options){const e=document.createElement("option");e.textContent=t.displayValue;e.value=t.exportValue;if(i.value.includes(t.exportValue)){e.setAttribute("selected",!0);n=!1}s.append(e)}let a=null;if(n){const t=document.createElement("option");t.value=" ";t.setAttribute("hidden",!0);t.setAttribute("selected",!0);s.prepend(t);a=()=>{t.remove();s.removeEventListener("input",a);a=null};s.addEventListener("input",a)}const getValue=t=>{const e=t?"value":"textContent",{options:i,multiple:n}=s;return n?Array.prototype.filter.call(i,(t=>t.selected)).map((t=>t[e])):-1===i.selectedIndex?null:i[i.selectedIndex][e]};let r=getValue(!1);const getItems=t=>{const e=t.target.options;return Array.prototype.map.call(e,(t=>({displayValue:t.textContent,exportValue:t.value})))};if(this.enableScripting&&this.hasJSActions){s.addEventListener("updatefromsandbox",(i=>{const n={value(i){a?.();const n=i.detail.value,o=new Set(Array.isArray(n)?n:[n]);for(const t of s.options)t.selected=o.has(t.value);t.setValue(e,{value:getValue(!0)});r=getValue(!1)},multipleSelection(t){s.multiple=!0},remove(i){const n=s.options,a=i.detail.remove;n[a].selected=!1;s.remove(a);if(n.length>0){-1===Array.prototype.findIndex.call(n,(t=>t.selected))&&(n[0].selected=!0)}t.setValue(e,{value:getValue(!0),items:getItems(i)});r=getValue(!1)},clear(i){for(;0!==s.length;)s.remove(0);t.setValue(e,{value:null,items:[]});r=getValue(!1)},insert(i){const{index:n,displayValue:a,exportValue:o}=i.detail.insert,h=s.children[n],l=document.createElement("option");l.textContent=a;l.value=o;h?h.before(l):s.append(l);t.setValue(e,{value:getValue(!0),items:getItems(i)});r=getValue(!1)},items(i){const{items:n}=i.detail;for(;0!==s.length;)s.remove(0);for(const t of n){const{displayValue:e,exportValue:i}=t,n=document.createElement("option");n.textContent=e;n.value=i;s.append(n)}s.options.length>0&&(s.options[0].selected=!0);t.setValue(e,{value:getValue(!0),items:getItems(i)});r=getValue(!1)},indices(i){const s=new Set(i.detail.indices);for(const t of i.target.options)t.selected=s.has(t.index);t.setValue(e,{value:getValue(!0)});r=getValue(!1)},editable(t){t.target.disabled=!t.detail.editable}};this._dispatchEventFromSandbox(n,i)}));s.addEventListener("input",(i=>{const s=getValue(!0),n=getValue(!1);t.setValue(e,{value:s});i.preventDefault();this.linkService.eventBus?.dispatch("dispatcheventinsandbox",{source:this,detail:{id:e,name:"Keystroke",value:r,change:n,changeEx:s,willCommit:!1,commitKey:1,keyDown:!1}})}));this._setEventListeners(s,null,[["focus","Focus"],["blur","Blur"],["mousedown","Mouse Down"],["mouseenter","Mouse Enter"],["mouseleave","Mouse Exit"],["mouseup","Mouse Up"],["input","Action"],["input","Validate"]],(t=>t.target.value))}else s.addEventListener("input",(function(i){t.setValue(e,{value:getValue(!0)})}));this.data.combo&&this._setTextStyle(s);this._setBackgroundColor(s);this._setDefaultPropertiesFromJS(s);this.container.append(s);return this.container}}class PopupAnnotationElement extends AnnotationElement{constructor(t){const{data:e,elements:i}=t;super(t,{isRenderable:AnnotationElement._hasPopupData(e)});this.elements=i;this.popup=null}render(){this.container.classList.add("popupAnnotation");const t=this.popup=new PopupElement({container:this.container,color:this.data.color,titleObj:this.data.titleObj,modificationDate:this.data.modificationDate,contentsObj:this.data.contentsObj,richText:this.data.richText,rect:this.data.rect,parentRect:this.data.parentRect||null,parent:this.parent,elements:this.elements,open:this.data.open}),e=[];for(const i of this.elements){i.popup=t;e.push(i.data.id);i.addHighlightArea()}this.container.setAttribute("aria-controls",e.map((t=>`${et}${t}`)).join(","));return this.container}}class PopupElement{#ns=this.#as.bind(this);#rs=this.#os.bind(this);#hs=this.#ls.bind(this);#ds=this.#cs.bind(this);#us=null;#ft=null;#ps=null;#gs=null;#ms=null;#fs=null;#bs=null;#vs=!1;#As=null;#E=null;#ys=null;#ws=null;#xs=null;#Qi=null;#Es=!1;constructor({container:t,color:e,elements:i,titleObj:s,modificationDate:n,contentsObj:a,richText:r,parent:o,rect:h,parentRect:l,open:d}){this.#ft=t;this.#xs=s;this.#ps=a;this.#ws=r;this.#fs=o;this.#us=e;this.#ys=h;this.#bs=l;this.#ms=i;this.#gs=PDFDateString.toDateObject(n);this.trigger=i.flatMap((t=>t.getElementsToTriggerPopup()));for(const t of this.trigger){t.addEventListener("click",this.#ds);t.addEventListener("mouseenter",this.#hs);t.addEventListener("mouseleave",this.#rs);t.classList.add("popupTriggerArea")}for(const t of i)t.container?.addEventListener("keydown",this.#ns);this.#ft.hidden=!0;d&&this.#cs()}render(){if(this.#As)return;const t=this.#As=document.createElement("div");t.className="popup";if(this.#us){const e=t.style.outlineColor=Util.makeHexColor(...this.#us);if(CSS.supports("background-color","color-mix(in srgb, red 30%, white)"))t.style.backgroundColor=`color-mix(in srgb, ${e} 30%, white)`;else{const e=.7;t.style.backgroundColor=Util.makeHexColor(...this.#us.map((t=>Math.floor(e*(255-t)+t))))}}const e=document.createElement("span");e.className="header";const i=document.createElement("h1");e.append(i);({dir:i.dir,str:i.textContent}=this.#xs);t.append(e);if(this.#gs){const t=document.createElement("span");t.classList.add("popupDate");t.setAttribute("data-l10n-id","pdfjs-annotation-date-string");t.setAttribute("data-l10n-args",JSON.stringify({date:this.#gs.toLocaleDateString(),time:this.#gs.toLocaleTimeString()}));e.append(t)}const s=this.#_s;if(s){XfaLayer.render({xfaHtml:s,intent:"richText",div:t});t.lastChild.classList.add("richText","popupContent")}else{const e=this._formatContents(this.#ps);t.append(e)}this.#ft.append(t)}get#_s(){const t=this.#ws,e=this.#ps;return!t?.str||e?.str&&e.str!==t.str?null:this.#ws.html||null}get#Cs(){return this.#_s?.attributes?.style?.fontSize||0}get#Ss(){return this.#_s?.attributes?.style?.color||null}#Ts(t){const e=[],i={str:t,html:{name:"div",attributes:{dir:"auto"},children:[{name:"p",children:e}]}},s={style:{color:this.#Ss,fontSize:this.#Cs?`calc(${this.#Cs}px * var(--scale-factor))`:""}};for(const i of t.split("\n"))e.push({name:"span",value:i,attributes:s});return i}_formatContents({str:t,dir:e}){const i=document.createElement("p");i.classList.add("popupContent");i.dir=e;const s=t.split(/(?:\r\n?|\n)/);for(let t=0,e=s.length;t<e;++t){const n=s[t];i.append(document.createTextNode(n));t<e-1&&i.append(document.createElement("br"))}return i}#as(t){t.altKey||t.shiftKey||t.ctrlKey||t.metaKey||("Enter"===t.key||"Escape"===t.key&&this.#vs)&&this.#cs()}updateEdited({rect:t,popupContent:e}){this.#Qi||={contentsObj:this.#ps,richText:this.#ws};t&&(this.#E=null);if(e){this.#ws=this.#Ts(e);this.#ps=null}this.#As?.remove();this.#As=null}resetEdited(){if(this.#Qi){({contentsObj:this.#ps,richText:this.#ws}=this.#Qi);this.#Qi=null;this.#As?.remove();this.#As=null;this.#E=null}}#Ms(){if(null!==this.#E)return;const{page:{view:t},viewport:{rawDims:{pageWidth:e,pageHeight:i,pageX:s,pageY:n}}}=this.#fs;let a=!!this.#bs,r=a?this.#bs:this.#ys;for(const t of this.#ms)if(!r||null!==Util.intersect(t.data.rect,r)){r=t.data.rect;a=!0;break}const o=Util.normalizeRect([r[0],t[3]-r[1]+t[1],r[2],t[3]-r[3]+t[1]]),h=a?r[2]-r[0]+5:0,l=o[0]+h,d=o[1];this.#E=[100*(l-s)/e,100*(d-n)/i];const{style:c}=this.#ft;c.left=`${this.#E[0]}%`;c.top=`${this.#E[1]}%`}#cs(){this.#vs=!this.#vs;if(this.#vs){this.#ls();this.#ft.addEventListener("click",this.#ds);this.#ft.addEventListener("keydown",this.#ns)}else{this.#os();this.#ft.removeEventListener("click",this.#ds);this.#ft.removeEventListener("keydown",this.#ns)}}#ls(){this.#As||this.render();if(this.isVisible)this.#vs&&this.#ft.classList.add("focused");else{this.#Ms();this.#ft.hidden=!1;this.#ft.style.zIndex=parseInt(this.#ft.style.zIndex)+1e3}}#os(){this.#ft.classList.remove("focused");if(!this.#vs&&this.isVisible){this.#ft.hidden=!0;this.#ft.style.zIndex=parseInt(this.#ft.style.zIndex)-1e3}}forceHide(){this.#Es=this.isVisible;this.#Es&&(this.#ft.hidden=!0)}maybeShow(){if(this.#Es){this.#As||this.#ls();this.#Es=!1;this.#ft.hidden=!1}}get isVisible(){return!1===this.#ft.hidden}}class FreeTextAnnotationElement extends AnnotationElement{constructor(t){super(t,{isRenderable:!0,ignoreBorder:!0});this.textContent=t.data.textContent;this.textPosition=t.data.textPosition;this.annotationEditorType=p.FREETEXT}render(){this.container.classList.add("freeTextAnnotation");if(this.textContent){const t=document.createElement("div");t.classList.add("annotationTextContent");t.setAttribute("role","comment");for(const e of this.textContent){const i=document.createElement("span");i.textContent=e;t.append(i)}this.container.append(t)}!this.data.popupRef&&this.hasPopupData&&this._createPopup();this._editOnDoubleClick();return this.container}get _isEditable(){return this.data.hasOwnCanvas}}class LineAnnotationElement extends AnnotationElement{#ks=null;constructor(t){super(t,{isRenderable:!0,ignoreBorder:!0})}render(){this.container.classList.add("lineAnnotation");const t=this.data,{width:e,height:i}=getRectDims(t.rect),s=this.svgFactory.create(e,i,!0),n=this.#ks=this.svgFactory.createElement("svg:line");n.setAttribute("x1",t.rect[2]-t.lineCoordinates[0]);n.setAttribute("y1",t.rect[3]-t.lineCoordinates[1]);n.setAttribute("x2",t.rect[2]-t.lineCoordinates[2]);n.setAttribute("y2",t.rect[3]-t.lineCoordinates[3]);n.setAttribute("stroke-width",t.borderStyle.width||1);n.setAttribute("stroke","transparent");n.setAttribute("fill","transparent");s.append(n);this.container.append(s);!t.popupRef&&this.hasPopupData&&this._createPopup();return this.container}getElementsToTriggerPopup(){return this.#ks}addHighlightArea(){this.container.classList.add("highlightArea")}}class SquareAnnotationElement extends AnnotationElement{#Ps=null;constructor(t){super(t,{isRenderable:!0,ignoreBorder:!0})}render(){this.container.classList.add("squareAnnotation");const t=this.data,{width:e,height:i}=getRectDims(t.rect),s=this.svgFactory.create(e,i,!0),n=t.borderStyle.width,a=this.#Ps=this.svgFactory.createElement("svg:rect");a.setAttribute("x",n/2);a.setAttribute("y",n/2);a.setAttribute("width",e-n);a.setAttribute("height",i-n);a.setAttribute("stroke-width",n||1);a.setAttribute("stroke","transparent");a.setAttribute("fill","transparent");s.append(a);this.container.append(s);!t.popupRef&&this.hasPopupData&&this._createPopup();return this.container}getElementsToTriggerPopup(){return this.#Ps}addHighlightArea(){this.container.classList.add("highlightArea")}}class CircleAnnotationElement extends AnnotationElement{#Ds=null;constructor(t){super(t,{isRenderable:!0,ignoreBorder:!0})}render(){this.container.classList.add("circleAnnotation");const t=this.data,{width:e,height:i}=getRectDims(t.rect),s=this.svgFactory.create(e,i,!0),n=t.borderStyle.width,a=this.#Ds=this.svgFactory.createElement("svg:ellipse");a.setAttribute("cx",e/2);a.setAttribute("cy",i/2);a.setAttribute("rx",e/2-n/2);a.setAttribute("ry",i/2-n/2);a.setAttribute("stroke-width",n||1);a.setAttribute("stroke","transparent");a.setAttribute("fill","transparent");s.append(a);this.container.append(s);!t.popupRef&&this.hasPopupData&&this._createPopup();return this.container}getElementsToTriggerPopup(){return this.#Ds}addHighlightArea(){this.container.classList.add("highlightArea")}}class PolylineAnnotationElement extends AnnotationElement{#Rs=null;constructor(t){super(t,{isRenderable:!0,ignoreBorder:!0});this.containerClassName="polylineAnnotation";this.svgElementName="svg:polyline"}render(){this.container.classList.add(this.containerClassName);const t=this.data,{width:e,height:i}=getRectDims(t.rect),s=this.svgFactory.create(e,i,!0);let n=[];for(const e of t.vertices){const i=e.x-t.rect[0],s=t.rect[3]-e.y;n.push(i+","+s)}n=n.join(" ");const a=this.#Rs=this.svgFactory.createElement(this.svgElementName);a.setAttribute("points",n);a.setAttribute("stroke-width",t.borderStyle.width||1);a.setAttribute("stroke","transparent");a.setAttribute("fill","transparent");s.append(a);this.container.append(s);!t.popupRef&&this.hasPopupData&&this._createPopup();return this.container}getElementsToTriggerPopup(){return this.#Rs}addHighlightArea(){this.container.classList.add("highlightArea")}}class PolygonAnnotationElement extends PolylineAnnotationElement{constructor(t){super(t);this.containerClassName="polygonAnnotation";this.svgElementName="svg:polygon"}}class CaretAnnotationElement extends AnnotationElement{constructor(t){super(t,{isRenderable:!0,ignoreBorder:!0})}render(){this.container.classList.add("caretAnnotation");!this.data.popupRef&&this.hasPopupData&&this._createPopup();return this.container}}class InkAnnotationElement extends AnnotationElement{#Fs=[];constructor(t){super(t,{isRenderable:!0,ignoreBorder:!0});this.containerClassName="inkAnnotation";this.svgElementName="svg:polyline";this.annotationEditorType=p.INK}render(){this.container.classList.add(this.containerClassName);const t=this.data,{width:e,height:i}=getRectDims(t.rect),s=this.svgFactory.create(e,i,!0);for(const e of t.inkLists){let i=[];for(const s of e){const e=s.x-t.rect[0],n=t.rect[3]-s.y;i.push(`${e},${n}`)}i=i.join(" ");const n=this.svgFactory.createElement(this.svgElementName);this.#Fs.push(n);n.setAttribute("points",i);n.setAttribute("stroke-width",t.borderStyle.width||1);n.setAttribute("stroke","transparent");n.setAttribute("fill","transparent");!t.popupRef&&this.hasPopupData&&this._createPopup();s.append(n)}this.container.append(s);return this.container}getElementsToTriggerPopup(){return this.#Fs}addHighlightArea(){this.container.classList.add("highlightArea")}}class HighlightAnnotationElement extends AnnotationElement{constructor(t){super(t,{isRenderable:!0,ignoreBorder:!0,createQuadrilaterals:!0})}render(){!this.data.popupRef&&this.hasPopupData&&this._createPopup();this.container.classList.add("highlightAnnotation");return this.container}}class UnderlineAnnotationElement extends AnnotationElement{constructor(t){super(t,{isRenderable:!0,ignoreBorder:!0,createQuadrilaterals:!0})}render(){!this.data.popupRef&&this.hasPopupData&&this._createPopup();this.container.classList.add("underlineAnnotation");return this.container}}class SquigglyAnnotationElement extends AnnotationElement{constructor(t){super(t,{isRenderable:!0,ignoreBorder:!0,createQuadrilaterals:!0})}render(){!this.data.popupRef&&this.hasPopupData&&this._createPopup();this.container.classList.add("squigglyAnnotation");return this.container}}class StrikeOutAnnotationElement extends AnnotationElement{constructor(t){super(t,{isRenderable:!0,ignoreBorder:!0,createQuadrilaterals:!0})}render(){!this.data.popupRef&&this.hasPopupData&&this._createPopup();this.container.classList.add("strikeoutAnnotation");return this.container}}class StampAnnotationElement extends AnnotationElement{constructor(t){super(t,{isRenderable:!0,ignoreBorder:!0})}render(){this.container.classList.add("stampAnnotation");!this.data.popupRef&&this.hasPopupData&&this._createPopup();return this.container}}class FileAttachmentAnnotationElement extends AnnotationElement{#Is=null;constructor(t){super(t,{isRenderable:!0});const{file:e}=this.data;this.filename=e.filename;this.content=e.content;this.linkService.eventBus?.dispatch("fileattachmentannotation",{source:this,...e})}render(){this.container.classList.add("fileAttachmentAnnotation");const{container:t,data:e}=this;let i;if(e.hasAppearance||0===e.fillAlpha)i=document.createElement("div");else{i=document.createElement("img");i.src=`${this.imageResourcesPath}annotation-${/paperclip/i.test(e.name)?"paperclip":"pushpin"}.svg`;e.fillAlpha&&e.fillAlpha<1&&(i.style=`filter: opacity(${Math.round(100*e.fillAlpha)}%);`)}i.addEventListener("dblclick",this.#Ls.bind(this));this.#Is=i;const{isMac:s}=util_FeatureTest.platform;t.addEventListener("keydown",(t=>{"Enter"===t.key&&(s?t.metaKey:t.ctrlKey)&&this.#Ls()}));!e.popupRef&&this.hasPopupData?this._createPopup():i.classList.add("popupTriggerArea");t.append(i);return t}getElementsToTriggerPopup(){return this.#Is}addHighlightArea(){this.container.classList.add("highlightArea")}#Ls(){this.downloadManager?.openOrDownloadData(this.content,this.filename)}}class AnnotationLayer{#Os=null;#Ns=null;#Bs=new Map;constructor({div:t,accessibilityManager:e,annotationCanvasMap:i,annotationEditorUIManager:s,page:n,viewport:a}){this.div=t;this.#Os=e;this.#Ns=i;this.page=n;this.viewport=a;this.zIndex=0;this._annotationEditorUIManager=s}#Hs(t,e){const i=t.firstChild||t;i.id=`${et}${e}`;this.div.append(t);this.#Os?.moveElementInDOM(this.div,t,i,!1)}async render(t){const{annotations:e}=t,i=this.div;setLayerDimensions(i,this.viewport);const s=new Map,n={data:null,layer:i,linkService:t.linkService,downloadManager:t.downloadManager,imageResourcesPath:t.imageResourcesPath||"",renderForms:!1!==t.renderForms,svgFactory:new DOMSVGFactory,annotationStorage:t.annotationStorage||new AnnotationStorage,enableScripting:!0===t.enableScripting,hasJSActions:t.hasJSActions,fieldObjects:t.fieldObjects,parent:this,elements:null};for(const t of e){if(t.noHTML)continue;const e=t.annotationType===B;if(e){const e=s.get(t.id);if(!e)continue;n.elements=e}else{const{width:e,height:i}=getRectDims(t.rect);if(e<=0||i<=0)continue}n.data=t;const i=AnnotationElementFactory.create(n);if(!i.isRenderable)continue;if(!e&&t.popupRef){const e=s.get(t.popupRef);e?e.push(i):s.set(t.popupRef,[i])}const a=i.render();t.hidden&&(a.style.visibility="hidden");this.#Hs(a,t.id);if(i.annotationEditorType>0){this.#Bs.set(i.data.id,i);this._annotationEditorUIManager?.renderAnnotationElement(i)}}this.#zs()}update({viewport:t}){const e=this.div;this.viewport=t;setLayerDimensions(e,{rotation:t.rotation});this.#zs();e.hidden=!1}#zs(){if(!this.#Ns)return;const t=this.div;for(const[e,i]of this.#Ns){const s=t.querySelector(`[data-annotation-id="${e}"]`);if(!s)continue;i.className="annotationContent";const{firstChild:n}=s;n?"CANVAS"===n.nodeName?n.replaceWith(i):n.classList.contains("annotationContent")?n.after(i):n.before(i):s.append(i)}this.#Ns.clear()}getEditableAnnotations(){return Array.from(this.#Bs.values())}getEditableAnnotation(t){return this.#Bs.get(t)}}const Zt=/\r\n?|\n/g;class FreeTextEditor extends AnnotationEditor{#Us=this.editorDivBlur.bind(this);#js=this.editorDivFocus.bind(this);#$s=this.editorDivInput.bind(this);#Vs=this.editorDivKeydown.bind(this);#Gs=this.editorDivPaste.bind(this);#us;#Ws="";#qs=`${this.id}-editor`;#Cs;#Xs=null;static _freeTextDefaultContent="";static _internalPadding=0;static _defaultColor=null;static _defaultFontSize=10;static get _keyboardManager(){const t=FreeTextEditor.prototype,arrowChecker=t=>t.isEmpty(),e=AnnotationEditorUIManager.TRANSLATE_SMALL,i=AnnotationEditorUIManager.TRANSLATE_BIG;return shadow(this,"_keyboardManager",new KeyboardManager([[["ctrl+s","mac+meta+s","ctrl+p","mac+meta+p"],t.commitOrRemove,{bubbles:!0}],[["ctrl+Enter","mac+meta+Enter","Escape","mac+Escape"],t.commitOrRemove],[["ArrowLeft","mac+ArrowLeft"],t._translateEmpty,{args:[-e,0],checker:arrowChecker}],[["ctrl+ArrowLeft","mac+shift+ArrowLeft"],t._translateEmpty,{args:[-i,0],checker:arrowChecker}],[["ArrowRight","mac+ArrowRight"],t._translateEmpty,{args:[e,0],checker:arrowChecker}],[["ctrl+ArrowRight","mac+shift+ArrowRight"],t._translateEmpty,{args:[i,0],checker:arrowChecker}],[["ArrowUp","mac+ArrowUp"],t._translateEmpty,{args:[0,-e],checker:arrowChecker}],[["ctrl+ArrowUp","mac+shift+ArrowUp"],t._translateEmpty,{args:[0,-i],checker:arrowChecker}],[["ArrowDown","mac+ArrowDown"],t._translateEmpty,{args:[0,e],checker:arrowChecker}],[["ctrl+ArrowDown","mac+shift+ArrowDown"],t._translateEmpty,{args:[0,i],checker:arrowChecker}]]))}static _type="freetext";static _editorType=p.FREETEXT;constructor(t){super({...t,name:"freeTextEditor"});this.#us=t.color||FreeTextEditor._defaultColor||AnnotationEditor._defaultLineColor;this.#Cs=t.fontSize||FreeTextEditor._defaultFontSize}static initialize(t,e){AnnotationEditor.initialize(t,e,{strings:["pdfjs-free-text-default-content"]});const i=getComputedStyle(document.documentElement);this._internalPadding=parseFloat(i.getPropertyValue("--freetext-padding"))}static updateDefaultParams(t,e){switch(t){case g.FREETEXT_SIZE:FreeTextEditor._defaultFontSize=e;break;case g.FREETEXT_COLOR:FreeTextEditor._defaultColor=e}}updateParams(t,e){switch(t){case g.FREETEXT_SIZE:this.#Ks(e);break;case g.FREETEXT_COLOR:this.#Ys(e)}}static get defaultPropertiesToUpdate(){return[[g.FREETEXT_SIZE,FreeTextEditor._defaultFontSize],[g.FREETEXT_COLOR,FreeTextEditor._defaultColor||AnnotationEditor._defaultLineColor]]}get propertiesToUpdate(){return[[g.FREETEXT_SIZE,this.#Cs],[g.FREETEXT_COLOR,this.#us]]}#Ks(t){const setFontsize=t=>{this.editorDiv.style.fontSize=`calc(${t}px * var(--scale-factor))`;this.translate(0,-(t-this.#Cs)*this.parentScale);this.#Cs=t;this.#Qs()},e=this.#Cs;this.addCommands({cmd:setFontsize.bind(this,t),undo:setFontsize.bind(this,e),post:this._uiManager.updateUI.bind(this._uiManager,this),mustExec:!0,type:g.FREETEXT_SIZE,overwriteIfSameType:!0,keepUndo:!0})}#Ys(t){const setColor=t=>{this.#us=this.editorDiv.style.color=t},e=this.#us;this.addCommands({cmd:setColor.bind(this,t),undo:setColor.bind(this,e),post:this._uiManager.updateUI.bind(this._uiManager,this),mustExec:!0,type:g.FREETEXT_COLOR,overwriteIfSameType:!0,keepUndo:!0})}_translateEmpty(t,e){this._uiManager.translateSelectedEditors(t,e,!0)}getInitialTranslation(){const t=this.parentScale;return[-FreeTextEditor._internalPadding*t,-(FreeTextEditor._internalPadding+this.#Cs)*t]}rebuild(){if(this.parent){super.rebuild();null!==this.div&&(this.isAttachedToDOM||this.parent.add(this))}}enableEditMode(){if(!this.isInEditMode()){this.parent.setEditingState(!1);this.parent.updateToolbar(p.FREETEXT);super.enableEditMode();this.overlayDiv.classList.remove("enabled");this.editorDiv.contentEditable=!0;this._isDraggable=!1;this.div.removeAttribute("aria-activedescendant");this.editorDiv.addEventListener("keydown",this.#Vs);this.editorDiv.addEventListener("focus",this.#js);this.editorDiv.addEventListener("blur",this.#Us);this.editorDiv.addEventListener("input",this.#$s);this.editorDiv.addEventListener("paste",this.#Gs)}}disableEditMode(){if(this.isInEditMode()){this.parent.setEditingState(!0);super.disableEditMode();this.overlayDiv.classList.add("enabled");this.editorDiv.contentEditable=!1;this.div.setAttribute("aria-activedescendant",this.#qs);this._isDraggable=!0;this.editorDiv.removeEventListener("keydown",this.#Vs);this.editorDiv.removeEventListener("focus",this.#js);this.editorDiv.removeEventListener("blur",this.#Us);this.editorDiv.removeEventListener("input",this.#$s);this.editorDiv.removeEventListener("paste",this.#Gs);this.div.focus({preventScroll:!0});this.isEditing=!1;this.parent.div.classList.add("freetextEditing")}}focusin(t){if(this._focusEventsAllowed){super.focusin(t);t.target!==this.editorDiv&&this.editorDiv.focus()}}onceAdded(){if(!this.width){this.enableEditMode();this.editorDiv.focus();this._initialOptions?.isCentered&&this.center();this._initialOptions=null}}isEmpty(){return!this.editorDiv||""===this.editorDiv.innerText.trim()}remove(){this.isEditing=!1;if(this.parent){this.parent.setEditingState(!0);this.parent.div.classList.add("freetextEditing")}super.remove()}#Js(){const t=[];this.editorDiv.normalize();for(const e of this.editorDiv.childNodes)t.push(FreeTextEditor.#Zs(e));return t.join("\n")}#Qs(){const[t,e]=this.parentDimensions;let i;if(this.isAttachedToDOM)i=this.div.getBoundingClientRect();else{const{currentLayer:t,div:e}=this,s=e.style.display,n=e.classList.contains("hidden");e.classList.remove("hidden");e.style.display="hidden";t.div.append(this.div);i=e.getBoundingClientRect();e.remove();e.style.display=s;e.classList.toggle("hidden",n)}if(this.rotation%180==this.parentRotation%180){this.width=i.width/t;this.height=i.height/e}else{this.width=i.height/t;this.height=i.width/e}this.fixAndSetPosition()}commit(){if(!this.isInEditMode())return;super.commit();this.disableEditMode();const t=this.#Ws,e=this.#Ws=this.#Js().trimEnd();if(t===e)return;const setText=t=>{this.#Ws=t;if(t){this.#tn();this._uiManager.rebuild(this);this.#Qs()}else this.remove()};this.addCommands({cmd:()=>{setText(e)},undo:()=>{setText(t)},mustExec:!1});this.#Qs()}shouldGetKeyboardEvents(){return this.isInEditMode()}enterInEditMode(){this.enableEditMode();this.editorDiv.focus()}dblclick(t){this.enterInEditMode()}keydown(t){if(t.target===this.div&&"Enter"===t.key){this.enterInEditMode();t.preventDefault()}}editorDivKeydown(t){FreeTextEditor._keyboardManager.exec(this,t)}editorDivFocus(t){this.isEditing=!0}editorDivBlur(t){this.isEditing=!1}editorDivInput(t){this.parent.div.classList.toggle("freetextEditing",this.isEmpty())}disableEditing(){this.editorDiv.setAttribute("role","comment");this.editorDiv.removeAttribute("aria-multiline")}enableEditing(){this.editorDiv.setAttribute("role","textbox");this.editorDiv.setAttribute("aria-multiline",!0)}render(){if(this.div)return this.div;let t,e;if(this.width){t=this.x;e=this.y}super.render();this.editorDiv=document.createElement("div");this.editorDiv.className="internal";this.editorDiv.setAttribute("id",this.#qs);this.editorDiv.setAttribute("data-l10n-id","pdfjs-free-text");this.enableEditing();AnnotationEditor._l10nPromise.get("pdfjs-free-text-default-content").then((t=>this.editorDiv?.setAttribute("default-content",t)));this.editorDiv.contentEditable=!0;const{style:i}=this.editorDiv;i.fontSize=`calc(${this.#Cs}px * var(--scale-factor))`;i.color=this.#us;this.div.append(this.editorDiv);this.overlayDiv=document.createElement("div");this.overlayDiv.classList.add("overlay","enabled");this.div.append(this.overlayDiv);bindEvents(this,this.div,["dblclick","keydown"]);if(this.width){const[i,s]=this.parentDimensions;if(this.annotationElementId){const{position:n}=this.#Xs;let[a,r]=this.getInitialTranslation();[a,r]=this.pageTranslationToScreen(a,r);const[o,h]=this.pageDimensions,[l,d]=this.pageTranslation;let c,u;switch(this.rotation){case 0:c=t+(n[0]-l)/o;u=e+this.height-(n[1]-d)/h;break;case 90:c=t+(n[0]-l)/o;u=e-(n[1]-d)/h;[a,r]=[r,-a];break;case 180:c=t-this.width+(n[0]-l)/o;u=e-(n[1]-d)/h;[a,r]=[-a,-r];break;case 270:c=t+(n[0]-l-this.height*h)/o;u=e+(n[1]-d-this.width*o)/h;[a,r]=[-r,a]}this.setAt(c*i,u*s,a,r)}else this.setAt(t*i,e*s,this.width*i,this.height*s);this.#tn();this._isDraggable=!0;this.editorDiv.contentEditable=!1}else{this._isDraggable=!1;this.editorDiv.contentEditable=!0}return this.div}static#Zs(t){return(t.nodeType===Node.TEXT_NODE?t.nodeValue:t.innerText).replaceAll(Zt,"")}editorDivPaste(t){const e=t.clipboardData||window.clipboardData,{types:i}=e;if(1===i.length&&"text/plain"===i[0])return;t.preventDefault();const s=FreeTextEditor.#en(e.getData("text")||"").replaceAll(Zt,"\n");if(!s)return;const n=window.getSelection();if(!n.rangeCount)return;this.editorDiv.normalize();n.deleteFromDocument();const a=n.getRangeAt(0);if(!s.includes("\n")){a.insertNode(document.createTextNode(s));this.editorDiv.normalize();n.collapseToStart();return}const{startContainer:r,startOffset:o}=a,h=[],l=[];if(r.nodeType===Node.TEXT_NODE){const t=r.parentElement;l.push(r.nodeValue.slice(o).replaceAll(Zt,""));if(t!==this.editorDiv){let e=h;for(const i of this.editorDiv.childNodes)i!==t?e.push(FreeTextEditor.#Zs(i)):e=l}h.push(r.nodeValue.slice(0,o).replaceAll(Zt,""))}else if(r===this.editorDiv){let t=h,e=0;for(const i of this.editorDiv.childNodes){e++===o&&(t=l);t.push(FreeTextEditor.#Zs(i))}}this.#Ws=`${h.join("\n")}${s}${l.join("\n")}`;this.#tn();const d=new Range;let c=h.reduce(((t,e)=>t+e.length),0);for(const{firstChild:t}of this.editorDiv.childNodes)if(t.nodeType===Node.TEXT_NODE){const e=t.nodeValue.length;if(c<=e){d.setStart(t,c);d.setEnd(t,c);break}c-=e}n.removeAllRanges();n.addRange(d)}#tn(){this.editorDiv.replaceChildren();if(this.#Ws)for(const t of this.#Ws.split("\n")){const e=document.createElement("div");e.append(t?document.createTextNode(t):document.createElement("br"));this.editorDiv.append(e)}}#in(){return this.#Ws.replaceAll(" "," ")}static#en(t){return t.replaceAll(" "," ")}get contentDiv(){return this.editorDiv}static deserialize(t,e,i){let s=null;if(t instanceof FreeTextAnnotationElement){const{data:{defaultAppearanceData:{fontSize:e,fontColor:i},rect:n,rotation:a,id:r},textContent:o,textPosition:h,parent:{page:{pageNumber:l}}}=t;if(!o||0===o.length)return null;s=t={annotationType:p.FREETEXT,color:Array.from(i),fontSize:e,value:o.join("\n"),position:h,pageIndex:l-1,rect:n.slice(0),rotation:a,id:r,deleted:!1}}const n=super.deserialize(t,e,i);n.#Cs=t.fontSize;n.#us=Util.makeHexColor(...t.color);n.#Ws=FreeTextEditor.#en(t.value);n.annotationElementId=t.id||null;n.#Xs=s;return n}serialize(t=!1){if(this.isEmpty())return null;if(this.deleted)return{pageIndex:this.pageIndex,id:this.annotationElementId,deleted:!0};const e=FreeTextEditor._internalPadding*this.parentScale,i=this.getRect(e,e),s=AnnotationEditor._colorManager.convert(this.isAttachedToDOM?getComputedStyle(this.editorDiv).color:this.#us),n={annotationType:p.FREETEXT,color:s,fontSize:this.#Cs,value:this.#in(),pageIndex:this.pageIndex,rect:i,rotation:this.rotation,structTreeParentId:this._structTreeParentId};if(t)return n;if(this.annotationElementId&&!this.#sn(n))return null;n.id=this.annotationElementId;return n}#sn(t){const{value:e,fontSize:i,color:s,pageIndex:n}=this.#Xs;return this._hasBeenMoved||t.value!==e||t.fontSize!==i||t.color.some(((t,e)=>t!==s[e]))||t.pageIndex!==n}renderAnnotationElement(t){const e=super.renderAnnotationElement(t);if(this.deleted)return e;const{style:i}=e;i.fontSize=`calc(${this.#Cs}px * var(--scale-factor))`;i.color=this.#us;e.replaceChildren();for(const t of this.#Ws.split("\n")){const i=document.createElement("div");i.append(t?document.createTextNode(t):document.createElement("br"));e.append(i)}const s=FreeTextEditor._internalPadding*this.parentScale;t.updateEdited({rect:this.getRect(s,s),popupContent:this.#Ws});return e}resetAnnotationElement(t){super.resetAnnotationElement(t);t.resetEdited()}}class Outliner{#nn;#an=[];#rn=[];constructor(t,e=0,i=0,s=!0){let n=1/0,a=-1/0,r=1/0,o=-1/0;const h=10**-4;for(const{x:i,y:s,width:l,height:d}of t){const t=Math.floor((i-e)/h)*h,c=Math.ceil((i+l+e)/h)*h,u=Math.floor((s-e)/h)*h,p=Math.ceil((s+d+e)/h)*h,g=[t,u,p,!0],m=[c,u,p,!1];this.#an.push(g,m);n=Math.min(n,t);a=Math.max(a,c);r=Math.min(r,u);o=Math.max(o,p)}const l=a-n+2*i,d=o-r+2*i,c=n-i,u=r-i,p=this.#an.at(s?-1:-2),g=[p[0],p[2]];for(const t of this.#an){const[e,i,s]=t;t[0]=(e-c)/l;t[1]=(i-u)/d;t[2]=(s-u)/d}this.#nn={x:c,y:u,width:l,height:d,lastPoint:g}}getOutlines(){this.#an.sort(((t,e)=>t[0]-e[0]||t[1]-e[1]||t[2]-e[2]));const t=[];for(const e of this.#an)if(e[3]){t.push(...this.#on(e));this.#hn(e)}else{this.#ln(e);t.push(...this.#on(e))}return this.#dn(t)}#dn(t){const e=[],i=new Set;for(const i of t){const[t,s,n]=i;e.push([t,s,i],[t,n,i])}e.sort(((t,e)=>t[1]-e[1]||t[0]-e[0]));for(let t=0,s=e.length;t<s;t+=2){const s=e[t][2],n=e[t+1][2];s.push(n);n.push(s);i.add(s);i.add(n)}const s=[];let n;for(;i.size>0;){const t=i.values().next().value;let[e,a,r,o,h]=t;i.delete(t);let l=e,d=a;n=[e,r];s.push(n);for(;;){let t;if(i.has(o))t=o;else{if(!i.has(h))break;t=h}i.delete(t);[e,a,r,o,h]=t;if(l!==e){n.push(l,d,e,d===a?a:r);l=e}d=d===a?r:a}n.push(l,d)}return new HighlightOutline(s,this.#nn)}#cn(t){const e=this.#rn;let i=0,s=e.length-1;for(;i<=s;){const n=i+s>>1,a=e[n][0];if(a===t)return n;a<t?i=n+1:s=n-1}return s+1}#hn([,t,e]){const i=this.#cn(t);this.#rn.splice(i,0,[t,e])}#ln([,t,e]){const i=this.#cn(t);for(let s=i;s<this.#rn.length;s++){const[i,n]=this.#rn[s];if(i!==t)break;if(i===t&&n===e){this.#rn.splice(s,1);return}}for(let s=i-1;s>=0;s--){const[i,n]=this.#rn[s];if(i!==t)break;if(i===t&&n===e){this.#rn.splice(s,1);return}}}#on(t){const[e,i,s]=t,n=[[e,i,s]],a=this.#cn(s);for(let t=0;t<a;t++){const[i,s]=this.#rn[t];for(let t=0,a=n.length;t<a;t++){const[,r,o]=n[t];if(!(s<=r||o<=i))if(r>=i)if(o>s)n[t][1]=s;else{if(1===a)return[];n.splice(t,1);t--;a--}else{n[t][2]=i;o>s&&n.push([e,s,o])}}}return n}}class Outline{toSVGPath(){throw new Error("Abstract method `toSVGPath` must be implemented.")}get box(){throw new Error("Abstract getter `box` must be implemented.")}serialize(t,e){throw new Error("Abstract method `serialize` must be implemented.")}get free(){return this instanceof FreeHighlightOutline}}class HighlightOutline extends Outline{#nn;#un;constructor(t,e){super();this.#un=t;this.#nn=e}toSVGPath(){const t=[];for(const e of this.#un){let[i,s]=e;t.push(`M${i} ${s}`);for(let n=2;n<e.length;n+=2){const a=e[n],r=e[n+1];if(a===i){t.push(`V${r}`);s=r}else if(r===s){t.push(`H${a}`);i=a}}t.push("Z")}return t.join(" ")}serialize([t,e,i,s],n){const a=[],r=i-t,o=s-e;for(const e of this.#un){const i=new Array(e.length);for(let n=0;n<e.length;n+=2){i[n]=t+e[n]*r;i[n+1]=s-e[n+1]*o}a.push(i)}return a}get box(){return this.#nn}}class FreeOutliner{#nn;#pn=[];#gn;#mn;#fn=[];#bn=new Float64Array(18);#vn;#An;#yn;#wn;#xn;#En;#_n=[];static#Cn=8;static#Sn=2;static#Tn=FreeOutliner.#Cn+FreeOutliner.#Sn;constructor({x:t,y:e},i,s,n,a,r=0){this.#nn=i;this.#En=n*s;this.#mn=a;this.#bn.set([NaN,NaN,NaN,NaN,t,e],6);this.#gn=r;this.#wn=FreeOutliner.#Cn*s;this.#yn=FreeOutliner.#Tn*s;this.#xn=s;this.#_n.push(t,e)}get free(){return!0}isEmpty(){return isNaN(this.#bn[8])}#Mn(){const t=this.#bn.subarray(4,6),e=this.#bn.subarray(16,18),[i,s,n,a]=this.#nn;return[(this.#vn+(t[0]-e[0])/2-i)/n,(this.#An+(t[1]-e[1])/2-s)/a,(this.#vn+(e[0]-t[0])/2-i)/n,(this.#An+(e[1]-t[1])/2-s)/a]}add({x:t,y:e}){this.#vn=t;this.#An=e;const[i,s,n,a]=this.#nn;let[r,o,h,l]=this.#bn.subarray(8,12);const d=t-h,c=e-l,u=Math.hypot(d,c);if(u<this.#yn)return!1;const p=u-this.#wn,g=p/u,m=g*d,f=g*c;let b=r,v=o;r=h;o=l;h+=m;l+=f;this.#_n?.push(t,e);const A=m/p,y=-f/p*this.#En,w=A*this.#En;this.#bn.set(this.#bn.subarray(2,8),0);this.#bn.set([h+y,l+w],4);this.#bn.set(this.#bn.subarray(14,18),12);this.#bn.set([h-y,l-w],16);if(isNaN(this.#bn[6])){if(0===this.#fn.length){this.#bn.set([r+y,o+w],2);this.#fn.push(NaN,NaN,NaN,NaN,(r+y-i)/n,(o+w-s)/a);this.#bn.set([r-y,o-w],14);this.#pn.push(NaN,NaN,NaN,NaN,(r-y-i)/n,(o-w-s)/a)}this.#bn.set([b,v,r,o,h,l],6);return!this.isEmpty()}this.#bn.set([b,v,r,o,h,l],6);if(Math.abs(Math.atan2(v-o,b-r)-Math.atan2(f,m))<Math.PI/2){[r,o,h,l]=this.#bn.subarray(2,6);this.#fn.push(NaN,NaN,NaN,NaN,((r+h)/2-i)/n,((o+l)/2-s)/a);[r,o,b,v]=this.#bn.subarray(14,18);this.#pn.push(NaN,NaN,NaN,NaN,((b+r)/2-i)/n,((v+o)/2-s)/a);return!0}[b,v,r,o,h,l]=this.#bn.subarray(0,6);this.#fn.push(((b+5*r)/6-i)/n,((v+5*o)/6-s)/a,((5*r+h)/6-i)/n,((5*o+l)/6-s)/a,((r+h)/2-i)/n,((o+l)/2-s)/a);[h,l,r,o,b,v]=this.#bn.subarray(12,18);this.#pn.push(((b+5*r)/6-i)/n,((v+5*o)/6-s)/a,((5*r+h)/6-i)/n,((5*o+l)/6-s)/a,((r+h)/2-i)/n,((o+l)/2-s)/a);return!0}toSVGPath(){if(this.isEmpty())return"";const t=this.#fn,e=this.#pn,i=this.#bn.subarray(4,6),s=this.#bn.subarray(16,18),[n,a,r,o]=this.#nn,[h,l,d,c]=this.#Mn();if(isNaN(this.#bn[6])&&!this.isEmpty())return`M${(this.#bn[2]-n)/r} ${(this.#bn[3]-a)/o} L${(this.#bn[4]-n)/r} ${(this.#bn[5]-a)/o} L${h} ${l} L${d} ${c} L${(this.#bn[16]-n)/r} ${(this.#bn[17]-a)/o} L${(this.#bn[14]-n)/r} ${(this.#bn[15]-a)/o} Z`;const u=[];u.push(`M${t[4]} ${t[5]}`);for(let e=6;e<t.length;e+=6)isNaN(t[e])?u.push(`L${t[e+4]} ${t[e+5]}`):u.push(`C${t[e]} ${t[e+1]} ${t[e+2]} ${t[e+3]} ${t[e+4]} ${t[e+5]}`);u.push(`L${(i[0]-n)/r} ${(i[1]-a)/o} L${h} ${l} L${d} ${c} L${(s[0]-n)/r} ${(s[1]-a)/o}`);for(let t=e.length-6;t>=6;t-=6)isNaN(e[t])?u.push(`L${e[t+4]} ${e[t+5]}`):u.push(`C${e[t]} ${e[t+1]} ${e[t+2]} ${e[t+3]} ${e[t+4]} ${e[t+5]}`);u.push(`L${e[4]} ${e[5]} Z`);return u.join(" ")}getOutlines(){const t=this.#fn,e=this.#pn,i=this.#bn,s=i.subarray(4,6),n=i.subarray(16,18),[a,r,o,h]=this.#nn,l=new Float64Array((this.#_n?.length??0)+2);for(let t=0,e=l.length-2;t<e;t+=2){l[t]=(this.#_n[t]-a)/o;l[t+1]=(this.#_n[t+1]-r)/h}l[l.length-2]=(this.#vn-a)/o;l[l.length-1]=(this.#An-r)/h;const[d,c,u,p]=this.#Mn();if(isNaN(i[6])&&!this.isEmpty()){const t=new Float64Array(36);t.set([NaN,NaN,NaN,NaN,(i[2]-a)/o,(i[3]-r)/h,NaN,NaN,NaN,NaN,(i[4]-a)/o,(i[5]-r)/h,NaN,NaN,NaN,NaN,d,c,NaN,NaN,NaN,NaN,u,p,NaN,NaN,NaN,NaN,(i[16]-a)/o,(i[17]-r)/h,NaN,NaN,NaN,NaN,(i[14]-a)/o,(i[15]-r)/h],0);return new FreeHighlightOutline(t,l,this.#nn,this.#xn,this.#gn,this.#mn)}const g=new Float64Array(this.#fn.length+24+this.#pn.length);let m=t.length;for(let e=0;e<m;e+=2)if(isNaN(t[e]))g[e]=g[e+1]=NaN;else{g[e]=t[e];g[e+1]=t[e+1]}g.set([NaN,NaN,NaN,NaN,(s[0]-a)/o,(s[1]-r)/h,NaN,NaN,NaN,NaN,d,c,NaN,NaN,NaN,NaN,u,p,NaN,NaN,NaN,NaN,(n[0]-a)/o,(n[1]-r)/h],m);m+=24;for(let t=e.length-6;t>=6;t-=6)for(let i=0;i<6;i+=2)if(isNaN(e[t+i])){g[m]=g[m+1]=NaN;m+=2}else{g[m]=e[t+i];g[m+1]=e[t+i+1];m+=2}g.set([NaN,NaN,NaN,NaN,e[4],e[5]],m);return new FreeHighlightOutline(g,l,this.#nn,this.#xn,this.#gn,this.#mn)}}class FreeHighlightOutline extends Outline{#nn;#kn=null;#gn;#mn;#_n;#xn;#Pn;constructor(t,e,i,s,n,a){super();this.#Pn=t;this.#_n=e;this.#nn=i;this.#xn=s;this.#gn=n;this.#mn=a;this.#Dn(a);const{x:r,y:o,width:h,height:l}=this.#kn;for(let e=0,i=t.length;e<i;e+=2){t[e]=(t[e]-r)/h;t[e+1]=(t[e+1]-o)/l}for(let t=0,i=e.length;t<i;t+=2){e[t]=(e[t]-r)/h;e[t+1]=(e[t+1]-o)/l}}toSVGPath(){const t=[`M${this.#Pn[4]} ${this.#Pn[5]}`];for(let e=6,i=this.#Pn.length;e<i;e+=6)isNaN(this.#Pn[e])?t.push(`L${this.#Pn[e+4]} ${this.#Pn[e+5]}`):t.push(`C${this.#Pn[e]} ${this.#Pn[e+1]} ${this.#Pn[e+2]} ${this.#Pn[e+3]} ${this.#Pn[e+4]} ${this.#Pn[e+5]}`);t.push("Z");return t.join(" ")}serialize([t,e,i,s],n){const a=i-t,r=s-e;let o,h;switch(n){case 0:o=this.#Rn(this.#Pn,t,s,a,-r);h=this.#Rn(this.#_n,t,s,a,-r);break;case 90:o=this.#Fn(this.#Pn,t,e,a,r);h=this.#Fn(this.#_n,t,e,a,r);break;case 180:o=this.#Rn(this.#Pn,i,e,-a,r);h=this.#Rn(this.#_n,i,e,-a,r);break;case 270:o=this.#Fn(this.#Pn,i,s,-a,-r);h=this.#Fn(this.#_n,i,s,-a,-r)}return{outline:Array.from(o),points:[Array.from(h)]}}#Rn(t,e,i,s,n){const a=new Float64Array(t.length);for(let r=0,o=t.length;r<o;r+=2){a[r]=e+t[r]*s;a[r+1]=i+t[r+1]*n}return a}#Fn(t,e,i,s,n){const a=new Float64Array(t.length);for(let r=0,o=t.length;r<o;r+=2){a[r]=e+t[r+1]*s;a[r+1]=i+t[r]*n}return a}#Dn(t){const e=this.#Pn;let i=e[4],s=e[5],n=i,a=s,r=i,o=s,h=i,l=s;const d=t?Math.max:Math.min;for(let t=6,c=e.length;t<c;t+=6){if(isNaN(e[t])){n=Math.min(n,e[t+4]);a=Math.min(a,e[t+5]);r=Math.max(r,e[t+4]);o=Math.max(o,e[t+5]);if(l<e[t+5]){h=e[t+4];l=e[t+5]}else l===e[t+5]&&(h=d(h,e[t+4]))}else{const c=Util.bezierBoundingBox(i,s,...e.slice(t,t+6));n=Math.min(n,c[0]);a=Math.min(a,c[1]);r=Math.max(r,c[2]);o=Math.max(o,c[3]);if(l<c[3]){h=c[2];l=c[3]}else l===c[3]&&(h=d(h,c[2]))}i=e[t+4];s=e[t+5]}const c=n-this.#gn,u=a-this.#gn,p=r-n+2*this.#gn,g=o-a+2*this.#gn;this.#kn={x:c,y:u,width:p,height:g,lastPoint:[h,l]}}get box(){return this.#kn}getNewOutline(t,e){const{x:i,y:s,width:n,height:a}=this.#kn,[r,o,h,l]=this.#nn,d=n*h,c=a*l,u=i*h+r,p=s*l+o,g=new FreeOutliner({x:this.#_n[0]*d+u,y:this.#_n[1]*c+p},this.#nn,this.#xn,t,this.#mn,e??this.#gn);for(let t=2;t<this.#_n.length;t+=2)g.add({x:this.#_n[t]*d+u,y:this.#_n[t+1]*c+p});return g.getOutlines()}}class ColorPicker{#ns=this.#as.bind(this);#In=this.#r.bind(this);#Ln=null;#On=null;#Nn;#Bn=null;#Hn=!1;#zn=!1;#n=null;#Un;#u=null;#jn;static get _keyboardManager(){return shadow(this,"_keyboardManager",new KeyboardManager([[["Escape","mac+Escape"],ColorPicker.prototype._hideDropdownFromKeyboard],[[" ","mac+ "],ColorPicker.prototype._colorSelectFromKeyboard],[["ArrowDown","ArrowRight","mac+ArrowDown","mac+ArrowRight"],ColorPicker.prototype._moveToNext],[["ArrowUp","ArrowLeft","mac+ArrowUp","mac+ArrowLeft"],ColorPicker.prototype._moveToPrevious],[["Home","mac+Home"],ColorPicker.prototype._moveToBeginning],[["End","mac+End"],ColorPicker.prototype._moveToEnd]]))}constructor({editor:t=null,uiManager:e=null}){if(t){this.#zn=!1;this.#jn=g.HIGHLIGHT_COLOR;this.#n=t}else{this.#zn=!0;this.#jn=g.HIGHLIGHT_DEFAULT_COLOR}this.#u=t?._uiManager||e;this.#Un=this.#u._eventBus;this.#Nn=t?.color||this.#u?.highlightColors.values().next().value||"#FFFF98"}renderButton(){const t=this.#Ln=document.createElement("button");t.className="colorPicker";t.tabIndex="0";t.setAttribute("data-l10n-id","pdfjs-editor-colorpicker-button");t.setAttribute("aria-haspopup",!0);t.addEventListener("click",this.#$n.bind(this));t.addEventListener("keydown",this.#ns);const e=this.#On=document.createElement("span");e.className="swatch";e.setAttribute("aria-hidden",!0);e.style.backgroundColor=this.#Nn;t.append(e);return t}renderMainDropdown(){const t=this.#Bn=this.#Vn();t.setAttribute("aria-orientation","horizontal");t.setAttribute("aria-labelledby","highlightColorPickerLabel");return t}#Vn(){const t=document.createElement("div");t.addEventListener("contextmenu",noContextMenu);t.className="dropdown";t.role="listbox";t.setAttribute("aria-multiselectable",!1);t.setAttribute("aria-orientation","vertical");t.setAttribute("data-l10n-id","pdfjs-editor-colorpicker-dropdown");for(const[e,i]of this.#u.highlightColors){const s=document.createElement("button");s.tabIndex="0";s.role="option";s.setAttribute("data-color",i);s.title=e;s.setAttribute("data-l10n-id",`pdfjs-editor-colorpicker-${e}`);const n=document.createElement("span");s.append(n);n.className="swatch";n.style.backgroundColor=i;s.setAttribute("aria-selected",i===this.#Nn);s.addEventListener("click",this.#Gn.bind(this,i));t.append(s)}t.addEventListener("keydown",this.#ns);return t}#Gn(t,e){e.stopPropagation();this.#Un.dispatch("switchannotationeditorparams",{source:this,type:this.#jn,value:t})}_colorSelectFromKeyboard(t){if(t.target===this.#Ln){this.#$n(t);return}const e=t.target.getAttribute("data-color");e&&this.#Gn(e,t)}_moveToNext(t){this.#Wn?t.target!==this.#Ln?t.target.nextSibling?.focus():this.#Bn.firstChild?.focus():this.#$n(t)}_moveToPrevious(t){if(t.target!==this.#Bn?.firstChild&&t.target!==this.#Ln){this.#Wn||this.#$n(t);t.target.previousSibling?.focus()}else this.#Wn&&this._hideDropdownFromKeyboard()}_moveToBeginning(t){this.#Wn?this.#Bn.firstChild?.focus():this.#$n(t)}_moveToEnd(t){this.#Wn?this.#Bn.lastChild?.focus():this.#$n(t)}#as(t){ColorPicker._keyboardManager.exec(this,t)}#$n(t){if(this.#Wn){this.hideDropdown();return}this.#Hn=0===t.detail;window.addEventListener("pointerdown",this.#In);if(this.#Bn){this.#Bn.classList.remove("hidden");return}const e=this.#Bn=this.#Vn();this.#Ln.append(e)}#r(t){this.#Bn?.contains(t.target)||this.hideDropdown()}hideDropdown(){this.#Bn?.classList.add("hidden");window.removeEventListener("pointerdown",this.#In)}get#Wn(){return this.#Bn&&!this.#Bn.classList.contains("hidden")}_hideDropdownFromKeyboard(){if(!this.#zn)if(this.#Wn){this.hideDropdown();this.#Ln.focus({preventScroll:!0,focusVisible:this.#Hn})}else this.#n?.unselect()}updateColor(t){this.#On&&(this.#On.style.backgroundColor=t);if(!this.#Bn)return;const e=this.#u.highlightColors.values();for(const i of this.#Bn.children)i.setAttribute("aria-selected",e.next().value===t)}destroy(){this.#Ln?.remove();this.#Ln=null;this.#On=null;this.#Bn?.remove();this.#Bn=null}}class HighlightEditor extends AnnotationEditor{#qn=null;#Xn=0;#Kn;#Yn=null;#s=null;#Qn=null;#Jn=null;#Zn=0;#ta=null;#ea=null;#f=null;#ia=!1;#at=this.#sa.bind(this);#na=null;#aa;#ra=null;#oa="";#En;#ha="";static _defaultColor=null;static _defaultOpacity=1;static _defaultThickness=12;static _l10nPromise;static _type="highlight";static _editorType=p.HIGHLIGHT;static _freeHighlightId=-1;static _freeHighlight=null;static _freeHighlightClipId="";static get _keyboardManager(){const t=HighlightEditor.prototype;return shadow(this,"_keyboardManager",new KeyboardManager([[["ArrowLeft","mac+ArrowLeft"],t._moveCaret,{args:[0]}],[["ArrowRight","mac+ArrowRight"],t._moveCaret,{args:[1]}],[["ArrowUp","mac+ArrowUp"],t._moveCaret,{args:[2]}],[["ArrowDown","mac+ArrowDown"],t._moveCaret,{args:[3]}]]))}constructor(t){super({...t,name:"highlightEditor"});this.color=t.color||HighlightEditor._defaultColor;this.#En=t.thickness||HighlightEditor._defaultThickness;this.#aa=t.opacity||HighlightEditor._defaultOpacity;this.#Kn=t.boxes||null;this.#ha=t.methodOfCreation||"";this.#oa=t.text||"";this._isDraggable=!1;if(t.highlightId>-1){this.#ia=!0;this.#la(t);this.#da()}else{this.#qn=t.anchorNode;this.#Xn=t.anchorOffset;this.#Jn=t.focusNode;this.#Zn=t.focusOffset;this.#ca();this.#da();this.rotate(this.rotation)}}get telemetryInitialData(){return{action:"added",type:this.#ia?"free_highlight":"highlight",color:this._uiManager.highlightColorNames.get(this.color),thickness:this.#En,methodOfCreation:this.#ha}}get telemetryFinalData(){return{type:"highlight",color:this._uiManager.highlightColorNames.get(this.color)}}static computeTelemetryFinalData(t){return{numberOfColors:t.get("color").size}}#ca(){const t=new Outliner(this.#Kn,.001);this.#ea=t.getOutlines();({x:this.x,y:this.y,width:this.width,height:this.height}=this.#ea.box);const e=new Outliner(this.#Kn,.0025,.001,"ltr"===this._uiManager.direction);this.#Qn=e.getOutlines();const{lastPoint:i}=this.#Qn.box;this.#na=[(i[0]-this.x)/this.width,(i[1]-this.y)/this.height]}#la({highlightOutlines:t,highlightId:e,clipPathId:i}){this.#ea=t;this.#Qn=t.getNewOutline(this.#En/2+1.5,.0025);if(e>=0){this.#f=e;this.#Yn=i;this.parent.drawLayer.finalizeLine(e,t);this.#ra=this.parent.drawLayer.highlightOutline(this.#Qn)}else if(this.parent){const e=this.parent.viewport.rotation;this.parent.drawLayer.updateLine(this.#f,t);this.parent.drawLayer.updateBox(this.#f,HighlightEditor.#ua(this.#ea.box,(e-this.rotation+360)%360));this.parent.drawLayer.updateLine(this.#ra,this.#Qn);this.parent.drawLayer.updateBox(this.#ra,HighlightEditor.#ua(this.#Qn.box,e))}const{x:s,y:n,width:a,height:r}=t.box;switch(this.rotation){case 0:this.x=s;this.y=n;this.width=a;this.height=r;break;case 90:{const[t,e]=this.parentDimensions;this.x=n;this.y=1-s;this.width=a*e/t;this.height=r*t/e;break}case 180:this.x=1-s;this.y=1-n;this.width=a;this.height=r;break;case 270:{const[t,e]=this.parentDimensions;this.x=1-n;this.y=s;this.width=a*e/t;this.height=r*t/e;break}}const{lastPoint:o}=this.#Qn.box;this.#na=[(o[0]-s)/a,(o[1]-n)/r]}static initialize(t,e){AnnotationEditor.initialize(t,e);HighlightEditor._defaultColor||=e.highlightColors?.values().next().value||"#fff066"}static updateDefaultParams(t,e){switch(t){case g.HIGHLIGHT_DEFAULT_COLOR:HighlightEditor._defaultColor=e;break;case g.HIGHLIGHT_THICKNESS:HighlightEditor._defaultThickness=e}}translateInPage(t,e){}get toolbarPosition(){return this.#na}updateParams(t,e){switch(t){case g.HIGHLIGHT_COLOR:this.#Ys(e);break;case g.HIGHLIGHT_THICKNESS:this.#pa(e)}}static get defaultPropertiesToUpdate(){return[[g.HIGHLIGHT_DEFAULT_COLOR,HighlightEditor._defaultColor],[g.HIGHLIGHT_THICKNESS,HighlightEditor._defaultThickness]]}get propertiesToUpdate(){return[[g.HIGHLIGHT_COLOR,this.color||HighlightEditor._defaultColor],[g.HIGHLIGHT_THICKNESS,this.#En||HighlightEditor._defaultThickness],[g.HIGHLIGHT_FREE,this.#ia]]}#Ys(t){const setColor=t=>{this.color=t;this.parent?.drawLayer.changeColor(this.#f,t);this.#s?.updateColor(t)},e=this.color;this.addCommands({cmd:setColor.bind(this,t),undo:setColor.bind(this,e),post:this._uiManager.updateUI.bind(this._uiManager,this),mustExec:!0,type:g.HIGHLIGHT_COLOR,overwriteIfSameType:!0,keepUndo:!0});this._reportTelemetry({action:"color_changed",color:this._uiManager.highlightColorNames.get(t)},!0)}#pa(t){const e=this.#En,setThickness=t=>{this.#En=t;this.#ga(t)};this.addCommands({cmd:setThickness.bind(this,t),undo:setThickness.bind(this,e),post:this._uiManager.updateUI.bind(this._uiManager,this),mustExec:!0,type:g.INK_THICKNESS,overwriteIfSameType:!0,keepUndo:!0});this._reportTelemetry({action:"thickness_changed",thickness:t},!0)}async addEditToolbar(){const t=await super.addEditToolbar();if(!t)return null;if(this._uiManager.highlightColors){this.#s=new ColorPicker({editor:this});t.addColorPicker(this.#s)}return t}disableEditing(){super.disableEditing();this.div.classList.toggle("disabled",!0)}enableEditing(){super.enableEditing();this.div.classList.toggle("disabled",!1)}fixAndSetPosition(){return super.fixAndSetPosition(this.#ma())}getBaseTranslation(){return[0,0]}getRect(t,e){return super.getRect(t,e,this.#ma())}onceAdded(){this.parent.addUndoableEditor(this);this.div.focus()}remove(){this.#fa();this._reportTelemetry({action:"deleted"});super.remove()}rebuild(){if(this.parent){super.rebuild();if(null!==this.div){this.#da();this.isAttachedToDOM||this.parent.add(this)}}}setParent(t){let e=!1;if(this.parent&&!t)this.#fa();else if(t){this.#da(t);e=!this.parent&&this.div?.classList.contains("selectedEditor")}super.setParent(t);this.show(this._isVisible);e&&this.select()}#ga(t){if(!this.#ia)return;this.#la({highlightOutlines:this.#ea.getNewOutline(t/2)});this.fixAndSetPosition();const[e,i]=this.parentDimensions;this.setDims(this.width*e,this.height*i)}#fa(){if(null!==this.#f&&this.parent){this.parent.drawLayer.remove(this.#f);this.#f=null;this.parent.drawLayer.remove(this.#ra);this.#ra=null}}#da(t=this.parent){if(null===this.#f){({id:this.#f,clipPathId:this.#Yn}=t.drawLayer.highlight(this.#ea,this.color,this.#aa));this.#ra=t.drawLayer.highlightOutline(this.#Qn);this.#ta&&(this.#ta.style.clipPath=this.#Yn)}}static#ua({x:t,y:e,width:i,height:s},n){switch(n){case 90:return{x:1-e-s,y:t,width:s,height:i};case 180:return{x:1-t-i,y:1-e-s,width:i,height:s};case 270:return{x:e,y:1-t-i,width:s,height:i}}return{x:t,y:e,width:i,height:s}}rotate(t){const{drawLayer:e}=this.parent;let i;if(this.#ia){t=(t-this.rotation+360)%360;i=HighlightEditor.#ua(this.#ea.box,t)}else i=HighlightEditor.#ua(this,t);e.rotate(this.#f,t);e.rotate(this.#ra,t);e.updateBox(this.#f,i);e.updateBox(this.#ra,HighlightEditor.#ua(this.#Qn.box,t))}render(){if(this.div)return this.div;const t=super.render();if(this.#oa){t.setAttribute("aria-label",this.#oa);t.setAttribute("role","mark")}this.#ia?t.classList.add("free"):this.div.addEventListener("keydown",this.#at);const e=this.#ta=document.createElement("div");t.append(e);e.setAttribute("aria-hidden","true");e.className="internal";e.style.clipPath=this.#Yn;const[i,s]=this.parentDimensions;this.setDims(this.width*i,this.height*s);bindEvents(this,this.#ta,["pointerover","pointerleave"]);this.enableEditing();return t}pointerover(){this.parent.drawLayer.addClass(this.#ra,"hovered")}pointerleave(){this.parent.drawLayer.removeClass(this.#ra,"hovered")}#sa(t){HighlightEditor._keyboardManager.exec(this,t)}_moveCaret(t){this.parent.unselect(this);switch(t){case 0:case 2:this.#ba(!0);break;case 1:case 3:this.#ba(!1)}}#ba(t){if(!this.#qn)return;const e=window.getSelection();t?e.setPosition(this.#qn,this.#Xn):e.setPosition(this.#Jn,this.#Zn)}select(){super.select();if(this.#ra){this.parent?.drawLayer.removeClass(this.#ra,"hovered");this.parent?.drawLayer.addClass(this.#ra,"selected")}}unselect(){super.unselect();if(this.#ra){this.parent?.drawLayer.removeClass(this.#ra,"selected");this.#ia||this.#ba(!1)}}get _mustFixPosition(){return!this.#ia}show(t=this._isVisible){super.show(t);if(this.parent){this.parent.drawLayer.show(this.#f,t);this.parent.drawLayer.show(this.#ra,t)}}#ma(){return this.#ia?this.rotation:0}#va(){if(this.#ia)return null;const[t,e]=this.pageDimensions,i=this.#Kn,s=new Array(8*i.length);let n=0;for(const{x:a,y:r,width:o,height:h}of i){const i=a*t,l=(1-r-h)*e;s[n]=s[n+4]=i;s[n+1]=s[n+3]=l;s[n+2]=s[n+6]=i+o*t;s[n+5]=s[n+7]=l+h*e;n+=8}return s}#Aa(t){return this.#ea.serialize(t,this.#ma())}static startHighlighting(t,e,{target:i,x:s,y:n}){const{x:a,y:r,width:o,height:h}=i.getBoundingClientRect(),pointerMove=e=>{this.#ya(t,e)},l={capture:!0,passive:!1},pointerDown=t=>{t.preventDefault();t.stopPropagation()},pointerUpCallback=e=>{i.removeEventListener("pointermove",pointerMove);window.removeEventListener("blur",pointerUpCallback);window.removeEventListener("pointerup",pointerUpCallback);window.removeEventListener("pointerdown",pointerDown,l);window.removeEventListener("contextmenu",noContextMenu);this.#wa(t,e)};window.addEventListener("blur",pointerUpCallback);window.addEventListener("pointerup",pointerUpCallback);window.addEventListener("pointerdown",pointerDown,l);window.addEventListener("contextmenu",noContextMenu);i.addEventListener("pointermove",pointerMove);this._freeHighlight=new FreeOutliner({x:s,y:n},[a,r,o,h],t.scale,this._defaultThickness/2,e,.001);({id:this._freeHighlightId,clipPathId:this._freeHighlightClipId}=t.drawLayer.highlight(this._freeHighlight,this._defaultColor,this._defaultOpacity,!0))}static#ya(t,e){this._freeHighlight.add(e)&&t.drawLayer.updatePath(this._freeHighlightId,this._freeHighlight)}static#wa(t,e){this._freeHighlight.isEmpty()?t.drawLayer.removeFreeHighlight(this._freeHighlightId):t.createAndAddNewEditor(e,!1,{highlightId:this._freeHighlightId,highlightOutlines:this._freeHighlight.getOutlines(),clipPathId:this._freeHighlightClipId,methodOfCreation:"main_toolbar"});this._freeHighlightId=-1;this._freeHighlight=null;this._freeHighlightClipId=""}static deserialize(t,e,i){const s=super.deserialize(t,e,i),{rect:[n,a,r,o],color:h,quadPoints:l}=t;s.color=Util.makeHexColor(...h);s.#aa=t.opacity;const[d,c]=s.pageDimensions;s.width=(r-n)/d;s.height=(o-a)/c;const u=s.#Kn=[];for(let t=0;t<l.length;t+=8)u.push({x:(l[4]-r)/d,y:(o-(1-l[t+5]))/c,width:(l[t+2]-l[t])/d,height:(l[t+5]-l[t+1])/c});s.#ca();return s}serialize(t=!1){if(this.isEmpty()||t)return null;const e=this.getRect(0,0),i=AnnotationEditor._colorManager.convert(this.color);return{annotationType:p.HIGHLIGHT,color:i,opacity:this.#aa,thickness:this.#En,quadPoints:this.#va(),outlines:this.#Aa(e),pageIndex:this.pageIndex,rect:e,rotation:this.#ma(),structTreeParentId:this._structTreeParentId}}static canCreateNewEmptyEditor(){return!1}}class InkEditor extends AnnotationEditor{#xa=0;#Ea=0;#_a=this.canvasPointermove.bind(this);#Ca=this.canvasPointerleave.bind(this);#Sa=this.canvasPointerup.bind(this);#Ta=this.canvasPointerdown.bind(this);#Ma=null;#ka=new Path2D;#Pa=!1;#Da=!1;#Ra=!1;#Fa=null;#Ia=0;#La=0;#Oa=null;static _defaultColor=null;static _defaultOpacity=1;static _defaultThickness=1;static _type="ink";static _editorType=p.INK;constructor(t){super({...t,name:"inkEditor"});this.color=t.color||null;this.thickness=t.thickness||null;this.opacity=t.opacity||null;this.paths=[];this.bezierPath2D=[];this.allRawPaths=[];this.currentPath=[];this.scaleFactor=1;this.translationX=this.translationY=0;this.x=0;this.y=0;this._willKeepAspectRatio=!0}static initialize(t,e){AnnotationEditor.initialize(t,e)}static updateDefaultParams(t,e){switch(t){case g.INK_THICKNESS:InkEditor._defaultThickness=e;break;case g.INK_COLOR:InkEditor._defaultColor=e;break;case g.INK_OPACITY:InkEditor._defaultOpacity=e/100}}updateParams(t,e){switch(t){case g.INK_THICKNESS:this.#pa(e);break;case g.INK_COLOR:this.#Ys(e);break;case g.INK_OPACITY:this.#Na(e)}}static get defaultPropertiesToUpdate(){return[[g.INK_THICKNESS,InkEditor._defaultThickness],[g.INK_COLOR,InkEditor._defaultColor||AnnotationEditor._defaultLineColor],[g.INK_OPACITY,Math.round(100*InkEditor._defaultOpacity)]]}get propertiesToUpdate(){return[[g.INK_THICKNESS,this.thickness||InkEditor._defaultThickness],[g.INK_COLOR,this.color||InkEditor._defaultColor||AnnotationEditor._defaultLineColor],[g.INK_OPACITY,Math.round(100*(this.opacity??InkEditor._defaultOpacity))]]}#pa(t){const setThickness=t=>{this.thickness=t;this.#Ba()},e=this.thickness;this.addCommands({cmd:setThickness.bind(this,t),undo:setThickness.bind(this,e),post:this._uiManager.updateUI.bind(this._uiManager,this),mustExec:!0,type:g.INK_THICKNESS,overwriteIfSameType:!0,keepUndo:!0})}#Ys(t){const setColor=t=>{this.color=t;this.#Ha()},e=this.color;this.addCommands({cmd:setColor.bind(this,t),undo:setColor.bind(this,e),post:this._uiManager.updateUI.bind(this._uiManager,this),mustExec:!0,type:g.INK_COLOR,overwriteIfSameType:!0,keepUndo:!0})}#Na(t){const setOpacity=t=>{this.opacity=t;this.#Ha()};t/=100;const e=this.opacity;this.addCommands({cmd:setOpacity.bind(this,t),undo:setOpacity.bind(this,e),post:this._uiManager.updateUI.bind(this._uiManager,this),mustExec:!0,type:g.INK_OPACITY,overwriteIfSameType:!0,keepUndo:!0})}rebuild(){if(this.parent){super.rebuild();if(null!==this.div){if(!this.canvas){this.#za();this.#Ua()}if(!this.isAttachedToDOM){this.parent.add(this);this.#ja()}this.#Ba()}}}remove(){if(null!==this.canvas){this.isEmpty()||this.commit();this.canvas.width=this.canvas.height=0;this.canvas.remove();this.canvas=null;if(this.#Ma){clearTimeout(this.#Ma);this.#Ma=null}this.#Fa.disconnect();this.#Fa=null;super.remove()}}setParent(t){!this.parent&&t?this._uiManager.removeShouldRescale(this):this.parent&&null===t&&this._uiManager.addShouldRescale(this);super.setParent(t)}onScaleChanging(){const[t,e]=this.parentDimensions,i=this.width*t,s=this.height*e;this.setDimensions(i,s)}enableEditMode(){if(!this.#Pa&&null!==this.canvas){super.enableEditMode();this._isDraggable=!1;this.canvas.addEventListener("pointerdown",this.#Ta)}}disableEditMode(){if(this.isInEditMode()&&null!==this.canvas){super.disableEditMode();this._isDraggable=!this.isEmpty();this.div.classList.remove("editing");this.canvas.removeEventListener("pointerdown",this.#Ta)}}onceAdded(){this._isDraggable=!this.isEmpty()}isEmpty(){return 0===this.paths.length||1===this.paths.length&&0===this.paths[0].length}#$a(){const{parentRotation:t,parentDimensions:[e,i]}=this;switch(t){case 90:return[0,i,i,e];case 180:return[e,i,e,i];case 270:return[e,0,i,e];default:return[0,0,e,i]}}#Va(){const{ctx:t,color:e,opacity:i,thickness:s,parentScale:n,scaleFactor:a}=this;t.lineWidth=s*n/a;t.lineCap="round";t.lineJoin="round";t.miterLimit=10;t.strokeStyle=`${e}${function opacityToHex(t){return Math.round(Math.min(255,Math.max(1,255*t))).toString(16).padStart(2,"0")}(i)}`}#Ga(t,e){this.canvas.addEventListener("contextmenu",noContextMenu);this.canvas.addEventListener("pointerleave",this.#Ca);this.canvas.addEventListener("pointermove",this.#_a);this.canvas.addEventListener("pointerup",this.#Sa);this.canvas.removeEventListener("pointerdown",this.#Ta);this.isEditing=!0;if(!this.#Ra){this.#Ra=!0;this.#ja();this.thickness||=InkEditor._defaultThickness;this.color||=InkEditor._defaultColor||AnnotationEditor._defaultLineColor;this.opacity??=InkEditor._defaultOpacity}this.currentPath.push([t,e]);this.#Da=!1;this.#Va();this.#Oa=()=>{this.#Wa();this.#Oa&&window.requestAnimationFrame(this.#Oa)};window.requestAnimationFrame(this.#Oa)}#qa(t,e){const[i,s]=this.currentPath.at(-1);if(this.currentPath.length>1&&t===i&&e===s)return;const n=this.currentPath;let a=this.#ka;n.push([t,e]);this.#Da=!0;if(n.length<=2){a.moveTo(...n[0]);a.lineTo(t,e)}else{if(3===n.length){this.#ka=a=new Path2D;a.moveTo(...n[0])}this.#Xa(a,...n.at(-3),...n.at(-2),t,e)}}#Ka(){if(0===this.currentPath.length)return;const t=this.currentPath.at(-1);this.#ka.lineTo(...t)}#Ya(t,e){this.#Oa=null;t=Math.min(Math.max(t,0),this.canvas.width);e=Math.min(Math.max(e,0),this.canvas.height);this.#qa(t,e);this.#Ka();let i;if(1!==this.currentPath.length)i=this.#Qa();else{const s=[t,e];i=[[s,s.slice(),s.slice(),s]]}const s=this.#ka,n=this.currentPath;this.currentPath=[];this.#ka=new Path2D;this.addCommands({cmd:()=>{this.allRawPaths.push(n);this.paths.push(i);this.bezierPath2D.push(s);this._uiManager.rebuild(this)},undo:()=>{this.allRawPaths.pop();this.paths.pop();this.bezierPath2D.pop();if(0===this.paths.length)this.remove();else{if(!this.canvas){this.#za();this.#Ua()}this.#Ba()}},mustExec:!0})}#Wa(){if(!this.#Da)return;this.#Da=!1;const t=Math.ceil(this.thickness*this.parentScale),e=this.currentPath.slice(-3),i=e.map((t=>t[0])),s=e.map((t=>t[1])),{ctx:n}=(Math.min(...i),Math.max(...i),Math.min(...s),Math.max(...s),this);n.save();n.clearRect(0,0,this.canvas.width,this.canvas.height);for(const t of this.bezierPath2D)n.stroke(t);n.stroke(this.#ka);n.restore()}#Xa(t,e,i,s,n,a,r){const o=(e+s)/2,h=(i+n)/2,l=(s+a)/2,d=(n+r)/2;t.bezierCurveTo(o+2*(s-o)/3,h+2*(n-h)/3,l+2*(s-l)/3,d+2*(n-d)/3,l,d)}#Qa(){const t=this.currentPath;if(t.length<=2)return[[t[0],t[0],t.at(-1),t.at(-1)]];const e=[];let i,[s,n]=t[0];for(i=1;i<t.length-2;i++){const[a,r]=t[i],[o,h]=t[i+1],l=(a+o)/2,d=(r+h)/2,c=[s+2*(a-s)/3,n+2*(r-n)/3],u=[l+2*(a-l)/3,d+2*(r-d)/3];e.push([[s,n],c,u,[l,d]]);[s,n]=[l,d]}const[a,r]=t[i],[o,h]=t[i+1],l=[s+2*(a-s)/3,n+2*(r-n)/3],d=[o+2*(a-o)/3,h+2*(r-h)/3];e.push([[s,n],l,d,[o,h]]);return e}#Ha(){if(this.isEmpty()){this.#Ja();return}this.#Va();const{canvas:t,ctx:e}=this;e.setTransform(1,0,0,1,0,0);e.clearRect(0,0,t.width,t.height);this.#Ja();for(const t of this.bezierPath2D)e.stroke(t)}commit(){if(!this.#Pa){super.commit();this.isEditing=!1;this.disableEditMode();this.setInForeground();this.#Pa=!0;this.div.classList.add("disabled");this.#Ba(!0);this.select();this.parent.addInkEditorIfNeeded(!0);this.moveInDOM();this.div.focus({preventScroll:!0})}}focusin(t){if(this._focusEventsAllowed){super.focusin(t);this.enableEditMode()}}canvasPointerdown(t){if(0===t.button&&this.isInEditMode()&&!this.#Pa){this.setInForeground();t.preventDefault();this.div.contains(document.activeElement)||this.div.focus({preventScroll:!0});this.#Ga(t.offsetX,t.offsetY)}}canvasPointermove(t){t.preventDefault();this.#qa(t.offsetX,t.offsetY)}canvasPointerup(t){t.preventDefault();this.#Za(t)}canvasPointerleave(t){this.#Za(t)}#Za(t){this.canvas.removeEventListener("pointerleave",this.#Ca);this.canvas.removeEventListener("pointermove",this.#_a);this.canvas.removeEventListener("pointerup",this.#Sa);this.canvas.addEventListener("pointerdown",this.#Ta);this.#Ma&&clearTimeout(this.#Ma);this.#Ma=setTimeout((()=>{this.#Ma=null;this.canvas.removeEventListener("contextmenu",noContextMenu)}),10);this.#Ya(t.offsetX,t.offsetY);this.addToAnnotationStorage();this.setInBackground()}#za(){this.canvas=document.createElement("canvas");this.canvas.width=this.canvas.height=0;this.canvas.className="inkEditorCanvas";this.canvas.setAttribute("data-l10n-id","pdfjs-ink-canvas");this.div.append(this.canvas);this.ctx=this.canvas.getContext("2d")}#Ua(){this.#Fa=new ResizeObserver((t=>{const e=t[0].contentRect;e.width&&e.height&&this.setDimensions(e.width,e.height)}));this.#Fa.observe(this.div)}get isResizable(){return!this.isEmpty()&&this.#Pa}render(){if(this.div)return this.div;let t,e;if(this.width){t=this.x;e=this.y}super.render();this.div.setAttribute("data-l10n-id","pdfjs-ink");const[i,s,n,a]=this.#$a();this.setAt(i,s,0,0);this.setDims(n,a);this.#za();if(this.width){const[i,s]=this.parentDimensions;this.setAspectRatio(this.width*i,this.height*s);this.setAt(t*i,e*s,this.width*i,this.height*s);this.#Ra=!0;this.#ja();this.setDims(this.width*i,this.height*s);this.#Ha();this.div.classList.add("disabled")}else{this.div.classList.add("editing");this.enableEditMode()}this.#Ua();return this.div}#ja(){if(!this.#Ra)return;const[t,e]=this.parentDimensions;this.canvas.width=Math.ceil(this.width*t);this.canvas.height=Math.ceil(this.height*e);this.#Ja()}setDimensions(t,e){const i=Math.round(t),s=Math.round(e);if(this.#Ia===i&&this.#La===s)return;this.#Ia=i;this.#La=s;this.canvas.style.visibility="hidden";const[n,a]=this.parentDimensions;this.width=t/n;this.height=e/a;this.fixAndSetPosition();this.#Pa&&this.#tr(t,e);this.#ja();this.#Ha();this.canvas.style.visibility="visible";this.fixDims()}#tr(t,e){const i=this.#er(),s=(t-i)/this.#Ea,n=(e-i)/this.#xa;this.scaleFactor=Math.min(s,n)}#Ja(){const t=this.#er()/2;this.ctx.setTransform(this.scaleFactor,0,0,this.scaleFactor,this.translationX*this.scaleFactor+t,this.translationY*this.scaleFactor+t)}static#ir(t){const e=new Path2D;for(let i=0,s=t.length;i<s;i++){const[s,n,a,r]=t[i];0===i&&e.moveTo(...s);e.bezierCurveTo(n[0],n[1],a[0],a[1],r[0],r[1])}return e}static#sr(t,e,i){const[s,n,a,r]=e;switch(i){case 0:for(let e=0,i=t.length;e<i;e+=2){t[e]+=s;t[e+1]=r-t[e+1]}break;case 90:for(let e=0,i=t.length;e<i;e+=2){const i=t[e];t[e]=t[e+1]+s;t[e+1]=i+n}break;case 180:for(let e=0,i=t.length;e<i;e+=2){t[e]=a-t[e];t[e+1]+=n}break;case 270:for(let e=0,i=t.length;e<i;e+=2){const i=t[e];t[e]=a-t[e+1];t[e+1]=r-i}break;default:throw new Error("Invalid rotation")}return t}static#nr(t,e,i){const[s,n,a,r]=e;switch(i){case 0:for(let e=0,i=t.length;e<i;e+=2){t[e]-=s;t[e+1]=r-t[e+1]}break;case 90:for(let e=0,i=t.length;e<i;e+=2){const i=t[e];t[e]=t[e+1]-n;t[e+1]=i-s}break;case 180:for(let e=0,i=t.length;e<i;e+=2){t[e]=a-t[e];t[e+1]-=n}break;case 270:for(let e=0,i=t.length;e<i;e+=2){const i=t[e];t[e]=r-t[e+1];t[e+1]=a-i}break;default:throw new Error("Invalid rotation")}return t}#ar(t,e,i,s){const n=[],a=this.thickness/2,r=t*e+a,o=t*i+a;for(const e of this.paths){const i=[],a=[];for(let s=0,n=e.length;s<n;s++){const[h,l,d,c]=e[s];if(h[0]===c[0]&&h[1]===c[1]&&1===n){const e=t*h[0]+r,s=t*h[1]+o;i.push(e,s);a.push(e,s);break}const u=t*h[0]+r,p=t*h[1]+o,g=t*l[0]+r,m=t*l[1]+o,f=t*d[0]+r,b=t*d[1]+o,v=t*c[0]+r,A=t*c[1]+o;if(0===s){i.push(u,p);a.push(u,p)}i.push(g,m,f,b,v,A);a.push(g,m);s===n-1&&a.push(v,A)}n.push({bezier:InkEditor.#sr(i,s,this.rotation),points:InkEditor.#sr(a,s,this.rotation)})}return n}#rr(){let t=1/0,e=-1/0,i=1/0,s=-1/0;for(const n of this.paths)for(const[a,r,o,h]of n){const n=Util.bezierBoundingBox(...a,...r,...o,...h);t=Math.min(t,n[0]);i=Math.min(i,n[1]);e=Math.max(e,n[2]);s=Math.max(s,n[3])}return[t,i,e,s]}#er(){return this.#Pa?Math.ceil(this.thickness*this.parentScale):0}#Ba(t=!1){if(this.isEmpty())return;if(!this.#Pa){this.#Ha();return}const e=this.#rr(),i=this.#er();this.#Ea=Math.max(AnnotationEditor.MIN_SIZE,e[2]-e[0]);this.#xa=Math.max(AnnotationEditor.MIN_SIZE,e[3]-e[1]);const s=Math.ceil(i+this.#Ea*this.scaleFactor),n=Math.ceil(i+this.#xa*this.scaleFactor),[a,r]=this.parentDimensions;this.width=s/a;this.height=n/r;this.setAspectRatio(s,n);const o=this.translationX,h=this.translationY;this.translationX=-e[0];this.translationY=-e[1];this.#ja();this.#Ha();this.#Ia=s;this.#La=n;this.setDims(s,n);const l=t?i/this.scaleFactor/2:0;this.translate(o-this.translationX-l,h-this.translationY-l)}static deserialize(t,e,i){if(t instanceof InkAnnotationElement)return null;const s=super.deserialize(t,e,i);s.thickness=t.thickness;s.color=Util.makeHexColor(...t.color);s.opacity=t.opacity;const[n,a]=s.pageDimensions,r=s.width*n,o=s.height*a,h=s.parentScale,l=t.thickness/2;s.#Pa=!0;s.#Ia=Math.round(r);s.#La=Math.round(o);const{paths:d,rect:c,rotation:u}=t;for(let{bezier:t}of d){t=InkEditor.#nr(t,c,u);const e=[];s.paths.push(e);let i=h*(t[0]-l),n=h*(t[1]-l);for(let s=2,a=t.length;s<a;s+=6){const a=h*(t[s]-l),r=h*(t[s+1]-l),o=h*(t[s+2]-l),d=h*(t[s+3]-l),c=h*(t[s+4]-l),u=h*(t[s+5]-l);e.push([[i,n],[a,r],[o,d],[c,u]]);i=c;n=u}const a=this.#ir(e);s.bezierPath2D.push(a)}const p=s.#rr();s.#Ea=Math.max(AnnotationEditor.MIN_SIZE,p[2]-p[0]);s.#xa=Math.max(AnnotationEditor.MIN_SIZE,p[3]-p[1]);s.#tr(r,o);return s}serialize(){if(this.isEmpty())return null;const t=this.getRect(0,0),e=AnnotationEditor._colorManager.convert(this.ctx.strokeStyle);return{annotationType:p.INK,color:e,thickness:this.thickness,opacity:this.opacity,paths:this.#ar(this.scaleFactor/this.parentScale,this.translationX,this.translationY,t),pageIndex:this.pageIndex,rect:t,rotation:this.rotation,structTreeParentId:this._structTreeParentId}}}class StampEditor extends AnnotationEditor{#or=null;#hr=null;#lr=null;#dr=null;#cr=null;#ur="";#pr=null;#Fa=null;#gr=null;#mr=!1;#fr=!1;static _type="stamp";static _editorType=p.STAMP;constructor(t){super({...t,name:"stampEditor"});this.#dr=t.bitmapUrl;this.#cr=t.bitmapFile}static initialize(t,e){AnnotationEditor.initialize(t,e)}static get supportedTypes(){return shadow(this,"supportedTypes",["apng","avif","bmp","gif","jpeg","png","svg+xml","webp","x-icon"].map((t=>`image/${t}`)))}static get supportedTypesStr(){return shadow(this,"supportedTypesStr",this.supportedTypes.join(","))}static isHandlingMimeForPasting(t){return this.supportedTypes.includes(t)}static paste(t,e){e.pasteEditor(p.STAMP,{bitmapFile:t.getAsFile()})}#br(t,e=!1){if(t){this.#or=t.bitmap;if(!e){this.#hr=t.id;this.#mr=t.isSvg}t.file&&(this.#ur=t.file.name);this.#za()}else this.remove()}#vr(){this.#lr=null;this._uiManager.enableWaiting(!1);this.#pr&&this.div.focus()}#Ar(){if(this.#hr){this._uiManager.enableWaiting(!0);this._uiManager.imageManager.getFromId(this.#hr).then((t=>this.#br(t,!0))).finally((()=>this.#vr()));return}if(this.#dr){const t=this.#dr;this.#dr=null;this._uiManager.enableWaiting(!0);this.#lr=this._uiManager.imageManager.getFromUrl(t).then((t=>this.#br(t))).finally((()=>this.#vr()));return}if(this.#cr){const t=this.#cr;this.#cr=null;this._uiManager.enableWaiting(!0);this.#lr=this._uiManager.imageManager.getFromFile(t).then((t=>this.#br(t))).finally((()=>this.#vr()));return}const t=document.createElement("input");t.type="file";t.accept=StampEditor.supportedTypesStr;this.#lr=new Promise((e=>{t.addEventListener("change",(async()=>{if(t.files&&0!==t.files.length){this._uiManager.enableWaiting(!0);const e=await this._uiManager.imageManager.getFromFile(t.files[0]);this.#br(e)}else this.remove();e()}));t.addEventListener("cancel",(()=>{this.remove();e()}))})).finally((()=>this.#vr()));t.click()}remove(){if(this.#hr){this.#or=null;this._uiManager.imageManager.deleteId(this.#hr);this.#pr?.remove();this.#pr=null;this.#Fa?.disconnect();this.#Fa=null;if(this.#gr){clearTimeout(this.#gr);this.#gr=null}}super.remove()}rebuild(){if(this.parent){super.rebuild();if(null!==this.div){this.#hr&&null===this.#pr&&this.#Ar();this.isAttachedToDOM||this.parent.add(this)}}else this.#hr&&this.#Ar()}onceAdded(){this._isDraggable=!0;this.div.focus()}isEmpty(){return!(this.#lr||this.#or||this.#dr||this.#cr||this.#hr)}get isResizable(){return!0}render(){if(this.div)return this.div;let t,e;if(this.width){t=this.x;e=this.y}super.render();this.div.hidden=!0;this.addAltTextButton();this.#or?this.#za():this.#Ar();if(this.width){const[i,s]=this.parentDimensions;this.setAt(t*i,e*s,this.width*i,this.height*s)}return this.div}#za(){const{div:t}=this;let{width:e,height:i}=this.#or;const[s,n]=this.pageDimensions,a=.75;if(this.width){e=this.width*s;i=this.height*n}else if(e>a*s||i>a*n){const t=Math.min(a*s/e,a*n/i);e*=t;i*=t}const[r,o]=this.parentDimensions;this.setDims(e*r/s,i*o/n);this._uiManager.enableWaiting(!1);const h=this.#pr=document.createElement("canvas");t.append(h);t.hidden=!1;this.#yr(e,i);this.#Ua();if(!this.#fr){this.parent.addUndoableEditor(this);this.#fr=!0}this._reportTelemetry({action:"inserted_image"});this.#ur&&h.setAttribute("aria-label",this.#ur)}#wr(t,e){const[i,s]=this.parentDimensions;this.width=t/i;this.height=e/s;this.setDims(t,e);this._initialOptions?.isCentered?this.center():this.fixAndSetPosition();this._initialOptions=null;null!==this.#gr&&clearTimeout(this.#gr);this.#gr=setTimeout((()=>{this.#gr=null;this.#yr(t,e)}),200)}#xr(t,e){const{width:i,height:s}=this.#or;let n=i,a=s,r=this.#or;for(;n>2*t||a>2*e;){const i=n,s=a;n>2*t&&(n=n>=16384?Math.floor(n/2)-1:Math.ceil(n/2));a>2*e&&(a=a>=16384?Math.floor(a/2)-1:Math.ceil(a/2));const o=new OffscreenCanvas(n,a);o.getContext("2d").drawImage(r,0,0,i,s,0,0,n,a);r=o.transferToImageBitmap()}return r}#yr(t,e){t=Math.ceil(t);e=Math.ceil(e);const i=this.#pr;if(!i||i.width===t&&i.height===e)return;i.width=t;i.height=e;const s=this.#mr?this.#or:this.#xr(t,e);if(this._uiManager.hasMLManager&&!this.hasAltText()){const i=new OffscreenCanvas(t,e).getContext("2d");i.drawImage(s,0,0,s.width,s.height,0,0,t,e);this._uiManager.mlGuess({service:"image-to-text",request:{data:i.getImageData(0,0,t,e).data,width:t,height:e,channels:4}}).then((t=>{const e=t?.output||"";this.parent&&e&&!this.hasAltText()&&(this.altTextData={altText:e,decorative:!1})}))}const n=i.getContext("2d");n.filter=this._uiManager.hcmFilter;n.drawImage(s,0,0,s.width,s.height,0,0,t,e)}getImageForAltText(){return this.#pr}#Er(t){if(t){if(this.#mr){const t=this._uiManager.imageManager.getSvgUrl(this.#hr);if(t)return t}const t=document.createElement("canvas");({width:t.width,height:t.height}=this.#or);t.getContext("2d").drawImage(this.#or,0,0);return t.toDataURL()}if(this.#mr){const[t,e]=this.pageDimensions,i=Math.round(this.width*t*PixelsPerInch.PDF_TO_CSS_UNITS),s=Math.round(this.height*e*PixelsPerInch.PDF_TO_CSS_UNITS),n=new OffscreenCanvas(i,s);n.getContext("2d").drawImage(this.#or,0,0,this.#or.width,this.#or.height,0,0,i,s);return n.transferToImageBitmap()}return structuredClone(this.#or)}#Ua(){this.#Fa=new ResizeObserver((t=>{const e=t[0].contentRect;e.width&&e.height&&this.#wr(e.width,e.height)}));this.#Fa.observe(this.div)}static deserialize(t,e,i){if(t instanceof StampAnnotationElement)return null;const s=super.deserialize(t,e,i),{rect:n,bitmapUrl:a,bitmapId:r,isSvg:o,accessibilityData:h}=t;r&&i.imageManager.isValidId(r)?s.#hr=r:s.#dr=a;s.#mr=o;const[l,d]=s.pageDimensions;s.width=(n[2]-n[0])/l;s.height=(n[3]-n[1])/d;h&&(s.altTextData=h);return s}serialize(t=!1,e=null){if(this.isEmpty())return null;const i={annotationType:p.STAMP,bitmapId:this.#hr,pageIndex:this.pageIndex,rect:this.getRect(0,0),rotation:this.rotation,isSvg:this.#mr,structTreeParentId:this._structTreeParentId};if(t){i.bitmapUrl=this.#Er(!0);i.accessibilityData=this.altTextData;return i}const{decorative:s,altText:n}=this.altTextData;!s&&n&&(i.accessibilityData={type:"Figure",alt:n});if(null===e)return i;e.stamps||=new Map;const a=this.#mr?(i.rect[2]-i.rect[0])*(i.rect[3]-i.rect[1]):null;if(e.stamps.has(this.#hr)){if(this.#mr){const t=e.stamps.get(this.#hr);if(a>t.area){t.area=a;t.serialized.bitmap.close();t.serialized.bitmap=this.#Er(!1)}}}else{e.stamps.set(this.#hr,{area:a,serialized:i});i.bitmap=this.#Er(!1)}return i}}class AnnotationEditorLayer{#Os;#_r=!1;#Cr=null;#Sr=null;#Tr=null;#Mr=null;#kr=null;#Pr=new Map;#Dr=!1;#Rr=!1;#Fr=!1;#Ir=null;#u;static _initialized=!1;static#L=new Map([FreeTextEditor,InkEditor,StampEditor,HighlightEditor].map((t=>[t._editorType,t])));constructor({uiManager:t,pageIndex:e,div:i,accessibilityManager:s,annotationLayer:n,drawLayer:a,textLayer:r,viewport:o,l10n:h}){const l=[...AnnotationEditorLayer.#L.values()];if(!AnnotationEditorLayer._initialized){AnnotationEditorLayer._initialized=!0;for(const e of l)e.initialize(h,t)}t.registerEditorTypes(l);this.#u=t;this.pageIndex=e;this.div=i;this.#Os=s;this.#Cr=n;this.viewport=o;this.#Ir=r;this.drawLayer=a;this.#u.addLayer(this)}get isEmpty(){return 0===this.#Pr.size}get isInvisible(){return this.isEmpty&&this.#u.getMode()===p.NONE}updateToolbar(t){this.#u.updateToolbar(t)}updateMode(t=this.#u.getMode()){this.#Lr();switch(t){case p.NONE:this.disableTextSelection();this.togglePointerEvents(!1);this.toggleAnnotationLayerPointerEvents(!0);this.disableClick();return;case p.INK:this.addInkEditorIfNeeded(!1);this.disableTextSelection();this.togglePointerEvents(!0);this.disableClick();break;case p.HIGHLIGHT:this.enableTextSelection();this.togglePointerEvents(!1);this.disableClick();break;default:this.disableTextSelection();this.togglePointerEvents(!0);this.enableClick()}this.toggleAnnotationLayerPointerEvents(!1);const{classList:e}=this.div;for(const i of AnnotationEditorLayer.#L.values())e.toggle(`${i._type}Editing`,t===i._editorType);this.div.hidden=!1}hasTextLayer(t){return t===this.#Ir?.div}addInkEditorIfNeeded(t){if(this.#u.getMode()!==p.INK)return;if(!t)for(const t of this.#Pr.values())if(t.isEmpty()){t.setInBackground();return}this.createAndAddNewEditor({offsetX:0,offsetY:0},!1).setInBackground()}setEditingState(t){this.#u.setEditingState(t)}addCommands(t){this.#u.addCommands(t)}togglePointerEvents(t=!1){this.div.classList.toggle("disabled",!t)}toggleAnnotationLayerPointerEvents(t=!1){this.#Cr?.div.classList.toggle("disabled",!t)}enable(){this.div.tabIndex=0;this.togglePointerEvents(!0);const t=new Set;for(const e of this.#Pr.values()){e.enableEditing();e.show(!0);if(e.annotationElementId){this.#u.removeChangedExistingAnnotation(e);t.add(e.annotationElementId)}}if(!this.#Cr)return;const e=this.#Cr.getEditableAnnotations();for(const i of e){i.hide();if(this.#u.isDeletedAnnotationElement(i.data.id))continue;if(t.has(i.data.id))continue;const e=this.deserialize(i);if(e){this.addOrRebuild(e);e.enableEditing()}}}disable(){this.#Fr=!0;this.div.tabIndex=-1;this.togglePointerEvents(!1);const t=new Map,e=new Map;for(const i of this.#Pr.values()){i.disableEditing();if(i.annotationElementId)if(null===i.serialize()){e.set(i.annotationElementId,i);this.getEditableAnnotation(i.annotationElementId)?.show();i.remove()}else t.set(i.annotationElementId,i)}if(this.#Cr){const i=this.#Cr.getEditableAnnotations();for(const s of i){const{id:i}=s.data;if(this.#u.isDeletedAnnotationElement(i))continue;let n=e.get(i);if(n){n.resetAnnotationElement(s);n.show(!1);s.show()}else{n=t.get(i);if(n){this.#u.addChangedExistingAnnotation(n);n.renderAnnotationElement(s);n.show(!1)}s.show()}}}this.#Lr();this.isEmpty&&(this.div.hidden=!0);const{classList:i}=this.div;for(const t of AnnotationEditorLayer.#L.values())i.remove(`${t._type}Editing`);this.disableTextSelection();this.toggleAnnotationLayerPointerEvents(!0);this.#Fr=!1}getEditableAnnotation(t){return this.#Cr?.getEditableAnnotation(t)||null}setActiveEditor(t){this.#u.getActive()!==t&&this.#u.setActiveEditor(t)}enableTextSelection(){this.div.tabIndex=-1;if(this.#Ir?.div&&!this.#Mr){this.#Mr=this.#Or.bind(this);this.#Ir.div.addEventListener("pointerdown",this.#Mr);this.#Ir.div.classList.add("highlighting")}}disableTextSelection(){this.div.tabIndex=0;if(this.#Ir?.div&&this.#Mr){this.#Ir.div.removeEventListener("pointerdown",this.#Mr);this.#Mr=null;this.#Ir.div.classList.remove("highlighting")}}#Or(t){this.#u.unselectAll();if(t.target===this.#Ir.div){const{isMac:e}=util_FeatureTest.platform;if(0!==t.button||t.ctrlKey&&e)return;this.#u.showAllEditors("highlight",!0,!0);this.#Ir.div.classList.add("free");HighlightEditor.startHighlighting(this,"ltr"===this.#u.direction,t);this.#Ir.div.addEventListener("pointerup",(()=>{this.#Ir.div.classList.remove("free")}),{once:!0});t.preventDefault()}}enableClick(){if(!this.#Tr){this.#Tr=this.pointerdown.bind(this);this.#Sr=this.pointerup.bind(this);this.div.addEventListener("pointerdown",this.#Tr);this.div.addEventListener("pointerup",this.#Sr)}}disableClick(){if(this.#Tr){this.div.removeEventListener("pointerdown",this.#Tr);this.div.removeEventListener("pointerup",this.#Sr);this.#Tr=null;this.#Sr=null}}attach(t){this.#Pr.set(t.id,t);const{annotationElementId:e}=t;e&&this.#u.isDeletedAnnotationElement(e)&&this.#u.removeDeletedAnnotationElement(t)}detach(t){this.#Pr.delete(t.id);this.#Os?.removePointerInTextLayer(t.contentDiv);!this.#Fr&&t.annotationElementId&&this.#u.addDeletedAnnotationElement(t)}remove(t){this.detach(t);this.#u.removeEditor(t);t.div.remove();t.isAttachedToDOM=!1;this.#Rr||this.addInkEditorIfNeeded(!1)}changeParent(t){if(t.parent!==this){if(t.parent&&t.annotationElementId){this.#u.addDeletedAnnotationElement(t.annotationElementId);AnnotationEditor.deleteAnnotationElement(t);t.annotationElementId=null}this.attach(t);t.parent?.detach(t);t.setParent(this);if(t.div&&t.isAttachedToDOM){t.div.remove();this.div.append(t.div)}}}add(t){if(t.parent!==this||!t.isAttachedToDOM){this.changeParent(t);this.#u.addEditor(t);this.attach(t);if(!t.isAttachedToDOM){const e=t.render();this.div.append(e);t.isAttachedToDOM=!0}t.fixAndSetPosition();t.onceAdded();this.#u.addToAnnotationStorage(t);t._reportTelemetry(t.telemetryInitialData)}}moveEditorInDOM(t){if(!t.isAttachedToDOM)return;const{activeElement:e}=document;if(t.div.contains(e)&&!this.#kr){t._focusEventsAllowed=!1;this.#kr=setTimeout((()=>{this.#kr=null;if(t.div.contains(document.activeElement))t._focusEventsAllowed=!0;else{t.div.addEventListener("focusin",(()=>{t._focusEventsAllowed=!0}),{once:!0});e.focus()}}),0)}t._structTreeParentId=this.#Os?.moveElementInDOM(this.div,t.div,t.contentDiv,!0)}addOrRebuild(t){if(t.needsToBeRebuilt()){t.parent||=this;t.rebuild();t.show()}else this.add(t)}addUndoableEditor(t){this.addCommands({cmd:()=>t._uiManager.rebuild(t),undo:()=>{t.remove()},mustExec:!1})}getNextId(){return this.#u.getId()}get#Nr(){return AnnotationEditorLayer.#L.get(this.#u.getMode())}#Br(t){const e=this.#Nr;return e?new e.prototype.constructor(t):null}canCreateNewEmptyEditor(){return this.#Nr?.canCreateNewEmptyEditor()}pasteEditor(t,e){this.#u.updateToolbar(t);this.#u.updateMode(t);const{offsetX:i,offsetY:s}=this.#Hr(),n=this.getNextId(),a=this.#Br({parent:this,id:n,x:i,y:s,uiManager:this.#u,isCentered:!0,...e});a&&this.add(a)}deserialize(t){return AnnotationEditorLayer.#L.get(t.annotationType??t.annotationEditorType)?.deserialize(t,this,this.#u)||null}createAndAddNewEditor(t,e,i={}){const s=this.getNextId(),n=this.#Br({parent:this,id:s,x:t.offsetX,y:t.offsetY,uiManager:this.#u,isCentered:e,...i});n&&this.add(n);return n}#Hr(){const{x:t,y:e,width:i,height:s}=this.div.getBoundingClientRect(),n=Math.max(0,t),a=Math.max(0,e),r=(n+Math.min(window.innerWidth,t+i))/2-t,o=(a+Math.min(window.innerHeight,e+s))/2-e,[h,l]=this.viewport.rotation%180==0?[r,o]:[o,r];return{offsetX:h,offsetY:l}}addNewEditor(){this.createAndAddNewEditor(this.#Hr(),!0)}setSelected(t){this.#u.setSelected(t)}toggleSelected(t){this.#u.toggleSelected(t)}isSelected(t){return this.#u.isSelected(t)}unselect(t){this.#u.unselect(t)}pointerup(t){const{isMac:e}=util_FeatureTest.platform;if(!(0!==t.button||t.ctrlKey&&e)&&t.target===this.div&&this.#Dr){this.#Dr=!1;this.#_r?this.#u.getMode()!==p.STAMP?this.createAndAddNewEditor(t,!1):this.#u.unselectAll():this.#_r=!0}}pointerdown(t){this.#u.getMode()===p.HIGHLIGHT&&this.enableTextSelection();if(this.#Dr){this.#Dr=!1;return}const{isMac:e}=util_FeatureTest.platform;if(0!==t.button||t.ctrlKey&&e)return;if(t.target!==this.div)return;this.#Dr=!0;const i=this.#u.getActive();this.#_r=!i||i.isEmpty()}findNewParent(t,e,i){const s=this.#u.findParent(e,i);if(null===s||s===this)return!1;s.changeParent(t);return!0}destroy(){if(this.#u.getActive()?.parent===this){this.#u.commitOrRemove();this.#u.setActiveEditor(null)}if(this.#kr){clearTimeout(this.#kr);this.#kr=null}for(const t of this.#Pr.values()){this.#Os?.removePointerInTextLayer(t.contentDiv);t.setParent(null);t.isAttachedToDOM=!1;t.div.remove()}this.div=null;this.#Pr.clear();this.#u.removeLayer(this)}#Lr(){this.#Rr=!0;for(const t of this.#Pr.values())t.isEmpty()&&t.remove();this.#Rr=!1}render({viewport:t}){this.viewport=t;setLayerDimensions(this.div,t);for(const t of this.#u.getEditors(this.pageIndex)){this.add(t);t.rebuild()}this.updateMode()}update({viewport:t}){this.#u.commitOrRemove();this.#Lr();const e=this.viewport.rotation,i=t.rotation;this.viewport=t;setLayerDimensions(this.div,{rotation:i});if(e!==i)for(const t of this.#Pr.values())t.rotate(i);this.addInkEditorIfNeeded(!1)}get pageDimensions(){const{pageWidth:t,pageHeight:e}=this.viewport.rawDims;return[t,e]}get scale(){return this.#u.viewParameters.realScale}}class DrawLayer{#fs=null;#f=0;#zr=new Map;#Ur=new Map;constructor({pageIndex:t}){this.pageIndex=t}setParent(t){if(this.#fs){if(this.#fs!==t){if(this.#zr.size>0)for(const e of this.#zr.values()){e.remove();t.append(e)}this.#fs=t}}else this.#fs=t}static get _svgFactory(){return shadow(this,"_svgFactory",new DOMSVGFactory)}static#jr(t,{x:e=0,y:i=0,width:s=1,height:n=1}={}){const{style:a}=t;a.top=100*i+"%";a.left=100*e+"%";a.width=100*s+"%";a.height=100*n+"%"}#$r(t){const e=DrawLayer._svgFactory.create(1,1,!0);this.#fs.append(e);e.setAttribute("aria-hidden",!0);DrawLayer.#jr(e,t);return e}#Vr(t,e){const i=DrawLayer._svgFactory.createElement("clipPath");t.append(i);const s=`clip_${e}`;i.setAttribute("id",s);i.setAttribute("clipPathUnits","objectBoundingBox");const n=DrawLayer._svgFactory.createElement("use");i.append(n);n.setAttribute("href",`#${e}`);n.classList.add("clip");return s}highlight(t,e,i,s=!1){const n=this.#f++,a=this.#$r(t.box);a.classList.add("highlight");t.free&&a.classList.add("free");const r=DrawLayer._svgFactory.createElement("defs");a.append(r);const o=DrawLayer._svgFactory.createElement("path");r.append(o);const h=`path_p${this.pageIndex}_${n}`;o.setAttribute("id",h);o.setAttribute("d",t.toSVGPath());s&&this.#Ur.set(n,o);const l=this.#Vr(r,h),d=DrawLayer._svgFactory.createElement("use");a.append(d);a.setAttribute("fill",e);a.setAttribute("fill-opacity",i);d.setAttribute("href",`#${h}`);this.#zr.set(n,a);return{id:n,clipPathId:`url(#${l})`}}highlightOutline(t){const e=this.#f++,i=this.#$r(t.box);i.classList.add("highlightOutline");const s=DrawLayer._svgFactory.createElement("defs");i.append(s);const n=DrawLayer._svgFactory.createElement("path");s.append(n);const a=`path_p${this.pageIndex}_${e}`;n.setAttribute("id",a);n.setAttribute("d",t.toSVGPath());n.setAttribute("vector-effect","non-scaling-stroke");let r;if(t.free){i.classList.add("free");const t=DrawLayer._svgFactory.createElement("mask");s.append(t);r=`mask_p${this.pageIndex}_${e}`;t.setAttribute("id",r);t.setAttribute("maskUnits","objectBoundingBox");const n=DrawLayer._svgFactory.createElement("rect");t.append(n);n.setAttribute("width","1");n.setAttribute("height","1");n.setAttribute("fill","white");const o=DrawLayer._svgFactory.createElement("use");t.append(o);o.setAttribute("href",`#${a}`);o.setAttribute("stroke","none");o.setAttribute("fill","black");o.setAttribute("fill-rule","nonzero");o.classList.add("mask")}const o=DrawLayer._svgFactory.createElement("use");i.append(o);o.setAttribute("href",`#${a}`);r&&o.setAttribute("mask",`url(#${r})`);const h=o.cloneNode();i.append(h);o.classList.add("mainOutline");h.classList.add("secondaryOutline");this.#zr.set(e,i);return e}finalizeLine(t,e){const i=this.#Ur.get(t);this.#Ur.delete(t);this.updateBox(t,e.box);i.setAttribute("d",e.toSVGPath())}updateLine(t,e){this.#zr.get(t).firstChild.firstChild.setAttribute("d",e.toSVGPath())}removeFreeHighlight(t){this.remove(t);this.#Ur.delete(t)}updatePath(t,e){this.#Ur.get(t).setAttribute("d",e.toSVGPath())}updateBox(t,e){DrawLayer.#jr(this.#zr.get(t),e)}show(t,e){this.#zr.get(t).classList.toggle("hidden",!e)}rotate(t,e){this.#zr.get(t).setAttribute("data-main-rotation",e)}changeColor(t,e){this.#zr.get(t).setAttribute("fill",e)}changeOpacity(t,e){this.#zr.get(t).setAttribute("fill-opacity",e)}addClass(t,e){this.#zr.get(t).classList.add(e)}removeClass(t,e){this.#zr.get(t).classList.remove(e)}remove(t){if(null!==this.#fs){this.#zr.get(t).remove();this.#zr.delete(t)}}destroy(){this.#fs=null;for(const t of this.#zr.values())t.remove();this.#zr.clear()}}var te=__webpack_exports__.AbortException,ee=__webpack_exports__.AnnotationEditorLayer,ie=__webpack_exports__.AnnotationEditorParamsType,se=__webpack_exports__.AnnotationEditorType,ne=__webpack_exports__.AnnotationEditorUIManager,ae=__webpack_exports__.AnnotationLayer,re=__webpack_exports__.AnnotationMode,oe=__webpack_exports__.CMapCompressionType,he=__webpack_exports__.ColorPicker,le=__webpack_exports__.DOMSVGFactory,de=__webpack_exports__.DrawLayer,ce=__webpack_exports__.FeatureTest,ue=__webpack_exports__.GlobalWorkerOptions,pe=__webpack_exports__.ImageKind,ge=__webpack_exports__.InvalidPDFException,me=__webpack_exports__.MissingPDFException,fe=__webpack_exports__.OPS,be=__webpack_exports__.Outliner,ve=__webpack_exports__.PDFDataRangeTransport,Ae=__webpack_exports__.PDFDateString,ye=__webpack_exports__.PDFWorker,we=__webpack_exports__.PasswordResponses,xe=__webpack_exports__.PermissionFlag,Ee=__webpack_exports__.PixelsPerInch,_e=__webpack_exports__.RenderingCancelledException,Ce=__webpack_exports__.TextLayer,Se=__webpack_exports__.UnexpectedResponseException,Te=__webpack_exports__.Util,Me=__webpack_exports__.VerbosityLevel,ke=__webpack_exports__.XfaLayer,Pe=__webpack_exports__.build,De=__webpack_exports__.createValidAbsoluteUrl,Re=__webpack_exports__.fetchData,Fe=__webpack_exports__.getDocument,Ie=__webpack_exports__.getFilenameFromUrl,Le=__webpack_exports__.getPdfFilenameFromUrl,Oe=__webpack_exports__.getXfaPageViewport,Ne=__webpack_exports__.isDataScheme,Be=__webpack_exports__.isPdfFile,He=__webpack_exports__.noContextMenu,ze=__webpack_exports__.normalizeUnicode,Ue=__webpack_exports__.renderTextLayer,je=__webpack_exports__.setLayerDimensions,$e=__webpack_exports__.shadow,Ve=__webpack_exports__.updateTextLayer,Ge=__webpack_exports__.version;export{te as AbortException,ee as AnnotationEditorLayer,ie as AnnotationEditorParamsType,se as AnnotationEditorType,ne as AnnotationEditorUIManager,ae as AnnotationLayer,re as AnnotationMode,oe as CMapCompressionType,he as ColorPicker,le as DOMSVGFactory,de as DrawLayer,ce as FeatureTest,ue as GlobalWorkerOptions,pe as ImageKind,ge as InvalidPDFException,me as MissingPDFException,fe as OPS,be as Outliner,ve as PDFDataRangeTransport,Ae as PDFDateString,ye as PDFWorker,we as PasswordResponses,xe as PermissionFlag,Ee as PixelsPerInch,_e as RenderingCancelledException,Ce as TextLayer,Se as UnexpectedResponseException,Te as Util,Me as VerbosityLevel,ke as XfaLayer,Pe as build,De as createValidAbsoluteUrl,Re as fetchData,Fe as getDocument,Ie as getFilenameFromUrl,Le as getPdfFilenameFromUrl,Oe as getXfaPageViewport,Ne as isDataScheme,Be as isPdfFile,He as noContextMenu,ze as normalizeUnicode,Ue as renderTextLayer,je as setLayerDimensions,$e as shadow,Ve as updateTextLayer,Ge as version}; \ No newline at end of file
diff --git a/vhosts/blog/public/pdf.worker.min.mjs b/vhosts/blog/public/pdf.worker.min.mjs
deleted file mode 100644
index ada02223..00000000
--- a/vhosts/blog/public/pdf.worker.min.mjs
+++ /dev/null
@@ -1,21 +0,0 @@
-/**
- * @licstart The following is the entire license notice for the
- * JavaScript code in this page
- *
- * Copyright 2023 Mozilla Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @licend The above is the entire license notice for the
- * JavaScript code in this page
- */var e={d:(t,i)=>{for(var a in i)e.o(i,a)&&!e.o(t,a)&&Object.defineProperty(t,a,{enumerable:!0,get:i[a]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},__webpack_exports__=globalThis.pdfjsWorker={};e.d(__webpack_exports__,{WorkerMessageHandler:()=>WorkerMessageHandler});const t=!("object"!=typeof process||process+""!="[object process]"||process.versions.nw||process.versions.electron&&process.type&&"browser"!==process.type),i=[1,0,0,1,0,0],a=[.001,0,0,.001,0,0],s=1.35,r=.35,n=.25925925925925924,o=1,g=2,c=4,h=8,l=16,C=64,Q=256,E="pdfjs_internal_editor_",u=3,d=9,f=13,p=15,m={PRINT:4,MODIFY_CONTENTS:8,COPY:16,MODIFY_ANNOTATIONS:32,FILL_INTERACTIVE_FORMS:256,COPY_FOR_ACCESSIBILITY:512,ASSEMBLE:1024,PRINT_HIGH_QUALITY:2048},y=0,w=4,b=1,D=2,F=3,S=1,k=2,R=3,N=4,G=5,x=6,M=7,U=8,L=9,J=10,H=11,Y=12,v=13,K=14,T=15,q=16,O=17,W=20,X="Group",j="R",Z=1,V=2,z=4,_=16,$=32,AA=128,eA=512,tA=1,iA=2,aA=4096,sA=8192,rA=32768,nA=65536,oA=131072,gA=1048576,IA=2097152,cA=8388608,hA=16777216,lA=1,CA=2,BA=3,QA=4,EA=5,uA={E:"Mouse Enter",X:"Mouse Exit",D:"Mouse Down",U:"Mouse Up",Fo:"Focus",Bl:"Blur",PO:"PageOpen",PC:"PageClose",PV:"PageVisible",PI:"PageInvisible",K:"Keystroke",F:"Format",V:"Validate",C:"Calculate"},dA={WC:"WillClose",WS:"WillSave",DS:"DidSave",WP:"WillPrint",DP:"DidPrint"},fA={O:"PageOpen",C:"PageClose"},pA={ERRORS:0,WARNINGS:1,INFOS:5},mA={NONE:0,BINARY:1},yA=1,wA=2,bA=3,DA=4,FA=5,SA=6,kA=7,RA=8,NA=9,GA=10,xA=11,MA=12,UA=13,LA=14,JA=15,HA=16,YA=17,vA=18,KA=19,TA=20,qA=21,OA=22,PA=23,WA=24,XA=25,jA=26,ZA=27,VA=28,zA=29,_A=30,$A=31,Ae=32,ee=33,te=34,ie=35,ae=36,se=37,re=38,ne=39,oe=40,ge=41,Ie=42,ce=43,he=44,le=45,Ce=46,Be=47,Qe=48,Ee=49,ue=50,de=51,fe=52,pe=53,me=54,ye=55,we=56,be=57,De=58,Fe=59,Se=60,ke=61,Re=62,Ne=63,Ge=64,xe=65,Me=66,Ue=67,Le=68,Je=69,He=70,Ye=71,ve=72,Ke=73,Te=74,qe=75,Oe=76,Pe=77,We=80,Xe=81,je=83,Ze=84,Ve=85,ze=86,_e=87,$e=88,At=89,et=90,tt=91,it=1,at=2;let st=pA.WARNINGS;function getVerbosityLevel(){return st}function info(e){st>=pA.INFOS&&console.log(`Info: ${e}`)}function warn(e){st>=pA.WARNINGS&&console.log(`Warning: ${e}`)}function unreachable(e){throw new Error(e)}function assert(e,t){e||unreachable(t)}function createValidAbsoluteUrl(e,t=null,i=null){if(!e)return null;try{if(i&&"string"==typeof e){if(i.addDefaultProtocol&&e.startsWith("www.")){const t=e.match(/\./g);t?.length>=2&&(e=`http://${e}`)}if(i.tryConvertEncoding)try{e=stringToUTF8String(e)}catch{}}const a=t?new URL(e,t):new URL(e);if(function _isValidProtocol(e){switch(e?.protocol){case"http:":case"https:":case"ftp:":case"mailto:":case"tel:":return!0;default:return!1}}(a))return a}catch{}return null}function shadow(e,t,i,a=!1){Object.defineProperty(e,t,{value:i,enumerable:!a,configurable:!0,writable:!1});return i}const rt=function BaseExceptionClosure(){function BaseException(e,t){this.constructor===BaseException&&unreachable("Cannot initialize BaseException.");this.message=e;this.name=t}BaseException.prototype=new Error;BaseException.constructor=BaseException;return BaseException}();class PasswordException extends rt{constructor(e,t){super(e,"PasswordException");this.code=t}}class UnknownErrorException extends rt{constructor(e,t){super(e,"UnknownErrorException");this.details=t}}class InvalidPDFException extends rt{constructor(e){super(e,"InvalidPDFException")}}class MissingPDFException extends rt{constructor(e){super(e,"MissingPDFException")}}class UnexpectedResponseException extends rt{constructor(e,t){super(e,"UnexpectedResponseException");this.status=t}}class FormatError extends rt{constructor(e){super(e,"FormatError")}}class AbortException extends rt{constructor(e){super(e,"AbortException")}}function bytesToString(e){"object"==typeof e&&void 0!==e?.length||unreachable("Invalid argument for bytesToString");const t=e.length,i=8192;if(t<i)return String.fromCharCode.apply(null,e);const a=[];for(let s=0;s<t;s+=i){const r=Math.min(s+i,t),n=e.subarray(s,r);a.push(String.fromCharCode.apply(null,n))}return a.join("")}function stringToBytes(e){"string"!=typeof e&&unreachable("Invalid argument for stringToBytes");const t=e.length,i=new Uint8Array(t);for(let a=0;a<t;++a)i[a]=255&e.charCodeAt(a);return i}function string32(e){return String.fromCharCode(e>>24&255,e>>16&255,e>>8&255,255&e)}function objectSize(e){return Object.keys(e).length}class FeatureTest{static get isLittleEndian(){return shadow(this,"isLittleEndian",function isLittleEndian(){const e=new Uint8Array(4);e[0]=1;return 1===new Uint32Array(e.buffer,0,1)[0]}())}static get isEvalSupported(){return shadow(this,"isEvalSupported",function isEvalSupported(){try{new Function("");return!0}catch{return!1}}())}static get isOffscreenCanvasSupported(){return shadow(this,"isOffscreenCanvasSupported","undefined"!=typeof OffscreenCanvas)}static get platform(){return"undefined"!=typeof navigator&&"string"==typeof navigator?.platform?shadow(this,"platform",{isMac:navigator.platform.includes("Mac")}):shadow(this,"platform",{isMac:!1})}static get isCSSRoundSupported(){return shadow(this,"isCSSRoundSupported",globalThis.CSS?.supports?.("width: round(1.5px, 1px)"))}}const nt=Array.from(Array(256).keys(),(e=>e.toString(16).padStart(2,"0")));class Util{static makeHexColor(e,t,i){return`#${nt[e]}${nt[t]}${nt[i]}`}static scaleMinMax(e,t){let i;if(e[0]){if(e[0]<0){i=t[0];t[0]=t[2];t[2]=i}t[0]*=e[0];t[2]*=e[0];if(e[3]<0){i=t[1];t[1]=t[3];t[3]=i}t[1]*=e[3];t[3]*=e[3]}else{i=t[0];t[0]=t[1];t[1]=i;i=t[2];t[2]=t[3];t[3]=i;if(e[1]<0){i=t[1];t[1]=t[3];t[3]=i}t[1]*=e[1];t[3]*=e[1];if(e[2]<0){i=t[0];t[0]=t[2];t[2]=i}t[0]*=e[2];t[2]*=e[2]}t[0]+=e[4];t[1]+=e[5];t[2]+=e[4];t[3]+=e[5]}static transform(e,t){return[e[0]*t[0]+e[2]*t[1],e[1]*t[0]+e[3]*t[1],e[0]*t[2]+e[2]*t[3],e[1]*t[2]+e[3]*t[3],e[0]*t[4]+e[2]*t[5]+e[4],e[1]*t[4]+e[3]*t[5]+e[5]]}static applyTransform(e,t){return[e[0]*t[0]+e[1]*t[2]+t[4],e[0]*t[1]+e[1]*t[3]+t[5]]}static applyInverseTransform(e,t){const i=t[0]*t[3]-t[1]*t[2];return[(e[0]*t[3]-e[1]*t[2]+t[2]*t[5]-t[4]*t[3])/i,(-e[0]*t[1]+e[1]*t[0]+t[4]*t[1]-t[5]*t[0])/i]}static getAxialAlignedBoundingBox(e,t){const i=this.applyTransform(e,t),a=this.applyTransform(e.slice(2,4),t),s=this.applyTransform([e[0],e[3]],t),r=this.applyTransform([e[2],e[1]],t);return[Math.min(i[0],a[0],s[0],r[0]),Math.min(i[1],a[1],s[1],r[1]),Math.max(i[0],a[0],s[0],r[0]),Math.max(i[1],a[1],s[1],r[1])]}static inverseTransform(e){const t=e[0]*e[3]-e[1]*e[2];return[e[3]/t,-e[1]/t,-e[2]/t,e[0]/t,(e[2]*e[5]-e[4]*e[3])/t,(e[4]*e[1]-e[5]*e[0])/t]}static singularValueDecompose2dScale(e){const t=[e[0],e[2],e[1],e[3]],i=e[0]*t[0]+e[1]*t[2],a=e[0]*t[1]+e[1]*t[3],s=e[2]*t[0]+e[3]*t[2],r=e[2]*t[1]+e[3]*t[3],n=(i+r)/2,o=Math.sqrt((i+r)**2-4*(i*r-s*a))/2,g=n+o||1,c=n-o||1;return[Math.sqrt(g),Math.sqrt(c)]}static normalizeRect(e){const t=e.slice(0);if(e[0]>e[2]){t[0]=e[2];t[2]=e[0]}if(e[1]>e[3]){t[1]=e[3];t[3]=e[1]}return t}static intersect(e,t){const i=Math.max(Math.min(e[0],e[2]),Math.min(t[0],t[2])),a=Math.min(Math.max(e[0],e[2]),Math.max(t[0],t[2]));if(i>a)return null;const s=Math.max(Math.min(e[1],e[3]),Math.min(t[1],t[3])),r=Math.min(Math.max(e[1],e[3]),Math.max(t[1],t[3]));return s>r?null:[i,s,a,r]}static#A(e,t,i,a,s,r,n,o,g,c){if(g<=0||g>=1)return;const h=1-g,l=g*g,C=l*g,Q=h*(h*(h*e+3*g*t)+3*l*i)+C*a,E=h*(h*(h*s+3*g*r)+3*l*n)+C*o;c[0]=Math.min(c[0],Q);c[1]=Math.min(c[1],E);c[2]=Math.max(c[2],Q);c[3]=Math.max(c[3],E)}static#e(e,t,i,a,s,r,n,o,g,c,h,l){if(Math.abs(g)<1e-12){Math.abs(c)>=1e-12&&this.#A(e,t,i,a,s,r,n,o,-h/c,l);return}const C=c**2-4*h*g;if(C<0)return;const Q=Math.sqrt(C),E=2*g;this.#A(e,t,i,a,s,r,n,o,(-c+Q)/E,l);this.#A(e,t,i,a,s,r,n,o,(-c-Q)/E,l)}static bezierBoundingBox(e,t,i,a,s,r,n,o,g){if(g){g[0]=Math.min(g[0],e,n);g[1]=Math.min(g[1],t,o);g[2]=Math.max(g[2],e,n);g[3]=Math.max(g[3],t,o)}else g=[Math.min(e,n),Math.min(t,o),Math.max(e,n),Math.max(t,o)];this.#e(e,i,s,n,t,a,r,o,3*(3*(i-s)-e+n),6*(e-2*i+s),3*(i-e),g);this.#e(e,i,s,n,t,a,r,o,3*(3*(a-r)-t+o),6*(t-2*a+r),3*(a-t),g);return g}}const ot=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,728,711,710,729,733,731,730,732,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8226,8224,8225,8230,8212,8211,402,8260,8249,8250,8722,8240,8222,8220,8221,8216,8217,8218,8482,64257,64258,321,338,352,376,381,305,322,339,353,382,0,8364];function stringToPDFString(e){if(e[0]>="ï"){let t;if("þ"===e[0]&&"ÿ"===e[1]){t="utf-16be";e.length%2==1&&(e=e.slice(0,-1))}else if("ÿ"===e[0]&&"þ"===e[1]){t="utf-16le";e.length%2==1&&(e=e.slice(0,-1))}else"ï"===e[0]&&"»"===e[1]&&"¿"===e[2]&&(t="utf-8");if(t)try{const i=new TextDecoder(t,{fatal:!0}),a=stringToBytes(e),s=i.decode(a);return s.includes("")?s.replaceAll(/\x1b[^\x1b]*(?:\x1b|$)/g,""):s}catch(e){warn(`stringToPDFString: "${e}".`)}}const t=[];for(let i=0,a=e.length;i<a;i++){const s=e.charCodeAt(i);if(27===s){for(;++i<a&&27!==e.charCodeAt(i););continue}const r=ot[s];t.push(r?String.fromCharCode(r):e.charAt(i))}return t.join("")}function stringToUTF8String(e){return decodeURIComponent(escape(e))}function utf8StringToString(e){return unescape(encodeURIComponent(e))}function isArrayEqual(e,t){if(e.length!==t.length)return!1;for(let i=0,a=e.length;i<a;i++)if(e[i]!==t[i])return!1;return!0}function getModificationDate(e=new Date){return[e.getUTCFullYear().toString(),(e.getUTCMonth()+1).toString().padStart(2,"0"),e.getUTCDate().toString().padStart(2,"0"),e.getUTCHours().toString().padStart(2,"0"),e.getUTCMinutes().toString().padStart(2,"0"),e.getUTCSeconds().toString().padStart(2,"0")].join("")}let gt=null,It=null;const ct=0,ht=1,lt=2,Ct=3,Bt=4,Qt=5,Et=6,ut=7,dt=8,ft=Symbol("CIRCULAR_REF"),pt=Symbol("EOF");let mt=Object.create(null),yt=Object.create(null),wt=Object.create(null);class Name{constructor(e){this.name=e}static get(e){return yt[e]||=new Name(e)}}class Cmd{constructor(e){this.cmd=e}static get(e){return mt[e]||=new Cmd(e)}}const bt=function nonSerializableClosure(){return bt};class Dict{constructor(e=null){this._map=Object.create(null);this.xref=e;this.objId=null;this.suppressEncryption=!1;this.__nonSerializable__=bt}assignXref(e){this.xref=e}get size(){return Object.keys(this._map).length}get(e,t,i){let a=this._map[e];if(void 0===a&&void 0!==t){a=this._map[t];void 0===a&&void 0!==i&&(a=this._map[i])}return a instanceof Ref&&this.xref?this.xref.fetch(a,this.suppressEncryption):a}async getAsync(e,t,i){let a=this._map[e];if(void 0===a&&void 0!==t){a=this._map[t];void 0===a&&void 0!==i&&(a=this._map[i])}return a instanceof Ref&&this.xref?this.xref.fetchAsync(a,this.suppressEncryption):a}getArray(e,t,i){let a=this._map[e];if(void 0===a&&void 0!==t){a=this._map[t];void 0===a&&void 0!==i&&(a=this._map[i])}a instanceof Ref&&this.xref&&(a=this.xref.fetch(a,this.suppressEncryption));if(Array.isArray(a)){a=a.slice();for(let e=0,t=a.length;e<t;e++)a[e]instanceof Ref&&this.xref&&(a[e]=this.xref.fetch(a[e],this.suppressEncryption))}return a}getRaw(e){return this._map[e]}getKeys(){return Object.keys(this._map)}getRawValues(){return Object.values(this._map)}set(e,t){this._map[e]=t}has(e){return void 0!==this._map[e]}forEach(e){for(const t in this._map)e(t,this.get(t))}static get empty(){const e=new Dict(null);e.set=(e,t)=>{unreachable("Should not call `set` on the empty dictionary.")};return shadow(this,"empty",e)}static merge({xref:e,dictArray:t,mergeSubDicts:i=!1}){const a=new Dict(e),s=new Map;for(const e of t)if(e instanceof Dict)for(const[t,a]of Object.entries(e._map)){let e=s.get(t);if(void 0===e){e=[];s.set(t,e)}else if(!(i&&a instanceof Dict))continue;e.push(a)}for(const[t,i]of s){if(1===i.length||!(i[0]instanceof Dict)){a._map[t]=i[0];continue}const s=new Dict(e);for(const e of i)for(const[t,i]of Object.entries(e._map))void 0===s._map[t]&&(s._map[t]=i);s.size>0&&(a._map[t]=s)}s.clear();return a.size>0?a:Dict.empty}clone(){const e=new Dict(this.xref);for(const t of this.getKeys())e.set(t,this.getRaw(t));return e}}class Ref{constructor(e,t){this.num=e;this.gen=t}toString(){return 0===this.gen?`${this.num}R`:`${this.num}R${this.gen}`}static fromString(e){const t=wt[e];if(t)return t;const i=/^(\d+)R(\d*)$/.exec(e);return i&&"0"!==i[1]?wt[e]=new Ref(parseInt(i[1]),i[2]?parseInt(i[2]):0):null}static get(e,t){const i=0===t?`${e}R`:`${e}R${t}`;return wt[i]||=new Ref(e,t)}}class RefSet{constructor(e=null){this._set=new Set(e?._set)}has(e){return this._set.has(e.toString())}put(e){this._set.add(e.toString())}remove(e){this._set.delete(e.toString())}[Symbol.iterator](){return this._set.values()}clear(){this._set.clear()}}class RefSetCache{constructor(){this._map=new Map}get size(){return this._map.size}get(e){return this._map.get(e.toString())}has(e){return this._map.has(e.toString())}put(e,t){this._map.set(e.toString(),t)}putAlias(e,t){this._map.set(e.toString(),this.get(t))}[Symbol.iterator](){return this._map.values()}clear(){this._map.clear()}*items(){for(const[e,t]of this._map)yield[Ref.fromString(e),t]}}function isName(e,t){return e instanceof Name&&(void 0===t||e.name===t)}function isCmd(e,t){return e instanceof Cmd&&(void 0===t||e.cmd===t)}function isDict(e,t){return e instanceof Dict&&(void 0===t||isName(e.get("Type"),t))}function isRefsEqual(e,t){return e.num===t.num&&e.gen===t.gen}class BaseStream{constructor(){this.constructor===BaseStream&&unreachable("Cannot initialize BaseStream.")}get length(){unreachable("Abstract getter `length` accessed")}get isEmpty(){unreachable("Abstract getter `isEmpty` accessed")}get isDataLoaded(){return shadow(this,"isDataLoaded",!0)}getByte(){unreachable("Abstract method `getByte` called")}getBytes(e){unreachable("Abstract method `getBytes` called")}peekByte(){const e=this.getByte();-1!==e&&this.pos--;return e}peekBytes(e){const t=this.getBytes(e);this.pos-=t.length;return t}getUint16(){const e=this.getByte(),t=this.getByte();return-1===e||-1===t?-1:(e<<8)+t}getInt32(){return(this.getByte()<<24)+(this.getByte()<<16)+(this.getByte()<<8)+this.getByte()}getByteRange(e,t){unreachable("Abstract method `getByteRange` called")}getString(e){return bytesToString(this.getBytes(e))}skip(e){this.pos+=e||1}reset(){unreachable("Abstract method `reset` called")}moveStart(){unreachable("Abstract method `moveStart` called")}makeSubStream(e,t,i=null){unreachable("Abstract method `makeSubStream` called")}getBaseStreams(){return null}}const Dt=/^[1-9]\.\d$/;function getLookupTableFactory(e){let t;return function(){if(e){t=Object.create(null);e(t);e=null}return t}}class MissingDataException extends rt{constructor(e,t){super(`Missing data [${e}, ${t})`,"MissingDataException");this.begin=e;this.end=t}}class ParserEOFException extends rt{constructor(e){super(e,"ParserEOFException")}}class XRefEntryException extends rt{constructor(e){super(e,"XRefEntryException")}}class XRefParseException extends rt{constructor(e){super(e,"XRefParseException")}}function arrayBuffersToBytes(e){const t=e.length;if(0===t)return new Uint8Array(0);if(1===t)return new Uint8Array(e[0]);let i=0;for(let a=0;a<t;a++)i+=e[a].byteLength;const a=new Uint8Array(i);let s=0;for(let i=0;i<t;i++){const t=new Uint8Array(e[i]);a.set(t,s);s+=t.byteLength}return a}function getInheritableProperty({dict:e,key:t,getArray:i=!1,stopWhenFound:a=!0}){let s;const r=new RefSet;for(;e instanceof Dict&&(!e.objId||!r.has(e.objId));){e.objId&&r.put(e.objId);const n=i?e.getArray(t):e.get(t);if(void 0!==n){if(a)return n;(s||=[]).push(n)}e=e.get("Parent")}return s}const Ft=["","C","CC","CCC","CD","D","DC","DCC","DCCC","CM","","X","XX","XXX","XL","L","LX","LXX","LXXX","XC","","I","II","III","IV","V","VI","VII","VIII","IX"];function toRomanNumerals(e,t=!1){assert(Number.isInteger(e)&&e>0,"The number should be a positive integer.");const i=[];let a;for(;e>=1e3;){e-=1e3;i.push("M")}a=e/100|0;e%=100;i.push(Ft[a]);a=e/10|0;e%=10;i.push(Ft[10+a]);i.push(Ft[20+e]);const s=i.join("");return t?s.toLowerCase():s}function log2(e){return e<=0?0:Math.ceil(Math.log2(e))}function readInt8(e,t){return e[t]<<24>>24}function readUint16(e,t){return e[t]<<8|e[t+1]}function readUint32(e,t){return(e[t]<<24|e[t+1]<<16|e[t+2]<<8|e[t+3])>>>0}function isWhiteSpace(e){return 32===e||9===e||13===e||10===e}function isNumberArray(e,t){return Array.isArray(e)&&(null===t||e.length===t)&&e.every((e=>"number"==typeof e))}function lookupMatrix(e,t){return isNumberArray(e,6)?e:t}function lookupRect(e,t){return isNumberArray(e,4)?e:t}function lookupNormalRect(e,t){return isNumberArray(e,4)?Util.normalizeRect(e):t}function parseXFAPath(e){const t=/(.+)\[(\d+)\]$/;return e.split(".").map((e=>{const i=e.match(t);return i?{name:i[1],pos:parseInt(i[2],10)}:{name:e,pos:0}}))}function escapePDFName(e){const t=[];let i=0;for(let a=0,s=e.length;a<s;a++){const s=e.charCodeAt(a);if(s<33||s>126||35===s||40===s||41===s||60===s||62===s||91===s||93===s||123===s||125===s||47===s||37===s){i<a&&t.push(e.substring(i,a));t.push(`#${s.toString(16)}`);i=a+1}}if(0===t.length)return e;i<e.length&&t.push(e.substring(i,e.length));return t.join("")}function escapeString(e){return e.replaceAll(/([()\\\n\r])/g,(e=>"\n"===e?"\\n":"\r"===e?"\\r":`\\${e}`))}function _collectJS(e,t,i,a){if(!e)return;let s=null;if(e instanceof Ref){if(a.has(e))return;s=e;a.put(s);e=t.fetch(e)}if(Array.isArray(e))for(const s of e)_collectJS(s,t,i,a);else if(e instanceof Dict){if(isName(e.get("S"),"JavaScript")){const t=e.get("JS");let a;t instanceof BaseStream?a=t.getString():"string"==typeof t&&(a=t);a&&=stringToPDFString(a).replaceAll("\0","");a&&i.push(a)}_collectJS(e.getRaw("Next"),t,i,a)}s&&a.remove(s)}function collectActions(e,t,i){const a=Object.create(null),s=getInheritableProperty({dict:t,key:"AA",stopWhenFound:!1});if(s)for(let t=s.length-1;t>=0;t--){const r=s[t];if(r instanceof Dict)for(const t of r.getKeys()){const s=i[t];if(!s)continue;const n=[];_collectJS(r.getRaw(t),e,n,new RefSet);n.length>0&&(a[s]=n)}}if(t.has("A")){const i=[];_collectJS(t.get("A"),e,i,new RefSet);i.length>0&&(a.Action=i)}return objectSize(a)>0?a:null}const St={60:"&lt;",62:"&gt;",38:"&amp;",34:"&quot;",39:"&apos;"};function*codePointIter(e){for(let t=0,i=e.length;t<i;t++){const i=e.codePointAt(t);i>55295&&(i<57344||i>65533)&&t++;yield i}}function encodeToXmlString(e){const t=[];let i=0;for(let a=0,s=e.length;a<s;a++){const s=e.codePointAt(a);if(32<=s&&s<=126){const r=St[s];if(r){i<a&&t.push(e.substring(i,a));t.push(r);i=a+1}}else{i<a&&t.push(e.substring(i,a));t.push(`&#x${s.toString(16).toUpperCase()};`);s>55295&&(s<57344||s>65533)&&a++;i=a+1}}if(0===t.length)return e;i<e.length&&t.push(e.substring(i,e.length));return t.join("")}function validateFontName(e,t=!1){const i=/^("|').*("|')$/.exec(e);if(i&&i[1]===i[2]){if(new RegExp(`[^\\\\]${i[1]}`).test(e.slice(1,-1))){t&&warn(`FontFamily contains unescaped ${i[1]}: ${e}.`);return!1}}else for(const i of e.split(/[ \t]+/))if(/^(\d|(-(\d|-)))/.test(i)||!/^[\w-\\]+$/.test(i)){t&&warn(`FontFamily contains invalid <custom-ident>: ${e}.`);return!1}return!0}function validateCSSFont(e){const t=new Set(["100","200","300","400","500","600","700","800","900","1000","normal","bold","bolder","lighter"]),{fontFamily:i,fontWeight:a,italicAngle:s}=e;if(!validateFontName(i,!0))return!1;const r=a?a.toString():"";e.fontWeight=t.has(r)?r:"400";const n=parseFloat(s);e.italicAngle=isNaN(n)||n<-90||n>90?"14":s.toString();return!0}function recoverJsURL(e){const t=new RegExp("^\\s*("+["app.launchURL","window.open","xfa.host.gotoURL"].join("|").replaceAll(".","\\.")+")\\((?:'|\")([^'\"]*)(?:'|\")(?:,\\s*(\\w+)\\)|\\))","i").exec(e);if(t?.[2]){const e=t[2];let i=!1;"true"===t[3]&&"app.launchURL"===t[1]&&(i=!0);return{url:e,newWindow:i}}return null}function numberToString(e){if(Number.isInteger(e))return e.toString();const t=Math.round(100*e);return t%100==0?(t/100).toString():t%10==0?e.toFixed(1):e.toFixed(2)}function getNewAnnotationsMap(e){if(!e)return null;const t=new Map;for(const[i,a]of e){if(!i.startsWith(E))continue;let e=t.get(a.pageIndex);if(!e){e=[];t.set(a.pageIndex,e)}e.push(a)}return t.size>0?t:null}function isAscii(e){return/^[\x00-\x7F]*$/.test(e)}function stringToUTF16HexString(e){const t=[];for(let i=0,a=e.length;i<a;i++){const a=e.charCodeAt(i);t.push((a>>8&255).toString(16).padStart(2,"0"),(255&a).toString(16).padStart(2,"0"))}return t.join("")}function stringToUTF16String(e,t=!1){const i=[];t&&i.push("þÿ");for(let t=0,a=e.length;t<a;t++){const a=e.charCodeAt(t);i.push(String.fromCharCode(a>>8&255),String.fromCharCode(255&a))}return i.join("")}function getRotationMatrix(e,t,i){switch(e){case 90:return[0,1,-1,0,t,0];case 180:return[-1,0,0,-1,t,i];case 270:return[0,-1,1,0,0,i];default:throw new Error("Invalid rotation")}}function getSizeInBytes(e){return Math.ceil(Math.ceil(Math.log2(1+e))/8)}class Stream extends BaseStream{constructor(e,t,i,a){super();this.bytes=e instanceof Uint8Array?e:new Uint8Array(e);this.start=t||0;this.pos=this.start;this.end=t+i||this.bytes.length;this.dict=a}get length(){return this.end-this.start}get isEmpty(){return 0===this.length}getByte(){return this.pos>=this.end?-1:this.bytes[this.pos++]}getBytes(e){const t=this.bytes,i=this.pos,a=this.end;if(!e)return t.subarray(i,a);let s=i+e;s>a&&(s=a);this.pos=s;return t.subarray(i,s)}getByteRange(e,t){e<0&&(e=0);t>this.end&&(t=this.end);return this.bytes.subarray(e,t)}reset(){this.pos=this.start}moveStart(){this.start=this.pos}makeSubStream(e,t,i=null){return new Stream(this.bytes.buffer,e,t,i)}}class StringStream extends Stream{constructor(e){super(stringToBytes(e))}}class NullStream extends Stream{constructor(){super(new Uint8Array(0))}}class ChunkedStream extends Stream{constructor(e,t,i){super(new Uint8Array(e),0,e,null);this.chunkSize=t;this._loadedChunks=new Set;this.numChunks=Math.ceil(e/t);this.manager=i;this.progressiveDataLength=0;this.lastSuccessfulEnsureByteChunk=-1}getMissingChunks(){const e=[];for(let t=0,i=this.numChunks;t<i;++t)this._loadedChunks.has(t)||e.push(t);return e}get numChunksLoaded(){return this._loadedChunks.size}get isDataLoaded(){return this.numChunksLoaded===this.numChunks}onReceiveData(e,t){const i=this.chunkSize;if(e%i!=0)throw new Error(`Bad begin offset: ${e}`);const a=e+t.byteLength;if(a%i!=0&&a!==this.bytes.length)throw new Error(`Bad end offset: ${a}`);this.bytes.set(new Uint8Array(t),e);const s=Math.floor(e/i),r=Math.floor((a-1)/i)+1;for(let e=s;e<r;++e)this._loadedChunks.add(e)}onReceiveProgressiveData(e){let t=this.progressiveDataLength;const i=Math.floor(t/this.chunkSize);this.bytes.set(new Uint8Array(e),t);t+=e.byteLength;this.progressiveDataLength=t;const a=t>=this.end?this.numChunks:Math.floor(t/this.chunkSize);for(let e=i;e<a;++e)this._loadedChunks.add(e)}ensureByte(e){if(e<this.progressiveDataLength)return;const t=Math.floor(e/this.chunkSize);if(!(t>this.numChunks)&&t!==this.lastSuccessfulEnsureByteChunk){if(!this._loadedChunks.has(t))throw new MissingDataException(e,e+1);this.lastSuccessfulEnsureByteChunk=t}}ensureRange(e,t){if(e>=t)return;if(t<=this.progressiveDataLength)return;const i=Math.floor(e/this.chunkSize);if(i>this.numChunks)return;const a=Math.min(Math.floor((t-1)/this.chunkSize)+1,this.numChunks);for(let s=i;s<a;++s)if(!this._loadedChunks.has(s))throw new MissingDataException(e,t)}nextEmptyChunk(e){const t=this.numChunks;for(let i=0;i<t;++i){const a=(e+i)%t;if(!this._loadedChunks.has(a))return a}return null}hasChunk(e){return this._loadedChunks.has(e)}getByte(){const e=this.pos;if(e>=this.end)return-1;e>=this.progressiveDataLength&&this.ensureByte(e);return this.bytes[this.pos++]}getBytes(e){const t=this.bytes,i=this.pos,a=this.end;if(!e){a>this.progressiveDataLength&&this.ensureRange(i,a);return t.subarray(i,a)}let s=i+e;s>a&&(s=a);s>this.progressiveDataLength&&this.ensureRange(i,s);this.pos=s;return t.subarray(i,s)}getByteRange(e,t){e<0&&(e=0);t>this.end&&(t=this.end);t>this.progressiveDataLength&&this.ensureRange(e,t);return this.bytes.subarray(e,t)}makeSubStream(e,t,i=null){t?e+t>this.progressiveDataLength&&this.ensureRange(e,e+t):e>=this.progressiveDataLength&&this.ensureByte(e);function ChunkedStreamSubstream(){}ChunkedStreamSubstream.prototype=Object.create(this);ChunkedStreamSubstream.prototype.getMissingChunks=function(){const e=this.chunkSize,t=Math.floor(this.start/e),i=Math.floor((this.end-1)/e)+1,a=[];for(let e=t;e<i;++e)this._loadedChunks.has(e)||a.push(e);return a};Object.defineProperty(ChunkedStreamSubstream.prototype,"isDataLoaded",{get(){return this.numChunksLoaded===this.numChunks||0===this.getMissingChunks().length},configurable:!0});const a=new ChunkedStreamSubstream;a.pos=a.start=e;a.end=e+t||this.end;a.dict=i;return a}getBaseStreams(){return[this]}}class ChunkedStreamManager{constructor(e,t){this.length=t.length;this.chunkSize=t.rangeChunkSize;this.stream=new ChunkedStream(this.length,this.chunkSize,this);this.pdfNetworkStream=e;this.disableAutoFetch=t.disableAutoFetch;this.msgHandler=t.msgHandler;this.currRequestId=0;this._chunksNeededByRequest=new Map;this._requestsByChunk=new Map;this._promisesByRequest=new Map;this.progressiveDataLength=0;this.aborted=!1;this._loadedStreamCapability=Promise.withResolvers()}sendRequest(e,t){const i=this.pdfNetworkStream.getRangeReader(e,t);i.isStreamingSupported||(i.onProgress=this.onProgress.bind(this));let a=[],s=0;return new Promise(((e,t)=>{const readChunk=({value:r,done:n})=>{try{if(n){const t=arrayBuffersToBytes(a);a=null;e(t);return}s+=r.byteLength;i.isStreamingSupported&&this.onProgress({loaded:s});a.push(r);i.read().then(readChunk,t)}catch(e){t(e)}};i.read().then(readChunk,t)})).then((t=>{this.aborted||this.onReceiveData({chunk:t,begin:e})}))}requestAllChunks(e=!1){if(!e){const e=this.stream.getMissingChunks();this._requestChunks(e)}return this._loadedStreamCapability.promise}_requestChunks(e){const t=this.currRequestId++,i=new Set;this._chunksNeededByRequest.set(t,i);for(const t of e)this.stream.hasChunk(t)||i.add(t);if(0===i.size)return Promise.resolve();const a=Promise.withResolvers();this._promisesByRequest.set(t,a);const s=[];for(const e of i){let i=this._requestsByChunk.get(e);if(!i){i=[];this._requestsByChunk.set(e,i);s.push(e)}i.push(t)}if(s.length>0){const e=this.groupChunks(s);for(const t of e){const e=t.beginChunk*this.chunkSize,i=Math.min(t.endChunk*this.chunkSize,this.length);this.sendRequest(e,i).catch(a.reject)}}return a.promise.catch((e=>{if(!this.aborted)throw e}))}getStream(){return this.stream}requestRange(e,t){t=Math.min(t,this.length);const i=this.getBeginChunk(e),a=this.getEndChunk(t),s=[];for(let e=i;e<a;++e)s.push(e);return this._requestChunks(s)}requestRanges(e=[]){const t=[];for(const i of e){const e=this.getBeginChunk(i.begin),a=this.getEndChunk(i.end);for(let i=e;i<a;++i)t.includes(i)||t.push(i)}t.sort((function(e,t){return e-t}));return this._requestChunks(t)}groupChunks(e){const t=[];let i=-1,a=-1;for(let s=0,r=e.length;s<r;++s){const r=e[s];i<0&&(i=r);if(a>=0&&a+1!==r){t.push({beginChunk:i,endChunk:a+1});i=r}s+1===e.length&&t.push({beginChunk:i,endChunk:r+1});a=r}return t}onProgress(e){this.msgHandler.send("DocProgress",{loaded:this.stream.numChunksLoaded*this.chunkSize+e.loaded,total:this.length})}onReceiveData(e){const t=e.chunk,i=void 0===e.begin,a=i?this.progressiveDataLength:e.begin,s=a+t.byteLength,r=Math.floor(a/this.chunkSize),n=s<this.length?Math.floor(s/this.chunkSize):Math.ceil(s/this.chunkSize);if(i){this.stream.onReceiveProgressiveData(t);this.progressiveDataLength=s}else this.stream.onReceiveData(a,t);this.stream.isDataLoaded&&this._loadedStreamCapability.resolve(this.stream);const o=[];for(let e=r;e<n;++e){const t=this._requestsByChunk.get(e);if(t){this._requestsByChunk.delete(e);for(const i of t){const t=this._chunksNeededByRequest.get(i);t.has(e)&&t.delete(e);t.size>0||o.push(i)}}}if(!this.disableAutoFetch&&0===this._requestsByChunk.size){let e;if(1===this.stream.numChunksLoaded){const t=this.stream.numChunks-1;this.stream.hasChunk(t)||(e=t)}else e=this.stream.nextEmptyChunk(n);Number.isInteger(e)&&this._requestChunks([e])}for(const e of o){const t=this._promisesByRequest.get(e);this._promisesByRequest.delete(e);t.resolve()}this.msgHandler.send("DocProgress",{loaded:this.stream.numChunksLoaded*this.chunkSize,total:this.length})}onError(e){this._loadedStreamCapability.reject(e)}getBeginChunk(e){return Math.floor(e/this.chunkSize)}getEndChunk(e){return Math.floor((e-1)/this.chunkSize)+1}abort(e){this.aborted=!0;this.pdfNetworkStream?.cancelAllRequests(e);for(const t of this._promisesByRequest.values())t.reject(e)}}class ColorSpace{constructor(e,t){this.constructor===ColorSpace&&unreachable("Cannot initialize ColorSpace.");this.name=e;this.numComps=t}getRgb(e,t){const i=new Uint8ClampedArray(3);this.getRgbItem(e,t,i,0);return i}getRgbItem(e,t,i,a){unreachable("Should not call ColorSpace.getRgbItem")}getRgbBuffer(e,t,i,a,s,r,n){unreachable("Should not call ColorSpace.getRgbBuffer")}getOutputLength(e,t){unreachable("Should not call ColorSpace.getOutputLength")}isPassthrough(e){return!1}isDefaultDecode(e,t){return ColorSpace.isDefaultDecode(e,this.numComps)}fillRgb(e,t,i,a,s,r,n,o,g){const c=t*i;let h=null;const l=1<<n,C=i!==s||t!==a;if(this.isPassthrough(n))h=o;else if(1===this.numComps&&c>l&&"DeviceGray"!==this.name&&"DeviceRGB"!==this.name){const t=n<=8?new Uint8Array(l):new Uint16Array(l);for(let e=0;e<l;e++)t[e]=e;const i=new Uint8ClampedArray(3*l);this.getRgbBuffer(t,0,l,i,0,n,0);if(C){h=new Uint8Array(3*c);let e=0;for(let t=0;t<c;++t){const a=3*o[t];h[e++]=i[a];h[e++]=i[a+1];h[e++]=i[a+2]}}else{let t=0;for(let a=0;a<c;++a){const s=3*o[a];e[t++]=i[s];e[t++]=i[s+1];e[t++]=i[s+2];t+=g}}}else if(C){h=new Uint8ClampedArray(3*c);this.getRgbBuffer(o,0,c,h,0,n,0)}else this.getRgbBuffer(o,0,a*r,e,0,n,g);if(h)if(C)!function resizeRgbImage(e,t,i,a,s,r,n){n=1!==n?0:n;const o=i/s,g=a/r;let c,h=0;const l=new Uint16Array(s),C=3*i;for(let e=0;e<s;e++)l[e]=3*Math.floor(e*o);for(let i=0;i<r;i++){const a=Math.floor(i*g)*C;for(let i=0;i<s;i++){c=a+l[i];t[h++]=e[c++];t[h++]=e[c++];t[h++]=e[c++];h+=n}}}(h,e,t,i,a,s,g);else{let t=0,i=0;for(let s=0,n=a*r;s<n;s++){e[t++]=h[i++];e[t++]=h[i++];e[t++]=h[i++];t+=g}}}get usesZeroToOneRange(){return shadow(this,"usesZeroToOneRange",!0)}static _cache(e,t,i,a){if(!i)throw new Error('ColorSpace._cache - expected "localColorSpaceCache" argument.');if(!a)throw new Error('ColorSpace._cache - expected "parsedColorSpace" argument.');let s,r;if(e instanceof Ref){r=e;e=t.fetch(e)}e instanceof Name&&(s=e.name);(s||r)&&i.set(s,r,a)}static getCached(e,t,i){if(!i)throw new Error('ColorSpace.getCached - expected "localColorSpaceCache" argument.');if(e instanceof Ref){const a=i.getByRef(e);if(a)return a;try{e=t.fetch(e)}catch(e){if(e instanceof MissingDataException)throw e}}if(e instanceof Name){const t=i.getByName(e.name);if(t)return t}return null}static async parseAsync({cs:e,xref:t,resources:i=null,pdfFunctionFactory:a,localColorSpaceCache:s}){const r=this._parse(e,t,i,a);this._cache(e,t,s,r);return r}static parse({cs:e,xref:t,resources:i=null,pdfFunctionFactory:a,localColorSpaceCache:s}){const r=this.getCached(e,t,s);if(r)return r;const n=this._parse(e,t,i,a);this._cache(e,t,s,n);return n}static _parse(e,t,i=null,a){if((e=t.fetchIfRef(e))instanceof Name)switch(e.name){case"G":case"DeviceGray":return this.singletons.gray;case"RGB":case"DeviceRGB":return this.singletons.rgb;case"CMYK":case"DeviceCMYK":return this.singletons.cmyk;case"Pattern":return new PatternCS(null);default:if(i instanceof Dict){const s=i.get("ColorSpace");if(s instanceof Dict){const r=s.get(e.name);if(r){if(r instanceof Name)return this._parse(r,t,i,a);e=r;break}}}throw new FormatError(`Unrecognized ColorSpace: ${e.name}`)}if(Array.isArray(e)){const s=t.fetchIfRef(e[0]).name;let r,n,o,g,c,h;switch(s){case"G":case"DeviceGray":return this.singletons.gray;case"RGB":case"DeviceRGB":return this.singletons.rgb;case"CMYK":case"DeviceCMYK":return this.singletons.cmyk;case"CalGray":r=t.fetchIfRef(e[1]);g=r.getArray("WhitePoint");c=r.getArray("BlackPoint");h=r.get("Gamma");return new CalGrayCS(g,c,h);case"CalRGB":r=t.fetchIfRef(e[1]);g=r.getArray("WhitePoint");c=r.getArray("BlackPoint");h=r.getArray("Gamma");const l=r.getArray("Matrix");return new CalRGBCS(g,c,h,l);case"ICCBased":const C=t.fetchIfRef(e[1]).dict;n=C.get("N");const Q=C.get("Alternate");if(Q){const e=this._parse(Q,t,i,a);if(e.numComps===n)return e;warn("ICCBased color space: Ignoring incorrect /Alternate entry.")}if(1===n)return this.singletons.gray;if(3===n)return this.singletons.rgb;if(4===n)return this.singletons.cmyk;break;case"Pattern":o=e[1]||null;o&&(o=this._parse(o,t,i,a));return new PatternCS(o);case"I":case"Indexed":o=this._parse(e[1],t,i,a);const E=t.fetchIfRef(e[2])+1,u=t.fetchIfRef(e[3]);return new IndexedCS(o,E,u);case"Separation":case"DeviceN":const d=t.fetchIfRef(e[1]);n=Array.isArray(d)?d.length:1;o=this._parse(e[2],t,i,a);const f=a.create(e[3]);return new AlternateCS(n,o,f);case"Lab":r=t.fetchIfRef(e[1]);g=r.getArray("WhitePoint");c=r.getArray("BlackPoint");const p=r.getArray("Range");return new LabCS(g,c,p);default:throw new FormatError(`Unimplemented ColorSpace object: ${s}`)}}throw new FormatError(`Unrecognized ColorSpace object: ${e}`)}static isDefaultDecode(e,t){if(!Array.isArray(e))return!0;if(2*t!==e.length){warn("The decode map is not the correct length");return!0}for(let t=0,i=e.length;t<i;t+=2)if(0!==e[t]||1!==e[t+1])return!1;return!0}static get singletons(){return shadow(this,"singletons",{get gray(){return shadow(this,"gray",new DeviceGrayCS)},get rgb(){return shadow(this,"rgb",new DeviceRgbCS)},get cmyk(){return shadow(this,"cmyk",new DeviceCmykCS)}})}}class AlternateCS extends ColorSpace{constructor(e,t,i){super("Alternate",e);this.base=t;this.tintFn=i;this.tmpBuf=new Float32Array(t.numComps)}getRgbItem(e,t,i,a){const s=this.tmpBuf;this.tintFn(e,t,s,0);this.base.getRgbItem(s,0,i,a)}getRgbBuffer(e,t,i,a,s,r,n){const o=this.tintFn,g=this.base,c=1/((1<<r)-1),h=g.numComps,l=g.usesZeroToOneRange,C=(g.isPassthrough(8)||!l)&&0===n;let Q=C?s:0;const E=C?a:new Uint8ClampedArray(h*i),u=this.numComps,d=new Float32Array(u),f=new Float32Array(h);let p,m;for(p=0;p<i;p++){for(m=0;m<u;m++)d[m]=e[t++]*c;o(d,0,f,0);if(l)for(m=0;m<h;m++)E[Q++]=255*f[m];else{g.getRgbItem(f,0,E,Q);Q+=h}}C||g.getRgbBuffer(E,0,i,a,s,8,n)}getOutputLength(e,t){return this.base.getOutputLength(e*this.base.numComps/this.numComps,t)}}class PatternCS extends ColorSpace{constructor(e){super("Pattern",null);this.base=e}isDefaultDecode(e,t){unreachable("Should not call PatternCS.isDefaultDecode")}}class IndexedCS extends ColorSpace{constructor(e,t,i){super("Indexed",1);this.base=e;this.highVal=t;const a=e.numComps*t;this.lookup=new Uint8Array(a);if(i instanceof BaseStream){const e=i.getBytes(a);this.lookup.set(e)}else{if("string"!=typeof i)throw new FormatError(`IndexedCS - unrecognized lookup table: ${i}`);for(let e=0;e<a;++e)this.lookup[e]=255&i.charCodeAt(e)}}getRgbItem(e,t,i,a){const s=this.base.numComps,r=e[t]*s;this.base.getRgbBuffer(this.lookup,r,1,i,a,8,0)}getRgbBuffer(e,t,i,a,s,r,n){const o=this.base,g=o.numComps,c=o.getOutputLength(g,n),h=this.lookup;for(let r=0;r<i;++r){const i=e[t++]*g;o.getRgbBuffer(h,i,1,a,s,8,n);s+=c}}getOutputLength(e,t){return this.base.getOutputLength(e*this.base.numComps,t)}isDefaultDecode(e,t){if(!Array.isArray(e))return!0;if(2!==e.length){warn("Decode map length is not correct");return!0}if(!Number.isInteger(t)||t<1){warn("Bits per component is not correct");return!0}return 0===e[0]&&e[1]===(1<<t)-1}}class DeviceGrayCS extends ColorSpace{constructor(){super("DeviceGray",1)}getRgbItem(e,t,i,a){const s=255*e[t];i[a]=i[a+1]=i[a+2]=s}getRgbBuffer(e,t,i,a,s,r,n){const o=255/((1<<r)-1);let g=t,c=s;for(let t=0;t<i;++t){const t=o*e[g++];a[c++]=t;a[c++]=t;a[c++]=t;c+=n}}getOutputLength(e,t){return e*(3+t)}}class DeviceRgbCS extends ColorSpace{constructor(){super("DeviceRGB",3)}getRgbItem(e,t,i,a){i[a]=255*e[t];i[a+1]=255*e[t+1];i[a+2]=255*e[t+2]}getRgbBuffer(e,t,i,a,s,r,n){if(8===r&&0===n){a.set(e.subarray(t,t+3*i),s);return}const o=255/((1<<r)-1);let g=t,c=s;for(let t=0;t<i;++t){a[c++]=o*e[g++];a[c++]=o*e[g++];a[c++]=o*e[g++];c+=n}}getOutputLength(e,t){return e*(3+t)/3|0}isPassthrough(e){return 8===e}}class DeviceCmykCS extends ColorSpace{constructor(){super("DeviceCMYK",4)}#t(e,t,i,a,s){const r=e[t]*i,n=e[t+1]*i,o=e[t+2]*i,g=e[t+3]*i;a[s]=255+r*(-4.387332384609988*r+54.48615194189176*n+18.82290502165302*o+212.25662451639585*g-285.2331026137004)+n*(1.7149763477362134*n-5.6096736904047315*o+-17.873870861415444*g-5.497006427196366)+o*(-2.5217340131683033*o-21.248923337353073*g+17.5119270841813)+g*(-21.86122147463605*g-189.48180835922747);a[s+1]=255+r*(8.841041422036149*r+60.118027045597366*n+6.871425592049007*o+31.159100130055922*g-79.2970844816548)+n*(-15.310361306967817*n+17.575251261109482*o+131.35250912493976*g-190.9453302588951)+o*(4.444339102852739*o+9.8632861493405*g-24.86741582555878)+g*(-20.737325471181034*g-187.80453709719578);a[s+2]=255+r*(.8842522430003296*r+8.078677503112928*n+30.89978309703729*o-.23883238689178934*g-14.183576799673286)+n*(10.49593273432072*n+63.02378494754052*o+50.606957656360734*g-112.23884253719248)+o*(.03296041114873217*o+115.60384449646641*g-193.58209356861505)+g*(-22.33816807309886*g-180.12613974708367)}getRgbItem(e,t,i,a){this.#t(e,t,1,i,a)}getRgbBuffer(e,t,i,a,s,r,n){const o=1/((1<<r)-1);for(let r=0;r<i;r++){this.#t(e,t,o,a,s);t+=4;s+=3+n}}getOutputLength(e,t){return e/4*(3+t)|0}}class CalGrayCS extends ColorSpace{constructor(e,t,i){super("CalGray",1);if(!e)throw new FormatError("WhitePoint missing - required for color space CalGray");[this.XW,this.YW,this.ZW]=e;[this.XB,this.YB,this.ZB]=t||[0,0,0];this.G=i||1;if(this.XW<0||this.ZW<0||1!==this.YW)throw new FormatError(`Invalid WhitePoint components for ${this.name}, no fallback available`);if(this.XB<0||this.YB<0||this.ZB<0){info(`Invalid BlackPoint for ${this.name}, falling back to default.`);this.XB=this.YB=this.ZB=0}0===this.XB&&0===this.YB&&0===this.ZB||warn(`${this.name}, BlackPoint: XB: ${this.XB}, YB: ${this.YB}, ZB: ${this.ZB}, only default values are supported.`);if(this.G<1){info(`Invalid Gamma: ${this.G} for ${this.name}, falling back to default.`);this.G=1}}#t(e,t,i,a,s){const r=(e[t]*s)**this.G,n=this.YW*r,o=Math.max(295.8*n**.3333333333333333-40.8,0);i[a]=o;i[a+1]=o;i[a+2]=o}getRgbItem(e,t,i,a){this.#t(e,t,i,a,1)}getRgbBuffer(e,t,i,a,s,r,n){const o=1/((1<<r)-1);for(let r=0;r<i;++r){this.#t(e,t,a,s,o);t+=1;s+=3+n}}getOutputLength(e,t){return e*(3+t)}}class CalRGBCS extends ColorSpace{static#i=new Float32Array([.8951,.2664,-.1614,-.7502,1.7135,.0367,.0389,-.0685,1.0296]);static#a=new Float32Array([.9869929,-.1470543,.1599627,.4323053,.5183603,.0492912,-.0085287,.0400428,.9684867]);static#s=new Float32Array([3.2404542,-1.5371385,-.4985314,-.969266,1.8760108,.041556,.0556434,-.2040259,1.0572252]);static#r=new Float32Array([1,1,1]);static#n=new Float32Array(3);static#o=new Float32Array(3);static#g=new Float32Array(3);static#I=(24/116)**3/8;constructor(e,t,i,a){super("CalRGB",3);if(!e)throw new FormatError("WhitePoint missing - required for color space CalRGB");const[s,r,n]=this.whitePoint=e,[o,g,c]=this.blackPoint=t||new Float32Array(3);[this.GR,this.GG,this.GB]=i||new Float32Array([1,1,1]);[this.MXA,this.MYA,this.MZA,this.MXB,this.MYB,this.MZB,this.MXC,this.MYC,this.MZC]=a||new Float32Array([1,0,0,0,1,0,0,0,1]);if(s<0||n<0||1!==r)throw new FormatError(`Invalid WhitePoint components for ${this.name}, no fallback available`);if(o<0||g<0||c<0){info(`Invalid BlackPoint for ${this.name} [${o}, ${g}, ${c}], falling back to default.`);this.blackPoint=new Float32Array(3)}if(this.GR<0||this.GG<0||this.GB<0){info(`Invalid Gamma [${this.GR}, ${this.GG}, ${this.GB}] for ${this.name}, falling back to default.`);this.GR=this.GG=this.GB=1}}#c(e,t,i){i[0]=e[0]*t[0]+e[1]*t[1]+e[2]*t[2];i[1]=e[3]*t[0]+e[4]*t[1]+e[5]*t[2];i[2]=e[6]*t[0]+e[7]*t[1]+e[8]*t[2]}#h(e,t,i){i[0]=1*t[0]/e[0];i[1]=1*t[1]/e[1];i[2]=1*t[2]/e[2]}#l(e,t,i){i[0]=.95047*t[0]/e[0];i[1]=1*t[1]/e[1];i[2]=1.08883*t[2]/e[2]}#C(e){return e<=.0031308?this.#B(0,1,12.92*e):e>=.99554525?1:this.#B(0,1,1.055*e**(1/2.4)-.055)}#B(e,t,i){return Math.max(e,Math.min(t,i))}#Q(e){return e<0?-this.#Q(-e):e>8?((e+16)/116)**3:e*CalRGBCS.#I}#E(e,t,i){if(0===e[0]&&0===e[1]&&0===e[2]){i[0]=t[0];i[1]=t[1];i[2]=t[2];return}const a=this.#Q(0),s=(1-a)/(1-this.#Q(e[0])),r=1-s,n=(1-a)/(1-this.#Q(e[1])),o=1-n,g=(1-a)/(1-this.#Q(e[2])),c=1-g;i[0]=t[0]*s+r;i[1]=t[1]*n+o;i[2]=t[2]*g+c}#u(e,t,i){if(1===e[0]&&1===e[2]){i[0]=t[0];i[1]=t[1];i[2]=t[2];return}const a=i;this.#c(CalRGBCS.#i,t,a);const s=CalRGBCS.#n;this.#h(e,a,s);this.#c(CalRGBCS.#a,s,i)}#d(e,t,i){const a=i;this.#c(CalRGBCS.#i,t,a);const s=CalRGBCS.#n;this.#l(e,a,s);this.#c(CalRGBCS.#a,s,i)}#t(e,t,i,a,s){const r=this.#B(0,1,e[t]*s),n=this.#B(0,1,e[t+1]*s),o=this.#B(0,1,e[t+2]*s),g=1===r?1:r**this.GR,c=1===n?1:n**this.GG,h=1===o?1:o**this.GB,l=this.MXA*g+this.MXB*c+this.MXC*h,C=this.MYA*g+this.MYB*c+this.MYC*h,Q=this.MZA*g+this.MZB*c+this.MZC*h,E=CalRGBCS.#o;E[0]=l;E[1]=C;E[2]=Q;const u=CalRGBCS.#g;this.#u(this.whitePoint,E,u);const d=CalRGBCS.#o;this.#E(this.blackPoint,u,d);const f=CalRGBCS.#g;this.#d(CalRGBCS.#r,d,f);const p=CalRGBCS.#o;this.#c(CalRGBCS.#s,f,p);i[a]=255*this.#C(p[0]);i[a+1]=255*this.#C(p[1]);i[a+2]=255*this.#C(p[2])}getRgbItem(e,t,i,a){this.#t(e,t,i,a,1)}getRgbBuffer(e,t,i,a,s,r,n){const o=1/((1<<r)-1);for(let r=0;r<i;++r){this.#t(e,t,a,s,o);t+=3;s+=3+n}}getOutputLength(e,t){return e*(3+t)/3|0}}class LabCS extends ColorSpace{constructor(e,t,i){super("Lab",3);if(!e)throw new FormatError("WhitePoint missing - required for color space Lab");[this.XW,this.YW,this.ZW]=e;[this.amin,this.amax,this.bmin,this.bmax]=i||[-100,100,-100,100];[this.XB,this.YB,this.ZB]=t||[0,0,0];if(this.XW<0||this.ZW<0||1!==this.YW)throw new FormatError("Invalid WhitePoint components, no fallback available");if(this.XB<0||this.YB<0||this.ZB<0){info("Invalid BlackPoint, falling back to default");this.XB=this.YB=this.ZB=0}if(this.amin>this.amax||this.bmin>this.bmax){info("Invalid Range, falling back to defaults");this.amin=-100;this.amax=100;this.bmin=-100;this.bmax=100}}#f(e){return e>=6/29?e**3:108/841*(e-4/29)}#p(e,t,i,a){return i+e*(a-i)/t}#t(e,t,i,a,s){let r=e[t],n=e[t+1],o=e[t+2];if(!1!==i){r=this.#p(r,i,0,100);n=this.#p(n,i,this.amin,this.amax);o=this.#p(o,i,this.bmin,this.bmax)}n>this.amax?n=this.amax:n<this.amin&&(n=this.amin);o>this.bmax?o=this.bmax:o<this.bmin&&(o=this.bmin);const g=(r+16)/116,c=g+n/500,h=g-o/200,l=this.XW*this.#f(c),C=this.YW*this.#f(g),Q=this.ZW*this.#f(h);let E,u,d;if(this.ZW<1){E=3.1339*l+-1.617*C+-.4906*Q;u=-.9785*l+1.916*C+.0333*Q;d=.072*l+-.229*C+1.4057*Q}else{E=3.2406*l+-1.5372*C+-.4986*Q;u=-.9689*l+1.8758*C+.0415*Q;d=.0557*l+-.204*C+1.057*Q}a[s]=255*Math.sqrt(E);a[s+1]=255*Math.sqrt(u);a[s+2]=255*Math.sqrt(d)}getRgbItem(e,t,i,a){this.#t(e,t,!1,i,a)}getRgbBuffer(e,t,i,a,s,r,n){const o=(1<<r)-1;for(let r=0;r<i;r++){this.#t(e,t,o,a,s);t+=3;s+=3+n}}getOutputLength(e,t){return e*(3+t)/3|0}isDefaultDecode(e,t){return!0}get usesZeroToOneRange(){return shadow(this,"usesZeroToOneRange",!1)}}function hexToInt(e,t){let i=0;for(let a=0;a<=t;a++)i=i<<8|e[a];return i>>>0}function hexToStr(e,t){return 1===t?String.fromCharCode(e[0],e[1]):3===t?String.fromCharCode(e[0],e[1],e[2],e[3]):String.fromCharCode(...e.subarray(0,t+1))}function addHex(e,t,i){let a=0;for(let s=i;s>=0;s--){a+=e[s]+t[s];e[s]=255&a;a>>=8}}function incHex(e,t){let i=1;for(let a=t;a>=0&&i>0;a--){i+=e[a];e[a]=255&i;i>>=8}}const kt=16;class BinaryCMapStream{constructor(e){this.buffer=e;this.pos=0;this.end=e.length;this.tmpBuf=new Uint8Array(19)}readByte(){return this.pos>=this.end?-1:this.buffer[this.pos++]}readNumber(){let e,t=0;do{const i=this.readByte();if(i<0)throw new FormatError("unexpected EOF in bcmap");e=!(128&i);t=t<<7|127&i}while(!e);return t}readSigned(){const e=this.readNumber();return 1&e?~(e>>>1):e>>>1}readHex(e,t){e.set(this.buffer.subarray(this.pos,this.pos+t+1));this.pos+=t+1}readHexNumber(e,t){let i;const a=this.tmpBuf;let s=0;do{const e=this.readByte();if(e<0)throw new FormatError("unexpected EOF in bcmap");i=!(128&e);a[s++]=127&e}while(!i);let r=t,n=0,o=0;for(;r>=0;){for(;o<8&&a.length>0;){n|=a[--s]<<o;o+=7}e[r]=255&n;r--;n>>=8;o-=8}}readHexSigned(e,t){this.readHexNumber(e,t);const i=1&e[t]?255:0;let a=0;for(let s=0;s<=t;s++){a=(1&a)<<8|e[s];e[s]=a>>1^i}}readString(){const e=this.readNumber(),t=new Array(e);for(let i=0;i<e;i++)t[i]=this.readNumber();return String.fromCharCode(...t)}}class BinaryCMapReader{async process(e,t,i){const a=new BinaryCMapStream(e),s=a.readByte();t.vertical=!!(1&s);let r=null;const n=new Uint8Array(kt),o=new Uint8Array(kt),g=new Uint8Array(kt),c=new Uint8Array(kt),h=new Uint8Array(kt);let l,C;for(;(C=a.readByte())>=0;){const e=C>>5;if(7===e){switch(31&C){case 0:a.readString();break;case 1:r=a.readString()}continue}const i=!!(16&C),s=15&C;if(s+1>kt)throw new Error("BinaryCMapReader.process: Invalid dataSize.");const Q=1,E=a.readNumber();switch(e){case 0:a.readHex(n,s);a.readHexNumber(o,s);addHex(o,n,s);t.addCodespaceRange(s+1,hexToInt(n,s),hexToInt(o,s));for(let e=1;e<E;e++){incHex(o,s);a.readHexNumber(n,s);addHex(n,o,s);a.readHexNumber(o,s);addHex(o,n,s);t.addCodespaceRange(s+1,hexToInt(n,s),hexToInt(o,s))}break;case 1:a.readHex(n,s);a.readHexNumber(o,s);addHex(o,n,s);a.readNumber();for(let e=1;e<E;e++){incHex(o,s);a.readHexNumber(n,s);addHex(n,o,s);a.readHexNumber(o,s);addHex(o,n,s);a.readNumber()}break;case 2:a.readHex(g,s);l=a.readNumber();t.mapOne(hexToInt(g,s),l);for(let e=1;e<E;e++){incHex(g,s);if(!i){a.readHexNumber(h,s);addHex(g,h,s)}l=a.readSigned()+(l+1);t.mapOne(hexToInt(g,s),l)}break;case 3:a.readHex(n,s);a.readHexNumber(o,s);addHex(o,n,s);l=a.readNumber();t.mapCidRange(hexToInt(n,s),hexToInt(o,s),l);for(let e=1;e<E;e++){incHex(o,s);if(i)n.set(o);else{a.readHexNumber(n,s);addHex(n,o,s)}a.readHexNumber(o,s);addHex(o,n,s);l=a.readNumber();t.mapCidRange(hexToInt(n,s),hexToInt(o,s),l)}break;case 4:a.readHex(g,Q);a.readHex(c,s);t.mapOne(hexToInt(g,Q),hexToStr(c,s));for(let e=1;e<E;e++){incHex(g,Q);if(!i){a.readHexNumber(h,Q);addHex(g,h,Q)}incHex(c,s);a.readHexSigned(h,s);addHex(c,h,s);t.mapOne(hexToInt(g,Q),hexToStr(c,s))}break;case 5:a.readHex(n,Q);a.readHexNumber(o,Q);addHex(o,n,Q);a.readHex(c,s);t.mapBfRange(hexToInt(n,Q),hexToInt(o,Q),hexToStr(c,s));for(let e=1;e<E;e++){incHex(o,Q);if(i)n.set(o);else{a.readHexNumber(n,Q);addHex(n,o,Q)}a.readHexNumber(o,Q);addHex(o,n,Q);a.readHex(c,s);t.mapBfRange(hexToInt(n,Q),hexToInt(o,Q),hexToStr(c,s))}break;default:throw new Error(`BinaryCMapReader.process - unknown type: ${e}`)}}return r?i(r):t}}const Rt=new Uint8Array(0);class DecodeStream extends BaseStream{constructor(e){super();this._rawMinBufferLength=e||0;this.pos=0;this.bufferLength=0;this.eof=!1;this.buffer=Rt;this.minBufferLength=512;if(e)for(;this.minBufferLength<e;)this.minBufferLength*=2}get isEmpty(){for(;!this.eof&&0===this.bufferLength;)this.readBlock();return 0===this.bufferLength}ensureBuffer(e){const t=this.buffer;if(e<=t.byteLength)return t;let i=this.minBufferLength;for(;i<e;)i*=2;const a=new Uint8Array(i);a.set(t);return this.buffer=a}getByte(){const e=this.pos;for(;this.bufferLength<=e;){if(this.eof)return-1;this.readBlock()}return this.buffer[this.pos++]}getBytes(e,t=!1){const i=this.pos;let a;if(e){this.ensureBuffer(i+e);a=i+e;for(;!this.eof&&this.bufferLength<a;)this.readBlock(t);const s=this.bufferLength;a>s&&(a=s)}else{for(;!this.eof;)this.readBlock(t);a=this.bufferLength}this.pos=a;return this.buffer.subarray(i,a)}reset(){this.pos=0}makeSubStream(e,t,i=null){if(void 0===t)for(;!this.eof;)this.readBlock();else{const i=e+t;for(;this.bufferLength<=i&&!this.eof;)this.readBlock()}return new Stream(this.buffer,e,t,i)}getBaseStreams(){return this.str?this.str.getBaseStreams():null}}class StreamsSequenceStream extends DecodeStream{constructor(e,t=null){let i=0;for(const t of e)i+=t instanceof DecodeStream?t._rawMinBufferLength:t.length;super(i);this.streams=e;this._onError=t}readBlock(){const e=this.streams;if(0===e.length){this.eof=!0;return}const t=e.shift();let i;try{i=t.getBytes()}catch(e){if(this._onError){this._onError(e,t.dict?.objId);return}throw e}const a=this.bufferLength,s=a+i.length;this.ensureBuffer(s).set(i,a);this.bufferLength=s}getBaseStreams(){const e=[];for(const t of this.streams){const i=t.getBaseStreams();i&&e.push(...i)}return e.length>0?e:null}}class Ascii85Stream extends DecodeStream{constructor(e,t){t&&(t*=.8);super(t);this.str=e;this.dict=e.dict;this.input=new Uint8Array(5)}readBlock(){const e=this.str;let t=e.getByte();for(;isWhiteSpace(t);)t=e.getByte();if(-1===t||126===t){this.eof=!0;return}const i=this.bufferLength;let a,s;if(122===t){a=this.ensureBuffer(i+4);for(s=0;s<4;++s)a[i+s]=0;this.bufferLength+=4}else{const r=this.input;r[0]=t;for(s=1;s<5;++s){t=e.getByte();for(;isWhiteSpace(t);)t=e.getByte();r[s]=t;if(-1===t||126===t)break}a=this.ensureBuffer(i+s-1);this.bufferLength+=s-1;if(s<5){for(;s<5;++s)r[s]=117;this.eof=!0}let n=0;for(s=0;s<5;++s)n=85*n+(r[s]-33);for(s=3;s>=0;--s){a[i+s]=255&n;n>>=8}}}}class AsciiHexStream extends DecodeStream{constructor(e,t){t&&(t*=.5);super(t);this.str=e;this.dict=e.dict;this.firstDigit=-1}readBlock(){const e=this.str.getBytes(8e3);if(!e.length){this.eof=!0;return}const t=e.length+1>>1,i=this.ensureBuffer(this.bufferLength+t);let a=this.bufferLength,s=this.firstDigit;for(const t of e){let e;if(t>=48&&t<=57)e=15&t;else{if(!(t>=65&&t<=70||t>=97&&t<=102)){if(62===t){this.eof=!0;break}continue}e=9+(15&t)}if(s<0)s=e;else{i[a++]=s<<4|e;s=-1}}if(s>=0&&this.eof){i[a++]=s<<4;s=-1}this.firstDigit=s;this.bufferLength=a}}const Nt=-1,Gt=[[-1,-1],[-1,-1],[7,8],[7,7],[6,6],[6,6],[6,5],[6,5],[4,0],[4,0],[4,0],[4,0],[4,0],[4,0],[4,0],[4,0],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[3,3],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2]],xt=[[-1,-1],[12,-2],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[11,1792],[11,1792],[12,1984],[12,2048],[12,2112],[12,2176],[12,2240],[12,2304],[11,1856],[11,1856],[11,1920],[11,1920],[12,2368],[12,2432],[12,2496],[12,2560]],Mt=[[-1,-1],[-1,-1],[-1,-1],[-1,-1],[8,29],[8,29],[8,30],[8,30],[8,45],[8,45],[8,46],[8,46],[7,22],[7,22],[7,22],[7,22],[7,23],[7,23],[7,23],[7,23],[8,47],[8,47],[8,48],[8,48],[6,13],[6,13],[6,13],[6,13],[6,13],[6,13],[6,13],[6,13],[7,20],[7,20],[7,20],[7,20],[8,33],[8,33],[8,34],[8,34],[8,35],[8,35],[8,36],[8,36],[8,37],[8,37],[8,38],[8,38],[7,19],[7,19],[7,19],[7,19],[8,31],[8,31],[8,32],[8,32],[6,1],[6,1],[6,1],[6,1],[6,1],[6,1],[6,1],[6,1],[6,12],[6,12],[6,12],[6,12],[6,12],[6,12],[6,12],[6,12],[8,53],[8,53],[8,54],[8,54],[7,26],[7,26],[7,26],[7,26],[8,39],[8,39],[8,40],[8,40],[8,41],[8,41],[8,42],[8,42],[8,43],[8,43],[8,44],[8,44],[7,21],[7,21],[7,21],[7,21],[7,28],[7,28],[7,28],[7,28],[8,61],[8,61],[8,62],[8,62],[8,63],[8,63],[8,0],[8,0],[8,320],[8,320],[8,384],[8,384],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,10],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[5,11],[7,27],[7,27],[7,27],[7,27],[8,59],[8,59],[8,60],[8,60],[9,1472],[9,1536],[9,1600],[9,1728],[7,18],[7,18],[7,18],[7,18],[7,24],[7,24],[7,24],[7,24],[8,49],[8,49],[8,50],[8,50],[8,51],[8,51],[8,52],[8,52],[7,25],[7,25],[7,25],[7,25],[8,55],[8,55],[8,56],[8,56],[8,57],[8,57],[8,58],[8,58],[6,192],[6,192],[6,192],[6,192],[6,192],[6,192],[6,192],[6,192],[6,1664],[6,1664],[6,1664],[6,1664],[6,1664],[6,1664],[6,1664],[6,1664],[8,448],[8,448],[8,512],[8,512],[9,704],[9,768],[8,640],[8,640],[8,576],[8,576],[9,832],[9,896],[9,960],[9,1024],[9,1088],[9,1152],[9,1216],[9,1280],[9,1344],[9,1408],[7,256],[7,256],[7,256],[7,256],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,128],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,8],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[5,9],[6,16],[6,16],[6,16],[6,16],[6,16],[6,16],[6,16],[6,16],[6,17],[6,17],[6,17],[6,17],[6,17],[6,17],[6,17],[6,17],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,4],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[4,5],[6,14],[6,14],[6,14],[6,14],[6,14],[6,14],[6,14],[6,14],[6,15],[6,15],[6,15],[6,15],[6,15],[6,15],[6,15],[6,15],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[5,64],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,6],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7],[4,7]],Ut=[[-1,-1],[-1,-1],[12,-2],[12,-2],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[-1,-1],[11,1792],[11,1792],[11,1792],[11,1792],[12,1984],[12,1984],[12,2048],[12,2048],[12,2112],[12,2112],[12,2176],[12,2176],[12,2240],[12,2240],[12,2304],[12,2304],[11,1856],[11,1856],[11,1856],[11,1856],[11,1920],[11,1920],[11,1920],[11,1920],[12,2368],[12,2368],[12,2432],[12,2432],[12,2496],[12,2496],[12,2560],[12,2560],[10,18],[10,18],[10,18],[10,18],[10,18],[10,18],[10,18],[10,18],[12,52],[12,52],[13,640],[13,704],[13,768],[13,832],[12,55],[12,55],[12,56],[12,56],[13,1280],[13,1344],[13,1408],[13,1472],[12,59],[12,59],[12,60],[12,60],[13,1536],[13,1600],[11,24],[11,24],[11,24],[11,24],[11,25],[11,25],[11,25],[11,25],[13,1664],[13,1728],[12,320],[12,320],[12,384],[12,384],[12,448],[12,448],[13,512],[13,576],[12,53],[12,53],[12,54],[12,54],[13,896],[13,960],[13,1024],[13,1088],[13,1152],[13,1216],[10,64],[10,64],[10,64],[10,64],[10,64],[10,64],[10,64],[10,64]],Lt=[[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[8,13],[11,23],[11,23],[12,50],[12,51],[12,44],[12,45],[12,46],[12,47],[12,57],[12,58],[12,61],[12,256],[10,16],[10,16],[10,16],[10,16],[10,17],[10,17],[10,17],[10,17],[12,48],[12,49],[12,62],[12,63],[12,30],[12,31],[12,32],[12,33],[12,40],[12,41],[11,22],[11,22],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[8,14],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,10],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[7,11],[9,15],[9,15],[9,15],[9,15],[9,15],[9,15],[9,15],[9,15],[12,128],[12,192],[12,26],[12,27],[12,28],[12,29],[11,19],[11,19],[11,20],[11,20],[12,34],[12,35],[12,36],[12,37],[12,38],[12,39],[11,21],[11,21],[12,42],[12,43],[10,0],[10,0],[10,0],[10,0],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12],[7,12]],Jt=[[-1,-1],[-1,-1],[-1,-1],[-1,-1],[6,9],[6,8],[5,7],[5,7],[4,6],[4,6],[4,6],[4,6],[4,5],[4,5],[4,5],[4,5],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2],[2,2]];class CCITTFaxDecoder{constructor(e,t={}){if(!e||"function"!=typeof e.next)throw new Error('CCITTFaxDecoder - invalid "source" parameter.');this.source=e;this.eof=!1;this.encoding=t.K||0;this.eoline=t.EndOfLine||!1;this.byteAlign=t.EncodedByteAlign||!1;this.columns=t.Columns||1728;this.rows=t.Rows||0;this.eoblock=t.EndOfBlock??!0;this.black=t.BlackIs1||!1;this.codingLine=new Uint32Array(this.columns+1);this.refLine=new Uint32Array(this.columns+2);this.codingLine[0]=this.columns;this.codingPos=0;this.row=0;this.nextLine2D=this.encoding<0;this.inputBits=0;this.inputBuf=0;this.outputBits=0;this.rowsDone=!1;let i;for(;0===(i=this._lookBits(12));)this._eatBits(1);1===i&&this._eatBits(12);if(this.encoding>0){this.nextLine2D=!this._lookBits(1);this._eatBits(1)}}readNextChar(){if(this.eof)return-1;const e=this.refLine,t=this.codingLine,i=this.columns;let a,s,r,n,o;if(0===this.outputBits){this.rowsDone&&(this.eof=!0);if(this.eof)return-1;this.err=!1;let r,o,g;if(this.nextLine2D){for(n=0;t[n]<i;++n)e[n]=t[n];e[n++]=i;e[n]=i;t[0]=0;this.codingPos=0;a=0;s=0;for(;t[this.codingPos]<i;){r=this._getTwoDimCode();switch(r){case 0:this._addPixels(e[a+1],s);e[a+1]<i&&(a+=2);break;case 1:r=o=0;if(s){do{r+=g=this._getBlackCode()}while(g>=64);do{o+=g=this._getWhiteCode()}while(g>=64)}else{do{r+=g=this._getWhiteCode()}while(g>=64);do{o+=g=this._getBlackCode()}while(g>=64)}this._addPixels(t[this.codingPos]+r,s);t[this.codingPos]<i&&this._addPixels(t[this.codingPos]+o,1^s);for(;e[a]<=t[this.codingPos]&&e[a]<i;)a+=2;break;case 7:this._addPixels(e[a]+3,s);s^=1;if(t[this.codingPos]<i){++a;for(;e[a]<=t[this.codingPos]&&e[a]<i;)a+=2}break;case 5:this._addPixels(e[a]+2,s);s^=1;if(t[this.codingPos]<i){++a;for(;e[a]<=t[this.codingPos]&&e[a]<i;)a+=2}break;case 3:this._addPixels(e[a]+1,s);s^=1;if(t[this.codingPos]<i){++a;for(;e[a]<=t[this.codingPos]&&e[a]<i;)a+=2}break;case 2:this._addPixels(e[a],s);s^=1;if(t[this.codingPos]<i){++a;for(;e[a]<=t[this.codingPos]&&e[a]<i;)a+=2}break;case 8:this._addPixelsNeg(e[a]-3,s);s^=1;if(t[this.codingPos]<i){a>0?--a:++a;for(;e[a]<=t[this.codingPos]&&e[a]<i;)a+=2}break;case 6:this._addPixelsNeg(e[a]-2,s);s^=1;if(t[this.codingPos]<i){a>0?--a:++a;for(;e[a]<=t[this.codingPos]&&e[a]<i;)a+=2}break;case 4:this._addPixelsNeg(e[a]-1,s);s^=1;if(t[this.codingPos]<i){a>0?--a:++a;for(;e[a]<=t[this.codingPos]&&e[a]<i;)a+=2}break;case Nt:this._addPixels(i,0);this.eof=!0;break;default:info("bad 2d code");this._addPixels(i,0);this.err=!0}}}else{t[0]=0;this.codingPos=0;s=0;for(;t[this.codingPos]<i;){r=0;if(s)do{r+=g=this._getBlackCode()}while(g>=64);else do{r+=g=this._getWhiteCode()}while(g>=64);this._addPixels(t[this.codingPos]+r,s);s^=1}}let c=!1;this.byteAlign&&(this.inputBits&=-8);if(this.eoblock||this.row!==this.rows-1){r=this._lookBits(12);if(this.eoline)for(;r!==Nt&&1!==r;){this._eatBits(1);r=this._lookBits(12)}else for(;0===r;){this._eatBits(1);r=this._lookBits(12)}if(1===r){this._eatBits(12);c=!0}else r===Nt&&(this.eof=!0)}else this.rowsDone=!0;if(!this.eof&&this.encoding>0&&!this.rowsDone){this.nextLine2D=!this._lookBits(1);this._eatBits(1)}if(this.eoblock&&c&&this.byteAlign){r=this._lookBits(12);if(1===r){this._eatBits(12);if(this.encoding>0){this._lookBits(1);this._eatBits(1)}if(this.encoding>=0)for(n=0;n<4;++n){r=this._lookBits(12);1!==r&&info("bad rtc code: "+r);this._eatBits(12);if(this.encoding>0){this._lookBits(1);this._eatBits(1)}}this.eof=!0}}else if(this.err&&this.eoline){for(;;){r=this._lookBits(13);if(r===Nt){this.eof=!0;return-1}if(r>>1==1)break;this._eatBits(1)}this._eatBits(12);if(this.encoding>0){this._eatBits(1);this.nextLine2D=!(1&r)}}this.outputBits=t[0]>0?t[this.codingPos=0]:t[this.codingPos=1];this.row++}if(this.outputBits>=8){o=1&this.codingPos?0:255;this.outputBits-=8;if(0===this.outputBits&&t[this.codingPos]<i){this.codingPos++;this.outputBits=t[this.codingPos]-t[this.codingPos-1]}}else{r=8;o=0;do{if("number"!=typeof this.outputBits)throw new FormatError('Invalid /CCITTFaxDecode data, "outputBits" must be a number.');if(this.outputBits>r){o<<=r;1&this.codingPos||(o|=255>>8-r);this.outputBits-=r;r=0}else{o<<=this.outputBits;1&this.codingPos||(o|=255>>8-this.outputBits);r-=this.outputBits;this.outputBits=0;if(t[this.codingPos]<i){this.codingPos++;this.outputBits=t[this.codingPos]-t[this.codingPos-1]}else if(r>0){o<<=r;r=0}}}while(r)}this.black&&(o^=255);return o}_addPixels(e,t){const i=this.codingLine;let a=this.codingPos;if(e>i[a]){if(e>this.columns){info("row is wrong length");this.err=!0;e=this.columns}1&a^t&&++a;i[a]=e}this.codingPos=a}_addPixelsNeg(e,t){const i=this.codingLine;let a=this.codingPos;if(e>i[a]){if(e>this.columns){info("row is wrong length");this.err=!0;e=this.columns}1&a^t&&++a;i[a]=e}else if(e<i[a]){if(e<0){info("invalid code");this.err=!0;e=0}for(;a>0&&e<i[a-1];)--a;i[a]=e}this.codingPos=a}_findTableCode(e,t,i,a){const s=a||0;for(let a=e;a<=t;++a){let e=this._lookBits(a);if(e===Nt)return[!0,1,!1];a<t&&(e<<=t-a);if(!s||e>=s){const t=i[e-s];if(t[0]===a){this._eatBits(a);return[!0,t[1],!0]}}}return[!1,0,!1]}_getTwoDimCode(){let e,t=0;if(this.eoblock){t=this._lookBits(7);e=Gt[t];if(e?.[0]>0){this._eatBits(e[0]);return e[1]}}else{const e=this._findTableCode(1,7,Gt);if(e[0]&&e[2])return e[1]}info("Bad two dim code");return Nt}_getWhiteCode(){let e,t=0;if(this.eoblock){t=this._lookBits(12);if(t===Nt)return 1;e=t>>5==0?xt[t]:Mt[t>>3];if(e[0]>0){this._eatBits(e[0]);return e[1]}}else{let e=this._findTableCode(1,9,Mt);if(e[0])return e[1];e=this._findTableCode(11,12,xt);if(e[0])return e[1]}info("bad white code");this._eatBits(1);return 1}_getBlackCode(){let e,t;if(this.eoblock){e=this._lookBits(13);if(e===Nt)return 1;t=e>>7==0?Ut[e]:e>>9==0&&e>>7!=0?Lt[(e>>1)-64]:Jt[e>>7];if(t[0]>0){this._eatBits(t[0]);return t[1]}}else{let e=this._findTableCode(2,6,Jt);if(e[0])return e[1];e=this._findTableCode(7,12,Lt,64);if(e[0])return e[1];e=this._findTableCode(10,13,Ut);if(e[0])return e[1]}info("bad black code");this._eatBits(1);return 1}_lookBits(e){let t;for(;this.inputBits<e;){if(-1===(t=this.source.next()))return 0===this.inputBits?Nt:this.inputBuf<<e-this.inputBits&65535>>16-e;this.inputBuf=this.inputBuf<<8|t;this.inputBits+=8}return this.inputBuf>>this.inputBits-e&65535>>16-e}_eatBits(e){(this.inputBits-=e)<0&&(this.inputBits=0)}}class CCITTFaxStream extends DecodeStream{constructor(e,t,i){super(t);this.str=e;this.dict=e.dict;i instanceof Dict||(i=Dict.empty);const a={next:()=>e.getByte()};this.ccittFaxDecoder=new CCITTFaxDecoder(a,{K:i.get("K"),EndOfLine:i.get("EndOfLine"),EncodedByteAlign:i.get("EncodedByteAlign"),Columns:i.get("Columns"),Rows:i.get("Rows"),EndOfBlock:i.get("EndOfBlock"),BlackIs1:i.get("BlackIs1")})}readBlock(){for(;!this.eof;){const e=this.ccittFaxDecoder.readNextChar();if(-1===e){this.eof=!0;return}this.ensureBuffer(this.bufferLength+1);this.buffer[this.bufferLength++]=e}}}const Ht=new Int32Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),Yt=new Int32Array([3,4,5,6,7,8,9,10,65547,65549,65551,65553,131091,131095,131099,131103,196643,196651,196659,196667,262211,262227,262243,262259,327811,327843,327875,327907,258,258,258]),vt=new Int32Array([1,2,3,4,65541,65543,131081,131085,196625,196633,262177,262193,327745,327777,393345,393409,459009,459137,524801,525057,590849,591361,657409,658433,724993,727041,794625,798721,868353,876545]),Kt=[new Int32Array([459008,524368,524304,524568,459024,524400,524336,590016,459016,524384,524320,589984,524288,524416,524352,590048,459012,524376,524312,589968,459028,524408,524344,590032,459020,524392,524328,59e4,524296,524424,524360,590064,459010,524372,524308,524572,459026,524404,524340,590024,459018,524388,524324,589992,524292,524420,524356,590056,459014,524380,524316,589976,459030,524412,524348,590040,459022,524396,524332,590008,524300,524428,524364,590072,459009,524370,524306,524570,459025,524402,524338,590020,459017,524386,524322,589988,524290,524418,524354,590052,459013,524378,524314,589972,459029,524410,524346,590036,459021,524394,524330,590004,524298,524426,524362,590068,459011,524374,524310,524574,459027,524406,524342,590028,459019,524390,524326,589996,524294,524422,524358,590060,459015,524382,524318,589980,459031,524414,524350,590044,459023,524398,524334,590012,524302,524430,524366,590076,459008,524369,524305,524569,459024,524401,524337,590018,459016,524385,524321,589986,524289,524417,524353,590050,459012,524377,524313,589970,459028,524409,524345,590034,459020,524393,524329,590002,524297,524425,524361,590066,459010,524373,524309,524573,459026,524405,524341,590026,459018,524389,524325,589994,524293,524421,524357,590058,459014,524381,524317,589978,459030,524413,524349,590042,459022,524397,524333,590010,524301,524429,524365,590074,459009,524371,524307,524571,459025,524403,524339,590022,459017,524387,524323,589990,524291,524419,524355,590054,459013,524379,524315,589974,459029,524411,524347,590038,459021,524395,524331,590006,524299,524427,524363,590070,459011,524375,524311,524575,459027,524407,524343,590030,459019,524391,524327,589998,524295,524423,524359,590062,459015,524383,524319,589982,459031,524415,524351,590046,459023,524399,524335,590014,524303,524431,524367,590078,459008,524368,524304,524568,459024,524400,524336,590017,459016,524384,524320,589985,524288,524416,524352,590049,459012,524376,524312,589969,459028,524408,524344,590033,459020,524392,524328,590001,524296,524424,524360,590065,459010,524372,524308,524572,459026,524404,524340,590025,459018,524388,524324,589993,524292,524420,524356,590057,459014,524380,524316,589977,459030,524412,524348,590041,459022,524396,524332,590009,524300,524428,524364,590073,459009,524370,524306,524570,459025,524402,524338,590021,459017,524386,524322,589989,524290,524418,524354,590053,459013,524378,524314,589973,459029,524410,524346,590037,459021,524394,524330,590005,524298,524426,524362,590069,459011,524374,524310,524574,459027,524406,524342,590029,459019,524390,524326,589997,524294,524422,524358,590061,459015,524382,524318,589981,459031,524414,524350,590045,459023,524398,524334,590013,524302,524430,524366,590077,459008,524369,524305,524569,459024,524401,524337,590019,459016,524385,524321,589987,524289,524417,524353,590051,459012,524377,524313,589971,459028,524409,524345,590035,459020,524393,524329,590003,524297,524425,524361,590067,459010,524373,524309,524573,459026,524405,524341,590027,459018,524389,524325,589995,524293,524421,524357,590059,459014,524381,524317,589979,459030,524413,524349,590043,459022,524397,524333,590011,524301,524429,524365,590075,459009,524371,524307,524571,459025,524403,524339,590023,459017,524387,524323,589991,524291,524419,524355,590055,459013,524379,524315,589975,459029,524411,524347,590039,459021,524395,524331,590007,524299,524427,524363,590071,459011,524375,524311,524575,459027,524407,524343,590031,459019,524391,524327,589999,524295,524423,524359,590063,459015,524383,524319,589983,459031,524415,524351,590047,459023,524399,524335,590015,524303,524431,524367,590079]),9],Tt=[new Int32Array([327680,327696,327688,327704,327684,327700,327692,327708,327682,327698,327690,327706,327686,327702,327694,0,327681,327697,327689,327705,327685,327701,327693,327709,327683,327699,327691,327707,327687,327703,327695,0]),5];class FlateStream extends DecodeStream{constructor(e,t){super(t);this.str=e;this.dict=e.dict;const i=e.getByte(),a=e.getByte();if(-1===i||-1===a)throw new FormatError(`Invalid header in flate stream: ${i}, ${a}`);if(8!=(15&i))throw new FormatError(`Unknown compression method in flate stream: ${i}, ${a}`);if(((i<<8)+a)%31!=0)throw new FormatError(`Bad FCHECK in flate stream: ${i}, ${a}`);if(32&a)throw new FormatError(`FDICT bit set in flate stream: ${i}, ${a}`);this.codeSize=0;this.codeBuf=0}getBits(e){const t=this.str;let i,a=this.codeSize,s=this.codeBuf;for(;a<e;){if(-1===(i=t.getByte()))throw new FormatError("Bad encoding in flate stream");s|=i<<a;a+=8}i=s&(1<<e)-1;this.codeBuf=s>>e;this.codeSize=a-=e;return i}getCode(e){const t=this.str,i=e[0],a=e[1];let s,r=this.codeSize,n=this.codeBuf;for(;r<a&&-1!==(s=t.getByte());){n|=s<<r;r+=8}const o=i[n&(1<<a)-1],g=o>>16,c=65535&o;if(g<1||r<g)throw new FormatError("Bad encoding in flate stream");this.codeBuf=n>>g;this.codeSize=r-g;return c}generateHuffmanTable(e){const t=e.length;let i,a=0;for(i=0;i<t;++i)e[i]>a&&(a=e[i]);const s=1<<a,r=new Int32Array(s);for(let n=1,o=0,g=2;n<=a;++n,o<<=1,g<<=1)for(let a=0;a<t;++a)if(e[a]===n){let e=0,t=o;for(i=0;i<n;++i){e=e<<1|1&t;t>>=1}for(i=e;i<s;i+=g)r[i]=n<<16|a;++o}return[r,a]}#m(e){info(e);this.eof=!0}readBlock(){let e,t;const i=this.str;let a,s,r=this.getBits(3);1&r&&(this.eof=!0);r>>=1;if(0===r){let t;if(-1===(t=i.getByte())){this.#m("Bad block header in flate stream");return}let a=t;if(-1===(t=i.getByte())){this.#m("Bad block header in flate stream");return}a|=t<<8;if(-1===(t=i.getByte())){this.#m("Bad block header in flate stream");return}let s=t;if(-1===(t=i.getByte())){this.#m("Bad block header in flate stream");return}s|=t<<8;if(s!==(65535&~a)&&(0!==a||0!==s))throw new FormatError("Bad uncompressed block length in flate stream");this.codeBuf=0;this.codeSize=0;const r=this.bufferLength,n=r+a;e=this.ensureBuffer(n);this.bufferLength=n;if(0===a)-1===i.peekByte()&&(this.eof=!0);else{const t=i.getBytes(a);e.set(t,r);t.length<a&&(this.eof=!0)}return}if(1===r){a=Kt;s=Tt}else{if(2!==r)throw new FormatError("Unknown block type in flate stream");{const e=this.getBits(5)+257,i=this.getBits(5)+1,r=this.getBits(4)+4,n=new Uint8Array(Ht.length);let o;for(o=0;o<r;++o)n[Ht[o]]=this.getBits(3);const g=this.generateHuffmanTable(n);t=0;o=0;const c=e+i,h=new Uint8Array(c);let l,C,Q;for(;o<c;){const e=this.getCode(g);if(16===e){l=2;C=3;Q=t}else if(17===e){l=3;C=3;Q=t=0}else{if(18!==e){h[o++]=t=e;continue}l=7;C=11;Q=t=0}let i=this.getBits(l)+C;for(;i-- >0;)h[o++]=Q}a=this.generateHuffmanTable(h.subarray(0,e));s=this.generateHuffmanTable(h.subarray(e,c))}}e=this.buffer;let n=e?e.length:0,o=this.bufferLength;for(;;){let i=this.getCode(a);if(i<256){if(o+1>=n){e=this.ensureBuffer(o+1);n=e.length}e[o++]=i;continue}if(256===i){this.bufferLength=o;return}i-=257;i=Yt[i];let r=i>>16;r>0&&(r=this.getBits(r));t=(65535&i)+r;i=this.getCode(s);i=vt[i];r=i>>16;r>0&&(r=this.getBits(r));const g=(65535&i)+r;if(o+t>=n){e=this.ensureBuffer(o+t);n=e.length}for(let i=0;i<t;++i,++o)e[o]=e[o-g]}}}const qt=[{qe:22017,nmps:1,nlps:1,switchFlag:1},{qe:13313,nmps:2,nlps:6,switchFlag:0},{qe:6145,nmps:3,nlps:9,switchFlag:0},{qe:2753,nmps:4,nlps:12,switchFlag:0},{qe:1313,nmps:5,nlps:29,switchFlag:0},{qe:545,nmps:38,nlps:33,switchFlag:0},{qe:22017,nmps:7,nlps:6,switchFlag:1},{qe:21505,nmps:8,nlps:14,switchFlag:0},{qe:18433,nmps:9,nlps:14,switchFlag:0},{qe:14337,nmps:10,nlps:14,switchFlag:0},{qe:12289,nmps:11,nlps:17,switchFlag:0},{qe:9217,nmps:12,nlps:18,switchFlag:0},{qe:7169,nmps:13,nlps:20,switchFlag:0},{qe:5633,nmps:29,nlps:21,switchFlag:0},{qe:22017,nmps:15,nlps:14,switchFlag:1},{qe:21505,nmps:16,nlps:14,switchFlag:0},{qe:20737,nmps:17,nlps:15,switchFlag:0},{qe:18433,nmps:18,nlps:16,switchFlag:0},{qe:14337,nmps:19,nlps:17,switchFlag:0},{qe:13313,nmps:20,nlps:18,switchFlag:0},{qe:12289,nmps:21,nlps:19,switchFlag:0},{qe:10241,nmps:22,nlps:19,switchFlag:0},{qe:9217,nmps:23,nlps:20,switchFlag:0},{qe:8705,nmps:24,nlps:21,switchFlag:0},{qe:7169,nmps:25,nlps:22,switchFlag:0},{qe:6145,nmps:26,nlps:23,switchFlag:0},{qe:5633,nmps:27,nlps:24,switchFlag:0},{qe:5121,nmps:28,nlps:25,switchFlag:0},{qe:4609,nmps:29,nlps:26,switchFlag:0},{qe:4353,nmps:30,nlps:27,switchFlag:0},{qe:2753,nmps:31,nlps:28,switchFlag:0},{qe:2497,nmps:32,nlps:29,switchFlag:0},{qe:2209,nmps:33,nlps:30,switchFlag:0},{qe:1313,nmps:34,nlps:31,switchFlag:0},{qe:1089,nmps:35,nlps:32,switchFlag:0},{qe:673,nmps:36,nlps:33,switchFlag:0},{qe:545,nmps:37,nlps:34,switchFlag:0},{qe:321,nmps:38,nlps:35,switchFlag:0},{qe:273,nmps:39,nlps:36,switchFlag:0},{qe:133,nmps:40,nlps:37,switchFlag:0},{qe:73,nmps:41,nlps:38,switchFlag:0},{qe:37,nmps:42,nlps:39,switchFlag:0},{qe:21,nmps:43,nlps:40,switchFlag:0},{qe:9,nmps:44,nlps:41,switchFlag:0},{qe:5,nmps:45,nlps:42,switchFlag:0},{qe:1,nmps:45,nlps:43,switchFlag:0},{qe:22017,nmps:46,nlps:46,switchFlag:0}];class ArithmeticDecoder{constructor(e,t,i){this.data=e;this.bp=t;this.dataEnd=i;this.chigh=e[t];this.clow=0;this.byteIn();this.chigh=this.chigh<<7&65535|this.clow>>9&127;this.clow=this.clow<<7&65535;this.ct-=7;this.a=32768}byteIn(){const e=this.data;let t=this.bp;if(255===e[t])if(e[t+1]>143){this.clow+=65280;this.ct=8}else{t++;this.clow+=e[t]<<9;this.ct=7;this.bp=t}else{t++;this.clow+=t<this.dataEnd?e[t]<<8:65280;this.ct=8;this.bp=t}if(this.clow>65535){this.chigh+=this.clow>>16;this.clow&=65535}}readBit(e,t){let i=e[t]>>1,a=1&e[t];const s=qt[i],r=s.qe;let n,o=this.a-r;if(this.chigh<r)if(o<r){o=r;n=a;i=s.nmps}else{o=r;n=1^a;1===s.switchFlag&&(a=n);i=s.nlps}else{this.chigh-=r;if(0!=(32768&o)){this.a=o;return a}if(o<r){n=1^a;1===s.switchFlag&&(a=n);i=s.nlps}else{n=a;i=s.nmps}}do{0===this.ct&&this.byteIn();o<<=1;this.chigh=this.chigh<<1&65535|this.clow>>15&1;this.clow=this.clow<<1&65535;this.ct--}while(0==(32768&o));this.a=o;e[t]=i<<1|a;return n}}class Jbig2Error extends rt{constructor(e){super(e,"Jbig2Error")}}class ContextCache{getContexts(e){return e in this?this[e]:this[e]=new Int8Array(65536)}}class DecodingContext{constructor(e,t,i){this.data=e;this.start=t;this.end=i}get decoder(){return shadow(this,"decoder",new ArithmeticDecoder(this.data,this.start,this.end))}get contextCache(){return shadow(this,"contextCache",new ContextCache)}}const Ot=2**31-1,Pt=-(2**31);function decodeInteger(e,t,i){const a=e.getContexts(t);let s=1;function readBits(e){let t=0;for(let r=0;r<e;r++){const e=i.readBit(a,s);s=s<256?s<<1|e:511&(s<<1|e)|256;t=t<<1|e}return t>>>0}const r=readBits(1),n=readBits(1)?readBits(1)?readBits(1)?readBits(1)?readBits(1)?readBits(32)+4436:readBits(12)+340:readBits(8)+84:readBits(6)+20:readBits(4)+4:readBits(2);let o;0===r?o=n:n>0&&(o=-n);return o>=Pt&&o<=Ot?o:null}function decodeIAID(e,t,i){const a=e.getContexts("IAID");let s=1;for(let e=0;e<i;e++){s=s<<1|t.readBit(a,s)}return i<31?s&(1<<i)-1:2147483647&s}const Wt=["SymbolDictionary",null,null,null,"IntermediateTextRegion",null,"ImmediateTextRegion","ImmediateLosslessTextRegion",null,null,null,null,null,null,null,null,"PatternDictionary",null,null,null,"IntermediateHalftoneRegion",null,"ImmediateHalftoneRegion","ImmediateLosslessHalftoneRegion",null,null,null,null,null,null,null,null,null,null,null,null,"IntermediateGenericRegion",null,"ImmediateGenericRegion","ImmediateLosslessGenericRegion","IntermediateGenericRefinementRegion",null,"ImmediateGenericRefinementRegion","ImmediateLosslessGenericRefinementRegion",null,null,null,null,"PageInformation","EndOfPage","EndOfStripe","EndOfFile","Profiles","Tables",null,null,null,null,null,null,null,null,"Extension"],Xt=[[{x:-1,y:-2},{x:0,y:-2},{x:1,y:-2},{x:-2,y:-1},{x:-1,y:-1},{x:0,y:-1},{x:1,y:-1},{x:2,y:-1},{x:-4,y:0},{x:-3,y:0},{x:-2,y:0},{x:-1,y:0}],[{x:-1,y:-2},{x:0,y:-2},{x:1,y:-2},{x:2,y:-2},{x:-2,y:-1},{x:-1,y:-1},{x:0,y:-1},{x:1,y:-1},{x:2,y:-1},{x:-3,y:0},{x:-2,y:0},{x:-1,y:0}],[{x:-1,y:-2},{x:0,y:-2},{x:1,y:-2},{x:-2,y:-1},{x:-1,y:-1},{x:0,y:-1},{x:1,y:-1},{x:-2,y:0},{x:-1,y:0}],[{x:-3,y:-1},{x:-2,y:-1},{x:-1,y:-1},{x:0,y:-1},{x:1,y:-1},{x:-4,y:0},{x:-3,y:0},{x:-2,y:0},{x:-1,y:0}]],jt=[{coding:[{x:0,y:-1},{x:1,y:-1},{x:-1,y:0}],reference:[{x:0,y:-1},{x:1,y:-1},{x:-1,y:0},{x:0,y:0},{x:1,y:0},{x:-1,y:1},{x:0,y:1},{x:1,y:1}]},{coding:[{x:-1,y:-1},{x:0,y:-1},{x:1,y:-1},{x:-1,y:0}],reference:[{x:0,y:-1},{x:-1,y:0},{x:0,y:0},{x:1,y:0},{x:0,y:1},{x:1,y:1}]}],Zt=[39717,1941,229,405],Vt=[32,8];function decodeBitmap(e,t,i,a,s,r,n,o){if(e){return decodeMMRBitmap(new Reader(o.data,o.start,o.end),t,i,!1)}if(0===a&&!r&&!s&&4===n.length&&3===n[0].x&&-1===n[0].y&&-3===n[1].x&&-1===n[1].y&&2===n[2].x&&-2===n[2].y&&-2===n[3].x&&-2===n[3].y)return function decodeBitmapTemplate0(e,t,i){const a=i.decoder,s=i.contextCache.getContexts("GB"),r=[];let n,o,g,c,h,l,C;for(o=0;o<t;o++){h=r[o]=new Uint8Array(e);l=o<1?h:r[o-1];C=o<2?h:r[o-2];n=C[0]<<13|C[1]<<12|C[2]<<11|l[0]<<7|l[1]<<6|l[2]<<5|l[3]<<4;for(g=0;g<e;g++){h[g]=c=a.readBit(s,n);n=(31735&n)<<1|(g+3<e?C[g+3]<<11:0)|(g+4<e?l[g+4]<<4:0)|c}}return r}(t,i,o);const g=!!r,c=Xt[a].concat(n);c.sort((function(e,t){return e.y-t.y||e.x-t.x}));const h=c.length,l=new Int8Array(h),C=new Int8Array(h),Q=[];let E,u,d=0,f=0,p=0,m=0;for(u=0;u<h;u++){l[u]=c[u].x;C[u]=c[u].y;f=Math.min(f,c[u].x);p=Math.max(p,c[u].x);m=Math.min(m,c[u].y);u<h-1&&c[u].y===c[u+1].y&&c[u].x===c[u+1].x-1?d|=1<<h-1-u:Q.push(u)}const y=Q.length,w=new Int8Array(y),b=new Int8Array(y),D=new Uint16Array(y);for(E=0;E<y;E++){u=Q[E];w[E]=c[u].x;b[E]=c[u].y;D[E]=1<<h-1-u}const F=-f,S=-m,k=t-p,R=Zt[a];let N=new Uint8Array(t);const G=[],x=o.decoder,M=o.contextCache.getContexts("GB");let U,L,J,H,Y,v=0,K=0;for(let e=0;e<i;e++){if(s){v^=x.readBit(M,R);if(v){G.push(N);continue}}N=new Uint8Array(N);G.push(N);for(U=0;U<t;U++){if(g&&r[e][U]){N[U]=0;continue}if(U>=F&&U<k&&e>=S){K=K<<1&d;for(u=0;u<y;u++){L=e+b[u];J=U+w[u];H=G[L][J];if(H){H=D[u];K|=H}}}else{K=0;Y=h-1;for(u=0;u<h;u++,Y--){J=U+l[u];if(J>=0&&J<t){L=e+C[u];if(L>=0){H=G[L][J];H&&(K|=H<<Y)}}}}const i=x.readBit(M,K);N[U]=i}}return G}function decodeRefinement(e,t,i,a,s,r,n,o,g){let c=jt[i].coding;0===i&&(c=c.concat([o[0]]));const h=c.length,l=new Int32Array(h),C=new Int32Array(h);let Q;for(Q=0;Q<h;Q++){l[Q]=c[Q].x;C[Q]=c[Q].y}let E=jt[i].reference;0===i&&(E=E.concat([o[1]]));const u=E.length,d=new Int32Array(u),f=new Int32Array(u);for(Q=0;Q<u;Q++){d[Q]=E[Q].x;f[Q]=E[Q].y}const p=a[0].length,m=a.length,y=Vt[i],w=[],b=g.decoder,D=g.contextCache.getContexts("GR");let F=0;for(let i=0;i<t;i++){if(n){F^=b.readBit(D,y);if(F)throw new Jbig2Error("prediction is not supported")}const t=new Uint8Array(e);w.push(t);for(let n=0;n<e;n++){let o,g,c=0;for(Q=0;Q<h;Q++){o=i+C[Q];g=n+l[Q];o<0||g<0||g>=e?c<<=1:c=c<<1|w[o][g]}for(Q=0;Q<u;Q++){o=i+f[Q]-r;g=n+d[Q]-s;o<0||o>=m||g<0||g>=p?c<<=1:c=c<<1|a[o][g]}const E=b.readBit(D,c);t[n]=E}}return w}function decodeTextRegion(e,t,i,a,s,r,n,o,g,c,h,l,C,Q,E,u,d,f,p){if(e&&t)throw new Jbig2Error("refinement with Huffman is not supported");const m=[];let y,w;for(y=0;y<a;y++){w=new Uint8Array(i);if(s)for(let e=0;e<i;e++)w[e]=s;m.push(w)}const b=d.decoder,D=d.contextCache;let F=e?-Q.tableDeltaT.decode(p):-decodeInteger(D,"IADT",b),S=0;y=0;for(;y<r;){F+=e?Q.tableDeltaT.decode(p):decodeInteger(D,"IADT",b);S+=e?Q.tableFirstS.decode(p):decodeInteger(D,"IAFS",b);let a=S;for(;;){let s=0;n>1&&(s=e?p.readBits(f):decodeInteger(D,"IAIT",b));const r=n*F+s,S=e?Q.symbolIDTable.decode(p):decodeIAID(D,b,g),k=t&&(e?p.readBit():decodeInteger(D,"IARI",b));let R=o[S],N=R[0].length,G=R.length;if(k){const e=decodeInteger(D,"IARDW",b),t=decodeInteger(D,"IARDH",b);N+=e;G+=t;R=decodeRefinement(N,G,E,R,(e>>1)+decodeInteger(D,"IARDX",b),(t>>1)+decodeInteger(D,"IARDY",b),!1,u,d)}let x=0;c?1&l?x=G-1:a+=G-1:l>1?a+=N-1:x=N-1;const M=r-(1&l?0:G-1),U=a-(2&l?N-1:0);let L,J,H;if(c)for(L=0;L<G;L++){w=m[U+L];if(!w)continue;H=R[L];const e=Math.min(i-M,N);switch(C){case 0:for(J=0;J<e;J++)w[M+J]|=H[J];break;case 2:for(J=0;J<e;J++)w[M+J]^=H[J];break;default:throw new Jbig2Error(`operator ${C} is not supported`)}}else for(J=0;J<G;J++){w=m[M+J];if(w){H=R[J];switch(C){case 0:for(L=0;L<N;L++)w[U+L]|=H[L];break;case 2:for(L=0;L<N;L++)w[U+L]^=H[L];break;default:throw new Jbig2Error(`operator ${C} is not supported`)}}}y++;const Y=e?Q.tableDeltaS.decode(p):decodeInteger(D,"IADS",b);if(null===Y)break;a+=x+Y+h}}return m}function readSegmentHeader(e,t){const i={};i.number=readUint32(e,t);const a=e[t+4],s=63&a;if(!Wt[s])throw new Jbig2Error("invalid segment type: "+s);i.type=s;i.typeName=Wt[s];i.deferredNonRetain=!!(128&a);const r=!!(64&a),n=e[t+5];let o=n>>5&7;const g=[31&n];let c=t+6;if(7===n){o=536870911&readUint32(e,c-1);c+=3;let t=o+7>>3;g[0]=e[c++];for(;--t>0;)g.push(e[c++])}else if(5===n||6===n)throw new Jbig2Error("invalid referred-to flags");i.retainBits=g;let h=4;i.number<=256?h=1:i.number<=65536&&(h=2);const l=[];let C,Q;for(C=0;C<o;C++){let t;t=1===h?e[c]:2===h?readUint16(e,c):readUint32(e,c);l.push(t);c+=h}i.referredTo=l;if(r){i.pageAssociation=readUint32(e,c);c+=4}else i.pageAssociation=e[c++];i.length=readUint32(e,c);c+=4;if(4294967295===i.length){if(38!==s)throw new Jbig2Error("invalid unknown segment length");{const t=readRegionSegmentInformation(e,c),a=!!(1&e[c+zt]),s=6,r=new Uint8Array(s);if(!a){r[0]=255;r[1]=172}r[2]=t.height>>>24&255;r[3]=t.height>>16&255;r[4]=t.height>>8&255;r[5]=255&t.height;for(C=c,Q=e.length;C<Q;C++){let t=0;for(;t<s&&r[t]===e[C+t];)t++;if(t===s){i.length=C+s;break}}if(4294967295===i.length)throw new Jbig2Error("segment end was not found")}}i.headerEnd=c;return i}function readSegments(e,t,i,a){const s=[];let r=i;for(;r<a;){const i=readSegmentHeader(t,r);r=i.headerEnd;const a={header:i,data:t};if(!e.randomAccess){a.start=r;r+=i.length;a.end=r}s.push(a);if(51===i.type)break}if(e.randomAccess)for(let e=0,t=s.length;e<t;e++){s[e].start=r;r+=s[e].header.length;s[e].end=r}return s}function readRegionSegmentInformation(e,t){return{width:readUint32(e,t),height:readUint32(e,t+4),x:readUint32(e,t+8),y:readUint32(e,t+12),combinationOperator:7&e[t+16]}}const zt=17;function processSegment(e,t){const i=e.header,a=e.data,s=e.end;let r,n,o,g,c=e.start;switch(i.type){case 0:const e={},t=readUint16(a,c);e.huffman=!!(1&t);e.refinement=!!(2&t);e.huffmanDHSelector=t>>2&3;e.huffmanDWSelector=t>>4&3;e.bitmapSizeSelector=t>>6&1;e.aggregationInstancesSelector=t>>7&1;e.bitmapCodingContextUsed=!!(256&t);e.bitmapCodingContextRetained=!!(512&t);e.template=t>>10&3;e.refinementTemplate=t>>12&1;c+=2;if(!e.huffman){g=0===e.template?4:1;n=[];for(o=0;o<g;o++){n.push({x:readInt8(a,c),y:readInt8(a,c+1)});c+=2}e.at=n}if(e.refinement&&!e.refinementTemplate){n=[];for(o=0;o<2;o++){n.push({x:readInt8(a,c),y:readInt8(a,c+1)});c+=2}e.refinementAt=n}e.numberOfExportedSymbols=readUint32(a,c);c+=4;e.numberOfNewSymbols=readUint32(a,c);c+=4;r=[e,i.number,i.referredTo,a,c,s];break;case 6:case 7:const h={};h.info=readRegionSegmentInformation(a,c);c+=zt;const l=readUint16(a,c);c+=2;h.huffman=!!(1&l);h.refinement=!!(2&l);h.logStripSize=l>>2&3;h.stripSize=1<<h.logStripSize;h.referenceCorner=l>>4&3;h.transposed=!!(64&l);h.combinationOperator=l>>7&3;h.defaultPixelValue=l>>9&1;h.dsOffset=l<<17>>27;h.refinementTemplate=l>>15&1;if(h.huffman){const e=readUint16(a,c);c+=2;h.huffmanFS=3&e;h.huffmanDS=e>>2&3;h.huffmanDT=e>>4&3;h.huffmanRefinementDW=e>>6&3;h.huffmanRefinementDH=e>>8&3;h.huffmanRefinementDX=e>>10&3;h.huffmanRefinementDY=e>>12&3;h.huffmanRefinementSizeSelector=!!(16384&e)}if(h.refinement&&!h.refinementTemplate){n=[];for(o=0;o<2;o++){n.push({x:readInt8(a,c),y:readInt8(a,c+1)});c+=2}h.refinementAt=n}h.numberOfSymbolInstances=readUint32(a,c);c+=4;r=[h,i.referredTo,a,c,s];break;case 16:const C={},Q=a[c++];C.mmr=!!(1&Q);C.template=Q>>1&3;C.patternWidth=a[c++];C.patternHeight=a[c++];C.maxPatternIndex=readUint32(a,c);c+=4;r=[C,i.number,a,c,s];break;case 22:case 23:const E={};E.info=readRegionSegmentInformation(a,c);c+=zt;const u=a[c++];E.mmr=!!(1&u);E.template=u>>1&3;E.enableSkip=!!(8&u);E.combinationOperator=u>>4&7;E.defaultPixelValue=u>>7&1;E.gridWidth=readUint32(a,c);c+=4;E.gridHeight=readUint32(a,c);c+=4;E.gridOffsetX=4294967295&readUint32(a,c);c+=4;E.gridOffsetY=4294967295&readUint32(a,c);c+=4;E.gridVectorX=readUint16(a,c);c+=2;E.gridVectorY=readUint16(a,c);c+=2;r=[E,i.referredTo,a,c,s];break;case 38:case 39:const d={};d.info=readRegionSegmentInformation(a,c);c+=zt;const f=a[c++];d.mmr=!!(1&f);d.template=f>>1&3;d.prediction=!!(8&f);if(!d.mmr){g=0===d.template?4:1;n=[];for(o=0;o<g;o++){n.push({x:readInt8(a,c),y:readInt8(a,c+1)});c+=2}d.at=n}r=[d,a,c,s];break;case 48:const p={width:readUint32(a,c),height:readUint32(a,c+4),resolutionX:readUint32(a,c+8),resolutionY:readUint32(a,c+12)};4294967295===p.height&&delete p.height;const m=a[c+16];readUint16(a,c+17);p.lossless=!!(1&m);p.refinement=!!(2&m);p.defaultPixelValue=m>>2&1;p.combinationOperator=m>>3&3;p.requiresBuffer=!!(32&m);p.combinationOperatorOverride=!!(64&m);r=[p];break;case 49:case 50:case 51:case 62:break;case 53:r=[i.number,a,c,s];break;default:throw new Jbig2Error(`segment type ${i.typeName}(${i.type}) is not implemented`)}const h="on"+i.typeName;h in t&&t[h].apply(t,r)}function processSegments(e,t){for(let i=0,a=e.length;i<a;i++)processSegment(e[i],t)}class SimpleSegmentVisitor{onPageInformation(e){this.currentPageInfo=e;const t=e.width+7>>3,i=new Uint8ClampedArray(t*e.height);e.defaultPixelValue&&i.fill(255);this.buffer=i}drawBitmap(e,t){const i=this.currentPageInfo,a=e.width,s=e.height,r=i.width+7>>3,n=i.combinationOperatorOverride?e.combinationOperator:i.combinationOperator,o=this.buffer,g=128>>(7&e.x);let c,h,l,C,Q=e.y*r+(e.x>>3);switch(n){case 0:for(c=0;c<s;c++){l=g;C=Q;for(h=0;h<a;h++){t[c][h]&&(o[C]|=l);l>>=1;if(!l){l=128;C++}}Q+=r}break;case 2:for(c=0;c<s;c++){l=g;C=Q;for(h=0;h<a;h++){t[c][h]&&(o[C]^=l);l>>=1;if(!l){l=128;C++}}Q+=r}break;default:throw new Jbig2Error(`operator ${n} is not supported`)}}onImmediateGenericRegion(e,t,i,a){const s=e.info,r=new DecodingContext(t,i,a),n=decodeBitmap(e.mmr,s.width,s.height,e.template,e.prediction,null,e.at,r);this.drawBitmap(s,n)}onImmediateLosslessGenericRegion(){this.onImmediateGenericRegion(...arguments)}onSymbolDictionary(e,t,i,a,s,r){let n,o;if(e.huffman){n=function getSymbolDictionaryHuffmanTables(e,t,i){let a,s,r,n,o=0;switch(e.huffmanDHSelector){case 0:case 1:a=getStandardTable(e.huffmanDHSelector+4);break;case 3:a=getCustomHuffmanTable(o,t,i);o++;break;default:throw new Jbig2Error("invalid Huffman DH selector")}switch(e.huffmanDWSelector){case 0:case 1:s=getStandardTable(e.huffmanDWSelector+2);break;case 3:s=getCustomHuffmanTable(o,t,i);o++;break;default:throw new Jbig2Error("invalid Huffman DW selector")}if(e.bitmapSizeSelector){r=getCustomHuffmanTable(o,t,i);o++}else r=getStandardTable(1);n=e.aggregationInstancesSelector?getCustomHuffmanTable(o,t,i):getStandardTable(1);return{tableDeltaHeight:a,tableDeltaWidth:s,tableBitmapSize:r,tableAggregateInstances:n}}(e,i,this.customTables);o=new Reader(a,s,r)}let g=this.symbols;g||(this.symbols=g={});const c=[];for(const e of i){const t=g[e];t&&c.push(...t)}const h=new DecodingContext(a,s,r);g[t]=function decodeSymbolDictionary(e,t,i,a,s,r,n,o,g,c,h,l){if(e&&t)throw new Jbig2Error("symbol refinement with Huffman is not supported");const C=[];let Q=0,E=log2(i.length+a);const u=h.decoder,d=h.contextCache;let f,p;if(e){f=getStandardTable(1);p=[];E=Math.max(E,1)}for(;C.length<a;){Q+=e?r.tableDeltaHeight.decode(l):decodeInteger(d,"IADH",u);let a=0,s=0;const f=e?p.length:0;for(;;){const f=e?r.tableDeltaWidth.decode(l):decodeInteger(d,"IADW",u);if(null===f)break;a+=f;s+=a;let m;if(t){const s=decodeInteger(d,"IAAI",u);if(s>1)m=decodeTextRegion(e,t,a,Q,0,s,1,i.concat(C),E,0,0,1,0,r,g,c,h,0,l);else{const e=decodeIAID(d,u,E),t=decodeInteger(d,"IARDX",u),s=decodeInteger(d,"IARDY",u);m=decodeRefinement(a,Q,g,e<i.length?i[e]:C[e-i.length],t,s,!1,c,h)}C.push(m)}else if(e)p.push(a);else{m=decodeBitmap(!1,a,Q,n,!1,null,o,h);C.push(m)}}if(e&&!t){const e=r.tableBitmapSize.decode(l);l.byteAlign();let t;if(0===e)t=readUncompressedBitmap(l,s,Q);else{const i=l.end,a=l.position+e;l.end=a;t=decodeMMRBitmap(l,s,Q,!1);l.end=i;l.position=a}const i=p.length;if(f===i-1)C.push(t);else{let e,a,s,r,n,o=0;for(e=f;e<i;e++){r=p[e];s=o+r;n=[];for(a=0;a<Q;a++)n.push(t[a].subarray(o,s));C.push(n);o=s}}}}const m=[],y=[];let w,b,D=!1;const F=i.length+a;for(;y.length<F;){let t=e?f.decode(l):decodeInteger(d,"IAEX",u);for(;t--;)y.push(D);D=!D}for(w=0,b=i.length;w<b;w++)y[w]&&m.push(i[w]);for(let e=0;e<a;w++,e++)y[w]&&m.push(C[e]);return m}(e.huffman,e.refinement,c,e.numberOfNewSymbols,e.numberOfExportedSymbols,n,e.template,e.at,e.refinementTemplate,e.refinementAt,h,o)}onImmediateTextRegion(e,t,i,a,s){const r=e.info;let n,o;const g=this.symbols,c=[];for(const e of t){const t=g[e];t&&c.push(...t)}const h=log2(c.length);if(e.huffman){o=new Reader(i,a,s);n=function getTextRegionHuffmanTables(e,t,i,a,s){const r=[];for(let e=0;e<=34;e++){const t=s.readBits(4);r.push(new HuffmanLine([e,t,0,0]))}const n=new HuffmanTable(r,!1);r.length=0;for(let e=0;e<a;){const t=n.decode(s);if(t>=32){let i,a,n;switch(t){case 32:if(0===e)throw new Jbig2Error("no previous value in symbol ID table");a=s.readBits(2)+3;i=r[e-1].prefixLength;break;case 33:a=s.readBits(3)+3;i=0;break;case 34:a=s.readBits(7)+11;i=0;break;default:throw new Jbig2Error("invalid code length in symbol ID table")}for(n=0;n<a;n++){r.push(new HuffmanLine([e,i,0,0]));e++}}else{r.push(new HuffmanLine([e,t,0,0]));e++}}s.byteAlign();const o=new HuffmanTable(r,!1);let g,c,h,l=0;switch(e.huffmanFS){case 0:case 1:g=getStandardTable(e.huffmanFS+6);break;case 3:g=getCustomHuffmanTable(l,t,i);l++;break;default:throw new Jbig2Error("invalid Huffman FS selector")}switch(e.huffmanDS){case 0:case 1:case 2:c=getStandardTable(e.huffmanDS+8);break;case 3:c=getCustomHuffmanTable(l,t,i);l++;break;default:throw new Jbig2Error("invalid Huffman DS selector")}switch(e.huffmanDT){case 0:case 1:case 2:h=getStandardTable(e.huffmanDT+11);break;case 3:h=getCustomHuffmanTable(l,t,i);l++;break;default:throw new Jbig2Error("invalid Huffman DT selector")}if(e.refinement)throw new Jbig2Error("refinement with Huffman is not supported");return{symbolIDTable:o,tableFirstS:g,tableDeltaS:c,tableDeltaT:h}}(e,t,this.customTables,c.length,o)}const l=new DecodingContext(i,a,s),C=decodeTextRegion(e.huffman,e.refinement,r.width,r.height,e.defaultPixelValue,e.numberOfSymbolInstances,e.stripSize,c,h,e.transposed,e.dsOffset,e.referenceCorner,e.combinationOperator,n,e.refinementTemplate,e.refinementAt,l,e.logStripSize,o);this.drawBitmap(r,C)}onImmediateLosslessTextRegion(){this.onImmediateTextRegion(...arguments)}onPatternDictionary(e,t,i,a,s){let r=this.patterns;r||(this.patterns=r={});const n=new DecodingContext(i,a,s);r[t]=function decodePatternDictionary(e,t,i,a,s,r){const n=[];if(!e){n.push({x:-t,y:0});0===s&&n.push({x:-3,y:-1},{x:2,y:-2},{x:-2,y:-2})}const o=decodeBitmap(e,(a+1)*t,i,s,!1,null,n,r),g=[];for(let e=0;e<=a;e++){const a=[],s=t*e,r=s+t;for(let e=0;e<i;e++)a.push(o[e].subarray(s,r));g.push(a)}return g}(e.mmr,e.patternWidth,e.patternHeight,e.maxPatternIndex,e.template,n)}onImmediateHalftoneRegion(e,t,i,a,s){const r=this.patterns[t[0]],n=e.info,o=new DecodingContext(i,a,s),g=function decodeHalftoneRegion(e,t,i,a,s,r,n,o,g,c,h,l,C,Q,E){if(n)throw new Jbig2Error("skip is not supported");if(0!==o)throw new Jbig2Error(`operator "${o}" is not supported in halftone region`);const u=[];let d,f,p;for(d=0;d<s;d++){p=new Uint8Array(a);if(r)for(f=0;f<a;f++)p[f]=r;u.push(p)}const m=t.length,y=t[0],w=y[0].length,b=y.length,D=log2(m),F=[];if(!e){F.push({x:i<=1?3:2,y:-1});0===i&&F.push({x:-3,y:-1},{x:2,y:-2},{x:-2,y:-2})}const S=[];let k,R,N,G,x,M,U,L,J,H,Y;e&&(k=new Reader(E.data,E.start,E.end));for(d=D-1;d>=0;d--){R=e?decodeMMRBitmap(k,g,c,!0):decodeBitmap(!1,g,c,i,!1,null,F,E);S[d]=R}for(N=0;N<c;N++)for(G=0;G<g;G++){x=0;M=0;for(f=D-1;f>=0;f--){x^=S[f][N][G];M|=x<<f}U=t[M];L=h+N*Q+G*C>>8;J=l+N*C-G*Q>>8;if(L>=0&&L+w<=a&&J>=0&&J+b<=s)for(d=0;d<b;d++){Y=u[J+d];H=U[d];for(f=0;f<w;f++)Y[L+f]|=H[f]}else{let e,t;for(d=0;d<b;d++){t=J+d;if(!(t<0||t>=s)){Y=u[t];H=U[d];for(f=0;f<w;f++){e=L+f;e>=0&&e<a&&(Y[e]|=H[f])}}}}}return u}(e.mmr,r,e.template,n.width,n.height,e.defaultPixelValue,e.enableSkip,e.combinationOperator,e.gridWidth,e.gridHeight,e.gridOffsetX,e.gridOffsetY,e.gridVectorX,e.gridVectorY,o);this.drawBitmap(n,g)}onImmediateLosslessHalftoneRegion(){this.onImmediateHalftoneRegion(...arguments)}onTables(e,t,i,a){let s=this.customTables;s||(this.customTables=s={});s[e]=function decodeTablesSegment(e,t,i){const a=e[t],s=4294967295&readUint32(e,t+1),r=4294967295&readUint32(e,t+5),n=new Reader(e,t+9,i),o=1+(a>>1&7),g=1+(a>>4&7),c=[];let h,l,C=s;do{h=n.readBits(o);l=n.readBits(g);c.push(new HuffmanLine([C,h,l,0]));C+=1<<l}while(C<r);h=n.readBits(o);c.push(new HuffmanLine([s-1,h,32,0,"lower"]));h=n.readBits(o);c.push(new HuffmanLine([r,h,32,0]));if(1&a){h=n.readBits(o);c.push(new HuffmanLine([h,0]))}return new HuffmanTable(c,!1)}(t,i,a)}}class HuffmanLine{constructor(e){if(2===e.length){this.isOOB=!0;this.rangeLow=0;this.prefixLength=e[0];this.rangeLength=0;this.prefixCode=e[1];this.isLowerRange=!1}else{this.isOOB=!1;this.rangeLow=e[0];this.prefixLength=e[1];this.rangeLength=e[2];this.prefixCode=e[3];this.isLowerRange="lower"===e[4]}}}class HuffmanTreeNode{constructor(e){this.children=[];if(e){this.isLeaf=!0;this.rangeLength=e.rangeLength;this.rangeLow=e.rangeLow;this.isLowerRange=e.isLowerRange;this.isOOB=e.isOOB}else this.isLeaf=!1}buildTree(e,t){const i=e.prefixCode>>t&1;if(t<=0)this.children[i]=new HuffmanTreeNode(e);else{let a=this.children[i];a||(this.children[i]=a=new HuffmanTreeNode(null));a.buildTree(e,t-1)}}decodeNode(e){if(this.isLeaf){if(this.isOOB)return null;const t=e.readBits(this.rangeLength);return this.rangeLow+(this.isLowerRange?-t:t)}const t=this.children[e.readBit()];if(!t)throw new Jbig2Error("invalid Huffman data");return t.decodeNode(e)}}class HuffmanTable{constructor(e,t){t||this.assignPrefixCodes(e);this.rootNode=new HuffmanTreeNode(null);for(let t=0,i=e.length;t<i;t++){const i=e[t];i.prefixLength>0&&this.rootNode.buildTree(i,i.prefixLength-1)}}decode(e){return this.rootNode.decodeNode(e)}assignPrefixCodes(e){const t=e.length;let i=0;for(let a=0;a<t;a++)i=Math.max(i,e[a].prefixLength);const a=new Uint32Array(i+1);for(let i=0;i<t;i++)a[e[i].prefixLength]++;let s,r,n,o=1,g=0;a[0]=0;for(;o<=i;){g=g+a[o-1]<<1;s=g;r=0;for(;r<t;){n=e[r];if(n.prefixLength===o){n.prefixCode=s;s++}r++}o++}}}const _t={};function getStandardTable(e){let t,i=_t[e];if(i)return i;switch(e){case 1:t=[[0,1,4,0],[16,2,8,2],[272,3,16,6],[65808,3,32,7]];break;case 2:t=[[0,1,0,0],[1,2,0,2],[2,3,0,6],[3,4,3,14],[11,5,6,30],[75,6,32,62],[6,63]];break;case 3:t=[[-256,8,8,254],[0,1,0,0],[1,2,0,2],[2,3,0,6],[3,4,3,14],[11,5,6,30],[-257,8,32,255,"lower"],[75,7,32,126],[6,62]];break;case 4:t=[[1,1,0,0],[2,2,0,2],[3,3,0,6],[4,4,3,14],[12,5,6,30],[76,5,32,31]];break;case 5:t=[[-255,7,8,126],[1,1,0,0],[2,2,0,2],[3,3,0,6],[4,4,3,14],[12,5,6,30],[-256,7,32,127,"lower"],[76,6,32,62]];break;case 6:t=[[-2048,5,10,28],[-1024,4,9,8],[-512,4,8,9],[-256,4,7,10],[-128,5,6,29],[-64,5,5,30],[-32,4,5,11],[0,2,7,0],[128,3,7,2],[256,3,8,3],[512,4,9,12],[1024,4,10,13],[-2049,6,32,62,"lower"],[2048,6,32,63]];break;case 7:t=[[-1024,4,9,8],[-512,3,8,0],[-256,4,7,9],[-128,5,6,26],[-64,5,5,27],[-32,4,5,10],[0,4,5,11],[32,5,5,28],[64,5,6,29],[128,4,7,12],[256,3,8,1],[512,3,9,2],[1024,3,10,3],[-1025,5,32,30,"lower"],[2048,5,32,31]];break;case 8:t=[[-15,8,3,252],[-7,9,1,508],[-5,8,1,253],[-3,9,0,509],[-2,7,0,124],[-1,4,0,10],[0,2,1,0],[2,5,0,26],[3,6,0,58],[4,3,4,4],[20,6,1,59],[22,4,4,11],[38,4,5,12],[70,5,6,27],[134,5,7,28],[262,6,7,60],[390,7,8,125],[646,6,10,61],[-16,9,32,510,"lower"],[1670,9,32,511],[2,1]];break;case 9:t=[[-31,8,4,252],[-15,9,2,508],[-11,8,2,253],[-7,9,1,509],[-5,7,1,124],[-3,4,1,10],[-1,3,1,2],[1,3,1,3],[3,5,1,26],[5,6,1,58],[7,3,5,4],[39,6,2,59],[43,4,5,11],[75,4,6,12],[139,5,7,27],[267,5,8,28],[523,6,8,60],[779,7,9,125],[1291,6,11,61],[-32,9,32,510,"lower"],[3339,9,32,511],[2,0]];break;case 10:t=[[-21,7,4,122],[-5,8,0,252],[-4,7,0,123],[-3,5,0,24],[-2,2,2,0],[2,5,0,25],[3,6,0,54],[4,7,0,124],[5,8,0,253],[6,2,6,1],[70,5,5,26],[102,6,5,55],[134,6,6,56],[198,6,7,57],[326,6,8,58],[582,6,9,59],[1094,6,10,60],[2118,7,11,125],[-22,8,32,254,"lower"],[4166,8,32,255],[2,2]];break;case 11:t=[[1,1,0,0],[2,2,1,2],[4,4,0,12],[5,4,1,13],[7,5,1,28],[9,5,2,29],[13,6,2,60],[17,7,2,122],[21,7,3,123],[29,7,4,124],[45,7,5,125],[77,7,6,126],[141,7,32,127]];break;case 12:t=[[1,1,0,0],[2,2,0,2],[3,3,1,6],[5,5,0,28],[6,5,1,29],[8,6,1,60],[10,7,0,122],[11,7,1,123],[13,7,2,124],[17,7,3,125],[25,7,4,126],[41,8,5,254],[73,8,32,255]];break;case 13:t=[[1,1,0,0],[2,3,0,4],[3,4,0,12],[4,5,0,28],[5,4,1,13],[7,3,3,5],[15,6,1,58],[17,6,2,59],[21,6,3,60],[29,6,4,61],[45,6,5,62],[77,7,6,126],[141,7,32,127]];break;case 14:t=[[-2,3,0,4],[-1,3,0,5],[0,1,0,0],[1,3,0,6],[2,3,0,7]];break;case 15:t=[[-24,7,4,124],[-8,6,2,60],[-4,5,1,28],[-2,4,0,12],[-1,3,0,4],[0,1,0,0],[1,3,0,5],[2,4,0,13],[3,5,1,29],[5,6,2,61],[9,7,4,125],[-25,7,32,126,"lower"],[25,7,32,127]];break;default:throw new Jbig2Error(`standard table B.${e} does not exist`)}for(let e=0,i=t.length;e<i;e++)t[e]=new HuffmanLine(t[e]);i=new HuffmanTable(t,!0);_t[e]=i;return i}class Reader{constructor(e,t,i){this.data=e;this.start=t;this.end=i;this.position=t;this.shift=-1;this.currentByte=0}readBit(){if(this.shift<0){if(this.position>=this.end)throw new Jbig2Error("end of data while reading bit");this.currentByte=this.data[this.position++];this.shift=7}const e=this.currentByte>>this.shift&1;this.shift--;return e}readBits(e){let t,i=0;for(t=e-1;t>=0;t--)i|=this.readBit()<<t;return i}byteAlign(){this.shift=-1}next(){return this.position>=this.end?-1:this.data[this.position++]}}function getCustomHuffmanTable(e,t,i){let a=0;for(let s=0,r=t.length;s<r;s++){const r=i[t[s]];if(r){if(e===a)return r;a++}}throw new Jbig2Error("can't find custom Huffman table")}function readUncompressedBitmap(e,t,i){const a=[];for(let s=0;s<i;s++){const i=new Uint8Array(t);a.push(i);for(let a=0;a<t;a++)i[a]=e.readBit();e.byteAlign()}return a}function decodeMMRBitmap(e,t,i,a){const s=new CCITTFaxDecoder(e,{K:-1,Columns:t,Rows:i,BlackIs1:!0,EndOfBlock:a}),r=[];let n,o=!1;for(let e=0;e<i;e++){const e=new Uint8Array(t);r.push(e);let i=-1;for(let a=0;a<t;a++){if(i<0){n=s.readNextChar();if(-1===n){n=0;o=!0}i=7}e[a]=n>>i&1;i--}}if(a&&!o){const e=5;for(let t=0;t<e&&-1!==s.readNextChar();t++);}return r}class Jbig2Image{parseChunks(e){return function parseJbig2Chunks(e){const t=new SimpleSegmentVisitor;for(let i=0,a=e.length;i<a;i++){const a=e[i];processSegments(readSegments({},a.data,a.start,a.end),t)}return t.buffer}(e)}parse(e){throw new Error("Not implemented: Jbig2Image.parse")}}class Jbig2Stream extends DecodeStream{constructor(e,t,i){super(t);this.stream=e;this.dict=e.dict;this.maybeLength=t;this.params=i}get bytes(){return shadow(this,"bytes",this.stream.getBytes(this.maybeLength))}ensureBuffer(e){}readBlock(){if(this.eof)return;const e=new Jbig2Image,t=[];if(this.params instanceof Dict){const e=this.params.get("JBIG2Globals");if(e instanceof BaseStream){const i=e.getBytes();t.push({data:i,start:0,end:i.length})}}t.push({data:this.bytes,start:0,end:this.bytes.length});const i=e.parseChunks(t),a=i.length;for(let e=0;e<a;e++)i[e]^=255;this.buffer=i;this.bufferLength=a;this.eof=!0}}function convertToRGBA(e){switch(e.kind){case b:return convertBlackAndWhiteToRGBA(e);case D:return function convertRGBToRGBA({src:e,srcPos:t=0,dest:i,destPos:a=0,width:s,height:r}){let n=0;const o=e.length>>2,g=new Uint32Array(e.buffer,t,o);if(FeatureTest.isLittleEndian){for(;n<o-2;n+=3,a+=4){const e=g[n],t=g[n+1],s=g[n+2];i[a]=4278190080|e;i[a+1]=e>>>24|t<<8|4278190080;i[a+2]=t>>>16|s<<16|4278190080;i[a+3]=s>>>8|4278190080}for(let t=4*n,s=e.length;t<s;t+=3)i[a++]=e[t]|e[t+1]<<8|e[t+2]<<16|4278190080}else{for(;n<o-2;n+=3,a+=4){const e=g[n],t=g[n+1],s=g[n+2];i[a]=255|e;i[a+1]=e<<24|t>>>8|255;i[a+2]=t<<16|s>>>16|255;i[a+3]=s<<8|255}for(let t=4*n,s=e.length;t<s;t+=3)i[a++]=e[t]<<24|e[t+1]<<16|e[t+2]<<8|255}return{srcPos:t,destPos:a}}(e)}return null}function convertBlackAndWhiteToRGBA({src:e,srcPos:t=0,dest:i,width:a,height:s,nonBlackColor:r=4294967295,inverseDecode:n=!1}){const o=FeatureTest.isLittleEndian?4278190080:255,[g,c]=n?[r,o]:[o,r],h=a>>3,l=7&a,C=e.length;i=new Uint32Array(i.buffer);let Q=0;for(let a=0;a<s;a++){for(const a=t+h;t<a;t++){const a=t<C?e[t]:255;i[Q++]=128&a?c:g;i[Q++]=64&a?c:g;i[Q++]=32&a?c:g;i[Q++]=16&a?c:g;i[Q++]=8&a?c:g;i[Q++]=4&a?c:g;i[Q++]=2&a?c:g;i[Q++]=1&a?c:g}if(0===l)continue;const a=t<C?e[t++]:255;for(let e=0;e<l;e++)i[Q++]=a&1<<7-e?c:g}return{srcPos:t,destPos:Q}}class JpegError extends rt{constructor(e){super(e,"JpegError")}}class DNLMarkerError extends rt{constructor(e,t){super(e,"DNLMarkerError");this.scanLines=t}}class EOIMarkerError extends rt{constructor(e){super(e,"EOIMarkerError")}}const $t=new Uint8Array([0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5,12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28,35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63]),Ai=4017,ei=799,ti=3406,ii=2276,ai=1567,si=3784,ri=5793,ni=2896;function buildHuffmanTable(e,t){let i,a,s=0,r=16;for(;r>0&&!e[r-1];)r--;const n=[{children:[],index:0}];let o,g=n[0];for(i=0;i<r;i++){for(a=0;a<e[i];a++){g=n.pop();g.children[g.index]=t[s];for(;g.index>0;)g=n.pop();g.index++;n.push(g);for(;n.length<=i;){n.push(o={children:[],index:0});g.children[g.index]=o.children;g=o}s++}if(i+1<r){n.push(o={children:[],index:0});g.children[g.index]=o.children;g=o}}return n[0].children}function getBlockBufferOffset(e,t,i){return 64*((e.blocksPerLine+1)*t+i)}function decodeScan(e,t,i,a,s,r,n,o,g,c=!1){const h=i.mcusPerLine,l=i.progressive,C=t;let Q=0,E=0;function readBit(){if(E>0){E--;return Q>>E&1}Q=e[t++];if(255===Q){const a=e[t++];if(a){if(220===a&&c){const a=readUint16(e,t+=2);t+=2;if(a>0&&a!==i.scanLines)throw new DNLMarkerError("Found DNL marker (0xFFDC) while parsing scan data",a)}else if(217===a){if(c){const e=p*(8===i.precision?8:0);if(e>0&&Math.round(i.scanLines/e)>=5)throw new DNLMarkerError("Found EOI marker (0xFFD9) while parsing scan data, possibly caused by incorrect `scanLines` parameter",e)}throw new EOIMarkerError("Found EOI marker (0xFFD9) while parsing scan data")}throw new JpegError(`unexpected marker ${(Q<<8|a).toString(16)}`)}}E=7;return Q>>>7}function decodeHuffman(e){let t=e;for(;;){t=t[readBit()];switch(typeof t){case"number":return t;case"object":continue}throw new JpegError("invalid huffman sequence")}}function receive(e){let t=0;for(;e>0;){t=t<<1|readBit();e--}return t}function receiveAndExtend(e){if(1===e)return 1===readBit()?1:-1;const t=receive(e);return t>=1<<e-1?t:t+(-1<<e)+1}let u=0;let d,f=0;let p=0;function decodeMcu(e,t,i,a,s){const r=i%h;p=(i/h|0)*e.v+a;const n=r*e.h+s;t(e,getBlockBufferOffset(e,p,n))}function decodeBlock(e,t,i){p=i/e.blocksPerLine|0;const a=i%e.blocksPerLine;t(e,getBlockBufferOffset(e,p,a))}const m=a.length;let y,w,b,D,F,S;S=l?0===r?0===o?function decodeDCFirst(e,t){const i=decodeHuffman(e.huffmanTableDC),a=0===i?0:receiveAndExtend(i)<<g;e.blockData[t]=e.pred+=a}:function decodeDCSuccessive(e,t){e.blockData[t]|=readBit()<<g}:0===o?function decodeACFirst(e,t){if(u>0){u--;return}let i=r;const a=n;for(;i<=a;){const a=decodeHuffman(e.huffmanTableAC),s=15&a,r=a>>4;if(0===s){if(r<15){u=receive(r)+(1<<r)-1;break}i+=16;continue}i+=r;const n=$t[i];e.blockData[t+n]=receiveAndExtend(s)*(1<<g);i++}}:function decodeACSuccessive(e,t){let i=r;const a=n;let s,o,c=0;for(;i<=a;){const a=t+$t[i],r=e.blockData[a]<0?-1:1;switch(f){case 0:o=decodeHuffman(e.huffmanTableAC);s=15&o;c=o>>4;if(0===s)if(c<15){u=receive(c)+(1<<c);f=4}else{c=16;f=1}else{if(1!==s)throw new JpegError("invalid ACn encoding");d=receiveAndExtend(s);f=c?2:3}continue;case 1:case 2:if(e.blockData[a])e.blockData[a]+=r*(readBit()<<g);else{c--;0===c&&(f=2===f?3:0)}break;case 3:if(e.blockData[a])e.blockData[a]+=r*(readBit()<<g);else{e.blockData[a]=d<<g;f=0}break;case 4:e.blockData[a]&&(e.blockData[a]+=r*(readBit()<<g))}i++}if(4===f){u--;0===u&&(f=0)}}:function decodeBaseline(e,t){const i=decodeHuffman(e.huffmanTableDC),a=0===i?0:receiveAndExtend(i);e.blockData[t]=e.pred+=a;let s=1;for(;s<64;){const i=decodeHuffman(e.huffmanTableAC),a=15&i,r=i>>4;if(0===a){if(r<15)break;s+=16;continue}s+=r;const n=$t[s];e.blockData[t+n]=receiveAndExtend(a);s++}};let k,R=0;const N=1===m?a[0].blocksPerLine*a[0].blocksPerColumn:h*i.mcusPerColumn;let G,x;for(;R<=N;){const i=s?Math.min(N-R,s):N;if(i>0){for(w=0;w<m;w++)a[w].pred=0;u=0;if(1===m){y=a[0];for(F=0;F<i;F++){decodeBlock(y,S,R);R++}}else for(F=0;F<i;F++){for(w=0;w<m;w++){y=a[w];G=y.h;x=y.v;for(b=0;b<x;b++)for(D=0;D<G;D++)decodeMcu(y,S,R,b,D)}R++}}E=0;k=findNextFileMarker(e,t);if(!k)break;if(k.invalid){warn(`decodeScan - ${i>0?"unexpected":"excessive"} MCU data, current marker is: ${k.invalid}`);t=k.offset}if(!(k.marker>=65488&&k.marker<=65495))break;t+=2}return t-C}function quantizeAndInverse(e,t,i){const a=e.quantizationTable,s=e.blockData;let r,n,o,g,c,h,l,C,Q,E,u,d,f,p,m,y,w;if(!a)throw new JpegError("missing required Quantization Table.");for(let e=0;e<64;e+=8){Q=s[t+e];E=s[t+e+1];u=s[t+e+2];d=s[t+e+3];f=s[t+e+4];p=s[t+e+5];m=s[t+e+6];y=s[t+e+7];Q*=a[e];if(0!=(E|u|d|f|p|m|y)){E*=a[e+1];u*=a[e+2];d*=a[e+3];f*=a[e+4];p*=a[e+5];m*=a[e+6];y*=a[e+7];r=ri*Q+128>>8;n=ri*f+128>>8;o=u;g=m;c=ni*(E-y)+128>>8;C=ni*(E+y)+128>>8;h=d<<4;l=p<<4;r=r+n+1>>1;n=r-n;w=o*si+g*ai+128>>8;o=o*ai-g*si+128>>8;g=w;c=c+l+1>>1;l=c-l;C=C+h+1>>1;h=C-h;r=r+g+1>>1;g=r-g;n=n+o+1>>1;o=n-o;w=c*ii+C*ti+2048>>12;c=c*ti-C*ii+2048>>12;C=w;w=h*ei+l*Ai+2048>>12;h=h*Ai-l*ei+2048>>12;l=w;i[e]=r+C;i[e+7]=r-C;i[e+1]=n+l;i[e+6]=n-l;i[e+2]=o+h;i[e+5]=o-h;i[e+3]=g+c;i[e+4]=g-c}else{w=ri*Q+512>>10;i[e]=w;i[e+1]=w;i[e+2]=w;i[e+3]=w;i[e+4]=w;i[e+5]=w;i[e+6]=w;i[e+7]=w}}for(let e=0;e<8;++e){Q=i[e];E=i[e+8];u=i[e+16];d=i[e+24];f=i[e+32];p=i[e+40];m=i[e+48];y=i[e+56];if(0!=(E|u|d|f|p|m|y)){r=ri*Q+2048>>12;n=ri*f+2048>>12;o=u;g=m;c=ni*(E-y)+2048>>12;C=ni*(E+y)+2048>>12;h=d;l=p;r=4112+(r+n+1>>1);n=r-n;w=o*si+g*ai+2048>>12;o=o*ai-g*si+2048>>12;g=w;c=c+l+1>>1;l=c-l;C=C+h+1>>1;h=C-h;r=r+g+1>>1;g=r-g;n=n+o+1>>1;o=n-o;w=c*ii+C*ti+2048>>12;c=c*ti-C*ii+2048>>12;C=w;w=h*ei+l*Ai+2048>>12;h=h*Ai-l*ei+2048>>12;l=w;Q=r+C;y=r-C;E=n+l;m=n-l;u=o+h;p=o-h;d=g+c;f=g-c;Q<16?Q=0:Q>=4080?Q=255:Q>>=4;E<16?E=0:E>=4080?E=255:E>>=4;u<16?u=0:u>=4080?u=255:u>>=4;d<16?d=0:d>=4080?d=255:d>>=4;f<16?f=0:f>=4080?f=255:f>>=4;p<16?p=0:p>=4080?p=255:p>>=4;m<16?m=0:m>=4080?m=255:m>>=4;y<16?y=0:y>=4080?y=255:y>>=4;s[t+e]=Q;s[t+e+8]=E;s[t+e+16]=u;s[t+e+24]=d;s[t+e+32]=f;s[t+e+40]=p;s[t+e+48]=m;s[t+e+56]=y}else{w=ri*Q+8192>>14;w=w<-2040?0:w>=2024?255:w+2056>>4;s[t+e]=w;s[t+e+8]=w;s[t+e+16]=w;s[t+e+24]=w;s[t+e+32]=w;s[t+e+40]=w;s[t+e+48]=w;s[t+e+56]=w}}}function buildComponentData(e,t){const i=t.blocksPerLine,a=t.blocksPerColumn,s=new Int16Array(64);for(let e=0;e<a;e++)for(let a=0;a<i;a++){quantizeAndInverse(t,getBlockBufferOffset(t,e,a),s)}return t.blockData}function findNextFileMarker(e,t,i=t){const a=e.length-1;let s=i<t?i:t;if(t>=a)return null;const r=readUint16(e,t);if(r>=65472&&r<=65534)return{invalid:null,marker:r,offset:t};let n=readUint16(e,s);for(;!(n>=65472&&n<=65534);){if(++s>=a)return null;n=readUint16(e,s)}return{invalid:r.toString(16),marker:n,offset:s}}class JpegImage{constructor({decodeTransform:e=null,colorTransform:t=-1}={}){this._decodeTransform=e;this._colorTransform=t}parse(e,{dnlScanLines:t=null}={}){function readDataBlock(){const t=readUint16(e,s);s+=2;let i=s+t-2;const a=findNextFileMarker(e,i,s);if(a?.invalid){warn("readDataBlock - incorrect length, current marker is: "+a.invalid);i=a.offset}const r=e.subarray(s,i);s+=r.length;return r}function prepareComponents(e){const t=Math.ceil(e.samplesPerLine/8/e.maxH),i=Math.ceil(e.scanLines/8/e.maxV);for(const a of e.components){const s=Math.ceil(Math.ceil(e.samplesPerLine/8)*a.h/e.maxH),r=Math.ceil(Math.ceil(e.scanLines/8)*a.v/e.maxV),n=t*a.h,o=64*(i*a.v)*(n+1);a.blockData=new Int16Array(o);a.blocksPerLine=s;a.blocksPerColumn=r}e.mcusPerLine=t;e.mcusPerColumn=i}let i,a,s=0,r=null,n=null,o=0;const g=[],c=[],h=[];let l=readUint16(e,s);s+=2;if(65496!==l)throw new JpegError("SOI not found");l=readUint16(e,s);s+=2;A:for(;65497!==l;){let C,Q,E;switch(l){case 65504:case 65505:case 65506:case 65507:case 65508:case 65509:case 65510:case 65511:case 65512:case 65513:case 65514:case 65515:case 65516:case 65517:case 65518:case 65519:case 65534:const u=readDataBlock();65504===l&&74===u[0]&&70===u[1]&&73===u[2]&&70===u[3]&&0===u[4]&&(r={version:{major:u[5],minor:u[6]},densityUnits:u[7],xDensity:u[8]<<8|u[9],yDensity:u[10]<<8|u[11],thumbWidth:u[12],thumbHeight:u[13],thumbData:u.subarray(14,14+3*u[12]*u[13])});65518===l&&65===u[0]&&100===u[1]&&111===u[2]&&98===u[3]&&101===u[4]&&(n={version:u[5]<<8|u[6],flags0:u[7]<<8|u[8],flags1:u[9]<<8|u[10],transformCode:u[11]});break;case 65499:const d=readUint16(e,s);s+=2;const f=d+s-2;let p;for(;s<f;){const t=e[s++],i=new Uint16Array(64);if(t>>4==0)for(Q=0;Q<64;Q++){p=$t[Q];i[p]=e[s++]}else{if(t>>4!=1)throw new JpegError("DQT - invalid table spec");for(Q=0;Q<64;Q++){p=$t[Q];i[p]=readUint16(e,s);s+=2}}g[15&t]=i}break;case 65472:case 65473:case 65474:if(i)throw new JpegError("Only single frame JPEGs supported");s+=2;i={};i.extended=65473===l;i.progressive=65474===l;i.precision=e[s++];const m=readUint16(e,s);s+=2;i.scanLines=t||m;i.samplesPerLine=readUint16(e,s);s+=2;i.components=[];i.componentIds={};const y=e[s++];let w=0,b=0;for(C=0;C<y;C++){const t=e[s],a=e[s+1]>>4,r=15&e[s+1];w<a&&(w=a);b<r&&(b=r);const n=e[s+2];E=i.components.push({h:a,v:r,quantizationId:n,quantizationTable:null});i.componentIds[t]=E-1;s+=3}i.maxH=w;i.maxV=b;prepareComponents(i);break;case 65476:const D=readUint16(e,s);s+=2;for(C=2;C<D;){const t=e[s++],i=new Uint8Array(16);let a=0;for(Q=0;Q<16;Q++,s++)a+=i[Q]=e[s];const r=new Uint8Array(a);for(Q=0;Q<a;Q++,s++)r[Q]=e[s];C+=17+a;(t>>4==0?h:c)[15&t]=buildHuffmanTable(i,r)}break;case 65501:s+=2;a=readUint16(e,s);s+=2;break;case 65498:const F=1==++o&&!t;s+=2;const S=e[s++],k=[];for(C=0;C<S;C++){const t=e[s++],a=i.componentIds[t],r=i.components[a];r.index=t;const n=e[s++];r.huffmanTableDC=h[n>>4];r.huffmanTableAC=c[15&n];k.push(r)}const R=e[s++],N=e[s++],G=e[s++];try{const t=decodeScan(e,s,i,k,a,R,N,G>>4,15&G,F);s+=t}catch(t){if(t instanceof DNLMarkerError){warn(`${t.message} -- attempting to re-parse the JPEG image.`);return this.parse(e,{dnlScanLines:t.scanLines})}if(t instanceof EOIMarkerError){warn(`${t.message} -- ignoring the rest of the image data.`);break A}throw t}break;case 65500:s+=4;break;case 65535:255!==e[s]&&s--;break;default:const x=findNextFileMarker(e,s-2,s-3);if(x?.invalid){warn("JpegImage.parse - unexpected data, current marker is: "+x.invalid);s=x.offset;break}if(!x||s>=e.length-1){warn("JpegImage.parse - reached the end of the image data without finding an EOI marker (0xFFD9).");break A}throw new JpegError("JpegImage.parse - unknown marker: "+l.toString(16))}l=readUint16(e,s);s+=2}if(!i)throw new JpegError("JpegImage.parse - no frame data found.");this.width=i.samplesPerLine;this.height=i.scanLines;this.jfif=r;this.adobe=n;this.components=[];for(const e of i.components){const t=g[e.quantizationId];t&&(e.quantizationTable=t);this.components.push({index:e.index,output:buildComponentData(0,e),scaleX:e.h/i.maxH,scaleY:e.v/i.maxV,blocksPerLine:e.blocksPerLine,blocksPerColumn:e.blocksPerColumn})}this.numComponents=this.components.length}_getLinearizedBlockData(e,t,i=!1){const a=this.width/e,s=this.height/t;let r,n,o,g,c,h,l,C,Q,E,u,d=0;const f=this.components.length,p=e*t*f,m=new Uint8ClampedArray(p),y=new Uint32Array(e),w=4294967288;let b;for(l=0;l<f;l++){r=this.components[l];n=r.scaleX*a;o=r.scaleY*s;d=l;u=r.output;g=r.blocksPerLine+1<<3;if(n!==b){for(c=0;c<e;c++){C=0|c*n;y[c]=(C&w)<<3|7&C}b=n}for(h=0;h<t;h++){C=0|h*o;E=g*(C&w)|(7&C)<<3;for(c=0;c<e;c++){m[d]=u[E+y[c]];d+=f}}}let D=this._decodeTransform;i||4!==f||D||(D=new Int32Array([-256,255,-256,255,-256,255,-256,255]));if(D)for(l=0;l<p;)for(C=0,Q=0;C<f;C++,l++,Q+=2)m[l]=(m[l]*D[Q]>>8)+D[Q+1];return m}get _isColorConversionNeeded(){return this.adobe?!!this.adobe.transformCode:3===this.numComponents?0!==this._colorTransform&&(82!==this.components[0].index||71!==this.components[1].index||66!==this.components[2].index):1===this._colorTransform}_convertYccToRgb(e){let t,i,a;for(let s=0,r=e.length;s<r;s+=3){t=e[s];i=e[s+1];a=e[s+2];e[s]=t-179.456+1.402*a;e[s+1]=t+135.459-.344*i-.714*a;e[s+2]=t-226.816+1.772*i}return e}_convertYccToRgba(e,t){for(let i=0,a=0,s=e.length;i<s;i+=3,a+=4){const s=e[i],r=e[i+1],n=e[i+2];t[a]=s-179.456+1.402*n;t[a+1]=s+135.459-.344*r-.714*n;t[a+2]=s-226.816+1.772*r;t[a+3]=255}return t}_convertYcckToRgb(e){let t,i,a,s,r=0;for(let n=0,o=e.length;n<o;n+=4){t=e[n];i=e[n+1];a=e[n+2];s=e[n+3];e[r++]=i*(-660635669420364e-19*i+.000437130475926232*a-54080610064599e-18*t+.00048449797120281*s-.154362151871126)-122.67195406894+a*(-.000957964378445773*a+.000817076911346625*t-.00477271405408747*s+1.53380253221734)+t*(.000961250184130688*t-.00266257332283933*s+.48357088451265)+s*(-.000336197177618394*s+.484791561490776);e[r++]=107.268039397724+i*(219927104525741e-19*i-.000640992018297945*a+.000659397001245577*t+.000426105652938837*s-.176491792462875)+a*(-.000778269941513683*a+.00130872261408275*t+.000770482631801132*s-.151051492775562)+t*(.00126935368114843*t-.00265090189010898*s+.25802910206845)+s*(-.000318913117588328*s-.213742400323665);e[r++]=i*(-.000570115196973677*i-263409051004589e-19*a+.0020741088115012*t-.00288260236853442*s+.814272968359295)-20.810012546947+a*(-153496057440975e-19*a-.000132689043961446*t+.000560833691242812*s-.195152027534049)+t*(.00174418132927582*t-.00255243321439347*s+.116935020465145)+s*(-.000343531996510555*s+.24165260232407)}return e.subarray(0,r)}_convertYcckToRgba(e){for(let t=0,i=e.length;t<i;t+=4){const i=e[t],a=e[t+1],s=e[t+2],r=e[t+3];e[t]=a*(-660635669420364e-19*a+.000437130475926232*s-54080610064599e-18*i+.00048449797120281*r-.154362151871126)-122.67195406894+s*(-.000957964378445773*s+.000817076911346625*i-.00477271405408747*r+1.53380253221734)+i*(.000961250184130688*i-.00266257332283933*r+.48357088451265)+r*(-.000336197177618394*r+.484791561490776);e[t+1]=107.268039397724+a*(219927104525741e-19*a-.000640992018297945*s+.000659397001245577*i+.000426105652938837*r-.176491792462875)+s*(-.000778269941513683*s+.00130872261408275*i+.000770482631801132*r-.151051492775562)+i*(.00126935368114843*i-.00265090189010898*r+.25802910206845)+r*(-.000318913117588328*r-.213742400323665);e[t+2]=a*(-.000570115196973677*a-263409051004589e-19*s+.0020741088115012*i-.00288260236853442*r+.814272968359295)-20.810012546947+s*(-153496057440975e-19*s-.000132689043961446*i+.000560833691242812*r-.195152027534049)+i*(.00174418132927582*i-.00255243321439347*r+.116935020465145)+r*(-.000343531996510555*r+.24165260232407);e[t+3]=255}return e}_convertYcckToCmyk(e){let t,i,a;for(let s=0,r=e.length;s<r;s+=4){t=e[s];i=e[s+1];a=e[s+2];e[s]=434.456-t-1.402*a;e[s+1]=119.541-t+.344*i+.714*a;e[s+2]=481.816-t-1.772*i}return e}_convertCmykToRgb(e){let t,i,a,s,r=0;for(let n=0,o=e.length;n<o;n+=4){t=e[n];i=e[n+1];a=e[n+2];s=e[n+3];e[r++]=255+t*(-6747147073602441e-20*t+.0008379262121013727*i+.0002894718188643294*a+.003264231057537806*s-1.1185611867203937)+i*(26374107616089405e-21*i-8626949158638572e-20*a-.0002748769067499491*s-.02155688794978967)+a*(-3878099212869363e-20*a-.0003267808279485286*s+.0686742238595345)-s*(.0003361971776183937*s+.7430659151342254);e[r++]=255+t*(.00013596372813588848*t+.000924537132573585*i+.00010567359618683593*a+.0004791864687436512*s-.3109689587515875)+i*(-.00023545346108370344*i+.0002702845253534714*a+.0020200308977307156*s-.7488052167015494)+a*(6834815998235662e-20*a+.00015168452363460973*s-.09751927774728933)-s*(.0003189131175883281*s+.7364883807733168);e[r++]=255+t*(13598650411385307e-21*t+.00012423956175490851*i+.0004751985097583589*a-36729317476630422e-22*s-.05562186980264034)+i*(.00016141380598724676*i+.0009692239130725186*a+.0007782692450036253*s-.44015232367526463)+a*(5.068882914068769e-7*a+.0017778369011375071*s-.7591454649749609)-s*(.0003435319965105553*s+.7063770186160144)}return e.subarray(0,r)}_convertCmykToRgba(e){for(let t=0,i=e.length;t<i;t+=4){const i=e[t],a=e[t+1],s=e[t+2],r=e[t+3];e[t]=255+i*(-6747147073602441e-20*i+.0008379262121013727*a+.0002894718188643294*s+.003264231057537806*r-1.1185611867203937)+a*(26374107616089405e-21*a-8626949158638572e-20*s-.0002748769067499491*r-.02155688794978967)+s*(-3878099212869363e-20*s-.0003267808279485286*r+.0686742238595345)-r*(.0003361971776183937*r+.7430659151342254);e[t+1]=255+i*(.00013596372813588848*i+.000924537132573585*a+.00010567359618683593*s+.0004791864687436512*r-.3109689587515875)+a*(-.00023545346108370344*a+.0002702845253534714*s+.0020200308977307156*r-.7488052167015494)+s*(6834815998235662e-20*s+.00015168452363460973*r-.09751927774728933)-r*(.0003189131175883281*r+.7364883807733168);e[t+2]=255+i*(13598650411385307e-21*i+.00012423956175490851*a+.0004751985097583589*s-36729317476630422e-22*r-.05562186980264034)+a*(.00016141380598724676*a+.0009692239130725186*s+.0007782692450036253*r-.44015232367526463)+s*(5.068882914068769e-7*s+.0017778369011375071*r-.7591454649749609)-r*(.0003435319965105553*r+.7063770186160144);e[t+3]=255}return e}getData({width:e,height:t,forceRGBA:i=!1,forceRGB:a=!1,isSourcePDF:s=!1}){if(this.numComponents>4)throw new JpegError("Unsupported color mode");const r=this._getLinearizedBlockData(e,t,s);if(1===this.numComponents&&(i||a)){const e=r.length*(i?4:3),t=new Uint8ClampedArray(e);let a=0;if(i)!function grayToRGBA(e,t){if(FeatureTest.isLittleEndian)for(let i=0,a=e.length;i<a;i++)t[i]=65793*e[i]|4278190080;else for(let i=0,a=e.length;i<a;i++)t[i]=16843008*e[i]|255}(r,new Uint32Array(t.buffer));else for(const e of r){t[a++]=e;t[a++]=e;t[a++]=e}return t}if(3===this.numComponents&&this._isColorConversionNeeded){if(i){const e=new Uint8ClampedArray(r.length/3*4);return this._convertYccToRgba(r,e)}return this._convertYccToRgb(r)}if(4===this.numComponents){if(this._isColorConversionNeeded)return i?this._convertYcckToRgba(r):a?this._convertYcckToRgb(r):this._convertYcckToCmyk(r);if(i)return this._convertCmykToRgba(r);if(a)return this._convertCmykToRgb(r)}return r}}class JpegStream extends DecodeStream{constructor(e,t,i){let a;for(;-1!==(a=e.getByte());)if(255===a){e.skip(-1);break}super(t);this.stream=e;this.dict=e.dict;this.maybeLength=t;this.params=i}get bytes(){return shadow(this,"bytes",this.stream.getBytes(this.maybeLength))}ensureBuffer(e){}readBlock(){if(this.eof)return;const e={decodeTransform:void 0,colorTransform:void 0},t=this.dict.getArray("D","Decode");if((this.forceRGBA||this.forceRGB)&&Array.isArray(t)){const i=this.dict.get("BPC","BitsPerComponent")||8,a=t.length,s=new Int32Array(a);let r=!1;const n=(1<<i)-1;for(let e=0;e<a;e+=2){s[e]=256*(t[e+1]-t[e])|0;s[e+1]=t[e]*n|0;256===s[e]&&0===s[e+1]||(r=!0)}r&&(e.decodeTransform=s)}if(this.params instanceof Dict){const t=this.params.get("ColorTransform");Number.isInteger(t)&&(e.colorTransform=t)}const i=new JpegImage(e);i.parse(this.bytes);const a=i.getData({width:this.drawWidth,height:this.drawHeight,forceRGBA:this.forceRGBA,forceRGB:this.forceRGB,isSourcePDF:!0});this.buffer=a;this.bufferLength=a.length;this.eof=!0}}var oi,gi=(oi="undefined"!=typeof document?document.currentScript?.src:void 0,function(e={}){var t,i,a=Object.assign({},e);new Promise(((e,a)=>{t=e;i=a}));a.decode=function(e,t){const i=e.length,s=a._malloc(i);a.HEAPU8.set(e,s);const r=a._jp2_decode(s,i,t?1:0);a._free(s);if(r){const{errorMessages:e}=a;if(e){delete a.errorMessages;return e}return"Unknown error"}const{imageData:n}=a;a.imageData=null;return n};var s,r=Object.assign({},a),n="./this.program",o="";"undefined"!=typeof document&&document.currentScript&&(o=document.currentScript.src);oi&&(o=oi);o=o.startsWith("blob:")?"":o.substr(0,o.replace(/[?#].*/,"").lastIndexOf("/")+1);var g,c,h,l,C,Q=a.print||console.log.bind(console),E=a.printErr||console.error.bind(console);Object.assign(a,r);r=null;a.arguments&&a.arguments;a.thisProgram&&(n=a.thisProgram);a.quit&&a.quit;a.wasmBinary&&(g=a.wasmBinary);function tryParseAsDataURI(e){if(isDataURI(e))return function intArrayFromBase64(e){for(var t=atob(e),i=new Uint8Array(t.length),a=0;a<t.length;++a)i[a]=t.charCodeAt(a);return i}(e.slice(b.length))}function updateMemoryViews(){var e=c.buffer;a.HEAP8=h=new Int8Array(e);a.HEAP16=new Int16Array(e);a.HEAPU8=l=new Uint8Array(e);a.HEAPU16=new Uint16Array(e);a.HEAP32=new Int32Array(e);a.HEAPU32=C=new Uint32Array(e);a.HEAPF32=new Float32Array(e);a.HEAPF64=new Float64Array(e)}var u,d=[],f=[],p=[],m=0,y=null,w=null,b="data:application/octet-stream;base64,",isDataURI=e=>e.startsWith(b);function instantiateSync(e,t){var i,a=function getBinarySync(e){if(e==u&&g)return new Uint8Array(g);var t=tryParseAsDataURI(e);if(t)return t;if(s)return s(e);throw'sync fetching of the wasm failed: you can preload it to Module["wasmBinary"] manually, or emcc.py will do that for you when generating HTML (but not JS)'}(e);i=new WebAssembly.Module(a);return[new WebAssembly.Instance(i,t),i]}var D,callRuntimeCallbacks=e=>{for(;e.length>0;)e.shift()(a)},F=(a.noExitRuntime,e=>{var t=(e-c.buffer.byteLength+65535)/65536;try{c.grow(t);updateMemoryViews();return 1}catch(e){}}),S={},getEnvStrings=()=>{if(!getEnvStrings.strings){var e={USER:"web_user",LOGNAME:"web_user",PATH:"/",PWD:"/",HOME:"/home/web_user",LANG:("object"==typeof navigator&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8",_:n||"./this.program"};for(var t in S)void 0===S[t]?delete e[t]:e[t]=S[t];var i=[];for(var t in e)i.push(`${t}=${e[t]}`);getEnvStrings.strings=i}return getEnvStrings.strings},k=[null,[],[]],R="undefined"!=typeof TextDecoder?new TextDecoder("utf8"):void 0,UTF8ArrayToString=(e,t,i)=>{for(var a=t+i,s=t;e[s]&&!(s>=a);)++s;if(s-t>16&&e.buffer&&R)return R.decode(e.subarray(t,s));for(var r="";t<s;){var n=e[t++];if(128&n){var o=63&e[t++];if(192!=(224&n)){var g=63&e[t++];if((n=224==(240&n)?(15&n)<<12|o<<6|g:(7&n)<<18|o<<12|g<<6|63&e[t++])<65536)r+=String.fromCharCode(n);else{var c=n-65536;r+=String.fromCharCode(55296|c>>10,56320|1023&c)}}else r+=String.fromCharCode((31&n)<<6|o)}else r+=String.fromCharCode(n)}return r},printChar=(e,t)=>{var i=k[e];if(0===t||10===t){(1===e?Q:E)(UTF8ArrayToString(i,0));i.length=0}else i.push(t)},UTF8ToString=(e,t)=>e?UTF8ArrayToString(l,e,t):"",N={f:(e,t,i)=>l.copyWithin(e,t,t+i),b:e=>{var t=l.length,i=2147483648;if((e>>>=0)>i)return!1;for(var a,s,r=1;r<=4;r*=2){var n=t*(1+.2/r);n=Math.min(n,e+100663296);var o=Math.min(i,(a=Math.max(e,n))+((s=65536)-a%s)%s);if(F(o))return!0}return!1},c:(e,t)=>{var i=0;getEnvStrings().forEach(((a,s)=>{var r=t+i;C[e+4*s>>2]=r;((e,t)=>{for(var i=0;i<e.length;++i)h[t++]=e.charCodeAt(i);h[t]=0})(a,r);i+=a.length+1}));return 0},d:(e,t)=>{var i=getEnvStrings();C[e>>2]=i.length;var a=0;i.forEach((e=>a+=e.length+1));C[t>>2]=a;return 0},e:(e,t,i,a)=>{for(var s=0,r=0;r<i;r++){var n=C[t>>2],o=C[t+4>>2];t+=8;for(var g=0;g<o;g++)printChar(e,l[n+g]);s+=o}C[a>>2]=s;return 0},g:function _jsPrintWarning(e){const t=UTF8ToString(e);(a.warn||console.warn)(`OpenJPEG: ${t}`)},h:function _setImageData(e,t){a.imageData=new Uint8ClampedArray(a.HEAPU8.subarray(e,e+t))},a:function _storeErrorMessage(e){const t=UTF8ToString(e);a.errorMessages?a.errorMessages+="\n"+t:a.errorMessages=t}},G=function createWasm(){var e=function getWasmImports(){return{a:N}}();function receiveInstance(e,t){G=e.exports;c=G.i;updateMemoryViews();!function addOnInit(e){f.unshift(e)}(G.j);!function removeRunDependency(e){m--;a.monitorRunDependencies?.(m);if(0==m){if(null!==y){clearInterval(y);y=null}if(w){var t=w;w=null;t()}}}();return G}!function addRunDependency(e){m++;a.monitorRunDependencies?.(m)}();if(a.instantiateWasm)try{return a.instantiateWasm(e,receiveInstance)}catch(e){E(`Module.instantiateWasm callback failed with error: ${e}`);i(e)}u||(u="data:application/octet-stream;base64,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dEGwnQFqKAIAIQICfiAAKQMIIg5CAFMEQEEMIAFBAWogAUELThshBCADQQFrIQNBfyACdEF/c0EBdCEBQgEMAQsgAUEBa0EAIAFBAUobIQQgDkE/IAJrrYinQX8gAnRBf3NxQQF0QQFyIQEgAyACQQFqIgJrIQMgAq0LIQ8gACADNgIQIAAgBDYCHCAAIA4gD4Y3AwggACAAKQMoQv//////QIMgAa1CI4aENwMoQQYhBSADQQZIDQAgACgCHCIBQQJ0QbCdAWooAgAhAgJ+IAApAwgiDkIAUwRAQQwgAUEBaiABQQtOGyEEIANBAWshA0F/IAJ0QX9zQQF0IQFCAQwBCyABQQFrQQAgAUEBShshBCAOQT8gAmutiKdBfyACdEF/c3FBAXRBAXIhASADIAJBAWoiAmshAyACrQshDyAAIAM2AhAgACAENgIcIAAgDiAPhjcDCCAAIAApAyhC////////QIMgAa1CKoaENwMoQQchBSADQQZIDQAgACgCHCIBQQJ0QbCdAWooAgAhAgJ+IAApAwgiDkIAUwRAQQwgAUEBaiABQQtOGyEEIANBAWshA0F/IAJ0QX9zQQF0IQFCAQwBCyABQQFrQQAgAUEBShshBCAOQT8gAmutiKdBfyACdEF/c3FBAXRBAXIhASADIAJBAWoiAmshAyACrQshDyAAIAM2AhAgACAENgIcIAAgDiAPhjcDCCAAIAApAyhC/////////0CDIAGtQjGGhDcDKEEIIQULIAAgBUEBazYCICAAIAApAygiDkIHiDcDKCAOp0H/AHELIgEBfyAABEAgACgCDCIBBEAgARAJIABBADYCDAsgABAJCwuFAQIFfwF+AkAgAEKAgICAEFQEQCAAIQcMAQsDQCABQQFrIgEgAEIKgCIHQvYBfiAAfKdBMHI6AAAgAEL/////nwFWIQUgByEAIAUNAAsLIAenIgIEQANAIAFBAWsiASACQQpuIgNB9gFsIAJqQTByOgAAIAJBCUshBiADIQIgBg0ACwsgAQv54gEEen8Gewh+AX0jAEEQayJOJAACQCAALQAIQYABcUUNACAAKALMASABRw0AIAAoApwBIAFBjCxsaiJPKALcKyIVRQRAIE8QKQwBCyAAKALIARogACgC0AEhGSAAKAJMIgdFBEAgACgCSCEHCyAHKAIAIQYgBygCBCELIAco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AAACAAAA/a4BQQL9rAH9sQH9CwIAIAEiBkEBaiIBIA9HDQALIA8hBwsgByAbTg0AA0AgB0EDdCEBIAcgLEghBgJAIAdBAEwEQCA2KAIAIQogB0EATgRAIBQgAUECdCIBaiIyIDIoAgAgCiABIDZqIEUgBhsoAgBqQQJqQQJ1azYCACABICRqIgogCigCACAgKAIAIAEgIGogPCAGGygCAGpBAmpBAnVrNgIAIAEgKmoiCiAKKAIAIB8oAgAgASAfaiA6IAYbKAIAakECakECdWs2AgAgQygCACABIENqICYgBhsoAgBqQQJqIQYgASApaiEBDAILIBQgAUECdCIBaiIGIAYoAgAgCkEBdEECakECdWs2AgAgASAkaiIGIAYoAgAgFCgCFEEBdEECakECdWs2AgAgASAqaiIGIAYoAgAgFCgCGEEBdEECakECdWs2AgAgASApaiEBIBQoAhxBAXRBAmohBgwBCyAUIAcgLCAGG0EDdEEEa0ECdCIKaigCACEyIAZFBEAgFCABQQJ0IgFqIgYgBigCACAyIEUoAgBqQQJqQQJ1azYCACABICRqIgYgBigCACAKICRqKAIAIDwoAgBqQQJqQQJ1azYCACABICpqIgYgBigCACAKICpqKAIAIDooAgBqQQJqQQJ1azYCACABIClqIQEgCiApaigCACAmKAIAakECaiEGDAELIBQgAUECdCIBaiIGIAYoAgAgMiAGKAIQakECakECdWs2AgAgASAkaiIGIAYoAgAgCiAkaigCACAGKAIQakECakECdWs2AgAgASAqaiIGIAYoAgAgCiAqaigCACAGKAIQakECakECdWs2AgAgCiApaigCACABIClqIgEoAhBqQQJqIQYLIAEgASgCACAGQQJ1azYCACAHQQFqIgcgG0cNAAsLIA4gHE4NACAMIA4iASIHSgRAA0AgFCABQQV0aiIHIAf9AAIgIAf9AAIA/a4BQQH9rAEgB/0AAhD9rgH9CwIQIAFBAWoiASAMRw0ACyAMIQcLIAcgHE4NAANAIEMgB0EDdCIBQQJ0aiIyAn8gB0EASARAIBQoAgAhBiAHQX9HBEAgNiABQQJ0IgFqIgogCigCACAGajYCACABICBqIgYgBigCACAkKAIAajYCACABIB9qIgEgASgCACAqKAIAajYCACApKAIADAILIDYgAUECdCIB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LQAAQYD+A3I2AgwLIABBADYCEEEBCwtJAQF/AkBBAUEsEAwiAQRAIAFBADYCEAJAIABBAEwEQCABQQFBCBAMIgA2AiQgAEUNAQwDCyABQQA2AgwLIAEQCQtBACEBCyABC34CAX8BfiAAvSIDQjSIp0H/D3EiAkH/D0cEfCACRQRAIAEgAEQAAAAAAAAAAGEEf0EABSAARAAAAAAAAPBDoiABEF8hACABKAIAQUBqCzYCACAADwsgASACQf4HazYCACADQv////////+HgH+DQoCAgICAgIDwP4S/BSAACwuRAgAgAEUEQEEADwsCfwJAIAFB/wBNDQACQEGUzwEoAgAoAgBFBEAgAUGAf3FBgL8DRg0CDAELIAFB/w9NBEAgACABQT9xQYABcjoAASAAIAFBBnZBwAFyOgAAQQIMAwsgAUGAQHFBgMADRyABQYCwA09xRQRAIAAgAUE/cUGAAXI6AAIgACABQQx2QeABcjoAACAAIAFBBnZBP3FBgAFyOgABQQMMAwsgAUGAgARrQf//P00EQCAAIAFBP3FBgAFyOgADIAAgAUESdkHwAXI6AAAgACABQQZ2QT9xQYABcjoAAiAAIAFBDHZBP3FBgAFyOgABQQQMAwsLQZTGAUEZNgIAQX8MAQsgACABOgAAQQELC7wCAAJAAkACQAJAAkACQAJAAkACQAJAAkAgAUEJaw4SAAgJCggJAQIDBAoJCgoICQUGBwsgAiACKAIAIgFBBGo2AgAgACABKAIANgIADwsgAiACKAIAIgFBBGo2AgAgACABMgEANwMADwsgAiACKAIAIgFBBGo2AgAgACABMwEANwMADwsgAiACKAIAIgFBBGo2AgAgACABMAAANwMADwsgAiACKAIAIgFBBGo2AgAgACABMQAANwMADwsgAiACKAIAQQdqQXhxIgFBCGo2AgAgACABKwMAOQMADwsgACACIAMRAwALDwsgAiACKAIAIgFBBGo2AgAgACABNAIANwMADwsgAiACKAIAIgFBBGo2AgAgACABNQIANwMADwsgAiACKAIAQQdqQXhxIgFBCGo2AgAgACABKQMANwMAC3MBBn8gACgCACIDLAAAQTBrIgFBCUsEQEEADwsDQEF/IQQgAkHMmbPmAE0EQEF/IAEgAkEKbCIFaiABIAVB/////wdzSxshBAsgACADQQFqIgU2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VP0gAiACKgJ0/SAD/QsCACABIAMgF2pBAnRqIAL9CQIYIAIqAjj9IAEgAioCWP0gAiACKgJ4/SAD/QsCACABIAMgFmpBAnRqIAL9CQIcIAIqAjz9IAEgAioCXP0gAiACKgJ8/SAD/QsCACADQQRqIgMgBEcNAAsgBCALRg0BCwNAIAEgBCAbakECdGogBiAEQQV0aiIDKgIQOAIAIAEgBCAYakECdGogAyoCFDgCACABIAQgF2pBAnRqIAMqAhg4AgAgASAEIBZqQQJ0aiADKgIcOAIAIARBAWoiBCALRw0ACwsgHUEBaiEdIAEgJEECdGohASAcQQhqIhwgACgCLE0NAAsLIAAoAgAQCSAAEAkLcwECfyAAKAIcIgFBCGoiAyAAKAIgIgJNBEADQCAAIAAoAhggAUECdGogACgCFEEIECsgAyIBQQhqIgMgACgCICICTQ0ACwsgASACSQRAIAAgACgCGCABQQJ0aiAAKAIUIAIgAWsQKwsgACgCABAJIAAQCQtEACAAKAIcIgEgACgCIEkEQANAIAAgACgCGCAAKAIUIAFsQQJ0ahBWIAFBAWoiASAAKAIgSQ0ACwsgACgCABAJIAAQCQuoAQEFfyAAKAJUIgMoAgAhBSADKAIEIgQgACgCFCAAKAIcIgdrIgYgBCAGSRsiBgRAIAUgByAGEAsaIAMgAygCACAGaiIFNgIAIAMgAygCBCAGayIENgIECyAEIAIgAiAESxsiBARAIAUgASAEEAsaIAMgAygCACAEaiIFNgIAIAMgAygCBCAEazYCBAsgBUEAOgAAIAAgACgCLCIBNgIcIAAgATYCFCACC54FAgZ+BH8gASABKAIAQQdqQXhxIgFBEGo2AgAgACELIAEpAwAhAyABKQMIIQcjAEEgayIIJAAgB0L///////8/gyEEAn4gB0IwiEL//wGDIgWnIgpBgfgAa0H9D00EQCAEQgSGIANCPIiEIQIgCkGA+ABrrSEFAkAgA0L//////////w+DIgNCgYCAgICAgIAIWgRAIAJCAXwhAgwBCyADQoCAgICAgICACFINACACQgGDIAJ8IQILQgAgAiACQv////////8HViIAGyECIACtIAV8DAELAkAgAyAEhFANACAFQv//AVINACAEQgSGIANCPIiEQoCAgICAgIAEhCECQv8PDAELQv8PIApB/ocB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JWQpIAAlc30KAAkJIH0KAFtERVZdIER1bXAgYW4gaW1hZ2VfY29tcF9oZWFkZXIgc3RydWN0IHsKAFtERVZdIER1bXAgYW4gaW1hZ2VfaGVhZGVyIHN0cnVjdCB7CgBJbWFnZSBpbmZvIHsKAAkgZGVmYXVsdCB0aWxlIHsKACVzCSBjb21wb25lbnQgJWQgewoACQkgY29tcCAlZCB7CgAJIFRpbGUgaW5kZXg6IHsKAAkgTWFya2VyIGxpc3Q6IHsKAENvZGVzdHJlYW0gaW5kZXggZnJvbSBtYWluIGhlYWRlcjogewoAQ29kZXN0cmVhbSBpbmZvIGZyb20gbWFpbiBoZWFkZXI6IHsKAFN0cmVhbSBlcnJvciB3aGlsZSByZWFkaW5nIEpQMiBIZWFkZXIgYm94CgBGb3VuZCBhIG1pc3BsYWNlZCAnJWMlYyVjJWMnIGJveCBvdXRzaWRlIGpwMmggYm94CgBNYWxmb3JtZWQgSlAyIGZpbGUgZm9ybWF0OiBmaXJzdCBib3ggbXVzdCBiZSBKUEVHIDIwMDAgc2lnbmF0dXJlIGJveAoATWFsZm9ybWVkIEpQMiBmaWxlIGZvcm1hdDogc2Vjb25kIGJveCBtdXN0IGJlIGZpbGUgdHlwZSBib3gKAE5vdCBlbm91Z2ggbWVtb3J5IHRvIGhhbmRsZSBqcGVnMjAwMCBib3gKAE5vdCBlbm91Z2ggbWVtb3J5IHdpdGggRlRZUCBCb3gKAEEgbWFya2VyIElEIHdhcyBleHBlY3RlZCAoMHhmZi0tKSBpbnN0ZWFkIG9mICUuOHgKAAkJIG1jdD0leAoACQkJIGNibGtzdHk9JSN4CgAJCQkgY3N0eT0lI3gKAAkJIHByZz0lI3gKAEludGVnZXIgb3ZlcmZsb3cKAAkgdGR4PSV1LCB0ZHk9JXUKAAkgdHc9JXUsIHRoPSV1CgAJIHR4MD0ldSwgdHkwPSV1CgBJbnZhbGlkIGNvbXBvbmVudCBpbmRleDogJXUKAFN0cmVhbSB0b28gc2hvcnQKAE1hcmtlciBoYW5kbGVyIGZ1bmN0aW9uIGZhaWxlZCB0byByZWFkIHRoZSBtYXJrZXIgc2VnbWVudAoATm90IGVub3VnaCBtZW1vcnkgZm9yIGN1cnJlbnQgcHJlY2luY3QgY29kZWJsb2NrIGVsZW1lbnQKAEVycm9yIHJlYWRpbmcgU1BDb2QgU1BDb2MgZWxlbWVudAoARXJyb3IgcmVhZGluZyBTUWNkIG9yIFNRY2MgZWxlbWVudAoAQSBCUENDIGhlYWRlciBib3ggaXMgYXZhaWxhYmxlIGFsdGhvdWdoIEJQQyBnaXZlbiBieSB0aGUgSUhEUiBib3ggKCVkKSBpbmRpY2F0ZSBjb21wb25lbnRzIGJpdCBkZXB0aCBpcyBjb25zdGFudAoARXJyb3Igd2l0aCBTSVogbWFya2VyOiBpbGxlZ2FsIHRpbGUgb2Zmc2V0CgBJbnZhbGlkIHByZWNpbmN0CgBOb3QgZW5vdWdoIG1lbW9yeSB0byBoYW5kbGUgYmFuZCBwcmVjaW50cwoARmFpbGVkIHRvIGRlY29kZSBhbGwgdXNlZCBjb21wb25lbnRzCgBTaXplIG9mIGNvZGUgYmxvY2sgZGF0YSBleGNlZWRzIHN5c3RlbSBsaW1pdHMKAFNpemUgb2YgdGlsZSBkYXRhIGV4Y2VlZHMgc3lzdGVtIGxpbWl0cwoAQ2Fubm90IHRha2UgaW4gY2hhcmdlIG11bHRpcGxlIE1DVCBtYXJrZXJzCgBDb3JydXB0ZWQgUFBNIG1hcmtlcnMKAE5vdCBlbm91Z2ggbWVtb3J5IGZvciB0aWxlIHJlc29sdXRpb25zCgBDYW5ub3QgdGFrZSBpbiBjaGFyZ2UgbXVsdGlwbGUgY29sbGVjdGlvbnMKAEludmFsaWQgUENMUiBib3guIFJlcG9ydHMgMCBwYWxldHRlIGNvbHVtbnMKAFdlIGRvIG5vdCBzdXBwb3J0IFJPSSBpbiBkZWNvZGluZyBIVCBjb2RlYmxvY2tzCgBDYW5ub3QgaGFuZGxlIGJveCBvZiB1bmRlZmluZWQgc2l6ZXMKAENhbm5vdCB0YWtlIGluIGNoYXJnZSBjb2xsZWN0aW9ucyB3aXRob3V0IHNhbWUgbnVtYmVyIG9mIGluZGl4ZXMKAEludmFsaWQgdGlsZWMtPndpbl94eHggdmFsdWVzCgBDYW5ub3QgaGFuZGxlIGJveCBvZiBsZXNzIHRoYW4gOCBieXRlcwoAQ2Fubm90IGhhbmRsZSBYTCBib3ggb2YgbGVzcyB0aGFuIDE2IGJ5dGVzCgBDb21wb25lbnQgaW5kZXggJXUgdXNlZCBzZXZlcmFsIHRpbWVzCgBJbnZhbGlkIFBDTFIgYm94LiBSZXBvcnRzICVkIGVudHJpZXMKAE5vdCBlbm91Z2ggbWVtb3J5IHRvIGNyZWF0ZSBUYWctdHJlZSBub2RlcwoAQ2Fubm90IHRha2UgaW4gY2hhcmdlIG1jdCBkYXRhIHdpdGhpbiBtdWx0aXBsZSBNQ1QgcmVjb3JkcwoAQ2Fubm90IGRlY29kZSB0aWxlLCBtZW1vcnkgZXJyb3IKAG9wal9qMmtfYXBwbHlfbmJfdGlsZV9wYXJ0c19jb3JyZWN0aW9uIGVycm9yCgBQcm9ibGVtIHdpdGggc2tpcHBpbmcgSlBFRzIwMDAgYm94LCBzdHJlYW0gZXJyb3IKAFByb2JsZW0gd2l0aCByZWFkaW5nIEpQRUcyMDAwIGJveCwgc3RyZWFtIGVycm9yCgBVbmtub3duIG1hcmtlcgoATm90IGVub3VnaCBtZW1vcnkgdG8gYWRkIHRsIG1hcmtlcgoATm90IGVub3VnaCBtZW1vcnkgdG8gYWRkIG1oIG1hcmtlcgoATm90IGVub3VnaCBtZW1vcnkgdG8gdGFrZSBpbiBjaGFyZ2UgU0laIG1hcmtlcgoARXJyb3IgcmVhZGluZyBQUFQgbWFya2VyCgBOb3QgZW5vdWdoIG1lbW9yeSB0byByZWFkIFBQVCBtYXJrZXIKAEVycm9yIHJlYWRpbmcgU09UIG1hcmtlcgoARXJyb3IgcmVhZGluZyBQTFQgbWFya2VyCgBFcnJvciByZWFkaW5nIE1DVCBtYXJrZXIKAE5vdCBlbm91Z2ggbWVtb3J5IHRvIHJlYWQgTUNUIG1hcmtlcgoATm90IGVub3VnaCBzcGFjZSBmb3IgZXhwZWN0ZWQgU09QIG1hcmtlcgoARXhwZWN0ZWQgU09QIG1hcmtlcgoARXJyb3IgcmVhZGluZyBNQ08gbWFya2VyCgBFcnJvciByZWFkaW5nIFJHTiBtYXJrZXIKAEVycm9yIHJlYWRpbmcgUFBNIG1hcmtlcgoATm90IGVub3VnaCBtZW1vcnkgdG8gcmVhZCBQUE0gbWFya2VyCgBFcnJvciByZWFkaW5nIFRMTSBtYXJrZXIKAEVycm9yIHJlYWRpbmcgUExNIG1hcmtlcgoATm90IGVub3VnaCBzcGFjZSBmb3IgZXhwZWN0ZWQgRVBIIG1hcmtlcgoARXhwZWN0ZWQgRVBIIG1hcmtlcgoARXJyb3IgcmVhZGluZyBDUkcgbWFya2VyCgBVbmtub3duIHByb2dyZXNzaW9uIG9yZGVyIGluIENPRCBtYXJrZXIKAFVua25vd24gU2NvZCB2YWx1ZSBpbiBDT0QgbWFya2VyCgBFcnJvciByZWFkaW5nIENPRCBtYXJrZXIKAEVycm9yIHJlYWRpbmcgUUNEIG1hcmtlcgoAQ3Jyb3IgcmVhZGluZyBDQkQgbWFya2VyCgBFcnJvciByZWFkaW5nIFBPQyBtYXJrZXIKAEVycm9yIHJlYWRpbmcgQ09DIG1hcmtlcgoARXJyb3IgcmVhZGluZyBRQ0MgbWFya2VyCgBFcnJvciByZWFkaW5nIE1DQyBtYXJrZXIKAE5vdCBlbm91Z2ggbWVtb3J5IHRvIHJlYWQgTUNDIG1hcmtlcgoAcmVxdWlyZWQgU0laIG1hcmtlciBub3QgZm91bmQgaW4gbWFpbiBoZWFkZXIKAHJlcXVpcmVkIENPRCBtYXJrZXIgbm90IGZvdW5kIGluIG1haW4gaGVhZGVyCgByZXF1aXJlZCBRQ0QgbWFya2VyIG5vdCBmb3VuZCBpbiBtYWluIGhlYWRlcgoATm90IGVub3VnaCBtZW1vcnkgdG8gaGFuZGxlIGpwZWcyMDAwIGZpbGUgaGVhZGVyCgBOb3QgZW5vdWdoIG1lbW9yeSB0byByZWFkIGhlYWRlcgoARXJyb3Igd2l0aCBKUCBTaWduYXR1cmUgOiBiYWQgbWFnaWMgbnVtYmVyCgBJbiBTT1QgbWFya2VyLCBUUFNvdCAoJWQpIGlzIG5vdCB2YWxpZCByZWdhcmRzIHRvIHRoZSBjdXJyZW50IG51bWJlciBvZiB0aWxlLXBhcnQgKCVkKSwgZ2l2aW5nIHVwCgBJbiBTT1QgbWFya2VyLCBUUFNvdCAoJWQpIGlzIG5vdCB2YWxpZCByZWdhcmRzIHRvIHRoZSBwcmV2aW91cyBudW1iZXIgb2YgdGlsZS1wYXJ0ICglZCksIGdpdmluZyB1cAoASW4gU09UIG1hcmtlciwgVFBTb3QgKCVkKSBpcyBub3QgdmFsaWQgcmVnYXJkcyB0byB0aGUgY3VycmVudCBudW1iZXIgb2YgdGlsZS1wYXJ0IChoZWFkZXIpICglZCksIGdpdmluZyB1cAoAdGlsZXMgcmVxdWlyZSBhdCBsZWFzdCBvbmUgcmVzb2x1dGlvbgoATWFya2VyIGlzIG5vdCBjb21wbGlhbnQgd2l0aCBpdHMgcG9zaXRpb24KAFByb2JsZW0gd2l0aCBzZWVrIGZ1bmN0aW9uCgBFcnJvciByZWFkaW5nIFNQQ29kIFNQQ29jIGVsZW1lbnQsIEludmFsaWQgY2Jsa3cvY2Jsa2ggY29tYmluYXRpb24KAEludmFsaWQgbXVsdGlwbGUgY29tcG9uZW50IHRyYW5zZm9ybWF0aW9uCgBDYW5ub3QgdGFrZSBpbiBjaGFyZ2UgY29sbGVjdGlvbnMgb3RoZXIgdGhhbiBhcnJheSBkZWNvcnJlbGF0aW9uCgBUb28gbGFyZ2UgdmFsdWUgZm9yIE5wcG0KAE5vdCBlbm91Z2ggYnl0ZXMgdG8gcmVhZCBOcHBtCgBiYWQgcGxhY2VkIGpwZWcgY29kZXN0cmVhbQoACSBNYWluIGhlYWRlciBzdGFydCBwb3NpdGlvbj0lbGxpCgkgTWFpbiBoZWFkZXIgZW5kIHBvc2l0aW9uPSVsbGkKAE1hcmtlciBzaXplIGluY29uc2lzdGVudCB3aXRoIHN0cmVhbSBsZW5ndGgKAFRpbGUgcGFydCBsZW5ndGggc2l6ZSBpbmNvbnNpc3RlbnQgd2l0aCBzdHJlYW0gbGVuZ3RoCgBDYW5ub3QgdGFrZSBpbiBjaGFyZ2UgbXVsdGlwbGUgZGF0YSBzcGFubmluZwoAV3JvbmcgZmxhZwoARXJyb3Igd2l0aCBGVFlQIHNpZ25hdHVyZSBCb3ggc2l6ZQoARXJyb3Igd2l0aCBKUCBzaWduYXR1cmUgQm94IHNpemUKAEludmFsaWQgcHJlY2luY3Qgc2l6ZQoASW5jb25zaXN0ZW50IG1hcmtlciBzaXplCgBJbnZhbGlkIG1hcmtlciBzaXplCgBFcnJvciB3aXRoIFNJWiBtYXJrZXIgc2l6ZQoATm90IGVub3VnaCBtZW1vcnkgdG8gYWRkIGEgbmV3IHZhbGlkYXRpb24gcHJvY2VkdXJlCgBOb3QgZW5vdWdoIG1lbW9yeSB0byBkZWNvZGUgdGlsZQoARmFpbGVkIHRvIGRlY29kZSB0aGUgY29kZXN0cmVhbSBpbiB0aGUgSlAyIGZpbGUKAENhbm5vdCB0YWtlIGluIGNoYXJnZSBjb2xsZWN0aW9ucyB3aXRoIGluZGl4IHNodWZmbGUKAENhbm5vdCBhbGxvY2F0ZSBUaWVyIDEgaGFuZGxlCgBObyBkZWNvZGVkIGFyZWEgcGFyYW1ldGVycywgc2V0IHRoZSBkZWNvZGVkIGFyZWEgdG8gdGhlIHdob2xlIGltYWdlCgBOb3QgZW5vdWdoIG1lbW9yeSB0byBjcmVhdGUgVGFnLXRyZWUKAE5vdCBlbm91Z2ggbWVtb3J5IHRvIHJlaW5pdGlhbGl6ZSB0aGUgdGFnIHRyZWUKAEVycm9yIHJlYWRpbmcgU1BDb2QgU1BDb2MgZWxlbWVudCwgSW52YWxpZCB0cmFuc2Zvcm1hdGlvbiBmb3VuZAoARXJyb3IgcmVhZGluZyBTUENvZCBTUENvYyBlbGVtZW50LiBVbnN1cHBvcnRlZCBNaXhlZCBIVCBjb2RlLWJsb2NrIHN0eWxlIGZvdW5kCgBUaWxlIFkgY29vcmRpbmF0ZXMgYXJlIG5vdCBzdXBwb3J0ZWQKAFRpbGUgWCBjb29yZGluYXRlcyBhcmUgbm90IHN1cHBvcnRlZAoASW1hZ2UgY29vcmRpbmF0ZXMgYWJvdmUgSU5UX01BWCBhcmUgbm90IHN1cHBvcnRlZAoASlBFRzIwMDAgSGVhZGVyIGJveCBub3QgcmVhZCB5ZXQsICclYyVjJWMlYycgYm94IHdpbGwgYmUgaWdub3JlZAoAb3BqX2oya19tZXJnZV9wcHQoKSBoYXMgYWxyZWFkeSBiZWVuIGNhbGxlZAoATm90IGVub3VnaCBtZW1vcnkgdG8gcmVhZCBTT1QgbWFya2VyLiBUaWxlIGluZGV4IGFsbG9jYXRpb24gZmFpbGVkCgBJZ25vcmluZyBpaGRyIGJveC4gRmlyc3QgaWhkciBib3ggYWxyZWFkeSByZWFkCgBacHB0ICV1IGFscmVhZHkgcmVhZAoAWnBwbSAldSBhbHJlYWR5IHJlYWQKAFBURVJNIGNoZWNrIGZhaWx1cmU6ICVkIHN5bnRoZXRpemVkIDB4RkYgbWFya2VycyByZWFkCgAJCQkgY2Jsa3c9Ml4lZAoACQkJIGNibGtoPTJeJWQKAAkJCSBxbnRzdHk9JWQKACVzIGR4PSVkLCBkeT0lZAoACQkJIHJvaXNoaWZ0PSVkCgAJCQkgbnVtZ2JpdHM9JWQKAAkJIG51bWxheWVycz0lZAoAJXMgbnVtY29tcHM9JWQKAG9wal9qcDJfYXBwbHlfY2RlZjogYWNuPSVkLCBudW1jb21wcz0lZAoAb3BqX2pwMl9hcHBseV9jZGVmOiBjbj0lZCwgbnVtY29tcHM9JWQKAAkJCSBudW1yZXNvbHV0aW9ucz0lZAoACQkgdHlwZT0lI3gsIHBvcz0lbGxpLCBsZW49JWQKACVzIHNnbmQ9JWQKAAkJCSBxbWZiaWQ9JWQKACVzIHByZWM9JWQKAAkJIG5iIG9mIHRpbGUtcGFydCBpbiB0aWxlIFslZF09JWQKACVzIHgxPSVkLCB5MT0lZAoAJXMgeDA9JWQsIHkwPSVkCgBGYWlsZWQgdG8gZGVjb2RlIHRpbGUgJWQvJWQKAFNldHRpbmcgZGVjb2RpbmcgYXJlYSB0byAlZCwlZCwlZCwlZAoARmFpbGVkIHRvIGRlY29kZSBjb21wb25lbnQgJWQKAEludmFsaWQgdmFsdWUgZm9yIG51bXJlc29sdXRpb25zIDogJWQsIG1heCB2YWx1ZSBpcyBzZXQgaW4gb3BlbmpwZWcuaCBhdCAlZAoASW52YWxpZCBjb21wb25lbnQgbnVtYmVyOiAlZCwgcmVnYXJkaW5nIHRoZSBudW1iZXIgb2YgY29tcG9uZW50cyAlZAoAVG9vIG1hbnkgUE9DcyAlZAoASW52YWxpZCB0aWxlIG51bWJlciAlZAoASW52YWxpZCB0aWxlIHBhcnQgaW5kZXggZm9yIHRpbGUgbnVtYmVyICVkLiBHb3QgJWQsIGV4cGVjdGVkICVkCgBFcnJvciB3aXRoIFNJWiBtYXJrZXI6IG51bWJlciBvZiBjb21wb25lbnQgaXMgaWxsZWdhbCAtPiAlZAoATm90IGVub3VnaCBtZW1vcnkgZm9yIGNpZWxhYgoAQ2Fubm90IGFsbG9jYXRlIGNibGstPmRlY29kZWRfZGF0YQoARmFpbGVkIHRvIG1lcmdlIFBQVCBkYXRhCgBGYWlsZWQgdG8gbWVyZ2UgUFBNIGRhdGEKAEludmFsaWQgbnVtYmVyIG9mIGxheWVycyBpbiBDT0QgbWFya2VyIDogJWQgbm90IGluIHJhbmdlIFsxLTY1NTM1XQoAU3RyZWFtIHRvbyBzaG9ydCwgZXhwZWN0ZWQgU09UCgBVbmFibGUgdG8gc2V0IHQxIGhhbmRsZSBhcyBUTFMKAFN0cmVhbSBkb2VzIG5vdCBlbmQgd2l0aCBFT0MKAENhbm5vdCBoYW5kbGUgYm94IHNpemVzIGhpZ2hlciB0aGFuIDJeMzIKAG9wal9waV9uZXh0X2xyY3AoKTogaW52YWxpZCBjb21wbm8wL2NvbXBubzEKAG9wal9waV9uZXh0X3JsY3AoKTogaW52YWxpZCBjb21wbm8wL2NvbXBubzEKAG9wal9waV9uZXh0X2NwcmwoKTogaW52YWxpZCBjb21wbm8wL2NvbXBubzEKAG9wal9waV9uZXh0X3BjcmwoKTogaW52YWxpZCBjb21wbm8wL2NvbXBubzEKAG9wal9waV9uZXh0X3JwY2woKTogaW52YWxpZCBjb21wbm8wL2NvbXBubzEKAG9wal90MV9kZWNvZGVfY2JsaygpOiB1bnN1cHBvcnRlZCBicG5vX3BsdXNfb25lID0gJWQgPj0gMzEKAEZhaWxlZCB0byBkZWNvZGUgdGlsZSAxLzEKAEluc3VmZmljaWVudCBkYXRhIGZvciBDTUFQIGJveC4KAE5lZWQgdG8gcmVhZCBhIFBDTFIgYm94IGJlZm9yZSB0aGUgQ01BUCBib3guCgBJbnN1ZmZpY2llbnQgZGF0YSBmb3IgQ0RFRiBib3guCgBOdW1iZXIgb2YgY2hhbm5lbCBkZXNjcmlwdGlvbiBpcyBlcXVhbCB0byB6ZXJvIGluIENERUYgYm94LgoAU3RyZWFtIGVycm9yIHdoaWxlIHJlYWRpbmcgSlAyIEhlYWRlciBib3g6IG5vICdpaGRyJyBib3guCgBOb24gY29uZm9ybWFudCBjb2Rlc3RyZWFtIFRQc290PT1UTnNvdC4KAFN0cmVhbSBlcnJvciB3aGlsZSByZWFkaW5nIEpQMiBIZWFkZXIgYm94OiBib3ggbGVuZ3RoIGlzIGluY29uc2lzdGVudC4KAEJveCBsZW5ndGggaXMgaW5jb25zaXN0ZW50LgoAUmVzb2x1dGlvbiBmYWN0b3IgaXMgZ3JlYXRlciB0aGFuIHRoZSBtYXhpbXVtIHJlc29sdXRpb24gaW4gdGhlIGNvbXBvbmVudC4KAENvbXBvbmVudCBtYXBwaW5nIHNlZW1zIHdyb25nLiBUcnlpbmcgdG8gY29ycmVjdC4KAEluY29tcGxldGUgY2hhbm5lbCBkZWZpbml0aW9ucy4KAE1hbGZvcm1lZCBIVCBjb2RlYmxvY2suIEludmFsaWQgY29kZWJsb2NrIGxlbmd0aCB2YWx1ZXMuCgBXZSBkbyBub3Qgc3VwcG9ydCBtb3JlIHRoYW4gMyBjb2RpbmcgcGFzc2VzIGluIGFuIEhUIGNvZGVibG9jazsgVGhpcyBjb2RlYmxvY2tzIGhhcyAlZCBwYXNzZXMuCgBNYWxmb3JtZWQgSFQgY29kZWJsb2NrLiBEZWNvZGluZyB0aGlzIGNvZGVibG9jayBpcyBzdG9wcGVkLiBUaGVyZSBhcmUgJWQgemVybyBiaXRwbGFuZXMgaW4gJWQgYml0cGxhbmVzLgoAQ2Fubm90IHRha2UgaW4gY2hhcmdlIG11bHRpcGxlIHRyYW5zZm9ybWF0aW9uIHN0YWdlcy4KAFVua25vd24gbWFya2VyIGhhcyBiZWVuIGRldGVjdGVkIGFuZCBnZW5lcmF0ZWQgZXJyb3IuCgBDb2RlYyBwcm92aWRlZCB0byB0aGUgb3BqX3NldF9kZWNvZGVkX2NvbXBvbmVudHMgZnVuY3Rpb24gaXMgbm90IGEgZGVjb21wcmVzc29yIGhhbmRsZXIuCgBDb2RlYyBwcm92aWRlZCB0byB0aGUgb3BqX3NldHVwX2RlY29kZXIgZnVuY3Rpb24gaXMgbm90IGEgZGVjb21wcmVzc29yIGhhbmRsZXIuCgBDb2RlYyBwcm92aWRlZCB0byB0aGUgb3BqX3JlYWRfaGVhZGVyIGZ1bmN0aW9uIGlzIG5vdCBhIGRlY29tcHJlc3NvciBoYW5kbGVyLgoAVGlsZXMgZG9uJ3QgYWxsIGhhdmUgdGhlIHNhbWUgZGltZW5zaW9uLiBTa2lwIHRoZSBNQ1Qgc3RlcC4KAE51bWJlciBvZiBjb21wb25lbnRzICglZCkgaXMgaW5jb25zaXN0ZW50IHdpdGggYSBNQ1QuIFNraXAgdGhlIE1DVCBzdGVwLgoASlAyIGJveCB3aGljaCBhcmUgYWZ0ZXIgdGhlIGNvZGVzdHJlYW0gd2lsbCBub3QgYmUgcmVhZCBieSB0aGlzIGZ1bmN0aW9uLgoATWFsZm9ybWVkIEhUIGNvZGVibG9jay4gV2hlbiB0aGUgbnVtYmVyIG9mIHplcm8gcGxhbmVzIGJpdHBsYW5lcyBpcyBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIGJpdHBsYW5lcywgb25seSB0aGUgY2xlYW51cCBwYXNzIG1ha2VzIHNlbnNlLCBidXQgd2UgaGF2ZSAlZCBwYXNzZXMgaW4gdGhpcyBjb2RlYmxvY2suIFRoZXJlZm9yZSwgb25seSB0aGUgY2xlYW51cCBwYXNzIHdpbGwgYmUgZGVjb2RlZC4gVGhpcyBtZXNzYWdlIHdpbGwgbm90IGJlIGRpc3BsYXllZCBhZ2Fpbi4KAEltYWdlIGhhcyBsZXNzIGNvbXBvbmVudHMgdGhhbiBjb2Rlc3RyZWFtLgoATmVlZCB0byBkZWNvZGUgdGhlIG1haW4gaGVhZGVyIGJlZm9yZSBiZWdpbiB0byBkZWNvZGUgdGhlIHJlbWFpbmluZyBjb2Rlc3RyZWFtLgoAUHNvdCB2YWx1ZSBvZiB0aGUgY3VycmVudCB0aWxlLXBhcnQgaXMgZXF1YWwgdG8gemVybywgd2UgYXNzdW1pbmcgaXQgaXMgdGhlIGxhc3QgdGlsZS1wYXJ0IG9mIHRoZSBjb2Rlc3RyZWFtLgoAQSBtYWxmb3JtZWQgY29kZWJsb2NrIHRoYXQgaGFzIG1vcmUgdGhhbiBvbmUgY29kaW5nIHBhc3MsIGJ1dCB6ZXJvIGxlbmd0aCBmb3IgMm5kIGFuZCBwb3RlbnRpYWxseSB0aGUgM3JkIHBhc3MgaW4gYW4gSFQgY29kZWJsb2NrLgoACQkJIHRpbGUtcGFydFslZF06IHN0YXJfcG9zPSVsbGksIGVuZF9oZWFkZXI9JWxsaSwgZW5kX3Bvcz0lbGxpLgoAVGlsZSAldSBoYXMgVFBzb3QgPT0gMCBhbmQgVE5zb3QgPT0gMCwgYnV0IG5vIG90aGVyIHRpbGUtcGFydHMgd2VyZSBmb3VuZC4gRU9DIGlzIGFsc28gbWlzc2luZy4KAENvbXBvbmVudCAlZCBkb2Vzbid0IGhhdmUgYSBtYXBwaW5nLgoAQSBjb25mb3JtaW5nIEpQMiByZWFkZXIgc2hhbGwgaWdub3JlIGFsbCBDb2xvdXIgU3BlY2lmaWNhdGlvbiBib3hlcyBhZnRlciB0aGUgZmlyc3QsIHNvIHdlIGlnbm9yZSB0aGlzIG9uZS4KAFRoZSBzaWduYXR1cmUgYm94IG11c3QgYmUgdGhlIGZpcnN0IGJveCBpbiB0aGUgZmlsZS4KAFRoZSAgYm94IG11c3QgYmUgdGhlIGZpcnN0IGJveCBpbiB0aGUgZmlsZS4KAFRoZSBmdHlwIGJveCBtdXN0IGJlIHRoZSBzZWNvbmQgYm94IGluIHRoZSBmaWxlLgoARmFpbGVkIHRvIGRlY29kZS4KAE1hbGZvcm1lZCBIVCBjb2RlYmxvY2suIEluY29ycmVjdCBNRUwgc2VnbWVudCBzZXF1ZW5jZS4KAENvbXBvbmVudCAlZCBpcyBtYXBwZWQgdHdpY2UuCgBPbmx5IG9uZSBDTUFQIGJveCBpcyBhbGxvd2VkLgoAYXBwbHlfY29sb3JfdHJhbnNmb3JtcyA9IE9QSl9UUlVFIGlzIG5vdCBzdXBwb3J0ZWQuCgBXZSBuZWVkIGFuIGltYWdlIHByZXZpb3VzbHkgY3JlYXRlZC4KAElIRFIgYm94X21pc3NpbmcuIFJlcXVpcmVkLgoASlAySCBib3ggbWlzc2luZy4gUmVxdWlyZWQuCgBOb3Qgc3VyZSBob3cgdGhhdCBoYXBwZW5lZC4KAE1haW4gaGVhZGVyIGhhcyBiZWVuIGNvcnJlY3RseSBkZWNvZGVkLgoAVGlsZSAlZC8lZCBoYXMgYmVlbiBkZWNvZGVkLgoASGVhZGVyIG9mIHRpbGUgJWQgLyAlZCBoYXMgYmVlbiByZWFkLgoARW1wdHkgU09UIG1hcmtlciBkZXRlY3RlZDogUHNvdD0lZC4KAERpcmVjdCB1c2UgYXQgIyVkIGhvd2V2ZXIgcGNvbD0lZC4KAEltcGxlbWVudGF0aW9uIGxpbWl0YXRpb246IGZvciBwYWxldHRlIG1hcHBpbmcsIHBjb2xbJWRdIHNob3VsZCBiZSBlcXVhbCB0byAlZCwgYnV0IGlzIGVxdWFsIHRvICVkLgoASW52YWxpZCBjb21wb25lbnQvcGFsZXR0ZSBpbmRleCBmb3IgZGlyZWN0IG1hcHBpbmcgJWQuCgBJbnZhbGlkIHZhbHVlIGZvciBjbWFwWyVkXS5tdHlwID0gJWQuCgBQc290IHZhbHVlIGlzIG5vdCBjb3JyZWN0IHJlZ2FyZHMgdG8gdGhlIEpQRUcyMDAwIG5vcm06ICVkLgoATWFsZm9ybWVkIEhUIGNvZGVibG9jay4gVkxDIGNvZGUgcHJvZHVjZXMgc2lnbmlmaWNhbnQgc2FtcGxlcyBvdXRzaWRlIHRoZSBjb2RlYmxvY2sgYXJlYS4KAFVuZXhwZWN0ZWQgT09NLgoAMzIgYml0cyBhcmUgbm90IGVub3VnaCB0byBkZWNvZGUgdGhpcyBjb2RlYmxvY2ssIHNpbmNlIHRoZSBudW1iZXIgb2YgYml0cGxhbmUsICVkLCBpcyBsYXJnZXIgdGhhbiAzMC4KAEJvdHRvbSBwb3NpdGlvbiBvZiB0aGUgZGVjb2RlZCBhcmVhIChyZWdpb25feTE9JWQpIHNob3VsZCBiZSA+IDAuCgBSaWdodCBwb3NpdGlvbiBvZiB0aGUgZGVjb2RlZCBhcmVhIChyZWdpb25feDE9JWQpIHNob3VsZCBiZSA+IDAuCgBVcCBwb3NpdGlvbiBvZiB0aGUgZGVjb2RlZCBhcmVhIChyZWdpb25feTA9JWQpIHNob3VsZCBiZSA+PSAwLgoATGVmdCBwb3NpdGlvbiBvZiB0aGUgZGVjb2RlZCBhcmVhIChyZWdpb25feDA9JWQpIHNob3VsZCBiZSA+PSAwLgoARXJyb3IgcmVhZGluZyBQUFQgbWFya2VyOiBwYWNrZXQgaGVhZGVyIGhhdmUgYmVlbiBwcmV2aW91c2x5IGZvdW5kIGluIHRoZSBtYWluIGhlYWRlciAoUFBNIG1hcmtlcikuCgBTdGFydCB0byByZWFkIGoyayBtYWluIGhlYWRlciAoJWxsZCkuCgBCb3R0b20gcG9zaXRpb24gb2YgdGhlIGRlY29kZWQgYXJlYSAocmVnaW9uX3kxPSVkKSBpcyBvdXRzaWRlIHRoZSBpbWFnZSBhcmVhIChZc2l6PSVkKS4KAFVwIHBvc2l0aW9uIG9mIHRoZSBkZWNvZGVkIGFyZWEgKHJlZ2lvbl95MD0lZCkgaXMgb3V0c2lkZSB0aGUgaW1hZ2UgYXJlYSAoWXNpej0lZCkuCgBSaWdodCBwb3NpdGlvbiBvZiB0aGUgZGVjb2RlZCBhcmVhIChyZWdpb25feDE9JWQpIGlzIG91dHNpZGUgdGhlIGltYWdlIGFyZWEgKFhzaXo9JWQpLgoATGVmdCBwb3NpdGlvbiBvZiB0aGUgZGVjb2RlZCBhcmVhIChyZWdpb25feDA9JWQpIGlzIG91dHNpZGUgdGhlIGltYWdlIGFyZWEgKFhzaXo9JWQpLgoAQm90dG9tIHBvc2l0aW9uIG9mIHRoZSBkZWNvZGVkIGFyZWEgKHJlZ2lvbl95MT0lZCkgaXMgb3V0c2lkZSB0aGUgaW1hZ2UgYXJlYSAoWU9zaXo9JWQpLgoAVXAgcG9zaXRpb24gb2YgdGhlIGRlY29kZWQgYXJlYSAocmVnaW9uX3kwPSVkKSBpcyBvdXRzaWRlIHRoZSBpbWFnZSBhcmVhIChZT3Npej0lZCkuCgBSaWdodCBwb3NpdGlvbiBvZiB0aGUgZGVjb2RlZCBhcmVhIChyZWdpb25feDE9JWQpIGlzIG91dHNpZGUgdGhlIGltYWdlIGFyZWEgKFhPc2l6PSVkKS4KAExlZnQgcG9zaXRpb24gb2YgdGhlIGRlY29kZWQgYXJlYSAocmVnaW9uX3gwPSVkKSBpcyBvdXRzaWRlIHRoZSBpbWFnZSBhcmVhIChYT3Npej0lZCkuCgBTaXplIHggb2YgdGhlIGRlY29kZWQgY29tcG9uZW50IGltYWdlIGlzIGluY29ycmVjdCAoY29tcFslZF0udz0lZCkuCgBTaXplIHkgb2YgdGhlIGRlY29kZWQgY29tcG9uZW50IGltYWdlIGlzIGluY29ycmVjdCAoY29tcFslZF0uaD0lZCkuCgBUaWxlIHJlYWQsIGRlY29kZWQgYW5kIHVwZGF0ZWQgaXMgbm90IHRoZSBkZXNpcmVkIG9uZSAoJWQgdnMgJWQpLgoASW52YWxpZCBjb21wb25lbnQgaW5kZXggJWQgKD49ICVkKS4KAG9wal9yZWFkX2hlYWRlcigpIHNob3VsZCBiZSBjYWxsZWQgYmVmb3JlIG9wal9zZXRfZGVjb2RlZF9jb21wb25lbnRzKCkuCgBNZW1vcnkgYWxsb2NhdGlvbiBmYWlsdXJlIGluIG9wal9qcDJfYXBwbHlfcGNscigpLgoAaW1hZ2UtPmNvbXBzWyVkXS5kYXRhID09IE5VTEwgaW4gb3BqX2pwMl9hcHBseV9wY2xyKCkuCgBpbnZhbGlkIGJveCBzaXplICVkICgleCkKAEZhaWwgdG8gcmVhZCB0aGUgY3VycmVudCBtYXJrZXIgc2VnbWVudCAoJSN4KQoARXJyb3Igd2l0aCBTSVogbWFya2VyOiBJSERSIHcoJXUpIGgoJXUpIHZzLiBTSVogdygldSkgaCgldSkKAEVycm9yIHJlYWRpbmcgQ09DIG1hcmtlciAoYmFkIG51bWJlciBvZiBjb21wb25lbnRzKQoASW52YWxpZCBudW1iZXIgb2YgdGlsZXMgOiAldSB4ICV1IChtYXhpbXVtIGZpeGVkIGJ5IGpwZWcyMDAwIG5vcm0gaXMgNjU1MzUgdGlsZXMpCgBJbnZhbGlkIG51bWJlciBvZiBjb21wb25lbnRzIChpaGRyKQoATm90IGVub3VnaCBtZW1vcnkgdG8gaGFuZGxlIGltYWdlIGhlYWRlciAoaWhkcikKAFdyb25nIHZhbHVlcyBmb3I6IHcoJWQpIGgoJWQpIG51bWNvbXBzKCVkKSAoaWhkcikKAEludmFsaWQgdmFsdWVzIGZvciBjb21wID0gJWQgOiBkeD0ldSBkeT0ldSAoc2hvdWxkIGJlIGJldHdlZW4gMSBhbmQgMjU1IGFjY29yZGluZyB0byB0aGUgSlBFRzIwMDAgbm9ybSkKAEJhZCBpbWFnZSBoZWFkZXIgYm94IChiYWQgc2l6ZSkKAEJhZCBDT0xSIGhlYWRlciBib3ggKGJhZCBzaXplKQoAQmFkIEJQQ0MgaGVhZGVyIGJveCAoYmFkIHNpemUpCgBFcnJvciB3aXRoIFNJWiBtYXJrZXI6IG5lZ2F0aXZlIG9yIHplcm8gaW1hZ2Ugc2l6ZSAoJWxsZCB4ICVsbGQpCgBza2lwOiBzZWdtZW50IHRvbyBsb25nICglZCkgd2l0aCBtYXggKCVkKSBmb3IgY29kZWJsb2NrICVkIChwPSVkLCBiPSVkLCByPSVkLCBjPSVkKQoAcmVhZDogc2VnbWVudCB0b28gbG9uZyAoJWQpIHdpdGggbWF4ICglZCkgZm9yIGNvZGVibG9jayAlZCAocD0lZCwgYj0lZCwgcj0lZCwgYz0lZCkKAERlc3BpdGUgSlAyIEJQQyE9MjU1LCBwcmVjaXNpb24gYW5kL29yIHNnbmQgdmFsdWVzIGZvciBjb21wWyVkXSBpcyBkaWZmZXJlbnQgdGhhbiBjb21wWzBdOgogICAgICAgIFswXSBwcmVjKCVkKSBzZ25kKCVkKSBbJWRdIHByZWMoJWQpIHNnbmQoJWQpCgBiYWQgY29tcG9uZW50IG51bWJlciBpbiBSR04gKCVkIHdoZW4gdGhlcmUgYXJlIG9ubHkgJWQpCgBFcnJvciB3aXRoIFNJWiBtYXJrZXI6IG51bWJlciBvZiBjb21wb25lbnQgaXMgbm90IGNvbXBhdGlibGUgd2l0aCB0aGUgcmVtYWluaW5nIG51bWJlciBvZiBwYXJhbWV0ZXJzICggJWQgdnMgJWQpCgBFcnJvciB3aXRoIFNJWiBtYXJrZXI6IGludmFsaWQgdGlsZSBzaXplICh0ZHg6ICVkLCB0ZHk6ICVkKQoAQmFkIENPTFIgaGVhZGVyIGJveCAoYmFkIHNpemU6ICVkKQoAQmFkIENPTFIgaGVhZGVyIGJveCAoQ0lFTGFiLCBiYWQgc2l6ZTogJWQpCgBQVEVSTSBjaGVjayBmYWlsdXJlOiAlZCByZW1haW5pbmcgYnl0ZXMgaW4gY29kZSBibG9jayAoJWQgdXNlZCAvICVkKQoATWFsZm9ybWVkIEhUIGNvZGVibG9jay4gT25lIG9mIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uIGlzIG5vdCBtZXQ6IDIgPD0gU2N1cCA8PSBtaW4oTGN1cCwgNDA3OSkKAEludmFsaWQgdmFsdWVzIGZvciBjb21wID0gJWQgOiBwcmVjPSV1IChzaG91bGQgYmUgYmV0d2VlbiAxIGFuZCAzOCBhY2NvcmRpbmcgdG8gdGhlIEpQRUcyMDAwIG5vcm0uIE9wZW5KcGVnIG9ubHkgc3VwcG9ydHMgdXAgdG8gMzEpCgBJbnZhbGlkIGJpdCBudW1iZXIgJWQgaW4gb3BqX3QyX3JlYWRfcGFja2V0X2hlYWRlcigpCgBTdHJlYW0gZXJyb3IhCgBFcnJvciBvbiB3cml0aW5nIHN0cmVhbSEKAFN0cmVhbSByZWFjaGVkIGl0cyBlbmQgIQoARXhwZWN0ZWQgYSBTT0MgbWFya2VyIAoASW52YWxpZCBib3ggc2l6ZSAlZCBmb3IgYm94ICclYyVjJWMlYycuIE5lZWQgJWQgYnl0ZXMsICVkIGJ5dGVzIHJlbWFpbmluZyAKAE1hbGZvcm1lZCBIVCBjb2RlYmxvY2suIERlY29kaW5nIHRoaXMgY29kZWJsb2NrIGlzIHN0b3BwZWQuIFVfcSBpcyBsYXJnZXIgdGhhbiB6ZXJvIGJpdHBsYW5lcyArIDEgCgBNYWxmb3JtZWQgSFQgY29kZWJsb2NrLiBEZWNvZGluZyB0aGlzIGNvZGVibG9jayBpcyBzdG9wcGVkLiBVX3EgaXNsYXJnZXIgdGhhbiBiaXRwbGFuZXMgKyAxIAoAQ09MUiBCT1ggbWV0aCB2YWx1ZSBpcyBub3QgYSByZWd1bGFyIHZhbHVlICglZCksIHNvIHdlIHdpbGwgaWdub3JlIHRoZSBlbnRpcmUgQ29sb3VyIFNwZWNpZmljYXRpb24gYm94LiAKAFdoaWxlIHJlYWRpbmcgQ0NQX1FOVFNUWSBlbGVtZW50IGluc2lkZSBRQ0Qgb3IgUUNDIG1hcmtlciBzZWdtZW50LCBudW1iZXIgb2Ygc3ViYmFuZHMgKCVkKSBpcyBncmVhdGVyIHRvIE9QSl9KMktfTUFYQkFORFMgKCVkKS4gU28gd2UgbGltaXQgdGhlIG51bWJlciBvZiBlbGVtZW50cyBzdG9yZWQgdG8gT1BKX0oyS19NQVhCQU5EUyAoJWQpIGFuZCBza2lwIHRoZSByZXN0LiAKAEpQMiBJSERSIGJveDogY29tcHJlc3Npb24gdHlwZSBpbmRpY2F0ZSB0aGF0IHRoZSBmaWxlIGlzIG5vdCBhIGNvbmZvcm1pbmcgSlAyIGZpbGUgKCVkKSAKAFRpbGUgaW5kZXggcHJvdmlkZWQgYnkgdGhlIHVzZXIgaXMgaW5jb3JyZWN0ICVkIChtYXggPSAlZCkgCgBFcnJvciBkZWNvZGluZyBjb21wb25lbnQgJWQuClRoZSBudW1iZXIgb2YgcmVzb2x1dGlvbnMgdG8gcmVtb3ZlICglZCkgaXMgZ3JlYXRlciBvciBlcXVhbCB0aGFuIHRoZSBudW1iZXIgb2YgcmVzb2x1dGlvbnMgb2YgdGhpcyBjb21wb25lbnQg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AAABVAAAAQAAABBQAADQUAAAAUgAAAAAAAAgUAAAwFAAAAFIAAABAAAAMFAAANBQAAABOAAAAAAAAEBQAADAUAAAATgAAAEAAABQUAAA0FAAAAEwAAAAAAAAYFAAACBRAAABMAAAAQAAAHBQAAAwUQAAASQAAAAAAACAUAAAQFEAAAEkAAABAAAAkFAAAFBRAAABHAAAAAAAAKBQAACAUQAAARwAAAEAAACwUAAAkFEAAAEWAAAAAAAAoFIAAKBRAAABFgAAAQAAALBSAACwUQAAAVYAAAAAAADgUAAA0FAAAAFWAAABAAAA8FAAAMBQAAABVAAAAAAAAABRAADAUAAAAVQAAAEAAAAQUQAA0FAAAAFRAAAAAAAAIFEAAOBQAAABUQAAAQAAADBRAADwUAAAAUgAAAAAAABAUQAAAFEAAAFIAAABAAAAUFEAABBRAAABOAAAAAAAAGBRAAAgUQAAATgAAAEAAABwUQAAMFEAAAE0AAAAAAAAgFEAAEBRAAABNAAAAQAAAJBRAABQUQAAATAAAAAAAACgUQAAYFEAAAEwAAABAAAAsFEAAHBRAAABKAAAAAAAAMBRAABgUQAAASgAAAEAAADQUQAAcFEAAAEkAAAAAAAA4FEAAIBRAAABJAAAAQAAAPBRAACQUQAAASIAAAAAAAAAUgAAoFEAAAEiAAABAAAAEFIAALBRAAABHAAAAAAAACBSAADAUQAAARwAAAEAAAAwUgAA0FEAAAEYAAAAAAAAQFIAAOBRAAABGAAAAQAAAFBSAADwUQAAARYAAAAAAABgUgAAAFIAAAEWAAABAAAAcFIAABBSAAABFAAAAAAAAIBSAAAgUgAAARQAAAEAAACQUgAAMFIAAAESAAAAAAAAoFIAAEBSAAABEgAAAQAAALBSAABQUgAAAREAAAAAAADAUgAAYFIAAAERAAABAAAA0FIAAHBSAADBCgAAAAAAAOBSAACAUgAAwQoAAAEAAADwUgAAkFIAAMEJAAAAAAAAAFMAAKBSAADBCQAAAQAAABBTAACwUgAAoQgAAAAAAAAgUwAAwFIAAKEIAAABAAAAMFMAANBSAAAhBQAAAAAAAEBTAADgUgAAIQUAAAEAAABQUwAA8FIAAEEEAAAAAAAAYFMAAABTAABBBAAAAQAAAHBTAAAQUwAAoQIAAAAAAACAUwAAIFMAAKECAAABAAAAkFMAADBTAAAhAgAAAAAAAKBTAABAUwAAIQIAAAEAAACwUwAAUFMAAEEBAAAAAAAAwFMAAGBTAABBAQAAAQAAANBTAABwUwAAEQEAAAAAAADgUwAAgFMAABEBAAABAAAA8FMAAJBTAACFAAAAAAAAAABUAACgUwAAhQAAAAEAAAAQVAAAsFMAAEkAAAAAAAAAIFQAAMBTAABJAAAAAQAAADBUAADQUwAAJQAAAAAAAABAVAAA4FMAACUAAAABAAAAUFQAAPBTAAAVAAAAAAAAAGBUAAAAVAAAFQAAAAEAAABwVAAAEFQAAAkAAAAAAAAAgFQAACBUAAAJAAAAAQAAAJBUAAAwVAAABQAAAAAAAACgVAAAQFQAAAUAAAABAAAAsFQAAFBUAAABAAAAAAAAAKBUAABgVAAAAQAAAAEAAACwVAAAcFQAAAFWAAAAAAAAwFQAAMBUAAABVgAAAQAAANBUAADQVAAAAAEDAwECAwMFBgcHBgYHBwABAwMBAgMDBQYHBwYGBwcFBgcHBgYHBwgICAgICAgIBQYHBwYGBwcICAgICAgICAECAwMCAgMDBgYHBwYGBwcBAgMDAgIDAwYGBwcGBgcHBgYHBwYGBwcICAgICAgICAYGBwcGBgcHCAgICAgICAgDAwQEAwMEBAcHBwcHBwcHAwMEBAMDBAQHBwcHBwcHBwcHBwcHBwcHCAgICAgICAgHBwcHBwcHBwgICAgICAgIAwMEBAMDBAQHBwcHBwcHBwMDBAQDAwQEBwcHBwcHBwcHBwcHBwcHBwgICAgICAgIBwcHBwcHBwcICAgICAgICAECAwMCAgMDBgYHBwYGBwcBAgMDAgIDAwYGBwcGBgcHBgYHBwYGBwcICAgICAgICAYGBwcGBgcHCAgICAgICAgCAgMDAgIDAwYGBwcGBgcHAgIDAwICAwMGBgcHBgYHBwYGBwcGBgcHCAgICAgICAgGBgcHBgYHBwgICAgICAgIAwMEBAMDBAQHBwcHBwcHBwMDBAQDAwQEBwcHBwcHBwcHBwcHBwcHBwgICAgICAgIBwcHBwcHBwcICAgICAgICAMDBAQDAwQEBwcHBwcHBwcDAwQEAwMEBAcHBwcHBwcHBwcHBwcHBwcICAgICAgICAcHBwcHBwcHCAgICAgICAgAAQUGAQIGBgMDBwcDAwcHAAEFBgECBgYDAwcHAwMHBwMDBwcDAwcHBAQHBwQEBwcDAwcHAwMHBwQEBwcEBAcHAQIGBgICBgYDAwcHAwMHBwECBgYCAgYGAwMHBwMDBwcDAwcHAwMHBwQEBwcEBAcHAwMHBwMDBwcEBAcHBAQHBwUGCAgGBggIBwcICAcHCAgFBggIBgYICAcHCAgHBwgIBwcICAcHCAgHBwgIBwcICAcHCAgHBwgIBwcICAcHCAgGBggIBgYICAcHCAgHBwgIBgYICAYGCAgHBwgIBwcICAcHCAgHBwgIBwcICAcHCAgHBwgIBwcICAcHCAgHBwgIAQIGBgICBgYDAwcHAwMHBwECBgYCAgYGAwMHBwMDBwcDAwcHAwMHBwQEBwcEBAcHAwMHBwMDBwcEBAcHBAQHBwICBgYCAgYGAwMHBwMDBwcCAgYGAgIGBgMDBwcDAwcHAwMHBwMDBwcEBAcHBAQHBwMDBwcDAwcHBAQHBwQEBwcGBggIBgYICAcHCAgHBwgIBgYICAYGCAgHBwgIBwcICAcHCAgHBwgIBwcICAcHCAgHBwgIBwcICAcHCAgHBwgIBgYICAYGCAgHBwgIBwcICAYGCAgGBggIBwcICAcHCAgHBwgIBwcICAcHCAgHBwgIBwcICAcHCAgHBwgIBwcICAABAwMBAgMDBQYHBwYGBwcAAQMDAQIDAwUGBwcGBgcHBQYHBwYGBwcICAgICAgICAUGBwcGBgcHCAgICAgICAgBAgMDAgIDAwYGBwcGBgcHAQIDAwICAwMGBgcHBgYHBwYGBwcGBgcHCAgICAgICAgGBgcHBgYHBwgICAgICAgIAwMEBAMDBAQHBwcHBwcHBwMDBAQDAwQEBwcHBwcHBwcHBwcHBwcHBwgICAgICAgIBwcHBwcHBwcICAgICAgICAMDBAQDAwQEBwcHBwcHBwcDAwQEAwMEBAcHBwcHBwcHBwcHBwcHBwcICAgICAgICAcHBwcHBwcHCAgICAgICAgBAgMDAgIDAwYGBwcGBgcHAQIDAwICAwMGBgcHBgYHBwYGBwcGBgcHCAgICAgICAgGBgcHBgYHBwgICAgICAgIAgIDAwICAwMGBgcHBgYHBwICAwMCAgMDBgYHBwYGBwcGBgcHBgYHBwgICAgICAgIBgYHBwYGBwcICAgICAgICAMDBAQDAwQEBwcHBwcHBwcDAwQEAwMEBAcHBwcHBwcHBwcHBwcHBwcICAgICAgICAcHBwcHBwcHCAgICAgICAgDAwQEAwMEBAcHBwcHBwcHAwMEBAMDBAQHBwcHBwcHBwcHBwcHBwcHCAgICAgICAgHBwcHBwcHBwgICAgICAgIAAMBBAMGBAcBBAIFBAcFBwADAQQDBgQHAQQCBQQHBQcBBAIFBAcFBwIFAgUFBwUHAQQCBQQHBQcCBQIFBQcFBwMGBAcGCAcIBAcFBwcIBwgDBgQHBggHCAQHBQcHCAcIBAcFBwcIBwgFBwUHBwgHCAQHBQcHCAcIBQcFBwcIBwgBBAIFBAcFBwIFAgUFBwUHAQQCBQQHBQcCBQIFBQcFBwIFAgUFBwUHAgUCBQUHBQcCBQIFBQcFBwIFAgUFBwUHBAcFBwcIBwgFBwUHBwgHCAQHBQcHCAcIBQcFBwcIBwgFBwUHBwgHCAUHBQcHCAcIBQcFBwcIBwgFBwUHBwgHCAMGBAcGCAcIBAcFBwcIBwgDBgQHBggHCAQHBQcHCAcIBAcFBwcIBwgFBwUHBwgHCAQHBQcHCAcIBQcFBwcIBwgGCAcICAgICAcIBwgICAgIBggHCAgICAgHCAcICAgICAcIBwgICAgIBwgHCAgICAgHCAcICAgICAcIBwgICAgIBAcFBwcIBwgFBwUHBwgHCAQHBQcHCAcIBQcFBwcIBwgFBwUHBwgHCAUHBQcHCAcIBQcFBwcIBwgFBwUHBwgHCAcIBwgICAgIBwgHCAgICAgHCAcICAgICAcIBwgICAgIBwgHCAgICAgHCAcICAgICAcIBwgICAgIBwgHCAgICAgJCQoKCQkKCgwMDQsMDA0LCQkKCgkJCgoMDAsNDAwLDQwMDQ0MDAsLDAkNCgkMCgsMDAsLDAwNDQwJCwoJDAoNCQkKCgkJCgoMDA0LDAwNCwkJCgoJCQoKDAwLDQwMCw0MDA0NDAwLCwwJDQoJDAoLDAwLCwwMDQ0MCQsKCQwKDQoKCgoKCgoKDQsNCw0LDQsKCgkJCgoJCQ0LDAwNCwwMDQ0NDQsLCwsNCg0KCgsKCw0NDAwLCwwMDQoMCQoLCQwKCgkJCgoJCQsNDAwLDQwMCgoKCgoKCgoLDQsNCw0LDQsLDAwNDQwMCwoMCQoNCQwLCwsLDQ0NDQsKCwoKDQoNAEHpuwELNwEAAQABAAEAAAEBAAABAQABAAEAAQABAAAAAAEBAQEAAAAAAAEAAQAAAAABAQEBAAAAAQABAQEAQam8AQs3AQABAAEAAQAAAQEAAAEBAAEAAQABAAEAAAAAAQEBAQAAAAAAAQABAAAAAAEBAQEAAAABAAEBAQBB6bwBCwcBAAEAAQABAEH5vAELlQIBAAEAAQABAAAAAAEBAQEAAAAAAAEAAQAAAAABAQEBAAAAAAABAAEBAQAAAQEAAAABAAEAAQABAQEBAQEBAQEAAQABAAEAAQAAAAABAQEBAAEAAAEBAAEAAAAAAQEBAQABAAEBAQEBAgAAAAQAAAAEAAAACAAAAJD/AAAMAAAAGAAAAFL/AAAUAAAAGQAAAFP/AAAUAAAAGgAAAF7/AAAUAAAAGwAAAFz/AAAUAAAAHAAAAF3/AAAUAAAAHQAAAF//AAAUAAAAHgAAAFH/AAACAAAAHwAAAFX/AAAEAAAAIAAAAFf/AAAEAAAAIQAAAFj/AAAQAAAAIgAAAGD/AAAEAAAAIwAAAGH/AAAQAAAAJAAAAJH/AEGYvwELZWP/AAAEAAAAJQAAAGT/AAAUAAAAJgAAAHT/AAAUAAAAJwAAAHj/AAAEAAAAKAAAAFD/AAAEAAAAKQAAAFn/AAAEAAAAKgAAAHX/AAAUAAAAKwAAAHf/AAAUAAAALAAAAAAAAAAUAEGQwAELNS0AAAAuAAAALwAAADAAAAAxAAAAMgAAADMAAAA0AAAAICBQajYAAABweXRmNwAAAGgycGo4AEHQwAELMnJkaGk5AAAAcmxvYzoAAABjY3BiOwAAAHJsY3A8AAAAcGFtYz0AAABmZWRjPgAAAHhiAEGQwQELQRkACwAZGRkAAAAABQAAAAAAAAkAAAAACwAAAAAAAAAAGQAKChkZGQMKBwABAAkLGAAACQYLAAALAAYZAAAAGRkZAEHhwQELIQ4AAAAAAAAAABkACw0ZGRkADQAAAgAJDgAAAAkADgAADgBBm8IBCwEMAEGnwgELFRMAAAAAEwAAAAAJDAAAAAAADAAADABB1cIBCwEQAEHhwgELFQ8AAAAEDwAAAAAJEAAAAAAAEAAAEABBj8MBCwESAEGbwwELHhEAAAAAEQAAAAAJEgAAAAAAEgAAEgAAGgAAABoaGgBB0sMBCw4aAAAAGhoaAAAAAAAACQBBg8QBCwEUAEGPxAELFRcAAAAAFwAAAAAJFAAAAAAAFAAAFABBvcQBCwEWAEHJxAELJxUAAAAAFQAAAAAJFgAAAAAAFgAAFgAAMDEyMzQ1Njc4OUFCQ0RFRgBB8cQBCwhsAQAAAAAABQBBhMUBCwFpAEGcxQELDmoAAABrAAAA+GcAAAAEAEG0xQELAQEAQcTFAQsF/////wo=");return receiveInstance(instantiateSync(u,e)[0])}();G.j,a._malloc=G.k,a._free=G.l,a._jp2_decode=G.n,G._emscripten_stack_restore,G._emscripten_stack_alloc,G.emscripten_stack_get_current;w=function runCaller(){D||run();D||(w=runCaller)};function run(){if(!(m>0)){!function preRun(){if(a.preRun){"function"==typeof a.preRun&&(a.preRun=[a.preRun]);for(;a.preRun.length;)e=a.preRun.shift(),d.unshift(e)}var e;callRuntimeCallbacks(d)}();if(!(m>0))if(a.setStatus){a.setStatus("Running...");setTimeout((function(){setTimeout((function(){a.setStatus("")}),1);doRun()}),1)}else doRun()}function doRun(){if(!D){D=!0;a.calledRun=!0;!function initRuntime(){callRuntimeCallbacks(f)}();t(a);a.onRuntimeInitialized&&a.onRuntimeInitialized();!function postRun(){if(a.postRun){"function"==typeof a.postRun&&(a.postRun=[a.postRun]);for(;a.postRun.length;)e=a.postRun.shift(),p.unshift(e)}var e;callRuntimeCallbacks(p)}()}}}if(a.preInit){"function"==typeof a.preInit&&(a.preInit=[a.preInit]);for(;a.preInit.length>0;)a.preInit.pop()()}run();return a});const Ii=gi;class JpxError extends rt{constructor(e){super(e,"JpxError")}}class JpxImage{static#y=null;static decode(e,t=!1){this.#y||=Ii({warn});const i=this.#y.decode(e,t);if("string"==typeof i)throw new JpxError(i);return i}static cleanup(){this.#y=null}static parseImageProperties(e){let t=e.getByte();for(;t>=0;){const i=t;t=e.getByte();if(65361===(i<<8|t)){e.skip(4);const t=e.getInt32()>>>0,i=e.getInt32()>>>0,a=e.getInt32()>>>0,s=e.getInt32()>>>0;e.skip(16);return{width:t-a,height:i-s,bitsPerComponent:8,componentsCount:e.getUint16()}}}throw new JpxError("No size marker found in JPX stream")}}class JpxStream extends DecodeStream{constructor(e,t,i){super(t);this.stream=e;this.dict=e.dict;this.maybeLength=t;this.params=i}get bytes(){return shadow(this,"bytes",this.stream.getBytes(this.maybeLength))}ensureBuffer(e){}readBlock(e){if(!this.eof){this.buffer=JpxImage.decode(this.bytes,e);this.bufferLength=this.buffer.length;this.eof=!0}}}class LZWStream extends DecodeStream{constructor(e,t,i){super(t);this.str=e;this.dict=e.dict;this.cachedData=0;this.bitsCached=0;const a=4096,s={earlyChange:i,codeLength:9,nextCode:258,dictionaryValues:new Uint8Array(a),dictionaryLengths:new Uint16Array(a),dictionaryPrevCodes:new Uint16Array(a),currentSequence:new Uint8Array(a),currentSequenceLength:0};for(let e=0;e<256;++e){s.dictionaryValues[e]=e;s.dictionaryLengths[e]=1}this.lzwState=s}readBits(e){let t=this.bitsCached,i=this.cachedData;for(;t<e;){const e=this.str.getByte();if(-1===e){this.eof=!0;return null}i=i<<8|e;t+=8}this.bitsCached=t-=e;this.cachedData=i;this.lastCode=null;return i>>>t&(1<<e)-1}readBlock(){let e,t,i,a=1024;const s=this.lzwState;if(!s)return;const r=s.earlyChange;let n=s.nextCode;const o=s.dictionaryValues,g=s.dictionaryLengths,c=s.dictionaryPrevCodes;let h=s.codeLength,l=s.prevCode;const C=s.currentSequence;let Q=s.currentSequenceLength,E=0,u=this.bufferLength,d=this.ensureBuffer(this.bufferLength+a);for(e=0;e<512;e++){const e=this.readBits(h),s=Q>0;if(e<256){C[0]=e;Q=1}else{if(!(e>=258)){if(256===e){h=9;n=258;Q=0;continue}this.eof=!0;delete this.lzwState;break}if(e<n){Q=g[e];for(t=Q-1,i=e;t>=0;t--){C[t]=o[i];i=c[i]}}else C[Q++]=C[0]}if(s){c[n]=l;g[n]=g[l]+1;o[n]=C[0];n++;h=n+r&n+r-1?h:0|Math.min(Math.log(n+r)/.6931471805599453+1,12)}l=e;E+=Q;if(a<E){do{a+=512}while(a<E);d=this.ensureBuffer(this.bufferLength+a)}for(t=0;t<Q;t++)d[u++]=C[t]}s.nextCode=n;s.codeLength=h;s.prevCode=l;s.currentSequenceLength=Q;this.bufferLength=u}}class PredictorStream extends DecodeStream{constructor(e,t,i){super(t);if(!(i instanceof Dict))return e;const a=this.predictor=i.get("Predictor")||1;if(a<=1)return e;if(2!==a&&(a<10||a>15))throw new FormatError(`Unsupported predictor: ${a}`);this.readBlock=2===a?this.readBlockTiff:this.readBlockPng;this.str=e;this.dict=e.dict;const s=this.colors=i.get("Colors")||1,r=this.bits=i.get("BPC","BitsPerComponent")||8,n=this.columns=i.get("Columns")||1;this.pixBytes=s*r+7>>3;this.rowBytes=n*s*r+7>>3;return this}readBlockTiff(){const e=this.rowBytes,t=this.bufferLength,i=this.ensureBuffer(t+e),a=this.bits,s=this.colors,r=this.str.getBytes(e);this.eof=!r.length;if(this.eof)return;let n,o=0,g=0,c=0,h=0,l=t;if(1===a&&1===s)for(n=0;n<e;++n){let e=r[n]^o;e^=e>>1;e^=e>>2;e^=e>>4;o=(1&e)<<7;i[l++]=e}else if(8===a){for(n=0;n<s;++n)i[l++]=r[n];for(;n<e;++n){i[l]=i[l-s]+r[n];l++}}else if(16===a){const t=2*s;for(n=0;n<t;++n)i[l++]=r[n];for(;n<e;n+=2){const e=((255&r[n])<<8)+(255&r[n+1])+((255&i[l-t])<<8)+(255&i[l-t+1]);i[l++]=e>>8&255;i[l++]=255&e}}else{const e=new Uint8Array(s+1),l=(1<<a)-1;let C=0,Q=t;const E=this.columns;for(n=0;n<E;++n)for(let t=0;t<s;++t){if(c<a){o=o<<8|255&r[C++];c+=8}e[t]=e[t]+(o>>c-a)&l;c-=a;g=g<<a|e[t];h+=a;if(h>=8){i[Q++]=g>>h-8&255;h-=8}}h>0&&(i[Q++]=(g<<8-h)+(o&(1<<8-h)-1))}this.bufferLength+=e}readBlockPng(){const e=this.rowBytes,t=this.pixBytes,i=this.str.getByte(),a=this.str.getBytes(e);this.eof=!a.length;if(this.eof)return;const s=this.bufferLength,r=this.ensureBuffer(s+e);let n=r.subarray(s-e,s);0===n.length&&(n=new Uint8Array(e));let o,g,c,h=s;switch(i){case 0:for(o=0;o<e;++o)r[h++]=a[o];break;case 1:for(o=0;o<t;++o)r[h++]=a[o];for(;o<e;++o){r[h]=r[h-t]+a[o]&255;h++}break;case 2:for(o=0;o<e;++o)r[h++]=n[o]+a[o]&255;break;case 3:for(o=0;o<t;++o)r[h++]=(n[o]>>1)+a[o];for(;o<e;++o){r[h]=(n[o]+r[h-t]>>1)+a[o]&255;h++}break;case 4:for(o=0;o<t;++o){g=n[o];c=a[o];r[h++]=g+c}for(;o<e;++o){g=n[o];const e=n[o-t],i=r[h-t],s=i+g-e;let l=s-i;l<0&&(l=-l);let C=s-g;C<0&&(C=-C);let Q=s-e;Q<0&&(Q=-Q);c=a[o];r[h++]=l<=C&&l<=Q?i+c:C<=Q?g+c:e+c}break;default:throw new FormatError(`Unsupported predictor: ${i}`)}this.bufferLength+=e}}class RunLengthStream extends DecodeStream{constructor(e,t){super(t);this.str=e;this.dict=e.dict}readBlock(){const e=this.str.getBytes(2);if(!e||e.length<2||128===e[0]){this.eof=!0;return}let t,i=this.bufferLength,a=e[0];if(a<128){t=this.ensureBuffer(i+a+1);t[i++]=e[1];if(a>0){const e=this.str.getBytes(a);t.set(e,i);i+=a}}else{a=257-a;const s=e[1];t=this.ensureBuffer(i+a+1);for(let e=0;e<a;e++)t[i++]=s}this.bufferLength=i}}class Parser{constructor({lexer:e,xref:t,allowStreams:i=!1,recoveryMode:a=!1}){this.lexer=e;this.xref=t;this.allowStreams=i;this.recoveryMode=a;this.imageCache=Object.create(null);this._imageId=0;this.refill()}refill(){this.buf1=this.lexer.getObj();this.buf2=this.lexer.getObj()}shift(){if(this.buf2 instanceof Cmd&&"ID"===this.buf2.cmd){this.buf1=this.buf2;this.buf2=null}else{this.buf1=this.buf2;this.buf2=this.lexer.getObj()}}tryShift(){try{this.shift();return!0}catch(e){if(e instanceof MissingDataException)throw e;return!1}}getObj(e=null){const t=this.buf1;this.shift();if(t instanceof Cmd)switch(t.cmd){case"BI":return this.makeInlineImage(e);case"[":const i=[];for(;!isCmd(this.buf1,"]")&&this.buf1!==pt;)i.push(this.getObj(e));if(this.buf1===pt){if(this.recoveryMode)return i;throw new ParserEOFException("End of file inside array.")}this.shift();return i;case"<<":const a=new Dict(this.xref);for(;!isCmd(this.buf1,">>")&&this.buf1!==pt;){if(!(this.buf1 instanceof Name)){info("Malformed dictionary: key must be a name object");this.shift();continue}const t=this.buf1.name;this.shift();if(this.buf1===pt)break;a.set(t,this.getObj(e))}if(this.buf1===pt){if(this.recoveryMode)return a;throw new ParserEOFException("End of file inside dictionary.")}if(isCmd(this.buf2,"stream"))return this.allowStreams?this.makeStream(a,e):a;this.shift();return a;default:return t}if(Number.isInteger(t)){if(Number.isInteger(this.buf1)&&isCmd(this.buf2,"R")){const e=Ref.get(t,this.buf1);this.shift();this.shift();return e}return t}return"string"==typeof t&&e?e.decryptString(t):t}findDefaultInlineStreamEnd(e){const{knownCommands:t}=this.lexer,i=e.pos;let a,s,r=0;for(;-1!==(a=e.getByte());)if(0===r)r=69===a?1:0;else if(1===r)r=73===a?2:0;else if(32===a||10===a||13===a){s=e.pos;const i=e.peekBytes(15),n=i.length;if(0===n)break;for(let e=0;e<n;e++){a=i[e];if((0!==a||0===i[e+1])&&(10!==a&&13!==a&&(a<32||a>127))){r=0;break}}if(2!==r)continue;if(!t){warn("findDefaultInlineStreamEnd - `lexer.knownCommands` is undefined.");continue}const o=new Lexer(new Stream(i.slice()),t);o._hexStringWarn=()=>{};let g=0;for(;;){const e=o.getObj();if(e===pt){r=0;break}if(e instanceof Cmd){const i=t[e.cmd];if(!i){r=0;break}if(i.variableArgs?g<=i.numArgs:g===i.numArgs)break;g=0}else g++}if(2===r)break}else r=0;if(-1===a){warn("findDefaultInlineStreamEnd: Reached the end of the stream without finding a valid EI marker");if(s){warn('... trying to recover by using the last "EI" occurrence.');e.skip(-(e.pos-s))}}let n=4;e.skip(-n);a=e.peekByte();e.skip(n);isWhiteSpace(a)||n--;return e.pos-n-i}findDCTDecodeInlineStreamEnd(e){const t=e.pos;let i,a,s=!1;for(;-1!==(i=e.getByte());)if(255===i){switch(e.getByte()){case 0:break;case 255:e.skip(-1);break;case 217:s=!0;break;case 192:case 193:case 194:case 195:case 197:case 198:case 199:case 201:case 202:case 203:case 205:case 206:case 207:case 196:case 204:case 218:case 219:case 220:case 221:case 222:case 223:case 224:case 225:case 226:case 227:case 228:case 229:case 230:case 231:case 232:case 233:case 234:case 235:case 236:case 237:case 238:case 239:case 254:a=e.getUint16();a>2?e.skip(a-2):e.skip(-2)}if(s)break}const r=e.pos-t;if(-1===i){warn("Inline DCTDecode image stream: EOI marker not found, searching for /EI/ instead.");e.skip(-r);return this.findDefaultInlineStreamEnd(e)}this.inlineStreamSkipEI(e);return r}findASCII85DecodeInlineStreamEnd(e){const t=e.pos;let i;for(;-1!==(i=e.getByte());)if(126===i){const t=e.pos;i=e.peekByte();for(;isWhiteSpace(i);){e.skip();i=e.peekByte()}if(62===i){e.skip();break}if(e.pos>t){const t=e.peekBytes(2);if(69===t[0]&&73===t[1])break}}const a=e.pos-t;if(-1===i){warn("Inline ASCII85Decode image stream: EOD marker not found, searching for /EI/ instead.");e.skip(-a);return this.findDefaultInlineStreamEnd(e)}this.inlineStreamSkipEI(e);return a}findASCIIHexDecodeInlineStreamEnd(e){const t=e.pos;let i;for(;-1!==(i=e.getByte())&&62!==i;);const a=e.pos-t;if(-1===i){warn("Inline ASCIIHexDecode image stream: EOD marker not found, searching for /EI/ instead.");e.skip(-a);return this.findDefaultInlineStreamEnd(e)}this.inlineStreamSkipEI(e);return a}inlineStreamSkipEI(e){let t,i=0;for(;-1!==(t=e.getByte());)if(0===i)i=69===t?1:0;else if(1===i)i=73===t?2:0;else if(2===i)break}makeInlineImage(e){const t=this.lexer,i=t.stream,a=Object.create(null);let s;for(;!isCmd(this.buf1,"ID")&&this.buf1!==pt;){if(!(this.buf1 instanceof Name))throw new FormatError("Dictionary key must be a name object");const t=this.buf1.name;this.shift();if(this.buf1===pt)break;a[t]=this.getObj(e)}-1!==t.beginInlineImagePos&&(s=i.pos-t.beginInlineImagePos);const r=this.xref.fetchIfRef(a.F||a.Filter);let n;if(r instanceof Name)n=r.name;else if(Array.isArray(r)){const e=this.xref.fetchIfRef(r[0]);e instanceof Name&&(n=e.name)}const o=i.pos;let g,c;switch(n){case"DCT":case"DCTDecode":g=this.findDCTDecodeInlineStreamEnd(i);break;case"A85":case"ASCII85Decode":g=this.findASCII85DecodeInlineStreamEnd(i);break;case"AHx":case"ASCIIHexDecode":g=this.findASCIIHexDecodeInlineStreamEnd(i);break;default:g=this.findDefaultInlineStreamEnd(i)}if(g<1e3&&s>0){const e=i.pos;i.pos=t.beginInlineImagePos;c=function getInlineImageCacheKey(e){const t=[],i=e.length;let a=0;for(;a<i-1;)t.push(e[a++]<<8|e[a++]);a<i&&t.push(e[a]);return i+"_"+String.fromCharCode.apply(null,t)}(i.getBytes(s+g));i.pos=e;const a=this.imageCache[c];if(void 0!==a){this.buf2=Cmd.get("EI");this.shift();a.reset();return a}}const h=new Dict(this.xref);for(const e in a)h.set(e,a[e]);let l=i.makeSubStream(o,g,h);e&&(l=e.createStream(l,g));l=this.filter(l,h,g);l.dict=h;if(void 0!==c){l.cacheKey="inline_img_"+ ++this._imageId;this.imageCache[c]=l}this.buf2=Cmd.get("EI");this.shift();return l}#w(e){const{stream:t}=this.lexer;t.pos=e;const i=new Uint8Array([101,110,100]),a=i.length,s=[new Uint8Array([115,116,114,101,97,109]),new Uint8Array([115,116,101,97,109]),new Uint8Array([115,116,114,101,97])],r=9-a;for(;t.pos<t.end;){const n=t.peekBytes(2048),o=n.length-9;if(o<=0)break;let g=0;for(;g<o;){let o=0;for(;o<a&&n[g+o]===i[o];)o++;if(o>=a){let a=!1;for(const e of s){const t=e.length;let s=0;for(;s<t&&n[g+o+s]===e[s];)s++;if(s>=r){a=!0;break}if(s>=t){if(isWhiteSpace(n[g+o+s])){info(`Found "${bytesToString([...i,...e])}" when searching for endstream command.`);a=!0}break}}if(a){t.pos+=g;return t.pos-e}}g++}t.pos+=o}return-1}makeStream(e,t){const i=this.lexer;let a=i.stream;i.skipToNextLine();const s=a.pos-1;let r=e.get("Length");if(!Number.isInteger(r)){info(`Bad length "${r&&r.toString()}" in stream.`);r=0}a.pos=s+r;i.nextChar();if(this.tryShift()&&isCmd(this.buf2,"endstream"))this.shift();else{r=this.#w(s);if(r<0)throw new FormatError("Missing endstream command.");i.nextChar();this.shift();this.shift()}this.shift();a=a.makeSubStream(s,r,e);t&&(a=t.createStream(a,r));a=this.filter(a,e,r);a.dict=e;return a}filter(e,t,i){let a=t.get("F","Filter"),s=t.get("DP","DecodeParms");if(a instanceof Name){Array.isArray(s)&&warn("/DecodeParms should not be an Array, when /Filter is a Name.");return this.makeFilter(e,a.name,i,s)}let r=i;if(Array.isArray(a)){const t=a,i=s;for(let n=0,o=t.length;n<o;++n){a=this.xref.fetchIfRef(t[n]);if(!(a instanceof Name))throw new FormatError(`Bad filter name "${a}"`);s=null;Array.isArray(i)&&n in i&&(s=this.xref.fetchIfRef(i[n]));e=this.makeFilter(e,a.name,r,s);r=null}}return e}makeFilter(e,t,i,a){if(0===i){warn(`Empty "${t}" stream.`);return new NullStream}try{switch(t){case"Fl":case"FlateDecode":return a?new PredictorStream(new FlateStream(e,i),i,a):new FlateStream(e,i);case"LZW":case"LZWDecode":let t=1;if(a){a.has("EarlyChange")&&(t=a.get("EarlyChange"));return new PredictorStream(new LZWStream(e,i,t),i,a)}return new LZWStream(e,i,t);case"DCT":case"DCTDecode":return new JpegStream(e,i,a);case"JPX":case"JPXDecode":return new JpxStream(e,i,a);case"A85":case"ASCII85Decode":return new Ascii85Stream(e,i);case"AHx":case"ASCIIHexDecode":return new AsciiHexStream(e,i);case"CCF":case"CCITTFaxDecode":return new CCITTFaxStream(e,i,a);case"RL":case"RunLengthDecode":return new RunLengthStream(e,i);case"JBIG2Decode":return new Jbig2Stream(e,i,a)}warn(`Filter "${t}" is not supported.`);return e}catch(e){if(e instanceof MissingDataException)throw e;warn(`Invalid stream: "${e}"`);return new NullStream}}}const ci=[1,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,2,0,0,2,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];function toHexDigit(e){return e>=48&&e<=57?15&e:e>=65&&e<=70||e>=97&&e<=102?9+(15&e):-1}class Lexer{constructor(e,t=null){this.stream=e;this.nextChar();this.strBuf=[];this.knownCommands=t;this._hexStringNumWarn=0;this.beginInlineImagePos=-1}nextChar(){return this.currentChar=this.stream.getByte()}peekChar(){return this.stream.peekByte()}getNumber(){let e=this.currentChar,t=!1,i=0,a=1;if(45===e){a=-1;e=this.nextChar();45===e&&(e=this.nextChar())}else 43===e&&(e=this.nextChar());if(10===e||13===e)do{e=this.nextChar()}while(10===e||13===e);if(46===e){i=10;e=this.nextChar()}if(e<48||e>57){const t=`Invalid number: ${String.fromCharCode(e)} (charCode ${e})`;if(isWhiteSpace(e)||-1===e){info(`Lexer.getNumber - "${t}".`);return 0}throw new FormatError(t)}let s=e-48,r=0,n=1;for(;(e=this.nextChar())>=0;)if(e>=48&&e<=57){const a=e-48;if(t)r=10*r+a;else{0!==i&&(i*=10);s=10*s+a}}else if(46===e){if(0!==i)break;i=1}else if(45===e)warn("Badly formatted number: minus sign in the middle");else{if(69!==e&&101!==e)break;e=this.peekChar();if(43===e||45===e){n=45===e?-1:1;this.nextChar()}else if(e<48||e>57)break;t=!0}0!==i&&(s/=i);t&&(s*=10**(n*r));return a*s}getString(){let e=1,t=!1;const i=this.strBuf;i.length=0;let a=this.nextChar();for(;;){let s=!1;switch(0|a){case-1:warn("Unterminated string");t=!0;break;case 40:++e;i.push("(");break;case 41:if(0==--e){this.nextChar();t=!0}else i.push(")");break;case 92:a=this.nextChar();switch(a){case-1:warn("Unterminated string");t=!0;break;case 110:i.push("\n");break;case 114:i.push("\r");break;case 116:i.push("\t");break;case 98:i.push("\b");break;case 102:i.push("\f");break;case 92:case 40:case 41:i.push(String.fromCharCode(a));break;case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:let e=15&a;a=this.nextChar();s=!0;if(a>=48&&a<=55){e=(e<<3)+(15&a);a=this.nextChar();if(a>=48&&a<=55){s=!1;e=(e<<3)+(15&a)}}i.push(String.fromCharCode(e));break;case 13:10===this.peekChar()&&this.nextChar();break;case 10:break;default:i.push(String.fromCharCode(a))}break;default:i.push(String.fromCharCode(a))}if(t)break;s||(a=this.nextChar())}return i.join("")}getName(){let e,t;const i=this.strBuf;i.length=0;for(;(e=this.nextChar())>=0&&!ci[e];)if(35===e){e=this.nextChar();if(ci[e]){warn("Lexer_getName: NUMBER SIGN (#) should be followed by a hexadecimal number.");i.push("#");break}const a=toHexDigit(e);if(-1!==a){t=e;e=this.nextChar();const s=toHexDigit(e);if(-1===s){warn(`Lexer_getName: Illegal digit (${String.fromCharCode(e)}) in hexadecimal number.`);i.push("#",String.fromCharCode(t));if(ci[e])break;i.push(String.fromCharCode(e));continue}i.push(String.fromCharCode(a<<4|s))}else i.push("#",String.fromCharCode(e))}else i.push(String.fromCharCode(e));i.length>127&&warn(`Name token is longer than allowed by the spec: ${i.length}`);return Name.get(i.join(""))}_hexStringWarn(e){5!=this._hexStringNumWarn++?this._hexStringNumWarn>5||warn(`getHexString - ignoring invalid character: ${e}`):warn("getHexString - ignoring additional invalid characters.")}getHexString(){const e=this.strBuf;e.length=0;let t,i,a=this.currentChar,s=!0;this._hexStringNumWarn=0;for(;;){if(a<0){warn("Unterminated hex string");break}if(62===a){this.nextChar();break}if(1!==ci[a]){if(s){t=toHexDigit(a);if(-1===t){this._hexStringWarn(a);a=this.nextChar();continue}}else{i=toHexDigit(a);if(-1===i){this._hexStringWarn(a);a=this.nextChar();continue}e.push(String.fromCharCode(t<<4|i))}s=!s;a=this.nextChar()}else a=this.nextChar()}return e.join("")}getObj(){let e=!1,t=this.currentChar;for(;;){if(t<0)return pt;if(e)10!==t&&13!==t||(e=!1);else if(37===t)e=!0;else if(1!==ci[t])break;t=this.nextChar()}switch(0|t){case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:case 43:case 45:case 46:return this.getNumber();case 40:return this.getString();case 47:return this.getName();case 91:this.nextChar();return Cmd.get("[");case 93:this.nextChar();return Cmd.get("]");case 60:t=this.nextChar();if(60===t){this.nextChar();return Cmd.get("<<")}return this.getHexString();case 62:t=this.nextChar();if(62===t){this.nextChar();return Cmd.get(">>")}return Cmd.get(">");case 123:this.nextChar();return Cmd.get("{");case 125:this.nextChar();return Cmd.get("}");case 41:this.nextChar();throw new FormatError(`Illegal character: ${t}`)}let i=String.fromCharCode(t);if(t<32||t>127){const e=this.peekChar();if(e>=32&&e<=127){this.nextChar();return Cmd.get(i)}}const a=this.knownCommands;let s=void 0!==a?.[i];for(;(t=this.nextChar())>=0&&!ci[t];){const e=i+String.fromCharCode(t);if(s&&void 0===a[e])break;if(128===i.length)throw new FormatError(`Command token too long: ${i.length}`);i=e;s=void 0!==a?.[i]}if("true"===i)return!0;if("false"===i)return!1;if("null"===i)return null;"BI"===i&&(this.beginInlineImagePos=this.stream.pos);return Cmd.get(i)}skipToNextLine(){let e=this.currentChar;for(;e>=0;){if(13===e){e=this.nextChar();10===e&&this.nextChar();break}if(10===e){this.nextChar();break}e=this.nextChar()}}}class Linearization{static create(e){function getInt(e,t,i=!1){const a=e.get(t);if(Number.isInteger(a)&&(i?a>=0:a>0))return a;throw new Error(`The "${t}" parameter in the linearization dictionary is invalid.`)}const t=new Parser({lexer:new Lexer(e),xref:null}),i=t.getObj(),a=t.getObj(),s=t.getObj(),r=t.getObj();let n,o;if(!(Number.isInteger(i)&&Number.isInteger(a)&&isCmd(s,"obj")&&r instanceof Dict&&"number"==typeof(n=r.get("Linearized"))&&n>0))return null;if((o=getInt(r,"L"))!==e.length)throw new Error('The "L" parameter in the linearization dictionary does not equal the stream length.');return{length:o,hints:function getHints(e){const t=e.get("H");let i;if(Array.isArray(t)&&(2===(i=t.length)||4===i)){for(let e=0;e<i;e++){const i=t[e];if(!(Number.isInteger(i)&&i>0))throw new Error(`Hint (${e}) in the linearization dictionary is invalid.`)}return t}throw new Error("Hint array in the linearization dictionary is invalid.")}(r),objectNumberFirst:getInt(r,"O"),endFirst:getInt(r,"E"),numPages:getInt(r,"N"),mainXRefEntriesOffset:getInt(r,"T"),pageFirst:r.has("P")?getInt(r,"P",!0):0}}}const hi=["Adobe-GB1-UCS2","Adobe-CNS1-UCS2","Adobe-Japan1-UCS2","Adobe-Korea1-UCS2","78-EUC-H","78-EUC-V","78-H","78-RKSJ-H","78-RKSJ-V","78-V","78ms-RKSJ-H","78ms-RKSJ-V","83pv-RKSJ-H","90ms-RKSJ-H","90ms-RKSJ-V","90msp-RKSJ-H","90msp-RKSJ-V","90pv-RKSJ-H","90pv-RKSJ-V","Add-H","Add-RKSJ-H","Add-RKSJ-V","Add-V","Adobe-CNS1-0","Adobe-CNS1-1","Adobe-CNS1-2","Adobe-CNS1-3","Adobe-CNS1-4","Adobe-CNS1-5","Adobe-CNS1-6","Adobe-GB1-0","Adobe-GB1-1","Adobe-GB1-2","Adobe-GB1-3","Adobe-GB1-4","Adobe-GB1-5","Adobe-Japan1-0","Adobe-Japan1-1","Adobe-Japan1-2","Adobe-Japan1-3","Adobe-Japan1-4","Adobe-Japan1-5","Adobe-Japan1-6","Adobe-Korea1-0","Adobe-Korea1-1","Adobe-Korea1-2","B5-H","B5-V","B5pc-H","B5pc-V","CNS-EUC-H","CNS-EUC-V","CNS1-H","CNS1-V","CNS2-H","CNS2-V","ETHK-B5-H","ETHK-B5-V","ETen-B5-H","ETen-B5-V","ETenms-B5-H","ETenms-B5-V","EUC-H","EUC-V","Ext-H","Ext-RKSJ-H","Ext-RKSJ-V","Ext-V","GB-EUC-H","GB-EUC-V","GB-H","GB-V","GBK-EUC-H","GBK-EUC-V","GBK2K-H","GBK2K-V","GBKp-EUC-H","GBKp-EUC-V","GBT-EUC-H","GBT-EUC-V","GBT-H","GBT-V","GBTpc-EUC-H","GBTpc-EUC-V","GBpc-EUC-H","GBpc-EUC-V","H","HKdla-B5-H","HKdla-B5-V","HKdlb-B5-H","HKdlb-B5-V","HKgccs-B5-H","HKgccs-B5-V","HKm314-B5-H","HKm314-B5-V","HKm471-B5-H","HKm471-B5-V","HKscs-B5-H","HKscs-B5-V","Hankaku","Hiragana","KSC-EUC-H","KSC-EUC-V","KSC-H","KSC-Johab-H","KSC-Johab-V","KSC-V","KSCms-UHC-H","KSCms-UHC-HW-H","KSCms-UHC-HW-V","KSCms-UHC-V","KSCpc-EUC-H","KSCpc-EUC-V","Katakana","NWP-H","NWP-V","RKSJ-H","RKSJ-V","Roman","UniCNS-UCS2-H","UniCNS-UCS2-V","UniCNS-UTF16-H","UniCNS-UTF16-V","UniCNS-UTF32-H","UniCNS-UTF32-V","UniCNS-UTF8-H","UniCNS-UTF8-V","UniGB-UCS2-H","UniGB-UCS2-V","UniGB-UTF16-H","UniGB-UTF16-V","UniGB-UTF32-H","UniGB-UTF32-V","UniGB-UTF8-H","UniGB-UTF8-V","UniJIS-UCS2-H","UniJIS-UCS2-HW-H","UniJIS-UCS2-HW-V","UniJIS-UCS2-V","UniJIS-UTF16-H","UniJIS-UTF16-V","UniJIS-UTF32-H","UniJIS-UTF32-V","UniJIS-UTF8-H","UniJIS-UTF8-V","UniJIS2004-UTF16-H","UniJIS2004-UTF16-V","UniJIS2004-UTF32-H","UniJIS2004-UTF32-V","UniJIS2004-UTF8-H","UniJIS2004-UTF8-V","UniJISPro-UCS2-HW-V","UniJISPro-UCS2-V","UniJISPro-UTF8-V","UniJISX0213-UTF32-H","UniJISX0213-UTF32-V","UniJISX02132004-UTF32-H","UniJISX02132004-UTF32-V","UniKS-UCS2-H","UniKS-UCS2-V","UniKS-UTF16-H","UniKS-UTF16-V","UniKS-UTF32-H","UniKS-UTF32-V","UniKS-UTF8-H","UniKS-UTF8-V","V","WP-Symbol"],li=2**24-1;class CMap{constructor(e=!1){this.codespaceRanges=[[],[],[],[]];this.numCodespaceRanges=0;this._map=[];this.name="";this.vertical=!1;this.useCMap=null;this.builtInCMap=e}addCodespaceRange(e,t,i){this.codespaceRanges[e-1].push(t,i);this.numCodespaceRanges++}mapCidRange(e,t,i){if(t-e>li)throw new Error("mapCidRange - ignoring data above MAX_MAP_RANGE.");for(;e<=t;)this._map[e++]=i++}mapBfRange(e,t,i){if(t-e>li)throw new Error("mapBfRange - ignoring data above MAX_MAP_RANGE.");const a=i.length-1;for(;e<=t;){this._map[e++]=i;const t=i.charCodeAt(a)+1;t>255?i=i.substring(0,a-1)+String.fromCharCode(i.charCodeAt(a-1)+1)+"\0":i=i.substring(0,a)+String.fromCharCode(t)}}mapBfRangeToArray(e,t,i){if(t-e>li)throw new Error("mapBfRangeToArray - ignoring data above MAX_MAP_RANGE.");const a=i.length;let s=0;for(;e<=t&&s<a;){this._map[e]=i[s++];++e}}mapOne(e,t){this._map[e]=t}lookup(e){return this._map[e]}contains(e){return void 0!==this._map[e]}forEach(e){const t=this._map,i=t.length;if(i<=65536)for(let a=0;a<i;a++)void 0!==t[a]&&e(a,t[a]);else for(const i in t)e(i,t[i])}charCodeOf(e){const t=this._map;if(t.length<=65536)return t.indexOf(e);for(const i in t)if(t[i]===e)return 0|i;return-1}getMap(){return this._map}readCharCode(e,t,i){let a=0;const s=this.codespaceRanges;for(let r=0,n=s.length;r<n;r++){a=(a<<8|e.charCodeAt(t+r))>>>0;const n=s[r];for(let e=0,t=n.length;e<t;){const t=n[e++],s=n[e++];if(a>=t&&a<=s){i.charcode=a;i.length=r+1;return}}}i.charcode=0;i.length=1}getCharCodeLength(e){const t=this.codespaceRanges;for(let i=0,a=t.length;i<a;i++){const a=t[i];for(let t=0,s=a.length;t<s;){const s=a[t++],r=a[t++];if(e>=s&&e<=r)return i+1}}return 1}get length(){return this._map.length}get isIdentityCMap(){if("Identity-H"!==this.name&&"Identity-V"!==this.name)return!1;if(65536!==this._map.length)return!1;for(let e=0;e<65536;e++)if(this._map[e]!==e)return!1;return!0}}class IdentityCMap extends CMap{constructor(e,t){super();this.vertical=e;this.addCodespaceRange(t,0,65535)}mapCidRange(e,t,i){unreachable("should not call mapCidRange")}mapBfRange(e,t,i){unreachable("should not call mapBfRange")}mapBfRangeToArray(e,t,i){unreachable("should not call mapBfRangeToArray")}mapOne(e,t){unreachable("should not call mapCidOne")}lookup(e){return Number.isInteger(e)&&e<=65535?e:void 0}contains(e){return Number.isInteger(e)&&e<=65535}forEach(e){for(let t=0;t<=65535;t++)e(t,t)}charCodeOf(e){return Number.isInteger(e)&&e<=65535?e:-1}getMap(){const e=new Array(65536);for(let t=0;t<=65535;t++)e[t]=t;return e}get length(){return 65536}get isIdentityCMap(){unreachable("should not access .isIdentityCMap")}}function strToInt(e){let t=0;for(let i=0;i<e.length;i++)t=t<<8|e.charCodeAt(i);return t>>>0}function expectString(e){if("string"!=typeof e)throw new FormatError("Malformed CMap: expected string.")}function expectInt(e){if(!Number.isInteger(e))throw new FormatError("Malformed CMap: expected int.")}function parseBfChar(e,t){for(;;){let i=t.getObj();if(i===pt)break;if(isCmd(i,"endbfchar"))return;expectString(i);const a=strToInt(i);i=t.getObj();expectString(i);const s=i;e.mapOne(a,s)}}function parseBfRange(e,t){for(;;){let i=t.getObj();if(i===pt)break;if(isCmd(i,"endbfrange"))return;expectString(i);const a=strToInt(i);i=t.getObj();expectString(i);const s=strToInt(i);i=t.getObj();if(Number.isInteger(i)||"string"==typeof i){const t=Number.isInteger(i)?String.fromCharCode(i):i;e.mapBfRange(a,s,t)}else{if(!isCmd(i,"["))break;{i=t.getObj();const r=[];for(;!isCmd(i,"]")&&i!==pt;){r.push(i);i=t.getObj()}e.mapBfRangeToArray(a,s,r)}}}throw new FormatError("Invalid bf range.")}function parseCidChar(e,t){for(;;){let i=t.getObj();if(i===pt)break;if(isCmd(i,"endcidchar"))return;expectString(i);const a=strToInt(i);i=t.getObj();expectInt(i);const s=i;e.mapOne(a,s)}}function parseCidRange(e,t){for(;;){let i=t.getObj();if(i===pt)break;if(isCmd(i,"endcidrange"))return;expectString(i);const a=strToInt(i);i=t.getObj();expectString(i);const s=strToInt(i);i=t.getObj();expectInt(i);const r=i;e.mapCidRange(a,s,r)}}function parseCodespaceRange(e,t){for(;;){let i=t.getObj();if(i===pt)break;if(isCmd(i,"endcodespacerange"))return;if("string"!=typeof i)break;const a=strToInt(i);i=t.getObj();if("string"!=typeof i)break;const s=strToInt(i);e.addCodespaceRange(i.length,a,s)}throw new FormatError("Invalid codespace range.")}function parseWMode(e,t){const i=t.getObj();Number.isInteger(i)&&(e.vertical=!!i)}function parseCMapName(e,t){const i=t.getObj();i instanceof Name&&(e.name=i.name)}async function parseCMap(e,t,i,a){let s,r;A:for(;;)try{const i=t.getObj();if(i===pt)break;if(i instanceof Name){"WMode"===i.name?parseWMode(e,t):"CMapName"===i.name&&parseCMapName(e,t);s=i}else if(i instanceof Cmd)switch(i.cmd){case"endcmap":break A;case"usecmap":s instanceof Name&&(r=s.name);break;case"begincodespacerange":parseCodespaceRange(e,t);break;case"beginbfchar":parseBfChar(e,t);break;case"begincidchar":parseCidChar(e,t);break;case"beginbfrange":parseBfRange(e,t);break;case"begincidrange":parseCidRange(e,t)}}catch(e){if(e instanceof MissingDataException)throw e;warn("Invalid cMap data: "+e);continue}!a&&r&&(a=r);return a?extendCMap(e,i,a):e}async function extendCMap(e,t,i){e.useCMap=await createBuiltInCMap(i,t);if(0===e.numCodespaceRanges){const t=e.useCMap.codespaceRanges;for(let i=0;i<t.length;i++)e.codespaceRanges[i]=t[i].slice();e.numCodespaceRanges=e.useCMap.numCodespaceRanges}e.useCMap.forEach((function(t,i){e.contains(t)||e.mapOne(t,e.useCMap.lookup(t))}));return e}async function createBuiltInCMap(e,t){if("Identity-H"===e)return new IdentityCMap(!1,2);if("Identity-V"===e)return new IdentityCMap(!0,2);if(!hi.includes(e))throw new Error("Unknown CMap name: "+e);if(!t)throw new Error("Built-in CMap parameters are not provided.");const{cMapData:i,compressionType:a}=await t(e),s=new CMap(!0);if(a===mA.BINARY)return(new BinaryCMapReader).process(i,s,(e=>extendCMap(s,t,e)));if(a===mA.NONE){const e=new Lexer(new Stream(i));return parseCMap(s,e,t,null)}throw new Error(`Invalid CMap "compressionType" value: ${a}`)}class CMapFactory{static async create({encoding:e,fetchBuiltInCMap:t,useCMap:i}){if(e instanceof Name)return createBuiltInCMap(e.name,t);if(e instanceof BaseStream){const a=await parseCMap(new CMap,new Lexer(e),t,i);return a.isIdentityCMap?createBuiltInCMap(a.name,t):a}throw new Error("Encoding required.")}}const Ci=[".notdef","space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quoteright","parenleft","parenright","asterisk","plus","comma","hyphen","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","at","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft","backslash","bracketright","asciicircum","underscore","quoteleft","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde","exclamdown","cent","sterling","fraction","yen","florin","section","currency","quotesingle","quotedblleft","guillemotleft","guilsinglleft","guilsinglright","fi","fl","endash","dagger","daggerdbl","periodcentered","paragraph","bullet","quotesinglbase","quotedblbase","quotedblright","guillemotright","ellipsis","perthousand","questiondown","grave","acute","circumflex","tilde","macron","breve","dotaccent","dieresis","ring","cedilla","hungarumlaut","ogonek","caron","emdash","AE","ordfeminine","Lslash","Oslash","OE","ordmasculine","ae","dotlessi","lslash","oslash","oe","germandbls","onesuperior","logicalnot","mu","trademark","Eth","onehalf","plusminus","Thorn","onequarter","divide","brokenbar","degree","thorn","threequarters","twosuperior","registered","minus","eth","multiply","threesuperior","copyright","Aacute","Acircumflex","Adieresis","Agrave","Aring","Atilde","Ccedilla","Eacute","Ecircumflex","Edieresis","Egrave","Iacute","Icircumflex","Idieresis","Igrave","Ntilde","Oacute","Ocircumflex","Odieresis","Ograve","Otilde","Scaron","Uacute","Ucircumflex","Udieresis","Ugrave","Yacute","Ydieresis","Zcaron","aacute","acircumflex","adieresis","agrave","aring","atilde","ccedilla","eacute","ecircumflex","edieresis","egrave","iacute","icircumflex","idieresis","igrave","ntilde","oacute","ocircumflex","odieresis","ograve","otilde","scaron","uacute","ucircumflex","udieresis","ugrave","yacute","ydieresis","zcaron"],Bi=[".notdef","space","exclamsmall","Hungarumlautsmall","dollaroldstyle","dollarsuperior","ampersandsmall","Acutesmall","parenleftsuperior","parenrightsuperior","twodotenleader","onedotenleader","comma","hyphen","period","fraction","zerooldstyle","oneoldstyle","twooldstyle","threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle","sevenoldstyle","eightoldstyle","nineoldstyle","colon","semicolon","commasuperior","threequartersemdash","periodsuperior","questionsmall","asuperior","bsuperior","centsuperior","dsuperior","esuperior","isuperior","lsuperior","msuperior","nsuperior","osuperior","rsuperior","ssuperior","tsuperior","ff","fi","fl","ffi","ffl","parenleftinferior","parenrightinferior","Circumflexsmall","hyphensuperior","Gravesmall","Asmall","Bsmall","Csmall","Dsmall","Esmall","Fsmall","Gsmall","Hsmall","Ismall","Jsmall","Ksmall","Lsmall","Msmall","Nsmall","Osmall","Psmall","Qsmall","Rsmall","Ssmall","Tsmall","Usmall","Vsmall","Wsmall","Xsmall","Ysmall","Zsmall","colonmonetary","onefitted","rupiah","Tildesmall","exclamdownsmall","centoldstyle","Lslashsmall","Scaronsmall","Zcaronsmall","Dieresissmall","Brevesmall","Caronsmall","Dotaccentsmall","Macronsmall","figuredash","hypheninferior","Ogoneksmall","Ringsmall","Cedillasmall","onequarter","onehalf","threequarters","questiondownsmall","oneeighth","threeeighths","fiveeighths","seveneighths","onethird","twothirds","zerosuperior","onesuperior","twosuperior","threesuperior","foursuperior","fivesuperior","sixsuperior","sevensuperior","eightsuperior","ninesuperior","zeroinferior","oneinferior","twoinferior","threeinferior","fourinferior","fiveinferior","sixinferior","seveninferior","eightinferior","nineinferior","centinferior","dollarinferior","periodinferior","commainferior","Agravesmall","Aacutesmall","Acircumflexsmall","Atildesmall","Adieresissmall","Aringsmall","AEsmall","Ccedillasmall","Egravesmall","Eacutesmall","Ecircumflexsmall","Edieresissmall","Igravesmall","Iacutesmall","Icircumflexsmall","Idieresissmall","Ethsmall","Ntildesmall","Ogravesmall","Oacutesmall","Ocircumflexsmall","Otildesmall","Odieresissmall","OEsmall","Oslashsmall","Ugravesmall","Uacutesmall","Ucircumflexsmall","Udieresissmall","Yacutesmall","Thornsmall","Ydieresissmall"],Qi=[".notdef","space","dollaroldstyle","dollarsuperior","parenleftsuperior","parenrightsuperior","twodotenleader","onedotenleader","comma","hyphen","period","fraction","zerooldstyle","oneoldstyle","twooldstyle","threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle","sevenoldstyle","eightoldstyle","nineoldstyle","colon","semicolon","commasuperior","threequartersemdash","periodsuperior","asuperior","bsuperior","centsuperior","dsuperior","esuperior","isuperior","lsuperior","msuperior","nsuperior","osuperior","rsuperior","ssuperior","tsuperior","ff","fi","fl","ffi","ffl","parenleftinferior","parenrightinferior","hyphensuperior","colonmonetary","onefitted","rupiah","centoldstyle","figuredash","hypheninferior","onequarter","onehalf","threequarters","oneeighth","threeeighths","fiveeighths","seveneighths","onethird","twothirds","zerosuperior","onesuperior","twosuperior","threesuperior","foursuperior","fivesuperior","sixsuperior","sevensuperior","eightsuperior","ninesuperior","zeroinferior","oneinferior","twoinferior","threeinferior","fourinferior","fiveinferior","sixinferior","seveninferior","eightinferior","nineinferior","centinferior","dollarinferior","periodinferior","commainferior"],Ei=["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","space","exclamsmall","Hungarumlautsmall","","dollaroldstyle","dollarsuperior","ampersandsmall","Acutesmall","parenleftsuperior","parenrightsuperior","twodotenleader","onedotenleader","comma","hyphen","period","fraction","zerooldstyle","oneoldstyle","twooldstyle","threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle","sevenoldstyle","eightoldstyle","nineoldstyle","colon","semicolon","commasuperior","threequartersemdash","periodsuperior","questionsmall","","asuperior","bsuperior","centsuperior","dsuperior","esuperior","","","","isuperior","","","lsuperior","msuperior","nsuperior","osuperior","","","rsuperior","ssuperior","tsuperior","","ff","fi","fl","ffi","ffl","parenleftinferior","","parenrightinferior","Circumflexsmall","hyphensuperior","Gravesmall","Asmall","Bsmall","Csmall","Dsmall","Esmall","Fsmall","Gsmall","Hsmall","Ismall","Jsmall","Ksmall","Lsmall","Msmall","Nsmall","Osmall","Psmall","Qsmall","Rsmall","Ssmall","Tsmall","Usmall","Vsmall","Wsmall","Xsmall","Ysmall","Zsmall","colonmonetary","onefitted","rupiah","Tildesmall","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","exclamdownsmall","centoldstyle","Lslashsmall","","","Scaronsmall","Zcaronsmall","Dieresissmall","Brevesmall","Caronsmall","","Dotaccentsmall","","","Macronsmall","","","figuredash","hypheninferior","","","Ogoneksmall","Ringsmall","Cedillasmall","","","","onequarter","onehalf","threequarters","questiondownsmall","oneeighth","threeeighths","fiveeighths","seveneighths","onethird","twothirds","","","zerosuperior","onesuperior","twosuperior","threesuperior","foursuperior","fivesuperior","sixsuperior","sevensuperior","eightsuperior","ninesuperior","zeroinferior","oneinferior","twoinferior","threeinferior","fourinferior","fiveinferior","sixinferior","seveninferior","eightinferior","nineinferior","centinferior","dollarinferior","periodinferior","commainferior","Agravesmall","Aacutesmall","Acircumflexsmall","Atildesmall","Adieresissmall","Aringsmall","AEsmall","Ccedillasmall","Egravesmall","Eacutesmall","Ecircumflexsmall","Edieresissmall","Igravesmall","Iacutesmall","Icircumflexsmall","Idieresissmall","Ethsmall","Ntildesmall","Ogravesmall","Oacutesmall","Ocircumflexsmall","Otildesmall","Odieresissmall","OEsmall","Oslashsmall","Ugravesmall","Uacutesmall","Ucircumflexsmall","Udieresissmall","Yacutesmall","Thornsmall","Ydieresissmall"],ui=["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","space","exclamsmall","Hungarumlautsmall","centoldstyle","dollaroldstyle","dollarsuperior","ampersandsmall","Acutesmall","parenleftsuperior","parenrightsuperior","twodotenleader","onedotenleader","comma","hyphen","period","fraction","zerooldstyle","oneoldstyle","twooldstyle","threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle","sevenoldstyle","eightoldstyle","nineoldstyle","colon","semicolon","","threequartersemdash","","questionsmall","","","","","Ethsmall","","","onequarter","onehalf","threequarters","oneeighth","threeeighths","fiveeighths","seveneighths","onethird","twothirds","","","","","","","ff","fi","fl","ffi","ffl","parenleftinferior","","parenrightinferior","Circumflexsmall","hypheninferior","Gravesmall","Asmall","Bsmall","Csmall","Dsmall","Esmall","Fsmall","Gsmall","Hsmall","Ismall","Jsmall","Ksmall","Lsmall","Msmall","Nsmall","Osmall","Psmall","Qsmall","Rsmall","Ssmall","Tsmall","Usmall","Vsmall","Wsmall","Xsmall","Ysmall","Zsmall","colonmonetary","onefitted","rupiah","Tildesmall","","","asuperior","centsuperior","","","","","Aacutesmall","Agravesmall","Acircumflexsmall","Adieresissmall","Atildesmall","Aringsmall","Ccedillasmall","Eacutesmall","Egravesmall","Ecircumflexsmall","Edieresissmall","Iacutesmall","Igravesmall","Icircumflexsmall","Idieresissmall","Ntildesmall","Oacutesmall","Ogravesmall","Ocircumflexsmall","Odieresissmall","Otildesmall","Uacutesmall","Ugravesmall","Ucircumflexsmall","Udieresissmall","","eightsuperior","fourinferior","threeinferior","sixinferior","eightinferior","seveninferior","Scaronsmall","","centinferior","twoinferior","","Dieresissmall","","Caronsmall","osuperior","fiveinferior","","commainferior","periodinferior","Yacutesmall","","dollarinferior","","","Thornsmall","","nineinferior","zeroinferior","Zcaronsmall","AEsmall","Oslashsmall","questiondownsmall","oneinferior","Lslashsmall","","","","","","","Cedillasmall","","","","","","OEsmall","figuredash","hyphensuperior","","","","","exclamdownsmall","","Ydieresissmall","","onesuperior","twosuperior","threesuperior","foursuperior","fivesuperior","sixsuperior","sevensuperior","ninesuperior","zerosuperior","","esuperior","rsuperior","tsuperior","","","isuperior","ssuperior","dsuperior","","","","","","lsuperior","Ogoneksmall","Brevesmall","Macronsmall","bsuperior","nsuperior","msuperior","commasuperior","periodsuperior","Dotaccentsmall","Ringsmall","","","",""],di=["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quotesingle","parenleft","parenright","asterisk","plus","comma","hyphen","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","at","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft","backslash","bracketright","asciicircum","underscore","grave","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde","","Adieresis","Aring","Ccedilla","Eacute","Ntilde","Odieresis","Udieresis","aacute","agrave","acircumflex","adieresis","atilde","aring","ccedilla","eacute","egrave","ecircumflex","edieresis","iacute","igrave","icircumflex","idieresis","ntilde","oacute","ograve","ocircumflex","odieresis","otilde","uacute","ugrave","ucircumflex","udieresis","dagger","degree","cent","sterling","section","bullet","paragraph","germandbls","registered","copyright","trademark","acute","dieresis","notequal","AE","Oslash","infinity","plusminus","lessequal","greaterequal","yen","mu","partialdiff","summation","product","pi","integral","ordfeminine","ordmasculine","Omega","ae","oslash","questiondown","exclamdown","logicalnot","radical","florin","approxequal","Delta","guillemotleft","guillemotright","ellipsis","space","Agrave","Atilde","Otilde","OE","oe","endash","emdash","quotedblleft","quotedblright","quoteleft","quoteright","divide","lozenge","ydieresis","Ydieresis","fraction","currency","guilsinglleft","guilsinglright","fi","fl","daggerdbl","periodcentered","quotesinglbase","quotedblbase","perthousand","Acircumflex","Ecircumflex","Aacute","Edieresis","Egrave","Iacute","Icircumflex","Idieresis","Igrave","Oacute","Ocircumflex","apple","Ograve","Uacute","Ucircumflex","Ugrave","dotlessi","circumflex","tilde","macron","breve","dotaccent","ring","cedilla","hungarumlaut","ogonek","caron"],fi=["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quoteright","parenleft","parenright","asterisk","plus","comma","hyphen","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","at","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft","backslash","bracketright","asciicircum","underscore","quoteleft","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","exclamdown","cent","sterling","fraction","yen","florin","section","currency","quotesingle","quotedblleft","guillemotleft","guilsinglleft","guilsinglright","fi","fl","","endash","dagger","daggerdbl","periodcentered","","paragraph","bullet","quotesinglbase","quotedblbase","quotedblright","guillemotright","ellipsis","perthousand","","questiondown","","grave","acute","circumflex","tilde","macron","breve","dotaccent","dieresis","","ring","cedilla","","hungarumlaut","ogonek","caron","emdash","","","","","","","","","","","","","","","","","AE","","ordfeminine","","","","","Lslash","Oslash","OE","ordmasculine","","","","","","ae","","","","dotlessi","","","lslash","oslash","oe","germandbls","","","",""],pi=["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quotesingle","parenleft","parenright","asterisk","plus","comma","hyphen","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","at","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft","backslash","bracketright","asciicircum","underscore","grave","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde","bullet","Euro","bullet","quotesinglbase","florin","quotedblbase","ellipsis","dagger","daggerdbl","circumflex","perthousand","Scaron","guilsinglleft","OE","bullet","Zcaron","bullet","bullet","quoteleft","quoteright","quotedblleft","quotedblright","bullet","endash","emdash","tilde","trademark","scaron","guilsinglright","oe","bullet","zcaron","Ydieresis","space","exclamdown","cent","sterling","currency","yen","brokenbar","section","dieresis","copyright","ordfeminine","guillemotleft","logicalnot","hyphen","registered","macron","degree","plusminus","twosuperior","threesuperior","acute","mu","paragraph","periodcentered","cedilla","onesuperior","ordmasculine","guillemotright","onequarter","onehalf","threequarters","questiondown","Agrave","Aacute","Acircumflex","Atilde","Adieresis","Aring","AE","Ccedilla","Egrave","Eacute","Ecircumflex","Edieresis","Igrave","Iacute","Icircumflex","Idieresis","Eth","Ntilde","Ograve","Oacute","Ocircumflex","Otilde","Odieresis","multiply","Oslash","Ugrave","Uacute","Ucircumflex","Udieresis","Yacute","Thorn","germandbls","agrave","aacute","acircumflex","atilde","adieresis","aring","ae","ccedilla","egrave","eacute","ecircumflex","edieresis","igrave","iacute","icircumflex","idieresis","eth","ntilde","ograve","oacute","ocircumflex","otilde","odieresis","divide","oslash","ugrave","uacute","ucircumflex","udieresis","yacute","thorn","ydieresis"],mi=["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","space","exclam","universal","numbersign","existential","percent","ampersand","suchthat","parenleft","parenright","asteriskmath","plus","comma","minus","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","congruent","Alpha","Beta","Chi","Delta","Epsilon","Phi","Gamma","Eta","Iota","theta1","Kappa","Lambda","Mu","Nu","Omicron","Pi","Theta","Rho","Sigma","Tau","Upsilon","sigma1","Omega","Xi","Psi","Zeta","bracketleft","therefore","bracketright","perpendicular","underscore","radicalex","alpha","beta","chi","delta","epsilon","phi","gamma","eta","iota","phi1","kappa","lambda","mu","nu","omicron","pi","theta","rho","sigma","tau","upsilon","omega1","omega","xi","psi","zeta","braceleft","bar","braceright","similar","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Euro","Upsilon1","minute","lessequal","fraction","infinity","florin","club","diamond","heart","spade","arrowboth","arrowleft","arrowup","arrowright","arrowdown","degree","plusminus","second","greaterequal","multiply","proportional","partialdiff","bullet","divide","notequal","equivalence","approxequal","ellipsis","arrowvertex","arrowhorizex","carriagereturn","aleph","Ifraktur","Rfraktur","weierstrass","circlemultiply","circleplus","emptyset","intersection","union","propersuperset","reflexsuperset","notsubset","propersubset","reflexsubset","element","notelement","angle","gradient","registerserif","copyrightserif","trademarkserif","product","radical","dotmath","logicalnot","logicaland","logicalor","arrowdblboth","arrowdblleft","arrowdblup","arrowdblright","arrowdbldown","lozenge","angleleft","registersans","copyrightsans","trademarksans","summation","parenlefttp","parenleftex","parenleftbt","bracketlefttp","bracketleftex","bracketleftbt","bracelefttp","braceleftmid","braceleftbt","braceex","","angleright","integral","integraltp","integralex","integralbt","parenrighttp","parenrightex","parenrightbt","bracketrighttp","bracketrightex","bracketrightbt","bracerighttp","bracerightmid","bracerightbt",""],yi=["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","space","a1","a2","a202","a3","a4","a5","a119","a118","a117","a11","a12","a13","a14","a15","a16","a105","a17","a18","a19","a20","a21","a22","a23","a24","a25","a26","a27","a28","a6","a7","a8","a9","a10","a29","a30","a31","a32","a33","a34","a35","a36","a37","a38","a39","a40","a41","a42","a43","a44","a45","a46","a47","a48","a49","a50","a51","a52","a53","a54","a55","a56","a57","a58","a59","a60","a61","a62","a63","a64","a65","a66","a67","a68","a69","a70","a71","a72","a73","a74","a203","a75","a204","a76","a77","a78","a79","a81","a82","a83","a84","a97","a98","a99","a100","","a89","a90","a93","a94","a91","a92","a205","a85","a206","a86","a87","a88","a95","a96","","","","","","","","","","","","","","","","","","","","a101","a102","a103","a104","a106","a107","a108","a112","a111","a110","a109","a120","a121","a122","a123","a124","a125","a126","a127","a128","a129","a130","a131","a132","a133","a134","a135","a136","a137","a138","a139","a140","a141","a142","a143","a144","a145","a146","a147","a148","a149","a150","a151","a152","a153","a154","a155","a156","a157","a158","a159","a160","a161","a163","a164","a196","a165","a192","a166","a167","a168","a169","a170","a171","a172","a173","a162","a174","a175","a176","a177","a178","a179","a193","a180","a199","a181","a200","a182","","a201","a183","a184","a197","a185","a194","a198","a186","a195","a187","a188","a189","a190","a191",""];function getEncoding(e){switch(e){case"WinAnsiEncoding":return pi;case"StandardEncoding":return fi;case"MacRomanEncoding":return di;case"SymbolSetEncoding":return mi;case"ZapfDingbatsEncoding":return yi;case"ExpertEncoding":return Ei;case"MacExpertEncoding":return ui;default:return null}}const wi=[".notdef","space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quoteright","parenleft","parenright","asterisk","plus","comma","hyphen","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","at","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft","backslash","bracketright","asciicircum","underscore","quoteleft","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde","exclamdown","cent","sterling","fraction","yen","florin","section","currency","quotesingle","quotedblleft","guillemotleft","guilsinglleft","guilsinglright","fi","fl","endash","dagger","daggerdbl","periodcentered","paragraph","bullet","quotesinglbase","quotedblbase","quotedblright","guillemotright","ellipsis","perthousand","questiondown","grave","acute","circumflex","tilde","macron","breve","dotaccent","dieresis","ring","cedilla","hungarumlaut","ogonek","caron","emdash","AE","ordfeminine","Lslash","Oslash","OE","ordmasculine","ae","dotlessi","lslash","oslash","oe","germandbls","onesuperior","logicalnot","mu","trademark","Eth","onehalf","plusminus","Thorn","onequarter","divide","brokenbar","degree","thorn","threequarters","twosuperior","registered","minus","eth","multiply","threesuperior","copyright","Aacute","Acircumflex","Adieresis","Agrave","Aring","Atilde","Ccedilla","Eacute","Ecircumflex","Edieresis","Egrave","Iacute","Icircumflex","Idieresis","Igrave","Ntilde","Oacute","Ocircumflex","Odieresis","Ograve","Otilde","Scaron","Uacute","Ucircumflex","Udieresis","Ugrave","Yacute","Ydieresis","Zcaron","aacute","acircumflex","adieresis","agrave","aring","atilde","ccedilla","eacute","ecircumflex","edieresis","egrave","iacute","icircumflex","idieresis","igrave","ntilde","oacute","ocircumflex","odieresis","ograve","otilde","scaron","uacute","ucircumflex","udieresis","ugrave","yacute","ydieresis","zcaron","exclamsmall","Hungarumlautsmall","dollaroldstyle","dollarsuperior","ampersandsmall","Acutesmall","parenleftsuperior","parenrightsuperior","twodotenleader","onedotenleader","zerooldstyle","oneoldstyle","twooldstyle","threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle","sevenoldstyle","eightoldstyle","nineoldstyle","commasuperior","threequartersemdash","periodsuperior","questionsmall","asuperior","bsuperior","centsuperior","dsuperior","esuperior","isuperior","lsuperior","msuperior","nsuperior","osuperior","rsuperior","ssuperior","tsuperior","ff","ffi","ffl","parenleftinferior","parenrightinferior","Circumflexsmall","hyphensuperior","Gravesmall","Asmall","Bsmall","Csmall","Dsmall","Esmall","Fsmall","Gsmall","Hsmall","Ismall","Jsmall","Ksmall","Lsmall","Msmall","Nsmall","Osmall","Psmall","Qsmall","Rsmall","Ssmall","Tsmall","Usmall","Vsmall","Wsmall","Xsmall","Ysmall","Zsmall","colonmonetary","onefitted","rupiah","Tildesmall","exclamdownsmall","centoldstyle","Lslashsmall","Scaronsmall","Zcaronsmall","Dieresissmall","Brevesmall","Caronsmall","Dotaccentsmall","Macronsmall","figuredash","hypheninferior","Ogoneksmall","Ringsmall","Cedillasmall","questiondownsmall","oneeighth","threeeighths","fiveeighths","seveneighths","onethird","twothirds","zerosuperior","foursuperior","fivesuperior","sixsuperior","sevensuperior","eightsuperior","ninesuperior","zeroinferior","oneinferior","twoinferior","threeinferior","fourinferior","fiveinferior","sixinferior","seveninferior","eightinferior","nineinferior","centinferior","dollarinferior","periodinferior","commainferior","Agravesmall","Aacutesmall","Acircumflexsmall","Atildesmall","Adieresissmall","Aringsmall","AEsmall","Ccedillasmall","Egravesmall","Eacutesmall","Ecircumflexsmall","Edieresissmall","Igravesmall","Iacutesmall","Icircumflexsmall","Idieresissmall","Ethsmall","Ntildesmall","Ogravesmall","Oacutesmall","Ocircumflexsmall","Otildesmall","Odieresissmall","OEsmall","Oslashsmall","Ugravesmall","Uacutesmall","Ucircumflexsmall","Udieresissmall","Yacutesmall","Thornsmall","Ydieresissmall","001.000","001.001","001.002","001.003","Black","Bold","Book","Light","Medium","Regular","Roman","Semibold"],bi=391,Di=[null,{id:"hstem",min:2,stackClearing:!0,stem:!0},null,{id:"vstem",min:2,stackClearing:!0,stem:!0},{id:"vmoveto",min:1,stackClearing:!0},{id:"rlineto",min:2,resetStack:!0},{id:"hlineto",min:1,resetStack:!0},{id:"vlineto",min:1,resetStack:!0},{id:"rrcurveto",min:6,resetStack:!0},null,{id:"callsubr",min:1,undefStack:!0},{id:"return",min:0,undefStack:!0},null,null,{id:"endchar",min:0,stackClearing:!0},null,null,null,{id:"hstemhm",min:2,stackClearing:!0,stem:!0},{id:"hintmask",min:0,stackClearing:!0},{id:"cntrmask",min:0,stackClearing:!0},{id:"rmoveto",min:2,stackClearing:!0},{id:"hmoveto",min:1,stackClearing:!0},{id:"vstemhm",min:2,stackClearing:!0,stem:!0},{id:"rcurveline",min:8,resetStack:!0},{id:"rlinecurve",min:8,resetStack:!0},{id:"vvcurveto",min:4,resetStack:!0},{id:"hhcurveto",min:4,resetStack:!0},null,{id:"callgsubr",min:1,undefStack:!0},{id:"vhcurveto",min:4,resetStack:!0},{id:"hvcurveto",min:4,resetStack:!0}],Fi=[null,null,null,{id:"and",min:2,stackDelta:-1},{id:"or",min:2,stackDelta:-1},{id:"not",min:1,stackDelta:0},null,null,null,{id:"abs",min:1,stackDelta:0},{id:"add",min:2,stackDelta:-1,stackFn(e,t){e[t-2]=e[t-2]+e[t-1]}},{id:"sub",min:2,stackDelta:-1,stackFn(e,t){e[t-2]=e[t-2]-e[t-1]}},{id:"div",min:2,stackDelta:-1,stackFn(e,t){e[t-2]=e[t-2]/e[t-1]}},null,{id:"neg",min:1,stackDelta:0,stackFn(e,t){e[t-1]=-e[t-1]}},{id:"eq",min:2,stackDelta:-1},null,null,{id:"drop",min:1,stackDelta:-1},null,{id:"put",min:2,stackDelta:-2},{id:"get",min:1,stackDelta:0},{id:"ifelse",min:4,stackDelta:-3},{id:"random",min:0,stackDelta:1},{id:"mul",min:2,stackDelta:-1,stackFn(e,t){e[t-2]=e[t-2]*e[t-1]}},null,{id:"sqrt",min:1,stackDelta:0},{id:"dup",min:1,stackDelta:1},{id:"exch",min:2,stackDelta:0},{id:"index",min:2,stackDelta:0},{id:"roll",min:3,stackDelta:-2},null,null,null,{id:"hflex",min:7,resetStack:!0},{id:"flex",min:13,resetStack:!0},{id:"hflex1",min:9,resetStack:!0},{id:"flex1",min:11,resetStack:!0}];class CFFParser{constructor(e,t,i){this.bytes=e.getBytes();this.properties=t;this.seacAnalysisEnabled=!!i}parse(){const e=this.properties,t=new CFF;this.cff=t;const i=this.parseHeader(),a=this.parseIndex(i.endPos),s=this.parseIndex(a.endPos),r=this.parseIndex(s.endPos),n=this.parseIndex(r.endPos),o=this.parseDict(s.obj.get(0)),g=this.createDict(CFFTopDict,o,t.strings);t.header=i.obj;t.names=this.parseNameIndex(a.obj);t.strings=this.parseStringIndex(r.obj);t.topDict=g;t.globalSubrIndex=n.obj;this.parsePrivateDict(t.topDict);t.isCIDFont=g.hasName("ROS");const c=g.getByName("CharStrings"),h=this.parseIndex(c).obj,l=g.getByName("FontMatrix");l&&(e.fontMatrix=l);const C=g.getByName("FontBBox");if(C){e.ascent=Math.max(C[3],C[1]);e.descent=Math.min(C[1],C[3]);e.ascentScaled=!0}let Q,E;if(t.isCIDFont){const e=this.parseIndex(g.getByName("FDArray")).obj;for(let i=0,a=e.count;i<a;++i){const a=e.get(i),s=this.createDict(CFFTopDict,this.parseDict(a),t.strings);this.parsePrivateDict(s);t.fdArray.push(s)}E=null;Q=this.parseCharsets(g.getByName("charset"),h.count,t.strings,!0);t.fdSelect=this.parseFDSelect(g.getByName("FDSelect"),h.count)}else{Q=this.parseCharsets(g.getByName("charset"),h.count,t.strings,!1);E=this.parseEncoding(g.getByName("Encoding"),e,t.strings,Q.charset)}t.charset=Q;t.encoding=E;const u=this.parseCharStrings({charStrings:h,localSubrIndex:g.privateDict.subrsIndex,globalSubrIndex:n.obj,fdSelect:t.fdSelect,fdArray:t.fdArray,privateDict:g.privateDict});t.charStrings=u.charStrings;t.seacs=u.seacs;t.widths=u.widths;return t}parseHeader(){let e=this.bytes;const t=e.length;let i=0;for(;i<t&&1!==e[i];)++i;if(i>=t)throw new FormatError("Invalid CFF header");if(0!==i){info("cff data is shifted");e=e.subarray(i);this.bytes=e}const a=e[0],s=e[1],r=e[2],n=e[3];return{obj:new CFFHeader(a,s,r,n),endPos:r}}parseDict(e){let t=0;function parseOperand(){let i=e[t++];if(30===i)return function parseFloatOperand(){let i="";const a=15,s=["0","1","2","3","4","5","6","7","8","9",".","E","E-",null,"-"],r=e.length;for(;t<r;){const r=e[t++],n=r>>4,o=15&r;if(n===a)break;i+=s[n];if(o===a)break;i+=s[o]}return parseFloat(i)}();if(28===i){i=e[t++];i=(i<<24|e[t++]<<16)>>16;return i}if(29===i){i=e[t++];i=i<<8|e[t++];i=i<<8|e[t++];i=i<<8|e[t++];return i}if(i>=32&&i<=246)return i-139;if(i>=247&&i<=250)return 256*(i-247)+e[t++]+108;if(i>=251&&i<=254)return-256*(i-251)-e[t++]-108;warn('CFFParser_parseDict: "'+i+'" is a reserved command.');return NaN}let i=[];const a=[];t=0;const s=e.length;for(;t<s;){let s=e[t];if(s<=21){12===s&&(s=s<<8|e[++t]);a.push([s,i]);i=[];++t}else i.push(parseOperand())}return a}parseIndex(e){const t=new CFFIndex,i=this.bytes,a=i[e++]<<8|i[e++],s=[];let r,n,o=e;if(0!==a){const t=i[e++],g=e+(a+1)*t-1;for(r=0,n=a+1;r<n;++r){let a=0;for(let s=0;s<t;++s){a<<=8;a+=i[e++]}s.push(g+a)}o=s[a]}for(r=0,n=s.length-1;r<n;++r){const e=s[r],a=s[r+1];t.add(i.subarray(e,a))}return{obj:t,endPos:o}}parseNameIndex(e){const t=[];for(let i=0,a=e.count;i<a;++i){const a=e.get(i);t.push(bytesToString(a))}return t}parseStringIndex(e){const t=new CFFStrings;for(let i=0,a=e.count;i<a;++i){const a=e.get(i);t.add(bytesToString(a))}return t}createDict(e,t,i){const a=new e(i);for(const[e,i]of t)a.setByKey(e,i);return a}parseCharString(e,t,i,a){if(!t||e.callDepth>10)return!1;let s=e.stackSize;const r=e.stack;let n=t.length;for(let o=0;o<n;){const g=t[o++];let c=null;if(12===g){const e=t[o++];if(0===e){t[o-2]=139;t[o-1]=22;s=0}else c=Fi[e]}else if(28===g){r[s]=(t[o]<<24|t[o+1]<<16)>>16;o+=2;s++}else if(14===g){if(s>=4){s-=4;if(this.seacAnalysisEnabled){e.seac=r.slice(s,s+4);return!1}}c=Di[g]}else if(g>=32&&g<=246){r[s]=g-139;s++}else if(g>=247&&g<=254){r[s]=g<251?(g-247<<8)+t[o]+108:-(g-251<<8)-t[o]-108;o++;s++}else if(255===g){r[s]=(t[o]<<24|t[o+1]<<16|t[o+2]<<8|t[o+3])/65536;o+=4;s++}else if(19===g||20===g){e.hints+=s>>1;if(0===e.hints){t.copyWithin(o-1,o,-1);o-=1;n-=1;continue}o+=e.hints+7>>3;s%=2;c=Di[g]}else{if(10===g||29===g){const t=10===g?i:a;if(!t){c=Di[g];warn("Missing subrsIndex for "+c.id);return!1}let n=32768;t.count<1240?n=107:t.count<33900&&(n=1131);const o=r[--s]+n;if(o<0||o>=t.count||isNaN(o)){c=Di[g];warn("Out of bounds subrIndex for "+c.id);return!1}e.stackSize=s;e.callDepth++;if(!this.parseCharString(e,t.get(o),i,a))return!1;e.callDepth--;s=e.stackSize;continue}if(11===g){e.stackSize=s;return!0}if(0===g&&o===t.length){t[o-1]=14;c=Di[14]}else{if(9===g){t.copyWithin(o-1,o,-1);o-=1;n-=1;continue}c=Di[g]}}if(c){if(c.stem){e.hints+=s>>1;if(3===g||23===g)e.hasVStems=!0;else if(e.hasVStems&&(1===g||18===g)){warn("CFF stem hints are in wrong order");t[o-1]=1===g?3:23}}if("min"in c&&!e.undefStack&&s<c.min){warn("Not enough parameters for "+c.id+"; actual: "+s+", expected: "+c.min);if(0===s){t[o-1]=14;return!0}return!1}if(e.firstStackClearing&&c.stackClearing){e.firstStackClearing=!1;s-=c.min;s>=2&&c.stem?s%=2:s>1&&warn("Found too many parameters for stack-clearing command");s>0&&(e.width=r[s-1])}if("stackDelta"in c){"stackFn"in c&&c.stackFn(r,s);s+=c.stackDelta}else if(c.stackClearing)s=0;else if(c.resetStack){s=0;e.undefStack=!1}else if(c.undefStack){s=0;e.undefStack=!0;e.firstStackClearing=!1}}}n<t.length&&t.fill(14,n);e.stackSize=s;return!0}parseCharStrings({charStrings:e,localSubrIndex:t,globalSubrIndex:i,fdSelect:a,fdArray:s,privateDict:r}){const n=[],o=[],g=e.count;for(let c=0;c<g;c++){const g=e.get(c),h={callDepth:0,stackSize:0,stack:[],undefStack:!0,hints:0,firstStackClearing:!0,seac:null,width:null,hasVStems:!1};let l=!0,C=null,Q=r;if(a&&s.length){const e=a.getFDIndex(c);if(-1===e){warn("Glyph index is not in fd select.");l=!1}if(e>=s.length){warn("Invalid fd index for glyph index.");l=!1}if(l){Q=s[e].privateDict;C=Q.subrsIndex}}else t&&(C=t);l&&(l=this.parseCharString(h,g,C,i));if(null!==h.width){const e=Q.getByName("nominalWidthX");o[c]=e+h.width}else{const e=Q.getByName("defaultWidthX");o[c]=e}null!==h.seac&&(n[c]=h.seac);l||e.set(c,new Uint8Array([14]))}return{charStrings:e,seacs:n,widths:o}}emptyPrivateDictionary(e){const t=this.createDict(CFFPrivateDict,[],e.strings);e.setByKey(18,[0,0]);e.privateDict=t}parsePrivateDict(e){if(!e.hasName("Private")){this.emptyPrivateDictionary(e);return}const t=e.getByName("Private");if(!Array.isArray(t)||2!==t.length){e.removeByName("Private");return}const i=t[0],a=t[1];if(0===i||a>=this.bytes.length){this.emptyPrivateDictionary(e);return}const s=a+i,r=this.bytes.subarray(a,s),n=this.parseDict(r),o=this.createDict(CFFPrivateDict,n,e.strings);e.privateDict=o;0===o.getByName("ExpansionFactor")&&o.setByName("ExpansionFactor",.06);if(!o.getByName("Subrs"))return;const g=o.getByName("Subrs"),c=a+g;if(0===g||c>=this.bytes.length){this.emptyPrivateDictionary(e);return}const h=this.parseIndex(c);o.subrsIndex=h.obj}parseCharsets(e,t,i,a){if(0===e)return new CFFCharset(!0,Ri.ISO_ADOBE,Ci);if(1===e)return new CFFCharset(!0,Ri.EXPERT,Bi);if(2===e)return new CFFCharset(!0,Ri.EXPERT_SUBSET,Qi);const s=this.bytes,r=e,n=s[e++],o=[a?0:".notdef"];let g,c,h;t-=1;switch(n){case 0:for(h=0;h<t;h++){g=s[e++]<<8|s[e++];o.push(a?g:i.get(g))}break;case 1:for(;o.length<=t;){g=s[e++]<<8|s[e++];c=s[e++];for(h=0;h<=c;h++)o.push(a?g++:i.get(g++))}break;case 2:for(;o.length<=t;){g=s[e++]<<8|s[e++];c=s[e++]<<8|s[e++];for(h=0;h<=c;h++)o.push(a?g++:i.get(g++))}break;default:throw new FormatError("Unknown charset format")}const l=e,C=s.subarray(r,l);return new CFFCharset(!1,n,o,C)}parseEncoding(e,t,i,a){const s=Object.create(null),r=this.bytes;let n,o,g,c=!1,h=null;if(0===e||1===e){c=!0;n=e;const t=e?Ei:fi;for(o=0,g=a.length;o<g;o++){const e=t.indexOf(a[o]);-1!==e&&(s[e]=o)}}else{const t=e;n=r[e++];switch(127&n){case 0:const t=r[e++];for(o=1;o<=t;o++)s[r[e++]]=o;break;case 1:const i=r[e++];let a=1;for(o=0;o<i;o++){const t=r[e++],i=r[e++];for(let e=t;e<=t+i;e++)s[e]=a++}break;default:throw new FormatError(`Unknown encoding format: ${n} in CFF`)}const g=e;if(128&n){r[t]&=127;!function readSupplement(){const t=r[e++];for(o=0;o<t;o++){const t=r[e++],n=(r[e++]<<8)+(255&r[e++]);s[t]=a.indexOf(i.get(n))}}()}h=r.subarray(t,g)}n&=127;return new CFFEncoding(c,n,s,h)}parseFDSelect(e,t){const i=this.bytes,a=i[e++],s=[];let r;switch(a){case 0:for(r=0;r<t;++r){const t=i[e++];s.push(t)}break;case 3:const n=i[e++]<<8|i[e++];for(r=0;r<n;++r){let t=i[e++]<<8|i[e++];if(0===r&&0!==t){warn("parseFDSelect: The first range must have a first GID of 0 -- trying to recover.");t=0}const a=i[e++],n=i[e]<<8|i[e+1];for(let e=t;e<n;++e)s.push(a)}e+=2;break;default:throw new FormatError(`parseFDSelect: Unknown format "${a}".`)}if(s.length!==t)throw new FormatError("parseFDSelect: Invalid font data.");return new CFFFDSelect(a,s)}}class CFF{constructor(){this.header=null;this.names=[];this.topDict=null;this.strings=new CFFStrings;this.globalSubrIndex=null;this.encoding=null;this.charset=null;this.charStrings=null;this.fdArray=[];this.fdSelect=null;this.isCIDFont=!1}duplicateFirstGlyph(){if(this.charStrings.count>=65535){warn("Not enough space in charstrings to duplicate first glyph.");return}const e=this.charStrings.get(0);this.charStrings.add(e);this.isCIDFont&&this.fdSelect.fdSelect.push(this.fdSelect.fdSelect[0])}hasGlyphId(e){if(e<0||e>=this.charStrings.count)return!1;return this.charStrings.get(e).length>0}}class CFFHeader{constructor(e,t,i,a){this.major=e;this.minor=t;this.hdrSize=i;this.offSize=a}}class CFFStrings{constructor(){this.strings=[]}get(e){return e>=0&&e<=390?wi[e]:e-bi<=this.strings.length?this.strings[e-bi]:wi[0]}getSID(e){let t=wi.indexOf(e);if(-1!==t)return t;t=this.strings.indexOf(e);return-1!==t?t+bi:-1}add(e){this.strings.push(e)}get count(){return this.strings.length}}class CFFIndex{constructor(){this.objects=[];this.length=0}add(e){this.length+=e.length;this.objects.push(e)}set(e,t){this.length+=t.length-this.objects[e].length;this.objects[e]=t}get(e){return this.objects[e]}get count(){return this.objects.length}}class CFFDict{constructor(e,t){this.keyToNameMap=e.keyToNameMap;this.nameToKeyMap=e.nameToKeyMap;this.defaults=e.defaults;this.types=e.types;this.opcodes=e.opcodes;this.order=e.order;this.strings=t;this.values=Object.create(null)}setByKey(e,t){if(!(e in this.keyToNameMap))return!1;if(0===t.length)return!0;for(const i of t)if(isNaN(i)){warn(`Invalid CFFDict value: "${t}" for key "${e}".`);return!0}const i=this.types[e];"num"!==i&&"sid"!==i&&"offset"!==i||(t=t[0]);this.values[e]=t;return!0}setByName(e,t){if(!(e in this.nameToKeyMap))throw new FormatError(`Invalid dictionary name "${e}"`);this.values[this.nameToKeyMap[e]]=t}hasName(e){return this.nameToKeyMap[e]in this.values}getByName(e){if(!(e in this.nameToKeyMap))throw new FormatError(`Invalid dictionary name ${e}"`);const t=this.nameToKeyMap[e];return t in this.values?this.values[t]:this.defaults[t]}removeByName(e){delete this.values[this.nameToKeyMap[e]]}static createTables(e){const t={keyToNameMap:{},nameToKeyMap:{},defaults:{},types:{},opcodes:{},order:[]};for(const i of e){const e=Array.isArray(i[0])?(i[0][0]<<8)+i[0][1]:i[0];t.keyToNameMap[e]=i[1];t.nameToKeyMap[i[1]]=e;t.types[e]=i[2];t.defaults[e]=i[3];t.opcodes[e]=Array.isArray(i[0])?i[0]:[i[0]];t.order.push(e)}return t}}const Si=[[[12,30],"ROS",["sid","sid","num"],null],[[12,20],"SyntheticBase","num",null],[0,"version","sid",null],[1,"Notice","sid",null],[[12,0],"Copyright","sid",null],[2,"FullName","sid",null],[3,"FamilyName","sid",null],[4,"Weight","sid",null],[[12,1],"isFixedPitch","num",0],[[12,2],"ItalicAngle","num",0],[[12,3],"UnderlinePosition","num",-100],[[12,4],"UnderlineThickness","num",50],[[12,5],"PaintType","num",0],[[12,6],"CharstringType","num",2],[[12,7],"FontMatrix",["num","num","num","num","num","num"],[.001,0,0,.001,0,0]],[13,"UniqueID","num",null],[5,"FontBBox",["num","num","num","num"],[0,0,0,0]],[[12,8],"StrokeWidth","num",0],[14,"XUID","array",null],[15,"charset","offset",0],[16,"Encoding","offset",0],[17,"CharStrings","offset",0],[18,"Private",["offset","offset"],null],[[12,21],"PostScript","sid",null],[[12,22],"BaseFontName","sid",null],[[12,23],"BaseFontBlend","delta",null],[[12,31],"CIDFontVersion","num",0],[[12,32],"CIDFontRevision","num",0],[[12,33],"CIDFontType","num",0],[[12,34],"CIDCount","num",8720],[[12,35],"UIDBase","num",null],[[12,37],"FDSelect","offset",null],[[12,36],"FDArray","offset",null],[[12,38],"FontName","sid",null]];class CFFTopDict extends CFFDict{static get tables(){return shadow(this,"tables",this.createTables(Si))}constructor(e){super(CFFTopDict.tables,e);this.privateDict=null}}const ki=[[6,"BlueValues","delta",null],[7,"OtherBlues","delta",null],[8,"FamilyBlues","delta",null],[9,"FamilyOtherBlues","delta",null],[[12,9],"BlueScale","num",.039625],[[12,10],"BlueShift","num",7],[[12,11],"BlueFuzz","num",1],[10,"StdHW","num",null],[11,"StdVW","num",null],[[12,12],"StemSnapH","delta",null],[[12,13],"StemSnapV","delta",null],[[12,14],"ForceBold","num",0],[[12,17],"LanguageGroup","num",0],[[12,18],"ExpansionFactor","num",.06],[[12,19],"initialRandomSeed","num",0],[20,"defaultWidthX","num",0],[21,"nominalWidthX","num",0],[19,"Subrs","offset",null]];class CFFPrivateDict extends CFFDict{static get tables(){return shadow(this,"tables",this.createTables(ki))}constructor(e){super(CFFPrivateDict.tables,e);this.subrsIndex=null}}const Ri={ISO_ADOBE:0,EXPERT:1,EXPERT_SUBSET:2};class CFFCharset{constructor(e,t,i,a){this.predefined=e;this.format=t;this.charset=i;this.raw=a}}class CFFEncoding{constructor(e,t,i,a){this.predefined=e;this.format=t;this.encoding=i;this.raw=a}}class CFFFDSelect{constructor(e,t){this.format=e;this.fdSelect=t}getFDIndex(e){return e<0||e>=this.fdSelect.length?-1:this.fdSelect[e]}}class CFFOffsetTracker{constructor(){this.offsets=Object.create(null)}isTracking(e){return e in this.offsets}track(e,t){if(e in this.offsets)throw new FormatError(`Already tracking location of ${e}`);this.offsets[e]=t}offset(e){for(const t in this.offsets)this.offsets[t]+=e}setEntryLocation(e,t,i){if(!(e in this.offsets))throw new FormatError(`Not tracking location of ${e}`);const a=i.data,s=this.offsets[e];for(let e=0,i=t.length;e<i;++e){const i=5*e+s,r=i+1,n=i+2,o=i+3,g=i+4;if(29!==a[i]||0!==a[r]||0!==a[n]||0!==a[o]||0!==a[g])throw new FormatError("writing to an offset that is not empty");const c=t[e];a[i]=29;a[r]=c>>24&255;a[n]=c>>16&255;a[o]=c>>8&255;a[g]=255&c}}}class CFFCompiler{constructor(e){this.cff=e}compile(){const e=this.cff,t={data:[],length:0,add(e){try{this.data.push(...e)}catch{this.data=this.data.concat(e)}this.length=this.data.length}},i=this.compileHeader(e.header);t.add(i);const a=this.compileNameIndex(e.names);t.add(a);if(e.isCIDFont&&e.topDict.hasName("FontMatrix")){const t=e.topDict.getByName("FontMatrix");e.topDict.removeByName("FontMatrix");for(const i of e.fdArray){let e=t.slice(0);i.hasName("FontMatrix")&&(e=Util.transform(e,i.getByName("FontMatrix")));i.setByName("FontMatrix",e)}}const s=e.topDict.getByName("XUID");s?.length>16&&e.topDict.removeByName("XUID");e.topDict.setByName("charset",0);let r=this.compileTopDicts([e.topDict],t.length,e.isCIDFont);t.add(r.output);const n=r.trackers[0],o=this.compileStringIndex(e.strings.strings);t.add(o);const g=this.compileIndex(e.globalSubrIndex);t.add(g);if(e.encoding&&e.topDict.hasName("Encoding"))if(e.encoding.predefined)n.setEntryLocation("Encoding",[e.encoding.format],t);else{const i=this.compileEncoding(e.encoding);n.setEntryLocation("Encoding",[t.length],t);t.add(i)}const c=this.compileCharset(e.charset,e.charStrings.count,e.strings,e.isCIDFont);n.setEntryLocation("charset",[t.length],t);t.add(c);const h=this.compileCharStrings(e.charStrings);n.setEntryLocation("CharStrings",[t.length],t);t.add(h);if(e.isCIDFont){n.setEntryLocation("FDSelect",[t.length],t);const i=this.compileFDSelect(e.fdSelect);t.add(i);r=this.compileTopDicts(e.fdArray,t.length,!0);n.setEntryLocation("FDArray",[t.length],t);t.add(r.output);const a=r.trackers;this.compilePrivateDicts(e.fdArray,a,t)}this.compilePrivateDicts([e.topDict],[n],t);t.add([0]);return t.data}encodeNumber(e){return Number.isInteger(e)?this.encodeInteger(e):this.encodeFloat(e)}static get EncodeFloatRegExp(){return shadow(this,"EncodeFloatRegExp",/\.(\d*?)(?:9{5,20}|0{5,20})\d{0,2}(?:e(.+)|$)/)}encodeFloat(e){let t=e.toString();const i=CFFCompiler.EncodeFloatRegExp.exec(t);if(i){const a=parseFloat("1e"+((i[2]?+i[2]:0)+i[1].length));t=(Math.round(e*a)/a).toString()}let a,s,r="";for(a=0,s=t.length;a<s;++a){const e=t[a];r+="e"===e?"-"===t[++a]?"c":"b":"."===e?"a":"-"===e?"e":e}r+=1&r.length?"f":"ff";const n=[30];for(a=0,s=r.length;a<s;a+=2)n.push(parseInt(r.substring(a,a+2),16));return n}encodeInteger(e){let t;t=e>=-107&&e<=107?[e+139]:e>=108&&e<=1131?[247+((e-=108)>>8),255&e]:e>=-1131&&e<=-108?[251+((e=-e-108)>>8),255&e]:e>=-32768&&e<=32767?[28,e>>8&255,255&e]:[29,e>>24&255,e>>16&255,e>>8&255,255&e];return t}compileHeader(e){return[e.major,e.minor,4,e.offSize]}compileNameIndex(e){const t=new CFFIndex;for(const i of e){const e=Math.min(i.length,127);let a=new Array(e);for(let t=0;t<e;t++){let e=i[t];(e<"!"||e>"~"||"["===e||"]"===e||"("===e||")"===e||"{"===e||"}"===e||"<"===e||">"===e||"/"===e||"%"===e)&&(e="_");a[t]=e}a=a.join("");""===a&&(a="Bad_Font_Name");t.add(stringToBytes(a))}return this.compileIndex(t)}compileTopDicts(e,t,i){const a=[];let s=new CFFIndex;for(const r of e){if(i){r.removeByName("CIDFontVersion");r.removeByName("CIDFontRevision");r.removeByName("CIDFontType");r.removeByName("CIDCount");r.removeByName("UIDBase")}const e=new CFFOffsetTracker,n=this.compileDict(r,e);a.push(e);s.add(n);e.offset(t)}s=this.compileIndex(s,a);return{trackers:a,output:s}}compilePrivateDicts(e,t,i){for(let a=0,s=e.length;a<s;++a){const s=e[a],r=s.privateDict;if(!r||!s.hasName("Private"))throw new FormatError("There must be a private dictionary.");const n=new CFFOffsetTracker,o=this.compileDict(r,n);let g=i.length;n.offset(g);o.length||(g=0);t[a].setEntryLocation("Private",[o.length,g],i);i.add(o);if(r.subrsIndex&&r.hasName("Subrs")){const e=this.compileIndex(r.subrsIndex);n.setEntryLocation("Subrs",[o.length],i);i.add(e)}}}compileDict(e,t){const i=[];for(const a of e.order){if(!(a in e.values))continue;let s=e.values[a],r=e.types[a];Array.isArray(r)||(r=[r]);Array.isArray(s)||(s=[s]);if(0!==s.length){for(let n=0,o=r.length;n<o;++n){const o=r[n],g=s[n];switch(o){case"num":case"sid":i.push(...this.encodeNumber(g));break;case"offset":const r=e.keyToNameMap[a];t.isTracking(r)||t.track(r,i.length);i.push(29,0,0,0,0);break;case"array":case"delta":i.push(...this.encodeNumber(g));for(let e=1,t=s.length;e<t;++e)i.push(...this.encodeNumber(s[e]));break;default:throw new FormatError(`Unknown data type of ${o}`)}}i.push(...e.opcodes[a])}}return i}compileStringIndex(e){const t=new CFFIndex;for(const i of e)t.add(stringToBytes(i));return this.compileIndex(t)}compileCharStrings(e){const t=new CFFIndex;for(let i=0;i<e.count;i++){const a=e.get(i);0!==a.length?t.add(a):t.add(new Uint8Array([139,14]))}return this.compileIndex(t)}compileCharset(e,t,i,a){let s;const r=t-1;if(a)s=new Uint8Array([2,0,0,r>>8&255,255&r]);else{s=new Uint8Array(1+2*r);s[0]=0;let t=0;const a=e.charset.length;let n=!1;for(let r=1;r<s.length;r+=2){let o=0;if(t<a){const a=e.charset[t++];o=i.getSID(a);if(-1===o){o=0;if(!n){n=!0;warn(`Couldn't find ${a} in CFF strings`)}}}s[r]=o>>8&255;s[r+1]=255&o}}return this.compileTypedArray(s)}compileEncoding(e){return this.compileTypedArray(e.raw)}compileFDSelect(e){const t=e.format;let i,a;switch(t){case 0:i=new Uint8Array(1+e.fdSelect.length);i[0]=t;for(a=0;a<e.fdSelect.length;a++)i[a+1]=e.fdSelect[a];break;case 3:const s=0;let r=e.fdSelect[0];const n=[t,0,0,s>>8&255,255&s,r];for(a=1;a<e.fdSelect.length;a++){const t=e.fdSelect[a];if(t!==r){n.push(a>>8&255,255&a,t);r=t}}const o=(n.length-3)/3;n[1]=o>>8&255;n[2]=255&o;n.push(a>>8&255,255&a);i=new Uint8Array(n)}return this.compileTypedArray(i)}compileTypedArray(e){return Array.from(e)}compileIndex(e,t=[]){const i=e.objects,a=i.length;if(0===a)return[0,0];const s=[a>>8&255,255&a];let r,n,o=1;for(r=0;r<a;++r)o+=i[r].length;n=o<256?1:o<65536?2:o<16777216?3:4;s.push(n);let g=1;for(r=0;r<a+1;r++){1===n?s.push(255&g):2===n?s.push(g>>8&255,255&g):3===n?s.push(g>>16&255,g>>8&255,255&g):s.push(g>>>24&255,g>>16&255,g>>8&255,255&g);i[r]&&(g+=i[r].length)}for(r=0;r<a;r++){t[r]&&t[r].offset(s.length);s.push(...i[r])}return s}}const Ni=getLookupTableFactory((function(e){e.A=65;e.AE=198;e.AEacute=508;e.AEmacron=482;e.AEsmall=63462;e.Aacute=193;e.Aacutesmall=63457;e.Abreve=258;e.Abreveacute=7854;e.Abrevecyrillic=1232;e.Abrevedotbelow=7862;e.Abrevegrave=7856;e.Abrevehookabove=7858;e.Abrevetilde=7860;e.Acaron=461;e.Acircle=9398;e.Acircumflex=194;e.Acircumflexacute=7844;e.Acircumflexdotbelow=7852;e.Acircumflexgrave=7846;e.Acircumflexhookabove=7848;e.Acircumflexsmall=63458;e.Acircumflextilde=7850;e.Acute=63177;e.Acutesmall=63412;e.Acyrillic=1040;e.Adblgrave=512;e.Adieresis=196;e.Adieresiscyrillic=1234;e.Adieresismacron=478;e.Adieresissmall=63460;e.Adotbelow=7840;e.Adotmacron=480;e.Agrave=192;e.Agravesmall=63456;e.Ahookabove=7842;e.Aiecyrillic=1236;e.Ainvertedbreve=514;e.Alpha=913;e.Alphatonos=902;e.Amacron=256;e.Amonospace=65313;e.Aogonek=260;e.Aring=197;e.Aringacute=506;e.Aringbelow=7680;e.Aringsmall=63461;e.Asmall=63329;e.Atilde=195;e.Atildesmall=63459;e.Aybarmenian=1329;e.B=66;e.Bcircle=9399;e.Bdotaccent=7682;e.Bdotbelow=7684;e.Becyrillic=1041;e.Benarmenian=1330;e.Beta=914;e.Bhook=385;e.Blinebelow=7686;e.Bmonospace=65314;e.Brevesmall=63220;e.Bsmall=63330;e.Btopbar=386;e.C=67;e.Caarmenian=1342;e.Cacute=262;e.Caron=63178;e.Caronsmall=63221;e.Ccaron=268;e.Ccedilla=199;e.Ccedillaacute=7688;e.Ccedillasmall=63463;e.Ccircle=9400;e.Ccircumflex=264;e.Cdot=266;e.Cdotaccent=266;e.Cedillasmall=63416;e.Chaarmenian=1353;e.Cheabkhasiancyrillic=1212;e.Checyrillic=1063;e.Chedescenderabkhasiancyrillic=1214;e.Chedescendercyrillic=1206;e.Chedieresiscyrillic=1268;e.Cheharmenian=1347;e.Chekhakassiancyrillic=1227;e.Cheverticalstrokecyrillic=1208;e.Chi=935;e.Chook=391;e.Circumflexsmall=63222;e.Cmonospace=65315;e.Coarmenian=1361;e.Csmall=63331;e.D=68;e.DZ=497;e.DZcaron=452;e.Daarmenian=1332;e.Dafrican=393;e.Dcaron=270;e.Dcedilla=7696;e.Dcircle=9401;e.Dcircumflexbelow=7698;e.Dcroat=272;e.Ddotaccent=7690;e.Ddotbelow=7692;e.Decyrillic=1044;e.Deicoptic=1006;e.Delta=8710;e.Deltagreek=916;e.Dhook=394;e.Dieresis=63179;e.DieresisAcute=63180;e.DieresisGrave=63181;e.Dieresissmall=63400;e.Digammagreek=988;e.Djecyrillic=1026;e.Dlinebelow=7694;e.Dmonospace=65316;e.Dotaccentsmall=63223;e.Dslash=272;e.Dsmall=63332;e.Dtopbar=395;e.Dz=498;e.Dzcaron=453;e.Dzeabkhasiancyrillic=1248;e.Dzecyrillic=1029;e.Dzhecyrillic=1039;e.E=69;e.Eacute=201;e.Eacutesmall=63465;e.Ebreve=276;e.Ecaron=282;e.Ecedillabreve=7708;e.Echarmenian=1333;e.Ecircle=9402;e.Ecircumflex=202;e.Ecircumflexacute=7870;e.Ecircumflexbelow=7704;e.Ecircumflexdotbelow=7878;e.Ecircumflexgrave=7872;e.Ecircumflexhookabove=7874;e.Ecircumflexsmall=63466;e.Ecircumflextilde=7876;e.Ecyrillic=1028;e.Edblgrave=516;e.Edieresis=203;e.Edieresissmall=63467;e.Edot=278;e.Edotaccent=278;e.Edotbelow=7864;e.Efcyrillic=1060;e.Egrave=200;e.Egravesmall=63464;e.Eharmenian=1335;e.Ehookabove=7866;e.Eightroman=8551;e.Einvertedbreve=518;e.Eiotifiedcyrillic=1124;e.Elcyrillic=1051;e.Elevenroman=8554;e.Emacron=274;e.Emacronacute=7702;e.Emacrongrave=7700;e.Emcyrillic=1052;e.Emonospace=65317;e.Encyrillic=1053;e.Endescendercyrillic=1186;e.Eng=330;e.Enghecyrillic=1188;e.Enhookcyrillic=1223;e.Eogonek=280;e.Eopen=400;e.Epsilon=917;e.Epsilontonos=904;e.Ercyrillic=1056;e.Ereversed=398;e.Ereversedcyrillic=1069;e.Escyrillic=1057;e.Esdescendercyrillic=1194;e.Esh=425;e.Esmall=63333;e.Eta=919;e.Etarmenian=1336;e.Etatonos=905;e.Eth=208;e.Ethsmall=63472;e.Etilde=7868;e.Etildebelow=7706;e.Euro=8364;e.Ezh=439;e.Ezhcaron=494;e.Ezhreversed=440;e.F=70;e.Fcircle=9403;e.Fdotaccent=7710;e.Feharmenian=1366;e.Feicoptic=996;e.Fhook=401;e.Fitacyrillic=1138;e.Fiveroman=8548;e.Fmonospace=65318;e.Fourroman=8547;e.Fsmall=63334;e.G=71;e.GBsquare=13191;e.Gacute=500;e.Gamma=915;e.Gammaafrican=404;e.Gangiacoptic=1002;e.Gbreve=286;e.Gcaron=486;e.Gcedilla=290;e.Gcircle=9404;e.Gcircumflex=284;e.Gcommaaccent=290;e.Gdot=288;e.Gdotaccent=288;e.Gecyrillic=1043;e.Ghadarmenian=1346;e.Ghemiddlehookcyrillic=1172;e.Ghestrokecyrillic=1170;e.Gheupturncyrillic=1168;e.Ghook=403;e.Gimarmenian=1331;e.Gjecyrillic=1027;e.Gmacron=7712;e.Gmonospace=65319;e.Grave=63182;e.Gravesmall=63328;e.Gsmall=63335;e.Gsmallhook=667;e.Gstroke=484;e.H=72;e.H18533=9679;e.H18543=9642;e.H18551=9643;e.H22073=9633;e.HPsquare=13259;e.Haabkhasiancyrillic=1192;e.Hadescendercyrillic=1202;e.Hardsigncyrillic=1066;e.Hbar=294;e.Hbrevebelow=7722;e.Hcedilla=7720;e.Hcircle=9405;e.Hcircumflex=292;e.Hdieresis=7718;e.Hdotaccent=7714;e.Hdotbelow=7716;e.Hmonospace=65320;e.Hoarmenian=1344;e.Horicoptic=1e3;e.Hsmall=63336;e.Hungarumlaut=63183;e.Hungarumlautsmall=63224;e.Hzsquare=13200;e.I=73;e.IAcyrillic=1071;e.IJ=306;e.IUcyrillic=1070;e.Iacute=205;e.Iacutesmall=63469;e.Ibreve=300;e.Icaron=463;e.Icircle=9406;e.Icircumflex=206;e.Icircumflexsmall=63470;e.Icyrillic=1030;e.Idblgrave=520;e.Idieresis=207;e.Idieresisacute=7726;e.Idieresiscyrillic=1252;e.Idieresissmall=63471;e.Idot=304;e.Idotaccent=304;e.Idotbelow=7882;e.Iebrevecyrillic=1238;e.Iecyrillic=1045;e.Ifraktur=8465;e.Igrave=204;e.Igravesmall=63468;e.Ihookabove=7880;e.Iicyrillic=1048;e.Iinvertedbreve=522;e.Iishortcyrillic=1049;e.Imacron=298;e.Imacroncyrillic=1250;e.Imonospace=65321;e.Iniarmenian=1339;e.Iocyrillic=1025;e.Iogonek=302;e.Iota=921;e.Iotaafrican=406;e.Iotadieresis=938;e.Iotatonos=906;e.Ismall=63337;e.Istroke=407;e.Itilde=296;e.Itildebelow=7724;e.Izhitsacyrillic=1140;e.Izhitsadblgravecyrillic=1142;e.J=74;e.Jaarmenian=1345;e.Jcircle=9407;e.Jcircumflex=308;e.Jecyrillic=1032;e.Jheharmenian=1355;e.Jmonospace=65322;e.Jsmall=63338;e.K=75;e.KBsquare=13189;e.KKsquare=13261;e.Kabashkircyrillic=1184;e.Kacute=7728;e.Kacyrillic=1050;e.Kadescendercyrillic=1178;e.Kahookcyrillic=1219;e.Kappa=922;e.Kastrokecyrillic=1182;e.Kaverticalstrokecyrillic=1180;e.Kcaron=488;e.Kcedilla=310;e.Kcircle=9408;e.Kcommaaccent=310;e.Kdotbelow=7730;e.Keharmenian=1364;e.Kenarmenian=1343;e.Khacyrillic=1061;e.Kheicoptic=998;e.Khook=408;e.Kjecyrillic=1036;e.Klinebelow=7732;e.Kmonospace=65323;e.Koppacyrillic=1152;e.Koppagreek=990;e.Ksicyrillic=1134;e.Ksmall=63339;e.L=76;e.LJ=455;e.LL=63167;e.Lacute=313;e.Lambda=923;e.Lcaron=317;e.Lcedilla=315;e.Lcircle=9409;e.Lcircumflexbelow=7740;e.Lcommaaccent=315;e.Ldot=319;e.Ldotaccent=319;e.Ldotbelow=7734;e.Ldotbelowmacron=7736;e.Liwnarmenian=1340;e.Lj=456;e.Ljecyrillic=1033;e.Llinebelow=7738;e.Lmonospace=65324;e.Lslash=321;e.Lslashsmall=63225;e.Lsmall=63340;e.M=77;e.MBsquare=13190;e.Macron=63184;e.Macronsmall=63407;e.Macute=7742;e.Mcircle=9410;e.Mdotaccent=7744;e.Mdotbelow=7746;e.Menarmenian=1348;e.Mmonospace=65325;e.Msmall=63341;e.Mturned=412;e.Mu=924;e.N=78;e.NJ=458;e.Nacute=323;e.Ncaron=327;e.Ncedilla=325;e.Ncircle=9411;e.Ncircumflexbelow=7754;e.Ncommaaccent=325;e.Ndotaccent=7748;e.Ndotbelow=7750;e.Nhookleft=413;e.Nineroman=8552;e.Nj=459;e.Njecyrillic=1034;e.Nlinebelow=7752;e.Nmonospace=65326;e.Nowarmenian=1350;e.Nsmall=63342;e.Ntilde=209;e.Ntildesmall=63473;e.Nu=925;e.O=79;e.OE=338;e.OEsmall=63226;e.Oacute=211;e.Oacutesmall=63475;e.Obarredcyrillic=1256;e.Obarreddieresiscyrillic=1258;e.Obreve=334;e.Ocaron=465;e.Ocenteredtilde=415;e.Ocircle=9412;e.Ocircumflex=212;e.Ocircumflexacute=7888;e.Ocircumflexdotbelow=7896;e.Ocircumflexgrave=7890;e.Ocircumflexhookabove=7892;e.Ocircumflexsmall=63476;e.Ocircumflextilde=7894;e.Ocyrillic=1054;e.Odblacute=336;e.Odblgrave=524;e.Odieresis=214;e.Odieresiscyrillic=1254;e.Odieresissmall=63478;e.Odotbelow=7884;e.Ogoneksmall=63227;e.Ograve=210;e.Ogravesmall=63474;e.Oharmenian=1365;e.Ohm=8486;e.Ohookabove=7886;e.Ohorn=416;e.Ohornacute=7898;e.Ohorndotbelow=7906;e.Ohorngrave=7900;e.Ohornhookabove=7902;e.Ohorntilde=7904;e.Ohungarumlaut=336;e.Oi=418;e.Oinvertedbreve=526;e.Omacron=332;e.Omacronacute=7762;e.Omacrongrave=7760;e.Omega=8486;e.Omegacyrillic=1120;e.Omegagreek=937;e.Omegaroundcyrillic=1146;e.Omegatitlocyrillic=1148;e.Omegatonos=911;e.Omicron=927;e.Omicrontonos=908;e.Omonospace=65327;e.Oneroman=8544;e.Oogonek=490;e.Oogonekmacron=492;e.Oopen=390;e.Oslash=216;e.Oslashacute=510;e.Oslashsmall=63480;e.Osmall=63343;e.Ostrokeacute=510;e.Otcyrillic=1150;e.Otilde=213;e.Otildeacute=7756;e.Otildedieresis=7758;e.Otildesmall=63477;e.P=80;e.Pacute=7764;e.Pcircle=9413;e.Pdotaccent=7766;e.Pecyrillic=1055;e.Peharmenian=1354;e.Pemiddlehookcyrillic=1190;e.Phi=934;e.Phook=420;e.Pi=928;e.Piwrarmenian=1363;e.Pmonospace=65328;e.Psi=936;e.Psicyrillic=1136;e.Psmall=63344;e.Q=81;e.Qcircle=9414;e.Qmonospace=65329;e.Qsmall=63345;e.R=82;e.Raarmenian=1356;e.Racute=340;e.Rcaron=344;e.Rcedilla=342;e.Rcircle=9415;e.Rcommaaccent=342;e.Rdblgrave=528;e.Rdotaccent=7768;e.Rdotbelow=7770;e.Rdotbelowmacron=7772;e.Reharmenian=1360;e.Rfraktur=8476;e.Rho=929;e.Ringsmall=63228;e.Rinvertedbreve=530;e.Rlinebelow=7774;e.Rmonospace=65330;e.Rsmall=63346;e.Rsmallinverted=641;e.Rsmallinvertedsuperior=694;e.S=83;e.SF010000=9484;e.SF020000=9492;e.SF030000=9488;e.SF040000=9496;e.SF050000=9532;e.SF060000=9516;e.SF070000=9524;e.SF080000=9500;e.SF090000=9508;e.SF100000=9472;e.SF110000=9474;e.SF190000=9569;e.SF200000=9570;e.SF210000=9558;e.SF220000=9557;e.SF230000=9571;e.SF240000=9553;e.SF250000=9559;e.SF260000=9565;e.SF270000=9564;e.SF280000=9563;e.SF360000=9566;e.SF370000=9567;e.SF380000=9562;e.SF390000=9556;e.SF400000=9577;e.SF410000=9574;e.SF420000=9568;e.SF430000=9552;e.SF440000=9580;e.SF450000=9575;e.SF460000=9576;e.SF470000=9572;e.SF480000=9573;e.SF490000=9561;e.SF500000=9560;e.SF510000=9554;e.SF520000=9555;e.SF530000=9579;e.SF540000=9578;e.Sacute=346;e.Sacutedotaccent=7780;e.Sampigreek=992;e.Scaron=352;e.Scarondotaccent=7782;e.Scaronsmall=63229;e.Scedilla=350;e.Schwa=399;e.Schwacyrillic=1240;e.Schwadieresiscyrillic=1242;e.Scircle=9416;e.Scircumflex=348;e.Scommaaccent=536;e.Sdotaccent=7776;e.Sdotbelow=7778;e.Sdotbelowdotaccent=7784;e.Seharmenian=1357;e.Sevenroman=8550;e.Shaarmenian=1351;e.Shacyrillic=1064;e.Shchacyrillic=1065;e.Sheicoptic=994;e.Shhacyrillic=1210;e.Shimacoptic=1004;e.Sigma=931;e.Sixroman=8549;e.Smonospace=65331;e.Softsigncyrillic=1068;e.Ssmall=63347;e.Stigmagreek=986;e.T=84;e.Tau=932;e.Tbar=358;e.Tcaron=356;e.Tcedilla=354;e.Tcircle=9417;e.Tcircumflexbelow=7792;e.Tcommaaccent=354;e.Tdotaccent=7786;e.Tdotbelow=7788;e.Tecyrillic=1058;e.Tedescendercyrillic=1196;e.Tenroman=8553;e.Tetsecyrillic=1204;e.Theta=920;e.Thook=428;e.Thorn=222;e.Thornsmall=63486;e.Threeroman=8546;e.Tildesmall=63230;e.Tiwnarmenian=1359;e.Tlinebelow=7790;e.Tmonospace=65332;e.Toarmenian=1337;e.Tonefive=444;e.Tonesix=388;e.Tonetwo=423;e.Tretroflexhook=430;e.Tsecyrillic=1062;e.Tshecyrillic=1035;e.Tsmall=63348;e.Twelveroman=8555;e.Tworoman=8545;e.U=85;e.Uacute=218;e.Uacutesmall=63482;e.Ubreve=364;e.Ucaron=467;e.Ucircle=9418;e.Ucircumflex=219;e.Ucircumflexbelow=7798;e.Ucircumflexsmall=63483;e.Ucyrillic=1059;e.Udblacute=368;e.Udblgrave=532;e.Udieresis=220;e.Udieresisacute=471;e.Udieresisbelow=7794;e.Udieresiscaron=473;e.Udieresiscyrillic=1264;e.Udieresisgrave=475;e.Udieresismacron=469;e.Udieresissmall=63484;e.Udotbelow=7908;e.Ugrave=217;e.Ugravesmall=63481;e.Uhookabove=7910;e.Uhorn=431;e.Uhornacute=7912;e.Uhorndotbelow=7920;e.Uhorngrave=7914;e.Uhornhookabove=7916;e.Uhorntilde=7918;e.Uhungarumlaut=368;e.Uhungarumlautcyrillic=1266;e.Uinvertedbreve=534;e.Ukcyrillic=1144;e.Umacron=362;e.Umacroncyrillic=1262;e.Umacrondieresis=7802;e.Umonospace=65333;e.Uogonek=370;e.Upsilon=933;e.Upsilon1=978;e.Upsilonacutehooksymbolgreek=979;e.Upsilonafrican=433;e.Upsilondieresis=939;e.Upsilondieresishooksymbolgreek=980;e.Upsilonhooksymbol=978;e.Upsilontonos=910;e.Uring=366;e.Ushortcyrillic=1038;e.Usmall=63349;e.Ustraightcyrillic=1198;e.Ustraightstrokecyrillic=1200;e.Utilde=360;e.Utildeacute=7800;e.Utildebelow=7796;e.V=86;e.Vcircle=9419;e.Vdotbelow=7806;e.Vecyrillic=1042;e.Vewarmenian=1358;e.Vhook=434;e.Vmonospace=65334;e.Voarmenian=1352;e.Vsmall=63350;e.Vtilde=7804;e.W=87;e.Wacute=7810;e.Wcircle=9420;e.Wcircumflex=372;e.Wdieresis=7812;e.Wdotaccent=7814;e.Wdotbelow=7816;e.Wgrave=7808;e.Wmonospace=65335;e.Wsmall=63351;e.X=88;e.Xcircle=9421;e.Xdieresis=7820;e.Xdotaccent=7818;e.Xeharmenian=1341;e.Xi=926;e.Xmonospace=65336;e.Xsmall=63352;e.Y=89;e.Yacute=221;e.Yacutesmall=63485;e.Yatcyrillic=1122;e.Ycircle=9422;e.Ycircumflex=374;e.Ydieresis=376;e.Ydieresissmall=63487;e.Ydotaccent=7822;e.Ydotbelow=7924;e.Yericyrillic=1067;e.Yerudieresiscyrillic=1272;e.Ygrave=7922;e.Yhook=435;e.Yhookabove=7926;e.Yiarmenian=1349;e.Yicyrillic=1031;e.Yiwnarmenian=1362;e.Ymonospace=65337;e.Ysmall=63353;e.Ytilde=7928;e.Yusbigcyrillic=1130;e.Yusbigiotifiedcyrillic=1132;e.Yuslittlecyrillic=1126;e.Yuslittleiotifiedcyrillic=1128;e.Z=90;e.Zaarmenian=1334;e.Zacute=377;e.Zcaron=381;e.Zcaronsmall=63231;e.Zcircle=9423;e.Zcircumflex=7824;e.Zdot=379;e.Zdotaccent=379;e.Zdotbelow=7826;e.Zecyrillic=1047;e.Zedescendercyrillic=1176;e.Zedieresiscyrillic=1246;e.Zeta=918;e.Zhearmenian=1338;e.Zhebrevecyrillic=1217;e.Zhecyrillic=1046;e.Zhedescendercyrillic=1174;e.Zhedieresiscyrillic=1244;e.Zlinebelow=7828;e.Zmonospace=65338;e.Zsmall=63354;e.Zstroke=437;e.a=97;e.aabengali=2438;e.aacute=225;e.aadeva=2310;e.aagujarati=2694;e.aagurmukhi=2566;e.aamatragurmukhi=2622;e.aarusquare=13059;e.aavowelsignbengali=2494;e.aavowelsigndeva=2366;e.aavowelsigngujarati=2750;e.abbreviationmarkarmenian=1375;e.abbreviationsigndeva=2416;e.abengali=2437;e.abopomofo=12570;e.abreve=259;e.abreveacute=7855;e.abrevecyrillic=1233;e.abrevedotbelow=7863;e.abrevegrave=7857;e.abrevehookabove=7859;e.abrevetilde=7861;e.acaron=462;e.acircle=9424;e.acircumflex=226;e.acircumflexacute=7845;e.acircumflexdotbelow=7853;e.acircumflexgrave=7847;e.acircumflexhookabove=7849;e.acircumflextilde=7851;e.acute=180;e.acutebelowcmb=791;e.acutecmb=769;e.acutecomb=769;e.acutedeva=2388;e.acutelowmod=719;e.acutetonecmb=833;e.acyrillic=1072;e.adblgrave=513;e.addakgurmukhi=2673;e.adeva=2309;e.adieresis=228;e.adieresiscyrillic=1235;e.adieresismacron=479;e.adotbelow=7841;e.adotmacron=481;e.ae=230;e.aeacute=509;e.aekorean=12624;e.aemacron=483;e.afii00208=8213;e.afii08941=8356;e.afii10017=1040;e.afii10018=1041;e.afii10019=1042;e.afii10020=1043;e.afii10021=1044;e.afii10022=1045;e.afii10023=1025;e.afii10024=1046;e.afii10025=1047;e.afii10026=1048;e.afii10027=1049;e.afii10028=1050;e.afii10029=1051;e.afii10030=1052;e.afii10031=1053;e.afii10032=1054;e.afii10033=1055;e.afii10034=1056;e.afii10035=1057;e.afii10036=1058;e.afii10037=1059;e.afii10038=1060;e.afii10039=1061;e.afii10040=1062;e.afii10041=1063;e.afii10042=1064;e.afii10043=1065;e.afii10044=1066;e.afii10045=1067;e.afii10046=1068;e.afii10047=1069;e.afii10048=1070;e.afii10049=1071;e.afii10050=1168;e.afii10051=1026;e.afii10052=1027;e.afii10053=1028;e.afii10054=1029;e.afii10055=1030;e.afii10056=1031;e.afii10057=1032;e.afii10058=1033;e.afii10059=1034;e.afii10060=1035;e.afii10061=1036;e.afii10062=1038;e.afii10063=63172;e.afii10064=63173;e.afii10065=1072;e.afii10066=1073;e.afii10067=1074;e.afii10068=1075;e.afii10069=1076;e.afii10070=1077;e.afii10071=1105;e.afii10072=1078;e.afii10073=1079;e.afii10074=1080;e.afii10075=1081;e.afii10076=1082;e.afii10077=1083;e.afii10078=1084;e.afii10079=1085;e.afii10080=1086;e.afii10081=1087;e.afii10082=1088;e.afii10083=1089;e.afii10084=1090;e.afii10085=1091;e.afii10086=1092;e.afii10087=1093;e.afii10088=1094;e.afii10089=1095;e.afii10090=1096;e.afii10091=1097;e.afii10092=1098;e.afii10093=1099;e.afii10094=1100;e.afii10095=1101;e.afii10096=1102;e.afii10097=1103;e.afii10098=1169;e.afii10099=1106;e.afii10100=1107;e.afii10101=1108;e.afii10102=1109;e.afii10103=1110;e.afii10104=1111;e.afii10105=1112;e.afii10106=1113;e.afii10107=1114;e.afii10108=1115;e.afii10109=1116;e.afii10110=1118;e.afii10145=1039;e.afii10146=1122;e.afii10147=1138;e.afii10148=1140;e.afii10192=63174;e.afii10193=1119;e.afii10194=1123;e.afii10195=1139;e.afii10196=1141;e.afii10831=63175;e.afii10832=63176;e.afii10846=1241;e.afii299=8206;e.afii300=8207;e.afii301=8205;e.afii57381=1642;e.afii57388=1548;e.afii57392=1632;e.afii57393=1633;e.afii57394=1634;e.afii57395=1635;e.afii57396=1636;e.afii57397=1637;e.afii57398=1638;e.afii57399=1639;e.afii57400=1640;e.afii57401=1641;e.afii57403=1563;e.afii57407=1567;e.afii57409=1569;e.afii57410=1570;e.afii57411=1571;e.afii57412=1572;e.afii57413=1573;e.afii57414=1574;e.afii57415=1575;e.afii57416=1576;e.afii57417=1577;e.afii57418=1578;e.afii57419=1579;e.afii57420=1580;e.afii57421=1581;e.afii57422=1582;e.afii57423=1583;e.afii57424=1584;e.afii57425=1585;e.afii57426=1586;e.afii57427=1587;e.afii57428=1588;e.afii57429=1589;e.afii57430=1590;e.afii57431=1591;e.afii57432=1592;e.afii57433=1593;e.afii57434=1594;e.afii57440=1600;e.afii57441=1601;e.afii57442=1602;e.afii57443=1603;e.afii57444=1604;e.afii57445=1605;e.afii57446=1606;e.afii57448=1608;e.afii57449=1609;e.afii57450=1610;e.afii57451=1611;e.afii57452=1612;e.afii57453=1613;e.afii57454=1614;e.afii57455=1615;e.afii57456=1616;e.afii57457=1617;e.afii57458=1618;e.afii57470=1607;e.afii57505=1700;e.afii57506=1662;e.afii57507=1670;e.afii57508=1688;e.afii57509=1711;e.afii57511=1657;e.afii57512=1672;e.afii57513=1681;e.afii57514=1722;e.afii57519=1746;e.afii57534=1749;e.afii57636=8362;e.afii57645=1470;e.afii57658=1475;e.afii57664=1488;e.afii57665=1489;e.afii57666=1490;e.afii57667=1491;e.afii57668=1492;e.afii57669=1493;e.afii57670=1494;e.afii57671=1495;e.afii57672=1496;e.afii57673=1497;e.afii57674=1498;e.afii57675=1499;e.afii57676=1500;e.afii57677=1501;e.afii57678=1502;e.afii57679=1503;e.afii57680=1504;e.afii57681=1505;e.afii57682=1506;e.afii57683=1507;e.afii57684=1508;e.afii57685=1509;e.afii57686=1510;e.afii57687=1511;e.afii57688=1512;e.afii57689=1513;e.afii57690=1514;e.afii57694=64298;e.afii57695=64299;e.afii57700=64331;e.afii57705=64287;e.afii57716=1520;e.afii57717=1521;e.afii57718=1522;e.afii57723=64309;e.afii57793=1460;e.afii57794=1461;e.afii57795=1462;e.afii57796=1467;e.afii57797=1464;e.afii57798=1463;e.afii57799=1456;e.afii57800=1458;e.afii57801=1457;e.afii57802=1459;e.afii57803=1474;e.afii57804=1473;e.afii57806=1465;e.afii57807=1468;e.afii57839=1469;e.afii57841=1471;e.afii57842=1472;e.afii57929=700;e.afii61248=8453;e.afii61289=8467;e.afii61352=8470;e.afii61573=8236;e.afii61574=8237;e.afii61575=8238;e.afii61664=8204;e.afii63167=1645;e.afii64937=701;e.agrave=224;e.agujarati=2693;e.agurmukhi=2565;e.ahiragana=12354;e.ahookabove=7843;e.aibengali=2448;e.aibopomofo=12574;e.aideva=2320;e.aiecyrillic=1237;e.aigujarati=2704;e.aigurmukhi=2576;e.aimatragurmukhi=2632;e.ainarabic=1593;e.ainfinalarabic=65226;e.aininitialarabic=65227;e.ainmedialarabic=65228;e.ainvertedbreve=515;e.aivowelsignbengali=2504;e.aivowelsigndeva=2376;e.aivowelsigngujarati=2760;e.akatakana=12450;e.akatakanahalfwidth=65393;e.akorean=12623;e.alef=1488;e.alefarabic=1575;e.alefdageshhebrew=64304;e.aleffinalarabic=65166;e.alefhamzaabovearabic=1571;e.alefhamzaabovefinalarabic=65156;e.alefhamzabelowarabic=1573;e.alefhamzabelowfinalarabic=65160;e.alefhebrew=1488;e.aleflamedhebrew=64335;e.alefmaddaabovearabic=1570;e.alefmaddaabovefinalarabic=65154;e.alefmaksuraarabic=1609;e.alefmaksurafinalarabic=65264;e.alefmaksurainitialarabic=65267;e.alefmaksuramedialarabic=65268;e.alefpatahhebrew=64302;e.alefqamatshebrew=64303;e.aleph=8501;e.allequal=8780;e.alpha=945;e.alphatonos=940;e.amacron=257;e.amonospace=65345;e.ampersand=38;e.ampersandmonospace=65286;e.ampersandsmall=63270;e.amsquare=13250;e.anbopomofo=12578;e.angbopomofo=12580;e.angbracketleft=12296;e.angbracketright=12297;e.angkhankhuthai=3674;e.angle=8736;e.anglebracketleft=12296;e.anglebracketleftvertical=65087;e.anglebracketright=12297;e.anglebracketrightvertical=65088;e.angleleft=9001;e.angleright=9002;e.angstrom=8491;e.anoteleia=903;e.anudattadeva=2386;e.anusvarabengali=2434;e.anusvaradeva=2306;e.anusvaragujarati=2690;e.aogonek=261;e.apaatosquare=13056;e.aparen=9372;e.apostrophearmenian=1370;e.apostrophemod=700;e.apple=63743;e.approaches=8784;e.approxequal=8776;e.approxequalorimage=8786;e.approximatelyequal=8773;e.araeaekorean=12686;e.araeakorean=12685;e.arc=8978;e.arighthalfring=7834;e.aring=229;e.aringacute=507;e.aringbelow=7681;e.arrowboth=8596;e.arrowdashdown=8675;e.arrowdashleft=8672;e.arrowdashright=8674;e.arrowdashup=8673;e.arrowdblboth=8660;e.arrowdbldown=8659;e.arrowdblleft=8656;e.arrowdblright=8658;e.arrowdblup=8657;e.arrowdown=8595;e.arrowdownleft=8601;e.arrowdownright=8600;e.arrowdownwhite=8681;e.arrowheaddownmod=709;e.arrowheadleftmod=706;e.arrowheadrightmod=707;e.arrowheadupmod=708;e.arrowhorizex=63719;e.arrowleft=8592;e.arrowleftdbl=8656;e.arrowleftdblstroke=8653;e.arrowleftoverright=8646;e.arrowleftwhite=8678;e.arrowright=8594;e.arrowrightdblstroke=8655;e.arrowrightheavy=10142;e.arrowrightoverleft=8644;e.arrowrightwhite=8680;e.arrowtableft=8676;e.arrowtabright=8677;e.arrowup=8593;e.arrowupdn=8597;e.arrowupdnbse=8616;e.arrowupdownbase=8616;e.arrowupleft=8598;e.arrowupleftofdown=8645;e.arrowupright=8599;e.arrowupwhite=8679;e.arrowvertex=63718;e.asciicircum=94;e.asciicircummonospace=65342;e.asciitilde=126;e.asciitildemonospace=65374;e.ascript=593;e.ascriptturned=594;e.asmallhiragana=12353;e.asmallkatakana=12449;e.asmallkatakanahalfwidth=65383;e.asterisk=42;e.asteriskaltonearabic=1645;e.asteriskarabic=1645;e.asteriskmath=8727;e.asteriskmonospace=65290;e.asterisksmall=65121;e.asterism=8258;e.asuperior=63209;e.asymptoticallyequal=8771;e.at=64;e.atilde=227;e.atmonospace=65312;e.atsmall=65131;e.aturned=592;e.aubengali=2452;e.aubopomofo=12576;e.audeva=2324;e.augujarati=2708;e.augurmukhi=2580;e.aulengthmarkbengali=2519;e.aumatragurmukhi=2636;e.auvowelsignbengali=2508;e.auvowelsigndeva=2380;e.auvowelsigngujarati=2764;e.avagrahadeva=2365;e.aybarmenian=1377;e.ayin=1506;e.ayinaltonehebrew=64288;e.ayinhebrew=1506;e.b=98;e.babengali=2476;e.backslash=92;e.backslashmonospace=65340;e.badeva=2348;e.bagujarati=2732;e.bagurmukhi=2604;e.bahiragana=12400;e.bahtthai=3647;e.bakatakana=12496;e.bar=124;e.barmonospace=65372;e.bbopomofo=12549;e.bcircle=9425;e.bdotaccent=7683;e.bdotbelow=7685;e.beamedsixteenthnotes=9836;e.because=8757;e.becyrillic=1073;e.beharabic=1576;e.behfinalarabic=65168;e.behinitialarabic=65169;e.behiragana=12409;e.behmedialarabic=65170;e.behmeeminitialarabic=64671;e.behmeemisolatedarabic=64520;e.behnoonfinalarabic=64621;e.bekatakana=12505;e.benarmenian=1378;e.bet=1489;e.beta=946;e.betasymbolgreek=976;e.betdagesh=64305;e.betdageshhebrew=64305;e.bethebrew=1489;e.betrafehebrew=64332;e.bhabengali=2477;e.bhadeva=2349;e.bhagujarati=2733;e.bhagurmukhi=2605;e.bhook=595;e.bihiragana=12403;e.bikatakana=12499;e.bilabialclick=664;e.bindigurmukhi=2562;e.birusquare=13105;e.blackcircle=9679;e.blackdiamond=9670;e.blackdownpointingtriangle=9660;e.blackleftpointingpointer=9668;e.blackleftpointingtriangle=9664;e.blacklenticularbracketleft=12304;e.blacklenticularbracketleftvertical=65083;e.blacklenticularbracketright=12305;e.blacklenticularbracketrightvertical=65084;e.blacklowerlefttriangle=9699;e.blacklowerrighttriangle=9698;e.blackrectangle=9644;e.blackrightpointingpointer=9658;e.blackrightpointingtriangle=9654;e.blacksmallsquare=9642;e.blacksmilingface=9787;e.blacksquare=9632;e.blackstar=9733;e.blackupperlefttriangle=9700;e.blackupperrighttriangle=9701;e.blackuppointingsmalltriangle=9652;e.blackuppointingtriangle=9650;e.blank=9251;e.blinebelow=7687;e.block=9608;e.bmonospace=65346;e.bobaimaithai=3610;e.bohiragana=12412;e.bokatakana=12508;e.bparen=9373;e.bqsquare=13251;e.braceex=63732;e.braceleft=123;e.braceleftbt=63731;e.braceleftmid=63730;e.braceleftmonospace=65371;e.braceleftsmall=65115;e.bracelefttp=63729;e.braceleftvertical=65079;e.braceright=125;e.bracerightbt=63742;e.bracerightmid=63741;e.bracerightmonospace=65373;e.bracerightsmall=65116;e.bracerighttp=63740;e.bracerightvertical=65080;e.bracketleft=91;e.bracketleftbt=63728;e.bracketleftex=63727;e.bracketleftmonospace=65339;e.bracketlefttp=63726;e.bracketright=93;e.bracketrightbt=63739;e.bracketrightex=63738;e.bracketrightmonospace=65341;e.bracketrighttp=63737;e.breve=728;e.brevebelowcmb=814;e.brevecmb=774;e.breveinvertedbelowcmb=815;e.breveinvertedcmb=785;e.breveinverteddoublecmb=865;e.bridgebelowcmb=810;e.bridgeinvertedbelowcmb=826;e.brokenbar=166;e.bstroke=384;e.bsuperior=63210;e.btopbar=387;e.buhiragana=12406;e.bukatakana=12502;e.bullet=8226;e.bulletinverse=9688;e.bulletoperator=8729;e.bullseye=9678;e.c=99;e.caarmenian=1390;e.cabengali=2458;e.cacute=263;e.cadeva=2330;e.cagujarati=2714;e.cagurmukhi=2586;e.calsquare=13192;e.candrabindubengali=2433;e.candrabinducmb=784;e.candrabindudeva=2305;e.candrabindugujarati=2689;e.capslock=8682;e.careof=8453;e.caron=711;e.caronbelowcmb=812;e.caroncmb=780;e.carriagereturn=8629;e.cbopomofo=12568;e.ccaron=269;e.ccedilla=231;e.ccedillaacute=7689;e.ccircle=9426;e.ccircumflex=265;e.ccurl=597;e.cdot=267;e.cdotaccent=267;e.cdsquare=13253;e.cedilla=184;e.cedillacmb=807;e.cent=162;e.centigrade=8451;e.centinferior=63199;e.centmonospace=65504;e.centoldstyle=63394;e.centsuperior=63200;e.chaarmenian=1401;e.chabengali=2459;e.chadeva=2331;e.chagujarati=2715;e.chagurmukhi=2587;e.chbopomofo=12564;e.cheabkhasiancyrillic=1213;e.checkmark=10003;e.checyrillic=1095;e.chedescenderabkhasiancyrillic=1215;e.chedescendercyrillic=1207;e.chedieresiscyrillic=1269;e.cheharmenian=1395;e.chekhakassiancyrillic=1228;e.cheverticalstrokecyrillic=1209;e.chi=967;e.chieuchacirclekorean=12919;e.chieuchaparenkorean=12823;e.chieuchcirclekorean=12905;e.chieuchkorean=12618;e.chieuchparenkorean=12809;e.chochangthai=3594;e.chochanthai=3592;e.chochingthai=3593;e.chochoethai=3596;e.chook=392;e.cieucacirclekorean=12918;e.cieucaparenkorean=12822;e.cieuccirclekorean=12904;e.cieuckorean=12616;e.cieucparenkorean=12808;e.cieucuparenkorean=12828;e.circle=9675;e.circlecopyrt=169;e.circlemultiply=8855;e.circleot=8857;e.circleplus=8853;e.circlepostalmark=12342;e.circlewithlefthalfblack=9680;e.circlewithrighthalfblack=9681;e.circumflex=710;e.circumflexbelowcmb=813;e.circumflexcmb=770;e.clear=8999;e.clickalveolar=450;e.clickdental=448;e.clicklateral=449;e.clickretroflex=451;e.club=9827;e.clubsuitblack=9827;e.clubsuitwhite=9831;e.cmcubedsquare=13220;e.cmonospace=65347;e.cmsquaredsquare=13216;e.coarmenian=1409;e.colon=58;e.colonmonetary=8353;e.colonmonospace=65306;e.colonsign=8353;e.colonsmall=65109;e.colontriangularhalfmod=721;e.colontriangularmod=720;e.comma=44;e.commaabovecmb=787;e.commaaboverightcmb=789;e.commaaccent=63171;e.commaarabic=1548;e.commaarmenian=1373;e.commainferior=63201;e.commamonospace=65292;e.commareversedabovecmb=788;e.commareversedmod=701;e.commasmall=65104;e.commasuperior=63202;e.commaturnedabovecmb=786;e.commaturnedmod=699;e.compass=9788;e.congruent=8773;e.contourintegral=8750;e.control=8963;e.controlACK=6;e.controlBEL=7;e.controlBS=8;e.controlCAN=24;e.controlCR=13;e.controlDC1=17;e.controlDC2=18;e.controlDC3=19;e.controlDC4=20;e.controlDEL=127;e.controlDLE=16;e.controlEM=25;e.controlENQ=5;e.controlEOT=4;e.controlESC=27;e.controlETB=23;e.controlETX=3;e.controlFF=12;e.controlFS=28;e.controlGS=29;e.controlHT=9;e.controlLF=10;e.controlNAK=21;e.controlNULL=0;e.controlRS=30;e.controlSI=15;e.controlSO=14;e.controlSOT=2;e.controlSTX=1;e.controlSUB=26;e.controlSYN=22;e.controlUS=31;e.controlVT=11;e.copyright=169;e.copyrightsans=63721;e.copyrightserif=63193;e.cornerbracketleft=12300;e.cornerbracketlefthalfwidth=65378;e.cornerbracketleftvertical=65089;e.cornerbracketright=12301;e.cornerbracketrighthalfwidth=65379;e.cornerbracketrightvertical=65090;e.corporationsquare=13183;e.cosquare=13255;e.coverkgsquare=13254;e.cparen=9374;e.cruzeiro=8354;e.cstretched=663;e.curlyand=8911;e.curlyor=8910;e.currency=164;e.cyrBreve=63185;e.cyrFlex=63186;e.cyrbreve=63188;e.cyrflex=63189;e.d=100;e.daarmenian=1380;e.dabengali=2470;e.dadarabic=1590;e.dadeva=2342;e.dadfinalarabic=65214;e.dadinitialarabic=65215;e.dadmedialarabic=65216;e.dagesh=1468;e.dageshhebrew=1468;e.dagger=8224;e.daggerdbl=8225;e.dagujarati=2726;e.dagurmukhi=2598;e.dahiragana=12384;e.dakatakana=12480;e.dalarabic=1583;e.dalet=1491;e.daletdagesh=64307;e.daletdageshhebrew=64307;e.dalethebrew=1491;e.dalfinalarabic=65194;e.dammaarabic=1615;e.dammalowarabic=1615;e.dammatanaltonearabic=1612;e.dammatanarabic=1612;e.danda=2404;e.dargahebrew=1447;e.dargalefthebrew=1447;e.dasiapneumatacyrilliccmb=1157;e.dblGrave=63187;e.dblanglebracketleft=12298;e.dblanglebracketleftvertical=65085;e.dblanglebracketright=12299;e.dblanglebracketrightvertical=65086;e.dblarchinvertedbelowcmb=811;e.dblarrowleft=8660;e.dblarrowright=8658;e.dbldanda=2405;e.dblgrave=63190;e.dblgravecmb=783;e.dblintegral=8748;e.dbllowline=8215;e.dbllowlinecmb=819;e.dbloverlinecmb=831;e.dblprimemod=698;e.dblverticalbar=8214;e.dblverticallineabovecmb=782;e.dbopomofo=12553;e.dbsquare=13256;e.dcaron=271;e.dcedilla=7697;e.dcircle=9427;e.dcircumflexbelow=7699;e.dcroat=273;e.ddabengali=2465;e.ddadeva=2337;e.ddagujarati=2721;e.ddagurmukhi=2593;e.ddalarabic=1672;e.ddalfinalarabic=64393;e.dddhadeva=2396;e.ddhabengali=2466;e.ddhadeva=2338;e.ddhagujarati=2722;e.ddhagurmukhi=2594;e.ddotaccent=7691;e.ddotbelow=7693;e.decimalseparatorarabic=1643;e.decimalseparatorpersian=1643;e.decyrillic=1076;e.degree=176;e.dehihebrew=1453;e.dehiragana=12391;e.deicoptic=1007;e.dekatakana=12487;e.deleteleft=9003;e.deleteright=8998;e.delta=948;e.deltaturned=397;e.denominatorminusonenumeratorbengali=2552;e.dezh=676;e.dhabengali=2471;e.dhadeva=2343;e.dhagujarati=2727;e.dhagurmukhi=2599;e.dhook=599;e.dialytikatonos=901;e.dialytikatonoscmb=836;e.diamond=9830;e.diamondsuitwhite=9826;e.dieresis=168;e.dieresisacute=63191;e.dieresisbelowcmb=804;e.dieresiscmb=776;e.dieresisgrave=63192;e.dieresistonos=901;e.dihiragana=12386;e.dikatakana=12482;e.dittomark=12291;e.divide=247;e.divides=8739;e.divisionslash=8725;e.djecyrillic=1106;e.dkshade=9619;e.dlinebelow=7695;e.dlsquare=13207;e.dmacron=273;e.dmonospace=65348;e.dnblock=9604;e.dochadathai=3598;e.dodekthai=3604;e.dohiragana=12393;e.dokatakana=12489;e.dollar=36;e.dollarinferior=63203;e.dollarmonospace=65284;e.dollaroldstyle=63268;e.dollarsmall=65129;e.dollarsuperior=63204;e.dong=8363;e.dorusquare=13094;e.dotaccent=729;e.dotaccentcmb=775;e.dotbelowcmb=803;e.dotbelowcomb=803;e.dotkatakana=12539;e.dotlessi=305;e.dotlessj=63166;e.dotlessjstrokehook=644;e.dotmath=8901;e.dottedcircle=9676;e.doubleyodpatah=64287;e.doubleyodpatahhebrew=64287;e.downtackbelowcmb=798;e.downtackmod=725;e.dparen=9375;e.dsuperior=63211;e.dtail=598;e.dtopbar=396;e.duhiragana=12389;e.dukatakana=12485;e.dz=499;e.dzaltone=675;e.dzcaron=454;e.dzcurl=677;e.dzeabkhasiancyrillic=1249;e.dzecyrillic=1109;e.dzhecyrillic=1119;e.e=101;e.eacute=233;e.earth=9793;e.ebengali=2447;e.ebopomofo=12572;e.ebreve=277;e.ecandradeva=2317;e.ecandragujarati=2701;e.ecandravowelsigndeva=2373;e.ecandravowelsigngujarati=2757;e.ecaron=283;e.ecedillabreve=7709;e.echarmenian=1381;e.echyiwnarmenian=1415;e.ecircle=9428;e.ecircumflex=234;e.ecircumflexacute=7871;e.ecircumflexbelow=7705;e.ecircumflexdotbelow=7879;e.ecircumflexgrave=7873;e.ecircumflexhookabove=7875;e.ecircumflextilde=7877;e.ecyrillic=1108;e.edblgrave=517;e.edeva=2319;e.edieresis=235;e.edot=279;e.edotaccent=279;e.edotbelow=7865;e.eegurmukhi=2575;e.eematragurmukhi=2631;e.efcyrillic=1092;e.egrave=232;e.egujarati=2703;e.eharmenian=1383;e.ehbopomofo=12573;e.ehiragana=12360;e.ehookabove=7867;e.eibopomofo=12575;e.eight=56;e.eightarabic=1640;e.eightbengali=2542;e.eightcircle=9319;e.eightcircleinversesansserif=10129;e.eightdeva=2414;e.eighteencircle=9329;e.eighteenparen=9349;e.eighteenperiod=9369;e.eightgujarati=2798;e.eightgurmukhi=2670;e.eighthackarabic=1640;e.eighthangzhou=12328;e.eighthnotebeamed=9835;e.eightideographicparen=12839;e.eightinferior=8328;e.eightmonospace=65304;e.eightoldstyle=63288;e.eightparen=9339;e.eightperiod=9359;e.eightpersian=1784;e.eightroman=8567;e.eightsuperior=8312;e.eightthai=3672;e.einvertedbreve=519;e.eiotifiedcyrillic=1125;e.ekatakana=12456;e.ekatakanahalfwidth=65396;e.ekonkargurmukhi=2676;e.ekorean=12628;e.elcyrillic=1083;e.element=8712;e.elevencircle=9322;e.elevenparen=9342;e.elevenperiod=9362;e.elevenroman=8570;e.ellipsis=8230;e.ellipsisvertical=8942;e.emacron=275;e.emacronacute=7703;e.emacrongrave=7701;e.emcyrillic=1084;e.emdash=8212;e.emdashvertical=65073;e.emonospace=65349;e.emphasismarkarmenian=1371;e.emptyset=8709;e.enbopomofo=12579;e.encyrillic=1085;e.endash=8211;e.endashvertical=65074;e.endescendercyrillic=1187;e.eng=331;e.engbopomofo=12581;e.enghecyrillic=1189;e.enhookcyrillic=1224;e.enspace=8194;e.eogonek=281;e.eokorean=12627;e.eopen=603;e.eopenclosed=666;e.eopenreversed=604;e.eopenreversedclosed=606;e.eopenreversedhook=605;e.eparen=9376;e.epsilon=949;e.epsilontonos=941;e.equal=61;e.equalmonospace=65309;e.equalsmall=65126;e.equalsuperior=8316;e.equivalence=8801;e.erbopomofo=12582;e.ercyrillic=1088;e.ereversed=600;e.ereversedcyrillic=1101;e.escyrillic=1089;e.esdescendercyrillic=1195;e.esh=643;e.eshcurl=646;e.eshortdeva=2318;e.eshortvowelsigndeva=2374;e.eshreversedloop=426;e.eshsquatreversed=645;e.esmallhiragana=12359;e.esmallkatakana=12455;e.esmallkatakanahalfwidth=65386;e.estimated=8494;e.esuperior=63212;e.eta=951;e.etarmenian=1384;e.etatonos=942;e.eth=240;e.etilde=7869;e.etildebelow=7707;e.etnahtafoukhhebrew=1425;e.etnahtafoukhlefthebrew=1425;e.etnahtahebrew=1425;e.etnahtalefthebrew=1425;e.eturned=477;e.eukorean=12641;e.euro=8364;e.evowelsignbengali=2503;e.evowelsigndeva=2375;e.evowelsigngujarati=2759;e.exclam=33;e.exclamarmenian=1372;e.exclamdbl=8252;e.exclamdown=161;e.exclamdownsmall=63393;e.exclammonospace=65281;e.exclamsmall=63265;e.existential=8707;e.ezh=658;e.ezhcaron=495;e.ezhcurl=659;e.ezhreversed=441;e.ezhtail=442;e.f=102;e.fadeva=2398;e.fagurmukhi=2654;e.fahrenheit=8457;e.fathaarabic=1614;e.fathalowarabic=1614;e.fathatanarabic=1611;e.fbopomofo=12552;e.fcircle=9429;e.fdotaccent=7711;e.feharabic=1601;e.feharmenian=1414;e.fehfinalarabic=65234;e.fehinitialarabic=65235;e.fehmedialarabic=65236;e.feicoptic=997;e.female=9792;e.ff=64256;e.f_f=64256;e.ffi=64259;e.f_f_i=64259;e.ffl=64260;e.f_f_l=64260;e.fi=64257;e.f_i=64257;e.fifteencircle=9326;e.fifteenparen=9346;e.fifteenperiod=9366;e.figuredash=8210;e.filledbox=9632;e.filledrect=9644;e.finalkaf=1498;e.finalkafdagesh=64314;e.finalkafdageshhebrew=64314;e.finalkafhebrew=1498;e.finalmem=1501;e.finalmemhebrew=1501;e.finalnun=1503;e.finalnunhebrew=1503;e.finalpe=1507;e.finalpehebrew=1507;e.finaltsadi=1509;e.finaltsadihebrew=1509;e.firsttonechinese=713;e.fisheye=9673;e.fitacyrillic=1139;e.five=53;e.fivearabic=1637;e.fivebengali=2539;e.fivecircle=9316;e.fivecircleinversesansserif=10126;e.fivedeva=2411;e.fiveeighths=8541;e.fivegujarati=2795;e.fivegurmukhi=2667;e.fivehackarabic=1637;e.fivehangzhou=12325;e.fiveideographicparen=12836;e.fiveinferior=8325;e.fivemonospace=65301;e.fiveoldstyle=63285;e.fiveparen=9336;e.fiveperiod=9356;e.fivepersian=1781;e.fiveroman=8564;e.fivesuperior=8309;e.fivethai=3669;e.fl=64258;e.f_l=64258;e.florin=402;e.fmonospace=65350;e.fmsquare=13209;e.fofanthai=3615;e.fofathai=3613;e.fongmanthai=3663;e.forall=8704;e.four=52;e.fourarabic=1636;e.fourbengali=2538;e.fourcircle=9315;e.fourcircleinversesansserif=10125;e.fourdeva=2410;e.fourgujarati=2794;e.fourgurmukhi=2666;e.fourhackarabic=1636;e.fourhangzhou=12324;e.fourideographicparen=12835;e.fourinferior=8324;e.fourmonospace=65300;e.fournumeratorbengali=2551;e.fouroldstyle=63284;e.fourparen=9335;e.fourperiod=9355;e.fourpersian=1780;e.fourroman=8563;e.foursuperior=8308;e.fourteencircle=9325;e.fourteenparen=9345;e.fourteenperiod=9365;e.fourthai=3668;e.fourthtonechinese=715;e.fparen=9377;e.fraction=8260;e.franc=8355;e.g=103;e.gabengali=2455;e.gacute=501;e.gadeva=2327;e.gafarabic=1711;e.gaffinalarabic=64403;e.gafinitialarabic=64404;e.gafmedialarabic=64405;e.gagujarati=2711;e.gagurmukhi=2583;e.gahiragana=12364;e.gakatakana=12460;e.gamma=947;e.gammalatinsmall=611;e.gammasuperior=736;e.gangiacoptic=1003;e.gbopomofo=12557;e.gbreve=287;e.gcaron=487;e.gcedilla=291;e.gcircle=9430;e.gcircumflex=285;e.gcommaaccent=291;e.gdot=289;e.gdotaccent=289;e.gecyrillic=1075;e.gehiragana=12370;e.gekatakana=12466;e.geometricallyequal=8785;e.gereshaccenthebrew=1436;e.gereshhebrew=1523;e.gereshmuqdamhebrew=1437;e.germandbls=223;e.gershayimaccenthebrew=1438;e.gershayimhebrew=1524;e.getamark=12307;e.ghabengali=2456;e.ghadarmenian=1394;e.ghadeva=2328;e.ghagujarati=2712;e.ghagurmukhi=2584;e.ghainarabic=1594;e.ghainfinalarabic=65230;e.ghaininitialarabic=65231;e.ghainmedialarabic=65232;e.ghemiddlehookcyrillic=1173;e.ghestrokecyrillic=1171;e.gheupturncyrillic=1169;e.ghhadeva=2394;e.ghhagurmukhi=2650;e.ghook=608;e.ghzsquare=13203;e.gihiragana=12366;e.gikatakana=12462;e.gimarmenian=1379;e.gimel=1490;e.gimeldagesh=64306;e.gimeldageshhebrew=64306;e.gimelhebrew=1490;e.gjecyrillic=1107;e.glottalinvertedstroke=446;e.glottalstop=660;e.glottalstopinverted=662;e.glottalstopmod=704;e.glottalstopreversed=661;e.glottalstopreversedmod=705;e.glottalstopreversedsuperior=740;e.glottalstopstroke=673;e.glottalstopstrokereversed=674;e.gmacron=7713;e.gmonospace=65351;e.gohiragana=12372;e.gokatakana=12468;e.gparen=9378;e.gpasquare=13228;e.gradient=8711;e.grave=96;e.gravebelowcmb=790;e.gravecmb=768;e.gravecomb=768;e.gravedeva=2387;e.gravelowmod=718;e.gravemonospace=65344;e.gravetonecmb=832;e.greater=62;e.greaterequal=8805;e.greaterequalorless=8923;e.greatermonospace=65310;e.greaterorequivalent=8819;e.greaterorless=8823;e.greateroverequal=8807;e.greatersmall=65125;e.gscript=609;e.gstroke=485;e.guhiragana=12368;e.guillemotleft=171;e.guillemotright=187;e.guilsinglleft=8249;e.guilsinglright=8250;e.gukatakana=12464;e.guramusquare=13080;e.gysquare=13257;e.h=104;e.haabkhasiancyrillic=1193;e.haaltonearabic=1729;e.habengali=2489;e.hadescendercyrillic=1203;e.hadeva=2361;e.hagujarati=2745;e.hagurmukhi=2617;e.haharabic=1581;e.hahfinalarabic=65186;e.hahinitialarabic=65187;e.hahiragana=12399;e.hahmedialarabic=65188;e.haitusquare=13098;e.hakatakana=12495;e.hakatakanahalfwidth=65418;e.halantgurmukhi=2637;e.hamzaarabic=1569;e.hamzalowarabic=1569;e.hangulfiller=12644;e.hardsigncyrillic=1098;e.harpoonleftbarbup=8636;e.harpoonrightbarbup=8640;e.hasquare=13258;e.hatafpatah=1458;e.hatafpatah16=1458;e.hatafpatah23=1458;e.hatafpatah2f=1458;e.hatafpatahhebrew=1458;e.hatafpatahnarrowhebrew=1458;e.hatafpatahquarterhebrew=1458;e.hatafpatahwidehebrew=1458;e.hatafqamats=1459;e.hatafqamats1b=1459;e.hatafqamats28=1459;e.hatafqamats34=1459;e.hatafqamatshebrew=1459;e.hatafqamatsnarrowhebrew=1459;e.hatafqamatsquarterhebrew=1459;e.hatafqamatswidehebrew=1459;e.hatafsegol=1457;e.hatafsegol17=1457;e.hatafsegol24=1457;e.hatafsegol30=1457;e.hatafsegolhebrew=1457;e.hatafsegolnarrowhebrew=1457;e.hatafsegolquarterhebrew=1457;e.hatafsegolwidehebrew=1457;e.hbar=295;e.hbopomofo=12559;e.hbrevebelow=7723;e.hcedilla=7721;e.hcircle=9431;e.hcircumflex=293;e.hdieresis=7719;e.hdotaccent=7715;e.hdotbelow=7717;e.he=1492;e.heart=9829;e.heartsuitblack=9829;e.heartsuitwhite=9825;e.hedagesh=64308;e.hedageshhebrew=64308;e.hehaltonearabic=1729;e.heharabic=1607;e.hehebrew=1492;e.hehfinalaltonearabic=64423;e.hehfinalalttwoarabic=65258;e.hehfinalarabic=65258;e.hehhamzaabovefinalarabic=64421;e.hehhamzaaboveisolatedarabic=64420;e.hehinitialaltonearabic=64424;e.hehinitialarabic=65259;e.hehiragana=12408;e.hehmedialaltonearabic=64425;e.hehmedialarabic=65260;e.heiseierasquare=13179;e.hekatakana=12504;e.hekatakanahalfwidth=65421;e.hekutaarusquare=13110;e.henghook=615;e.herutusquare=13113;e.het=1495;e.hethebrew=1495;e.hhook=614;e.hhooksuperior=689;e.hieuhacirclekorean=12923;e.hieuhaparenkorean=12827;e.hieuhcirclekorean=12909;e.hieuhkorean=12622;e.hieuhparenkorean=12813;e.hihiragana=12402;e.hikatakana=12498;e.hikatakanahalfwidth=65419;e.hiriq=1460;e.hiriq14=1460;e.hiriq21=1460;e.hiriq2d=1460;e.hiriqhebrew=1460;e.hiriqnarrowhebrew=1460;e.hiriqquarterhebrew=1460;e.hiriqwidehebrew=1460;e.hlinebelow=7830;e.hmonospace=65352;e.hoarmenian=1392;e.hohipthai=3627;e.hohiragana=12411;e.hokatakana=12507;e.hokatakanahalfwidth=65422;e.holam=1465;e.holam19=1465;e.holam26=1465;e.holam32=1465;e.holamhebrew=1465;e.holamnarrowhebrew=1465;e.holamquarterhebrew=1465;e.holamwidehebrew=1465;e.honokhukthai=3630;e.hookabovecomb=777;e.hookcmb=777;e.hookpalatalizedbelowcmb=801;e.hookretroflexbelowcmb=802;e.hoonsquare=13122;e.horicoptic=1001;e.horizontalbar=8213;e.horncmb=795;e.hotsprings=9832;e.house=8962;e.hparen=9379;e.hsuperior=688;e.hturned=613;e.huhiragana=12405;e.huiitosquare=13107;e.hukatakana=12501;e.hukatakanahalfwidth=65420;e.hungarumlaut=733;e.hungarumlautcmb=779;e.hv=405;e.hyphen=45;e.hypheninferior=63205;e.hyphenmonospace=65293;e.hyphensmall=65123;e.hyphensuperior=63206;e.hyphentwo=8208;e.i=105;e.iacute=237;e.iacyrillic=1103;e.ibengali=2439;e.ibopomofo=12583;e.ibreve=301;e.icaron=464;e.icircle=9432;e.icircumflex=238;e.icyrillic=1110;e.idblgrave=521;e.ideographearthcircle=12943;e.ideographfirecircle=12939;e.ideographicallianceparen=12863;e.ideographiccallparen=12858;e.ideographiccentrecircle=12965;e.ideographicclose=12294;e.ideographiccomma=12289;e.ideographiccommaleft=65380;e.ideographiccongratulationparen=12855;e.ideographiccorrectcircle=12963;e.ideographicearthparen=12847;e.ideographicenterpriseparen=12861;e.ideographicexcellentcircle=12957;e.ideographicfestivalparen=12864;e.ideographicfinancialcircle=12950;e.ideographicfinancialparen=12854;e.ideographicfireparen=12843;e.ideographichaveparen=12850;e.ideographichighcircle=12964;e.ideographiciterationmark=12293;e.ideographiclaborcircle=12952;e.ideographiclaborparen=12856;e.ideographicleftcircle=12967;e.ideographiclowcircle=12966;e.ideographicmedicinecircle=12969;e.ideographicmetalparen=12846;e.ideographicmoonparen=12842;e.ideographicnameparen=12852;e.ideographicperiod=12290;e.ideographicprintcircle=12958;e.ideographicreachparen=12867;e.ideographicrepresentparen=12857;e.ideographicresourceparen=12862;e.ideographicrightcircle=12968;e.ideographicsecretcircle=12953;e.ideographicselfparen=12866;e.ideographicsocietyparen=12851;e.ideographicspace=12288;e.ideographicspecialparen=12853;e.ideographicstockparen=12849;e.ideographicstudyparen=12859;e.ideographicsunparen=12848;e.ideographicsuperviseparen=12860;e.ideographicwaterparen=12844;e.ideographicwoodparen=12845;e.ideographiczero=12295;e.ideographmetalcircle=12942;e.ideographmooncircle=12938;e.ideographnamecircle=12948;e.ideographsuncircle=12944;e.ideographwatercircle=12940;e.ideographwoodcircle=12941;e.ideva=2311;e.idieresis=239;e.idieresisacute=7727;e.idieresiscyrillic=1253;e.idotbelow=7883;e.iebrevecyrillic=1239;e.iecyrillic=1077;e.ieungacirclekorean=12917;e.ieungaparenkorean=12821;e.ieungcirclekorean=12903;e.ieungkorean=12615;e.ieungparenkorean=12807;e.igrave=236;e.igujarati=2695;e.igurmukhi=2567;e.ihiragana=12356;e.ihookabove=7881;e.iibengali=2440;e.iicyrillic=1080;e.iideva=2312;e.iigujarati=2696;e.iigurmukhi=2568;e.iimatragurmukhi=2624;e.iinvertedbreve=523;e.iishortcyrillic=1081;e.iivowelsignbengali=2496;e.iivowelsigndeva=2368;e.iivowelsigngujarati=2752;e.ij=307;e.ikatakana=12452;e.ikatakanahalfwidth=65394;e.ikorean=12643;e.ilde=732;e.iluyhebrew=1452;e.imacron=299;e.imacroncyrillic=1251;e.imageorapproximatelyequal=8787;e.imatragurmukhi=2623;e.imonospace=65353;e.increment=8710;e.infinity=8734;e.iniarmenian=1387;e.integral=8747;e.integralbottom=8993;e.integralbt=8993;e.integralex=63733;e.integraltop=8992;e.integraltp=8992;e.intersection=8745;e.intisquare=13061;e.invbullet=9688;e.invcircle=9689;e.invsmileface=9787;e.iocyrillic=1105;e.iogonek=303;e.iota=953;e.iotadieresis=970;e.iotadieresistonos=912;e.iotalatin=617;e.iotatonos=943;e.iparen=9380;e.irigurmukhi=2674;e.ismallhiragana=12355;e.ismallkatakana=12451;e.ismallkatakanahalfwidth=65384;e.issharbengali=2554;e.istroke=616;e.isuperior=63213;e.iterationhiragana=12445;e.iterationkatakana=12541;e.itilde=297;e.itildebelow=7725;e.iubopomofo=12585;e.iucyrillic=1102;e.ivowelsignbengali=2495;e.ivowelsigndeva=2367;e.ivowelsigngujarati=2751;e.izhitsacyrillic=1141;e.izhitsadblgravecyrillic=1143;e.j=106;e.jaarmenian=1393;e.jabengali=2460;e.jadeva=2332;e.jagujarati=2716;e.jagurmukhi=2588;e.jbopomofo=12560;e.jcaron=496;e.jcircle=9433;e.jcircumflex=309;e.jcrossedtail=669;e.jdotlessstroke=607;e.jecyrillic=1112;e.jeemarabic=1580;e.jeemfinalarabic=65182;e.jeeminitialarabic=65183;e.jeemmedialarabic=65184;e.jeharabic=1688;e.jehfinalarabic=64395;e.jhabengali=2461;e.jhadeva=2333;e.jhagujarati=2717;e.jhagurmukhi=2589;e.jheharmenian=1403;e.jis=12292;e.jmonospace=65354;e.jparen=9381;e.jsuperior=690;e.k=107;e.kabashkircyrillic=1185;e.kabengali=2453;e.kacute=7729;e.kacyrillic=1082;e.kadescendercyrillic=1179;e.kadeva=2325;e.kaf=1499;e.kafarabic=1603;e.kafdagesh=64315;e.kafdageshhebrew=64315;e.kaffinalarabic=65242;e.kafhebrew=1499;e.kafinitialarabic=65243;e.kafmedialarabic=65244;e.kafrafehebrew=64333;e.kagujarati=2709;e.kagurmukhi=2581;e.kahiragana=12363;e.kahookcyrillic=1220;e.kakatakana=12459;e.kakatakanahalfwidth=65398;e.kappa=954;e.kappasymbolgreek=1008;e.kapyeounmieumkorean=12657;e.kapyeounphieuphkorean=12676;e.kapyeounpieupkorean=12664;e.kapyeounssangpieupkorean=12665;e.karoriisquare=13069;e.kashidaautoarabic=1600;e.kashidaautonosidebearingarabic=1600;e.kasmallkatakana=12533;e.kasquare=13188;e.kasraarabic=1616;e.kasratanarabic=1613;e.kastrokecyrillic=1183;e.katahiraprolongmarkhalfwidth=65392;e.kaverticalstrokecyrillic=1181;e.kbopomofo=12558;e.kcalsquare=13193;e.kcaron=489;e.kcedilla=311;e.kcircle=9434;e.kcommaaccent=311;e.kdotbelow=7731;e.keharmenian=1412;e.kehiragana=12369;e.kekatakana=12465;e.kekatakanahalfwidth=65401;e.kenarmenian=1391;e.kesmallkatakana=12534;e.kgreenlandic=312;e.khabengali=2454;e.khacyrillic=1093;e.khadeva=2326;e.khagujarati=2710;e.khagurmukhi=2582;e.khaharabic=1582;e.khahfinalarabic=65190;e.khahinitialarabic=65191;e.khahmedialarabic=65192;e.kheicoptic=999;e.khhadeva=2393;e.khhagurmukhi=2649;e.khieukhacirclekorean=12920;e.khieukhaparenkorean=12824;e.khieukhcirclekorean=12906;e.khieukhkorean=12619;e.khieukhparenkorean=12810;e.khokhaithai=3586;e.khokhonthai=3589;e.khokhuatthai=3587;e.khokhwaithai=3588;e.khomutthai=3675;e.khook=409;e.khorakhangthai=3590;e.khzsquare=13201;e.kihiragana=12365;e.kikatakana=12461;e.kikatakanahalfwidth=65399;e.kiroguramusquare=13077;e.kiromeetorusquare=13078;e.kirosquare=13076;e.kiyeokacirclekorean=12910;e.kiyeokaparenkorean=12814;e.kiyeokcirclekorean=12896;e.kiyeokkorean=12593;e.kiyeokparenkorean=12800;e.kiyeoksioskorean=12595;e.kjecyrillic=1116;e.klinebelow=7733;e.klsquare=13208;e.kmcubedsquare=13222;e.kmonospace=65355;e.kmsquaredsquare=13218;e.kohiragana=12371;e.kohmsquare=13248;e.kokaithai=3585;e.kokatakana=12467;e.kokatakanahalfwidth=65402;e.kooposquare=13086;e.koppacyrillic=1153;e.koreanstandardsymbol=12927;e.koroniscmb=835;e.kparen=9382;e.kpasquare=13226;e.ksicyrillic=1135;e.ktsquare=13263;e.kturned=670;e.kuhiragana=12367;e.kukatakana=12463;e.kukatakanahalfwidth=65400;e.kvsquare=13240;e.kwsquare=13246;e.l=108;e.labengali=2482;e.lacute=314;e.ladeva=2354;e.lagujarati=2738;e.lagurmukhi=2610;e.lakkhangyaothai=3653;e.lamaleffinalarabic=65276;e.lamalefhamzaabovefinalarabic=65272;e.lamalefhamzaaboveisolatedarabic=65271;e.lamalefhamzabelowfinalarabic=65274;e.lamalefhamzabelowisolatedarabic=65273;e.lamalefisolatedarabic=65275;e.lamalefmaddaabovefinalarabic=65270;e.lamalefmaddaaboveisolatedarabic=65269;e.lamarabic=1604;e.lambda=955;e.lambdastroke=411;e.lamed=1500;e.lameddagesh=64316;e.lameddageshhebrew=64316;e.lamedhebrew=1500;e.lamfinalarabic=65246;e.lamhahinitialarabic=64714;e.laminitialarabic=65247;e.lamjeeminitialarabic=64713;e.lamkhahinitialarabic=64715;e.lamlamhehisolatedarabic=65010;e.lammedialarabic=65248;e.lammeemhahinitialarabic=64904;e.lammeeminitialarabic=64716;e.largecircle=9711;e.lbar=410;e.lbelt=620;e.lbopomofo=12556;e.lcaron=318;e.lcedilla=316;e.lcircle=9435;e.lcircumflexbelow=7741;e.lcommaaccent=316;e.ldot=320;e.ldotaccent=320;e.ldotbelow=7735;e.ldotbelowmacron=7737;e.leftangleabovecmb=794;e.lefttackbelowcmb=792;e.less=60;e.lessequal=8804;e.lessequalorgreater=8922;e.lessmonospace=65308;e.lessorequivalent=8818;e.lessorgreater=8822;e.lessoverequal=8806;e.lesssmall=65124;e.lezh=622;e.lfblock=9612;e.lhookretroflex=621;e.lira=8356;e.liwnarmenian=1388;e.lj=457;e.ljecyrillic=1113;e.ll=63168;e.lladeva=2355;e.llagujarati=2739;e.llinebelow=7739;e.llladeva=2356;e.llvocalicbengali=2529;e.llvocalicdeva=2401;e.llvocalicvowelsignbengali=2531;e.llvocalicvowelsigndeva=2403;e.lmiddletilde=619;e.lmonospace=65356;e.lmsquare=13264;e.lochulathai=3628;e.logicaland=8743;e.logicalnot=172;e.logicalnotreversed=8976;e.logicalor=8744;e.lolingthai=3621;e.longs=383;e.lowlinecenterline=65102;e.lowlinecmb=818;e.lowlinedashed=65101;e.lozenge=9674;e.lparen=9383;e.lslash=322;e.lsquare=8467;e.lsuperior=63214;e.ltshade=9617;e.luthai=3622;e.lvocalicbengali=2444;e.lvocalicdeva=2316;e.lvocalicvowelsignbengali=2530;e.lvocalicvowelsigndeva=2402;e.lxsquare=13267;e.m=109;e.mabengali=2478;e.macron=175;e.macronbelowcmb=817;e.macroncmb=772;e.macronlowmod=717;e.macronmonospace=65507;e.macute=7743;e.madeva=2350;e.magujarati=2734;e.magurmukhi=2606;e.mahapakhhebrew=1444;e.mahapakhlefthebrew=1444;e.mahiragana=12414;e.maichattawalowleftthai=63637;e.maichattawalowrightthai=63636;e.maichattawathai=3659;e.maichattawaupperleftthai=63635;e.maieklowleftthai=63628;e.maieklowrightthai=63627;e.maiekthai=3656;e.maiekupperleftthai=63626;e.maihanakatleftthai=63620;e.maihanakatthai=3633;e.maitaikhuleftthai=63625;e.maitaikhuthai=3655;e.maitholowleftthai=63631;e.maitholowrightthai=63630;e.maithothai=3657;e.maithoupperleftthai=63629;e.maitrilowleftthai=63634;e.maitrilowrightthai=63633;e.maitrithai=3658;e.maitriupperleftthai=63632;e.maiyamokthai=3654;e.makatakana=12510;e.makatakanahalfwidth=65423;e.male=9794;e.mansyonsquare=13127;e.maqafhebrew=1470;e.mars=9794;e.masoracirclehebrew=1455;e.masquare=13187;e.mbopomofo=12551;e.mbsquare=13268;e.mcircle=9436;e.mcubedsquare=13221;e.mdotaccent=7745;e.mdotbelow=7747;e.meemarabic=1605;e.meemfinalarabic=65250;e.meeminitialarabic=65251;e.meemmedialarabic=65252;e.meemmeeminitialarabic=64721;e.meemmeemisolatedarabic=64584;e.meetorusquare=13133;e.mehiragana=12417;e.meizierasquare=13182;e.mekatakana=12513;e.mekatakanahalfwidth=65426;e.mem=1502;e.memdagesh=64318;e.memdageshhebrew=64318;e.memhebrew=1502;e.menarmenian=1396;e.merkhahebrew=1445;e.merkhakefulahebrew=1446;e.merkhakefulalefthebrew=1446;e.merkhalefthebrew=1445;e.mhook=625;e.mhzsquare=13202;e.middledotkatakanahalfwidth=65381;e.middot=183;e.mieumacirclekorean=12914;e.mieumaparenkorean=12818;e.mieumcirclekorean=12900;e.mieumkorean=12609;e.mieumpansioskorean=12656;e.mieumparenkorean=12804;e.mieumpieupkorean=12654;e.mieumsioskorean=12655;e.mihiragana=12415;e.mikatakana=12511;e.mikatakanahalfwidth=65424;e.minus=8722;e.minusbelowcmb=800;e.minuscircle=8854;e.minusmod=727;e.minusplus=8723;e.minute=8242;e.miribaarusquare=13130;e.mirisquare=13129;e.mlonglegturned=624;e.mlsquare=13206;e.mmcubedsquare=13219;e.mmonospace=65357;e.mmsquaredsquare=13215;e.mohiragana=12418;e.mohmsquare=13249;e.mokatakana=12514;e.mokatakanahalfwidth=65427;e.molsquare=13270;e.momathai=3617;e.moverssquare=13223;e.moverssquaredsquare=13224;e.mparen=9384;e.mpasquare=13227;e.mssquare=13235;e.msuperior=63215;e.mturned=623;e.mu=181;e.mu1=181;e.muasquare=13186;e.muchgreater=8811;e.muchless=8810;e.mufsquare=13196;e.mugreek=956;e.mugsquare=13197;e.muhiragana=12416;e.mukatakana=12512;e.mukatakanahalfwidth=65425;e.mulsquare=13205;e.multiply=215;e.mumsquare=13211;e.munahhebrew=1443;e.munahlefthebrew=1443;e.musicalnote=9834;e.musicalnotedbl=9835;e.musicflatsign=9837;e.musicsharpsign=9839;e.mussquare=13234;e.muvsquare=13238;e.muwsquare=13244;e.mvmegasquare=13241;e.mvsquare=13239;e.mwmegasquare=13247;e.mwsquare=13245;e.n=110;e.nabengali=2472;e.nabla=8711;e.nacute=324;e.nadeva=2344;e.nagujarati=2728;e.nagurmukhi=2600;e.nahiragana=12394;e.nakatakana=12490;e.nakatakanahalfwidth=65413;e.napostrophe=329;e.nasquare=13185;e.nbopomofo=12555;e.nbspace=160;e.ncaron=328;e.ncedilla=326;e.ncircle=9437;e.ncircumflexbelow=7755;e.ncommaaccent=326;e.ndotaccent=7749;e.ndotbelow=7751;e.nehiragana=12397;e.nekatakana=12493;e.nekatakanahalfwidth=65416;e.newsheqelsign=8362;e.nfsquare=13195;e.ngabengali=2457;e.ngadeva=2329;e.ngagujarati=2713;e.ngagurmukhi=2585;e.ngonguthai=3591;e.nhiragana=12435;e.nhookleft=626;e.nhookretroflex=627;e.nieunacirclekorean=12911;e.nieunaparenkorean=12815;e.nieuncieuckorean=12597;e.nieuncirclekorean=12897;e.nieunhieuhkorean=12598;e.nieunkorean=12596;e.nieunpansioskorean=12648;e.nieunparenkorean=12801;e.nieunsioskorean=12647;e.nieuntikeutkorean=12646;e.nihiragana=12395;e.nikatakana=12491;e.nikatakanahalfwidth=65414;e.nikhahitleftthai=63641;e.nikhahitthai=3661;e.nine=57;e.ninearabic=1641;e.ninebengali=2543;e.ninecircle=9320;e.ninecircleinversesansserif=10130;e.ninedeva=2415;e.ninegujarati=2799;e.ninegurmukhi=2671;e.ninehackarabic=1641;e.ninehangzhou=12329;e.nineideographicparen=12840;e.nineinferior=8329;e.ninemonospace=65305;e.nineoldstyle=63289;e.nineparen=9340;e.nineperiod=9360;e.ninepersian=1785;e.nineroman=8568;e.ninesuperior=8313;e.nineteencircle=9330;e.nineteenparen=9350;e.nineteenperiod=9370;e.ninethai=3673;e.nj=460;e.njecyrillic=1114;e.nkatakana=12531;e.nkatakanahalfwidth=65437;e.nlegrightlong=414;e.nlinebelow=7753;e.nmonospace=65358;e.nmsquare=13210;e.nnabengali=2467;e.nnadeva=2339;e.nnagujarati=2723;e.nnagurmukhi=2595;e.nnnadeva=2345;e.nohiragana=12398;e.nokatakana=12494;e.nokatakanahalfwidth=65417;e.nonbreakingspace=160;e.nonenthai=3603;e.nonuthai=3609;e.noonarabic=1606;e.noonfinalarabic=65254;e.noonghunnaarabic=1722;e.noonghunnafinalarabic=64415;e.nooninitialarabic=65255;e.noonjeeminitialarabic=64722;e.noonjeemisolatedarabic=64587;e.noonmedialarabic=65256;e.noonmeeminitialarabic=64725;e.noonmeemisolatedarabic=64590;e.noonnoonfinalarabic=64653;e.notcontains=8716;e.notelement=8713;e.notelementof=8713;e.notequal=8800;e.notgreater=8815;e.notgreaternorequal=8817;e.notgreaternorless=8825;e.notidentical=8802;e.notless=8814;e.notlessnorequal=8816;e.notparallel=8742;e.notprecedes=8832;e.notsubset=8836;e.notsucceeds=8833;e.notsuperset=8837;e.nowarmenian=1398;e.nparen=9385;e.nssquare=13233;e.nsuperior=8319;e.ntilde=241;e.nu=957;e.nuhiragana=12396;e.nukatakana=12492;e.nukatakanahalfwidth=65415;e.nuktabengali=2492;e.nuktadeva=2364;e.nuktagujarati=2748;e.nuktagurmukhi=2620;e.numbersign=35;e.numbersignmonospace=65283;e.numbersignsmall=65119;e.numeralsigngreek=884;e.numeralsignlowergreek=885;e.numero=8470;e.nun=1504;e.nundagesh=64320;e.nundageshhebrew=64320;e.nunhebrew=1504;e.nvsquare=13237;e.nwsquare=13243;e.nyabengali=2462;e.nyadeva=2334;e.nyagujarati=2718;e.nyagurmukhi=2590;e.o=111;e.oacute=243;e.oangthai=3629;e.obarred=629;e.obarredcyrillic=1257;e.obarreddieresiscyrillic=1259;e.obengali=2451;e.obopomofo=12571;e.obreve=335;e.ocandradeva=2321;e.ocandragujarati=2705;e.ocandravowelsigndeva=2377;e.ocandravowelsigngujarati=2761;e.ocaron=466;e.ocircle=9438;e.ocircumflex=244;e.ocircumflexacute=7889;e.ocircumflexdotbelow=7897;e.ocircumflexgrave=7891;e.ocircumflexhookabove=7893;e.ocircumflextilde=7895;e.ocyrillic=1086;e.odblacute=337;e.odblgrave=525;e.odeva=2323;e.odieresis=246;e.odieresiscyrillic=1255;e.odotbelow=7885;e.oe=339;e.oekorean=12634;e.ogonek=731;e.ogonekcmb=808;e.ograve=242;e.ogujarati=2707;e.oharmenian=1413;e.ohiragana=12362;e.ohookabove=7887;e.ohorn=417;e.ohornacute=7899;e.ohorndotbelow=7907;e.ohorngrave=7901;e.ohornhookabove=7903;e.ohorntilde=7905;e.ohungarumlaut=337;e.oi=419;e.oinvertedbreve=527;e.okatakana=12458;e.okatakanahalfwidth=65397;e.okorean=12631;e.olehebrew=1451;e.omacron=333;e.omacronacute=7763;e.omacrongrave=7761;e.omdeva=2384;e.omega=969;e.omega1=982;e.omegacyrillic=1121;e.omegalatinclosed=631;e.omegaroundcyrillic=1147;e.omegatitlocyrillic=1149;e.omegatonos=974;e.omgujarati=2768;e.omicron=959;e.omicrontonos=972;e.omonospace=65359;e.one=49;e.onearabic=1633;e.onebengali=2535;e.onecircle=9312;e.onecircleinversesansserif=10122;e.onedeva=2407;e.onedotenleader=8228;e.oneeighth=8539;e.onefitted=63196;e.onegujarati=2791;e.onegurmukhi=2663;e.onehackarabic=1633;e.onehalf=189;e.onehangzhou=12321;e.oneideographicparen=12832;e.oneinferior=8321;e.onemonospace=65297;e.onenumeratorbengali=2548;e.oneoldstyle=63281;e.oneparen=9332;e.oneperiod=9352;e.onepersian=1777;e.onequarter=188;e.oneroman=8560;e.onesuperior=185;e.onethai=3665;e.onethird=8531;e.oogonek=491;e.oogonekmacron=493;e.oogurmukhi=2579;e.oomatragurmukhi=2635;e.oopen=596;e.oparen=9386;e.openbullet=9702;e.option=8997;e.ordfeminine=170;e.ordmasculine=186;e.orthogonal=8735;e.oshortdeva=2322;e.oshortvowelsigndeva=2378;e.oslash=248;e.oslashacute=511;e.osmallhiragana=12361;e.osmallkatakana=12457;e.osmallkatakanahalfwidth=65387;e.ostrokeacute=511;e.osuperior=63216;e.otcyrillic=1151;e.otilde=245;e.otildeacute=7757;e.otildedieresis=7759;e.oubopomofo=12577;e.overline=8254;e.overlinecenterline=65098;e.overlinecmb=773;e.overlinedashed=65097;e.overlinedblwavy=65100;e.overlinewavy=65099;e.overscore=175;e.ovowelsignbengali=2507;e.ovowelsigndeva=2379;e.ovowelsigngujarati=2763;e.p=112;e.paampssquare=13184;e.paasentosquare=13099;e.pabengali=2474;e.pacute=7765;e.padeva=2346;e.pagedown=8671;e.pageup=8670;e.pagujarati=2730;e.pagurmukhi=2602;e.pahiragana=12401;e.paiyannoithai=3631;e.pakatakana=12497;e.palatalizationcyrilliccmb=1156;e.palochkacyrillic=1216;e.pansioskorean=12671;e.paragraph=182;e.parallel=8741;e.parenleft=40;e.parenleftaltonearabic=64830;e.parenleftbt=63725;e.parenleftex=63724;e.parenleftinferior=8333;e.parenleftmonospace=65288;e.parenleftsmall=65113;e.parenleftsuperior=8317;e.parenlefttp=63723;e.parenleftvertical=65077;e.parenright=41;e.parenrightaltonearabic=64831;e.parenrightbt=63736;e.parenrightex=63735;e.parenrightinferior=8334;e.parenrightmonospace=65289;e.parenrightsmall=65114;e.parenrightsuperior=8318;e.parenrighttp=63734;e.parenrightvertical=65078;e.partialdiff=8706;e.paseqhebrew=1472;e.pashtahebrew=1433;e.pasquare=13225;e.patah=1463;e.patah11=1463;e.patah1d=1463;e.patah2a=1463;e.patahhebrew=1463;e.patahnarrowhebrew=1463;e.patahquarterhebrew=1463;e.patahwidehebrew=1463;e.pazerhebrew=1441;e.pbopomofo=12550;e.pcircle=9439;e.pdotaccent=7767;e.pe=1508;e.pecyrillic=1087;e.pedagesh=64324;e.pedageshhebrew=64324;e.peezisquare=13115;e.pefinaldageshhebrew=64323;e.peharabic=1662;e.peharmenian=1402;e.pehebrew=1508;e.pehfinalarabic=64343;e.pehinitialarabic=64344;e.pehiragana=12410;e.pehmedialarabic=64345;e.pekatakana=12506;e.pemiddlehookcyrillic=1191;e.perafehebrew=64334;e.percent=37;e.percentarabic=1642;e.percentmonospace=65285;e.percentsmall=65130;e.period=46;e.periodarmenian=1417;e.periodcentered=183;e.periodhalfwidth=65377;e.periodinferior=63207;e.periodmonospace=65294;e.periodsmall=65106;e.periodsuperior=63208;e.perispomenigreekcmb=834;e.perpendicular=8869;e.perthousand=8240;e.peseta=8359;e.pfsquare=13194;e.phabengali=2475;e.phadeva=2347;e.phagujarati=2731;e.phagurmukhi=2603;e.phi=966;e.phi1=981;e.phieuphacirclekorean=12922;e.phieuphaparenkorean=12826;e.phieuphcirclekorean=12908;e.phieuphkorean=12621;e.phieuphparenkorean=12812;e.philatin=632;e.phinthuthai=3642;e.phisymbolgreek=981;e.phook=421;e.phophanthai=3614;e.phophungthai=3612;e.phosamphaothai=3616;e.pi=960;e.pieupacirclekorean=12915;e.pieupaparenkorean=12819;e.pieupcieuckorean=12662;e.pieupcirclekorean=12901;e.pieupkiyeokkorean=12658;e.pieupkorean=12610;e.pieupparenkorean=12805;e.pieupsioskiyeokkorean=12660;e.pieupsioskorean=12612;e.pieupsiostikeutkorean=12661;e.pieupthieuthkorean=12663;e.pieuptikeutkorean=12659;e.pihiragana=12404;e.pikatakana=12500;e.pisymbolgreek=982;e.piwrarmenian=1411;e.planckover2pi=8463;e.planckover2pi1=8463;e.plus=43;e.plusbelowcmb=799;e.pluscircle=8853;e.plusminus=177;e.plusmod=726;e.plusmonospace=65291;e.plussmall=65122;e.plussuperior=8314;e.pmonospace=65360;e.pmsquare=13272;e.pohiragana=12413;e.pointingindexdownwhite=9759;e.pointingindexleftwhite=9756;e.pointingindexrightwhite=9758;e.pointingindexupwhite=9757;e.pokatakana=12509;e.poplathai=3611;e.postalmark=12306;e.postalmarkface=12320;e.pparen=9387;e.precedes=8826;e.prescription=8478;e.primemod=697;e.primereversed=8245;e.product=8719;e.projective=8965;e.prolongedkana=12540;e.propellor=8984;e.propersubset=8834;e.propersuperset=8835;e.proportion=8759;e.proportional=8733;e.psi=968;e.psicyrillic=1137;e.psilipneumatacyrilliccmb=1158;e.pssquare=13232;e.puhiragana=12407;e.pukatakana=12503;e.pvsquare=13236;e.pwsquare=13242;e.q=113;e.qadeva=2392;e.qadmahebrew=1448;e.qafarabic=1602;e.qaffinalarabic=65238;e.qafinitialarabic=65239;e.qafmedialarabic=65240;e.qamats=1464;e.qamats10=1464;e.qamats1a=1464;e.qamats1c=1464;e.qamats27=1464;e.qamats29=1464;e.qamats33=1464;e.qamatsde=1464;e.qamatshebrew=1464;e.qamatsnarrowhebrew=1464;e.qamatsqatanhebrew=1464;e.qamatsqatannarrowhebrew=1464;e.qamatsqatanquarterhebrew=1464;e.qamatsqatanwidehebrew=1464;e.qamatsquarterhebrew=1464;e.qamatswidehebrew=1464;e.qarneyparahebrew=1439;e.qbopomofo=12561;e.qcircle=9440;e.qhook=672;e.qmonospace=65361;e.qof=1511;e.qofdagesh=64327;e.qofdageshhebrew=64327;e.qofhebrew=1511;e.qparen=9388;e.quarternote=9833;e.qubuts=1467;e.qubuts18=1467;e.qubuts25=1467;e.qubuts31=1467;e.qubutshebrew=1467;e.qubutsnarrowhebrew=1467;e.qubutsquarterhebrew=1467;e.qubutswidehebrew=1467;e.question=63;e.questionarabic=1567;e.questionarmenian=1374;e.questiondown=191;e.questiondownsmall=63423;e.questiongreek=894;e.questionmonospace=65311;e.questionsmall=63295;e.quotedbl=34;e.quotedblbase=8222;e.quotedblleft=8220;e.quotedblmonospace=65282;e.quotedblprime=12318;e.quotedblprimereversed=12317;e.quotedblright=8221;e.quoteleft=8216;e.quoteleftreversed=8219;e.quotereversed=8219;e.quoteright=8217;e.quoterightn=329;e.quotesinglbase=8218;e.quotesingle=39;e.quotesinglemonospace=65287;e.r=114;e.raarmenian=1404;e.rabengali=2480;e.racute=341;e.radeva=2352;e.radical=8730;e.radicalex=63717;e.radoverssquare=13230;e.radoverssquaredsquare=13231;e.radsquare=13229;e.rafe=1471;e.rafehebrew=1471;e.ragujarati=2736;e.ragurmukhi=2608;e.rahiragana=12425;e.rakatakana=12521;e.rakatakanahalfwidth=65431;e.ralowerdiagonalbengali=2545;e.ramiddlediagonalbengali=2544;e.ramshorn=612;e.ratio=8758;e.rbopomofo=12566;e.rcaron=345;e.rcedilla=343;e.rcircle=9441;e.rcommaaccent=343;e.rdblgrave=529;e.rdotaccent=7769;e.rdotbelow=7771;e.rdotbelowmacron=7773;e.referencemark=8251;e.reflexsubset=8838;e.reflexsuperset=8839;e.registered=174;e.registersans=63720;e.registerserif=63194;e.reharabic=1585;e.reharmenian=1408;e.rehfinalarabic=65198;e.rehiragana=12428;e.rekatakana=12524;e.rekatakanahalfwidth=65434;e.resh=1512;e.reshdageshhebrew=64328;e.reshhebrew=1512;e.reversedtilde=8765;e.reviahebrew=1431;e.reviamugrashhebrew=1431;e.revlogicalnot=8976;e.rfishhook=638;e.rfishhookreversed=639;e.rhabengali=2525;e.rhadeva=2397;e.rho=961;e.rhook=637;e.rhookturned=635;e.rhookturnedsuperior=693;e.rhosymbolgreek=1009;e.rhotichookmod=734;e.rieulacirclekorean=12913;e.rieulaparenkorean=12817;e.rieulcirclekorean=12899;e.rieulhieuhkorean=12608;e.rieulkiyeokkorean=12602;e.rieulkiyeoksioskorean=12649;e.rieulkorean=12601;e.rieulmieumkorean=12603;e.rieulpansioskorean=12652;e.rieulparenkorean=12803;e.rieulphieuphkorean=12607;e.rieulpieupkorean=12604;e.rieulpieupsioskorean=12651;e.rieulsioskorean=12605;e.rieulthieuthkorean=12606;e.rieultikeutkorean=12650;e.rieulyeorinhieuhkorean=12653;e.rightangle=8735;e.righttackbelowcmb=793;e.righttriangle=8895;e.rihiragana=12426;e.rikatakana=12522;e.rikatakanahalfwidth=65432;e.ring=730;e.ringbelowcmb=805;e.ringcmb=778;e.ringhalfleft=703;e.ringhalfleftarmenian=1369;e.ringhalfleftbelowcmb=796;e.ringhalfleftcentered=723;e.ringhalfright=702;e.ringhalfrightbelowcmb=825;e.ringhalfrightcentered=722;e.rinvertedbreve=531;e.rittorusquare=13137;e.rlinebelow=7775;e.rlongleg=636;e.rlonglegturned=634;e.rmonospace=65362;e.rohiragana=12429;e.rokatakana=12525;e.rokatakanahalfwidth=65435;e.roruathai=3619;e.rparen=9389;e.rrabengali=2524;e.rradeva=2353;e.rragurmukhi=2652;e.rreharabic=1681;e.rrehfinalarabic=64397;e.rrvocalicbengali=2528;e.rrvocalicdeva=2400;e.rrvocalicgujarati=2784;e.rrvocalicvowelsignbengali=2500;e.rrvocalicvowelsigndeva=2372;e.rrvocalicvowelsigngujarati=2756;e.rsuperior=63217;e.rtblock=9616;e.rturned=633;e.rturnedsuperior=692;e.ruhiragana=12427;e.rukatakana=12523;e.rukatakanahalfwidth=65433;e.rupeemarkbengali=2546;e.rupeesignbengali=2547;e.rupiah=63197;e.ruthai=3620;e.rvocalicbengali=2443;e.rvocalicdeva=2315;e.rvocalicgujarati=2699;e.rvocalicvowelsignbengali=2499;e.rvocalicvowelsigndeva=2371;e.rvocalicvowelsigngujarati=2755;e.s=115;e.sabengali=2488;e.sacute=347;e.sacutedotaccent=7781;e.sadarabic=1589;e.sadeva=2360;e.sadfinalarabic=65210;e.sadinitialarabic=65211;e.sadmedialarabic=65212;e.sagujarati=2744;e.sagurmukhi=2616;e.sahiragana=12373;e.sakatakana=12469;e.sakatakanahalfwidth=65403;e.sallallahoualayhewasallamarabic=65018;e.samekh=1505;e.samekhdagesh=64321;e.samekhdageshhebrew=64321;e.samekhhebrew=1505;e.saraaathai=3634;e.saraaethai=3649;e.saraaimaimalaithai=3652;e.saraaimaimuanthai=3651;e.saraamthai=3635;e.saraathai=3632;e.saraethai=3648;e.saraiileftthai=63622;e.saraiithai=3637;e.saraileftthai=63621;e.saraithai=3636;e.saraothai=3650;e.saraueeleftthai=63624;e.saraueethai=3639;e.saraueleftthai=63623;e.sarauethai=3638;e.sarauthai=3640;e.sarauuthai=3641;e.sbopomofo=12569;e.scaron=353;e.scarondotaccent=7783;e.scedilla=351;e.schwa=601;e.schwacyrillic=1241;e.schwadieresiscyrillic=1243;e.schwahook=602;e.scircle=9442;e.scircumflex=349;e.scommaaccent=537;e.sdotaccent=7777;e.sdotbelow=7779;e.sdotbelowdotaccent=7785;e.seagullbelowcmb=828;e.second=8243;e.secondtonechinese=714;e.section=167;e.seenarabic=1587;e.seenfinalarabic=65202;e.seeninitialarabic=65203;e.seenmedialarabic=65204;e.segol=1462;e.segol13=1462;e.segol1f=1462;e.segol2c=1462;e.segolhebrew=1462;e.segolnarrowhebrew=1462;e.segolquarterhebrew=1462;e.segoltahebrew=1426;e.segolwidehebrew=1462;e.seharmenian=1405;e.sehiragana=12379;e.sekatakana=12475;e.sekatakanahalfwidth=65406;e.semicolon=59;e.semicolonarabic=1563;e.semicolonmonospace=65307;e.semicolonsmall=65108;e.semivoicedmarkkana=12444;e.semivoicedmarkkanahalfwidth=65439;e.sentisquare=13090;e.sentosquare=13091;e.seven=55;e.sevenarabic=1639;e.sevenbengali=2541;e.sevencircle=9318;e.sevencircleinversesansserif=10128;e.sevendeva=2413;e.seveneighths=8542;e.sevengujarati=2797;e.sevengurmukhi=2669;e.sevenhackarabic=1639;e.sevenhangzhou=12327;e.sevenideographicparen=12838;e.seveninferior=8327;e.sevenmonospace=65303;e.sevenoldstyle=63287;e.sevenparen=9338;e.sevenperiod=9358;e.sevenpersian=1783;e.sevenroman=8566;e.sevensuperior=8311;e.seventeencircle=9328;e.seventeenparen=9348;e.seventeenperiod=9368;e.seventhai=3671;e.sfthyphen=173;e.shaarmenian=1399;e.shabengali=2486;e.shacyrillic=1096;e.shaddaarabic=1617;e.shaddadammaarabic=64609;e.shaddadammatanarabic=64606;e.shaddafathaarabic=64608;e.shaddakasraarabic=64610;e.shaddakasratanarabic=64607;e.shade=9618;e.shadedark=9619;e.shadelight=9617;e.shademedium=9618;e.shadeva=2358;e.shagujarati=2742;e.shagurmukhi=2614;e.shalshelethebrew=1427;e.shbopomofo=12565;e.shchacyrillic=1097;e.sheenarabic=1588;e.sheenfinalarabic=65206;e.sheeninitialarabic=65207;e.sheenmedialarabic=65208;e.sheicoptic=995;e.sheqel=8362;e.sheqelhebrew=8362;e.sheva=1456;e.sheva115=1456;e.sheva15=1456;e.sheva22=1456;e.sheva2e=1456;e.shevahebrew=1456;e.shevanarrowhebrew=1456;e.shevaquarterhebrew=1456;e.shevawidehebrew=1456;e.shhacyrillic=1211;e.shimacoptic=1005;e.shin=1513;e.shindagesh=64329;e.shindageshhebrew=64329;e.shindageshshindot=64300;e.shindageshshindothebrew=64300;e.shindageshsindot=64301;e.shindageshsindothebrew=64301;e.shindothebrew=1473;e.shinhebrew=1513;e.shinshindot=64298;e.shinshindothebrew=64298;e.shinsindot=64299;e.shinsindothebrew=64299;e.shook=642;e.sigma=963;e.sigma1=962;e.sigmafinal=962;e.sigmalunatesymbolgreek=1010;e.sihiragana=12375;e.sikatakana=12471;e.sikatakanahalfwidth=65404;e.siluqhebrew=1469;e.siluqlefthebrew=1469;e.similar=8764;e.sindothebrew=1474;e.siosacirclekorean=12916;e.siosaparenkorean=12820;e.sioscieuckorean=12670;e.sioscirclekorean=12902;e.sioskiyeokkorean=12666;e.sioskorean=12613;e.siosnieunkorean=12667;e.siosparenkorean=12806;e.siospieupkorean=12669;e.siostikeutkorean=12668;e.six=54;e.sixarabic=1638;e.sixbengali=2540;e.sixcircle=9317;e.sixcircleinversesansserif=10127;e.sixdeva=2412;e.sixgujarati=2796;e.sixgurmukhi=2668;e.sixhackarabic=1638;e.sixhangzhou=12326;e.sixideographicparen=12837;e.sixinferior=8326;e.sixmonospace=65302;e.sixoldstyle=63286;e.sixparen=9337;e.sixperiod=9357;e.sixpersian=1782;e.sixroman=8565;e.sixsuperior=8310;e.sixteencircle=9327;e.sixteencurrencydenominatorbengali=2553;e.sixteenparen=9347;e.sixteenperiod=9367;e.sixthai=3670;e.slash=47;e.slashmonospace=65295;e.slong=383;e.slongdotaccent=7835;e.smileface=9786;e.smonospace=65363;e.sofpasuqhebrew=1475;e.softhyphen=173;e.softsigncyrillic=1100;e.sohiragana=12381;e.sokatakana=12477;e.sokatakanahalfwidth=65407;e.soliduslongoverlaycmb=824;e.solidusshortoverlaycmb=823;e.sorusithai=3625;e.sosalathai=3624;e.sosothai=3595;e.sosuathai=3626;e.space=32;e.spacehackarabic=32;e.spade=9824;e.spadesuitblack=9824;e.spadesuitwhite=9828;e.sparen=9390;e.squarebelowcmb=827;e.squarecc=13252;e.squarecm=13213;e.squarediagonalcrosshatchfill=9641;e.squarehorizontalfill=9636;e.squarekg=13199;e.squarekm=13214;e.squarekmcapital=13262;e.squareln=13265;e.squarelog=13266;e.squaremg=13198;e.squaremil=13269;e.squaremm=13212;e.squaremsquared=13217;e.squareorthogonalcrosshatchfill=9638;e.squareupperlefttolowerrightfill=9639;e.squareupperrighttolowerleftfill=9640;e.squareverticalfill=9637;e.squarewhitewithsmallblack=9635;e.srsquare=13275;e.ssabengali=2487;e.ssadeva=2359;e.ssagujarati=2743;e.ssangcieuckorean=12617;e.ssanghieuhkorean=12677;e.ssangieungkorean=12672;e.ssangkiyeokkorean=12594;e.ssangnieunkorean=12645;e.ssangpieupkorean=12611;e.ssangsioskorean=12614;e.ssangtikeutkorean=12600;e.ssuperior=63218;e.sterling=163;e.sterlingmonospace=65505;e.strokelongoverlaycmb=822;e.strokeshortoverlaycmb=821;e.subset=8834;e.subsetnotequal=8842;e.subsetorequal=8838;e.succeeds=8827;e.suchthat=8715;e.suhiragana=12377;e.sukatakana=12473;e.sukatakanahalfwidth=65405;e.sukunarabic=1618;e.summation=8721;e.sun=9788;e.superset=8835;e.supersetnotequal=8843;e.supersetorequal=8839;e.svsquare=13276;e.syouwaerasquare=13180;e.t=116;e.tabengali=2468;e.tackdown=8868;e.tackleft=8867;e.tadeva=2340;e.tagujarati=2724;e.tagurmukhi=2596;e.taharabic=1591;e.tahfinalarabic=65218;e.tahinitialarabic=65219;e.tahiragana=12383;e.tahmedialarabic=65220;e.taisyouerasquare=13181;e.takatakana=12479;e.takatakanahalfwidth=65408;e.tatweelarabic=1600;e.tau=964;e.tav=1514;e.tavdages=64330;e.tavdagesh=64330;e.tavdageshhebrew=64330;e.tavhebrew=1514;e.tbar=359;e.tbopomofo=12554;e.tcaron=357;e.tccurl=680;e.tcedilla=355;e.tcheharabic=1670;e.tchehfinalarabic=64379;e.tchehinitialarabic=64380;e.tchehmedialarabic=64381;e.tcircle=9443;e.tcircumflexbelow=7793;e.tcommaaccent=355;e.tdieresis=7831;e.tdotaccent=7787;e.tdotbelow=7789;e.tecyrillic=1090;e.tedescendercyrillic=1197;e.teharabic=1578;e.tehfinalarabic=65174;e.tehhahinitialarabic=64674;e.tehhahisolatedarabic=64524;e.tehinitialarabic=65175;e.tehiragana=12390;e.tehjeeminitialarabic=64673;e.tehjeemisolatedarabic=64523;e.tehmarbutaarabic=1577;e.tehmarbutafinalarabic=65172;e.tehmedialarabic=65176;e.tehmeeminitialarabic=64676;e.tehmeemisolatedarabic=64526;e.tehnoonfinalarabic=64627;e.tekatakana=12486;e.tekatakanahalfwidth=65411;e.telephone=8481;e.telephoneblack=9742;e.telishagedolahebrew=1440;e.telishaqetanahebrew=1449;e.tencircle=9321;e.tenideographicparen=12841;e.tenparen=9341;e.tenperiod=9361;e.tenroman=8569;e.tesh=679;e.tet=1496;e.tetdagesh=64312;e.tetdageshhebrew=64312;e.tethebrew=1496;e.tetsecyrillic=1205;e.tevirhebrew=1435;e.tevirlefthebrew=1435;e.thabengali=2469;e.thadeva=2341;e.thagujarati=2725;e.thagurmukhi=2597;e.thalarabic=1584;e.thalfinalarabic=65196;e.thanthakhatlowleftthai=63640;e.thanthakhatlowrightthai=63639;e.thanthakhatthai=3660;e.thanthakhatupperleftthai=63638;e.theharabic=1579;e.thehfinalarabic=65178;e.thehinitialarabic=65179;e.thehmedialarabic=65180;e.thereexists=8707;e.therefore=8756;e.theta=952;e.theta1=977;e.thetasymbolgreek=977;e.thieuthacirclekorean=12921;e.thieuthaparenkorean=12825;e.thieuthcirclekorean=12907;e.thieuthkorean=12620;e.thieuthparenkorean=12811;e.thirteencircle=9324;e.thirteenparen=9344;e.thirteenperiod=9364;e.thonangmonthothai=3601;e.thook=429;e.thophuthaothai=3602;e.thorn=254;e.thothahanthai=3607;e.thothanthai=3600;e.thothongthai=3608;e.thothungthai=3606;e.thousandcyrillic=1154;e.thousandsseparatorarabic=1644;e.thousandsseparatorpersian=1644;e.three=51;e.threearabic=1635;e.threebengali=2537;e.threecircle=9314;e.threecircleinversesansserif=10124;e.threedeva=2409;e.threeeighths=8540;e.threegujarati=2793;e.threegurmukhi=2665;e.threehackarabic=1635;e.threehangzhou=12323;e.threeideographicparen=12834;e.threeinferior=8323;e.threemonospace=65299;e.threenumeratorbengali=2550;e.threeoldstyle=63283;e.threeparen=9334;e.threeperiod=9354;e.threepersian=1779;e.threequarters=190;e.threequartersemdash=63198;e.threeroman=8562;e.threesuperior=179;e.threethai=3667;e.thzsquare=13204;e.tihiragana=12385;e.tikatakana=12481;e.tikatakanahalfwidth=65409;e.tikeutacirclekorean=12912;e.tikeutaparenkorean=12816;e.tikeutcirclekorean=12898;e.tikeutkorean=12599;e.tikeutparenkorean=12802;e.tilde=732;e.tildebelowcmb=816;e.tildecmb=771;e.tildecomb=771;e.tildedoublecmb=864;e.tildeoperator=8764;e.tildeoverlaycmb=820;e.tildeverticalcmb=830;e.timescircle=8855;e.tipehahebrew=1430;e.tipehalefthebrew=1430;e.tippigurmukhi=2672;e.titlocyrilliccmb=1155;e.tiwnarmenian=1407;e.tlinebelow=7791;e.tmonospace=65364;e.toarmenian=1385;e.tohiragana=12392;e.tokatakana=12488;e.tokatakanahalfwidth=65412;e.tonebarextrahighmod=741;e.tonebarextralowmod=745;e.tonebarhighmod=742;e.tonebarlowmod=744;e.tonebarmidmod=743;e.tonefive=445;e.tonesix=389;e.tonetwo=424;e.tonos=900;e.tonsquare=13095;e.topatakthai=3599;e.tortoiseshellbracketleft=12308;e.tortoiseshellbracketleftsmall=65117;e.tortoiseshellbracketleftvertical=65081;e.tortoiseshellbracketright=12309;e.tortoiseshellbracketrightsmall=65118;e.tortoiseshellbracketrightvertical=65082;e.totaothai=3605;e.tpalatalhook=427;e.tparen=9391;e.trademark=8482;e.trademarksans=63722;e.trademarkserif=63195;e.tretroflexhook=648;e.triagdn=9660;e.triaglf=9668;e.triagrt=9658;e.triagup=9650;e.ts=678;e.tsadi=1510;e.tsadidagesh=64326;e.tsadidageshhebrew=64326;e.tsadihebrew=1510;e.tsecyrillic=1094;e.tsere=1461;e.tsere12=1461;e.tsere1e=1461;e.tsere2b=1461;e.tserehebrew=1461;e.tserenarrowhebrew=1461;e.tserequarterhebrew=1461;e.tserewidehebrew=1461;e.tshecyrillic=1115;e.tsuperior=63219;e.ttabengali=2463;e.ttadeva=2335;e.ttagujarati=2719;e.ttagurmukhi=2591;e.tteharabic=1657;e.ttehfinalarabic=64359;e.ttehinitialarabic=64360;e.ttehmedialarabic=64361;e.tthabengali=2464;e.tthadeva=2336;e.tthagujarati=2720;e.tthagurmukhi=2592;e.tturned=647;e.tuhiragana=12388;e.tukatakana=12484;e.tukatakanahalfwidth=65410;e.tusmallhiragana=12387;e.tusmallkatakana=12483;e.tusmallkatakanahalfwidth=65391;e.twelvecircle=9323;e.twelveparen=9343;e.twelveperiod=9363;e.twelveroman=8571;e.twentycircle=9331;e.twentyhangzhou=21316;e.twentyparen=9351;e.twentyperiod=9371;e.two=50;e.twoarabic=1634;e.twobengali=2536;e.twocircle=9313;e.twocircleinversesansserif=10123;e.twodeva=2408;e.twodotenleader=8229;e.twodotleader=8229;e.twodotleadervertical=65072;e.twogujarati=2792;e.twogurmukhi=2664;e.twohackarabic=1634;e.twohangzhou=12322;e.twoideographicparen=12833;e.twoinferior=8322;e.twomonospace=65298;e.twonumeratorbengali=2549;e.twooldstyle=63282;e.twoparen=9333;e.twoperiod=9353;e.twopersian=1778;e.tworoman=8561;e.twostroke=443;e.twosuperior=178;e.twothai=3666;e.twothirds=8532;e.u=117;e.uacute=250;e.ubar=649;e.ubengali=2441;e.ubopomofo=12584;e.ubreve=365;e.ucaron=468;e.ucircle=9444;e.ucircumflex=251;e.ucircumflexbelow=7799;e.ucyrillic=1091;e.udattadeva=2385;e.udblacute=369;e.udblgrave=533;e.udeva=2313;e.udieresis=252;e.udieresisacute=472;e.udieresisbelow=7795;e.udieresiscaron=474;e.udieresiscyrillic=1265;e.udieresisgrave=476;e.udieresismacron=470;e.udotbelow=7909;e.ugrave=249;e.ugujarati=2697;e.ugurmukhi=2569;e.uhiragana=12358;e.uhookabove=7911;e.uhorn=432;e.uhornacute=7913;e.uhorndotbelow=7921;e.uhorngrave=7915;e.uhornhookabove=7917;e.uhorntilde=7919;e.uhungarumlaut=369;e.uhungarumlautcyrillic=1267;e.uinvertedbreve=535;e.ukatakana=12454;e.ukatakanahalfwidth=65395;e.ukcyrillic=1145;e.ukorean=12636;e.umacron=363;e.umacroncyrillic=1263;e.umacrondieresis=7803;e.umatragurmukhi=2625;e.umonospace=65365;e.underscore=95;e.underscoredbl=8215;e.underscoremonospace=65343;e.underscorevertical=65075;e.underscorewavy=65103;e.union=8746;e.universal=8704;e.uogonek=371;e.uparen=9392;e.upblock=9600;e.upperdothebrew=1476;e.upsilon=965;e.upsilondieresis=971;e.upsilondieresistonos=944;e.upsilonlatin=650;e.upsilontonos=973;e.uptackbelowcmb=797;e.uptackmod=724;e.uragurmukhi=2675;e.uring=367;e.ushortcyrillic=1118;e.usmallhiragana=12357;e.usmallkatakana=12453;e.usmallkatakanahalfwidth=65385;e.ustraightcyrillic=1199;e.ustraightstrokecyrillic=1201;e.utilde=361;e.utildeacute=7801;e.utildebelow=7797;e.uubengali=2442;e.uudeva=2314;e.uugujarati=2698;e.uugurmukhi=2570;e.uumatragurmukhi=2626;e.uuvowelsignbengali=2498;e.uuvowelsigndeva=2370;e.uuvowelsigngujarati=2754;e.uvowelsignbengali=2497;e.uvowelsigndeva=2369;e.uvowelsigngujarati=2753;e.v=118;e.vadeva=2357;e.vagujarati=2741;e.vagurmukhi=2613;e.vakatakana=12535;e.vav=1493;e.vavdagesh=64309;e.vavdagesh65=64309;e.vavdageshhebrew=64309;e.vavhebrew=1493;e.vavholam=64331;e.vavholamhebrew=64331;e.vavvavhebrew=1520;e.vavyodhebrew=1521;e.vcircle=9445;e.vdotbelow=7807;e.vecyrillic=1074;e.veharabic=1700;e.vehfinalarabic=64363;e.vehinitialarabic=64364;e.vehmedialarabic=64365;e.vekatakana=12537;e.venus=9792;e.verticalbar=124;e.verticallineabovecmb=781;e.verticallinebelowcmb=809;e.verticallinelowmod=716;e.verticallinemod=712;e.vewarmenian=1406;e.vhook=651;e.vikatakana=12536;e.viramabengali=2509;e.viramadeva=2381;e.viramagujarati=2765;e.visargabengali=2435;e.visargadeva=2307;e.visargagujarati=2691;e.vmonospace=65366;e.voarmenian=1400;e.voicediterationhiragana=12446;e.voicediterationkatakana=12542;e.voicedmarkkana=12443;e.voicedmarkkanahalfwidth=65438;e.vokatakana=12538;e.vparen=9393;e.vtilde=7805;e.vturned=652;e.vuhiragana=12436;e.vukatakana=12532;e.w=119;e.wacute=7811;e.waekorean=12633;e.wahiragana=12431;e.wakatakana=12527;e.wakatakanahalfwidth=65436;e.wakorean=12632;e.wasmallhiragana=12430;e.wasmallkatakana=12526;e.wattosquare=13143;e.wavedash=12316;e.wavyunderscorevertical=65076;e.wawarabic=1608;e.wawfinalarabic=65262;e.wawhamzaabovearabic=1572;e.wawhamzaabovefinalarabic=65158;e.wbsquare=13277;e.wcircle=9446;e.wcircumflex=373;e.wdieresis=7813;e.wdotaccent=7815;e.wdotbelow=7817;e.wehiragana=12433;e.weierstrass=8472;e.wekatakana=12529;e.wekorean=12638;e.weokorean=12637;e.wgrave=7809;e.whitebullet=9702;e.whitecircle=9675;e.whitecircleinverse=9689;e.whitecornerbracketleft=12302;e.whitecornerbracketleftvertical=65091;e.whitecornerbracketright=12303;e.whitecornerbracketrightvertical=65092;e.whitediamond=9671;e.whitediamondcontainingblacksmalldiamond=9672;e.whitedownpointingsmalltriangle=9663;e.whitedownpointingtriangle=9661;e.whiteleftpointingsmalltriangle=9667;e.whiteleftpointingtriangle=9665;e.whitelenticularbracketleft=12310;e.whitelenticularbracketright=12311;e.whiterightpointingsmalltriangle=9657;e.whiterightpointingtriangle=9655;e.whitesmallsquare=9643;e.whitesmilingface=9786;e.whitesquare=9633;e.whitestar=9734;e.whitetelephone=9743;e.whitetortoiseshellbracketleft=12312;e.whitetortoiseshellbracketright=12313;e.whiteuppointingsmalltriangle=9653;e.whiteuppointingtriangle=9651;e.wihiragana=12432;e.wikatakana=12528;e.wikorean=12639;e.wmonospace=65367;e.wohiragana=12434;e.wokatakana=12530;e.wokatakanahalfwidth=65382;e.won=8361;e.wonmonospace=65510;e.wowaenthai=3623;e.wparen=9394;e.wring=7832;e.wsuperior=695;e.wturned=653;e.wynn=447;e.x=120;e.xabovecmb=829;e.xbopomofo=12562;e.xcircle=9447;e.xdieresis=7821;e.xdotaccent=7819;e.xeharmenian=1389;e.xi=958;e.xmonospace=65368;e.xparen=9395;e.xsuperior=739;e.y=121;e.yaadosquare=13134;e.yabengali=2479;e.yacute=253;e.yadeva=2351;e.yaekorean=12626;e.yagujarati=2735;e.yagurmukhi=2607;e.yahiragana=12420;e.yakatakana=12516;e.yakatakanahalfwidth=65428;e.yakorean=12625;e.yamakkanthai=3662;e.yasmallhiragana=12419;e.yasmallkatakana=12515;e.yasmallkatakanahalfwidth=65388;e.yatcyrillic=1123;e.ycircle=9448;e.ycircumflex=375;e.ydieresis=255;e.ydotaccent=7823;e.ydotbelow=7925;e.yeharabic=1610;e.yehbarreearabic=1746;e.yehbarreefinalarabic=64431;e.yehfinalarabic=65266;e.yehhamzaabovearabic=1574;e.yehhamzaabovefinalarabic=65162;e.yehhamzaaboveinitialarabic=65163;e.yehhamzaabovemedialarabic=65164;e.yehinitialarabic=65267;e.yehmedialarabic=65268;e.yehmeeminitialarabic=64733;e.yehmeemisolatedarabic=64600;e.yehnoonfinalarabic=64660;e.yehthreedotsbelowarabic=1745;e.yekorean=12630;e.yen=165;e.yenmonospace=65509;e.yeokorean=12629;e.yeorinhieuhkorean=12678;e.yerahbenyomohebrew=1450;e.yerahbenyomolefthebrew=1450;e.yericyrillic=1099;e.yerudieresiscyrillic=1273;e.yesieungkorean=12673;e.yesieungpansioskorean=12675;e.yesieungsioskorean=12674;e.yetivhebrew=1434;e.ygrave=7923;e.yhook=436;e.yhookabove=7927;e.yiarmenian=1397;e.yicyrillic=1111;e.yikorean=12642;e.yinyang=9775;e.yiwnarmenian=1410;e.ymonospace=65369;e.yod=1497;e.yoddagesh=64313;e.yoddageshhebrew=64313;e.yodhebrew=1497;e.yodyodhebrew=1522;e.yodyodpatahhebrew=64287;e.yohiragana=12424;e.yoikorean=12681;e.yokatakana=12520;e.yokatakanahalfwidth=65430;e.yokorean=12635;e.yosmallhiragana=12423;e.yosmallkatakana=12519;e.yosmallkatakanahalfwidth=65390;e.yotgreek=1011;e.yoyaekorean=12680;e.yoyakorean=12679;e.yoyakthai=3618;e.yoyingthai=3597;e.yparen=9396;e.ypogegrammeni=890;e.ypogegrammenigreekcmb=837;e.yr=422;e.yring=7833;e.ysuperior=696;e.ytilde=7929;e.yturned=654;e.yuhiragana=12422;e.yuikorean=12684;e.yukatakana=12518;e.yukatakanahalfwidth=65429;e.yukorean=12640;e.yusbigcyrillic=1131;e.yusbigiotifiedcyrillic=1133;e.yuslittlecyrillic=1127;e.yuslittleiotifiedcyrillic=1129;e.yusmallhiragana=12421;e.yusmallkatakana=12517;e.yusmallkatakanahalfwidth=65389;e.yuyekorean=12683;e.yuyeokorean=12682;e.yyabengali=2527;e.yyadeva=2399;e.z=122;e.zaarmenian=1382;e.zacute=378;e.zadeva=2395;e.zagurmukhi=2651;e.zaharabic=1592;e.zahfinalarabic=65222;e.zahinitialarabic=65223;e.zahiragana=12374;e.zahmedialarabic=65224;e.zainarabic=1586;e.zainfinalarabic=65200;e.zakatakana=12470;e.zaqefgadolhebrew=1429;e.zaqefqatanhebrew=1428;e.zarqahebrew=1432;e.zayin=1494;e.zayindagesh=64310;e.zayindageshhebrew=64310;e.zayinhebrew=1494;e.zbopomofo=12567;e.zcaron=382;e.zcircle=9449;e.zcircumflex=7825;e.zcurl=657;e.zdot=380;e.zdotaccent=380;e.zdotbelow=7827;e.zecyrillic=1079;e.zedescendercyrillic=1177;e.zedieresiscyrillic=1247;e.zehiragana=12380;e.zekatakana=12476;e.zero=48;e.zeroarabic=1632;e.zerobengali=2534;e.zerodeva=2406;e.zerogujarati=2790;e.zerogurmukhi=2662;e.zerohackarabic=1632;e.zeroinferior=8320;e.zeromonospace=65296;e.zerooldstyle=63280;e.zeropersian=1776;e.zerosuperior=8304;e.zerothai=3664;e.zerowidthjoiner=65279;e.zerowidthnonjoiner=8204;e.zerowidthspace=8203;e.zeta=950;e.zhbopomofo=12563;e.zhearmenian=1386;e.zhebrevecyrillic=1218;e.zhecyrillic=1078;e.zhedescendercyrillic=1175;e.zhedieresiscyrillic=1245;e.zihiragana=12376;e.zikatakana=12472;e.zinorhebrew=1454;e.zlinebelow=7829;e.zmonospace=65370;e.zohiragana=12382;e.zokatakana=12478;e.zparen=9397;e.zretroflexhook=656;e.zstroke=438;e.zuhiragana=12378;e.zukatakana=12474;e[".notdef"]=0;e.angbracketleftbig=9001;e.angbracketleftBig=9001;e.angbracketleftbigg=9001;e.angbracketleftBigg=9001;e.angbracketrightBig=9002;e.angbracketrightbig=9002;e.angbracketrightBigg=9002;e.angbracketrightbigg=9002;e.arrowhookleft=8618;e.arrowhookright=8617;e.arrowlefttophalf=8636;e.arrowleftbothalf=8637;e.arrownortheast=8599;e.arrownorthwest=8598;e.arrowrighttophalf=8640;e.arrowrightbothalf=8641;e.arrowsoutheast=8600;e.arrowsouthwest=8601;e.backslashbig=8726;e.backslashBig=8726;e.backslashBigg=8726;e.backslashbigg=8726;e.bardbl=8214;e.bracehtipdownleft=65079;e.bracehtipdownright=65079;e.bracehtipupleft=65080;e.bracehtipupright=65080;e.braceleftBig=123;e.braceleftbig=123;e.braceleftbigg=123;e.braceleftBigg=123;e.bracerightBig=125;e.bracerightbig=125;e.bracerightbigg=125;e.bracerightBigg=125;e.bracketleftbig=91;e.bracketleftBig=91;e.bracketleftbigg=91;e.bracketleftBigg=91;e.bracketrightBig=93;e.bracketrightbig=93;e.bracketrightbigg=93;e.bracketrightBigg=93;e.ceilingleftbig=8968;e.ceilingleftBig=8968;e.ceilingleftBigg=8968;e.ceilingleftbigg=8968;e.ceilingrightbig=8969;e.ceilingrightBig=8969;e.ceilingrightbigg=8969;e.ceilingrightBigg=8969;e.circledotdisplay=8857;e.circledottext=8857;e.circlemultiplydisplay=8855;e.circlemultiplytext=8855;e.circleplusdisplay=8853;e.circleplustext=8853;e.contintegraldisplay=8750;e.contintegraltext=8750;e.coproductdisplay=8720;e.coproducttext=8720;e.floorleftBig=8970;e.floorleftbig=8970;e.floorleftbigg=8970;e.floorleftBigg=8970;e.floorrightbig=8971;e.floorrightBig=8971;e.floorrightBigg=8971;e.floorrightbigg=8971;e.hatwide=770;e.hatwider=770;e.hatwidest=770;e.intercal=7488;e.integraldisplay=8747;e.integraltext=8747;e.intersectiondisplay=8898;e.intersectiontext=8898;e.logicalanddisplay=8743;e.logicalandtext=8743;e.logicalordisplay=8744;e.logicalortext=8744;e.parenleftBig=40;e.parenleftbig=40;e.parenleftBigg=40;e.parenleftbigg=40;e.parenrightBig=41;e.parenrightbig=41;e.parenrightBigg=41;e.parenrightbigg=41;e.prime=8242;e.productdisplay=8719;e.producttext=8719;e.radicalbig=8730;e.radicalBig=8730;e.radicalBigg=8730;e.radicalbigg=8730;e.radicalbt=8730;e.radicaltp=8730;e.radicalvertex=8730;e.slashbig=47;e.slashBig=47;e.slashBigg=47;e.slashbigg=47;e.summationdisplay=8721;e.summationtext=8721;e.tildewide=732;e.tildewider=732;e.tildewidest=732;e.uniondisplay=8899;e.unionmultidisplay=8846;e.unionmultitext=8846;e.unionsqdisplay=8852;e.unionsqtext=8852;e.uniontext=8899;e.vextenddouble=8741;e.vextendsingle=8739})),Gi=getLookupTableFactory((function(e){e.space=32;e.a1=9985;e.a2=9986;e.a202=9987;e.a3=9988;e.a4=9742;e.a5=9990;e.a119=9991;e.a118=9992;e.a117=9993;e.a11=9755;e.a12=9758;e.a13=9996;e.a14=9997;e.a15=9998;e.a16=9999;e.a105=1e4;e.a17=10001;e.a18=10002;e.a19=10003;e.a20=10004;e.a21=10005;e.a22=10006;e.a23=10007;e.a24=10008;e.a25=10009;e.a26=10010;e.a27=10011;e.a28=10012;e.a6=10013;e.a7=10014;e.a8=10015;e.a9=10016;e.a10=10017;e.a29=10018;e.a30=10019;e.a31=10020;e.a32=10021;e.a33=10022;e.a34=10023;e.a35=9733;e.a36=10025;e.a37=10026;e.a38=10027;e.a39=10028;e.a40=10029;e.a41=10030;e.a42=10031;e.a43=10032;e.a44=10033;e.a45=10034;e.a46=10035;e.a47=10036;e.a48=10037;e.a49=10038;e.a50=10039;e.a51=10040;e.a52=10041;e.a53=10042;e.a54=10043;e.a55=10044;e.a56=10045;e.a57=10046;e.a58=10047;e.a59=10048;e.a60=10049;e.a61=10050;e.a62=10051;e.a63=10052;e.a64=10053;e.a65=10054;e.a66=10055;e.a67=10056;e.a68=10057;e.a69=10058;e.a70=10059;e.a71=9679;e.a72=10061;e.a73=9632;e.a74=10063;e.a203=10064;e.a75=10065;e.a204=10066;e.a76=9650;e.a77=9660;e.a78=9670;e.a79=10070;e.a81=9687;e.a82=10072;e.a83=10073;e.a84=10074;e.a97=10075;e.a98=10076;e.a99=10077;e.a100=10078;e.a101=10081;e.a102=10082;e.a103=10083;e.a104=10084;e.a106=10085;e.a107=10086;e.a108=10087;e.a112=9827;e.a111=9830;e.a110=9829;e.a109=9824;e.a120=9312;e.a121=9313;e.a122=9314;e.a123=9315;e.a124=9316;e.a125=9317;e.a126=9318;e.a127=9319;e.a128=9320;e.a129=9321;e.a130=10102;e.a131=10103;e.a132=10104;e.a133=10105;e.a134=10106;e.a135=10107;e.a136=10108;e.a137=10109;e.a138=10110;e.a139=10111;e.a140=10112;e.a141=10113;e.a142=10114;e.a143=10115;e.a144=10116;e.a145=10117;e.a146=10118;e.a147=10119;e.a148=10120;e.a149=10121;e.a150=10122;e.a151=10123;e.a152=10124;e.a153=10125;e.a154=10126;e.a155=10127;e.a156=10128;e.a157=10129;e.a158=10130;e.a159=10131;e.a160=10132;e.a161=8594;e.a163=8596;e.a164=8597;e.a196=10136;e.a165=10137;e.a192=10138;e.a166=10139;e.a167=10140;e.a168=10141;e.a169=10142;e.a170=10143;e.a171=10144;e.a172=10145;e.a173=10146;e.a162=10147;e.a174=10148;e.a175=10149;e.a176=10150;e.a177=10151;e.a178=10152;e.a179=10153;e.a193=10154;e.a180=10155;e.a199=10156;e.a181=10157;e.a200=10158;e.a182=10159;e.a201=10161;e.a183=10162;e.a184=10163;e.a197=10164;e.a185=10165;e.a194=10166;e.a198=10167;e.a186=10168;e.a195=10169;e.a187=10170;e.a188=10171;e.a189=10172;e.a190=10173;e.a191=10174;e.a89=10088;e.a90=10089;e.a93=10090;e.a94=10091;e.a91=10092;e.a92=10093;e.a205=10094;e.a85=10095;e.a206=10096;e.a86=10097;e.a87=10098;e.a88=10099;e.a95=10100;e.a96=10101;e[".notdef"]=0})),xi=getLookupTableFactory((function(e){e[63721]=169;e[63193]=169;e[63720]=174;e[63194]=174;e[63722]=8482;e[63195]=8482;e[63729]=9127;e[63730]=9128;e[63731]=9129;e[63740]=9131;e[63741]=9132;e[63742]=9133;e[63726]=9121;e[63727]=9122;e[63728]=9123;e[63737]=9124;e[63738]=9125;e[63739]=9126;e[63723]=9115;e[63724]=9116;e[63725]=9117;e[63734]=9118;e[63735]=9119;e[63736]=9120}));function getUnicodeForGlyph(e,t){let i=t[e];if(void 0!==i)return i;if(!e)return-1;if("u"===e[0]){const t=e.length;let a;if(7===t&&"n"===e[1]&&"i"===e[2])a=e.substring(3);else{if(!(t>=5&&t<=7))return-1;a=e.substring(1)}if(a===a.toUpperCase()){i=parseInt(a,16);if(i>=0)return i}}return-1}const Mi=[[0,127],[128,255],[256,383],[384,591],[592,687,7424,7551,7552,7615],[688,767,42752,42783],[768,879,7616,7679],[880,1023],[11392,11519],[1024,1279,1280,1327,11744,11775,42560,42655],[1328,1423],[1424,1535],[42240,42559],[1536,1791,1872,1919],[1984,2047],[2304,2431],[2432,2559],[2560,2687],[2688,2815],[2816,2943],[2944,3071],[3072,3199],[3200,3327],[3328,3455],[3584,3711],[3712,3839],[4256,4351,11520,11567],[6912,7039],[4352,4607],[7680,7935,11360,11391,42784,43007],[7936,8191],[8192,8303,11776,11903],[8304,8351],[8352,8399],[8400,8447],[8448,8527],[8528,8591],[8592,8703,10224,10239,10496,10623,11008,11263],[8704,8959,10752,11007,10176,10223,10624,10751],[8960,9215],[9216,9279],[9280,9311],[9312,9471],[9472,9599],[9600,9631],[9632,9727],[9728,9983],[9984,10175],[12288,12351],[12352,12447],[12448,12543,12784,12799],[12544,12591,12704,12735],[12592,12687],[43072,43135],[12800,13055],[13056,13311],[44032,55215],[55296,57343],[67840,67871],[19968,40959,11904,12031,12032,12255,12272,12287,13312,19903,131072,173791,12688,12703],[57344,63743],[12736,12783,63744,64255,194560,195103],[64256,64335],[64336,65023],[65056,65071],[65040,65055],[65104,65135],[65136,65279],[65280,65519],[65520,65535],[3840,4095],[1792,1871],[1920,1983],[3456,3583],[4096,4255],[4608,4991,4992,5023,11648,11743],[5024,5119],[5120,5759],[5760,5791],[5792,5887],[6016,6143],[6144,6319],[10240,10495],[40960,42127],[5888,5919,5920,5951,5952,5983,5984,6015],[66304,66351],[66352,66383],[66560,66639],[118784,119039,119040,119295,119296,119375],[119808,120831],[1044480,1048573],[65024,65039,917760,917999],[917504,917631],[6400,6479],[6480,6527],[6528,6623],[6656,6687],[11264,11359],[11568,11647],[19904,19967],[43008,43055],[65536,65663,65664,65791,65792,65855],[65856,65935],[66432,66463],[66464,66527],[66640,66687],[66688,66735],[67584,67647],[68096,68191],[119552,119647],[73728,74751,74752,74879],[119648,119679],[7040,7103],[7168,7247],[7248,7295],[43136,43231],[43264,43311],[43312,43359],[43520,43615],[65936,65999],[66e3,66047],[66208,66271,66176,66207,67872,67903],[127024,127135,126976,127023]];function getUnicodeRangeFor(e,t=-1){if(-1!==t){const i=Mi[t];for(let a=0,s=i.length;a<s;a+=2)if(e>=i[a]&&e<=i[a+1])return t}for(let t=0,i=Mi.length;t<i;t++){const i=Mi[t];for(let a=0,s=i.length;a<s;a+=2)if(e>=i[a]&&e<=i[a+1])return t}return-1}const Ji=new RegExp("^(\\s)|(\\p{Mn})|(\\p{Cf})$","u"),Hi=new Map;const Yi=!0,vi=1,Ki=2,Ti=4,qi=32,Oi=[".notdef",".null","nonmarkingreturn","space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quotesingle","parenleft","parenright","asterisk","plus","comma","hyphen","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","at","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft","backslash","bracketright","asciicircum","underscore","grave","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde","Adieresis","Aring","Ccedilla","Eacute","Ntilde","Odieresis","Udieresis","aacute","agrave","acircumflex","adieresis","atilde","aring","ccedilla","eacute","egrave","ecircumflex","edieresis","iacute","igrave","icircumflex","idieresis","ntilde","oacute","ograve","ocircumflex","odieresis","otilde","uacute","ugrave","ucircumflex","udieresis","dagger","degree","cent","sterling","section","bullet","paragraph","germandbls","registered","copyright","trademark","acute","dieresis","notequal","AE","Oslash","infinity","plusminus","lessequal","greaterequal","yen","mu","partialdiff","summation","product","pi","integral","ordfeminine","ordmasculine","Omega","ae","oslash","questiondown","exclamdown","logicalnot","radical","florin","approxequal","Delta","guillemotleft","guillemotright","ellipsis","nonbreakingspace","Agrave","Atilde","Otilde","OE","oe","endash","emdash","quotedblleft","quotedblright","quoteleft","quoteright","divide","lozenge","ydieresis","Ydieresis","fraction","currency","guilsinglleft","guilsinglright","fi","fl","daggerdbl","periodcentered","quotesinglbase","quotedblbase","perthousand","Acircumflex","Ecircumflex","Aacute","Edieresis","Egrave","Iacute","Icircumflex","Idieresis","Igrave","Oacute","Ocircumflex","apple","Ograve","Uacute","Ucircumflex","Ugrave","dotlessi","circumflex","tilde","macron","breve","dotaccent","ring","cedilla","hungarumlaut","ogonek","caron","Lslash","lslash","Scaron","scaron","Zcaron","zcaron","brokenbar","Eth","eth","Yacute","yacute","Thorn","thorn","minus","multiply","onesuperior","twosuperior","threesuperior","onehalf","onequarter","threequarters","franc","Gbreve","gbreve","Idotaccent","Scedilla","scedilla","Cacute","cacute","Ccaron","ccaron","dcroat"];function recoverGlyphName(e,t){if(void 0!==t[e])return e;const i=getUnicodeForGlyph(e,t);if(-1!==i)for(const e in t)if(t[e]===i)return e;info("Unable to recover a standard glyph name for: "+e);return e}function type1FontGlyphMapping(e,t,i){const a=Object.create(null);let s,r,n;const o=!!(e.flags&Ti);if(e.isInternalFont){n=t;for(r=0;r<n.length;r++){s=i.indexOf(n[r]);a[r]=s>=0?s:0}}else if(e.baseEncodingName){n=getEncoding(e.baseEncodingName);for(r=0;r<n.length;r++){s=i.indexOf(n[r]);a[r]=s>=0?s:0}}else if(o)for(r in t)a[r]=t[r];else{n=fi;for(r=0;r<n.length;r++){s=i.indexOf(n[r]);a[r]=s>=0?s:0}}const g=e.differences;let c;if(g)for(r in g){const e=g[r];s=i.indexOf(e);if(-1===s){c||(c=Ni());const t=recoverGlyphName(e,c);t!==e&&(s=i.indexOf(t))}a[r]=s>=0?s:0}return a}function normalizeFontName(e){return e.replaceAll(/[,_]/g,"-").replaceAll(/\s/g,"")}const Pi=getLookupTableFactory((function(e){e["Times-Roman"]="Times-Roman";e.Helvetica="Helvetica";e.Courier="Courier";e.Symbol="Symbol";e["Times-Bold"]="Times-Bold";e["Helvetica-Bold"]="Helvetica-Bold";e["Courier-Bold"]="Courier-Bold";e.ZapfDingbats="ZapfDingbats";e["Times-Italic"]="Times-Italic";e["Helvetica-Oblique"]="Helvetica-Oblique";e["Courier-Oblique"]="Courier-Oblique";e["Times-BoldItalic"]="Times-BoldItalic";e["Helvetica-BoldOblique"]="Helvetica-BoldOblique";e["Courier-BoldOblique"]="Courier-BoldOblique";e.ArialNarrow="Helvetica";e["ArialNarrow-Bold"]="Helvetica-Bold";e["ArialNarrow-BoldItalic"]="Helvetica-BoldOblique";e["ArialNarrow-Italic"]="Helvetica-Oblique";e.ArialBlack="Helvetica";e["ArialBlack-Bold"]="Helvetica-Bold";e["ArialBlack-BoldItalic"]="Helvetica-BoldOblique";e["ArialBlack-Italic"]="Helvetica-Oblique";e["Arial-Black"]="Helvetica";e["Arial-Black-Bold"]="Helvetica-Bold";e["Arial-Black-BoldItalic"]="Helvetica-BoldOblique";e["Arial-Black-Italic"]="Helvetica-Oblique";e.Arial="Helvetica";e["Arial-Bold"]="Helvetica-Bold";e["Arial-BoldItalic"]="Helvetica-BoldOblique";e["Arial-Italic"]="Helvetica-Oblique";e.ArialMT="Helvetica";e["Arial-BoldItalicMT"]="Helvetica-BoldOblique";e["Arial-BoldMT"]="Helvetica-Bold";e["Arial-ItalicMT"]="Helvetica-Oblique";e["Arial-BoldItalicMT-BoldItalic"]="Helvetica-BoldOblique";e["Arial-BoldMT-Bold"]="Helvetica-Bold";e["Arial-ItalicMT-Italic"]="Helvetica-Oblique";e.ArialUnicodeMS="Helvetica";e["ArialUnicodeMS-Bold"]="Helvetica-Bold";e["ArialUnicodeMS-BoldItalic"]="Helvetica-BoldOblique";e["ArialUnicodeMS-Italic"]="Helvetica-Oblique";e["Courier-BoldItalic"]="Courier-BoldOblique";e["Courier-Italic"]="Courier-Oblique";e.CourierNew="Courier";e["CourierNew-Bold"]="Courier-Bold";e["CourierNew-BoldItalic"]="Courier-BoldOblique";e["CourierNew-Italic"]="Courier-Oblique";e["CourierNewPS-BoldItalicMT"]="Courier-BoldOblique";e["CourierNewPS-BoldMT"]="Courier-Bold";e["CourierNewPS-ItalicMT"]="Courier-Oblique";e.CourierNewPSMT="Courier";e["Helvetica-BoldItalic"]="Helvetica-BoldOblique";e["Helvetica-Italic"]="Helvetica-Oblique";e["Symbol-Bold"]="Symbol";e["Symbol-BoldItalic"]="Symbol";e["Symbol-Italic"]="Symbol";e.TimesNewRoman="Times-Roman";e["TimesNewRoman-Bold"]="Times-Bold";e["TimesNewRoman-BoldItalic"]="Times-BoldItalic";e["TimesNewRoman-Italic"]="Times-Italic";e.TimesNewRomanPS="Times-Roman";e["TimesNewRomanPS-Bold"]="Times-Bold";e["TimesNewRomanPS-BoldItalic"]="Times-BoldItalic";e["TimesNewRomanPS-BoldItalicMT"]="Times-BoldItalic";e["TimesNewRomanPS-BoldMT"]="Times-Bold";e["TimesNewRomanPS-Italic"]="Times-Italic";e["TimesNewRomanPS-ItalicMT"]="Times-Italic";e.TimesNewRomanPSMT="Times-Roman";e["TimesNewRomanPSMT-Bold"]="Times-Bold";e["TimesNewRomanPSMT-BoldItalic"]="Times-BoldItalic";e["TimesNewRomanPSMT-Italic"]="Times-Italic"})),Wi=getLookupTableFactory((function(e){e.Courier="FoxitFixed.pfb";e["Courier-Bold"]="FoxitFixedBold.pfb";e["Courier-BoldOblique"]="FoxitFixedBoldItalic.pfb";e["Courier-Oblique"]="FoxitFixedItalic.pfb";e.Helvetica="LiberationSans-Regular.ttf";e["Helvetica-Bold"]="LiberationSans-Bold.ttf";e["Helvetica-BoldOblique"]="LiberationSans-BoldItalic.ttf";e["Helvetica-Oblique"]="LiberationSans-Italic.ttf";e["Times-Roman"]="FoxitSerif.pfb";e["Times-Bold"]="FoxitSerifBold.pfb";e["Times-BoldItalic"]="FoxitSerifBoldItalic.pfb";e["Times-Italic"]="FoxitSerifItalic.pfb";e.Symbol="FoxitSymbol.pfb";e.ZapfDingbats="FoxitDingbats.pfb";e["LiberationSans-Regular"]="LiberationSans-Regular.ttf";e["LiberationSans-Bold"]="LiberationSans-Bold.ttf";e["LiberationSans-Italic"]="LiberationSans-Italic.ttf";e["LiberationSans-BoldItalic"]="LiberationSans-BoldItalic.ttf"})),Xi=getLookupTableFactory((function(e){e.Calibri="Helvetica";e["Calibri-Bold"]="Helvetica-Bold";e["Calibri-BoldItalic"]="Helvetica-BoldOblique";e["Calibri-Italic"]="Helvetica-Oblique";e.CenturyGothic="Helvetica";e["CenturyGothic-Bold"]="Helvetica-Bold";e["CenturyGothic-BoldItalic"]="Helvetica-BoldOblique";e["CenturyGothic-Italic"]="Helvetica-Oblique";e.ComicSansMS="Comic Sans MS";e["ComicSansMS-Bold"]="Comic Sans MS-Bold";e["ComicSansMS-BoldItalic"]="Comic Sans MS-BoldItalic";e["ComicSansMS-Italic"]="Comic Sans MS-Italic";e.Impact="Helvetica";e["ItcSymbol-Bold"]="Helvetica-Bold";e["ItcSymbol-BoldItalic"]="Helvetica-BoldOblique";e["ItcSymbol-Book"]="Helvetica";e["ItcSymbol-BookItalic"]="Helvetica-Oblique";e["ItcSymbol-Medium"]="Helvetica";e["ItcSymbol-MediumItalic"]="Helvetica-Oblique";e.LucidaConsole="Courier";e["LucidaConsole-Bold"]="Courier-Bold";e["LucidaConsole-BoldItalic"]="Courier-BoldOblique";e["LucidaConsole-Italic"]="Courier-Oblique";e["LucidaSans-Demi"]="Helvetica-Bold";e["MS-Gothic"]="MS Gothic";e["MS-Gothic-Bold"]="MS Gothic-Bold";e["MS-Gothic-BoldItalic"]="MS Gothic-BoldItalic";e["MS-Gothic-Italic"]="MS Gothic-Italic";e["MS-Mincho"]="MS Mincho";e["MS-Mincho-Bold"]="MS Mincho-Bold";e["MS-Mincho-BoldItalic"]="MS Mincho-BoldItalic";e["MS-Mincho-Italic"]="MS Mincho-Italic";e["MS-PGothic"]="MS PGothic";e["MS-PGothic-Bold"]="MS PGothic-Bold";e["MS-PGothic-BoldItalic"]="MS PGothic-BoldItalic";e["MS-PGothic-Italic"]="MS PGothic-Italic";e["MS-PMincho"]="MS PMincho";e["MS-PMincho-Bold"]="MS PMincho-Bold";e["MS-PMincho-BoldItalic"]="MS PMincho-BoldItalic";e["MS-PMincho-Italic"]="MS PMincho-Italic";e.NuptialScript="Times-Italic";e.SegoeUISymbol="Helvetica"})),ji=getLookupTableFactory((function(e){e["Adobe Jenson"]=!0;e["Adobe Text"]=!0;e.Albertus=!0;e.Aldus=!0;e.Alexandria=!0;e.Algerian=!0;e["American Typewriter"]=!0;e.Antiqua=!0;e.Apex=!0;e.Arno=!0;e.Aster=!0;e.Aurora=!0;e.Baskerville=!0;e.Bell=!0;e.Bembo=!0;e["Bembo Schoolbook"]=!0;e.Benguiat=!0;e["Berkeley Old Style"]=!0;e["Bernhard Modern"]=!0;e["Berthold City"]=!0;e.Bodoni=!0;e["Bauer Bodoni"]=!0;e["Book Antiqua"]=!0;e.Bookman=!0;e["Bordeaux Roman"]=!0;e["Californian FB"]=!0;e.Calisto=!0;e.Calvert=!0;e.Capitals=!0;e.Cambria=!0;e.Cartier=!0;e.Caslon=!0;e.Catull=!0;e.Centaur=!0;e["Century Old Style"]=!0;e["Century Schoolbook"]=!0;e.Chaparral=!0;e["Charis SIL"]=!0;e.Cheltenham=!0;e["Cholla Slab"]=!0;e.Clarendon=!0;e.Clearface=!0;e.Cochin=!0;e.Colonna=!0;e["Computer Modern"]=!0;e["Concrete Roman"]=!0;e.Constantia=!0;e["Cooper Black"]=!0;e.Corona=!0;e.Ecotype=!0;e.Egyptienne=!0;e.Elephant=!0;e.Excelsior=!0;e.Fairfield=!0;e["FF Scala"]=!0;e.Folkard=!0;e.Footlight=!0;e.FreeSerif=!0;e["Friz Quadrata"]=!0;e.Garamond=!0;e.Gentium=!0;e.Georgia=!0;e.Gloucester=!0;e["Goudy Old Style"]=!0;e["Goudy Schoolbook"]=!0;e["Goudy Pro Font"]=!0;e.Granjon=!0;e["Guardian Egyptian"]=!0;e.Heather=!0;e.Hercules=!0;e["High Tower Text"]=!0;e.Hiroshige=!0;e["Hoefler Text"]=!0;e["Humana Serif"]=!0;e.Imprint=!0;e["Ionic No. 5"]=!0;e.Janson=!0;e.Joanna=!0;e.Korinna=!0;e.Lexicon=!0;e.LiberationSerif=!0;e["Liberation Serif"]=!0;e["Linux Libertine"]=!0;e.Literaturnaya=!0;e.Lucida=!0;e["Lucida Bright"]=!0;e.Melior=!0;e.Memphis=!0;e.Miller=!0;e.Minion=!0;e.Modern=!0;e["Mona Lisa"]=!0;e["Mrs Eaves"]=!0;e["MS Serif"]=!0;e["Museo Slab"]=!0;e["New York"]=!0;e["Nimbus Roman"]=!0;e["NPS Rawlinson Roadway"]=!0;e.NuptialScript=!0;e.Palatino=!0;e.Perpetua=!0;e.Plantin=!0;e["Plantin Schoolbook"]=!0;e.Playbill=!0;e["Poor Richard"]=!0;e["Rawlinson Roadway"]=!0;e.Renault=!0;e.Requiem=!0;e.Rockwell=!0;e.Roman=!0;e["Rotis Serif"]=!0;e.Sabon=!0;e.Scala=!0;e.Seagull=!0;e.Sistina=!0;e.Souvenir=!0;e.STIX=!0;e["Stone Informal"]=!0;e["Stone Serif"]=!0;e.Sylfaen=!0;e.Times=!0;e.Trajan=!0;e["Trinité"]=!0;e["Trump Mediaeval"]=!0;e.Utopia=!0;e["Vale Type"]=!0;e["Bitstream Vera"]=!0;e["Vera Serif"]=!0;e.Versailles=!0;e.Wanted=!0;e.Weiss=!0;e["Wide Latin"]=!0;e.Windsor=!0;e.XITS=!0})),Zi=getLookupTableFactory((function(e){e.Dingbats=!0;e.Symbol=!0;e.ZapfDingbats=!0;e.Wingdings=!0;e["Wingdings-Bold"]=!0;e["Wingdings-Regular"]=!0})),Vi=getLookupTableFactory((function(e){e[2]=10;e[3]=32;e[4]=33;e[5]=34;e[6]=35;e[7]=36;e[8]=37;e[9]=38;e[10]=39;e[11]=40;e[12]=41;e[13]=42;e[14]=43;e[15]=44;e[16]=45;e[17]=46;e[18]=47;e[19]=48;e[20]=49;e[21]=50;e[22]=51;e[23]=52;e[24]=53;e[25]=54;e[26]=55;e[27]=56;e[28]=57;e[29]=58;e[30]=894;e[31]=60;e[32]=61;e[33]=62;e[34]=63;e[35]=64;e[36]=65;e[37]=66;e[38]=67;e[39]=68;e[40]=69;e[41]=70;e[42]=71;e[43]=72;e[44]=73;e[45]=74;e[46]=75;e[47]=76;e[48]=77;e[49]=78;e[50]=79;e[51]=80;e[52]=81;e[53]=82;e[54]=83;e[55]=84;e[56]=85;e[57]=86;e[58]=87;e[59]=88;e[60]=89;e[61]=90;e[62]=91;e[63]=92;e[64]=93;e[65]=94;e[66]=95;e[67]=96;e[68]=97;e[69]=98;e[70]=99;e[71]=100;e[72]=101;e[73]=102;e[74]=103;e[75]=104;e[76]=105;e[77]=106;e[78]=107;e[79]=108;e[80]=109;e[81]=110;e[82]=111;e[83]=112;e[84]=113;e[85]=114;e[86]=115;e[87]=116;e[88]=117;e[89]=118;e[90]=119;e[91]=120;e[92]=121;e[93]=122;e[94]=123;e[95]=124;e[96]=125;e[97]=126;e[98]=196;e[99]=197;e[100]=199;e[101]=201;e[102]=209;e[103]=214;e[104]=220;e[105]=225;e[106]=224;e[107]=226;e[108]=228;e[109]=227;e[110]=229;e[111]=231;e[112]=233;e[113]=232;e[114]=234;e[115]=235;e[116]=237;e[117]=236;e[118]=238;e[119]=239;e[120]=241;e[121]=243;e[122]=242;e[123]=244;e[124]=246;e[125]=245;e[126]=250;e[127]=249;e[128]=251;e[129]=252;e[130]=8224;e[131]=176;e[132]=162;e[133]=163;e[134]=167;e[135]=8226;e[136]=182;e[137]=223;e[138]=174;e[139]=169;e[140]=8482;e[141]=180;e[142]=168;e[143]=8800;e[144]=198;e[145]=216;e[146]=8734;e[147]=177;e[148]=8804;e[149]=8805;e[150]=165;e[151]=181;e[152]=8706;e[153]=8721;e[154]=8719;e[156]=8747;e[157]=170;e[158]=186;e[159]=8486;e[160]=230;e[161]=248;e[162]=191;e[163]=161;e[164]=172;e[165]=8730;e[166]=402;e[167]=8776;e[168]=8710;e[169]=171;e[170]=187;e[171]=8230;e[179]=8220;e[180]=8221;e[181]=8216;e[182]=8217;e[200]=193;e[203]=205;e[207]=211;e[210]=218;e[223]=711;e[224]=321;e[225]=322;e[226]=352;e[227]=353;e[228]=381;e[229]=382;e[233]=221;e[234]=253;e[252]=263;e[253]=268;e[254]=269;e[258]=258;e[260]=260;e[261]=261;e[265]=280;e[266]=281;e[267]=282;e[268]=283;e[269]=313;e[275]=323;e[276]=324;e[278]=328;e[283]=344;e[284]=345;e[285]=346;e[286]=347;e[292]=367;e[295]=377;e[296]=378;e[298]=380;e[305]=963;e[306]=964;e[307]=966;e[308]=8215;e[309]=8252;e[310]=8319;e[311]=8359;e[312]=8592;e[313]=8593;e[337]=9552;e[493]=1039;e[494]=1040;e[672]=1488;e[673]=1489;e[674]=1490;e[675]=1491;e[676]=1492;e[677]=1493;e[678]=1494;e[679]=1495;e[680]=1496;e[681]=1497;e[682]=1498;e[683]=1499;e[684]=1500;e[685]=1501;e[686]=1502;e[687]=1503;e[688]=1504;e[689]=1505;e[690]=1506;e[691]=1507;e[692]=1508;e[693]=1509;e[694]=1510;e[695]=1511;e[696]=1512;e[697]=1513;e[698]=1514;e[705]=1524;e[706]=8362;e[710]=64288;e[711]=64298;e[759]=1617;e[761]=1776;e[763]=1778;e[775]=1652;e[777]=1764;e[778]=1780;e[779]=1781;e[780]=1782;e[782]=771;e[783]=64726;e[786]=8363;e[788]=8532;e[790]=768;e[791]=769;e[792]=768;e[795]=803;e[797]=64336;e[798]=64337;e[799]=64342;e[800]=64343;e[801]=64344;e[802]=64345;e[803]=64362;e[804]=64363;e[805]=64364;e[2424]=7821;e[2425]=7822;e[2426]=7823;e[2427]=7824;e[2428]=7825;e[2429]=7826;e[2430]=7827;e[2433]=7682;e[2678]=8045;e[2679]=8046;e[2830]=1552;e[2838]=686;e[2840]=751;e[2842]=753;e[2843]=754;e[2844]=755;e[2846]=757;e[2856]=767;e[2857]=848;e[2858]=849;e[2862]=853;e[2863]=854;e[2864]=855;e[2865]=861;e[2866]=862;e[2906]=7460;e[2908]=7462;e[2909]=7463;e[2910]=7464;e[2912]=7466;e[2913]=7467;e[2914]=7468;e[2916]=7470;e[2917]=7471;e[2918]=7472;e[2920]=7474;e[2921]=7475;e[2922]=7476;e[2924]=7478;e[2925]=7479;e[2926]=7480;e[2928]=7482;e[2929]=7483;e[2930]=7484;e[2932]=7486;e[2933]=7487;e[2934]=7488;e[2936]=7490;e[2937]=7491;e[2938]=7492;e[2940]=7494;e[2941]=7495;e[2942]=7496;e[2944]=7498;e[2946]=7500;e[2948]=7502;e[2950]=7504;e[2951]=7505;e[2952]=7506;e[2954]=7508;e[2955]=7509;e[2956]=7510;e[2958]=7512;e[2959]=7513;e[2960]=7514;e[2962]=7516;e[2963]=7517;e[2964]=7518;e[2966]=7520;e[2967]=7521;e[2968]=7522;e[2970]=7524;e[2971]=7525;e[2972]=7526;e[2974]=7528;e[2975]=7529;e[2976]=7530;e[2978]=1537;e[2979]=1538;e[2980]=1539;e[2982]=1549;e[2983]=1551;e[2984]=1552;e[2986]=1554;e[2987]=1555;e[2988]=1556;e[2990]=1623;e[2991]=1624;e[2995]=1775;e[2999]=1791;e[3002]=64290;e[3003]=64291;e[3004]=64292;e[3006]=64294;e[3007]=64295;e[3008]=64296;e[3011]=1900;e[3014]=8223;e[3015]=8244;e[3017]=7532;e[3018]=7533;e[3019]=7534;e[3075]=7590;e[3076]=7591;e[3079]=7594;e[3080]=7595;e[3083]=7598;e[3084]=7599;e[3087]=7602;e[3088]=7603;e[3091]=7606;e[3092]=7607;e[3095]=7610;e[3096]=7611;e[3099]=7614;e[3100]=7615;e[3103]=7618;e[3104]=7619;e[3107]=8337;e[3108]=8338;e[3116]=1884;e[3119]=1885;e[3120]=1885;e[3123]=1886;e[3124]=1886;e[3127]=1887;e[3128]=1887;e[3131]=1888;e[3132]=1888;e[3135]=1889;e[3136]=1889;e[3139]=1890;e[3140]=1890;e[3143]=1891;e[3144]=1891;e[3147]=1892;e[3148]=1892;e[3153]=580;e[3154]=581;e[3157]=584;e[3158]=585;e[3161]=588;e[3162]=589;e[3165]=891;e[3166]=892;e[3169]=1274;e[3170]=1275;e[3173]=1278;e[3174]=1279;e[3181]=7622;e[3182]=7623;e[3282]=11799;e[3316]=578;e[3379]=42785;e[3393]=1159;e[3416]=8377})),zi=getLookupTableFactory((function(e){e[227]=322;e[264]=261;e[291]=346})),_i=getLookupTableFactory((function(e){e[1]=32;e[4]=65;e[5]=192;e[6]=193;e[9]=196;e[17]=66;e[18]=67;e[21]=268;e[24]=68;e[28]=69;e[29]=200;e[30]=201;e[32]=282;e[38]=70;e[39]=71;e[44]=72;e[47]=73;e[48]=204;e[49]=205;e[58]=74;e[60]=75;e[62]=76;e[68]=77;e[69]=78;e[75]=79;e[76]=210;e[80]=214;e[87]=80;e[89]=81;e[90]=82;e[92]=344;e[94]=83;e[97]=352;e[100]=84;e[104]=85;e[109]=220;e[115]=86;e[116]=87;e[121]=88;e[122]=89;e[124]=221;e[127]=90;e[129]=381;e[258]=97;e[259]=224;e[260]=225;e[263]=228;e[268]=261;e[271]=98;e[272]=99;e[273]=263;e[275]=269;e[282]=100;e[286]=101;e[287]=232;e[288]=233;e[290]=283;e[295]=281;e[296]=102;e[336]=103;e[346]=104;e[349]=105;e[350]=236;e[351]=237;e[361]=106;e[364]=107;e[367]=108;e[371]=322;e[373]=109;e[374]=110;e[381]=111;e[382]=242;e[383]=243;e[386]=246;e[393]=112;e[395]=113;e[396]=114;e[398]=345;e[400]=115;e[401]=347;e[403]=353;e[410]=116;e[437]=117;e[442]=252;e[448]=118;e[449]=119;e[454]=120;e[455]=121;e[457]=253;e[460]=122;e[462]=382;e[463]=380;e[853]=44;e[855]=58;e[856]=46;e[876]=47;e[878]=45;e[882]=45;e[894]=40;e[895]=41;e[896]=91;e[897]=93;e[923]=64;e[1004]=48;e[1005]=49;e[1006]=50;e[1007]=51;e[1008]=52;e[1009]=53;e[1010]=54;e[1011]=55;e[1012]=56;e[1013]=57;e[1081]=37;e[1085]=43;e[1086]=45}));function getStandardFontName(e){const t=normalizeFontName(e);return Pi()[t]}function isKnownFontName(e){const t=normalizeFontName(e);return!!(Pi()[t]||Xi()[t]||ji()[t]||Zi()[t])}class ToUnicodeMap{constructor(e=[]){this._map=e}get length(){return this._map.length}forEach(e){for(const t in this._map)e(t,this._map[t].charCodeAt(0))}has(e){return void 0!==this._map[e]}get(e){return this._map[e]}charCodeOf(e){const t=this._map;if(t.length<=65536)return t.indexOf(e);for(const i in t)if(t[i]===e)return 0|i;return-1}amend(e){for(const t in e)this._map[t]=e[t]}}class IdentityToUnicodeMap{constructor(e,t){this.firstChar=e;this.lastChar=t}get length(){return this.lastChar+1-this.firstChar}forEach(e){for(let t=this.firstChar,i=this.lastChar;t<=i;t++)e(t,t)}has(e){return this.firstChar<=e&&e<=this.lastChar}get(e){if(this.firstChar<=e&&e<=this.lastChar)return String.fromCharCode(e)}charCodeOf(e){return Number.isInteger(e)&&e>=this.firstChar&&e<=this.lastChar?e:-1}amend(e){unreachable("Should not call amend()")}}class CFFFont{constructor(e,t){this.properties=t;const i=new CFFParser(e,t,Yi);this.cff=i.parse();this.cff.duplicateFirstGlyph();const a=new CFFCompiler(this.cff);this.seacs=this.cff.seacs;try{this.data=a.compile()}catch{warn("Failed to compile font "+t.loadedName);this.data=e}this._createBuiltInEncoding()}get numGlyphs(){return this.cff.charStrings.count}getCharset(){return this.cff.charset.charset}getGlyphMapping(){const e=this.cff,t=this.properties,{cidToGidMap:i,cMap:a}=t,s=e.charset.charset;let r,n;if(t.composite){let t,o;if(i?.length>0){t=Object.create(null);for(let e=0,a=i.length;e<a;e++){const a=i[e];void 0!==a&&(t[a]=e)}}r=Object.create(null);if(e.isCIDFont)for(n=0;n<s.length;n++){const e=s[n];o=a.charCodeOf(e);void 0!==t?.[o]&&(o=t[o]);r[o]=n}else for(n=0;n<e.charStrings.count;n++){o=a.charCodeOf(n);r[o]=n}return r}let o=e.encoding?e.encoding.encoding:null;t.isInternalFont&&(o=t.defaultEncoding);r=type1FontGlyphMapping(t,o,s);return r}hasGlyphId(e){return this.cff.hasGlyphId(e)}_createBuiltInEncoding(){const{charset:e,encoding:t}=this.cff;if(!e||!t)return;const i=e.charset,a=t.encoding,s=[];for(const e in a){const t=a[e];if(t>=0){const a=i[t];a&&(s[e]=a)}}s.length>0&&(this.properties.builtInEncoding=s)}}function getUint32(e,t){return(e[t]<<24|e[t+1]<<16|e[t+2]<<8|e[t+3])>>>0}function getUint16(e,t){return e[t]<<8|e[t+1]}function getInt16(e,t){return(e[t]<<24|e[t+1]<<16)>>16}function getInt8(e,t){return e[t]<<24>>24}function getFloat214(e,t){return getInt16(e,t)/16384}function getSubroutineBias(e){const t=e.length;let i=32768;t<1240?i=107:t<33900&&(i=1131);return i}function parseCmap(e,t,i){const a=1===getUint16(e,t+2)?getUint32(e,t+8):getUint32(e,t+16),s=getUint16(e,t+a);let r,n,o;if(4===s){getUint16(e,t+a+2);const i=getUint16(e,t+a+6)>>1;n=t+a+14;r=[];for(o=0;o<i;o++,n+=2)r[o]={end:getUint16(e,n)};n+=2;for(o=0;o<i;o++,n+=2)r[o].start=getUint16(e,n);for(o=0;o<i;o++,n+=2)r[o].idDelta=getUint16(e,n);for(o=0;o<i;o++,n+=2){let t=getUint16(e,n);if(0!==t){r[o].ids=[];for(let i=0,a=r[o].end-r[o].start+1;i<a;i++){r[o].ids[i]=getUint16(e,n+t);t+=2}}}return r}if(12===s){const i=getUint32(e,t+a+12);n=t+a+16;r=[];for(o=0;o<i;o++){t=getUint32(e,n);r.push({start:t,end:getUint32(e,n+4),idDelta:getUint32(e,n+8)-t});n+=12}return r}throw new FormatError(`unsupported cmap: ${s}`)}function parseCff(e,t,i,a){const s=new CFFParser(new Stream(e,t,i-t),{},a).parse();return{glyphs:s.charStrings.objects,subrs:s.topDict.privateDict?.subrsIndex?.objects,gsubrs:s.globalSubrIndex?.objects,isCFFCIDFont:s.isCIDFont,fdSelect:s.fdSelect,fdArray:s.fdArray}}function lookupCmap(e,t){const i=t.codePointAt(0);let a=0,s=0,r=e.length-1;for(;s<r;){const t=s+r+1>>1;i<e[t].start?r=t-1:s=t}e[s].start<=i&&i<=e[s].end&&(a=e[s].idDelta+(e[s].ids?e[s].ids[i-e[s].start]:i)&65535);return{charCode:i,glyphId:a}}function compileGlyf(e,t,i){function moveTo(e,i){t.add(ht,[e,i])}function lineTo(e,i){t.add(lt,[e,i])}function quadraticCurveTo(e,i,a,s){t.add(Ct,[e,i,a,s])}let a=0;const s=getInt16(e,a);let r,n=0,o=0;a+=10;if(s<0)do{r=getUint16(e,a);const s=getUint16(e,a+2);a+=4;let g,c;if(1&r){if(2&r){g=getInt16(e,a);c=getInt16(e,a+2)}else{g=getUint16(e,a);c=getUint16(e,a+2)}a+=4}else if(2&r){g=getInt8(e,a++);c=getInt8(e,a++)}else{g=e[a++];c=e[a++]}if(2&r){n=g;o=c}else{n=0;o=0}let h=1,l=1,C=0,Q=0;if(8&r){h=l=getFloat214(e,a);a+=2}else if(64&r){h=getFloat214(e,a);l=getFloat214(e,a+2);a+=4}else if(128&r){h=getFloat214(e,a);C=getFloat214(e,a+2);Q=getFloat214(e,a+4);l=getFloat214(e,a+6);a+=8}const E=i.glyphs[s];if(E){t.add(Qt);t.add(ut,[h,C,Q,l,n,o]);compileGlyf(E,t,i);t.add(Bt)}}while(32&r);else{const t=[];let i,g;for(i=0;i<s;i++){t.push(getUint16(e,a));a+=2}a+=2+getUint16(e,a);const c=t.at(-1)+1,h=[];for(;h.length<c;){r=e[a++];let t=1;8&r&&(t+=e[a++]);for(;t-- >0;)h.push({flags:r})}for(i=0;i<c;i++){switch(18&h[i].flags){case 0:n+=getInt16(e,a);a+=2;break;case 2:n-=e[a++];break;case 18:n+=e[a++]}h[i].x=n}for(i=0;i<c;i++){switch(36&h[i].flags){case 0:o+=getInt16(e,a);a+=2;break;case 4:o-=e[a++];break;case 36:o+=e[a++]}h[i].y=o}let l=0;for(a=0;a<s;a++){const e=t[a],s=h.slice(l,e+1);if(1&s[0].flags)s.push(s[0]);else if(1&s.at(-1).flags)s.unshift(s.at(-1));else{const e={flags:1,x:(s[0].x+s.at(-1).x)/2,y:(s[0].y+s.at(-1).y)/2};s.unshift(e);s.push(e)}moveTo(s[0].x,s[0].y);for(i=1,g=s.length;i<g;i++)if(1&s[i].flags)lineTo(s[i].x,s[i].y);else if(1&s[i+1].flags){quadraticCurveTo(s[i].x,s[i].y,s[i+1].x,s[i+1].y);i++}else quadraticCurveTo(s[i].x,s[i].y,(s[i].x+s[i+1].x)/2,(s[i].y+s[i+1].y)/2);l=e+1}}}function compileCharString(e,t,i,a){function moveTo(e,i){t.add(ht,[e,i])}function lineTo(e,i){t.add(lt,[e,i])}function bezierCurveTo(e,i,a,s,r,n){t.add(ct,[e,i,a,s,r,n])}const s=[];let r=0,n=0,o=0;!function parse(e){let g=0;for(;g<e.length;){let c,h,l,C,Q,E,u,d,f,p=!1,m=e[g++];switch(m){case 1:case 3:case 18:case 23:o+=s.length>>1;p=!0;break;case 4:n+=s.pop();moveTo(r,n);p=!0;break;case 5:for(;s.length>0;){r+=s.shift();n+=s.shift();lineTo(r,n)}break;case 6:for(;s.length>0;){r+=s.shift();lineTo(r,n);if(0===s.length)break;n+=s.shift();lineTo(r,n)}break;case 7:for(;s.length>0;){n+=s.shift();lineTo(r,n);if(0===s.length)break;r+=s.shift();lineTo(r,n)}break;case 8:for(;s.length>0;){c=r+s.shift();l=n+s.shift();h=c+s.shift();C=l+s.shift();r=h+s.shift();n=C+s.shift();bezierCurveTo(c,l,h,C,r,n)}break;case 10:d=s.pop();f=null;if(i.isCFFCIDFont){const e=i.fdSelect.getFDIndex(a);if(e>=0&&e<i.fdArray.length){const t=i.fdArray[e];let a;t.privateDict?.subrsIndex&&(a=t.privateDict.subrsIndex.objects);if(a){d+=getSubroutineBias(a);f=a[d]}}else warn("Invalid fd index for glyph index.")}else f=i.subrs[d+i.subrsBias];f&&parse(f);break;case 11:return;case 12:m=e[g++];switch(m){case 34:c=r+s.shift();h=c+s.shift();Q=n+s.shift();r=h+s.shift();bezierCurveTo(c,n,h,Q,r,Q);c=r+s.shift();h=c+s.shift();r=h+s.shift();bezierCurveTo(c,Q,h,n,r,n);break;case 35:c=r+s.shift();l=n+s.shift();h=c+s.shift();C=l+s.shift();r=h+s.shift();n=C+s.shift();bezierCurveTo(c,l,h,C,r,n);c=r+s.shift();l=n+s.shift();h=c+s.shift();C=l+s.shift();r=h+s.shift();n=C+s.shift();bezierCurveTo(c,l,h,C,r,n);s.pop();break;case 36:c=r+s.shift();Q=n+s.shift();h=c+s.shift();E=Q+s.shift();r=h+s.shift();bezierCurveTo(c,Q,h,E,r,E);c=r+s.shift();h=c+s.shift();u=E+s.shift();r=h+s.shift();bezierCurveTo(c,E,h,u,r,n);break;case 37:const e=r,t=n;c=r+s.shift();l=n+s.shift();h=c+s.shift();C=l+s.shift();r=h+s.shift();n=C+s.shift();bezierCurveTo(c,l,h,C,r,n);c=r+s.shift();l=n+s.shift();h=c+s.shift();C=l+s.shift();r=h;n=C;Math.abs(r-e)>Math.abs(n-t)?r+=s.shift():n+=s.shift();bezierCurveTo(c,l,h,C,r,n);break;default:throw new FormatError(`unknown operator: 12 ${m}`)}break;case 14:if(s.length>=4){const e=s.pop(),a=s.pop();n=s.pop();r=s.pop();t.add(Qt);t.add(dt,[r,n]);let o=lookupCmap(i.cmap,String.fromCharCode(i.glyphNameMap[fi[e]]));compileCharString(i.glyphs[o.glyphId],t,i,o.glyphId);t.add(Bt);o=lookupCmap(i.cmap,String.fromCharCode(i.glyphNameMap[fi[a]]));compileCharString(i.glyphs[o.glyphId],t,i,o.glyphId)}return;case 19:case 20:o+=s.length>>1;g+=o+7>>3;p=!0;break;case 21:n+=s.pop();r+=s.pop();moveTo(r,n);p=!0;break;case 22:r+=s.pop();moveTo(r,n);p=!0;break;case 24:for(;s.length>2;){c=r+s.shift();l=n+s.shift();h=c+s.shift();C=l+s.shift();r=h+s.shift();n=C+s.shift();bezierCurveTo(c,l,h,C,r,n)}r+=s.shift();n+=s.shift();lineTo(r,n);break;case 25:for(;s.length>6;){r+=s.shift();n+=s.shift();lineTo(r,n)}c=r+s.shift();l=n+s.shift();h=c+s.shift();C=l+s.shift();r=h+s.shift();n=C+s.shift();bezierCurveTo(c,l,h,C,r,n);break;case 26:s.length%2&&(r+=s.shift());for(;s.length>0;){c=r;l=n+s.shift();h=c+s.shift();C=l+s.shift();r=h;n=C+s.shift();bezierCurveTo(c,l,h,C,r,n)}break;case 27:s.length%2&&(n+=s.shift());for(;s.length>0;){c=r+s.shift();l=n;h=c+s.shift();C=l+s.shift();r=h+s.shift();n=C;bezierCurveTo(c,l,h,C,r,n)}break;case 28:s.push((e[g]<<24|e[g+1]<<16)>>16);g+=2;break;case 29:d=s.pop()+i.gsubrsBias;f=i.gsubrs[d];f&&parse(f);break;case 30:for(;s.length>0;){c=r;l=n+s.shift();h=c+s.shift();C=l+s.shift();r=h+s.shift();n=C+(1===s.length?s.shift():0);bezierCurveTo(c,l,h,C,r,n);if(0===s.length)break;c=r+s.shift();l=n;h=c+s.shift();C=l+s.shift();n=C+s.shift();r=h+(1===s.length?s.shift():0);bezierCurveTo(c,l,h,C,r,n)}break;case 31:for(;s.length>0;){c=r+s.shift();l=n;h=c+s.shift();C=l+s.shift();n=C+s.shift();r=h+(1===s.length?s.shift():0);bezierCurveTo(c,l,h,C,r,n);if(0===s.length)break;c=r;l=n+s.shift();h=c+s.shift();C=l+s.shift();r=h+s.shift();n=C+(1===s.length?s.shift():0);bezierCurveTo(c,l,h,C,r,n)}break;default:if(m<32)throw new FormatError(`unknown operator: ${m}`);if(m<247)s.push(m-139);else if(m<251)s.push(256*(m-247)+e[g++]+108);else if(m<255)s.push(256*-(m-251)-e[g++]-108);else{s.push((e[g]<<24|e[g+1]<<16|e[g+2]<<8|e[g+3])/65536);g+=4}}p&&(s.length=0)}}(e)}const $i=[];class Commands{cmds=[];add(e,t){if(t)if(isNumberArray(t,null))this.cmds.push(e,...t);else{warn(`Commands.add - "${e}" has at least one non-number arg: "${t}".`);const i=t.map((e=>"number"==typeof e?e:0));this.cmds.push(e,...i)}else this.cmds.push(e)}}class CompiledFont{constructor(e){this.constructor===CompiledFont&&unreachable("Cannot initialize CompiledFont.");this.fontMatrix=e;this.compiledGlyphs=Object.create(null);this.compiledCharCodeToGlyphId=Object.create(null)}getPathJs(e){const{charCode:t,glyphId:i}=lookupCmap(this.cmap,e);let a,s=this.compiledGlyphs[i];if(!s){try{s=this.compileGlyph(this.glyphs[i],i)}catch(e){s=$i;a=e}this.compiledGlyphs[i]=s}this.compiledCharCodeToGlyphId[t]??=i;if(a)throw a;return s}compileGlyph(e,t){if(!e||0===e.length||14===e[0])return $i;let i=this.fontMatrix;if(this.isCFFCIDFont){const e=this.fdSelect.getFDIndex(t);if(e>=0&&e<this.fdArray.length){i=this.fdArray[e].getByName("FontMatrix")||a}else warn("Invalid fd index for glyph index.")}const s=new Commands;s.add(Qt);s.add(ut,i.slice());s.add(Et);this.compileGlyphImpl(e,s,t);s.add(Bt);return s.cmds}compileGlyphImpl(){unreachable("Children classes should implement this.")}hasBuiltPath(e){const{charCode:t,glyphId:i}=lookupCmap(this.cmap,e);return void 0!==this.compiledGlyphs[i]&&void 0!==this.compiledCharCodeToGlyphId[t]}}class TrueTypeCompiled extends CompiledFont{constructor(e,t,i){super(i||[488e-6,0,0,488e-6,0,0]);this.glyphs=e;this.cmap=t}compileGlyphImpl(e,t){compileGlyf(e,t,this)}}class Type2Compiled extends CompiledFont{constructor(e,t,i,a){super(i||[.001,0,0,.001,0,0]);this.glyphs=e.glyphs;this.gsubrs=e.gsubrs||[];this.subrs=e.subrs||[];this.cmap=t;this.glyphNameMap=a||Ni();this.gsubrsBias=getSubroutineBias(this.gsubrs);this.subrsBias=getSubroutineBias(this.subrs);this.isCFFCIDFont=e.isCFFCIDFont;this.fdSelect=e.fdSelect;this.fdArray=e.fdArray}compileGlyphImpl(e,t,i){compileCharString(e,t,this,i)}}class FontRendererFactory{static create(e,t){const i=new Uint8Array(e.data);let a,s,r,n,o,g;const c=getUint16(i,4);for(let e=0,h=12;e<c;e++,h+=16){const e=bytesToString(i.subarray(h,h+4)),c=getUint32(i,h+8),l=getUint32(i,h+12);switch(e){case"cmap":a=parseCmap(i,c);break;case"glyf":s=i.subarray(c,c+l);break;case"loca":r=i.subarray(c,c+l);break;case"head":g=getUint16(i,c+18);o=getUint16(i,c+50);break;case"CFF ":n=parseCff(i,c,c+l,t)}}if(s){const t=g?[1/g,0,0,1/g,0,0]:e.fontMatrix;return new TrueTypeCompiled(function parseGlyfTable(e,t,i){let a,s;if(i){a=4;s=getUint32}else{a=2;s=(e,t)=>2*getUint16(e,t)}const r=[];let n=s(t,0);for(let i=a;i<t.length;i+=a){const a=s(t,i);r.push(e.subarray(n,a));n=a}return r}(s,r,o),a,t)}return new Type2Compiled(n,a,e.fontMatrix,e.glyphNameMap)}}const Aa=getLookupTableFactory((function(e){e.Courier=600;e["Courier-Bold"]=600;e["Courier-BoldOblique"]=600;e["Courier-Oblique"]=600;e.Helvetica=getLookupTableFactory((function(e){e.space=278;e.exclam=278;e.quotedbl=355;e.numbersign=556;e.dollar=556;e.percent=889;e.ampersand=667;e.quoteright=222;e.parenleft=333;e.parenright=333;e.asterisk=389;e.plus=584;e.comma=278;e.hyphen=333;e.period=278;e.slash=278;e.zero=556;e.one=556;e.two=556;e.three=556;e.four=556;e.five=556;e.six=556;e.seven=556;e.eight=556;e.nine=556;e.colon=278;e.semicolon=278;e.less=584;e.equal=584;e.greater=584;e.question=556;e.at=1015;e.A=667;e.B=667;e.C=722;e.D=722;e.E=667;e.F=611;e.G=778;e.H=722;e.I=278;e.J=500;e.K=667;e.L=556;e.M=833;e.N=722;e.O=778;e.P=667;e.Q=778;e.R=722;e.S=667;e.T=611;e.U=722;e.V=667;e.W=944;e.X=667;e.Y=667;e.Z=611;e.bracketleft=278;e.backslash=278;e.bracketright=278;e.asciicircum=469;e.underscore=556;e.quoteleft=222;e.a=556;e.b=556;e.c=500;e.d=556;e.e=556;e.f=278;e.g=556;e.h=556;e.i=222;e.j=222;e.k=500;e.l=222;e.m=833;e.n=556;e.o=556;e.p=556;e.q=556;e.r=333;e.s=500;e.t=278;e.u=556;e.v=500;e.w=722;e.x=500;e.y=500;e.z=500;e.braceleft=334;e.bar=260;e.braceright=334;e.asciitilde=584;e.exclamdown=333;e.cent=556;e.sterling=556;e.fraction=167;e.yen=556;e.florin=556;e.section=556;e.currency=556;e.quotesingle=191;e.quotedblleft=333;e.guillemotleft=556;e.guilsinglleft=333;e.guilsinglright=333;e.fi=500;e.fl=500;e.endash=556;e.dagger=556;e.daggerdbl=556;e.periodcentered=278;e.paragraph=537;e.bullet=350;e.quotesinglbase=222;e.quotedblbase=333;e.quotedblright=333;e.guillemotright=556;e.ellipsis=1e3;e.perthousand=1e3;e.questiondown=611;e.grave=333;e.acute=333;e.circumflex=333;e.tilde=333;e.macron=333;e.breve=333;e.dotaccent=333;e.dieresis=333;e.ring=333;e.cedilla=333;e.hungarumlaut=333;e.ogonek=333;e.caron=333;e.emdash=1e3;e.AE=1e3;e.ordfeminine=370;e.Lslash=556;e.Oslash=778;e.OE=1e3;e.ordmasculine=365;e.ae=889;e.dotlessi=278;e.lslash=222;e.oslash=611;e.oe=944;e.germandbls=611;e.Idieresis=278;e.eacute=556;e.abreve=556;e.uhungarumlaut=556;e.ecaron=556;e.Ydieresis=667;e.divide=584;e.Yacute=667;e.Acircumflex=667;e.aacute=556;e.Ucircumflex=722;e.yacute=500;e.scommaaccent=500;e.ecircumflex=556;e.Uring=722;e.Udieresis=722;e.aogonek=556;e.Uacute=722;e.uogonek=556;e.Edieresis=667;e.Dcroat=722;e.commaaccent=250;e.copyright=737;e.Emacron=667;e.ccaron=500;e.aring=556;e.Ncommaaccent=722;e.lacute=222;e.agrave=556;e.Tcommaaccent=611;e.Cacute=722;e.atilde=556;e.Edotaccent=667;e.scaron=500;e.scedilla=500;e.iacute=278;e.lozenge=471;e.Rcaron=722;e.Gcommaaccent=778;e.ucircumflex=556;e.acircumflex=556;e.Amacron=667;e.rcaron=333;e.ccedilla=500;e.Zdotaccent=611;e.Thorn=667;e.Omacron=778;e.Racute=722;e.Sacute=667;e.dcaron=643;e.Umacron=722;e.uring=556;e.threesuperior=333;e.Ograve=778;e.Agrave=667;e.Abreve=667;e.multiply=584;e.uacute=556;e.Tcaron=611;e.partialdiff=476;e.ydieresis=500;e.Nacute=722;e.icircumflex=278;e.Ecircumflex=667;e.adieresis=556;e.edieresis=556;e.cacute=500;e.nacute=556;e.umacron=556;e.Ncaron=722;e.Iacute=278;e.plusminus=584;e.brokenbar=260;e.registered=737;e.Gbreve=778;e.Idotaccent=278;e.summation=600;e.Egrave=667;e.racute=333;e.omacron=556;e.Zacute=611;e.Zcaron=611;e.greaterequal=549;e.Eth=722;e.Ccedilla=722;e.lcommaaccent=222;e.tcaron=317;e.eogonek=556;e.Uogonek=722;e.Aacute=667;e.Adieresis=667;e.egrave=556;e.zacute=500;e.iogonek=222;e.Oacute=778;e.oacute=556;e.amacron=556;e.sacute=500;e.idieresis=278;e.Ocircumflex=778;e.Ugrave=722;e.Delta=612;e.thorn=556;e.twosuperior=333;e.Odieresis=778;e.mu=556;e.igrave=278;e.ohungarumlaut=556;e.Eogonek=667;e.dcroat=556;e.threequarters=834;e.Scedilla=667;e.lcaron=299;e.Kcommaaccent=667;e.Lacute=556;e.trademark=1e3;e.edotaccent=556;e.Igrave=278;e.Imacron=278;e.Lcaron=556;e.onehalf=834;e.lessequal=549;e.ocircumflex=556;e.ntilde=556;e.Uhungarumlaut=722;e.Eacute=667;e.emacron=556;e.gbreve=556;e.onequarter=834;e.Scaron=667;e.Scommaaccent=667;e.Ohungarumlaut=778;e.degree=400;e.ograve=556;e.Ccaron=722;e.ugrave=556;e.radical=453;e.Dcaron=722;e.rcommaaccent=333;e.Ntilde=722;e.otilde=556;e.Rcommaaccent=722;e.Lcommaaccent=556;e.Atilde=667;e.Aogonek=667;e.Aring=667;e.Otilde=778;e.zdotaccent=500;e.Ecaron=667;e.Iogonek=278;e.kcommaaccent=500;e.minus=584;e.Icircumflex=278;e.ncaron=556;e.tcommaaccent=278;e.logicalnot=584;e.odieresis=556;e.udieresis=556;e.notequal=549;e.gcommaaccent=556;e.eth=556;e.zcaron=500;e.ncommaaccent=556;e.onesuperior=333;e.imacron=278;e.Euro=556}));e["Helvetica-Bold"]=getLookupTableFactory((function(e){e.space=278;e.exclam=333;e.quotedbl=474;e.numbersign=556;e.dollar=556;e.percent=889;e.ampersand=722;e.quoteright=278;e.parenleft=333;e.parenright=333;e.asterisk=389;e.plus=584;e.comma=278;e.hyphen=333;e.period=278;e.slash=278;e.zero=556;e.one=556;e.two=556;e.three=556;e.four=556;e.five=556;e.six=556;e.seven=556;e.eight=556;e.nine=556;e.colon=333;e.semicolon=333;e.less=584;e.equal=584;e.greater=584;e.question=611;e.at=975;e.A=722;e.B=722;e.C=722;e.D=722;e.E=667;e.F=611;e.G=778;e.H=722;e.I=278;e.J=556;e.K=722;e.L=611;e.M=833;e.N=722;e.O=778;e.P=667;e.Q=778;e.R=722;e.S=667;e.T=611;e.U=722;e.V=667;e.W=944;e.X=667;e.Y=667;e.Z=611;e.bracketleft=333;e.backslash=278;e.bracketright=333;e.asciicircum=584;e.underscore=556;e.quoteleft=278;e.a=556;e.b=611;e.c=556;e.d=611;e.e=556;e.f=333;e.g=611;e.h=611;e.i=278;e.j=278;e.k=556;e.l=278;e.m=889;e.n=611;e.o=611;e.p=611;e.q=611;e.r=389;e.s=556;e.t=333;e.u=611;e.v=556;e.w=778;e.x=556;e.y=556;e.z=500;e.braceleft=389;e.bar=280;e.braceright=389;e.asciitilde=584;e.exclamdown=333;e.cent=556;e.sterling=556;e.fraction=167;e.yen=556;e.florin=556;e.section=556;e.currency=556;e.quotesingle=238;e.quotedblleft=500;e.guillemotleft=556;e.guilsinglleft=333;e.guilsinglright=333;e.fi=611;e.fl=611;e.endash=556;e.dagger=556;e.daggerdbl=556;e.periodcentered=278;e.paragraph=556;e.bullet=350;e.quotesinglbase=278;e.quotedblbase=500;e.quotedblright=500;e.guillemotright=556;e.ellipsis=1e3;e.perthousand=1e3;e.questiondown=611;e.grave=333;e.acute=333;e.circumflex=333;e.tilde=333;e.macron=333;e.breve=333;e.dotaccent=333;e.dieresis=333;e.ring=333;e.cedilla=333;e.hungarumlaut=333;e.ogonek=333;e.caron=333;e.emdash=1e3;e.AE=1e3;e.ordfeminine=370;e.Lslash=611;e.Oslash=778;e.OE=1e3;e.ordmasculine=365;e.ae=889;e.dotlessi=278;e.lslash=278;e.oslash=611;e.oe=944;e.germandbls=611;e.Idieresis=278;e.eacute=556;e.abreve=556;e.uhungarumlaut=611;e.ecaron=556;e.Ydieresis=667;e.divide=584;e.Yacute=667;e.Acircumflex=722;e.aacute=556;e.Ucircumflex=722;e.yacute=556;e.scommaaccent=556;e.ecircumflex=556;e.Uring=722;e.Udieresis=722;e.aogonek=556;e.Uacute=722;e.uogonek=611;e.Edieresis=667;e.Dcroat=722;e.commaaccent=250;e.copyright=737;e.Emacron=667;e.ccaron=556;e.aring=556;e.Ncommaaccent=722;e.lacute=278;e.agrave=556;e.Tcommaaccent=611;e.Cacute=722;e.atilde=556;e.Edotaccent=667;e.scaron=556;e.scedilla=556;e.iacute=278;e.lozenge=494;e.Rcaron=722;e.Gcommaaccent=778;e.ucircumflex=611;e.acircumflex=556;e.Amacron=722;e.rcaron=389;e.ccedilla=556;e.Zdotaccent=611;e.Thorn=667;e.Omacron=778;e.Racute=722;e.Sacute=667;e.dcaron=743;e.Umacron=722;e.uring=611;e.threesuperior=333;e.Ograve=778;e.Agrave=722;e.Abreve=722;e.multiply=584;e.uacute=611;e.Tcaron=611;e.partialdiff=494;e.ydieresis=556;e.Nacute=722;e.icircumflex=278;e.Ecircumflex=667;e.adieresis=556;e.edieresis=556;e.cacute=556;e.nacute=611;e.umacron=611;e.Ncaron=722;e.Iacute=278;e.plusminus=584;e.brokenbar=280;e.registered=737;e.Gbreve=778;e.Idotaccent=278;e.summation=600;e.Egrave=667;e.racute=389;e.omacron=611;e.Zacute=611;e.Zcaron=611;e.greaterequal=549;e.Eth=722;e.Ccedilla=722;e.lcommaaccent=278;e.tcaron=389;e.eogonek=556;e.Uogonek=722;e.Aacute=722;e.Adieresis=722;e.egrave=556;e.zacute=500;e.iogonek=278;e.Oacute=778;e.oacute=611;e.amacron=556;e.sacute=556;e.idieresis=278;e.Ocircumflex=778;e.Ugrave=722;e.Delta=612;e.thorn=611;e.twosuperior=333;e.Odieresis=778;e.mu=611;e.igrave=278;e.ohungarumlaut=611;e.Eogonek=667;e.dcroat=611;e.threequarters=834;e.Scedilla=667;e.lcaron=400;e.Kcommaaccent=722;e.Lacute=611;e.trademark=1e3;e.edotaccent=556;e.Igrave=278;e.Imacron=278;e.Lcaron=611;e.onehalf=834;e.lessequal=549;e.ocircumflex=611;e.ntilde=611;e.Uhungarumlaut=722;e.Eacute=667;e.emacron=556;e.gbreve=611;e.onequarter=834;e.Scaron=667;e.Scommaaccent=667;e.Ohungarumlaut=778;e.degree=400;e.ograve=611;e.Ccaron=722;e.ugrave=611;e.radical=549;e.Dcaron=722;e.rcommaaccent=389;e.Ntilde=722;e.otilde=611;e.Rcommaaccent=722;e.Lcommaaccent=611;e.Atilde=722;e.Aogonek=722;e.Aring=722;e.Otilde=778;e.zdotaccent=500;e.Ecaron=667;e.Iogonek=278;e.kcommaaccent=556;e.minus=584;e.Icircumflex=278;e.ncaron=611;e.tcommaaccent=333;e.logicalnot=584;e.odieresis=611;e.udieresis=611;e.notequal=549;e.gcommaaccent=611;e.eth=611;e.zcaron=500;e.ncommaaccent=611;e.onesuperior=333;e.imacron=278;e.Euro=556}));e["Helvetica-BoldOblique"]=getLookupTableFactory((function(e){e.space=278;e.exclam=333;e.quotedbl=474;e.numbersign=556;e.dollar=556;e.percent=889;e.ampersand=722;e.quoteright=278;e.parenleft=333;e.parenright=333;e.asterisk=389;e.plus=584;e.comma=278;e.hyphen=333;e.period=278;e.slash=278;e.zero=556;e.one=556;e.two=556;e.three=556;e.four=556;e.five=556;e.six=556;e.seven=556;e.eight=556;e.nine=556;e.colon=333;e.semicolon=333;e.less=584;e.equal=584;e.greater=584;e.question=611;e.at=975;e.A=722;e.B=722;e.C=722;e.D=722;e.E=667;e.F=611;e.G=778;e.H=722;e.I=278;e.J=556;e.K=722;e.L=611;e.M=833;e.N=722;e.O=778;e.P=667;e.Q=778;e.R=722;e.S=667;e.T=611;e.U=722;e.V=667;e.W=944;e.X=667;e.Y=667;e.Z=611;e.bracketleft=333;e.backslash=278;e.bracketright=333;e.asciicircum=584;e.underscore=556;e.quoteleft=278;e.a=556;e.b=611;e.c=556;e.d=611;e.e=556;e.f=333;e.g=611;e.h=611;e.i=278;e.j=278;e.k=556;e.l=278;e.m=889;e.n=611;e.o=611;e.p=611;e.q=611;e.r=389;e.s=556;e.t=333;e.u=611;e.v=556;e.w=778;e.x=556;e.y=556;e.z=500;e.braceleft=389;e.bar=280;e.braceright=389;e.asciitilde=584;e.exclamdown=333;e.cent=556;e.sterling=556;e.fraction=167;e.yen=556;e.florin=556;e.section=556;e.currency=556;e.quotesingle=238;e.quotedblleft=500;e.guillemotleft=556;e.guilsinglleft=333;e.guilsinglright=333;e.fi=611;e.fl=611;e.endash=556;e.dagger=556;e.daggerdbl=556;e.periodcentered=278;e.paragraph=556;e.bullet=350;e.quotesinglbase=278;e.quotedblbase=500;e.quotedblright=500;e.guillemotright=556;e.ellipsis=1e3;e.perthousand=1e3;e.questiondown=611;e.grave=333;e.acute=333;e.circumflex=333;e.tilde=333;e.macron=333;e.breve=333;e.dotaccent=333;e.dieresis=333;e.ring=333;e.cedilla=333;e.hungarumlaut=333;e.ogonek=333;e.caron=333;e.emdash=1e3;e.AE=1e3;e.ordfeminine=370;e.Lslash=611;e.Oslash=778;e.OE=1e3;e.ordmasculine=365;e.ae=889;e.dotlessi=278;e.lslash=278;e.oslash=611;e.oe=944;e.germandbls=611;e.Idieresis=278;e.eacute=556;e.abreve=556;e.uhungarumlaut=611;e.ecaron=556;e.Ydieresis=667;e.divide=584;e.Yacute=667;e.Acircumflex=722;e.aacute=556;e.Ucircumflex=722;e.yacute=556;e.scommaaccent=556;e.ecircumflex=556;e.Uring=722;e.Udieresis=722;e.aogonek=556;e.Uacute=722;e.uogonek=611;e.Edieresis=667;e.Dcroat=722;e.commaaccent=250;e.copyright=737;e.Emacron=667;e.ccaron=556;e.aring=556;e.Ncommaaccent=722;e.lacute=278;e.agrave=556;e.Tcommaaccent=611;e.Cacute=722;e.atilde=556;e.Edotaccent=667;e.scaron=556;e.scedilla=556;e.iacute=278;e.lozenge=494;e.Rcaron=722;e.Gcommaaccent=778;e.ucircumflex=611;e.acircumflex=556;e.Amacron=722;e.rcaron=389;e.ccedilla=556;e.Zdotaccent=611;e.Thorn=667;e.Omacron=778;e.Racute=722;e.Sacute=667;e.dcaron=743;e.Umacron=722;e.uring=611;e.threesuperior=333;e.Ograve=778;e.Agrave=722;e.Abreve=722;e.multiply=584;e.uacute=611;e.Tcaron=611;e.partialdiff=494;e.ydieresis=556;e.Nacute=722;e.icircumflex=278;e.Ecircumflex=667;e.adieresis=556;e.edieresis=556;e.cacute=556;e.nacute=611;e.umacron=611;e.Ncaron=722;e.Iacute=278;e.plusminus=584;e.brokenbar=280;e.registered=737;e.Gbreve=778;e.Idotaccent=278;e.summation=600;e.Egrave=667;e.racute=389;e.omacron=611;e.Zacute=611;e.Zcaron=611;e.greaterequal=549;e.Eth=722;e.Ccedilla=722;e.lcommaaccent=278;e.tcaron=389;e.eogonek=556;e.Uogonek=722;e.Aacute=722;e.Adieresis=722;e.egrave=556;e.zacute=500;e.iogonek=278;e.Oacute=778;e.oacute=611;e.amacron=556;e.sacute=556;e.idieresis=278;e.Ocircumflex=778;e.Ugrave=722;e.Delta=612;e.thorn=611;e.twosuperior=333;e.Odieresis=778;e.mu=611;e.igrave=278;e.ohungarumlaut=611;e.Eogonek=667;e.dcroat=611;e.threequarters=834;e.Scedilla=667;e.lcaron=400;e.Kcommaaccent=722;e.Lacute=611;e.trademark=1e3;e.edotaccent=556;e.Igrave=278;e.Imacron=278;e.Lcaron=611;e.onehalf=834;e.lessequal=549;e.ocircumflex=611;e.ntilde=611;e.Uhungarumlaut=722;e.Eacute=667;e.emacron=556;e.gbreve=611;e.onequarter=834;e.Scaron=667;e.Scommaaccent=667;e.Ohungarumlaut=778;e.degree=400;e.ograve=611;e.Ccaron=722;e.ugrave=611;e.radical=549;e.Dcaron=722;e.rcommaaccent=389;e.Ntilde=722;e.otilde=611;e.Rcommaaccent=722;e.Lcommaaccent=611;e.Atilde=722;e.Aogonek=722;e.Aring=722;e.Otilde=778;e.zdotaccent=500;e.Ecaron=667;e.Iogonek=278;e.kcommaaccent=556;e.minus=584;e.Icircumflex=278;e.ncaron=611;e.tcommaaccent=333;e.logicalnot=584;e.odieresis=611;e.udieresis=611;e.notequal=549;e.gcommaaccent=611;e.eth=611;e.zcaron=500;e.ncommaaccent=611;e.onesuperior=333;e.imacron=278;e.Euro=556}));e["Helvetica-Oblique"]=getLookupTableFactory((function(e){e.space=278;e.exclam=278;e.quotedbl=355;e.numbersign=556;e.dollar=556;e.percent=889;e.ampersand=667;e.quoteright=222;e.parenleft=333;e.parenright=333;e.asterisk=389;e.plus=584;e.comma=278;e.hyphen=333;e.period=278;e.slash=278;e.zero=556;e.one=556;e.two=556;e.three=556;e.four=556;e.five=556;e.six=556;e.seven=556;e.eight=556;e.nine=556;e.colon=278;e.semicolon=278;e.less=584;e.equal=584;e.greater=584;e.question=556;e.at=1015;e.A=667;e.B=667;e.C=722;e.D=722;e.E=667;e.F=611;e.G=778;e.H=722;e.I=278;e.J=500;e.K=667;e.L=556;e.M=833;e.N=722;e.O=778;e.P=667;e.Q=778;e.R=722;e.S=667;e.T=611;e.U=722;e.V=667;e.W=944;e.X=667;e.Y=667;e.Z=611;e.bracketleft=278;e.backslash=278;e.bracketright=278;e.asciicircum=469;e.underscore=556;e.quoteleft=222;e.a=556;e.b=556;e.c=500;e.d=556;e.e=556;e.f=278;e.g=556;e.h=556;e.i=222;e.j=222;e.k=500;e.l=222;e.m=833;e.n=556;e.o=556;e.p=556;e.q=556;e.r=333;e.s=500;e.t=278;e.u=556;e.v=500;e.w=722;e.x=500;e.y=500;e.z=500;e.braceleft=334;e.bar=260;e.braceright=334;e.asciitilde=584;e.exclamdown=333;e.cent=556;e.sterling=556;e.fraction=167;e.yen=556;e.florin=556;e.section=556;e.currency=556;e.quotesingle=191;e.quotedblleft=333;e.guillemotleft=556;e.guilsinglleft=333;e.guilsinglright=333;e.fi=500;e.fl=500;e.endash=556;e.dagger=556;e.daggerdbl=556;e.periodcentered=278;e.paragraph=537;e.bullet=350;e.quotesinglbase=222;e.quotedblbase=333;e.quotedblright=333;e.guillemotright=556;e.ellipsis=1e3;e.perthousand=1e3;e.questiondown=611;e.grave=333;e.acute=333;e.circumflex=333;e.tilde=333;e.macron=333;e.breve=333;e.dotaccent=333;e.dieresis=333;e.ring=333;e.cedilla=333;e.hungarumlaut=333;e.ogonek=333;e.caron=333;e.emdash=1e3;e.AE=1e3;e.ordfeminine=370;e.Lslash=556;e.Oslash=778;e.OE=1e3;e.ordmasculine=365;e.ae=889;e.dotlessi=278;e.lslash=222;e.oslash=611;e.oe=944;e.germandbls=611;e.Idieresis=278;e.eacute=556;e.abreve=556;e.uhungarumlaut=556;e.ecaron=556;e.Ydieresis=667;e.divide=584;e.Yacute=667;e.Acircumflex=667;e.aacute=556;e.Ucircumflex=722;e.yacute=500;e.scommaaccent=500;e.ecircumflex=556;e.Uring=722;e.Udieresis=722;e.aogonek=556;e.Uacute=722;e.uogonek=556;e.Edieresis=667;e.Dcroat=722;e.commaaccent=250;e.copyright=737;e.Emacron=667;e.ccaron=500;e.aring=556;e.Ncommaaccent=722;e.lacute=222;e.agrave=556;e.Tcommaaccent=611;e.Cacute=722;e.atilde=556;e.Edotaccent=667;e.scaron=500;e.scedilla=500;e.iacute=278;e.lozenge=471;e.Rcaron=722;e.Gcommaaccent=778;e.ucircumflex=556;e.acircumflex=556;e.Amacron=667;e.rcaron=333;e.ccedilla=500;e.Zdotaccent=611;e.Thorn=667;e.Omacron=778;e.Racute=722;e.Sacute=667;e.dcaron=643;e.Umacron=722;e.uring=556;e.threesuperior=333;e.Ograve=778;e.Agrave=667;e.Abreve=667;e.multiply=584;e.uacute=556;e.Tcaron=611;e.partialdiff=476;e.ydieresis=500;e.Nacute=722;e.icircumflex=278;e.Ecircumflex=667;e.adieresis=556;e.edieresis=556;e.cacute=500;e.nacute=556;e.umacron=556;e.Ncaron=722;e.Iacute=278;e.plusminus=584;e.brokenbar=260;e.registered=737;e.Gbreve=778;e.Idotaccent=278;e.summation=600;e.Egrave=667;e.racute=333;e.omacron=556;e.Zacute=611;e.Zcaron=611;e.greaterequal=549;e.Eth=722;e.Ccedilla=722;e.lcommaaccent=222;e.tcaron=317;e.eogonek=556;e.Uogonek=722;e.Aacute=667;e.Adieresis=667;e.egrave=556;e.zacute=500;e.iogonek=222;e.Oacute=778;e.oacute=556;e.amacron=556;e.sacute=500;e.idieresis=278;e.Ocircumflex=778;e.Ugrave=722;e.Delta=612;e.thorn=556;e.twosuperior=333;e.Odieresis=778;e.mu=556;e.igrave=278;e.ohungarumlaut=556;e.Eogonek=667;e.dcroat=556;e.threequarters=834;e.Scedilla=667;e.lcaron=299;e.Kcommaaccent=667;e.Lacute=556;e.trademark=1e3;e.edotaccent=556;e.Igrave=278;e.Imacron=278;e.Lcaron=556;e.onehalf=834;e.lessequal=549;e.ocircumflex=556;e.ntilde=556;e.Uhungarumlaut=722;e.Eacute=667;e.emacron=556;e.gbreve=556;e.onequarter=834;e.Scaron=667;e.Scommaaccent=667;e.Ohungarumlaut=778;e.degree=400;e.ograve=556;e.Ccaron=722;e.ugrave=556;e.radical=453;e.Dcaron=722;e.rcommaaccent=333;e.Ntilde=722;e.otilde=556;e.Rcommaaccent=722;e.Lcommaaccent=556;e.Atilde=667;e.Aogonek=667;e.Aring=667;e.Otilde=778;e.zdotaccent=500;e.Ecaron=667;e.Iogonek=278;e.kcommaaccent=500;e.minus=584;e.Icircumflex=278;e.ncaron=556;e.tcommaaccent=278;e.logicalnot=584;e.odieresis=556;e.udieresis=556;e.notequal=549;e.gcommaaccent=556;e.eth=556;e.zcaron=500;e.ncommaaccent=556;e.onesuperior=333;e.imacron=278;e.Euro=556}));e.Symbol=getLookupTableFactory((function(e){e.space=250;e.exclam=333;e.universal=713;e.numbersign=500;e.existential=549;e.percent=833;e.ampersand=778;e.suchthat=439;e.parenleft=333;e.parenright=333;e.asteriskmath=500;e.plus=549;e.comma=250;e.minus=549;e.period=250;e.slash=278;e.zero=500;e.one=500;e.two=500;e.three=500;e.four=500;e.five=500;e.six=500;e.seven=500;e.eight=500;e.nine=500;e.colon=278;e.semicolon=278;e.less=549;e.equal=549;e.greater=549;e.question=444;e.congruent=549;e.Alpha=722;e.Beta=667;e.Chi=722;e.Delta=612;e.Epsilon=611;e.Phi=763;e.Gamma=603;e.Eta=722;e.Iota=333;e.theta1=631;e.Kappa=722;e.Lambda=686;e.Mu=889;e.Nu=722;e.Omicron=722;e.Pi=768;e.Theta=741;e.Rho=556;e.Sigma=592;e.Tau=611;e.Upsilon=690;e.sigma1=439;e.Omega=768;e.Xi=645;e.Psi=795;e.Zeta=611;e.bracketleft=333;e.therefore=863;e.bracketright=333;e.perpendicular=658;e.underscore=500;e.radicalex=500;e.alpha=631;e.beta=549;e.chi=549;e.delta=494;e.epsilon=439;e.phi=521;e.gamma=411;e.eta=603;e.iota=329;e.phi1=603;e.kappa=549;e.lambda=549;e.mu=576;e.nu=521;e.omicron=549;e.pi=549;e.theta=521;e.rho=549;e.sigma=603;e.tau=439;e.upsilon=576;e.omega1=713;e.omega=686;e.xi=493;e.psi=686;e.zeta=494;e.braceleft=480;e.bar=200;e.braceright=480;e.similar=549;e.Euro=750;e.Upsilon1=620;e.minute=247;e.lessequal=549;e.fraction=167;e.infinity=713;e.florin=500;e.club=753;e.diamond=753;e.heart=753;e.spade=753;e.arrowboth=1042;e.arrowleft=987;e.arrowup=603;e.arrowright=987;e.arrowdown=603;e.degree=400;e.plusminus=549;e.second=411;e.greaterequal=549;e.multiply=549;e.proportional=713;e.partialdiff=494;e.bullet=460;e.divide=549;e.notequal=549;e.equivalence=549;e.approxequal=549;e.ellipsis=1e3;e.arrowvertex=603;e.arrowhorizex=1e3;e.carriagereturn=658;e.aleph=823;e.Ifraktur=686;e.Rfraktur=795;e.weierstrass=987;e.circlemultiply=768;e.circleplus=768;e.emptyset=823;e.intersection=768;e.union=768;e.propersuperset=713;e.reflexsuperset=713;e.notsubset=713;e.propersubset=713;e.reflexsubset=713;e.element=713;e.notelement=713;e.angle=768;e.gradient=713;e.registerserif=790;e.copyrightserif=790;e.trademarkserif=890;e.product=823;e.radical=549;e.dotmath=250;e.logicalnot=713;e.logicaland=603;e.logicalor=603;e.arrowdblboth=1042;e.arrowdblleft=987;e.arrowdblup=603;e.arrowdblright=987;e.arrowdbldown=603;e.lozenge=494;e.angleleft=329;e.registersans=790;e.copyrightsans=790;e.trademarksans=786;e.summation=713;e.parenlefttp=384;e.parenleftex=384;e.parenleftbt=384;e.bracketlefttp=384;e.bracketleftex=384;e.bracketleftbt=384;e.bracelefttp=494;e.braceleftmid=494;e.braceleftbt=494;e.braceex=494;e.angleright=329;e.integral=274;e.integraltp=686;e.integralex=686;e.integralbt=686;e.parenrighttp=384;e.parenrightex=384;e.parenrightbt=384;e.bracketrighttp=384;e.bracketrightex=384;e.bracketrightbt=384;e.bracerighttp=494;e.bracerightmid=494;e.bracerightbt=494;e.apple=790}));e["Times-Roman"]=getLookupTableFactory((function(e){e.space=250;e.exclam=333;e.quotedbl=408;e.numbersign=500;e.dollar=500;e.percent=833;e.ampersand=778;e.quoteright=333;e.parenleft=333;e.parenright=333;e.asterisk=500;e.plus=564;e.comma=250;e.hyphen=333;e.period=250;e.slash=278;e.zero=500;e.one=500;e.two=500;e.three=500;e.four=500;e.five=500;e.six=500;e.seven=500;e.eight=500;e.nine=500;e.colon=278;e.semicolon=278;e.less=564;e.equal=564;e.greater=564;e.question=444;e.at=921;e.A=722;e.B=667;e.C=667;e.D=722;e.E=611;e.F=556;e.G=722;e.H=722;e.I=333;e.J=389;e.K=722;e.L=611;e.M=889;e.N=722;e.O=722;e.P=556;e.Q=722;e.R=667;e.S=556;e.T=611;e.U=722;e.V=722;e.W=944;e.X=722;e.Y=722;e.Z=611;e.bracketleft=333;e.backslash=278;e.bracketright=333;e.asciicircum=469;e.underscore=500;e.quoteleft=333;e.a=444;e.b=500;e.c=444;e.d=500;e.e=444;e.f=333;e.g=500;e.h=500;e.i=278;e.j=278;e.k=500;e.l=278;e.m=778;e.n=500;e.o=500;e.p=500;e.q=500;e.r=333;e.s=389;e.t=278;e.u=500;e.v=500;e.w=722;e.x=500;e.y=500;e.z=444;e.braceleft=480;e.bar=200;e.braceright=480;e.asciitilde=541;e.exclamdown=333;e.cent=500;e.sterling=500;e.fraction=167;e.yen=500;e.florin=500;e.section=500;e.currency=500;e.quotesingle=180;e.quotedblleft=444;e.guillemotleft=500;e.guilsinglleft=333;e.guilsinglright=333;e.fi=556;e.fl=556;e.endash=500;e.dagger=500;e.daggerdbl=500;e.periodcentered=250;e.paragraph=453;e.bullet=350;e.quotesinglbase=333;e.quotedblbase=444;e.quotedblright=444;e.guillemotright=500;e.ellipsis=1e3;e.perthousand=1e3;e.questiondown=444;e.grave=333;e.acute=333;e.circumflex=333;e.tilde=333;e.macron=333;e.breve=333;e.dotaccent=333;e.dieresis=333;e.ring=333;e.cedilla=333;e.hungarumlaut=333;e.ogonek=333;e.caron=333;e.emdash=1e3;e.AE=889;e.ordfeminine=276;e.Lslash=611;e.Oslash=722;e.OE=889;e.ordmasculine=310;e.ae=667;e.dotlessi=278;e.lslash=278;e.oslash=500;e.oe=722;e.germandbls=500;e.Idieresis=333;e.eacute=444;e.abreve=444;e.uhungarumlaut=500;e.ecaron=444;e.Ydieresis=722;e.divide=564;e.Yacute=722;e.Acircumflex=722;e.aacute=444;e.Ucircumflex=722;e.yacute=500;e.scommaaccent=389;e.ecircumflex=444;e.Uring=722;e.Udieresis=722;e.aogonek=444;e.Uacute=722;e.uogonek=500;e.Edieresis=611;e.Dcroat=722;e.commaaccent=250;e.copyright=760;e.Emacron=611;e.ccaron=444;e.aring=444;e.Ncommaaccent=722;e.lacute=278;e.agrave=444;e.Tcommaaccent=611;e.Cacute=667;e.atilde=444;e.Edotaccent=611;e.scaron=389;e.scedilla=389;e.iacute=278;e.lozenge=471;e.Rcaron=667;e.Gcommaaccent=722;e.ucircumflex=500;e.acircumflex=444;e.Amacron=722;e.rcaron=333;e.ccedilla=444;e.Zdotaccent=611;e.Thorn=556;e.Omacron=722;e.Racute=667;e.Sacute=556;e.dcaron=588;e.Umacron=722;e.uring=500;e.threesuperior=300;e.Ograve=722;e.Agrave=722;e.Abreve=722;e.multiply=564;e.uacute=500;e.Tcaron=611;e.partialdiff=476;e.ydieresis=500;e.Nacute=722;e.icircumflex=278;e.Ecircumflex=611;e.adieresis=444;e.edieresis=444;e.cacute=444;e.nacute=500;e.umacron=500;e.Ncaron=722;e.Iacute=333;e.plusminus=564;e.brokenbar=200;e.registered=760;e.Gbreve=722;e.Idotaccent=333;e.summation=600;e.Egrave=611;e.racute=333;e.omacron=500;e.Zacute=611;e.Zcaron=611;e.greaterequal=549;e.Eth=722;e.Ccedilla=667;e.lcommaaccent=278;e.tcaron=326;e.eogonek=444;e.Uogonek=722;e.Aacute=722;e.Adieresis=722;e.egrave=444;e.zacute=444;e.iogonek=278;e.Oacute=722;e.oacute=500;e.amacron=444;e.sacute=389;e.idieresis=278;e.Ocircumflex=722;e.Ugrave=722;e.Delta=612;e.thorn=500;e.twosuperior=300;e.Odieresis=722;e.mu=500;e.igrave=278;e.ohungarumlaut=500;e.Eogonek=611;e.dcroat=500;e.threequarters=750;e.Scedilla=556;e.lcaron=344;e.Kcommaaccent=722;e.Lacute=611;e.trademark=980;e.edotaccent=444;e.Igrave=333;e.Imacron=333;e.Lcaron=611;e.onehalf=750;e.lessequal=549;e.ocircumflex=500;e.ntilde=500;e.Uhungarumlaut=722;e.Eacute=611;e.emacron=444;e.gbreve=500;e.onequarter=750;e.Scaron=556;e.Scommaaccent=556;e.Ohungarumlaut=722;e.degree=400;e.ograve=500;e.Ccaron=667;e.ugrave=500;e.radical=453;e.Dcaron=722;e.rcommaaccent=333;e.Ntilde=722;e.otilde=500;e.Rcommaaccent=667;e.Lcommaaccent=611;e.Atilde=722;e.Aogonek=722;e.Aring=722;e.Otilde=722;e.zdotaccent=444;e.Ecaron=611;e.Iogonek=333;e.kcommaaccent=500;e.minus=564;e.Icircumflex=333;e.ncaron=500;e.tcommaaccent=278;e.logicalnot=564;e.odieresis=500;e.udieresis=500;e.notequal=549;e.gcommaaccent=500;e.eth=500;e.zcaron=444;e.ncommaaccent=500;e.onesuperior=300;e.imacron=278;e.Euro=500}));e["Times-Bold"]=getLookupTableFactory((function(e){e.space=250;e.exclam=333;e.quotedbl=555;e.numbersign=500;e.dollar=500;e.percent=1e3;e.ampersand=833;e.quoteright=333;e.parenleft=333;e.parenright=333;e.asterisk=500;e.plus=570;e.comma=250;e.hyphen=333;e.period=250;e.slash=278;e.zero=500;e.one=500;e.two=500;e.three=500;e.four=500;e.five=500;e.six=500;e.seven=500;e.eight=500;e.nine=500;e.colon=333;e.semicolon=333;e.less=570;e.equal=570;e.greater=570;e.question=500;e.at=930;e.A=722;e.B=667;e.C=722;e.D=722;e.E=667;e.F=611;e.G=778;e.H=778;e.I=389;e.J=500;e.K=778;e.L=667;e.M=944;e.N=722;e.O=778;e.P=611;e.Q=778;e.R=722;e.S=556;e.T=667;e.U=722;e.V=722;e.W=1e3;e.X=722;e.Y=722;e.Z=667;e.bracketleft=333;e.backslash=278;e.bracketright=333;e.asciicircum=581;e.underscore=500;e.quoteleft=333;e.a=500;e.b=556;e.c=444;e.d=556;e.e=444;e.f=333;e.g=500;e.h=556;e.i=278;e.j=333;e.k=556;e.l=278;e.m=833;e.n=556;e.o=500;e.p=556;e.q=556;e.r=444;e.s=389;e.t=333;e.u=556;e.v=500;e.w=722;e.x=500;e.y=500;e.z=444;e.braceleft=394;e.bar=220;e.braceright=394;e.asciitilde=520;e.exclamdown=333;e.cent=500;e.sterling=500;e.fraction=167;e.yen=500;e.florin=500;e.section=500;e.currency=500;e.quotesingle=278;e.quotedblleft=500;e.guillemotleft=500;e.guilsinglleft=333;e.guilsinglright=333;e.fi=556;e.fl=556;e.endash=500;e.dagger=500;e.daggerdbl=500;e.periodcentered=250;e.paragraph=540;e.bullet=350;e.quotesinglbase=333;e.quotedblbase=500;e.quotedblright=500;e.guillemotright=500;e.ellipsis=1e3;e.perthousand=1e3;e.questiondown=500;e.grave=333;e.acute=333;e.circumflex=333;e.tilde=333;e.macron=333;e.breve=333;e.dotaccent=333;e.dieresis=333;e.ring=333;e.cedilla=333;e.hungarumlaut=333;e.ogonek=333;e.caron=333;e.emdash=1e3;e.AE=1e3;e.ordfeminine=300;e.Lslash=667;e.Oslash=778;e.OE=1e3;e.ordmasculine=330;e.ae=722;e.dotlessi=278;e.lslash=278;e.oslash=500;e.oe=722;e.germandbls=556;e.Idieresis=389;e.eacute=444;e.abreve=500;e.uhungarumlaut=556;e.ecaron=444;e.Ydieresis=722;e.divide=570;e.Yacute=722;e.Acircumflex=722;e.aacute=500;e.Ucircumflex=722;e.yacute=500;e.scommaaccent=389;e.ecircumflex=444;e.Uring=722;e.Udieresis=722;e.aogonek=500;e.Uacute=722;e.uogonek=556;e.Edieresis=667;e.Dcroat=722;e.commaaccent=250;e.copyright=747;e.Emacron=667;e.ccaron=444;e.aring=500;e.Ncommaaccent=722;e.lacute=278;e.agrave=500;e.Tcommaaccent=667;e.Cacute=722;e.atilde=500;e.Edotaccent=667;e.scaron=389;e.scedilla=389;e.iacute=278;e.lozenge=494;e.Rcaron=722;e.Gcommaaccent=778;e.ucircumflex=556;e.acircumflex=500;e.Amacron=722;e.rcaron=444;e.ccedilla=444;e.Zdotaccent=667;e.Thorn=611;e.Omacron=778;e.Racute=722;e.Sacute=556;e.dcaron=672;e.Umacron=722;e.uring=556;e.threesuperior=300;e.Ograve=778;e.Agrave=722;e.Abreve=722;e.multiply=570;e.uacute=556;e.Tcaron=667;e.partialdiff=494;e.ydieresis=500;e.Nacute=722;e.icircumflex=278;e.Ecircumflex=667;e.adieresis=500;e.edieresis=444;e.cacute=444;e.nacute=556;e.umacron=556;e.Ncaron=722;e.Iacute=389;e.plusminus=570;e.brokenbar=220;e.registered=747;e.Gbreve=778;e.Idotaccent=389;e.summation=600;e.Egrave=667;e.racute=444;e.omacron=500;e.Zacute=667;e.Zcaron=667;e.greaterequal=549;e.Eth=722;e.Ccedilla=722;e.lcommaaccent=278;e.tcaron=416;e.eogonek=444;e.Uogonek=722;e.Aacute=722;e.Adieresis=722;e.egrave=444;e.zacute=444;e.iogonek=278;e.Oacute=778;e.oacute=500;e.amacron=500;e.sacute=389;e.idieresis=278;e.Ocircumflex=778;e.Ugrave=722;e.Delta=612;e.thorn=556;e.twosuperior=300;e.Odieresis=778;e.mu=556;e.igrave=278;e.ohungarumlaut=500;e.Eogonek=667;e.dcroat=556;e.threequarters=750;e.Scedilla=556;e.lcaron=394;e.Kcommaaccent=778;e.Lacute=667;e.trademark=1e3;e.edotaccent=444;e.Igrave=389;e.Imacron=389;e.Lcaron=667;e.onehalf=750;e.lessequal=549;e.ocircumflex=500;e.ntilde=556;e.Uhungarumlaut=722;e.Eacute=667;e.emacron=444;e.gbreve=500;e.onequarter=750;e.Scaron=556;e.Scommaaccent=556;e.Ohungarumlaut=778;e.degree=400;e.ograve=500;e.Ccaron=722;e.ugrave=556;e.radical=549;e.Dcaron=722;e.rcommaaccent=444;e.Ntilde=722;e.otilde=500;e.Rcommaaccent=722;e.Lcommaaccent=667;e.Atilde=722;e.Aogonek=722;e.Aring=722;e.Otilde=778;e.zdotaccent=444;e.Ecaron=667;e.Iogonek=389;e.kcommaaccent=556;e.minus=570;e.Icircumflex=389;e.ncaron=556;e.tcommaaccent=333;e.logicalnot=570;e.odieresis=500;e.udieresis=556;e.notequal=549;e.gcommaaccent=500;e.eth=500;e.zcaron=444;e.ncommaaccent=556;e.onesuperior=300;e.imacron=278;e.Euro=500}));e["Times-BoldItalic"]=getLookupTableFactory((function(e){e.space=250;e.exclam=389;e.quotedbl=555;e.numbersign=500;e.dollar=500;e.percent=833;e.ampersand=778;e.quoteright=333;e.parenleft=333;e.parenright=333;e.asterisk=500;e.plus=570;e.comma=250;e.hyphen=333;e.period=250;e.slash=278;e.zero=500;e.one=500;e.two=500;e.three=500;e.four=500;e.five=500;e.six=500;e.seven=500;e.eight=500;e.nine=500;e.colon=333;e.semicolon=333;e.less=570;e.equal=570;e.greater=570;e.question=500;e.at=832;e.A=667;e.B=667;e.C=667;e.D=722;e.E=667;e.F=667;e.G=722;e.H=778;e.I=389;e.J=500;e.K=667;e.L=611;e.M=889;e.N=722;e.O=722;e.P=611;e.Q=722;e.R=667;e.S=556;e.T=611;e.U=722;e.V=667;e.W=889;e.X=667;e.Y=611;e.Z=611;e.bracketleft=333;e.backslash=278;e.bracketright=333;e.asciicircum=570;e.underscore=500;e.quoteleft=333;e.a=500;e.b=500;e.c=444;e.d=500;e.e=444;e.f=333;e.g=500;e.h=556;e.i=278;e.j=278;e.k=500;e.l=278;e.m=778;e.n=556;e.o=500;e.p=500;e.q=500;e.r=389;e.s=389;e.t=278;e.u=556;e.v=444;e.w=667;e.x=500;e.y=444;e.z=389;e.braceleft=348;e.bar=220;e.braceright=348;e.asciitilde=570;e.exclamdown=389;e.cent=500;e.sterling=500;e.fraction=167;e.yen=500;e.florin=500;e.section=500;e.currency=500;e.quotesingle=278;e.quotedblleft=500;e.guillemotleft=500;e.guilsinglleft=333;e.guilsinglright=333;e.fi=556;e.fl=556;e.endash=500;e.dagger=500;e.daggerdbl=500;e.periodcentered=250;e.paragraph=500;e.bullet=350;e.quotesinglbase=333;e.quotedblbase=500;e.quotedblright=500;e.guillemotright=500;e.ellipsis=1e3;e.perthousand=1e3;e.questiondown=500;e.grave=333;e.acute=333;e.circumflex=333;e.tilde=333;e.macron=333;e.breve=333;e.dotaccent=333;e.dieresis=333;e.ring=333;e.cedilla=333;e.hungarumlaut=333;e.ogonek=333;e.caron=333;e.emdash=1e3;e.AE=944;e.ordfeminine=266;e.Lslash=611;e.Oslash=722;e.OE=944;e.ordmasculine=300;e.ae=722;e.dotlessi=278;e.lslash=278;e.oslash=500;e.oe=722;e.germandbls=500;e.Idieresis=389;e.eacute=444;e.abreve=500;e.uhungarumlaut=556;e.ecaron=444;e.Ydieresis=611;e.divide=570;e.Yacute=611;e.Acircumflex=667;e.aacute=500;e.Ucircumflex=722;e.yacute=444;e.scommaaccent=389;e.ecircumflex=444;e.Uring=722;e.Udieresis=722;e.aogonek=500;e.Uacute=722;e.uogonek=556;e.Edieresis=667;e.Dcroat=722;e.commaaccent=250;e.copyright=747;e.Emacron=667;e.ccaron=444;e.aring=500;e.Ncommaaccent=722;e.lacute=278;e.agrave=500;e.Tcommaaccent=611;e.Cacute=667;e.atilde=500;e.Edotaccent=667;e.scaron=389;e.scedilla=389;e.iacute=278;e.lozenge=494;e.Rcaron=667;e.Gcommaaccent=722;e.ucircumflex=556;e.acircumflex=500;e.Amacron=667;e.rcaron=389;e.ccedilla=444;e.Zdotaccent=611;e.Thorn=611;e.Omacron=722;e.Racute=667;e.Sacute=556;e.dcaron=608;e.Umacron=722;e.uring=556;e.threesuperior=300;e.Ograve=722;e.Agrave=667;e.Abreve=667;e.multiply=570;e.uacute=556;e.Tcaron=611;e.partialdiff=494;e.ydieresis=444;e.Nacute=722;e.icircumflex=278;e.Ecircumflex=667;e.adieresis=500;e.edieresis=444;e.cacute=444;e.nacute=556;e.umacron=556;e.Ncaron=722;e.Iacute=389;e.plusminus=570;e.brokenbar=220;e.registered=747;e.Gbreve=722;e.Idotaccent=389;e.summation=600;e.Egrave=667;e.racute=389;e.omacron=500;e.Zacute=611;e.Zcaron=611;e.greaterequal=549;e.Eth=722;e.Ccedilla=667;e.lcommaaccent=278;e.tcaron=366;e.eogonek=444;e.Uogonek=722;e.Aacute=667;e.Adieresis=667;e.egrave=444;e.zacute=389;e.iogonek=278;e.Oacute=722;e.oacute=500;e.amacron=500;e.sacute=389;e.idieresis=278;e.Ocircumflex=722;e.Ugrave=722;e.Delta=612;e.thorn=500;e.twosuperior=300;e.Odieresis=722;e.mu=576;e.igrave=278;e.ohungarumlaut=500;e.Eogonek=667;e.dcroat=500;e.threequarters=750;e.Scedilla=556;e.lcaron=382;e.Kcommaaccent=667;e.Lacute=611;e.trademark=1e3;e.edotaccent=444;e.Igrave=389;e.Imacron=389;e.Lcaron=611;e.onehalf=750;e.lessequal=549;e.ocircumflex=500;e.ntilde=556;e.Uhungarumlaut=722;e.Eacute=667;e.emacron=444;e.gbreve=500;e.onequarter=750;e.Scaron=556;e.Scommaaccent=556;e.Ohungarumlaut=722;e.degree=400;e.ograve=500;e.Ccaron=667;e.ugrave=556;e.radical=549;e.Dcaron=722;e.rcommaaccent=389;e.Ntilde=722;e.otilde=500;e.Rcommaaccent=667;e.Lcommaaccent=611;e.Atilde=667;e.Aogonek=667;e.Aring=667;e.Otilde=722;e.zdotaccent=389;e.Ecaron=667;e.Iogonek=389;e.kcommaaccent=500;e.minus=606;e.Icircumflex=389;e.ncaron=556;e.tcommaaccent=278;e.logicalnot=606;e.odieresis=500;e.udieresis=556;e.notequal=549;e.gcommaaccent=500;e.eth=500;e.zcaron=389;e.ncommaaccent=556;e.onesuperior=300;e.imacron=278;e.Euro=500}));e["Times-Italic"]=getLookupTableFactory((function(e){e.space=250;e.exclam=333;e.quotedbl=420;e.numbersign=500;e.dollar=500;e.percent=833;e.ampersand=778;e.quoteright=333;e.parenleft=333;e.parenright=333;e.asterisk=500;e.plus=675;e.comma=250;e.hyphen=333;e.period=250;e.slash=278;e.zero=500;e.one=500;e.two=500;e.three=500;e.four=500;e.five=500;e.six=500;e.seven=500;e.eight=500;e.nine=500;e.colon=333;e.semicolon=333;e.less=675;e.equal=675;e.greater=675;e.question=500;e.at=920;e.A=611;e.B=611;e.C=667;e.D=722;e.E=611;e.F=611;e.G=722;e.H=722;e.I=333;e.J=444;e.K=667;e.L=556;e.M=833;e.N=667;e.O=722;e.P=611;e.Q=722;e.R=611;e.S=500;e.T=556;e.U=722;e.V=611;e.W=833;e.X=611;e.Y=556;e.Z=556;e.bracketleft=389;e.backslash=278;e.bracketright=389;e.asciicircum=422;e.underscore=500;e.quoteleft=333;e.a=500;e.b=500;e.c=444;e.d=500;e.e=444;e.f=278;e.g=500;e.h=500;e.i=278;e.j=278;e.k=444;e.l=278;e.m=722;e.n=500;e.o=500;e.p=500;e.q=500;e.r=389;e.s=389;e.t=278;e.u=500;e.v=444;e.w=667;e.x=444;e.y=444;e.z=389;e.braceleft=400;e.bar=275;e.braceright=400;e.asciitilde=541;e.exclamdown=389;e.cent=500;e.sterling=500;e.fraction=167;e.yen=500;e.florin=500;e.section=500;e.currency=500;e.quotesingle=214;e.quotedblleft=556;e.guillemotleft=500;e.guilsinglleft=333;e.guilsinglright=333;e.fi=500;e.fl=500;e.endash=500;e.dagger=500;e.daggerdbl=500;e.periodcentered=250;e.paragraph=523;e.bullet=350;e.quotesinglbase=333;e.quotedblbase=556;e.quotedblright=556;e.guillemotright=500;e.ellipsis=889;e.perthousand=1e3;e.questiondown=500;e.grave=333;e.acute=333;e.circumflex=333;e.tilde=333;e.macron=333;e.breve=333;e.dotaccent=333;e.dieresis=333;e.ring=333;e.cedilla=333;e.hungarumlaut=333;e.ogonek=333;e.caron=333;e.emdash=889;e.AE=889;e.ordfeminine=276;e.Lslash=556;e.Oslash=722;e.OE=944;e.ordmasculine=310;e.ae=667;e.dotlessi=278;e.lslash=278;e.oslash=500;e.oe=667;e.germandbls=500;e.Idieresis=333;e.eacute=444;e.abreve=500;e.uhungarumlaut=500;e.ecaron=444;e.Ydieresis=556;e.divide=675;e.Yacute=556;e.Acircumflex=611;e.aacute=500;e.Ucircumflex=722;e.yacute=444;e.scommaaccent=389;e.ecircumflex=444;e.Uring=722;e.Udieresis=722;e.aogonek=500;e.Uacute=722;e.uogonek=500;e.Edieresis=611;e.Dcroat=722;e.commaaccent=250;e.copyright=760;e.Emacron=611;e.ccaron=444;e.aring=500;e.Ncommaaccent=667;e.lacute=278;e.agrave=500;e.Tcommaaccent=556;e.Cacute=667;e.atilde=500;e.Edotaccent=611;e.scaron=389;e.scedilla=389;e.iacute=278;e.lozenge=471;e.Rcaron=611;e.Gcommaaccent=722;e.ucircumflex=500;e.acircumflex=500;e.Amacron=611;e.rcaron=389;e.ccedilla=444;e.Zdotaccent=556;e.Thorn=611;e.Omacron=722;e.Racute=611;e.Sacute=500;e.dcaron=544;e.Umacron=722;e.uring=500;e.threesuperior=300;e.Ograve=722;e.Agrave=611;e.Abreve=611;e.multiply=675;e.uacute=500;e.Tcaron=556;e.partialdiff=476;e.ydieresis=444;e.Nacute=667;e.icircumflex=278;e.Ecircumflex=611;e.adieresis=500;e.edieresis=444;e.cacute=444;e.nacute=500;e.umacron=500;e.Ncaron=667;e.Iacute=333;e.plusminus=675;e.brokenbar=275;e.registered=760;e.Gbreve=722;e.Idotaccent=333;e.summation=600;e.Egrave=611;e.racute=389;e.omacron=500;e.Zacute=556;e.Zcaron=556;e.greaterequal=549;e.Eth=722;e.Ccedilla=667;e.lcommaaccent=278;e.tcaron=300;e.eogonek=444;e.Uogonek=722;e.Aacute=611;e.Adieresis=611;e.egrave=444;e.zacute=389;e.iogonek=278;e.Oacute=722;e.oacute=500;e.amacron=500;e.sacute=389;e.idieresis=278;e.Ocircumflex=722;e.Ugrave=722;e.Delta=612;e.thorn=500;e.twosuperior=300;e.Odieresis=722;e.mu=500;e.igrave=278;e.ohungarumlaut=500;e.Eogonek=611;e.dcroat=500;e.threequarters=750;e.Scedilla=500;e.lcaron=300;e.Kcommaaccent=667;e.Lacute=556;e.trademark=980;e.edotaccent=444;e.Igrave=333;e.Imacron=333;e.Lcaron=611;e.onehalf=750;e.lessequal=549;e.ocircumflex=500;e.ntilde=500;e.Uhungarumlaut=722;e.Eacute=611;e.emacron=444;e.gbreve=500;e.onequarter=750;e.Scaron=500;e.Scommaaccent=500;e.Ohungarumlaut=722;e.degree=400;e.ograve=500;e.Ccaron=667;e.ugrave=500;e.radical=453;e.Dcaron=722;e.rcommaaccent=389;e.Ntilde=667;e.otilde=500;e.Rcommaaccent=611;e.Lcommaaccent=556;e.Atilde=611;e.Aogonek=611;e.Aring=611;e.Otilde=722;e.zdotaccent=389;e.Ecaron=611;e.Iogonek=333;e.kcommaaccent=444;e.minus=675;e.Icircumflex=333;e.ncaron=500;e.tcommaaccent=278;e.logicalnot=675;e.odieresis=500;e.udieresis=500;e.notequal=549;e.gcommaaccent=500;e.eth=500;e.zcaron=389;e.ncommaaccent=500;e.onesuperior=300;e.imacron=278;e.Euro=500}));e.ZapfDingbats=getLookupTableFactory((function(e){e.space=278;e.a1=974;e.a2=961;e.a202=974;e.a3=980;e.a4=719;e.a5=789;e.a119=790;e.a118=791;e.a117=690;e.a11=960;e.a12=939;e.a13=549;e.a14=855;e.a15=911;e.a16=933;e.a105=911;e.a17=945;e.a18=974;e.a19=755;e.a20=846;e.a21=762;e.a22=761;e.a23=571;e.a24=677;e.a25=763;e.a26=760;e.a27=759;e.a28=754;e.a6=494;e.a7=552;e.a8=537;e.a9=577;e.a10=692;e.a29=786;e.a30=788;e.a31=788;e.a32=790;e.a33=793;e.a34=794;e.a35=816;e.a36=823;e.a37=789;e.a38=841;e.a39=823;e.a40=833;e.a41=816;e.a42=831;e.a43=923;e.a44=744;e.a45=723;e.a46=749;e.a47=790;e.a48=792;e.a49=695;e.a50=776;e.a51=768;e.a52=792;e.a53=759;e.a54=707;e.a55=708;e.a56=682;e.a57=701;e.a58=826;e.a59=815;e.a60=789;e.a61=789;e.a62=707;e.a63=687;e.a64=696;e.a65=689;e.a66=786;e.a67=787;e.a68=713;e.a69=791;e.a70=785;e.a71=791;e.a72=873;e.a73=761;e.a74=762;e.a203=762;e.a75=759;e.a204=759;e.a76=892;e.a77=892;e.a78=788;e.a79=784;e.a81=438;e.a82=138;e.a83=277;e.a84=415;e.a97=392;e.a98=392;e.a99=668;e.a100=668;e.a89=390;e.a90=390;e.a93=317;e.a94=317;e.a91=276;e.a92=276;e.a205=509;e.a85=509;e.a206=410;e.a86=410;e.a87=234;e.a88=234;e.a95=334;e.a96=334;e.a101=732;e.a102=544;e.a103=544;e.a104=910;e.a106=667;e.a107=760;e.a108=760;e.a112=776;e.a111=595;e.a110=694;e.a109=626;e.a120=788;e.a121=788;e.a122=788;e.a123=788;e.a124=788;e.a125=788;e.a126=788;e.a127=788;e.a128=788;e.a129=788;e.a130=788;e.a131=788;e.a132=788;e.a133=788;e.a134=788;e.a135=788;e.a136=788;e.a137=788;e.a138=788;e.a139=788;e.a140=788;e.a141=788;e.a142=788;e.a143=788;e.a144=788;e.a145=788;e.a146=788;e.a147=788;e.a148=788;e.a149=788;e.a150=788;e.a151=788;e.a152=788;e.a153=788;e.a154=788;e.a155=788;e.a156=788;e.a157=788;e.a158=788;e.a159=788;e.a160=894;e.a161=838;e.a163=1016;e.a164=458;e.a196=748;e.a165=924;e.a192=748;e.a166=918;e.a167=927;e.a168=928;e.a169=928;e.a170=834;e.a171=873;e.a172=828;e.a173=924;e.a162=924;e.a174=917;e.a175=930;e.a176=931;e.a177=463;e.a178=883;e.a179=836;e.a193=836;e.a180=867;e.a199=867;e.a181=696;e.a200=696;e.a182=874;e.a201=874;e.a183=760;e.a184=946;e.a197=771;e.a185=865;e.a194=771;e.a198=888;e.a186=967;e.a195=888;e.a187=831;e.a188=873;e.a189=927;e.a190=970;e.a191=918}))})),ea=getLookupTableFactory((function(e){e.Courier={ascent:629,descent:-157,capHeight:562,xHeight:-426};e["Courier-Bold"]={ascent:629,descent:-157,capHeight:562,xHeight:439};e["Courier-Oblique"]={ascent:629,descent:-157,capHeight:562,xHeight:426};e["Courier-BoldOblique"]={ascent:629,descent:-157,capHeight:562,xHeight:426};e.Helvetica={ascent:718,descent:-207,capHeight:718,xHeight:523};e["Helvetica-Bold"]={ascent:718,descent:-207,capHeight:718,xHeight:532};e["Helvetica-Oblique"]={ascent:718,descent:-207,capHeight:718,xHeight:523};e["Helvetica-BoldOblique"]={ascent:718,descent:-207,capHeight:718,xHeight:532};e["Times-Roman"]={ascent:683,descent:-217,capHeight:662,xHeight:450};e["Times-Bold"]={ascent:683,descent:-217,capHeight:676,xHeight:461};e["Times-Italic"]={ascent:683,descent:-217,capHeight:653,xHeight:441};e["Times-BoldItalic"]={ascent:683,descent:-217,capHeight:669,xHeight:462};e.Symbol={ascent:Math.NaN,descent:Math.NaN,capHeight:Math.NaN,xHeight:Math.NaN};e.ZapfDingbats={ascent:Math.NaN,descent:Math.NaN,capHeight:Math.NaN,xHeight:Math.NaN}}));class GlyfTable{constructor({glyfTable:e,isGlyphLocationsLong:t,locaTable:i,numGlyphs:a}){this.glyphs=[];const s=new DataView(i.buffer,i.byteOffset,i.byteLength),r=new DataView(e.buffer,e.byteOffset,e.byteLength),n=t?4:2;let o=t?s.getUint32(0):2*s.getUint16(0),g=0;for(let e=0;e<a;e++){g+=n;const e=t?s.getUint32(g):2*s.getUint16(g);if(e===o){this.glyphs.push(new Glyph({}));continue}const i=Glyph.parse(o,r);this.glyphs.push(i);o=e}}getSize(){return this.glyphs.reduce(((e,t)=>e+(t.getSize()+3&-4)),0)}write(){const e=this.getSize(),t=new DataView(new ArrayBuffer(e)),i=e>131070,a=i?4:2,s=new DataView(new ArrayBuffer((this.glyphs.length+1)*a));i?s.setUint32(0,0):s.setUint16(0,0);let r=0,n=0;for(const e of this.glyphs){r+=e.write(r,t);r=r+3&-4;n+=a;i?s.setUint32(n,r):s.setUint16(n,r>>1)}return{isLocationLong:i,loca:new Uint8Array(s.buffer),glyf:new Uint8Array(t.buffer)}}scale(e){for(let t=0,i=this.glyphs.length;t<i;t++)this.glyphs[t].scale(e[t])}}class Glyph{constructor({header:e=null,simple:t=null,composites:i=null}){this.header=e;this.simple=t;this.composites=i}static parse(e,t){const[i,a]=GlyphHeader.parse(e,t);e+=i;if(a.numberOfContours<0){const i=[];for(;;){const[a,s]=CompositeGlyph.parse(e,t);e+=a;i.push(s);if(!(32&s.flags))break}return new Glyph({header:a,composites:i})}const s=SimpleGlyph.parse(e,t,a.numberOfContours);return new Glyph({header:a,simple:s})}getSize(){if(!this.header)return 0;const e=this.simple?this.simple.getSize():this.composites.reduce(((e,t)=>e+t.getSize()),0);return this.header.getSize()+e}write(e,t){if(!this.header)return 0;const i=e;e+=this.header.write(e,t);if(this.simple)e+=this.simple.write(e,t);else for(const i of this.composites)e+=i.write(e,t);return e-i}scale(e){if(!this.header)return;const t=(this.header.xMin+this.header.xMax)/2;this.header.scale(t,e);if(this.simple)this.simple.scale(t,e);else for(const i of this.composites)i.scale(t,e)}}class GlyphHeader{constructor({numberOfContours:e,xMin:t,yMin:i,xMax:a,yMax:s}){this.numberOfContours=e;this.xMin=t;this.yMin=i;this.xMax=a;this.yMax=s}static parse(e,t){return[10,new GlyphHeader({numberOfContours:t.getInt16(e),xMin:t.getInt16(e+2),yMin:t.getInt16(e+4),xMax:t.getInt16(e+6),yMax:t.getInt16(e+8)})]}getSize(){return 10}write(e,t){t.setInt16(e,this.numberOfContours);t.setInt16(e+2,this.xMin);t.setInt16(e+4,this.yMin);t.setInt16(e+6,this.xMax);t.setInt16(e+8,this.yMax);return 10}scale(e,t){this.xMin=Math.round(e+(this.xMin-e)*t);this.xMax=Math.round(e+(this.xMax-e)*t)}}class Contour{constructor({flags:e,xCoordinates:t,yCoordinates:i}){this.xCoordinates=t;this.yCoordinates=i;this.flags=e}}class SimpleGlyph{constructor({contours:e,instructions:t}){this.contours=e;this.instructions=t}static parse(e,t,i){const a=[];for(let s=0;s<i;s++){const i=t.getUint16(e);e+=2;a.push(i)}const s=a[i-1]+1,r=t.getUint16(e);e+=2;const n=new Uint8Array(t).slice(e,e+r);e+=r;const o=[];for(let i=0;i<s;e++,i++){let a=t.getUint8(e);o.push(a);if(8&a){const s=t.getUint8(++e);a^=8;for(let e=0;e<s;e++)o.push(a);i+=s}}const g=[];let c=[],h=[],l=[];const C=[];let Q=0,E=0;for(let i=0;i<s;i++){const s=o[i];if(2&s){const i=t.getUint8(e++);E+=16&s?i:-i;c.push(E)}else if(16&s)c.push(E);else{E+=t.getInt16(e);e+=2;c.push(E)}if(a[Q]===i){Q++;g.push(c);c=[]}}E=0;Q=0;for(let i=0;i<s;i++){const s=o[i];if(4&s){const i=t.getUint8(e++);E+=32&s?i:-i;h.push(E)}else if(32&s)h.push(E);else{E+=t.getInt16(e);e+=2;h.push(E)}l.push(1&s|64&s);if(a[Q]===i){c=g[Q];Q++;C.push(new Contour({flags:l,xCoordinates:c,yCoordinates:h}));h=[];l=[]}}return new SimpleGlyph({contours:C,instructions:n})}getSize(){let e=2*this.contours.length+2+this.instructions.length,t=0,i=0;for(const a of this.contours){e+=a.flags.length;for(let s=0,r=a.xCoordinates.length;s<r;s++){const r=a.xCoordinates[s],n=a.yCoordinates[s];let o=Math.abs(r-t);o>255?e+=2:o>0&&(e+=1);t=r;o=Math.abs(n-i);o>255?e+=2:o>0&&(e+=1);i=n}}return e}write(e,t){const i=e,a=[],s=[],r=[];let n=0,o=0;for(const i of this.contours){for(let e=0,t=i.xCoordinates.length;e<t;e++){let t=i.flags[e];const g=i.xCoordinates[e];let c=g-n;if(0===c){t|=16;a.push(0)}else{const e=Math.abs(c);if(e<=255){t|=c>=0?18:2;a.push(e)}else a.push(c)}n=g;const h=i.yCoordinates[e];c=h-o;if(0===c){t|=32;s.push(0)}else{const e=Math.abs(c);if(e<=255){t|=c>=0?36:4;s.push(e)}else s.push(c)}o=h;r.push(t)}t.setUint16(e,a.length-1);e+=2}t.setUint16(e,this.instructions.length);e+=2;if(this.instructions.length){new Uint8Array(t.buffer,0,t.buffer.byteLength).set(this.instructions,e);e+=this.instructions.length}for(const i of r)t.setUint8(e++,i);for(let i=0,s=a.length;i<s;i++){const s=a[i],n=r[i];if(2&n)t.setUint8(e++,s);else if(!(16&n)){t.setInt16(e,s);e+=2}}for(let i=0,a=s.length;i<a;i++){const a=s[i],n=r[i];if(4&n)t.setUint8(e++,a);else if(!(32&n)){t.setInt16(e,a);e+=2}}return e-i}scale(e,t){for(const i of this.contours)if(0!==i.xCoordinates.length)for(let a=0,s=i.xCoordinates.length;a<s;a++)i.xCoordinates[a]=Math.round(e+(i.xCoordinates[a]-e)*t)}}class CompositeGlyph{constructor({flags:e,glyphIndex:t,argument1:i,argument2:a,transf:s,instructions:r}){this.flags=e;this.glyphIndex=t;this.argument1=i;this.argument2=a;this.transf=s;this.instructions=r}static parse(e,t){const i=e,a=[];let s=t.getUint16(e);const r=t.getUint16(e+2);e+=4;let n,o;if(1&s){if(2&s){n=t.getInt16(e);o=t.getInt16(e+2)}else{n=t.getUint16(e);o=t.getUint16(e+2)}e+=4;s^=1}else{if(2&s){n=t.getInt8(e);o=t.getInt8(e+1)}else{n=t.getUint8(e);o=t.getUint8(e+1)}e+=2}if(8&s){a.push(t.getUint16(e));e+=2}else if(64&s){a.push(t.getUint16(e),t.getUint16(e+2));e+=4}else if(128&s){a.push(t.getUint16(e),t.getUint16(e+2),t.getUint16(e+4),t.getUint16(e+6));e+=8}let g=null;if(256&s){const i=t.getUint16(e);e+=2;g=new Uint8Array(t).slice(e,e+i);e+=i}return[e-i,new CompositeGlyph({flags:s,glyphIndex:r,argument1:n,argument2:o,transf:a,instructions:g})]}getSize(){let e=4+2*this.transf.length;256&this.flags&&(e+=2+this.instructions.length);e+=2;2&this.flags?this.argument1>=-128&&this.argument1<=127&&this.argument2>=-128&&this.argument2<=127||(e+=2):this.argument1>=0&&this.argument1<=255&&this.argument2>=0&&this.argument2<=255||(e+=2);return e}write(e,t){const i=e;2&this.flags?this.argument1>=-128&&this.argument1<=127&&this.argument2>=-128&&this.argument2<=127||(this.flags|=1):this.argument1>=0&&this.argument1<=255&&this.argument2>=0&&this.argument2<=255||(this.flags|=1);t.setUint16(e,this.flags);t.setUint16(e+2,this.glyphIndex);e+=4;if(1&this.flags){if(2&this.flags){t.setInt16(e,this.argument1);t.setInt16(e+2,this.argument2)}else{t.setUint16(e,this.argument1);t.setUint16(e+2,this.argument2)}e+=4}else{t.setUint8(e,this.argument1);t.setUint8(e+1,this.argument2);e+=2}if(256&this.flags){t.setUint16(e,this.instructions.length);e+=2;if(this.instructions.length){new Uint8Array(t.buffer,0,t.buffer.byteLength).set(this.instructions,e);e+=this.instructions.length}}return e-i}scale(e,t){}}function writeInt16(e,t,i){e[t]=i>>8&255;e[t+1]=255&i}function writeInt32(e,t,i){e[t]=i>>24&255;e[t+1]=i>>16&255;e[t+2]=i>>8&255;e[t+3]=255&i}function writeData(e,t,i){if(i instanceof Uint8Array)e.set(i,t);else if("string"==typeof i)for(let a=0,s=i.length;a<s;a++)e[t++]=255&i.charCodeAt(a);else for(const a of i)e[t++]=255&a}class OpenTypeFileBuilder{constructor(e){this.sfnt=e;this.tables=Object.create(null)}static getSearchParams(e,t){let i=1,a=0;for(;(i^e)>i;){i<<=1;a++}const s=i*t;return{range:s,entry:a,rangeShift:t*e-s}}toArray(){let e=this.sfnt;const t=this.tables,i=Object.keys(t);i.sort();const a=i.length;let s,r,n,o,g,c=12+16*a;const h=[c];for(s=0;s<a;s++){o=t[i[s]];c+=(o.length+3&-4)>>>0;h.push(c)}const l=new Uint8Array(c);for(s=0;s<a;s++){o=t[i[s]];writeData(l,h[s],o)}"true"===e&&(e=string32(65536));l[0]=255&e.charCodeAt(0);l[1]=255&e.charCodeAt(1);l[2]=255&e.charCodeAt(2);l[3]=255&e.charCodeAt(3);writeInt16(l,4,a);const C=OpenTypeFileBuilder.getSearchParams(a,16);writeInt16(l,6,C.range);writeInt16(l,8,C.entry);writeInt16(l,10,C.rangeShift);c=12;for(s=0;s<a;s++){g=i[s];l[c]=255&g.charCodeAt(0);l[c+1]=255&g.charCodeAt(1);l[c+2]=255&g.charCodeAt(2);l[c+3]=255&g.charCodeAt(3);let e=0;for(r=h[s],n=h[s+1];r<n;r+=4){e=e+readUint32(l,r)>>>0}writeInt32(l,c+4,e);writeInt32(l,c+8,h[s]);writeInt32(l,c+12,t[g].length);c+=16}return l}addTable(e,t){if(e in this.tables)throw new Error("Table "+e+" already exists");this.tables[e]=t}}const ta=[4],ia=[5],aa=[6],sa=[7],ra=[8],na=[12,35],oa=[14],ga=[21],Ia=[22],ca=[30],ha=[31];class Type1CharString{constructor(){this.width=0;this.lsb=0;this.flexing=!1;this.output=[];this.stack=[]}convert(e,t,i){const a=e.length;let s,r,n,o=!1;for(let g=0;g<a;g++){let a=e[g];if(a<32){12===a&&(a=(a<<8)+e[++g]);switch(a){case 1:case 3:case 9:case 3072:case 3073:case 3074:case 3105:this.stack=[];break;case 4:if(this.flexing){if(this.stack.length<1){o=!0;break}const e=this.stack.pop();this.stack.push(0,e);break}o=this.executeCommand(1,ta);break;case 5:o=this.executeCommand(2,ia);break;case 6:o=this.executeCommand(1,aa);break;case 7:o=this.executeCommand(1,sa);break;case 8:o=this.executeCommand(6,ra);break;case 10:if(this.stack.length<1){o=!0;break}n=this.stack.pop();if(!t[n]){o=!0;break}o=this.convert(t[n],t,i);break;case 11:return o;case 13:if(this.stack.length<2){o=!0;break}s=this.stack.pop();r=this.stack.pop();this.lsb=r;this.width=s;this.stack.push(s,r);o=this.executeCommand(2,Ia);break;case 14:this.output.push(oa[0]);break;case 21:if(this.flexing)break;o=this.executeCommand(2,ga);break;case 22:if(this.flexing){this.stack.push(0);break}o=this.executeCommand(1,Ia);break;case 30:o=this.executeCommand(4,ca);break;case 31:o=this.executeCommand(4,ha);break;case 3078:if(i){const e=this.stack.at(-5);this.seac=this.stack.splice(-4,4);this.seac[0]+=this.lsb-e;o=this.executeCommand(0,oa)}else o=this.executeCommand(4,oa);break;case 3079:if(this.stack.length<4){o=!0;break}this.stack.pop();s=this.stack.pop();const e=this.stack.pop();r=this.stack.pop();this.lsb=r;this.width=s;this.stack.push(s,r,e);o=this.executeCommand(3,ga);break;case 3084:if(this.stack.length<2){o=!0;break}const g=this.stack.pop(),c=this.stack.pop();this.stack.push(c/g);break;case 3088:if(this.stack.length<2){o=!0;break}n=this.stack.pop();const h=this.stack.pop();if(0===n&&3===h){const e=this.stack.splice(-17,17);this.stack.push(e[2]+e[0],e[3]+e[1],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14]);o=this.executeCommand(13,na,!0);this.flexing=!1;this.stack.push(e[15],e[16])}else 1===n&&0===h&&(this.flexing=!0);break;case 3089:break;default:warn('Unknown type 1 charstring command of "'+a+'"')}if(o)break}else{a<=246?a-=139:a=a<=250?256*(a-247)+e[++g]+108:a<=254?-256*(a-251)-e[++g]-108:(255&e[++g])<<24|(255&e[++g])<<16|(255&e[++g])<<8|(255&e[++g])<<0;this.stack.push(a)}}return o}executeCommand(e,t,i){const a=this.stack.length;if(e>a)return!0;const s=a-e;for(let e=s;e<a;e++){let t=this.stack[e];if(Number.isInteger(t))this.output.push(28,t>>8&255,255&t);else{t=65536*t|0;this.output.push(255,t>>24&255,t>>16&255,t>>8&255,255&t)}}this.output.push(...t);i?this.stack.splice(s,e):this.stack.length=0;return!1}}function isHexDigit(e){return e>=48&&e<=57||e>=65&&e<=70||e>=97&&e<=102}function decrypt(e,t,i){if(i>=e.length)return new Uint8Array(0);let a,s,r=0|t;for(a=0;a<i;a++)r=52845*(e[a]+r)+22719&65535;const n=e.length-i,o=new Uint8Array(n);for(a=i,s=0;s<n;a++,s++){const t=e[a];o[s]=t^r>>8;r=52845*(t+r)+22719&65535}return o}function isSpecial(e){return 47===e||91===e||93===e||123===e||125===e||40===e||41===e}class Type1Parser{constructor(e,t,i){if(t){const t=e.getBytes(),i=!((isHexDigit(t[0])||isWhiteSpace(t[0]))&&isHexDigit(t[1])&&isHexDigit(t[2])&&isHexDigit(t[3])&&isHexDigit(t[4])&&isHexDigit(t[5])&&isHexDigit(t[6])&&isHexDigit(t[7]));e=new Stream(i?decrypt(t,55665,4):function decryptAscii(e,t,i){let a=0|t;const s=e.length,r=new Uint8Array(s>>>1);let n,o;for(n=0,o=0;n<s;n++){const t=e[n];if(!isHexDigit(t))continue;n++;let i;for(;n<s&&!isHexDigit(i=e[n]);)n++;if(n<s){const e=parseInt(String.fromCharCode(t,i),16);r[o++]=e^a>>8;a=52845*(e+a)+22719&65535}}return r.slice(i,o)}(t,55665,4))}this.seacAnalysisEnabled=!!i;this.stream=e;this.nextChar()}readNumberArray(){this.getToken();const e=[];for(;;){const t=this.getToken();if(null===t||"]"===t||"}"===t)break;e.push(parseFloat(t||0))}return e}readNumber(){const e=this.getToken();return parseFloat(e||0)}readInt(){const e=this.getToken();return 0|parseInt(e||0,10)}readBoolean(){return"true"===this.getToken()?1:0}nextChar(){return this.currentChar=this.stream.getByte()}prevChar(){this.stream.skip(-2);return this.currentChar=this.stream.getByte()}getToken(){let e=!1,t=this.currentChar;for(;;){if(-1===t)return null;if(e)10!==t&&13!==t||(e=!1);else if(37===t)e=!0;else if(!isWhiteSpace(t))break;t=this.nextChar()}if(isSpecial(t)){this.nextChar();return String.fromCharCode(t)}let i="";do{i+=String.fromCharCode(t);t=this.nextChar()}while(t>=0&&!isWhiteSpace(t)&&!isSpecial(t));return i}readCharStrings(e,t){return-1===t?e:decrypt(e,4330,t)}extractFontProgram(e){const t=this.stream,i=[],a=[],s=Object.create(null);s.lenIV=4;const r={subrs:[],charstrings:[],properties:{privateData:s}};let n,o,g,c;for(;null!==(n=this.getToken());)if("/"===n){n=this.getToken();switch(n){case"CharStrings":this.getToken();this.getToken();this.getToken();this.getToken();for(;;){n=this.getToken();if(null===n||"end"===n)break;if("/"!==n)continue;const e=this.getToken();o=this.readInt();this.getToken();g=o>0?t.getBytes(o):new Uint8Array(0);c=r.properties.privateData.lenIV;const i=this.readCharStrings(g,c);this.nextChar();n=this.getToken();"noaccess"===n?this.getToken():"/"===n&&this.prevChar();a.push({glyph:e,encoded:i})}break;case"Subrs":this.readInt();this.getToken();for(;"dup"===this.getToken();){const e=this.readInt();o=this.readInt();this.getToken();g=o>0?t.getBytes(o):new Uint8Array(0);c=r.properties.privateData.lenIV;const a=this.readCharStrings(g,c);this.nextChar();n=this.getToken();"noaccess"===n&&this.getToken();i[e]=a}break;case"BlueValues":case"OtherBlues":case"FamilyBlues":case"FamilyOtherBlues":const e=this.readNumberArray();e.length>0&&e.length,0;break;case"StemSnapH":case"StemSnapV":r.properties.privateData[n]=this.readNumberArray();break;case"StdHW":case"StdVW":r.properties.privateData[n]=this.readNumberArray()[0];break;case"BlueShift":case"lenIV":case"BlueFuzz":case"BlueScale":case"LanguageGroup":r.properties.privateData[n]=this.readNumber();break;case"ExpansionFactor":r.properties.privateData[n]=this.readNumber()||.06;break;case"ForceBold":r.properties.privateData[n]=this.readBoolean()}}for(const{encoded:t,glyph:s}of a){const a=new Type1CharString,n=a.convert(t,i,this.seacAnalysisEnabled);let o=a.output;n&&(o=[14]);const g={glyphName:s,charstring:o,width:a.width,lsb:a.lsb,seac:a.seac};".notdef"===s?r.charstrings.unshift(g):r.charstrings.push(g);if(e.builtInEncoding){const t=e.builtInEncoding.indexOf(s);t>-1&&void 0===e.widths[t]&&t>=e.firstChar&&t<=e.lastChar&&(e.widths[t]=a.width)}}return r}extractFontHeader(e){let t;for(;null!==(t=this.getToken());)if("/"===t){t=this.getToken();switch(t){case"FontMatrix":const i=this.readNumberArray();e.fontMatrix=i;break;case"Encoding":const a=this.getToken();let s;if(/^\d+$/.test(a)){s=[];const e=0|parseInt(a,10);this.getToken();for(let i=0;i<e;i++){t=this.getToken();for(;"dup"!==t&&"def"!==t;){t=this.getToken();if(null===t)return}if("def"===t)break;const e=this.readInt();this.getToken();const i=this.getToken();s[e]=i;this.getToken()}}else s=getEncoding(a);e.builtInEncoding=s;break;case"FontBBox":const r=this.readNumberArray();e.ascent=Math.max(r[3],r[1]);e.descent=Math.min(r[1],r[3]);e.ascentScaled=!0}}}}function findBlock(e,t,i){const a=e.length,s=t.length,r=a-s;let n=i,o=!1;for(;n<r;){let i=0;for(;i<s&&e[n+i]===t[i];)i++;if(i>=s){n+=i;for(;n<a&&isWhiteSpace(e[n]);)n++;o=!0;break}n++}return{found:o,length:n}}class Type1Font{constructor(e,t,i){let a=i.length1,s=i.length2,r=t.peekBytes(6);const n=128===r[0]&&1===r[1];if(n){t.skip(6);a=r[5]<<24|r[4]<<16|r[3]<<8|r[2]}const o=function getHeaderBlock(e,t){const i=[101,101,120,101,99],a=e.pos;let s,r,n,o;try{s=e.getBytes(t);r=s.length}catch{}if(r===t){n=findBlock(s,i,t-2*i.length);if(n.found&&n.length===t)return{stream:new Stream(s),length:t}}warn('Invalid "Length1" property in Type1 font -- trying to recover.');e.pos=a;for(;;){n=findBlock(e.peekBytes(2048),i,0);if(0===n.length)break;e.pos+=n.length;if(n.found){o=e.pos-a;break}}e.pos=a;if(o)return{stream:new Stream(e.getBytes(o)),length:o};warn('Unable to recover "Length1" property in Type1 font -- using as is.');return{stream:new Stream(e.getBytes(t)),length:t}}(t,a);new Type1Parser(o.stream,!1,Yi).extractFontHeader(i);if(n){r=t.getBytes(6);s=r[5]<<24|r[4]<<16|r[3]<<8|r[2]}const g=function getEexecBlock(e,t){const i=e.getBytes();if(0===i.length)throw new FormatError("getEexecBlock - no font program found.");return{stream:new Stream(i),length:i.length}}(t),c=new Type1Parser(g.stream,!0,Yi).extractFontProgram(i);for(const e in c.properties)i[e]=c.properties[e];const h=c.charstrings,l=this.getType2Charstrings(h),C=this.getType2Subrs(c.subrs);this.charstrings=h;this.data=this.wrap(e,l,this.charstrings,C,i);this.seacs=this.getSeacs(c.charstrings)}get numGlyphs(){return this.charstrings.length+1}getCharset(){const e=[".notdef"];for(const{glyphName:t}of this.charstrings)e.push(t);return e}getGlyphMapping(e){const t=this.charstrings;if(e.composite){const i=Object.create(null);for(let a=0,s=t.length;a<s;a++){i[e.cMap.charCodeOf(a)]=a+1}return i}const i=[".notdef"];let a,s;for(s=0;s<t.length;s++)i.push(t[s].glyphName);const r=e.builtInEncoding;if(r){a=Object.create(null);for(const e in r){s=i.indexOf(r[e]);s>=0&&(a[e]=s)}}return type1FontGlyphMapping(e,a,i)}hasGlyphId(e){if(e<0||e>=this.numGlyphs)return!1;if(0===e)return!0;return this.charstrings[e-1].charstring.length>0}getSeacs(e){const t=[];for(let i=0,a=e.length;i<a;i++){const a=e[i];a.seac&&(t[i+1]=a.seac)}return t}getType2Charstrings(e){const t=[];for(const i of e)t.push(i.charstring);return t}getType2Subrs(e){let t=0;const i=e.length;t=i<1133?107:i<33769?1131:32768;const a=[];let s;for(s=0;s<t;s++)a.push([11]);for(s=0;s<i;s++)a.push(e[s]);return a}wrap(e,t,i,a,s){const r=new CFF;r.header=new CFFHeader(1,0,4,4);r.names=[e];const n=new CFFTopDict;n.setByName("version",391);n.setByName("Notice",392);n.setByName("FullName",393);n.setByName("FamilyName",394);n.setByName("Weight",395);n.setByName("Encoding",null);n.setByName("FontMatrix",s.fontMatrix);n.setByName("FontBBox",s.bbox);n.setByName("charset",null);n.setByName("CharStrings",null);n.setByName("Private",null);r.topDict=n;const o=new CFFStrings;o.add("Version 0.11");o.add("See original notice");o.add(e);o.add(e);o.add("Medium");r.strings=o;r.globalSubrIndex=new CFFIndex;const g=t.length,c=[".notdef"];let h,l;for(h=0;h<g;h++){const e=i[h].glyphName;-1===wi.indexOf(e)&&o.add(e);c.push(e)}r.charset=new CFFCharset(!1,0,c);const C=new CFFIndex;C.add([139,14]);for(h=0;h<g;h++)C.add(t[h]);r.charStrings=C;const Q=new CFFPrivateDict;Q.setByName("Subrs",null);const E=["BlueValues","OtherBlues","FamilyBlues","FamilyOtherBlues","StemSnapH","StemSnapV","BlueShift","BlueFuzz","BlueScale","LanguageGroup","ExpansionFactor","ForceBold","StdHW","StdVW"];for(h=0,l=E.length;h<l;h++){const e=E[h];if(!(e in s.privateData))continue;const t=s.privateData[e];if(Array.isArray(t))for(let e=t.length-1;e>0;e--)t[e]-=t[e-1];Q.setByName(e,t)}r.topDict.privateDict=Q;const u=new CFFIndex;for(h=0,l=a.length;h<l;h++)u.add(a[h]);Q.subrsIndex=u;return new CFFCompiler(r).compile()}}const la=[[57344,63743],[1048576,1114109]],Ca=1e3,Ba=["ascent","bbox","black","bold","charProcOperatorList","composite","cssFontInfo","data","defaultVMetrics","defaultWidth","descent","fallbackName","fontMatrix","isInvalidPDFjsFont","isType3Font","italic","loadedName","mimetype","missingFile","name","remeasure","subtype","systemFontInfo","type","vertical"],Qa=["cMap","defaultEncoding","differences","isMonospace","isSerifFont","isSymbolicFont","seacMap","toFontChar","toUnicode","vmetrics","widths"];function adjustWidths(e){if(!e.fontMatrix)return;if(e.fontMatrix[0]===a[0])return;const t=.001/e.fontMatrix[0],i=e.widths;for(const e in i)i[e]*=t;e.defaultWidth*=t}function amendFallbackToUnicode(e){if(!e.fallbackToUnicode)return;if(e.toUnicode instanceof IdentityToUnicodeMap)return;const t=[];for(const i in e.fallbackToUnicode)e.toUnicode.has(i)||(t[i]=e.fallbackToUnicode[i]);t.length>0&&e.toUnicode.amend(t)}class fonts_Glyph{constructor(e,t,i,a,s,r,n,o,g){this.originalCharCode=e;this.fontChar=t;this.unicode=i;this.accent=a;this.width=s;this.vmetric=r;this.operatorListId=n;this.isSpace=o;this.isInFont=g}get category(){return shadow(this,"category",function getCharUnicodeCategory(e){const t=Hi.get(e);if(t)return t;const i=e.match(Ji),a={isWhitespace:!!i?.[1],isZeroWidthDiacritic:!!i?.[2],isInvisibleFormatMark:!!i?.[3]};Hi.set(e,a);return a}(this.unicode),!0)}}function int16(e,t){return(e<<8)+t}function writeSignedInt16(e,t,i){e[t+1]=i;e[t]=i>>>8}function signedInt16(e,t){const i=(e<<8)+t;return 32768&i?i-65536:i}function string16(e){return String.fromCharCode(e>>8&255,255&e)}function safeString16(e){e>32767?e=32767:e<-32768&&(e=-32768);return String.fromCharCode(e>>8&255,255&e)}function isTrueTypeCollectionFile(e){return"ttcf"===bytesToString(e.peekBytes(4))}function getFontFileType(e,{type:t,subtype:i,composite:a}){let s,r;if(function isTrueTypeFile(e){const t=e.peekBytes(4);return 65536===readUint32(t,0)||"true"===bytesToString(t)}(e)||isTrueTypeCollectionFile(e))s=a?"CIDFontType2":"TrueType";else if(function isOpenTypeFile(e){return"OTTO"===bytesToString(e.peekBytes(4))}(e))s=a?"CIDFontType2":"OpenType";else if(function isType1File(e){const t=e.peekBytes(2);return 37===t[0]&&33===t[1]||128===t[0]&&1===t[1]}(e))s=a?"CIDFontType0":"MMType1"===t?"MMType1":"Type1";else if(function isCFFFile(e){const t=e.peekBytes(4);return t[0]>=1&&t[3]>=1&&t[3]<=4}(e))if(a){s="CIDFontType0";r="CIDFontType0C"}else{s="MMType1"===t?"MMType1":"Type1";r="Type1C"}else{warn("getFontFileType: Unable to detect correct font file Type/Subtype.");s=t;r=i}return[s,r]}function applyStandardFontGlyphMap(e,t){for(const i in t)e[+i]=t[i]}function buildToFontChar(e,t,i){const a=[];let s;for(let i=0,r=e.length;i<r;i++){s=getUnicodeForGlyph(e[i],t);-1!==s&&(a[i]=s)}for(const e in i){s=getUnicodeForGlyph(i[e],t);-1!==s&&(a[+e]=s)}return a}function isMacNameRecord(e){return 1===e.platform&&0===e.encoding&&0===e.language}function isWinNameRecord(e){return 3===e.platform&&1===e.encoding&&1033===e.language}function convertCidString(e,t,i=!1){switch(t.length){case 1:return t.charCodeAt(0);case 2:return t.charCodeAt(0)<<8|t.charCodeAt(1)}const a=`Unsupported CID string (charCode ${e}): "${t}".`;if(i)throw new FormatError(a);warn(a);return t}function adjustMapping(e,t,i,a){const s=Object.create(null),r=new Map,n=[],o=new Set;let g=0;let c=la[g][0],h=la[g][1];for(const C in e){let Q=e[C];if(!t(Q))continue;if(c>h){g++;if(g>=la.length){warn("Ran out of space in font private use area.");break}c=la[g][0];h=la[g][1]}const E=c++;0===Q&&(Q=i);let u=a.get(C);"string"==typeof u&&(u=u.codePointAt(0));if(u&&!(l=u,la[0][0]<=l&&l<=la[0][1]||la[1][0]<=l&&l<=la[1][1])&&!o.has(Q)){r.set(u,Q);o.add(Q)}s[E]=Q;n[C]=E}var l;return{toFontChar:n,charCodeToGlyphId:s,toUnicodeExtraMap:r,nextAvailableFontCharCode:c}}function createCmapTable(e,t,i){const a=function getRanges(e,t,i){const a=[];for(const t in e)e[t]>=i||a.push({fontCharCode:0|t,glyphId:e[t]});if(t)for(const[e,s]of t)s>=i||a.push({fontCharCode:e,glyphId:s});0===a.length&&a.push({fontCharCode:0,glyphId:0});a.sort((function fontGetRangesSort(e,t){return e.fontCharCode-t.fontCharCode}));const s=[],r=a.length;for(let e=0;e<r;){const t=a[e].fontCharCode,i=[a[e].glyphId];++e;let n=t;for(;e<r&&n+1===a[e].fontCharCode;){i.push(a[e].glyphId);++n;++e;if(65535===n)break}s.push([t,n,i])}return s}(e,t,i),s=a.at(-1)[1]>65535?2:1;let r,n,o,g,c="\0\0"+string16(s)+"\0\0"+string32(4+8*s);for(r=a.length-1;r>=0&&!(a[r][0]<=65535);--r);const h=r+1;a[r][0]<65535&&65535===a[r][1]&&(a[r][1]=65534);const l=a[r][1]<65535?1:0,C=h+l,Q=OpenTypeFileBuilder.getSearchParams(C,2);let E,u,d,f,p="",m="",y="",w="",b="",D=0;for(r=0,n=h;r<n;r++){E=a[r];u=E[0];d=E[1];p+=string16(u);m+=string16(d);f=E[2];let e=!0;for(o=1,g=f.length;o<g;++o)if(f[o]!==f[o-1]+1){e=!1;break}if(e){y+=string16(f[0]-u&65535);w+=string16(0)}else{const e=2*(C-r)+2*D;D+=d-u+1;y+=string16(0);w+=string16(e);for(o=0,g=f.length;o<g;++o)b+=string16(f[o])}}if(l>0){m+="ÿÿ";p+="ÿÿ";y+="\0";w+="\0\0"}const F="\0\0"+string16(2*C)+string16(Q.range)+string16(Q.entry)+string16(Q.rangeShift)+m+"\0\0"+p+y+w+b;let S="",k="";if(s>1){c+="\0\0\n"+string32(4+8*s+4+F.length);S="";for(r=0,n=a.length;r<n;r++){E=a[r];u=E[0];f=E[2];let e=f[0];for(o=1,g=f.length;o<g;++o)if(f[o]!==f[o-1]+1){d=E[0]+o-1;S+=string32(u)+string32(d)+string32(e);u=d+1;e=f[o]}S+=string32(u)+string32(E[1])+string32(e)}k="\0\f\0\0"+string32(S.length+16)+"\0\0\0\0"+string32(S.length/12)}return c+"\0"+string16(F.length+4)+F+k+S}function createOS2Table(e,t,i){i||={unitsPerEm:0,yMax:0,yMin:0,ascent:0,descent:0};let s=0,r=0,n=0,o=0,g=null,c=0,h=-1;if(t){for(let e in t){e|=0;(g>e||!g)&&(g=e);c<e&&(c=e);h=getUnicodeRangeFor(e,h);if(h<32)s|=1<<h;else if(h<64)r|=1<<h-32;else if(h<96)n|=1<<h-64;else{if(!(h<123))throw new FormatError("Unicode ranges Bits > 123 are reserved for internal usage");o|=1<<h-96}}c>65535&&(c=65535)}else{g=0;c=255}const l=e.bbox||[0,0,0,0],C=i.unitsPerEm||1/(e.fontMatrix||a)[0],Q=e.ascentScaled?1:C/Ca,E=i.ascent||Math.round(Q*(e.ascent||l[3]));let u=i.descent||Math.round(Q*(e.descent||l[1]));u>0&&e.descent>0&&l[1]<0&&(u=-u);const d=i.yMax||E,f=-i.yMin||-u;return"\0$ô\0\0\0Š»\0\0\0ŒŠ»\0\0ß\x001\0\0\0\0"+String.fromCharCode(e.fixedPitch?9:0)+"\0\0\0\0\0\0"+string32(s)+string32(r)+string32(n)+string32(o)+"*21*"+string16(e.italicAngle?1:0)+string16(g||e.firstChar)+string16(c||e.lastChar)+string16(E)+string16(u)+"\0d"+string16(d)+string16(f)+"\0\0\0\0\0\0\0\0"+string16(e.xHeight)+string16(e.capHeight)+string16(0)+string16(g||e.firstChar)+"\0"}function createPostTable(e){return"\0\0\0"+string32(Math.floor(65536*e.italicAngle))+"\0\0\0\0"+string32(e.fixedPitch?1:0)+"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"}function createPostscriptName(e){return e.replaceAll(/[^\x21-\x7E]|[[\](){}<>/%]/g,"").slice(0,63)}function createNameTable(e,t){t||(t=[[],[]]);const i=[t[0][0]||"Original licence",t[0][1]||e,t[0][2]||"Unknown",t[0][3]||"uniqueID",t[0][4]||e,t[0][5]||"Version 0.11",t[0][6]||createPostscriptName(e),t[0][7]||"Unknown",t[0][8]||"Unknown",t[0][9]||"Unknown"],a=[];let s,r,n,o,g;for(s=0,r=i.length;s<r;s++){g=t[1][s]||i[s];const e=[];for(n=0,o=g.length;n<o;n++)e.push(string16(g.charCodeAt(n)));a.push(e.join(""))}const c=[i,a],h=["\0","\0"],l=["\0\0","\0"],C=["\0\0","\t"],Q=i.length*h.length;let E="\0\0"+string16(Q)+string16(12*Q+6),u=0;for(s=0,r=h.length;s<r;s++){const e=c[s];for(n=0,o=e.length;n<o;n++){g=e[n];E+=h[s]+l[s]+C[s]+string16(n)+string16(g.length)+string16(u);u+=g.length}}E+=i.join("")+a.join("");return E}class Font{constructor(e,t,i){this.name=e;this.psName=null;this.mimetype=null;this.disableFontFace=!1;this.loadedName=i.loadedName;this.isType3Font=i.isType3Font;this.missingFile=!1;this.cssFontInfo=i.cssFontInfo;this._charsCache=Object.create(null);this._glyphCache=Object.create(null);let a=!!(i.flags&Ki);if(!a&&!i.isSimulatedFlags){const t=e.replaceAll(/[,_]/g,"-").split("-",1)[0],i=ji();for(const e of t.split("+"))if(i[e]){a=!0;break}}this.isSerifFont=a;this.isSymbolicFont=!!(i.flags&Ti);this.isMonospace=!!(i.flags&vi);let{type:s,subtype:r}=i;this.type=s;this.subtype=r;this.systemFontInfo=i.systemFontInfo;const n=e.match(/^InvalidPDFjsFont_(.*)_\d+$/);this.isInvalidPDFjsFont=!!n;this.isInvalidPDFjsFont?this.fallbackName=n[1]:this.isMonospace?this.fallbackName="monospace":this.isSerifFont?this.fallbackName="serif":this.fallbackName="sans-serif";if(this.systemFontInfo?.guessFallback){this.systemFontInfo.guessFallback=!1;this.systemFontInfo.css+=`,${this.fallbackName}`}this.differences=i.differences;this.widths=i.widths;this.defaultWidth=i.defaultWidth;this.composite=i.composite;this.cMap=i.cMap;this.capHeight=i.capHeight/Ca;this.ascent=i.ascent/Ca;this.descent=i.descent/Ca;this.lineHeight=this.ascent-this.descent;this.fontMatrix=i.fontMatrix;this.bbox=i.bbox;this.defaultEncoding=i.defaultEncoding;this.toUnicode=i.toUnicode;this.toFontChar=[];if("Type3"===i.type){for(let e=0;e<256;e++)this.toFontChar[e]=this.differences[e]||i.defaultEncoding[e];return}this.cidEncoding=i.cidEncoding||"";this.vertical=!!i.vertical;if(this.vertical){this.vmetrics=i.vmetrics;this.defaultVMetrics=i.defaultVMetrics}if(!t||t.isEmpty){t&&warn('Font file is empty in "'+e+'" ('+this.loadedName+")");this.fallbackToSystemFont(i);return}[s,r]=getFontFileType(t,i);s===this.type&&r===this.subtype||info(`Inconsistent font file Type/SubType, expected: ${this.type}/${this.subtype} but found: ${s}/${r}.`);let o;try{switch(s){case"MMType1":info("MMType1 font ("+e+"), falling back to Type1.");case"Type1":case"CIDFontType0":this.mimetype="font/opentype";const a="Type1C"===r||"CIDFontType0C"===r?new CFFFont(t,i):new Type1Font(e,t,i);adjustWidths(i);o=this.convert(e,a,i);break;case"OpenType":case"TrueType":case"CIDFontType2":this.mimetype="font/opentype";o=this.checkAndRepair(e,t,i);if(this.isOpenType){adjustWidths(i);s="OpenType"}break;default:throw new FormatError(`Font ${s} is not supported`)}}catch(e){warn(e);this.fallbackToSystemFont(i);return}amendFallbackToUnicode(i);this.data=o;this.type=s;this.subtype=r;this.fontMatrix=i.fontMatrix;this.widths=i.widths;this.defaultWidth=i.defaultWidth;this.toUnicode=i.toUnicode;this.seacMap=i.seacMap}get renderer(){return shadow(this,"renderer",FontRendererFactory.create(this,Yi))}exportData(e=!1){const t=e?[...Ba,...Qa]:Ba,i=Object.create(null);let a,s;for(a of t){s=this[a];void 0!==s&&(i[a]=s)}return i}fallbackToSystemFont(e){this.missingFile=!0;const{name:t,type:i}=this;let a=normalizeFontName(t);const s=Pi(),r=Xi(),n=!!s[a],o=!(!r[a]||!s[r[a]]);a=s[a]||r[a]||a;const g=ea()[a];if(g){isNaN(this.ascent)&&(this.ascent=g.ascent/Ca);isNaN(this.descent)&&(this.descent=g.descent/Ca);isNaN(this.capHeight)&&(this.capHeight=g.capHeight/Ca)}this.bold=/bold/gi.test(a);this.italic=/oblique|italic/gi.test(a);this.black=/Black/g.test(t);const c=/Narrow/g.test(t);this.remeasure=(!n||c)&&Object.keys(this.widths).length>0;if((n||o)&&"CIDFontType2"===i&&this.cidEncoding.startsWith("Identity-")){const i=e.cidToGidMap,a=[];applyStandardFontGlyphMap(a,Vi());/Arial-?Black/i.test(t)?applyStandardFontGlyphMap(a,zi()):/Calibri/i.test(t)&&applyStandardFontGlyphMap(a,_i());if(i){for(const e in a){const t=a[e];void 0!==i[t]&&(a[+e]=i[t])}i.length!==this.toUnicode.length&&e.hasIncludedToUnicodeMap&&this.toUnicode instanceof IdentityToUnicodeMap&&this.toUnicode.forEach((function(e,t){const s=a[e];void 0===i[s]&&(a[+e]=t)}))}this.toUnicode instanceof IdentityToUnicodeMap||this.toUnicode.forEach((function(e,t){a[+e]=t}));this.toFontChar=a;this.toUnicode=new ToUnicodeMap(a)}else if(/Symbol/i.test(a))this.toFontChar=buildToFontChar(mi,Ni(),this.differences);else if(/Dingbats/i.test(a))this.toFontChar=buildToFontChar(yi,Gi(),this.differences);else if(n){const e=buildToFontChar(this.defaultEncoding,Ni(),this.differences);"CIDFontType2"!==i||this.cidEncoding.startsWith("Identity-")||this.toUnicode instanceof IdentityToUnicodeMap||this.toUnicode.forEach((function(t,i){e[+t]=i}));this.toFontChar=e}else{const e=Ni(),i=[];this.toUnicode.forEach(((t,a)=>{if(!this.composite){const i=getUnicodeForGlyph(this.differences[t]||this.defaultEncoding[t],e);-1!==i&&(a=i)}i[+t]=a}));this.composite&&this.toUnicode instanceof IdentityToUnicodeMap&&/Tahoma|Verdana/i.test(t)&&applyStandardFontGlyphMap(i,Vi());this.toFontChar=i}amendFallbackToUnicode(e);this.loadedName=a.split("-",1)[0]}checkAndRepair(e,t,i){const a=["OS/2","cmap","head","hhea","hmtx","maxp","name","post","loca","glyf","fpgm","prep","cvt ","CFF "];function readTables(e,t){const i=Object.create(null);i["OS/2"]=null;i.cmap=null;i.head=null;i.hhea=null;i.hmtx=null;i.maxp=null;i.name=null;i.post=null;for(let s=0;s<t;s++){const t=readTableEntry(e);a.includes(t.tag)&&(0!==t.length&&(i[t.tag]=t))}return i}function readTableEntry(e){const t=e.getString(4),i=e.getInt32()>>>0,a=e.getInt32()>>>0,s=e.getInt32()>>>0,r=e.pos;e.pos=e.start||0;e.skip(a);const n=e.getBytes(s);e.pos=r;if("head"===t){n[8]=n[9]=n[10]=n[11]=0;n[17]|=32}return{tag:t,checksum:i,length:s,offset:a,data:n}}function readOpenTypeHeader(e){return{version:e.getString(4),numTables:e.getUint16(),searchRange:e.getUint16(),entrySelector:e.getUint16(),rangeShift:e.getUint16()}}function sanitizeGlyph(e,t,i,a,s,r){const n={length:0,sizeOfInstructions:0};if(t<0||t>=e.length||i>e.length||i-t<=12)return n;const o=e.subarray(t,i),g=signedInt16(o[2],o[3]),c=signedInt16(o[4],o[5]),h=signedInt16(o[6],o[7]),l=signedInt16(o[8],o[9]);if(g>h){writeSignedInt16(o,2,h);writeSignedInt16(o,6,g)}if(c>l){writeSignedInt16(o,4,l);writeSignedInt16(o,8,c)}const C=signedInt16(o[0],o[1]);if(C<0){if(C<-1)return n;a.set(o,s);n.length=o.length;return n}let Q,E=10,u=0;for(Q=0;Q<C;Q++){u=(o[E]<<8|o[E+1])+1;E+=2}const d=E,f=o[E]<<8|o[E+1];n.sizeOfInstructions=f;E+=2+f;const p=E;let m=0;for(Q=0;Q<u;Q++){const e=o[E++];192&e&&(o[E-1]=63&e);let t=2;2&e?t=1:16&e&&(t=0);let i=2;4&e?i=1:32&e&&(i=0);const a=t+i;m+=a;if(8&e){const e=o[E++];0===e&&(o[E-1]^=8);Q+=e;m+=e*a}}if(0===m)return n;let y=E+m;if(y>o.length)return n;if(!r&&f>0){a.set(o.subarray(0,d),s);a.set([0,0],s+d);a.set(o.subarray(p,y),s+d+2);y-=f;o.length-y>3&&(y=y+3&-4);n.length=y;return n}if(o.length-y>3){y=y+3&-4;a.set(o.subarray(0,y),s);n.length=y;return n}a.set(o,s);n.length=o.length;return n}function readNameTable(e){const i=(t.start||0)+e.offset;t.pos=i;const a=[[],[]],s=[],r=e.length,n=i+r;if(0!==t.getUint16()||r<6)return[a,s];const o=t.getUint16(),g=t.getUint16();let c,h;for(c=0;c<o&&t.pos+12<=n;c++){const e={platform:t.getUint16(),encoding:t.getUint16(),language:t.getUint16(),name:t.getUint16(),length:t.getUint16(),offset:t.getUint16()};(isMacNameRecord(e)||isWinNameRecord(e))&&s.push(e)}for(c=0,h=s.length;c<h;c++){const e=s[c];if(e.length<=0)continue;const r=i+g+e.offset;if(r+e.length>n)continue;t.pos=r;const o=e.name;if(e.encoding){let i="";for(let a=0,s=e.length;a<s;a+=2)i+=String.fromCharCode(t.getUint16());a[1][o]=i}else a[0][o]=t.getString(e.length)}return[a,s]}const s=[0,0,0,0,0,0,0,0,-2,-2,-2,-2,0,0,-2,-5,-1,-1,-1,-1,-1,-1,-1,-1,0,0,-1,0,-1,-1,-1,-1,1,-1,-999,0,1,0,-1,-2,0,-1,-2,-1,-1,0,-1,-1,0,0,-999,-999,-1,-1,-1,-1,-2,-999,-2,-2,-999,0,-2,-2,0,0,-2,0,-2,0,0,0,-2,-1,-1,1,1,0,0,-1,-1,-1,-1,-1,-1,-1,0,0,-1,0,-1,-1,0,-999,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,-2,-999,-999,-999,-999,-999,-1,-1,-2,-2,0,0,0,0,-1,-1,-999,-2,-2,0,0,-1,-2,-2,0,0,0,-1,-1,-1,-2];function sanitizeTTProgram(e,t){let i,a,r,n,o,g=e.data,c=0,h=0,l=0;const C=[],Q=[],E=[];let u=t.tooComplexToFollowFunctions,d=!1,f=0,p=0;for(let e=g.length;c<e;){const e=g[c++];if(64===e){a=g[c++];if(d||p)c+=a;else for(i=0;i<a;i++)C.push(g[c++])}else if(65===e){a=g[c++];if(d||p)c+=2*a;else for(i=0;i<a;i++){r=g[c++];C.push(r<<8|g[c++])}}else if(176==(248&e)){a=e-176+1;if(d||p)c+=a;else for(i=0;i<a;i++)C.push(g[c++])}else if(184==(248&e)){a=e-184+1;if(d||p)c+=2*a;else for(i=0;i<a;i++){r=g[c++];C.push(r<<8|g[c++])}}else if(43!==e||u)if(44!==e||u){if(45===e)if(d){d=!1;h=c}else{o=Q.pop();if(!o){warn("TT: ENDF bad stack");t.hintsValid=!1;return}n=E.pop();g=o.data;c=o.i;t.functionsStackDeltas[n]=C.length-o.stackTop}else if(137===e){if(d||p){warn("TT: nested IDEFs not allowed");u=!0}d=!0;l=c}else if(88===e)++f;else if(27===e)p=f;else if(89===e){p===f&&(p=0);--f}else if(28===e&&!d&&!p){const e=C.at(-1);e>0&&(c+=e-1)}}else{if(d||p){warn("TT: nested FDEFs not allowed");u=!0}d=!0;l=c;n=C.pop();t.functionsDefined[n]={data:g,i:c}}else if(!d&&!p){n=C.at(-1);if(isNaN(n))info("TT: CALL empty stack (or invalid entry).");else{t.functionsUsed[n]=!0;if(n in t.functionsStackDeltas){const e=C.length+t.functionsStackDeltas[n];if(e<0){warn("TT: CALL invalid functions stack delta.");t.hintsValid=!1;return}C.length=e}else if(n in t.functionsDefined&&!E.includes(n)){Q.push({data:g,i:c,stackTop:C.length-1});E.push(n);o=t.functionsDefined[n];if(!o){warn("TT: CALL non-existent function");t.hintsValid=!1;return}g=o.data;c=o.i}}}if(!d&&!p){let t=0;e<=142?t=s[e]:e>=192&&e<=223?t=-1:e>=224&&(t=-2);if(e>=113&&e<=117){a=C.pop();isNaN(a)||(t=2*-a)}for(;t<0&&C.length>0;){C.pop();t++}for(;t>0;){C.push(NaN);t--}}}t.tooComplexToFollowFunctions=u;const m=[g];c>g.length&&m.push(new Uint8Array(c-g.length));if(l>h){warn("TT: complementing a missing function tail");m.push(new Uint8Array([34,45]))}!function foldTTTable(e,t){if(t.length>1){let i,a,s=0;for(i=0,a=t.length;i<a;i++)s+=t[i].length;s=s+3&-4;const r=new Uint8Array(s);let n=0;for(i=0,a=t.length;i<a;i++){r.set(t[i],n);n+=t[i].length}e.data=r;e.length=s}}(e,m)}let r,n,o,g;if(isTrueTypeCollectionFile(t=new Stream(new Uint8Array(t.getBytes())))){const e=function readTrueTypeCollectionData(e,t){const{numFonts:i,offsetTable:a}=function readTrueTypeCollectionHeader(e){const t=e.getString(4);assert("ttcf"===t,"Must be a TrueType Collection font.");const i=e.getUint16(),a=e.getUint16(),s=e.getInt32()>>>0,r=[];for(let t=0;t<s;t++)r.push(e.getInt32()>>>0);const n={ttcTag:t,majorVersion:i,minorVersion:a,numFonts:s,offsetTable:r};switch(i){case 1:return n;case 2:n.dsigTag=e.getInt32()>>>0;n.dsigLength=e.getInt32()>>>0;n.dsigOffset=e.getInt32()>>>0;return n}throw new FormatError(`Invalid TrueType Collection majorVersion: ${i}.`)}(e),s=t.split("+");let r;for(let n=0;n<i;n++){e.pos=(e.start||0)+a[n];const i=readOpenTypeHeader(e),o=readTables(e,i.numTables);if(!o.name)throw new FormatError('TrueType Collection font must contain a "name" table.');const[g]=readNameTable(o.name);for(let e=0,a=g.length;e<a;e++)for(let a=0,n=g[e].length;a<n;a++){const n=g[e][a]?.replaceAll(/\s/g,"");if(n){if(n===t)return{header:i,tables:o};if(!(s.length<2))for(const e of s)n===e&&(r={name:e,header:i,tables:o})}}}if(r){warn(`TrueType Collection does not contain "${t}" font, falling back to "${r.name}" font instead.`);return{header:r.header,tables:r.tables}}throw new FormatError(`TrueType Collection does not contain "${t}" font.`)}(t,this.name);r=e.header;n=e.tables}else{r=readOpenTypeHeader(t);n=readTables(t,r.numTables)}const c=!n["CFF "];if(c){if(!n.loca)throw new FormatError('Required "loca" table is not found');if(!n.glyf){warn('Required "glyf" table is not found -- trying to recover.');n.glyf={tag:"glyf",data:new Uint8Array(0)}}this.isOpenType=!1}else{const t=i.composite&&(i.cidToGidMap?.length>0||!(i.cMap instanceof IdentityCMap));if("OTTO"===r.version&&!t||!n.head||!n.hhea||!n.maxp||!n.post){g=new Stream(n["CFF "].data);o=new CFFFont(g,i);adjustWidths(i);return this.convert(e,o,i)}delete n.glyf;delete n.loca;delete n.fpgm;delete n.prep;delete n["cvt "];this.isOpenType=!0}if(!n.maxp)throw new FormatError('Required "maxp" table is not found');t.pos=(t.start||0)+n.maxp.offset;let h=t.getInt32();const l=t.getUint16();if(65536!==h&&20480!==h){if(6===n.maxp.length)h=20480;else{if(!(n.maxp.length>=32))throw new FormatError('"maxp" table has a wrong version number');h=65536}!function writeUint32(e,t,i){e[t+3]=255&i;e[t+2]=i>>>8;e[t+1]=i>>>16;e[t]=i>>>24}(n.maxp.data,0,h)}if(i.scaleFactors?.length===l&&c){const{scaleFactors:e}=i,t=int16(n.head.data[50],n.head.data[51]),a=new GlyfTable({glyfTable:n.glyf.data,isGlyphLocationsLong:t,locaTable:n.loca.data,numGlyphs:l});a.scale(e);const{glyf:s,loca:r,isLocationLong:o}=a.write();n.glyf.data=s;n.loca.data=r;if(o!==!!t){n.head.data[50]=0;n.head.data[51]=o?1:0}const g=n.hmtx.data;for(let t=0;t<l;t++){const i=4*t,a=Math.round(e[t]*int16(g[i],g[i+1]));g[i]=a>>8&255;g[i+1]=255&a;writeSignedInt16(g,i+2,Math.round(e[t]*signedInt16(g[i+2],g[i+3])))}}let C=l+1,Q=!0;if(C>65535){Q=!1;C=l;warn("Not enough space in glyfs to duplicate first glyph.")}let E=0,u=0;if(h>=65536&&n.maxp.length>=32){t.pos+=8;if(t.getUint16()>2){n.maxp.data[14]=0;n.maxp.data[15]=2}t.pos+=4;E=t.getUint16();t.pos+=4;u=t.getUint16()}n.maxp.data[4]=C>>8;n.maxp.data[5]=255&C;const d=function sanitizeTTPrograms(e,t,i,a){const s={functionsDefined:[],functionsUsed:[],functionsStackDeltas:[],tooComplexToFollowFunctions:!1,hintsValid:!0};e&&sanitizeTTProgram(e,s);t&&sanitizeTTProgram(t,s);e&&function checkInvalidFunctions(e,t){if(!e.tooComplexToFollowFunctions)if(e.functionsDefined.length>t){warn("TT: more functions defined than expected");e.hintsValid=!1}else for(let i=0,a=e.functionsUsed.length;i<a;i++){if(i>t){warn("TT: invalid function id: "+i);e.hintsValid=!1;return}if(e.functionsUsed[i]&&!e.functionsDefined[i]){warn("TT: undefined function: "+i);e.hintsValid=!1;return}}}(s,a);if(i&&1&i.length){const e=new Uint8Array(i.length+1);e.set(i.data);i.data=e}return s.hintsValid}(n.fpgm,n.prep,n["cvt "],E);if(!d){delete n.fpgm;delete n.prep;delete n["cvt "]}!function sanitizeMetrics(e,t,i,a,s,r){if(!t){i&&(i.data=null);return}e.pos=(e.start||0)+t.offset;e.pos+=4;e.pos+=2;e.pos+=2;e.pos+=2;e.pos+=2;e.pos+=2;e.pos+=2;e.pos+=2;e.pos+=2;e.pos+=2;const n=e.getUint16();e.pos+=8;e.pos+=2;let o=e.getUint16();if(0!==n){if(!(2&int16(a.data[44],a.data[45]))){t.data[22]=0;t.data[23]=0}}if(o>s){info(`The numOfMetrics (${o}) should not be greater than the numGlyphs (${s}).`);o=s;t.data[34]=(65280&o)>>8;t.data[35]=255&o}const g=s-o-(i.length-4*o>>1);if(g>0){const e=new Uint8Array(i.length+2*g);e.set(i.data);if(r){e[i.length]=i.data[2];e[i.length+1]=i.data[3]}i.data=e}}(t,n.hhea,n.hmtx,n.head,C,Q);if(!n.head)throw new FormatError('Required "head" table is not found');!function sanitizeHead(e,t,i){const a=e.data,s=function int32(e,t,i,a){return(e<<24)+(t<<16)+(i<<8)+a}(a[0],a[1],a[2],a[3]);if(s>>16!=1){info("Attempting to fix invalid version in head table: "+s);a[0]=0;a[1]=1;a[2]=0;a[3]=0}const r=int16(a[50],a[51]);if(r<0||r>1){info("Attempting to fix invalid indexToLocFormat in head table: "+r);const e=t+1;if(i===e<<1){a[50]=0;a[51]=0}else{if(i!==e<<2)throw new FormatError("Could not fix indexToLocFormat: "+r);a[50]=0;a[51]=1}}}(n.head,l,c?n.loca.length:0);let f=Object.create(null);if(c){const e=int16(n.head.data[50],n.head.data[51]),t=function sanitizeGlyphLocations(e,t,i,a,s,r,n){let o,g,c;if(a){o=4;g=function fontItemDecodeLong(e,t){return e[t]<<24|e[t+1]<<16|e[t+2]<<8|e[t+3]};c=function fontItemEncodeLong(e,t,i){e[t]=i>>>24&255;e[t+1]=i>>16&255;e[t+2]=i>>8&255;e[t+3]=255&i}}else{o=2;g=function fontItemDecode(e,t){return e[t]<<9|e[t+1]<<1};c=function fontItemEncode(e,t,i){e[t]=i>>9&255;e[t+1]=i>>1&255}}const h=r?i+1:i,l=o*(1+h),C=new Uint8Array(l);C.set(e.data.subarray(0,l));e.data=C;const Q=t.data,E=Q.length,u=new Uint8Array(E);let d,f;const p=[];for(d=0,f=0;d<i+1;d++,f+=o){let e=g(C,f);e>E&&(e=E);p.push({index:d,offset:e,endOffset:0})}p.sort(((e,t)=>e.offset-t.offset));for(d=0;d<i;d++)p[d].endOffset=p[d+1].offset;p.sort(((e,t)=>e.index-t.index));for(d=0;d<i;d++){const{offset:e,endOffset:t}=p[d];if(0!==e||0!==t)break;const i=p[d+1].offset;if(0!==i){p[d].endOffset=i;break}}const m=p.at(-2);0!==m.offset&&0===m.endOffset&&(m.endOffset=E);const y=Object.create(null);let w=0;c(C,0,w);for(d=0,f=o;d<i;d++,f+=o){const e=sanitizeGlyph(Q,p[d].offset,p[d].endOffset,u,w,s),t=e.length;0===t&&(y[d]=!0);e.sizeOfInstructions>n&&(n=e.sizeOfInstructions);w+=t;c(C,f,w)}if(0===w){const e=new Uint8Array([0,1,0,0,0,0,0,0,0,0,0,0,0,0,49,0]);for(d=0,f=o;d<h;d++,f+=o)c(C,f,e.length);t.data=e}else if(r){const i=g(C,o);if(u.length>i+w)t.data=u.subarray(0,i+w);else{t.data=new Uint8Array(i+w);t.data.set(u.subarray(0,w))}t.data.set(u.subarray(0,i),w);c(e.data,C.length-o,w+i)}else t.data=u.subarray(0,w);return{missingGlyphs:y,maxSizeOfInstructions:n}}(n.loca,n.glyf,l,e,d,Q,u);f=t.missingGlyphs;if(h>=65536&&n.maxp.length>=32){n.maxp.data[26]=t.maxSizeOfInstructions>>8;n.maxp.data[27]=255&t.maxSizeOfInstructions}}if(!n.hhea)throw new FormatError('Required "hhea" table is not found');if(0===n.hhea.data[10]&&0===n.hhea.data[11]){n.hhea.data[10]=255;n.hhea.data[11]=255}const p={unitsPerEm:int16(n.head.data[18],n.head.data[19]),yMax:signedInt16(n.head.data[42],n.head.data[43]),yMin:signedInt16(n.head.data[38],n.head.data[39]),ascent:signedInt16(n.hhea.data[4],n.hhea.data[5]),descent:signedInt16(n.hhea.data[6],n.hhea.data[7]),lineGap:signedInt16(n.hhea.data[8],n.hhea.data[9])};this.ascent=p.ascent/p.unitsPerEm;this.descent=p.descent/p.unitsPerEm;this.lineGap=p.lineGap/p.unitsPerEm;if(this.cssFontInfo?.lineHeight){this.lineHeight=this.cssFontInfo.metrics.lineHeight;this.lineGap=this.cssFontInfo.metrics.lineGap}else this.lineHeight=this.ascent-this.descent+this.lineGap;n.post&&function readPostScriptTable(e,i,a){const s=(t.start||0)+e.offset;t.pos=s;const r=s+e.length,n=t.getInt32();t.skip(28);let o,g,c=!0;switch(n){case 65536:o=Oi;break;case 131072:const e=t.getUint16();if(e!==a){c=!1;break}const s=[];for(g=0;g<e;++g){const e=t.getUint16();if(e>=32768){c=!1;break}s.push(e)}if(!c)break;const h=[],l=[];for(;t.pos<r;){const e=t.getByte();l.length=e;for(g=0;g<e;++g)l[g]=String.fromCharCode(t.getByte());h.push(l.join(""))}o=[];for(g=0;g<e;++g){const e=s[g];e<258?o.push(Oi[e]):o.push(h[e-258])}break;case 196608:break;default:warn("Unknown/unsupported post table version "+n);c=!1;i.defaultEncoding&&(o=i.defaultEncoding)}i.glyphNames=o;return c}(n.post,i,l);n.post={tag:"post",data:createPostTable(i)};const m=Object.create(null);function hasGlyph(e){return!f[e]}if(i.composite){const e=i.cidToGidMap||[],t=0===e.length;i.cMap.forEach((function(i,a){"string"==typeof a&&(a=convertCidString(i,a,!0));if(a>65535)throw new FormatError("Max size of CID is 65,535");let s=-1;t?s=a:void 0!==e[a]&&(s=e[a]);s>=0&&s<l&&hasGlyph(s)&&(m[i]=s)}))}else{const e=function readCmapTable(e,t,i,a){if(!e){warn("No cmap table available.");return{platformId:-1,encodingId:-1,mappings:[],hasShortCmap:!1}}let s,r=(t.start||0)+e.offset;t.pos=r;t.skip(2);const n=t.getUint16();let o,g=!1;for(let e=0;e<n;e++){const s=t.getUint16(),r=t.getUint16(),c=t.getInt32()>>>0;let h=!1;if(o?.platformId!==s||o?.encodingId!==r){if(0!==s||0!==r&&1!==r&&3!==r)if(1===s&&0===r)h=!0;else if(3!==s||1!==r||!a&&o){if(i&&3===s&&0===r){h=!0;let i=!0;if(e<n-1){const e=t.peekBytes(2);int16(e[0],e[1])<s&&(i=!1)}i&&(g=!0)}}else{h=!0;i||(g=!0)}else h=!0;h&&(o={platformId:s,encodingId:r,offset:c});if(g)break}}o&&(t.pos=r+o.offset);if(!o||-1===t.peekByte()){warn("Could not find a preferred cmap table.");return{platformId:-1,encodingId:-1,mappings:[],hasShortCmap:!1}}const c=t.getUint16();let h=!1;const l=[];let C,Q;if(0===c){t.skip(4);for(C=0;C<256;C++){const e=t.getByte();e&&l.push({charCode:C,glyphId:e})}h=!0}else if(2===c){t.skip(4);const e=[];let i=0;for(let a=0;a<256;a++){const a=t.getUint16()>>3;e.push(a);i=Math.max(a,i)}const a=[];for(let e=0;e<=i;e++)a.push({firstCode:t.getUint16(),entryCount:t.getUint16(),idDelta:signedInt16(t.getByte(),t.getByte()),idRangePos:t.pos+t.getUint16()});for(let i=0;i<256;i++)if(0===e[i]){t.pos=a[0].idRangePos+2*i;Q=t.getUint16();l.push({charCode:i,glyphId:Q})}else{const s=a[e[i]];for(C=0;C<s.entryCount;C++){const e=(i<<8)+C+s.firstCode;t.pos=s.idRangePos+2*C;Q=t.getUint16();0!==Q&&(Q=(Q+s.idDelta)%65536);l.push({charCode:e,glyphId:Q})}}}else if(4===c){t.skip(4);const e=t.getUint16()>>1;t.skip(6);const i=[];let a;for(a=0;a<e;a++)i.push({end:t.getUint16()});t.skip(2);for(a=0;a<e;a++)i[a].start=t.getUint16();for(a=0;a<e;a++)i[a].delta=t.getUint16();let n,o=0;for(a=0;a<e;a++){s=i[a];const r=t.getUint16();if(r){n=(r>>1)-(e-a);s.offsetIndex=n;o=Math.max(o,n+s.end-s.start+1)}else s.offsetIndex=-1}const g=[];for(C=0;C<o;C++)g.push(t.getUint16());for(a=0;a<e;a++){s=i[a];r=s.start;const e=s.end,t=s.delta;n=s.offsetIndex;for(C=r;C<=e;C++)if(65535!==C){Q=n<0?C:g[n+C-r];Q=Q+t&65535;l.push({charCode:C,glyphId:Q})}}}else if(6===c){t.skip(4);const e=t.getUint16(),i=t.getUint16();for(C=0;C<i;C++){Q=t.getUint16();const i=e+C;l.push({charCode:i,glyphId:Q})}}else{if(12!==c){warn("cmap table has unsupported format: "+c);return{platformId:-1,encodingId:-1,mappings:[],hasShortCmap:!1}}{t.skip(10);const e=t.getInt32()>>>0;for(C=0;C<e;C++){const e=t.getInt32()>>>0,i=t.getInt32()>>>0;let a=t.getInt32()>>>0;for(let t=e;t<=i;t++)l.push({charCode:t,glyphId:a++})}}}l.sort((function(e,t){return e.charCode-t.charCode}));for(let e=1;e<l.length;e++)if(l[e-1].charCode===l[e].charCode){l.splice(e,1);e--}return{platformId:o.platformId,encodingId:o.encodingId,mappings:l,hasShortCmap:h}}(n.cmap,t,this.isSymbolicFont,i.hasEncoding),a=e.platformId,s=e.encodingId,r=e.mappings;let o=[],g=!1;!i.hasEncoding||"MacRomanEncoding"!==i.baseEncodingName&&"WinAnsiEncoding"!==i.baseEncodingName||(o=getEncoding(i.baseEncodingName));if(i.hasEncoding&&!this.isSymbolicFont&&(3===a&&1===s||1===a&&0===s)){const e=Ni();for(let t=0;t<256;t++){let n;n=void 0!==this.differences[t]?this.differences[t]:o.length&&""!==o[t]?o[t]:fi[t];if(!n)continue;const g=recoverGlyphName(n,e);let c;3===a&&1===s?c=e[g]:1===a&&0===s&&(c=di.indexOf(g));if(void 0===c){if(!i.glyphNames&&i.hasIncludedToUnicodeMap&&!(this.toUnicode instanceof IdentityToUnicodeMap)){const e=this.toUnicode.get(t);e&&(c=e.codePointAt(0))}if(void 0===c)continue}for(const e of r)if(e.charCode===c){m[t]=e.glyphId;break}}}else if(0===a){for(const e of r)m[e.charCode]=e.glyphId;g=!0}else if(3===a&&0===s)for(const e of r){let t=e.charCode;t>=61440&&t<=61695&&(t&=255);m[t]=e.glyphId}else for(const e of r)m[e.charCode]=e.glyphId;if(i.glyphNames&&(o.length||this.differences.length))for(let e=0;e<256;++e){if(!g&&void 0!==m[e])continue;const t=this.differences[e]||o[e];if(!t)continue;const a=i.glyphNames.indexOf(t);a>0&&hasGlyph(a)&&(m[e]=a)}}0===m.length&&(m[0]=0);let y=C-1;Q||(y=0);if(!i.cssFontInfo){const e=adjustMapping(m,hasGlyph,y,this.toUnicode);this.toFontChar=e.toFontChar;n.cmap={tag:"cmap",data:createCmapTable(e.charCodeToGlyphId,e.toUnicodeExtraMap,C)};n["OS/2"]&&function validateOS2Table(e,t){t.pos=(t.start||0)+e.offset;const i=t.getUint16();t.skip(60);const a=t.getUint16();if(i<4&&768&a)return!1;if(t.getUint16()>t.getUint16())return!1;t.skip(6);if(0===t.getUint16())return!1;e.data[8]=e.data[9]=0;return!0}(n["OS/2"],t)||(n["OS/2"]={tag:"OS/2",data:createOS2Table(i,e.charCodeToGlyphId,p)})}if(!c)try{g=new Stream(n["CFF "].data);o=new CFFParser(g,i,Yi).parse();o.duplicateFirstGlyph();const e=new CFFCompiler(o);n["CFF "].data=e.compile()}catch{warn("Failed to compile font "+i.loadedName)}if(n.name){const[t,a]=readNameTable(n.name);n.name.data=createNameTable(e,t);this.psName=t[0][6]||null;i.composite||function adjustTrueTypeToUnicode(e,t,i){if(e.isInternalFont)return;if(e.hasIncludedToUnicodeMap)return;if(e.hasEncoding)return;if(e.toUnicode instanceof IdentityToUnicodeMap)return;if(!t)return;if(0===i.length)return;if(e.defaultEncoding===pi)return;for(const e of i)if(!isWinNameRecord(e))return;const a=pi,s=[],r=Ni();for(const e in a){const t=a[e];if(""===t)continue;const i=r[t];void 0!==i&&(s[e]=String.fromCharCode(i))}s.length>0&&e.toUnicode.amend(s)}(i,this.isSymbolicFont,a)}else n.name={tag:"name",data:createNameTable(this.name)};const w=new OpenTypeFileBuilder(r.version);for(const e in n)w.addTable(e,n[e].data);return w.toArray()}convert(e,t,i){i.fixedPitch=!1;i.builtInEncoding&&function adjustType1ToUnicode(e,t){if(e.isInternalFont)return;if(e.hasIncludedToUnicodeMap)return;if(t===e.defaultEncoding)return;if(e.toUnicode instanceof IdentityToUnicodeMap)return;const i=[],a=Ni();for(const s in t){if(e.hasEncoding&&(e.baseEncodingName||void 0!==e.differences[s]))continue;const r=getUnicodeForGlyph(t[s],a);-1!==r&&(i[s]=String.fromCharCode(r))}i.length>0&&e.toUnicode.amend(i)}(i,i.builtInEncoding);let s=1;t instanceof CFFFont&&(s=t.numGlyphs-1);const r=t.getGlyphMapping(i);let n=null,o=r,g=null;if(!i.cssFontInfo){n=adjustMapping(r,t.hasGlyphId.bind(t),s,this.toUnicode);this.toFontChar=n.toFontChar;o=n.charCodeToGlyphId;g=n.toUnicodeExtraMap}const c=t.numGlyphs;function getCharCodes(e,t){let i=null;for(const a in e)t===e[a]&&(i||=[]).push(0|a);return i}function createCharCode(e,t){for(const i in e)if(t===e[i])return 0|i;n.charCodeToGlyphId[n.nextAvailableFontCharCode]=t;return n.nextAvailableFontCharCode++}const h=t.seacs;if(n&&h?.length){const e=i.fontMatrix||a,s=t.getCharset(),o=Object.create(null);for(let t in h){t|=0;const i=h[t],a=fi[i[2]],g=fi[i[3]],c=s.indexOf(a),l=s.indexOf(g);if(c<0||l<0)continue;const C={x:i[0]*e[0]+i[1]*e[2]+e[4],y:i[0]*e[1]+i[1]*e[3]+e[5]},Q=getCharCodes(r,t);if(Q)for(const e of Q){const t=n.charCodeToGlyphId,i=createCharCode(t,c),a=createCharCode(t,l);o[e]={baseFontCharCode:i,accentFontCharCode:a,accentOffset:C}}}i.seacMap=o}const l=1/(i.fontMatrix||a)[0],C=new OpenTypeFileBuilder("OTTO");C.addTable("CFF ",t.data);C.addTable("OS/2",createOS2Table(i,o));C.addTable("cmap",createCmapTable(o,g,c));C.addTable("head","\0\0\0\0\0\0\0\0\0\0_<õ\0\0"+safeString16(l)+"\0\0\0\0ž\v~'\0\0\0\0ž\v~'\0\0"+safeString16(i.descent)+"ÿ"+safeString16(i.ascent)+string16(i.italicAngle?2:0)+"\0\0\0\0\0\0\0");C.addTable("hhea","\0\0\0"+safeString16(i.ascent)+safeString16(i.descent)+"\0\0ÿÿ\0\0\0\0\0\0"+safeString16(i.capHeight)+safeString16(Math.tan(i.italicAngle)*i.xHeight)+"\0\0\0\0\0\0\0\0\0\0\0\0"+string16(c));C.addTable("hmtx",function fontFieldsHmtx(){const e=t.charstrings,i=t.cff?t.cff.widths:null;let a="\0\0\0\0";for(let t=1,s=c;t<s;t++){let s=0;if(e){const i=e[t-1];s="width"in i?i.width:0}else i&&(s=Math.ceil(i[t]||0));a+=string16(s)+string16(0)}return a}());C.addTable("maxp","\0\0P\0"+string16(c));C.addTable("name",createNameTable(e));C.addTable("post",createPostTable(i));return C.toArray()}_charToGlyph(e,t=!1){let i,a,s,r=this._glyphCache[e];if(r?.isSpace===t)return r;let n=e;if(this.cMap?.contains(e)){n=this.cMap.lookup(e);"string"==typeof n&&(n=convertCidString(e,n))}a=this.widths[n];"number"!=typeof a&&(a=this.defaultWidth);const o=this.vmetrics?.[n];let g=this.toUnicode.get(e)||e;"number"==typeof g&&(g=String.fromCharCode(g));let c=void 0!==this.toFontChar[e];i=this.toFontChar[e]||e;if(this.missingFile){const t=this.differences[e]||this.defaultEncoding[e];".notdef"!==t&&""!==t||"Type1"!==this.type||(i=32);i=function mapSpecialUnicodeValues(e){return e>=65520&&e<=65535?0:e>=62976&&e<=63743?xi()[e]||e:173===e?45:e}(i)}this.isType3Font&&(s=i);let h=null;if(this.seacMap?.[e]){c=!0;const t=this.seacMap[e];i=t.baseFontCharCode;h={fontChar:String.fromCodePoint(t.accentFontCharCode),offset:t.accentOffset}}let l="";"number"==typeof i&&(i<=1114111?l=String.fromCodePoint(i):warn(`charToGlyph - invalid fontCharCode: ${i}`));r=new fonts_Glyph(e,l,g,h,a,o,s,t,c);return this._glyphCache[e]=r}charsToGlyphs(e){let t=this._charsCache[e];if(t)return t;t=[];if(this.cMap){const i=Object.create(null),a=e.length;let s=0;for(;s<a;){this.cMap.readCharCode(e,s,i);const{charcode:a,length:r}=i;s+=r;const n=this._charToGlyph(a,1===r&&32===e.charCodeAt(s-1));t.push(n)}}else for(let i=0,a=e.length;i<a;++i){const a=e.charCodeAt(i),s=this._charToGlyph(a,32===a);t.push(s)}return this._charsCache[e]=t}getCharPositions(e){const t=[];if(this.cMap){const i=Object.create(null);let a=0;for(;a<e.length;){this.cMap.readCharCode(e,a,i);const s=i.length;t.push([a,a+s]);a+=s}}else for(let i=0,a=e.length;i<a;++i)t.push([i,i+1]);return t}get glyphCacheValues(){return Object.values(this._glyphCache)}encodeString(e){const t=[],i=[],hasCurrentBufErrors=()=>t.length%2==1,a=this.toUnicode instanceof IdentityToUnicodeMap?e=>this.toUnicode.charCodeOf(e):e=>this.toUnicode.charCodeOf(String.fromCodePoint(e));for(let s=0,r=e.length;s<r;s++){const r=e.codePointAt(s);r>55295&&(r<57344||r>65533)&&s++;if(this.toUnicode){const e=a(r);if(-1!==e){if(hasCurrentBufErrors()){t.push(i.join(""));i.length=0}for(let t=(this.cMap?this.cMap.getCharCodeLength(e):1)-1;t>=0;t--)i.push(String.fromCharCode(e>>8*t&255));continue}}if(!hasCurrentBufErrors()){t.push(i.join(""));i.length=0}i.push(String.fromCodePoint(r))}t.push(i.join(""));return t}}class ErrorFont{constructor(e){this.error=e;this.loadedName="g_font_error";this.missingFile=!0}charsToGlyphs(){return[]}encodeString(e){return[e]}exportData(e=!1){return{error:this.error}}}const Ea=2,ua=3,da=4,fa=5,pa=6,ma=7;class Pattern{constructor(){unreachable("Cannot initialize Pattern.")}static parseShading(e,t,i,a,s){const r=e instanceof BaseStream?e.dict:e,n=r.get("ShadingType");try{switch(n){case Ea:case ua:return new RadialAxialShading(r,t,i,a,s);case da:case fa:case pa:case ma:return new MeshShading(e,t,i,a,s);default:throw new FormatError("Unsupported ShadingType: "+n)}}catch(e){if(e instanceof MissingDataException)throw e;warn(e);return new DummyShading}}}class BaseShading{static SMALL_NUMBER=1e-6;constructor(){this.constructor===BaseShading&&unreachable("Cannot initialize BaseShading.")}getIR(){unreachable("Abstract method `getIR` called.")}}class RadialAxialShading extends BaseShading{constructor(e,t,i,a,s){super();this.shadingType=e.get("ShadingType");let r=0;this.shadingType===Ea?r=4:this.shadingType===ua&&(r=6);this.coordsArr=e.getArray("Coords");if(!isNumberArray(this.coordsArr,r))throw new FormatError("RadialAxialShading: Invalid /Coords array.");const n=ColorSpace.parse({cs:e.getRaw("CS")||e.getRaw("ColorSpace"),xref:t,resources:i,pdfFunctionFactory:a,localColorSpaceCache:s});this.bbox=lookupNormalRect(e.getArray("BBox"),null);let o=0,g=1;const c=e.getArray("Domain");isNumberArray(c,2)&&([o,g]=c);let h=!1,l=!1;const C=e.getArray("Extend");(function isBooleanArray(e,t){return Array.isArray(e)&&(null===t||e.length===t)&&e.every((e=>"boolean"==typeof e))})(C,2)&&([h,l]=C);if(!(this.shadingType!==ua||h&&l)){const[e,t,i,a,s,r]=this.coordsArr,n=Math.hypot(e-a,t-s);i<=r+n&&r<=i+n&&warn("Unsupported radial gradient.")}this.extendStart=h;this.extendEnd=l;const Q=e.getRaw("Function"),E=a.createFromArray(Q),u=(g-o)/840,d=this.colorStops=[];if(o>=g||u<=0){info("Bad shading domain.");return}const f=new Float32Array(n.numComps),p=new Float32Array(1);let m,y=0;p[0]=o;E(p,0,f,0);let w=n.getRgb(f,0);const b=Util.makeHexColor(w[0],w[1],w[2]);d.push([0,b]);let D=1;p[0]=o+u;E(p,0,f,0);let F=n.getRgb(f,0),S=F[0]-w[0]+1,k=F[1]-w[1]+1,R=F[2]-w[2]+1,N=F[0]-w[0]-1,G=F[1]-w[1]-1,x=F[2]-w[2]-1;for(let e=2;e<840;e++){p[0]=o+e*u;E(p,0,f,0);m=n.getRgb(f,0);const t=e-y;S=Math.min(S,(m[0]-w[0]+1)/t);k=Math.min(k,(m[1]-w[1]+1)/t);R=Math.min(R,(m[2]-w[2]+1)/t);N=Math.max(N,(m[0]-w[0]-1)/t);G=Math.max(G,(m[1]-w[1]-1)/t);x=Math.max(x,(m[2]-w[2]-1)/t);if(!(N<=S&&G<=k&&x<=R)){const e=Util.makeHexColor(F[0],F[1],F[2]);d.push([D/840,e]);S=m[0]-F[0]+1;k=m[1]-F[1]+1;R=m[2]-F[2]+1;N=m[0]-F[0]-1;G=m[1]-F[1]-1;x=m[2]-F[2]-1;y=D;w=F}D=e;F=m}const M=Util.makeHexColor(F[0],F[1],F[2]);d.push([1,M]);let U="transparent";if(e.has("Background")){m=n.getRgb(e.get("Background"),0);U=Util.makeHexColor(m[0],m[1],m[2])}if(!h){d.unshift([0,U]);d[1][0]+=BaseShading.SMALL_NUMBER}if(!l){d.at(-1)[0]-=BaseShading.SMALL_NUMBER;d.push([1,U])}this.colorStops=d}getIR(){const{coordsArr:e,shadingType:t}=this;let i,a,s,r,n;if(t===Ea){a=[e[0],e[1]];s=[e[2],e[3]];r=null;n=null;i="axial"}else if(t===ua){a=[e[0],e[1]];s=[e[3],e[4]];r=e[2];n=e[5];i="radial"}else unreachable(`getPattern type unknown: ${t}`);return["RadialAxial",i,this.bbox,this.colorStops,a,s,r,n]}}class MeshStreamReader{constructor(e,t){this.stream=e;this.context=t;this.buffer=0;this.bufferLength=0;const i=t.numComps;this.tmpCompsBuf=new Float32Array(i);const a=t.colorSpace.numComps;this.tmpCsCompsBuf=t.colorFn?new Float32Array(a):this.tmpCompsBuf}get hasData(){if(this.stream.end)return this.stream.pos<this.stream.end;if(this.bufferLength>0)return!0;const e=this.stream.getByte();if(e<0)return!1;this.buffer=e;this.bufferLength=8;return!0}readBits(e){let t=this.buffer,i=this.bufferLength;if(32===e){if(0===i)return(this.stream.getByte()<<24|this.stream.getByte()<<16|this.stream.getByte()<<8|this.stream.getByte())>>>0;t=t<<24|this.stream.getByte()<<16|this.stream.getByte()<<8|this.stream.getByte();const e=this.stream.getByte();this.buffer=e&(1<<i)-1;return(t<<8-i|(255&e)>>i)>>>0}if(8===e&&0===i)return this.stream.getByte();for(;i<e;){t=t<<8|this.stream.getByte();i+=8}i-=e;this.bufferLength=i;this.buffer=t&(1<<i)-1;return t>>i}align(){this.buffer=0;this.bufferLength=0}readFlag(){return this.readBits(this.context.bitsPerFlag)}readCoordinate(){const e=this.context.bitsPerCoordinate,t=this.readBits(e),i=this.readBits(e),a=this.context.decode,s=e<32?1/((1<<e)-1):2.3283064365386963e-10;return[t*s*(a[1]-a[0])+a[0],i*s*(a[3]-a[2])+a[2]]}readComponents(){const e=this.context.numComps,t=this.context.bitsPerComponent,i=t<32?1/((1<<t)-1):2.3283064365386963e-10,a=this.context.decode,s=this.tmpCompsBuf;for(let r=0,n=4;r<e;r++,n+=2){const e=this.readBits(t);s[r]=e*i*(a[n+1]-a[n])+a[n]}const r=this.tmpCsCompsBuf;this.context.colorFn&&this.context.colorFn(s,0,r,0);return this.context.colorSpace.getRgb(r,0)}}let ya=Object.create(null);function getB(e){return ya[e]||=function buildB(e){const t=[];for(let i=0;i<=e;i++){const a=i/e,s=1-a;t.push(new Float32Array([s**3,3*a*s**2,3*a**2*s,a**3]))}return t}(e)}class MeshShading extends BaseShading{static MIN_SPLIT_PATCH_CHUNKS_AMOUNT=3;static MAX_SPLIT_PATCH_CHUNKS_AMOUNT=20;static TRIANGLE_DENSITY=20;constructor(e,t,i,a,s){super();if(!(e instanceof BaseStream))throw new FormatError("Mesh data is not a stream");const r=e.dict;this.shadingType=r.get("ShadingType");this.bbox=lookupNormalRect(r.getArray("BBox"),null);const n=ColorSpace.parse({cs:r.getRaw("CS")||r.getRaw("ColorSpace"),xref:t,resources:i,pdfFunctionFactory:a,localColorSpaceCache:s});this.background=r.has("Background")?n.getRgb(r.get("Background"),0):null;const o=r.getRaw("Function"),g=o?a.createFromArray(o):null;this.coords=[];this.colors=[];this.figures=[];const c={bitsPerCoordinate:r.get("BitsPerCoordinate"),bitsPerComponent:r.get("BitsPerComponent"),bitsPerFlag:r.get("BitsPerFlag"),decode:r.getArray("Decode"),colorFn:g,colorSpace:n,numComps:g?1:n.numComps},h=new MeshStreamReader(e,c);let l=!1;switch(this.shadingType){case da:this._decodeType4Shading(h);break;case fa:const e=0|r.get("VerticesPerRow");if(e<2)throw new FormatError("Invalid VerticesPerRow");this._decodeType5Shading(h,e);break;case pa:this._decodeType6Shading(h);l=!0;break;case ma:this._decodeType7Shading(h);l=!0;break;default:unreachable("Unsupported mesh type.")}if(l){this._updateBounds();for(let e=0,t=this.figures.length;e<t;e++)this._buildFigureFromPatch(e)}this._updateBounds();this._packData()}_decodeType4Shading(e){const t=this.coords,i=this.colors,a=[],s=[];let r=0;for(;e.hasData;){const n=e.readFlag(),o=e.readCoordinate(),g=e.readComponents();if(0===r){if(!(0<=n&&n<=2))throw new FormatError("Unknown type4 flag");switch(n){case 0:r=3;break;case 1:s.push(s.at(-2),s.at(-1));r=1;break;case 2:s.push(s.at(-3),s.at(-1));r=1}a.push(n)}s.push(t.length);t.push(o);i.push(g);r--;e.align()}this.figures.push({type:"triangles",coords:new Int32Array(s),colors:new Int32Array(s)})}_decodeType5Shading(e,t){const i=this.coords,a=this.colors,s=[];for(;e.hasData;){const t=e.readCoordinate(),r=e.readComponents();s.push(i.length);i.push(t);a.push(r)}this.figures.push({type:"lattice",coords:new Int32Array(s),colors:new Int32Array(s),verticesPerRow:t})}_decodeType6Shading(e){const t=this.coords,i=this.colors,a=new Int32Array(16),s=new Int32Array(4);for(;e.hasData;){const r=e.readFlag();if(!(0<=r&&r<=3))throw new FormatError("Unknown type6 flag");const n=t.length;for(let i=0,a=0!==r?8:12;i<a;i++)t.push(e.readCoordinate());const o=i.length;for(let t=0,a=0!==r?2:4;t<a;t++)i.push(e.readComponents());let g,c,h,l;switch(r){case 0:a[12]=n+3;a[13]=n+4;a[14]=n+5;a[15]=n+6;a[8]=n+2;a[11]=n+7;a[4]=n+1;a[7]=n+8;a[0]=n;a[1]=n+11;a[2]=n+10;a[3]=n+9;s[2]=o+1;s[3]=o+2;s[0]=o;s[1]=o+3;break;case 1:g=a[12];c=a[13];h=a[14];l=a[15];a[12]=l;a[13]=n+0;a[14]=n+1;a[15]=n+2;a[8]=h;a[11]=n+3;a[4]=c;a[7]=n+4;a[0]=g;a[1]=n+7;a[2]=n+6;a[3]=n+5;g=s[2];c=s[3];s[2]=c;s[3]=o;s[0]=g;s[1]=o+1;break;case 2:g=a[15];c=a[11];a[12]=a[3];a[13]=n+0;a[14]=n+1;a[15]=n+2;a[8]=a[7];a[11]=n+3;a[4]=c;a[7]=n+4;a[0]=g;a[1]=n+7;a[2]=n+6;a[3]=n+5;g=s[3];s[2]=s[1];s[3]=o;s[0]=g;s[1]=o+1;break;case 3:a[12]=a[0];a[13]=n+0;a[14]=n+1;a[15]=n+2;a[8]=a[1];a[11]=n+3;a[4]=a[2];a[7]=n+4;a[0]=a[3];a[1]=n+7;a[2]=n+6;a[3]=n+5;s[2]=s[0];s[3]=o;s[0]=s[1];s[1]=o+1}a[5]=t.length;t.push([(-4*t[a[0]][0]-t[a[15]][0]+6*(t[a[4]][0]+t[a[1]][0])-2*(t[a[12]][0]+t[a[3]][0])+3*(t[a[13]][0]+t[a[7]][0]))/9,(-4*t[a[0]][1]-t[a[15]][1]+6*(t[a[4]][1]+t[a[1]][1])-2*(t[a[12]][1]+t[a[3]][1])+3*(t[a[13]][1]+t[a[7]][1]))/9]);a[6]=t.length;t.push([(-4*t[a[3]][0]-t[a[12]][0]+6*(t[a[2]][0]+t[a[7]][0])-2*(t[a[0]][0]+t[a[15]][0])+3*(t[a[4]][0]+t[a[14]][0]))/9,(-4*t[a[3]][1]-t[a[12]][1]+6*(t[a[2]][1]+t[a[7]][1])-2*(t[a[0]][1]+t[a[15]][1])+3*(t[a[4]][1]+t[a[14]][1]))/9]);a[9]=t.length;t.push([(-4*t[a[12]][0]-t[a[3]][0]+6*(t[a[8]][0]+t[a[13]][0])-2*(t[a[0]][0]+t[a[15]][0])+3*(t[a[11]][0]+t[a[1]][0]))/9,(-4*t[a[12]][1]-t[a[3]][1]+6*(t[a[8]][1]+t[a[13]][1])-2*(t[a[0]][1]+t[a[15]][1])+3*(t[a[11]][1]+t[a[1]][1]))/9]);a[10]=t.length;t.push([(-4*t[a[15]][0]-t[a[0]][0]+6*(t[a[11]][0]+t[a[14]][0])-2*(t[a[12]][0]+t[a[3]][0])+3*(t[a[2]][0]+t[a[8]][0]))/9,(-4*t[a[15]][1]-t[a[0]][1]+6*(t[a[11]][1]+t[a[14]][1])-2*(t[a[12]][1]+t[a[3]][1])+3*(t[a[2]][1]+t[a[8]][1]))/9]);this.figures.push({type:"patch",coords:new Int32Array(a),colors:new Int32Array(s)})}}_decodeType7Shading(e){const t=this.coords,i=this.colors,a=new Int32Array(16),s=new Int32Array(4);for(;e.hasData;){const r=e.readFlag();if(!(0<=r&&r<=3))throw new FormatError("Unknown type7 flag");const n=t.length;for(let i=0,a=0!==r?12:16;i<a;i++)t.push(e.readCoordinate());const o=i.length;for(let t=0,a=0!==r?2:4;t<a;t++)i.push(e.readComponents());let g,c,h,l;switch(r){case 0:a[12]=n+3;a[13]=n+4;a[14]=n+5;a[15]=n+6;a[8]=n+2;a[9]=n+13;a[10]=n+14;a[11]=n+7;a[4]=n+1;a[5]=n+12;a[6]=n+15;a[7]=n+8;a[0]=n;a[1]=n+11;a[2]=n+10;a[3]=n+9;s[2]=o+1;s[3]=o+2;s[0]=o;s[1]=o+3;break;case 1:g=a[12];c=a[13];h=a[14];l=a[15];a[12]=l;a[13]=n+0;a[14]=n+1;a[15]=n+2;a[8]=h;a[9]=n+9;a[10]=n+10;a[11]=n+3;a[4]=c;a[5]=n+8;a[6]=n+11;a[7]=n+4;a[0]=g;a[1]=n+7;a[2]=n+6;a[3]=n+5;g=s[2];c=s[3];s[2]=c;s[3]=o;s[0]=g;s[1]=o+1;break;case 2:g=a[15];c=a[11];a[12]=a[3];a[13]=n+0;a[14]=n+1;a[15]=n+2;a[8]=a[7];a[9]=n+9;a[10]=n+10;a[11]=n+3;a[4]=c;a[5]=n+8;a[6]=n+11;a[7]=n+4;a[0]=g;a[1]=n+7;a[2]=n+6;a[3]=n+5;g=s[3];s[2]=s[1];s[3]=o;s[0]=g;s[1]=o+1;break;case 3:a[12]=a[0];a[13]=n+0;a[14]=n+1;a[15]=n+2;a[8]=a[1];a[9]=n+9;a[10]=n+10;a[11]=n+3;a[4]=a[2];a[5]=n+8;a[6]=n+11;a[7]=n+4;a[0]=a[3];a[1]=n+7;a[2]=n+6;a[3]=n+5;s[2]=s[0];s[3]=o;s[0]=s[1];s[1]=o+1}this.figures.push({type:"patch",coords:new Int32Array(a),colors:new Int32Array(s)})}}_buildFigureFromPatch(e){const t=this.figures[e];assert("patch"===t.type,"Unexpected patch mesh figure");const i=this.coords,a=this.colors,s=t.coords,r=t.colors,n=Math.min(i[s[0]][0],i[s[3]][0],i[s[12]][0],i[s[15]][0]),o=Math.min(i[s[0]][1],i[s[3]][1],i[s[12]][1],i[s[15]][1]),g=Math.max(i[s[0]][0],i[s[3]][0],i[s[12]][0],i[s[15]][0]),c=Math.max(i[s[0]][1],i[s[3]][1],i[s[12]][1],i[s[15]][1]);let h=Math.ceil((g-n)*MeshShading.TRIANGLE_DENSITY/(this.bounds[2]-this.bounds[0]));h=Math.max(MeshShading.MIN_SPLIT_PATCH_CHUNKS_AMOUNT,Math.min(MeshShading.MAX_SPLIT_PATCH_CHUNKS_AMOUNT,h));let l=Math.ceil((c-o)*MeshShading.TRIANGLE_DENSITY/(this.bounds[3]-this.bounds[1]));l=Math.max(MeshShading.MIN_SPLIT_PATCH_CHUNKS_AMOUNT,Math.min(MeshShading.MAX_SPLIT_PATCH_CHUNKS_AMOUNT,l));const C=h+1,Q=new Int32Array((l+1)*C),E=new Int32Array((l+1)*C);let u=0;const d=new Uint8Array(3),f=new Uint8Array(3),p=a[r[0]],m=a[r[1]],y=a[r[2]],w=a[r[3]],b=getB(l),D=getB(h);for(let e=0;e<=l;e++){d[0]=(p[0]*(l-e)+y[0]*e)/l|0;d[1]=(p[1]*(l-e)+y[1]*e)/l|0;d[2]=(p[2]*(l-e)+y[2]*e)/l|0;f[0]=(m[0]*(l-e)+w[0]*e)/l|0;f[1]=(m[1]*(l-e)+w[1]*e)/l|0;f[2]=(m[2]*(l-e)+w[2]*e)/l|0;for(let t=0;t<=h;t++,u++){if(!(0!==e&&e!==l||0!==t&&t!==h))continue;let r=0,n=0,o=0;for(let a=0;a<=3;a++)for(let g=0;g<=3;g++,o++){const c=b[e][a]*D[t][g];r+=i[s[o]][0]*c;n+=i[s[o]][1]*c}Q[u]=i.length;i.push([r,n]);E[u]=a.length;const g=new Uint8Array(3);g[0]=(d[0]*(h-t)+f[0]*t)/h|0;g[1]=(d[1]*(h-t)+f[1]*t)/h|0;g[2]=(d[2]*(h-t)+f[2]*t)/h|0;a.push(g)}}Q[0]=s[0];E[0]=r[0];Q[h]=s[3];E[h]=r[1];Q[C*l]=s[12];E[C*l]=r[2];Q[C*l+h]=s[15];E[C*l+h]=r[3];this.figures[e]={type:"lattice",coords:Q,colors:E,verticesPerRow:C}}_updateBounds(){let e=this.coords[0][0],t=this.coords[0][1],i=e,a=t;for(let s=1,r=this.coords.length;s<r;s++){const r=this.coords[s][0],n=this.coords[s][1];e=e>r?r:e;t=t>n?n:t;i=i<r?r:i;a=a<n?n:a}this.bounds=[e,t,i,a]}_packData(){let e,t,i,a;const s=this.coords,r=new Float32Array(2*s.length);for(e=0,i=0,t=s.length;e<t;e++){const t=s[e];r[i++]=t[0];r[i++]=t[1]}this.coords=r;const n=this.colors,o=new Uint8Array(3*n.length);for(e=0,i=0,t=n.length;e<t;e++){const t=n[e];o[i++]=t[0];o[i++]=t[1];o[i++]=t[2]}this.colors=o;const g=this.figures;for(e=0,t=g.length;e<t;e++){const t=g[e],s=t.coords,r=t.colors;for(i=0,a=s.length;i<a;i++){s[i]*=2;r[i]*=3}}}getIR(){const{bounds:e}=this;if(e[2]-e[0]==0||e[3]-e[1]==0)throw new FormatError(`Invalid MeshShading bounds: [${e}].`);return["Mesh",this.shadingType,this.coords,this.colors,this.figures,e,this.bbox,this.background]}}class DummyShading extends BaseShading{getIR(){return["Dummy"]}}function getTilingPatternIR(e,t,a){const s=lookupMatrix(t.getArray("Matrix"),i),r=lookupNormalRect(t.getArray("BBox"),null);if(!r||r[2]-r[0]==0||r[3]-r[1]==0)throw new FormatError("Invalid getTilingPatternIR /BBox array.");const n=t.get("XStep");if("number"!=typeof n)throw new FormatError("Invalid getTilingPatternIR /XStep value.");const o=t.get("YStep");if("number"!=typeof o)throw new FormatError("Invalid getTilingPatternIR /YStep value.");const g=t.get("PaintType");if(!Number.isInteger(g))throw new FormatError("Invalid getTilingPatternIR /PaintType value.");const c=t.get("TilingType");if(!Number.isInteger(c))throw new FormatError("Invalid getTilingPatternIR /TilingType value.");return["TilingPattern",a,e,s,r,n,o,g,c]}const wa=[1.3877,1,1,1,.97801,.92482,.89552,.91133,.81988,.97566,.98152,.93548,.93548,1.2798,.85284,.92794,1,.96134,1.54657,.91133,.91133,.91133,.91133,.91133,.91133,.91133,.91133,.91133,.91133,.82845,.82845,.85284,.85284,.85284,.75859,.92138,.83908,.7762,.73293,.87289,.73133,.7514,.81921,.87356,.95958,.59526,.75727,.69225,1.04924,.9121,.86943,.79795,.88198,.77958,.70864,.81055,.90399,.88653,.96017,.82577,.77892,.78257,.97507,1.54657,.97507,.85284,.89552,.90176,.88762,.8785,.75241,.8785,.90518,.95015,.77618,.8785,.88401,.91916,.86304,.88401,.91488,.8785,.8801,.8785,.8785,.91343,.7173,1.04106,.8785,.85075,.95794,.82616,.85162,.79492,.88331,1.69808,.88331,.85284,.97801,.89552,.91133,.89552,.91133,1.7801,.89552,1.24487,1.13254,1.12401,.96839,.85284,.68787,.70645,.85592,.90747,1.01466,1.0088,.90323,1,1.07463,1,.91056,.75806,1.19118,.96839,.78864,.82845,.84133,.75859,.83908,.83908,.83908,.83908,.83908,.83908,.77539,.73293,.73133,.73133,.73133,.73133,.95958,.95958,.95958,.95958,.88506,.9121,.86943,.86943,.86943,.86943,.86943,.85284,.87508,.90399,.90399,.90399,.90399,.77892,.79795,.90807,.88762,.88762,.88762,.88762,.88762,.88762,.8715,.75241,.90518,.90518,.90518,.90518,.88401,.88401,.88401,.88401,.8785,.8785,.8801,.8801,.8801,.8801,.8801,.90747,.89049,.8785,.8785,.8785,.8785,.85162,.8785,.85162,.83908,.88762,.83908,.88762,.83908,.88762,.73293,.75241,.73293,.75241,.73293,.75241,.73293,.75241,.87289,.83016,.88506,.93125,.73133,.90518,.73133,.90518,.73133,.90518,.73133,.90518,.73133,.90518,.81921,.77618,.81921,.77618,.81921,.77618,1,1,.87356,.8785,.91075,.89608,.95958,.88401,.95958,.88401,.95958,.88401,.95958,.88401,.95958,.88401,.76229,.90167,.59526,.91916,1,1,.86304,.69225,.88401,1,1,.70424,.79468,.91926,.88175,.70823,.94903,.9121,.8785,1,1,.9121,.8785,.87802,.88656,.8785,.86943,.8801,.86943,.8801,.86943,.8801,.87402,.89291,.77958,.91343,1,1,.77958,.91343,.70864,.7173,.70864,.7173,.70864,.7173,.70864,.7173,1,1,.81055,.75841,.81055,1.06452,.90399,.8785,.90399,.8785,.90399,.8785,.90399,.8785,.90399,.8785,.90399,.8785,.96017,.95794,.77892,.85162,.77892,.78257,.79492,.78257,.79492,.78257,.79492,.9297,.56892,.83908,.88762,.77539,.8715,.87508,.89049,1,1,.81055,1.04106,1.20528,1.20528,1,1.15543,.70674,.98387,.94721,1.33431,1.45894,.95161,1.06303,.83908,.80352,.57184,.6965,.56289,.82001,.56029,.81235,1.02988,.83908,.7762,.68156,.80367,.73133,.78257,.87356,.86943,.95958,.75727,.89019,1.04924,.9121,.7648,.86943,.87356,.79795,.78275,.81055,.77892,.9762,.82577,.99819,.84896,.95958,.77892,.96108,1.01407,.89049,1.02988,.94211,.96108,.8936,.84021,.87842,.96399,.79109,.89049,1.00813,1.02988,.86077,.87445,.92099,.84723,.86513,.8801,.75638,.85714,.78216,.79586,.87965,.94211,.97747,.78287,.97926,.84971,1.02988,.94211,.8801,.94211,.84971,.73133,1,1,1,1,1,1,1,1,1,1,1,1,.90264,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.90518,1,1,1,1,1,1,1,1,1,1,1,1,.90548,1,1,1,1,1,1,.96017,.95794,.96017,.95794,.96017,.95794,.77892,.85162,1,1,.89552,.90527,1,.90363,.92794,.92794,.92794,.92794,.87012,.87012,.87012,.89552,.89552,1.42259,.71143,1.06152,1,1,1.03372,1.03372,.97171,1.4956,2.2807,.93835,.83406,.91133,.84107,.91133,1,1,1,.72021,1,1.23108,.83489,.88525,.88525,.81499,.90527,1.81055,.90527,1.81055,1.31006,1.53711,.94434,1.08696,1,.95018,.77192,.85284,.90747,1.17534,.69825,.9716,1.37077,.90747,.90747,.85356,.90747,.90747,1.44947,.85284,.8941,.8941,.70572,.8,.70572,.70572,.70572,.70572,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.99862,.99862,1,1,1,1,1,1.08004,.91027,1,1,1,.99862,1,1,1,1,1,1,1,1,1,1,1,1,.90727,.90727,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],ba={lineHeight:1.2207,lineGap:.2207},Da=[1.3877,1,1,1,.97801,.92482,.89552,.91133,.81988,.97566,.98152,.93548,.93548,1.2798,.85284,.92794,1,.96134,1.56239,.91133,.91133,.91133,.91133,.91133,.91133,.91133,.91133,.91133,.91133,.82845,.82845,.85284,.85284,.85284,.75859,.92138,.83908,.7762,.71805,.87289,.73133,.7514,.81921,.87356,.95958,.59526,.75727,.69225,1.04924,.90872,.85938,.79795,.87068,.77958,.69766,.81055,.90399,.88653,.96068,.82577,.77892,.78257,.97507,1.529,.97507,.85284,.89552,.90176,.94908,.86411,.74012,.86411,.88323,.95015,.86411,.86331,.88401,.91916,.86304,.88401,.9039,.86331,.86331,.86411,.86411,.90464,.70852,1.04106,.86331,.84372,.95794,.82616,.84548,.79492,.88331,1.69808,.88331,.85284,.97801,.89552,.91133,.89552,.91133,1.7801,.89552,1.24487,1.13254,1.19129,.96839,.85284,.68787,.70645,.85592,.90747,1.01466,1.0088,.90323,1,1.07463,1,.91056,.75806,1.19118,.96839,.78864,.82845,.84133,.75859,.83908,.83908,.83908,.83908,.83908,.83908,.77539,.71805,.73133,.73133,.73133,.73133,.95958,.95958,.95958,.95958,.88506,.90872,.85938,.85938,.85938,.85938,.85938,.85284,.87068,.90399,.90399,.90399,.90399,.77892,.79795,.90807,.94908,.94908,.94908,.94908,.94908,.94908,.85887,.74012,.88323,.88323,.88323,.88323,.88401,.88401,.88401,.88401,.8785,.86331,.86331,.86331,.86331,.86331,.86331,.90747,.89049,.86331,.86331,.86331,.86331,.84548,.86411,.84548,.83908,.94908,.83908,.94908,.83908,.94908,.71805,.74012,.71805,.74012,.71805,.74012,.71805,.74012,.87289,.79538,.88506,.92726,.73133,.88323,.73133,.88323,.73133,.88323,.73133,.88323,.73133,.88323,.81921,.86411,.81921,.86411,.81921,.86411,1,1,.87356,.86331,.91075,.8777,.95958,.88401,.95958,.88401,.95958,.88401,.95958,.88401,.95958,.88401,.76467,.90167,.59526,.91916,1,1,.86304,.69225,.88401,1,1,.70424,.77312,.91926,.88175,.70823,.94903,.90872,.86331,1,1,.90872,.86331,.86906,.88116,.86331,.85938,.86331,.85938,.86331,.85938,.86331,.87402,.86549,.77958,.90464,1,1,.77958,.90464,.69766,.70852,.69766,.70852,.69766,.70852,.69766,.70852,1,1,.81055,.75841,.81055,1.06452,.90399,.86331,.90399,.86331,.90399,.86331,.90399,.86331,.90399,.86331,.90399,.86331,.96068,.95794,.77892,.84548,.77892,.78257,.79492,.78257,.79492,.78257,.79492,.9297,.56892,.83908,.94908,.77539,.85887,.87068,.89049,1,1,.81055,1.04106,1.20528,1.20528,1,1.15543,.70088,.98387,.94721,1.33431,1.45894,.95161,1.48387,.83908,.80352,.57118,.6965,.56347,.79179,.55853,.80346,1.02988,.83908,.7762,.67174,.86036,.73133,.78257,.87356,.86441,.95958,.75727,.89019,1.04924,.90872,.74889,.85938,.87891,.79795,.7957,.81055,.77892,.97447,.82577,.97466,.87179,.95958,.77892,.94252,.95612,.8753,1.02988,.92733,.94252,.87411,.84021,.8728,.95612,.74081,.8753,1.02189,1.02988,.84814,.87445,.91822,.84723,.85668,.86331,.81344,.87581,.76422,.82046,.96057,.92733,.99375,.78022,.95452,.86015,1.02988,.92733,.86331,.92733,.86015,.73133,1,1,1,1,1,1,1,1,1,1,1,1,.90631,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.88323,1,1,1,1,1,1,1,1,1,1,1,1,.85174,1,1,1,1,1,1,.96068,.95794,.96068,.95794,.96068,.95794,.77892,.84548,1,1,.89552,.90527,1,.90363,.92794,.92794,.92794,.89807,.87012,.87012,.87012,.89552,.89552,1.42259,.71094,1.06152,1,1,1.03372,1.03372,.97171,1.4956,2.2807,.92972,.83406,.91133,.83326,.91133,1,1,1,.72021,1,1.23108,.83489,.88525,.88525,.81499,.90616,1.81055,.90527,1.81055,1.3107,1.53711,.94434,1.08696,1,.95018,.77192,.85284,.90747,1.17534,.69825,.9716,1.37077,.90747,.90747,.85356,.90747,.90747,1.44947,.85284,.8941,.8941,.70572,.8,.70572,.70572,.70572,.70572,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.99862,.99862,1,1,1,1,1,1.08004,.91027,1,1,1,.99862,1,1,1,1,1,1,1,1,1,1,1,1,.90727,.90727,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],Fa={lineHeight:1.2207,lineGap:.2207},Sa=[1.3877,1,1,1,1.17223,1.1293,.89552,.91133,.80395,1.02269,1.15601,.91056,.91056,1.2798,.85284,.89807,1,.90861,1.39543,.91133,.91133,.91133,.91133,.91133,.91133,.91133,.91133,.91133,.91133,.96309,.96309,.85284,.85284,.85284,.83319,.88071,.8675,.81552,.72346,.85193,.73206,.7522,.81105,.86275,.90685,.6377,.77892,.75593,1.02638,.89249,.84118,.77452,.85374,.75186,.67789,.79776,.88844,.85066,.94309,.77818,.7306,.76659,1.10369,1.38313,1.10369,1.06139,.89552,.8739,.9245,.9245,.83203,.9245,.85865,1.09842,.9245,.9245,1.03297,1.07692,.90918,1.03297,.94959,.9245,.92274,.9245,.9245,1.02933,.77832,1.20562,.9245,.8916,.98986,.86621,.89453,.79004,.94152,1.77256,.94152,.85284,.97801,.89552,.91133,.89552,.91133,1.91729,.89552,1.17889,1.13254,1.16359,.92098,.85284,.68787,.71353,.84737,.90747,1.0088,1.0044,.87683,1,1.09091,1,.92229,.739,1.15642,.92098,.76288,.80504,.80972,.75859,.8675,.8675,.8675,.8675,.8675,.8675,.76318,.72346,.73206,.73206,.73206,.73206,.90685,.90685,.90685,.90685,.86477,.89249,.84118,.84118,.84118,.84118,.84118,.85284,.84557,.88844,.88844,.88844,.88844,.7306,.77452,.86331,.9245,.9245,.9245,.9245,.9245,.9245,.84843,.83203,.85865,.85865,.85865,.85865,.82601,.82601,.82601,.82601,.94469,.9245,.92274,.92274,.92274,.92274,.92274,.90747,.86651,.9245,.9245,.9245,.9245,.89453,.9245,.89453,.8675,.9245,.8675,.9245,.8675,.9245,.72346,.83203,.72346,.83203,.72346,.83203,.72346,.83203,.85193,.8875,.86477,.99034,.73206,.85865,.73206,.85865,.73206,.85865,.73206,.85865,.73206,.85865,.81105,.9245,.81105,.9245,.81105,.9245,1,1,.86275,.9245,.90872,.93591,.90685,.82601,.90685,.82601,.90685,.82601,.90685,1.03297,.90685,.82601,.77896,1.05611,.6377,1.07692,1,1,.90918,.75593,1.03297,1,1,.76032,.9375,.98156,.93407,.77261,1.11429,.89249,.9245,1,1,.89249,.9245,.92534,.86698,.9245,.84118,.92274,.84118,.92274,.84118,.92274,.8667,.86291,.75186,1.02933,1,1,.75186,1.02933,.67789,.77832,.67789,.77832,.67789,.77832,.67789,.77832,1,1,.79776,.97655,.79776,1.23023,.88844,.9245,.88844,.9245,.88844,.9245,.88844,.9245,.88844,.9245,.88844,.9245,.94309,.98986,.7306,.89453,.7306,.76659,.79004,.76659,.79004,.76659,.79004,1.09231,.54873,.8675,.9245,.76318,.84843,.84557,.86651,1,1,.79776,1.20562,1.18622,1.18622,1,1.1437,.67009,.96334,.93695,1.35191,1.40909,.95161,1.48387,.8675,.90861,.6192,.7363,.64824,.82411,.56321,.85696,1.23516,.8675,.81552,.7286,.84134,.73206,.76659,.86275,.84369,.90685,.77892,.85871,1.02638,.89249,.75828,.84118,.85984,.77452,.76466,.79776,.7306,.90782,.77818,.903,.87291,.90685,.7306,.99058,1.03667,.94635,1.23516,.9849,.99058,.92393,.8916,.942,1.03667,.75026,.94635,1.0297,1.23516,.90918,.94048,.98217,.89746,.84153,.92274,.82507,.88832,.84438,.88178,1.03525,.9849,1.00225,.78086,.97248,.89404,1.23516,.9849,.92274,.9849,.89404,.73206,1,1,1,1,1,1,1,1,1,1,1,1,.89693,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.85865,1,1,1,1,1,1,1,1,1,1,1,1,.90933,1,1,1,1,1,1,.94309,.98986,.94309,.98986,.94309,.98986,.7306,.89453,1,1,.89552,.90527,1,.90186,1.12308,1.12308,1.12308,1.12308,1.2566,1.2566,1.2566,.89552,.89552,1.42259,.68994,1.03809,1,1,1.0176,1.0176,1.11523,1.4956,2.01462,.97858,.82616,.91133,.83437,.91133,1,1,1,.70508,1,1.23108,.79801,.84426,.84426,.774,.90572,1.81055,.90749,1.81055,1.28809,1.55469,.94434,1.07806,1,.97094,.7589,.85284,.90747,1.19658,.69825,.97622,1.33512,.90747,.90747,.85284,.90747,.90747,1.44947,.85284,.8941,.8941,.70572,.8,.70572,.70572,.70572,.70572,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.99862,.99862,1,1,1,1,1,1.0336,.91027,1,1,1,.99862,1,1,1,1,1,1,1,1,1,1,1,1,1.05859,1.05859,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],ka={lineHeight:1.2207,lineGap:.2207},Ra=[1.3877,1,1,1,1.17223,1.1293,.89552,.91133,.80395,1.02269,1.15601,.91056,.91056,1.2798,.85284,.89807,1,.90861,1.39016,.91133,.91133,.91133,.91133,.91133,.91133,.91133,.91133,.91133,.91133,.96309,.96309,.85284,.85284,.85284,.83319,.88071,.8675,.81552,.73834,.85193,.73206,.7522,.81105,.86275,.90685,.6377,.77892,.75593,1.02638,.89385,.85122,.77452,.86503,.75186,.68887,.79776,.88844,.85066,.94258,.77818,.7306,.76659,1.10369,1.39016,1.10369,1.06139,.89552,.8739,.86128,.94469,.8457,.94469,.89464,1.09842,.84636,.94469,1.03297,1.07692,.90918,1.03297,.95897,.94469,.9482,.94469,.94469,1.04692,.78223,1.20562,.94469,.90332,.98986,.86621,.90527,.79004,.94152,1.77256,.94152,.85284,.97801,.89552,.91133,.89552,.91133,1.91729,.89552,1.17889,1.13254,1.08707,.92098,.85284,.68787,.71353,.84737,.90747,1.0088,1.0044,.87683,1,1.09091,1,.92229,.739,1.15642,.92098,.76288,.80504,.80972,.75859,.8675,.8675,.8675,.8675,.8675,.8675,.76318,.73834,.73206,.73206,.73206,.73206,.90685,.90685,.90685,.90685,.86477,.89385,.85122,.85122,.85122,.85122,.85122,.85284,.85311,.88844,.88844,.88844,.88844,.7306,.77452,.86331,.86128,.86128,.86128,.86128,.86128,.86128,.8693,.8457,.89464,.89464,.89464,.89464,.82601,.82601,.82601,.82601,.94469,.94469,.9482,.9482,.9482,.9482,.9482,.90747,.86651,.94469,.94469,.94469,.94469,.90527,.94469,.90527,.8675,.86128,.8675,.86128,.8675,.86128,.73834,.8457,.73834,.8457,.73834,.8457,.73834,.8457,.85193,.92454,.86477,.9921,.73206,.89464,.73206,.89464,.73206,.89464,.73206,.89464,.73206,.89464,.81105,.84636,.81105,.84636,.81105,.84636,1,1,.86275,.94469,.90872,.95786,.90685,.82601,.90685,.82601,.90685,.82601,.90685,1.03297,.90685,.82601,.77741,1.05611,.6377,1.07692,1,1,.90918,.75593,1.03297,1,1,.76032,.90452,.98156,1.11842,.77261,1.11429,.89385,.94469,1,1,.89385,.94469,.95877,.86901,.94469,.85122,.9482,.85122,.9482,.85122,.9482,.8667,.90016,.75186,1.04692,1,1,.75186,1.04692,.68887,.78223,.68887,.78223,.68887,.78223,.68887,.78223,1,1,.79776,.92188,.79776,1.23023,.88844,.94469,.88844,.94469,.88844,.94469,.88844,.94469,.88844,.94469,.88844,.94469,.94258,.98986,.7306,.90527,.7306,.76659,.79004,.76659,.79004,.76659,.79004,1.09231,.54873,.8675,.86128,.76318,.8693,.85311,.86651,1,1,.79776,1.20562,1.18622,1.18622,1,1.1437,.67742,.96334,.93695,1.35191,1.40909,.95161,1.48387,.86686,.90861,.62267,.74359,.65649,.85498,.56963,.88254,1.23516,.8675,.81552,.75443,.84503,.73206,.76659,.86275,.85122,.90685,.77892,.85746,1.02638,.89385,.75657,.85122,.86275,.77452,.74171,.79776,.7306,.95165,.77818,.89772,.88831,.90685,.7306,.98142,1.02191,.96576,1.23516,.99018,.98142,.9236,.89258,.94035,1.02191,.78848,.96576,.9561,1.23516,.90918,.92578,.95424,.89746,.83969,.9482,.80113,.89442,.85208,.86155,.98022,.99018,1.00452,.81209,.99247,.89181,1.23516,.99018,.9482,.99018,.89181,.73206,1,1,1,1,1,1,1,1,1,1,1,1,.88844,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.89464,1,1,1,1,1,1,1,1,1,1,1,1,.96766,1,1,1,1,1,1,.94258,.98986,.94258,.98986,.94258,.98986,.7306,.90527,1,1,.89552,.90527,1,.90186,1.12308,1.12308,1.12308,1.12308,1.2566,1.2566,1.2566,.89552,.89552,1.42259,.69043,1.03809,1,1,1.0176,1.0176,1.11523,1.4956,2.01462,.99331,.82616,.91133,.84286,.91133,1,1,1,.70508,1,1.23108,.79801,.84426,.84426,.774,.90527,1.81055,.90527,1.81055,1.28809,1.55469,.94434,1.07806,1,.97094,.7589,.85284,.90747,1.19658,.69825,.97622,1.33512,.90747,.90747,.85356,.90747,.90747,1.44947,.85284,.8941,.8941,.70572,.8,.70572,.70572,.70572,.70572,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.99862,.99862,1,1,1,1,1,1.0336,.91027,1,1,1,.99862,1,1,1,1,1,1,1,1,1,1,1,1,1.05859,1.05859,1,1,1,1.07185,.99413,.96334,1.08065,1,1,1,1,1,1,1,1,1,1,1],Na={lineHeight:1.2207,lineGap:.2207},Ga=[.76116,1,1,1.0006,.99998,.99974,.99973,.99973,.99982,.99977,1.00087,.99998,.99998,.99959,1.00003,1.0006,.99998,1.0006,1.0006,.99973,.99973,.99973,.99973,.99973,.99973,.99973,.99973,.99973,.99973,.99998,1,1.00003,1.00003,1.00003,1.00026,.9999,.99977,.99977,.99977,.99977,1.00001,1.00026,1.00022,.99977,1.0006,.99973,.99977,1.00026,.99999,.99977,1.00022,1.00001,1.00022,.99977,1.00001,1.00026,.99977,1.00001,1.00016,1.00001,1.00001,1.00026,.99998,1.0006,.99998,1.00003,.99973,.99998,.99973,1.00026,.99973,1.00026,.99973,.99998,1.00026,1.00026,1.0006,1.0006,.99973,1.0006,.99982,1.00026,1.00026,1.00026,1.00026,.99959,.99973,.99998,1.00026,.99973,1.00022,.99973,.99973,1,.99959,1.00077,.99959,1.00003,.99998,.99973,.99973,.99973,.99973,1.00077,.99973,.99998,1.00025,.99968,.99973,1.00003,1.00025,.60299,1.00024,1.06409,1,1,.99998,1,.99973,1.0006,.99998,1,.99936,.99973,1.00002,1.00002,1.00002,1.00026,.99977,.99977,.99977,.99977,.99977,.99977,1,.99977,1.00001,1.00001,1.00001,1.00001,1.0006,1.0006,1.0006,1.0006,.99977,.99977,1.00022,1.00022,1.00022,1.00022,1.00022,1.00003,1.00022,.99977,.99977,.99977,.99977,1.00001,1.00001,1.00026,.99973,.99973,.99973,.99973,.99973,.99973,.99982,.99973,.99973,.99973,.99973,.99973,1.0006,1.0006,1.0006,1.0006,1.00026,1.00026,1.00026,1.00026,1.00026,1.00026,1.00026,1.06409,1.00026,1.00026,1.00026,1.00026,1.00026,.99973,1.00026,.99973,.99977,.99973,.99977,.99973,.99977,.99973,.99977,.99973,.99977,.99973,.99977,.99973,.99977,.99973,.99977,1.03374,.99977,1.00026,1.00001,.99973,1.00001,.99973,1.00001,.99973,1.00001,.99973,1.00001,.99973,1.00022,1.00026,1.00022,1.00026,1.00022,1.00026,1.00022,1.00026,.99977,1.00026,.99977,1.00026,1.0006,1.0006,1.0006,1.0006,1.0006,1.0006,1.0006,1.0006,1.0006,1.0006,1.00042,.99973,.99973,1.0006,.99977,.99973,.99973,1.00026,1.0006,1.00026,1.0006,1.00026,1.03828,1.00026,.99999,1.00026,1.0006,.99977,1.00026,.99977,1.00026,.99977,1.00026,.9993,.9998,1.00026,1.00022,1.00026,1.00022,1.00026,1.00022,1.00026,1,1.00016,.99977,.99959,.99977,.99959,.99977,.99959,1.00001,.99973,1.00001,.99973,1.00001,.99973,1.00001,.99973,1.00026,.99998,1.00026,.8121,1.00026,.99998,.99977,1.00026,.99977,1.00026,.99977,1.00026,.99977,1.00026,.99977,1.00026,.99977,1.00026,1.00016,1.00022,1.00001,.99973,1.00001,1.00026,1,1.00026,1,1.00026,1,1.0006,.99973,.99977,.99973,1,.99982,1.00022,1.00026,1.00001,.99973,1.00026,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,1.00034,.99977,1,.99997,1.00026,1.00078,1.00036,.99973,1.00013,1.0006,.99977,.99977,.99988,.85148,1.00001,1.00026,.99977,1.00022,1.0006,.99977,1.00001,.99999,.99977,1.00069,1.00022,.99977,1.00001,.99984,1.00026,1.00001,1.00024,1.00001,.9999,1,1.0006,1.00001,1.00041,.99962,1.00026,1.0006,.99995,1.00041,.99942,.99973,.99927,1.00082,.99902,1.00026,1.00087,1.0006,1.00069,.99973,.99867,.99973,.9993,1.00026,1.00049,1.00056,1,.99988,.99935,.99995,.99954,1.00055,.99945,1.00032,1.0006,.99995,1.00026,.99995,1.00032,1.00001,1.00008,.99971,1.00019,.9994,1.00001,1.0006,1.00044,.99973,1.00023,1.00047,1,.99942,.99561,.99989,1.00035,.99977,1.00035,.99977,1.00019,.99944,1.00001,1.00021,.99926,1.00035,1.00035,.99942,1.00048,.99999,.99977,1.00022,1.00035,1.00001,.99977,1.00026,.99989,1.00057,1.00001,.99936,1.00052,1.00012,.99996,1.00043,1,1.00035,.9994,.99976,1.00035,.99973,1.00052,1.00041,1.00119,1.00037,.99973,1.00002,.99986,1.00041,1.00041,.99902,.9996,1.00034,.99999,1.00026,.99999,1.00026,.99973,1.00052,.99973,1,.99973,1.00041,1.00075,.9994,1.0003,.99999,1,1.00041,.99955,1,.99915,.99973,.99973,1.00026,1.00119,.99955,.99973,1.0006,.99911,1.0006,1.00026,.99972,1.00026,.99902,1.00041,.99973,.99999,1,1,1.00038,1.0005,1.00016,1.00022,1.00016,1.00022,1.00016,1.00022,1.00001,.99973,1,1,.99973,1,1,.99955,1.0006,1.0006,1.0006,1.0006,1,1,1,.99973,.99973,.99972,1,1,1.00106,.99999,.99998,.99998,.99999,.99998,1.66475,1,.99973,.99973,1.00023,.99973,.99971,1.00047,1.00023,1,.99991,.99984,1.00002,1.00002,1.00002,1.00002,1,1,1,1,1,1,1,.99972,1,1.20985,1.39713,1.00003,1.00031,1.00015,1,.99561,1.00027,1.00031,1.00031,.99915,1.00031,1.00031,.99999,1.00003,.99999,.99999,1.41144,1.6,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.40579,1.40579,1.36625,.99999,1,.99861,.99861,1,1.00026,1.00026,1.00026,1.00026,.99972,.99999,.99999,.99999,.99999,1.40483,1,.99977,1.00054,1,1,.99953,.99962,1.00042,.9995,1,1,1,1,1,1,1,1,.99998,.99998,.99998,.99998,1,1,1,1,1,1,1,1,1,1,1],xa={lineHeight:1.2,lineGap:.2},Ma=[.76116,1,1,1.0006,.99998,.99974,.99973,.99973,.99982,.99977,1.00087,.99998,.99998,.99959,1.00003,1.0006,.99998,1.0006,1.0006,.99973,.99973,.99973,.99973,.99973,.99973,.99973,.99973,.99973,.99973,.99998,1,1.00003,1.00003,1.00003,1.00026,.9999,.99977,.99977,.99977,.99977,1.00001,1.00026,1.00022,.99977,1.0006,.99973,.99977,1.00026,.99999,.99977,1.00022,1.00001,1.00022,.99977,1.00001,1.00026,.99977,1.00001,1.00016,1.00001,1.00001,1.00026,.99998,1.0006,.99998,1.00003,.99973,.99998,.99973,1.00026,.99973,1.00026,.99973,.99998,1.00026,1.00026,1.0006,1.0006,.99973,1.0006,.99982,1.00026,1.00026,1.00026,1.00026,.99959,.99973,.99998,1.00026,.99973,1.00022,.99973,.99973,1,.99959,1.00077,.99959,1.00003,.99998,.99973,.99973,.99973,.99973,1.00077,.99973,.99998,1.00025,.99968,.99973,1.00003,1.00025,.60299,1.00024,1.06409,1,1,.99998,1,.99973,1.0006,.99998,1,.99936,.99973,1.00002,1.00002,1.00002,1.00026,.99977,.99977,.99977,.99977,.99977,.99977,1,.99977,1.00001,1.00001,1.00001,1.00001,1.0006,1.0006,1.0006,1.0006,.99977,.99977,1.00022,1.00022,1.00022,1.00022,1.00022,1.00003,1.00022,.99977,.99977,.99977,.99977,1.00001,1.00001,1.00026,.99973,.99973,.99973,.99973,.99973,.99973,.99982,.99973,.99973,.99973,.99973,.99973,1.0006,1.0006,1.0006,1.0006,1.00026,1.00026,1.00026,1.00026,1.00026,1.00026,1.00026,1.06409,1.00026,1.00026,1.00026,1.00026,1.00026,.99973,1.00026,.99973,.99977,.99973,.99977,.99973,.99977,.99973,.99977,.99973,.99977,.99973,.99977,.99973,.99977,.99973,.99977,1.0044,.99977,1.00026,1.00001,.99973,1.00001,.99973,1.00001,.99973,1.00001,.99973,1.00001,.99973,1.00022,1.00026,1.00022,1.00026,1.00022,1.00026,1.00022,1.00026,.99977,1.00026,.99977,1.00026,1.0006,1.0006,1.0006,1.0006,1.0006,1.0006,1.0006,1.0006,1.0006,1.0006,.99971,.99973,.99973,1.0006,.99977,.99973,.99973,1.00026,1.0006,1.00026,1.0006,1.00026,1.01011,1.00026,.99999,1.00026,1.0006,.99977,1.00026,.99977,1.00026,.99977,1.00026,.9993,.9998,1.00026,1.00022,1.00026,1.00022,1.00026,1.00022,1.00026,1,1.00016,.99977,.99959,.99977,.99959,.99977,.99959,1.00001,.99973,1.00001,.99973,1.00001,.99973,1.00001,.99973,1.00026,.99998,1.00026,.8121,1.00026,.99998,.99977,1.00026,.99977,1.00026,.99977,1.00026,.99977,1.00026,.99977,1.00026,.99977,1.00026,1.00016,1.00022,1.00001,.99973,1.00001,1.00026,1,1.00026,1,1.00026,1,1.0006,.99973,.99977,.99973,1,.99982,1.00022,1.00026,1.00001,.99973,1.00026,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99977,1,1,1.00026,.99969,.99972,.99981,.9998,1.0006,.99977,.99977,1.00022,.91155,1.00001,1.00026,.99977,1.00022,1.0006,.99977,1.00001,.99999,.99977,.99966,1.00022,1.00032,1.00001,.99944,1.00026,1.00001,.99968,1.00001,1.00047,1,1.0006,1.00001,.99981,1.00101,1.00026,1.0006,.99948,.99981,1.00064,.99973,.99942,1.00101,1.00061,1.00026,1.00069,1.0006,1.00014,.99973,1.01322,.99973,1.00065,1.00026,1.00012,.99923,1,1.00064,1.00076,.99948,1.00055,1.00063,1.00007,.99943,1.0006,.99948,1.00026,.99948,.99943,1.00001,1.00001,1.00029,1.00038,1.00035,1.00001,1.0006,1.0006,.99973,.99978,1.00001,1.00057,.99989,.99967,.99964,.99967,.99977,.99999,.99977,1.00038,.99977,1.00001,.99973,1.00066,.99967,.99967,1.00041,.99998,.99999,.99977,1.00022,.99967,1.00001,.99977,1.00026,.99964,1.00031,1.00001,.99999,.99999,1,1.00023,1,1,.99999,1.00035,1.00001,.99999,.99973,.99977,.99999,1.00058,.99973,.99973,.99955,.9995,1.00026,1.00026,1.00032,.99989,1.00034,.99999,1.00026,1.00026,1.00026,.99973,.45998,.99973,1.00026,.99973,1.00001,.99999,.99982,.99994,.99996,1,1.00042,1.00044,1.00029,1.00023,.99973,.99973,1.00026,.99949,1.00002,.99973,1.0006,1.0006,1.0006,.99975,1.00026,1.00026,1.00032,.98685,.99973,1.00026,1,1,.99966,1.00044,1.00016,1.00022,1.00016,1.00022,1.00016,1.00022,1.00001,.99973,1,1,.99973,1,1,.99955,1.0006,1.0006,1.0006,1.0006,1,1,1,.99973,.99973,.99972,1,1,1.00106,.99999,.99998,.99998,.99999,.99998,1.66475,1,.99973,.99973,1,.99973,.99971,.99978,1,1,.99991,.99984,1.00002,1.00002,1.00002,1.00002,1.00098,1,1,1,1.00049,1,1,.99972,1,1.20985,1.39713,1.00003,1.00031,1.00015,1,.99561,1.00027,1.00031,1.00031,.99915,1.00031,1.00031,.99999,1.00003,.99999,.99999,1.41144,1.6,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.40579,1.40579,1.36625,.99999,1,.99861,.99861,1,1.00026,1.00026,1.00026,1.00026,.99972,.99999,.99999,.99999,.99999,1.40483,1,.99977,1.00054,1,1,.99953,.99962,1.00042,.9995,1,1,1,1,1,1,1,1,.99998,.99998,.99998,.99998,1,1,1,1,1,1,1,1,1,1,1],Ua={lineHeight:1.35,lineGap:.2},La=[.76116,1,1,1.0006,1.0006,1.00006,.99973,.99973,.99982,1.00001,1.00043,.99998,.99998,.99959,1.00003,1.0006,.99998,1.0006,1.0006,.99973,.99973,.99973,.99973,.99973,.99973,.99973,.99973,.99973,.99973,1.0006,1,1.00003,1.00003,1.00003,.99973,.99987,1.00001,1.00001,.99977,.99977,1.00001,1.00026,1.00022,.99977,1.0006,1,1.00001,.99973,.99999,.99977,1.00022,1.00001,1.00022,.99977,1.00001,1.00026,.99977,1.00001,1.00016,1.00001,1.00001,1.00026,1.0006,1.0006,1.0006,.99949,.99973,.99998,.99973,.99973,1,.99973,.99973,1.0006,.99973,.99973,.99924,.99924,1,.99924,.99999,.99973,.99973,.99973,.99973,.99998,1,1.0006,.99973,1,.99977,1,1,1,1.00005,1.0009,1.00005,1.00003,.99998,.99973,.99973,.99973,.99973,1.0009,.99973,.99998,1.00025,.99968,.99973,1.00003,1.00025,.60299,1.00024,1.06409,1,1,.99998,1,.9998,1.0006,.99998,1,.99936,.99973,1.00002,1.00002,1.00002,1.00026,1.00001,1.00001,1.00001,1.00001,1.00001,1.00001,1,.99977,1.00001,1.00001,1.00001,1.00001,1.0006,1.0006,1.0006,1.0006,.99977,.99977,1.00022,1.00022,1.00022,1.00022,1.00022,1.00003,1.00022,.99977,.99977,.99977,.99977,1.00001,1.00001,1.00026,.99973,.99973,.99973,.99973,.99973,.99973,.99982,1,.99973,.99973,.99973,.99973,1.0006,1.0006,1.0006,1.0006,.99973,.99973,.99973,.99973,.99973,.99973,.99973,1.06409,1.00026,.99973,.99973,.99973,.99973,1,.99973,1,1.00001,.99973,1.00001,.99973,1.00001,.99973,.99977,1,.99977,1,.99977,1,.99977,1,.99977,1.0288,.99977,.99973,1.00001,.99973,1.00001,.99973,1.00001,.99973,1.00001,.99973,1.00001,.99973,1.00022,.99973,1.00022,.99973,1.00022,.99973,1.00022,.99973,.99977,.99973,.99977,.99973,1.0006,1.0006,1.0006,1.0006,1.0006,1.0006,1.0006,.99924,1.0006,1.0006,.99946,1.00034,1,.99924,1.00001,1,1,.99973,.99924,.99973,.99924,.99973,1.06311,.99973,1.00024,.99973,.99924,.99977,.99973,.99977,.99973,.99977,.99973,1.00041,.9998,.99973,1.00022,.99973,1.00022,.99973,1.00022,.99973,1,1.00016,.99977,.99998,.99977,.99998,.99977,.99998,1.00001,1,1.00001,1,1.00001,1,1.00001,1,1.00026,1.0006,1.00026,.89547,1.00026,1.0006,.99977,.99973,.99977,.99973,.99977,.99973,.99977,.99973,.99977,.99973,.99977,.99973,1.00016,.99977,1.00001,1,1.00001,1.00026,1,1.00026,1,1.00026,1,.99924,.99973,1.00001,.99973,1,.99982,1.00022,1.00026,1.00001,1,1.00026,1.0006,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,1.00001,1,1.00054,.99977,1.00084,1.00007,.99973,1.00013,.99924,1.00001,1.00001,.99945,.91221,1.00001,1.00026,.99977,1.00022,1.0006,1.00001,1.00001,.99999,.99977,.99933,1.00022,1.00054,1.00001,1.00065,1.00026,1.00001,1.0001,1.00001,1.00052,1,1.0006,1.00001,.99945,.99897,.99968,.99924,1.00036,.99945,.99949,1,1.0006,.99897,.99918,.99968,.99911,.99924,1,.99962,1.01487,1,1.0005,.99973,1.00012,1.00043,1,.99995,.99994,1.00036,.99947,1.00019,1.00063,1.00025,.99924,1.00036,.99973,1.00036,1.00025,1.00001,1.00001,1.00027,1.0001,1.00068,1.00001,1.0006,1.0006,1,1.00008,.99957,.99972,.9994,.99954,.99975,1.00051,1.00001,1.00019,1.00001,1.0001,.99986,1.00001,1.00001,1.00038,.99954,.99954,.9994,1.00066,.99999,.99977,1.00022,1.00054,1.00001,.99977,1.00026,.99975,1.0001,1.00001,.99993,.9995,.99955,1.00016,.99978,.99974,1.00019,1.00022,.99955,1.00053,.99973,1.00089,1.00005,.99967,1.00048,.99973,1.00002,1.00034,.99973,.99973,.99964,1.00006,1.00066,.99947,.99973,.98894,.99973,1,.44898,1,.99946,1,1.00039,1.00082,.99991,.99991,.99985,1.00022,1.00023,1.00061,1.00006,.99966,.99973,.99973,.99973,1.00019,1.0008,1,.99924,.99924,.99924,.99983,1.00044,.99973,.99964,.98332,1,.99973,1,1,.99962,.99895,1.00016,.99977,1.00016,.99977,1.00016,.99977,1.00001,1,1,1,.99973,1,1,.99955,.99924,.99924,.99924,.99924,.99998,.99998,.99998,.99973,.99973,.99972,1,1,1.00267,.99999,.99998,.99998,1,.99998,1.66475,1,.99973,.99973,1.00023,.99973,1.00423,.99925,.99999,1,.99991,.99984,1.00002,1.00002,1.00002,1.00002,1.00049,1,1.00245,1,1,1,1,.96329,1,1.20985,1.39713,1.00003,.8254,1.00015,1,1.00035,1.00027,1.00031,1.00031,1.00003,1.00031,1.00031,.99999,1.00003,.99999,.99999,1.41144,1.6,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.40579,1.40579,1.36625,.99999,1,.99861,.99861,1,1.00026,1.00026,1.00026,1.00026,.95317,.99999,.99999,.99999,.99999,1.40483,1,.99977,1.00054,1,1,.99953,.99962,1.00042,.9995,1,1,1,1,1,1,1,1,.99998,.99998,.99998,.99998,1,1,1,1,1,1,1,1,1,1,1],Ja={lineHeight:1.35,lineGap:.2},Ha=[.76116,1,1,1.0006,1.0006,1.00006,.99973,.99973,.99982,1.00001,1.00043,.99998,.99998,.99959,1.00003,1.0006,.99998,1.0006,1.0006,.99973,.99973,.99973,.99973,.99973,.99973,.99973,.99973,.99973,.99973,1.0006,1,1.00003,1.00003,1.00003,.99973,.99987,1.00001,1.00001,.99977,.99977,1.00001,1.00026,1.00022,.99977,1.0006,1,1.00001,.99973,.99999,.99977,1.00022,1.00001,1.00022,.99977,1.00001,1.00026,.99977,1.00001,1.00016,1.00001,1.00001,1.00026,1.0006,1.0006,1.0006,.99949,.99973,.99998,.99973,.99973,1,.99973,.99973,1.0006,.99973,.99973,.99924,.99924,1,.99924,.99999,.99973,.99973,.99973,.99973,.99998,1,1.0006,.99973,1,.99977,1,1,1,1.00005,1.0009,1.00005,1.00003,.99998,.99973,.99973,.99973,.99973,1.0009,.99973,.99998,1.00025,.99968,.99973,1.00003,1.00025,.60299,1.00024,1.06409,1,1,.99998,1,.9998,1.0006,.99998,1,.99936,.99973,1.00002,1.00002,1.00002,1.00026,1.00001,1.00001,1.00001,1.00001,1.00001,1.00001,1,.99977,1.00001,1.00001,1.00001,1.00001,1.0006,1.0006,1.0006,1.0006,.99977,.99977,1.00022,1.00022,1.00022,1.00022,1.00022,1.00003,1.00022,.99977,.99977,.99977,.99977,1.00001,1.00001,1.00026,.99973,.99973,.99973,.99973,.99973,.99973,.99982,1,.99973,.99973,.99973,.99973,1.0006,1.0006,1.0006,1.0006,.99973,.99973,.99973,.99973,.99973,.99973,.99973,1.06409,1.00026,.99973,.99973,.99973,.99973,1,.99973,1,1.00001,.99973,1.00001,.99973,1.00001,.99973,.99977,1,.99977,1,.99977,1,.99977,1,.99977,1.04596,.99977,.99973,1.00001,.99973,1.00001,.99973,1.00001,.99973,1.00001,.99973,1.00001,.99973,1.00022,.99973,1.00022,.99973,1.00022,.99973,1.00022,.99973,.99977,.99973,.99977,.99973,1.0006,1.0006,1.0006,1.0006,1.0006,1.0006,1.0006,.99924,1.0006,1.0006,1.00019,1.00034,1,.99924,1.00001,1,1,.99973,.99924,.99973,.99924,.99973,1.02572,.99973,1.00005,.99973,.99924,.99977,.99973,.99977,.99973,.99977,.99973,.99999,.9998,.99973,1.00022,.99973,1.00022,.99973,1.00022,.99973,1,1.00016,.99977,.99998,.99977,.99998,.99977,.99998,1.00001,1,1.00001,1,1.00001,1,1.00001,1,1.00026,1.0006,1.00026,.84533,1.00026,1.0006,.99977,.99973,.99977,.99973,.99977,.99973,.99977,.99973,.99977,.99973,.99977,.99973,1.00016,.99977,1.00001,1,1.00001,1.00026,1,1.00026,1,1.00026,1,.99924,.99973,1.00001,.99973,1,.99982,1.00022,1.00026,1.00001,1,1.00026,1.0006,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99928,1,.99977,1.00013,1.00055,.99947,.99945,.99941,.99924,1.00001,1.00001,1.0004,.91621,1.00001,1.00026,.99977,1.00022,1.0006,1.00001,1.00005,.99999,.99977,1.00015,1.00022,.99977,1.00001,.99973,1.00026,1.00001,1.00019,1.00001,.99946,1,1.0006,1.00001,.99978,1.00045,.99973,.99924,1.00023,.99978,.99966,1,1.00065,1.00045,1.00019,.99973,.99973,.99924,1,1,.96499,1,1.00055,.99973,1.00008,1.00027,1,.9997,.99995,1.00023,.99933,1.00019,1.00015,1.00031,.99924,1.00023,.99973,1.00023,1.00031,1.00001,.99928,1.00029,1.00092,1.00035,1.00001,1.0006,1.0006,1,.99988,.99975,1,1.00082,.99561,.9996,1.00035,1.00001,.99962,1.00001,1.00092,.99964,1.00001,.99963,.99999,1.00035,1.00035,1.00082,.99962,.99999,.99977,1.00022,1.00035,1.00001,.99977,1.00026,.9996,.99967,1.00001,1.00034,1.00074,1.00054,1.00053,1.00063,.99971,.99962,1.00035,.99975,.99977,.99973,1.00043,.99953,1.0007,.99915,.99973,1.00008,.99892,1.00073,1.00073,1.00114,.99915,1.00073,.99955,.99973,1.00092,.99973,1,.99998,1,1.0003,1,1.00043,1.00001,.99969,1.0003,1,1.00035,1.00001,.9995,1,1.00092,.99973,.99973,.99973,1.0007,.9995,1,.99924,1.0006,.99924,.99972,1.00062,.99973,1.00114,1.00073,1,.99955,1,1,1.00047,.99968,1.00016,.99977,1.00016,.99977,1.00016,.99977,1.00001,1,1,1,.99973,1,1,.99955,.99924,.99924,.99924,.99924,.99998,.99998,.99998,.99973,.99973,.99972,1,1,1.00267,.99999,.99998,.99998,1,.99998,1.66475,1,.99973,.99973,1.00023,.99973,.99971,.99925,1.00023,1,.99991,.99984,1.00002,1.00002,1.00002,1.00002,1,1,1,1,1,1,1,.96329,1,1.20985,1.39713,1.00003,.8254,1.00015,1,1.00035,1.00027,1.00031,1.00031,.99915,1.00031,1.00031,.99999,1.00003,.99999,.99999,1.41144,1.6,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.40579,1.40579,1.36625,.99999,1,.99861,.99861,1,1.00026,1.00026,1.00026,1.00026,.95317,.99999,.99999,.99999,.99999,1.40483,1,.99977,1.00054,1,1,.99953,.99962,1.00042,.9995,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],Ya={lineHeight:1.2,lineGap:.2},va=[365,0,333,278,333,474,556,556,889,722,238,333,333,389,584,278,333,278,278,556,556,556,556,556,556,556,556,556,556,333,333,584,584,584,611,975,722,722,722,722,667,611,778,722,278,556,722,611,833,722,778,667,778,722,667,611,722,667,944,667,667,611,333,278,333,584,556,333,556,611,556,611,556,333,611,611,278,278,556,278,889,611,611,611,611,389,556,333,611,556,778,556,556,500,389,280,389,584,333,556,556,556,556,280,556,333,737,370,556,584,737,552,400,549,333,333,333,576,556,278,333,333,365,556,834,834,834,611,722,722,722,722,722,722,1e3,722,667,667,667,667,278,278,278,278,722,722,778,778,778,778,778,584,778,722,722,722,722,667,667,611,556,556,556,556,556,556,889,556,556,556,556,556,278,278,278,278,611,611,611,611,611,611,611,549,611,611,611,611,611,556,611,556,722,556,722,556,722,556,722,556,722,556,722,556,722,556,722,719,722,611,667,556,667,556,667,556,667,556,667,556,778,611,778,611,778,611,778,611,722,611,722,611,278,278,278,278,278,278,278,278,278,278,785,556,556,278,722,556,556,611,278,611,278,611,385,611,479,611,278,722,611,722,611,722,611,708,723,611,778,611,778,611,778,611,1e3,944,722,389,722,389,722,389,667,556,667,556,667,556,667,556,611,333,611,479,611,333,722,611,722,611,722,611,722,611,722,611,722,611,944,778,667,556,667,611,500,611,500,611,500,278,556,722,556,1e3,889,778,611,667,556,611,333,333,333,333,333,333,333,333,333,333,333,465,722,333,853,906,474,825,927,838,278,722,722,601,719,667,611,722,778,278,722,667,833,722,644,778,722,667,600,611,667,821,667,809,802,278,667,615,451,611,278,582,615,610,556,606,475,460,611,541,278,558,556,612,556,445,611,766,619,520,684,446,582,715,576,753,845,278,582,611,582,845,667,669,885,567,711,667,278,276,556,1094,1062,875,610,722,622,719,722,719,722,567,712,667,904,626,719,719,610,702,833,722,778,719,667,722,611,622,854,667,730,703,1005,1019,870,979,719,711,1031,719,556,618,615,417,635,556,709,497,615,615,500,635,740,604,611,604,611,556,490,556,875,556,615,581,833,844,729,854,615,552,854,583,556,556,611,417,552,556,278,281,278,969,906,611,500,615,556,604,778,611,487,447,944,778,944,778,944,778,667,556,333,333,556,1e3,1e3,552,278,278,278,278,500,500,500,556,556,350,1e3,1e3,240,479,333,333,604,333,167,396,556,556,1094,556,885,489,1115,1e3,768,600,834,834,834,834,1e3,500,1e3,500,1e3,500,500,494,612,823,713,584,549,713,979,722,274,549,549,583,549,549,604,584,604,604,708,625,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,729,604,604,354,354,1e3,990,990,990,990,494,604,604,604,604,354,1021,1052,917,750,750,531,656,594,510,500,750,750,611,611,333,333,333,333,333,333,333,333,222,222,333,333,333,333,333,333,333,333],Ka=[-1,-1,-1,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,161,162,163,164,165,166,167,168,169,170,171,172,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,402,506,507,508,509,510,511,536,537,538,539,710,711,713,728,729,730,731,732,733,900,901,902,903,904,905,906,908,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,1117,1118,1119,1138,1139,1168,1169,7808,7809,7810,7811,7812,7813,7922,7923,8208,8209,8211,8212,8213,8215,8216,8217,8218,8219,8220,8221,8222,8224,8225,8226,8230,8240,8242,8243,8249,8250,8252,8254,8260,8319,8355,8356,8359,8364,8453,8467,8470,8482,8486,8494,8539,8540,8541,8542,8592,8593,8594,8595,8596,8597,8616,8706,8710,8719,8721,8722,8730,8734,8735,8745,8747,8776,8800,8801,8804,8805,8962,8976,8992,8993,9472,9474,9484,9488,9492,9496,9500,9508,9516,9524,9532,9552,9553,9554,9555,9556,9557,9558,9559,9560,9561,9562,9563,9564,9565,9566,9567,9568,9569,9570,9571,9572,9573,9574,9575,9576,9577,9578,9579,9580,9600,9604,9608,9612,9616,9617,9618,9619,9632,9633,9642,9643,9644,9650,9658,9660,9668,9674,9675,9679,9688,9689,9702,9786,9787,9788,9792,9794,9824,9827,9829,9830,9834,9835,9836,61441,61442,61445,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],Ta=[365,0,333,278,333,474,556,556,889,722,238,333,333,389,584,278,333,278,278,556,556,556,556,556,556,556,556,556,556,333,333,584,584,584,611,975,722,722,722,722,667,611,778,722,278,556,722,611,833,722,778,667,778,722,667,611,722,667,944,667,667,611,333,278,333,584,556,333,556,611,556,611,556,333,611,611,278,278,556,278,889,611,611,611,611,389,556,333,611,556,778,556,556,500,389,280,389,584,333,556,556,556,556,280,556,333,737,370,556,584,737,552,400,549,333,333,333,576,556,278,333,333,365,556,834,834,834,611,722,722,722,722,722,722,1e3,722,667,667,667,667,278,278,278,278,722,722,778,778,778,778,778,584,778,722,722,722,722,667,667,611,556,556,556,556,556,556,889,556,556,556,556,556,278,278,278,278,611,611,611,611,611,611,611,549,611,611,611,611,611,556,611,556,722,556,722,556,722,556,722,556,722,556,722,556,722,556,722,740,722,611,667,556,667,556,667,556,667,556,667,556,778,611,778,611,778,611,778,611,722,611,722,611,278,278,278,278,278,278,278,278,278,278,782,556,556,278,722,556,556,611,278,611,278,611,396,611,479,611,278,722,611,722,611,722,611,708,723,611,778,611,778,611,778,611,1e3,944,722,389,722,389,722,389,667,556,667,556,667,556,667,556,611,333,611,479,611,333,722,611,722,611,722,611,722,611,722,611,722,611,944,778,667,556,667,611,500,611,500,611,500,278,556,722,556,1e3,889,778,611,667,556,611,333,333,333,333,333,333,333,333,333,333,333,333,722,333,854,906,473,844,930,847,278,722,722,610,671,667,611,722,778,278,722,667,833,722,657,778,718,667,590,611,667,822,667,829,781,278,667,620,479,611,278,591,620,621,556,610,479,492,611,558,278,566,556,603,556,450,611,712,605,532,664,409,591,704,578,773,834,278,591,611,591,834,667,667,886,614,719,667,278,278,556,1094,1042,854,622,719,677,719,722,708,722,614,722,667,927,643,719,719,615,687,833,722,778,719,667,722,611,677,781,667,729,708,979,989,854,1e3,708,719,1042,729,556,619,604,534,618,556,736,510,611,611,507,622,740,604,611,611,611,556,889,556,885,556,646,583,889,935,707,854,594,552,865,589,556,556,611,469,563,556,278,278,278,969,906,611,507,619,556,611,778,611,575,467,944,778,944,778,944,778,667,556,333,333,556,1e3,1e3,552,278,278,278,278,500,500,500,556,556,350,1e3,1e3,240,479,333,333,604,333,167,396,556,556,1104,556,885,516,1146,1e3,768,600,834,834,834,834,999,500,1e3,500,1e3,500,500,494,612,823,713,584,549,713,979,722,274,549,549,583,549,549,604,584,604,604,708,625,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,729,604,604,354,354,1e3,990,990,990,990,494,604,604,604,604,354,1021,1052,917,750,750,531,656,594,510,500,750,750,611,611,333,333,333,333,333,333,333,333,222,222,333,333,333,333,333,333,333,333],qa=[-1,-1,-1,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,161,162,163,164,165,166,167,168,169,170,171,172,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,402,506,507,508,509,510,511,536,537,538,539,710,711,713,728,729,730,731,732,733,900,901,902,903,904,905,906,908,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,1117,1118,1119,1138,1139,1168,1169,7808,7809,7810,7811,7812,7813,7922,7923,8208,8209,8211,8212,8213,8215,8216,8217,8218,8219,8220,8221,8222,8224,8225,8226,8230,8240,8242,8243,8249,8250,8252,8254,8260,8319,8355,8356,8359,8364,8453,8467,8470,8482,8486,8494,8539,8540,8541,8542,8592,8593,8594,8595,8596,8597,8616,8706,8710,8719,8721,8722,8730,8734,8735,8745,8747,8776,8800,8801,8804,8805,8962,8976,8992,8993,9472,9474,9484,9488,9492,9496,9500,9508,9516,9524,9532,9552,9553,9554,9555,9556,9557,9558,9559,9560,9561,9562,9563,9564,9565,9566,9567,9568,9569,9570,9571,9572,9573,9574,9575,9576,9577,9578,9579,9580,9600,9604,9608,9612,9616,9617,9618,9619,9632,9633,9642,9643,9644,9650,9658,9660,9668,9674,9675,9679,9688,9689,9702,9786,9787,9788,9792,9794,9824,9827,9829,9830,9834,9835,9836,61441,61442,61445,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],Oa=[365,0,333,278,278,355,556,556,889,667,191,333,333,389,584,278,333,278,278,556,556,556,556,556,556,556,556,556,556,278,278,584,584,584,556,1015,667,667,722,722,667,611,778,722,278,500,667,556,833,722,778,667,778,722,667,611,722,667,944,667,667,611,278,278,278,469,556,333,556,556,500,556,556,278,556,556,222,222,500,222,833,556,556,556,556,333,500,278,556,500,722,500,500,500,334,260,334,584,333,556,556,556,556,260,556,333,737,370,556,584,737,552,400,549,333,333,333,576,537,278,333,333,365,556,834,834,834,611,667,667,667,667,667,667,1e3,722,667,667,667,667,278,278,278,278,722,722,778,778,778,778,778,584,778,722,722,722,722,667,667,611,556,556,556,556,556,556,889,500,556,556,556,556,278,278,278,278,556,556,556,556,556,556,556,549,611,556,556,556,556,500,556,500,667,556,667,556,667,556,722,500,722,500,722,500,722,500,722,625,722,556,667,556,667,556,667,556,667,556,667,556,778,556,778,556,778,556,778,556,722,556,722,556,278,278,278,278,278,278,278,222,278,278,733,444,500,222,667,500,500,556,222,556,222,556,281,556,400,556,222,722,556,722,556,722,556,615,723,556,778,556,778,556,778,556,1e3,944,722,333,722,333,722,333,667,500,667,500,667,500,667,500,611,278,611,354,611,278,722,556,722,556,722,556,722,556,722,556,722,556,944,722,667,500,667,611,500,611,500,611,500,222,556,667,556,1e3,889,778,611,667,500,611,278,333,333,333,333,333,333,333,333,333,333,333,667,278,789,846,389,794,865,775,222,667,667,570,671,667,611,722,778,278,667,667,833,722,648,778,725,667,600,611,667,837,667,831,761,278,667,570,439,555,222,550,570,571,500,556,439,463,555,542,222,500,492,548,500,447,556,670,573,486,603,374,550,652,546,728,779,222,550,556,550,779,667,667,843,544,708,667,278,278,500,1066,982,844,589,715,639,724,667,651,667,544,704,667,917,614,715,715,589,686,833,722,778,725,667,722,611,639,795,667,727,673,920,923,805,886,651,694,1022,682,556,562,522,493,553,556,688,465,556,556,472,564,686,550,556,556,556,500,833,500,835,500,572,518,830,851,621,736,526,492,752,534,556,556,556,378,496,500,222,222,222,910,828,556,472,565,500,556,778,556,492,339,944,722,944,722,944,722,667,500,333,333,556,1e3,1e3,552,222,222,222,222,333,333,333,556,556,350,1e3,1e3,188,354,333,333,500,333,167,365,556,556,1094,556,885,323,1083,1e3,768,600,834,834,834,834,1e3,500,998,500,1e3,500,500,494,612,823,713,584,549,713,979,719,274,549,549,584,549,549,604,584,604,604,708,625,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,729,604,604,354,354,1e3,990,990,990,990,494,604,604,604,604,354,1021,1052,917,750,750,531,656,594,510,500,750,750,500,500,333,333,333,333,333,333,333,333,222,222,294,294,324,324,316,328,398,285],Pa=[-1,-1,-1,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,161,162,163,164,165,166,167,168,169,170,171,172,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,402,506,507,508,509,510,511,536,537,538,539,710,711,713,728,729,730,731,732,733,900,901,902,903,904,905,906,908,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,1117,1118,1119,1138,1139,1168,1169,7808,7809,7810,7811,7812,7813,7922,7923,8208,8209,8211,8212,8213,8215,8216,8217,8218,8219,8220,8221,8222,8224,8225,8226,8230,8240,8242,8243,8249,8250,8252,8254,8260,8319,8355,8356,8359,8364,8453,8467,8470,8482,8486,8494,8539,8540,8541,8542,8592,8593,8594,8595,8596,8597,8616,8706,8710,8719,8721,8722,8730,8734,8735,8745,8747,8776,8800,8801,8804,8805,8962,8976,8992,8993,9472,9474,9484,9488,9492,9496,9500,9508,9516,9524,9532,9552,9553,9554,9555,9556,9557,9558,9559,9560,9561,9562,9563,9564,9565,9566,9567,9568,9569,9570,9571,9572,9573,9574,9575,9576,9577,9578,9579,9580,9600,9604,9608,9612,9616,9617,9618,9619,9632,9633,9642,9643,9644,9650,9658,9660,9668,9674,9675,9679,9688,9689,9702,9786,9787,9788,9792,9794,9824,9827,9829,9830,9834,9835,9836,61441,61442,61445,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],Wa=[365,0,333,278,278,355,556,556,889,667,191,333,333,389,584,278,333,278,278,556,556,556,556,556,556,556,556,556,556,278,278,584,584,584,556,1015,667,667,722,722,667,611,778,722,278,500,667,556,833,722,778,667,778,722,667,611,722,667,944,667,667,611,278,278,278,469,556,333,556,556,500,556,556,278,556,556,222,222,500,222,833,556,556,556,556,333,500,278,556,500,722,500,500,500,334,260,334,584,333,556,556,556,556,260,556,333,737,370,556,584,737,552,400,549,333,333,333,576,537,278,333,333,365,556,834,834,834,611,667,667,667,667,667,667,1e3,722,667,667,667,667,278,278,278,278,722,722,778,778,778,778,778,584,778,722,722,722,722,667,667,611,556,556,556,556,556,556,889,500,556,556,556,556,278,278,278,278,556,556,556,556,556,556,556,549,611,556,556,556,556,500,556,500,667,556,667,556,667,556,722,500,722,500,722,500,722,500,722,615,722,556,667,556,667,556,667,556,667,556,667,556,778,556,778,556,778,556,778,556,722,556,722,556,278,278,278,278,278,278,278,222,278,278,735,444,500,222,667,500,500,556,222,556,222,556,292,556,334,556,222,722,556,722,556,722,556,604,723,556,778,556,778,556,778,556,1e3,944,722,333,722,333,722,333,667,500,667,500,667,500,667,500,611,278,611,375,611,278,722,556,722,556,722,556,722,556,722,556,722,556,944,722,667,500,667,611,500,611,500,611,500,222,556,667,556,1e3,889,778,611,667,500,611,278,333,333,333,333,333,333,333,333,333,333,333,667,278,784,838,384,774,855,752,222,667,667,551,668,667,611,722,778,278,667,668,833,722,650,778,722,667,618,611,667,798,667,835,748,278,667,578,446,556,222,547,578,575,500,557,446,441,556,556,222,500,500,576,500,448,556,690,569,482,617,395,547,648,525,713,781,222,547,556,547,781,667,667,865,542,719,667,278,278,500,1057,1010,854,583,722,635,719,667,656,667,542,677,667,923,604,719,719,583,656,833,722,778,719,667,722,611,635,760,667,740,667,917,938,792,885,656,719,1010,722,556,573,531,365,583,556,669,458,559,559,438,583,688,552,556,542,556,500,458,500,823,500,573,521,802,823,625,719,521,510,750,542,556,556,556,365,510,500,222,278,222,906,812,556,438,559,500,552,778,556,489,411,944,722,944,722,944,722,667,500,333,333,556,1e3,1e3,552,222,222,222,222,333,333,333,556,556,350,1e3,1e3,188,354,333,333,500,333,167,365,556,556,1094,556,885,323,1073,1e3,768,600,834,834,834,834,1e3,500,1e3,500,1e3,500,500,494,612,823,713,584,549,713,979,719,274,549,549,583,549,549,604,584,604,604,708,625,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,729,604,604,354,354,1e3,990,990,990,990,494,604,604,604,604,354,1021,1052,917,750,750,531,656,594,510,500,750,750,500,500,333,333,333,333,333,333,333,333,222,222,294,294,324,324,316,328,398,285],Xa=[-1,-1,-1,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,161,162,163,164,165,166,167,168,169,170,171,172,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,402,506,507,508,509,510,511,536,537,538,539,710,711,713,728,729,730,731,732,733,900,901,902,903,904,905,906,908,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,1117,1118,1119,1138,1139,1168,1169,7808,7809,7810,7811,7812,7813,7922,7923,8208,8209,8211,8212,8213,8215,8216,8217,8218,8219,8220,8221,8222,8224,8225,8226,8230,8240,8242,8243,8249,8250,8252,8254,8260,8319,8355,8356,8359,8364,8453,8467,8470,8482,8486,8494,8539,8540,8541,8542,8592,8593,8594,8595,8596,8597,8616,8706,8710,8719,8721,8722,8730,8734,8735,8745,8747,8776,8800,8801,8804,8805,8962,8976,8992,8993,9472,9474,9484,9488,9492,9496,9500,9508,9516,9524,9532,9552,9553,9554,9555,9556,9557,9558,9559,9560,9561,9562,9563,9564,9565,9566,9567,9568,9569,9570,9571,9572,9573,9574,9575,9576,9577,9578,9579,9580,9600,9604,9608,9612,9616,9617,9618,9619,9632,9633,9642,9643,9644,9650,9658,9660,9668,9674,9675,9679,9688,9689,9702,9786,9787,9788,9792,9794,9824,9827,9829,9830,9834,9835,9836,61441,61442,61445,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],ja=[1.36898,1,1,.72706,.80479,.83734,.98894,.99793,.9897,.93884,.86209,.94292,.94292,1.16661,1.02058,.93582,.96694,.93582,1.19137,.99793,.99793,.99793,.99793,.99793,.99793,.99793,.99793,.99793,.99793,.78076,.78076,1.02058,1.02058,1.02058,.72851,.78966,.90838,.83637,.82391,.96376,.80061,.86275,.8768,.95407,1.0258,.73901,.85022,.83655,1.0156,.95546,.92179,.87107,.92179,.82114,.8096,.89713,.94438,.95353,.94083,.91905,.90406,.9446,.94292,1.18777,.94292,1.02058,.89903,.90088,.94938,.97898,.81093,.97571,.94938,1.024,.9577,.95933,.98621,1.0474,.97455,.98981,.9672,.95933,.9446,.97898,.97407,.97646,.78036,1.10208,.95442,.95298,.97579,.9332,.94039,.938,.80687,1.01149,.80687,1.02058,.80479,.99793,.99793,.99793,.99793,1.01149,1.00872,.90088,.91882,1.0213,.8361,1.02058,.62295,.54324,.89022,1.08595,1,1,.90088,1,.97455,.93582,.90088,1,1.05686,.8361,.99642,.99642,.99642,.72851,.90838,.90838,.90838,.90838,.90838,.90838,.868,.82391,.80061,.80061,.80061,.80061,1.0258,1.0258,1.0258,1.0258,.97484,.95546,.92179,.92179,.92179,.92179,.92179,1.02058,.92179,.94438,.94438,.94438,.94438,.90406,.86958,.98225,.94938,.94938,.94938,.94938,.94938,.94938,.9031,.81093,.94938,.94938,.94938,.94938,.98621,.98621,.98621,.98621,.93969,.95933,.9446,.9446,.9446,.9446,.9446,1.08595,.9446,.95442,.95442,.95442,.95442,.94039,.97898,.94039,.90838,.94938,.90838,.94938,.90838,.94938,.82391,.81093,.82391,.81093,.82391,.81093,.82391,.81093,.96376,.84313,.97484,.97571,.80061,.94938,.80061,.94938,.80061,.94938,.80061,.94938,.80061,.94938,.8768,.9577,.8768,.9577,.8768,.9577,1,1,.95407,.95933,.97069,.95933,1.0258,.98621,1.0258,.98621,1.0258,.98621,1.0258,.98621,1.0258,.98621,.887,1.01591,.73901,1.0474,1,1,.97455,.83655,.98981,1,1,.83655,.73977,.83655,.73903,.84638,1.033,.95546,.95933,1,1,.95546,.95933,.8271,.95417,.95933,.92179,.9446,.92179,.9446,.92179,.9446,.936,.91964,.82114,.97646,1,1,.82114,.97646,.8096,.78036,.8096,.78036,1,1,.8096,.78036,1,1,.89713,.77452,.89713,1.10208,.94438,.95442,.94438,.95442,.94438,.95442,.94438,.95442,.94438,.95442,.94438,.95442,.94083,.97579,.90406,.94039,.90406,.9446,.938,.9446,.938,.9446,.938,1,.99793,.90838,.94938,.868,.9031,.92179,.9446,1,1,.89713,1.10208,.90088,.90088,.90088,.90088,.90088,.90088,.90088,.90088,.90088,.90989,.9358,.91945,.83181,.75261,.87992,.82976,.96034,.83689,.97268,1.0078,.90838,.83637,.8019,.90157,.80061,.9446,.95407,.92436,1.0258,.85022,.97153,1.0156,.95546,.89192,.92179,.92361,.87107,.96318,.89713,.93704,.95638,.91905,.91709,.92796,1.0258,.93704,.94836,1.0373,.95933,1.0078,.95871,.94836,.96174,.92601,.9498,.98607,.95776,.95933,1.05453,1.0078,.98275,.9314,.95617,.91701,1.05993,.9446,.78367,.9553,1,.86832,1.0128,.95871,.99394,.87548,.96361,.86774,1.0078,.95871,.9446,.95871,.86774,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.94083,.97579,.94083,.97579,.94083,.97579,.90406,.94039,.96694,1,.89903,1,1,1,.93582,.93582,.93582,1,.908,.908,.918,.94219,.94219,.96544,1,1.285,1,1,.81079,.81079,1,1,.74854,1,1,1,1,.99793,1,1,1,.65,1,1.36145,1,1,1,1,1,1,1,1,1,1,1,1.17173,1,.80535,.76169,1.02058,1.0732,1.05486,1,1,1.30692,1.08595,1.08595,1,1.08595,1.08595,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1.16161,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],Za={lineHeight:1.2,lineGap:.2},Va=[1.36898,1,1,.66227,.80779,.81625,.97276,.97276,.97733,.92222,.83266,.94292,.94292,1.16148,1.02058,.93582,.96694,.93582,1.17337,.97276,.97276,.97276,.97276,.97276,.97276,.97276,.97276,.97276,.97276,.78076,.78076,1.02058,1.02058,1.02058,.71541,.76813,.85576,.80591,.80729,.94299,.77512,.83655,.86523,.92222,.98621,.71743,.81698,.79726,.98558,.92222,.90637,.83809,.90637,.80729,.76463,.86275,.90699,.91605,.9154,.85308,.85458,.90531,.94292,1.21296,.94292,1.02058,.89903,1.18616,.99613,.91677,.78216,.91677,.90083,.98796,.9135,.92168,.95381,.98981,.95298,.95381,.93459,.92168,.91513,.92004,.91677,.95077,.748,1.04502,.91677,.92061,.94236,.89544,.89364,.9,.80687,.8578,.80687,1.02058,.80779,.97276,.97276,.97276,.97276,.8578,.99973,1.18616,.91339,1.08074,.82891,1.02058,.55509,.71526,.89022,1.08595,1,1,1.18616,1,.96736,.93582,1.18616,1,1.04864,.82711,.99043,.99043,.99043,.71541,.85576,.85576,.85576,.85576,.85576,.85576,.845,.80729,.77512,.77512,.77512,.77512,.98621,.98621,.98621,.98621,.95961,.92222,.90637,.90637,.90637,.90637,.90637,1.02058,.90251,.90699,.90699,.90699,.90699,.85458,.83659,.94951,.99613,.99613,.99613,.99613,.99613,.99613,.85811,.78216,.90083,.90083,.90083,.90083,.95381,.95381,.95381,.95381,.9135,.92168,.91513,.91513,.91513,.91513,.91513,1.08595,.91677,.91677,.91677,.91677,.91677,.89364,.92332,.89364,.85576,.99613,.85576,.99613,.85576,.99613,.80729,.78216,.80729,.78216,.80729,.78216,.80729,.78216,.94299,.76783,.95961,.91677,.77512,.90083,.77512,.90083,.77512,.90083,.77512,.90083,.77512,.90083,.86523,.9135,.86523,.9135,.86523,.9135,1,1,.92222,.92168,.92222,.92168,.98621,.95381,.98621,.95381,.98621,.95381,.98621,.95381,.98621,.95381,.86036,.97096,.71743,.98981,1,1,.95298,.79726,.95381,1,1,.79726,.6894,.79726,.74321,.81691,1.0006,.92222,.92168,1,1,.92222,.92168,.79464,.92098,.92168,.90637,.91513,.90637,.91513,.90637,.91513,.909,.87514,.80729,.95077,1,1,.80729,.95077,.76463,.748,.76463,.748,1,1,.76463,.748,1,1,.86275,.72651,.86275,1.04502,.90699,.91677,.90699,.91677,.90699,.91677,.90699,.91677,.90699,.91677,.90699,.91677,.9154,.94236,.85458,.89364,.85458,.90531,.9,.90531,.9,.90531,.9,1,.97276,.85576,.99613,.845,.85811,.90251,.91677,1,1,.86275,1.04502,1.18616,1.18616,1.18616,1.18616,1.18616,1.18616,1.18616,1.18616,1.18616,1.00899,1.30628,.85576,.80178,.66862,.7927,.69323,.88127,.72459,.89711,.95381,.85576,.80591,.7805,.94729,.77512,.90531,.92222,.90637,.98621,.81698,.92655,.98558,.92222,.85359,.90637,.90976,.83809,.94523,.86275,.83509,.93157,.85308,.83392,.92346,.98621,.83509,.92886,.91324,.92168,.95381,.90646,.92886,.90557,.86847,.90276,.91324,.86842,.92168,.99531,.95381,.9224,.85408,.92699,.86847,1.0051,.91513,.80487,.93481,1,.88159,1.05214,.90646,.97355,.81539,.89398,.85923,.95381,.90646,.91513,.90646,.85923,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.9154,.94236,.9154,.94236,.9154,.94236,.85458,.89364,.96694,1,.89903,1,1,1,.91782,.91782,.91782,1,.896,.896,.896,.9332,.9332,.95973,1,1.26,1,1,.80479,.80178,1,1,.85633,1,1,1,1,.97276,1,1,1,.698,1,1.36145,1,1,1,1,1,1,1,1,1,1,1,1.14542,1,.79199,.78694,1.02058,1.03493,1.05486,1,1,1.23026,1.08595,1.08595,1,1.08595,1.08595,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1.20006,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],za={lineHeight:1.2,lineGap:.2},_a=[1.36898,1,1,.65507,.84943,.85639,.88465,.88465,.86936,.88307,.86948,.85283,.85283,1.06383,1.02058,.75945,.9219,.75945,1.17337,.88465,.88465,.88465,.88465,.88465,.88465,.88465,.88465,.88465,.88465,.75945,.75945,1.02058,1.02058,1.02058,.69046,.70926,.85158,.77812,.76852,.89591,.70466,.76125,.80094,.86822,.83864,.728,.77212,.79475,.93637,.87514,.8588,.76013,.8588,.72421,.69866,.77598,.85991,.80811,.87832,.78112,.77512,.8562,1.0222,1.18417,1.0222,1.27014,.89903,1.15012,.93859,.94399,.846,.94399,.81453,1.0186,.94219,.96017,1.03075,1.02175,.912,1.03075,.96998,.96017,.93859,.94399,.94399,.95493,.746,1.12658,.94578,.91,.979,.882,.882,.83,.85034,.83537,.85034,1.02058,.70869,.88465,.88465,.88465,.88465,.83537,.90083,1.15012,.9161,.94565,.73541,1.02058,.53609,.69353,.79519,1.08595,1,1,1.15012,1,.91974,.75945,1.15012,1,.9446,.73361,.9005,.9005,.9005,.62864,.85158,.85158,.85158,.85158,.85158,.85158,.773,.76852,.70466,.70466,.70466,.70466,.83864,.83864,.83864,.83864,.90561,.87514,.8588,.8588,.8588,.8588,.8588,1.02058,.85751,.85991,.85991,.85991,.85991,.77512,.76013,.88075,.93859,.93859,.93859,.93859,.93859,.93859,.8075,.846,.81453,.81453,.81453,.81453,.82424,.82424,.82424,.82424,.9278,.96017,.93859,.93859,.93859,.93859,.93859,1.08595,.8562,.94578,.94578,.94578,.94578,.882,.94578,.882,.85158,.93859,.85158,.93859,.85158,.93859,.76852,.846,.76852,.846,.76852,.846,.76852,.846,.89591,.8544,.90561,.94399,.70466,.81453,.70466,.81453,.70466,.81453,.70466,.81453,.70466,.81453,.80094,.94219,.80094,.94219,.80094,.94219,1,1,.86822,.96017,.86822,.96017,.83864,.82424,.83864,.82424,.83864,.82424,.83864,1.03075,.83864,.82424,.81402,1.02738,.728,1.02175,1,1,.912,.79475,1.03075,1,1,.79475,.83911,.79475,.66266,.80553,1.06676,.87514,.96017,1,1,.87514,.96017,.86865,.87396,.96017,.8588,.93859,.8588,.93859,.8588,.93859,.867,.84759,.72421,.95493,1,1,.72421,.95493,.69866,.746,.69866,.746,1,1,.69866,.746,1,1,.77598,.88417,.77598,1.12658,.85991,.94578,.85991,.94578,.85991,.94578,.85991,.94578,.85991,.94578,.85991,.94578,.87832,.979,.77512,.882,.77512,.8562,.83,.8562,.83,.8562,.83,1,.88465,.85158,.93859,.773,.8075,.85751,.8562,1,1,.77598,1.12658,1.15012,1.15012,1.15012,1.15012,1.15012,1.15313,1.15012,1.15012,1.15012,1.08106,1.03901,.85158,.77025,.62264,.7646,.65351,.86026,.69461,.89947,1.03075,.85158,.77812,.76449,.88836,.70466,.8562,.86822,.8588,.83864,.77212,.85308,.93637,.87514,.82352,.8588,.85701,.76013,.89058,.77598,.8156,.82565,.78112,.77899,.89386,.83864,.8156,.9486,.92388,.96186,1.03075,.91123,.9486,.93298,.878,.93942,.92388,.84596,.96186,.95119,1.03075,.922,.88787,.95829,.88,.93559,.93859,.78815,.93758,1,.89217,1.03737,.91123,.93969,.77487,.85769,.86799,1.03075,.91123,.93859,.91123,.86799,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.87832,.979,.87832,.979,.87832,.979,.77512,.882,.9219,1,.89903,1,1,1,.87321,.87321,.87321,1,1.027,1.027,1.027,.86847,.86847,.79121,1,1.124,1,1,.73572,.73572,1,1,.85034,1,1,1,1,.88465,1,1,1,.669,1,1.36145,1,1,1,1,1,1,1,1,1,1,1,1.04828,1,.74948,.75187,1.02058,.98391,1.02119,1,1,1.06233,1.08595,1.08595,1,1.08595,1.08595,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1.05233,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],$a={lineHeight:1.2,lineGap:.2},As=[1.36898,1,1,.76305,.82784,.94935,.89364,.92241,.89073,.90706,.98472,.85283,.85283,1.0664,1.02058,.74505,.9219,.74505,1.23456,.92241,.92241,.92241,.92241,.92241,.92241,.92241,.92241,.92241,.92241,.74505,.74505,1.02058,1.02058,1.02058,.73002,.72601,.91755,.8126,.80314,.92222,.73764,.79726,.83051,.90284,.86023,.74,.8126,.84869,.96518,.91115,.8858,.79761,.8858,.74498,.73914,.81363,.89591,.83659,.89633,.85608,.8111,.90531,1.0222,1.22736,1.0222,1.27014,.89903,.90088,.86667,1.0231,.896,1.01411,.90083,1.05099,1.00512,.99793,1.05326,1.09377,.938,1.06226,1.00119,.99793,.98714,1.0231,1.01231,.98196,.792,1.19137,.99074,.962,1.01915,.926,.942,.856,.85034,.92006,.85034,1.02058,.69067,.92241,.92241,.92241,.92241,.92006,.9332,.90088,.91882,.93484,.75339,1.02058,.56866,.54324,.79519,1.08595,1,1,.90088,1,.95325,.74505,.90088,1,.97198,.75339,.91009,.91009,.91009,.66466,.91755,.91755,.91755,.91755,.91755,.91755,.788,.80314,.73764,.73764,.73764,.73764,.86023,.86023,.86023,.86023,.92915,.91115,.8858,.8858,.8858,.8858,.8858,1.02058,.8858,.89591,.89591,.89591,.89591,.8111,.79611,.89713,.86667,.86667,.86667,.86667,.86667,.86667,.86936,.896,.90083,.90083,.90083,.90083,.84224,.84224,.84224,.84224,.97276,.99793,.98714,.98714,.98714,.98714,.98714,1.08595,.89876,.99074,.99074,.99074,.99074,.942,1.0231,.942,.91755,.86667,.91755,.86667,.91755,.86667,.80314,.896,.80314,.896,.80314,.896,.80314,.896,.92222,.93372,.92915,1.01411,.73764,.90083,.73764,.90083,.73764,.90083,.73764,.90083,.73764,.90083,.83051,1.00512,.83051,1.00512,.83051,1.00512,1,1,.90284,.99793,.90976,.99793,.86023,.84224,.86023,.84224,.86023,.84224,.86023,1.05326,.86023,.84224,.82873,1.07469,.74,1.09377,1,1,.938,.84869,1.06226,1,1,.84869,.83704,.84869,.81441,.85588,1.08927,.91115,.99793,1,1,.91115,.99793,.91887,.90991,.99793,.8858,.98714,.8858,.98714,.8858,.98714,.894,.91434,.74498,.98196,1,1,.74498,.98196,.73914,.792,.73914,.792,1,1,.73914,.792,1,1,.81363,.904,.81363,1.19137,.89591,.99074,.89591,.99074,.89591,.99074,.89591,.99074,.89591,.99074,.89591,.99074,.89633,1.01915,.8111,.942,.8111,.90531,.856,.90531,.856,.90531,.856,1,.92241,.91755,.86667,.788,.86936,.8858,.89876,1,1,.81363,1.19137,.90088,.90088,.90088,.90088,.90088,.90088,.90088,.90088,.90088,.90388,1.03901,.92138,.78105,.7154,.86169,.80513,.94007,.82528,.98612,1.06226,.91755,.8126,.81884,.92819,.73764,.90531,.90284,.8858,.86023,.8126,.91172,.96518,.91115,.83089,.8858,.87791,.79761,.89297,.81363,.88157,.89992,.85608,.81992,.94307,.86023,.88157,.95308,.98699,.99793,1.06226,.95817,.95308,.97358,.928,.98088,.98699,.92761,.99793,.96017,1.06226,.986,.944,.95978,.938,.96705,.98714,.80442,.98972,1,.89762,1.04552,.95817,.99007,.87064,.91879,.88888,1.06226,.95817,.98714,.95817,.88888,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.89633,1.01915,.89633,1.01915,.89633,1.01915,.8111,.942,.9219,1,.89903,1,1,1,.93173,.93173,.93173,1,1.06304,1.06304,1.06904,.89903,.89903,.80549,1,1.156,1,1,.76575,.76575,1,1,.72458,1,1,1,1,.92241,1,1,1,.619,1,1.36145,1,1,1,1,1,1,1,1,1,1,1,1.07257,1,.74705,.71119,1.02058,1.024,1.02119,1,1,1.1536,1.08595,1.08595,1,1.08595,1.08595,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1.05638,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],es={lineHeight:1.2,lineGap:.2},ts=[1.76738,1,1,.99297,.9824,1.04016,1.06497,1.03424,.97529,1.17647,1.23203,1.1085,1.1085,1.16939,1.2107,.9754,1.21408,.9754,1.59578,1.03424,1.03424,1.03424,1.03424,1.03424,1.03424,1.03424,1.03424,1.03424,1.03424,.81378,.81378,1.2107,1.2107,1.2107,.71703,.97847,.97363,.88776,.8641,1.02096,.79795,.85132,.914,1.06085,1.1406,.8007,.89858,.83693,1.14889,1.09398,.97489,.92094,.97489,.90399,.84041,.95923,1.00135,1,1.06467,.98243,.90996,.99361,1.1085,1.56942,1.1085,1.2107,.74627,.94282,.96752,1.01519,.86304,1.01359,.97278,1.15103,1.01359,.98561,1.02285,1.02285,1.00527,1.02285,1.0302,.99041,1.0008,1.01519,1.01359,1.02258,.79104,1.16862,.99041,.97454,1.02511,.99298,.96752,.95801,.94856,1.16579,.94856,1.2107,.9824,1.03424,1.03424,1,1.03424,1.16579,.8727,1.3871,1.18622,1.10818,1.04478,1.2107,1.18622,.75155,.94994,1.28826,1.21408,1.21408,.91056,1,.91572,.9754,.64663,1.18328,1.24866,1.04478,1.14169,1.15749,1.17389,.71703,.97363,.97363,.97363,.97363,.97363,.97363,.93506,.8641,.79795,.79795,.79795,.79795,1.1406,1.1406,1.1406,1.1406,1.02096,1.09398,.97426,.97426,.97426,.97426,.97426,1.2107,.97489,1.00135,1.00135,1.00135,1.00135,.90996,.92094,1.02798,.96752,.96752,.96752,.96752,.96752,.96752,.93136,.86304,.97278,.97278,.97278,.97278,1.02285,1.02285,1.02285,1.02285,.97122,.99041,1,1,1,1,1,1.28826,1.0008,.99041,.99041,.99041,.99041,.96752,1.01519,.96752,.97363,.96752,.97363,.96752,.97363,.96752,.8641,.86304,.8641,.86304,.8641,.86304,.8641,.86304,1.02096,1.03057,1.02096,1.03517,.79795,.97278,.79795,.97278,.79795,.97278,.79795,.97278,.79795,.97278,.914,1.01359,.914,1.01359,.914,1.01359,1,1,1.06085,.98561,1.06085,1.00879,1.1406,1.02285,1.1406,1.02285,1.1406,1.02285,1.1406,1.02285,1.1406,1.02285,.97138,1.08692,.8007,1.02285,1,1,1.00527,.83693,1.02285,1,1,.83693,.9455,.83693,.90418,.83693,1.13005,1.09398,.99041,1,1,1.09398,.99041,.96692,1.09251,.99041,.97489,1.0008,.97489,1.0008,.97489,1.0008,.93994,.97931,.90399,1.02258,1,1,.90399,1.02258,.84041,.79104,.84041,.79104,.84041,.79104,.84041,.79104,1,1,.95923,1.07034,.95923,1.16862,1.00135,.99041,1.00135,.99041,1.00135,.99041,1.00135,.99041,1.00135,.99041,1.00135,.99041,1.06467,1.02511,.90996,.96752,.90996,.99361,.95801,.99361,.95801,.99361,.95801,1.07733,1.03424,.97363,.96752,.93506,.93136,.97489,1.0008,1,1,.95923,1.16862,1.15103,1.15103,1.01173,1.03959,.75953,.81378,.79912,1.15103,1.21994,.95161,.87815,1.01149,.81525,.7676,.98167,1.01134,1.02546,.84097,1.03089,1.18102,.97363,.88776,.85134,.97826,.79795,.99361,1.06085,.97489,1.1406,.89858,1.0388,1.14889,1.09398,.86039,.97489,1.0595,.92094,.94793,.95923,.90996,.99346,.98243,1.02112,.95493,1.1406,.90996,1.03574,1.02597,1.0008,1.18102,1.06628,1.03574,1.0192,1.01932,1.00886,.97531,1.0106,1.0008,1.13189,1.18102,1.02277,.98683,1.0016,.99561,1.07237,1.0008,.90434,.99921,.93803,.8965,1.23085,1.06628,1.04983,.96268,1.0499,.98439,1.18102,1.06628,1.0008,1.06628,.98439,.79795,1,1,1,1,1,1,1,1,1,1,1,1,1.09466,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.97278,1,1,1,1,1,1,1,1,1,1,1,1,1.02065,1,1,1,1,1,1,1.06467,1.02511,1.06467,1.02511,1.06467,1.02511,.90996,.96752,1,1.21408,.89903,1,1,.75155,1.04394,1.04394,1.04394,1.04394,.98633,.98633,.98633,.73047,.73047,1.20642,.91211,1.25635,1.222,1.02956,1.03372,1.03372,.96039,1.24633,1,1.12454,.93503,1.03424,1.19687,1.03424,1,1,1,.771,1,1,1.15749,1.15749,1.15749,1.10948,.86279,.94434,.86279,.94434,.86182,1,1,1.16897,1,.96085,.90137,1.2107,1.18416,1.13973,.69825,.9716,2.10339,1.29004,1.29004,1.21172,1.29004,1.29004,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1.42603,1,.99862,.99862,1,.87025,.87025,.87025,.87025,1.18874,1.42603,1,1.42603,1.42603,.99862,1,1,1,1,1,1.2886,1.04315,1.15296,1.34163,1,1,1,1.09193,1.09193,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],is={lineHeight:1.33008,lineGap:0},as=[1.76738,1,1,.98946,1.03959,1.04016,1.02809,1.036,.97639,1.10953,1.23203,1.11144,1.11144,1.16939,1.21237,.9754,1.21261,.9754,1.59754,1.036,1.036,1.036,1.036,1.036,1.036,1.036,1.036,1.036,1.036,.81378,.81378,1.21237,1.21237,1.21237,.73541,.97847,.97363,.89723,.87897,1.0426,.79429,.85292,.91149,1.05815,1.1406,.79631,.90128,.83853,1.04396,1.10615,.97552,.94436,.97552,.88641,.80527,.96083,1.00135,1,1.06777,.9817,.91142,.99361,1.11144,1.57293,1.11144,1.21237,.74627,1.31818,1.06585,.97042,.83055,.97042,.93503,1.1261,.97042,.97922,1.14236,.94552,1.01054,1.14236,1.02471,.97922,.94165,.97042,.97042,1.0276,.78929,1.1261,.97922,.95874,1.02197,.98507,.96752,.97168,.95107,1.16579,.95107,1.21237,1.03959,1.036,1.036,1,1.036,1.16579,.87357,1.31818,1.18754,1.26781,1.05356,1.21237,1.18622,.79487,.94994,1.29004,1.24047,1.24047,1.31818,1,.91484,.9754,1.31818,1.1349,1.24866,1.05356,1.13934,1.15574,1.17389,.73541,.97363,.97363,.97363,.97363,.97363,.97363,.94385,.87897,.79429,.79429,.79429,.79429,1.1406,1.1406,1.1406,1.1406,1.0426,1.10615,.97552,.97552,.97552,.97552,.97552,1.21237,.97552,1.00135,1.00135,1.00135,1.00135,.91142,.94436,.98721,1.06585,1.06585,1.06585,1.06585,1.06585,1.06585,.96705,.83055,.93503,.93503,.93503,.93503,1.14236,1.14236,1.14236,1.14236,.93125,.97922,.94165,.94165,.94165,.94165,.94165,1.29004,.94165,.97922,.97922,.97922,.97922,.96752,.97042,.96752,.97363,1.06585,.97363,1.06585,.97363,1.06585,.87897,.83055,.87897,.83055,.87897,.83055,.87897,.83055,1.0426,1.0033,1.0426,.97042,.79429,.93503,.79429,.93503,.79429,.93503,.79429,.93503,.79429,.93503,.91149,.97042,.91149,.97042,.91149,.97042,1,1,1.05815,.97922,1.05815,.97922,1.1406,1.14236,1.1406,1.14236,1.1406,1.14236,1.1406,1.14236,1.1406,1.14236,.97441,1.04302,.79631,1.01582,1,1,1.01054,.83853,1.14236,1,1,.83853,1.09125,.83853,.90418,.83853,1.19508,1.10615,.97922,1,1,1.10615,.97922,1.01034,1.10466,.97922,.97552,.94165,.97552,.94165,.97552,.94165,.91602,.91981,.88641,1.0276,1,1,.88641,1.0276,.80527,.78929,.80527,.78929,.80527,.78929,.80527,.78929,1,1,.96083,1.05403,.95923,1.16862,1.00135,.97922,1.00135,.97922,1.00135,.97922,1.00135,.97922,1.00135,.97922,1.00135,.97922,1.06777,1.02197,.91142,.96752,.91142,.99361,.97168,.99361,.97168,.99361,.97168,1.23199,1.036,.97363,1.06585,.94385,.96705,.97552,.94165,1,1,.96083,1.1261,1.31818,1.31818,1.31818,1.31818,1.31818,1.31818,1.31818,1.31818,1.31818,.95161,1.27126,1.00811,.83284,.77702,.99137,.95253,1.0347,.86142,1.07205,1.14236,.97363,.89723,.86869,1.09818,.79429,.99361,1.05815,.97552,1.1406,.90128,1.06662,1.04396,1.10615,.84918,.97552,1.04694,.94436,.98015,.96083,.91142,1.00356,.9817,1.01945,.98999,1.1406,.91142,1.04961,.9898,1.00639,1.14236,1.07514,1.04961,.99607,1.02897,1.008,.9898,.95134,1.00639,1.11121,1.14236,1.00518,.97981,1.02186,1,1.08578,.94165,.99314,.98387,.93028,.93377,1.35125,1.07514,1.10687,.93491,1.04232,1.00351,1.14236,1.07514,.94165,1.07514,1.00351,.79429,1,1,1,1,1,1,1,1,1,1,1,1,1.09097,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.93503,1,1,1,1,1,1,1,1,1,1,1,1,.96609,1,1,1,1,1,1,1.06777,1.02197,1.06777,1.02197,1.06777,1.02197,.91142,.96752,1,1.21261,.89903,1,1,.75155,1.04745,1.04745,1.04745,1.04394,.98633,.98633,.98633,.72959,.72959,1.20502,.91406,1.26514,1.222,1.02956,1.03372,1.03372,.96039,1.24633,1,1.09125,.93327,1.03336,1.16541,1.036,1,1,1,.771,1,1,1.15574,1.15574,1.15574,1.15574,.86364,.94434,.86279,.94434,.86224,1,1,1.16798,1,.96085,.90068,1.21237,1.18416,1.13904,.69825,.9716,2.10339,1.29004,1.29004,1.21339,1.29004,1.29004,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1.42603,1,.99862,.99862,1,.87025,.87025,.87025,.87025,1.18775,1.42603,1,1.42603,1.42603,.99862,1,1,1,1,1,1.2886,1.04315,1.15296,1.34163,1,1,1,1.13269,1.13269,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],ss={lineHeight:1.33008,lineGap:0},rs=[1.76738,1,1,.98946,1.14763,1.05365,1.06234,.96927,.92586,1.15373,1.18414,.91349,.91349,1.07403,1.17308,.78383,1.20088,.78383,1.42531,.96927,.96927,.96927,.96927,.96927,.96927,.96927,.96927,.96927,.96927,.78383,.78383,1.17308,1.17308,1.17308,.77349,.94565,.94729,.85944,.88506,.9858,.74817,.80016,.88449,.98039,.95782,.69238,.89898,.83231,.98183,1.03989,.96924,.86237,.96924,.80595,.74524,.86091,.95402,.94143,.98448,.8858,.83089,.93285,1.0949,1.39016,1.0949,1.45994,.74627,1.04839,.97454,.97454,.87207,.97454,.87533,1.06151,.97454,1.00176,1.16484,1.08132,.98047,1.16484,1.02989,1.01054,.96225,.97454,.97454,1.06598,.79004,1.16344,1.00351,.94629,.9973,.91016,.96777,.9043,.91082,.92481,.91082,1.17308,.95748,.96927,.96927,1,.96927,.92481,.80597,1.04839,1.23393,1.1781,.9245,1.17308,1.20808,.63218,.94261,1.24822,1.09971,1.09971,1.04839,1,.85273,.78032,1.04839,1.09971,1.22326,.9245,1.09836,1.13525,1.15222,.70424,.94729,.94729,.94729,.94729,.94729,.94729,.85498,.88506,.74817,.74817,.74817,.74817,.95782,.95782,.95782,.95782,.9858,1.03989,.96924,.96924,.96924,.96924,.96924,1.17308,.96924,.95402,.95402,.95402,.95402,.83089,.86237,.88409,.97454,.97454,.97454,.97454,.97454,.97454,.92916,.87207,.87533,.87533,.87533,.87533,.93146,.93146,.93146,.93146,.93854,1.01054,.96225,.96225,.96225,.96225,.96225,1.24822,.8761,1.00351,1.00351,1.00351,1.00351,.96777,.97454,.96777,.94729,.97454,.94729,.97454,.94729,.97454,.88506,.87207,.88506,.87207,.88506,.87207,.88506,.87207,.9858,.95391,.9858,.97454,.74817,.87533,.74817,.87533,.74817,.87533,.74817,.87533,.74817,.87533,.88449,.97454,.88449,.97454,.88449,.97454,1,1,.98039,1.00176,.98039,1.00176,.95782,.93146,.95782,.93146,.95782,.93146,.95782,1.16484,.95782,.93146,.84421,1.12761,.69238,1.08132,1,1,.98047,.83231,1.16484,1,1,.84723,1.04861,.84723,.78755,.83231,1.23736,1.03989,1.01054,1,1,1.03989,1.01054,.9857,1.03849,1.01054,.96924,.96225,.96924,.96225,.96924,.96225,.92383,.90171,.80595,1.06598,1,1,.80595,1.06598,.74524,.79004,.74524,.79004,.74524,.79004,.74524,.79004,1,1,.86091,1.02759,.85771,1.16344,.95402,1.00351,.95402,1.00351,.95402,1.00351,.95402,1.00351,.95402,1.00351,.95402,1.00351,.98448,.9973,.83089,.96777,.83089,.93285,.9043,.93285,.9043,.93285,.9043,1.31868,.96927,.94729,.97454,.85498,.92916,.96924,.8761,1,1,.86091,1.16344,1.04839,1.04839,1.04839,1.04839,1.04839,1.04839,1.04839,1.04839,1.04839,.81965,.81965,.94729,.78032,.71022,.90883,.84171,.99877,.77596,1.05734,1.2,.94729,.85944,.82791,.9607,.74817,.93285,.98039,.96924,.95782,.89898,.98316,.98183,1.03989,.78614,.96924,.97642,.86237,.86075,.86091,.83089,.90082,.8858,.97296,1.01284,.95782,.83089,1.0976,1.04,1.03342,1.2,1.0675,1.0976,.98205,1.03809,1.05097,1.04,.95364,1.03342,1.05401,1.2,1.02148,1.0119,1.04724,1.0127,1.02732,.96225,.8965,.97783,.93574,.94818,1.30679,1.0675,1.11826,.99821,1.0557,1.0326,1.2,1.0675,.96225,1.0675,1.0326,.74817,1,1,1,1,1,1,1,1,1,1,1,1,1.03754,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.87533,1,1,1,1,1,1,1,1,1,1,1,1,.98705,1,1,1,1,1,1,.98448,.9973,.98448,.9973,.98448,.9973,.83089,.96777,1,1.20088,.89903,1,1,.75155,.94945,.94945,.94945,.94945,1.12317,1.12317,1.12317,.67603,.67603,1.15621,.73584,1.21191,1.22135,1.06483,.94868,.94868,.95996,1.24633,1,1.07497,.87709,.96927,1.01473,.96927,1,1,1,.77295,1,1,1.09836,1.09836,1.09836,1.01522,.86321,.94434,.8649,.94434,.86182,1,1,1.083,1,.91578,.86438,1.17308,1.18416,1.14589,.69825,.97622,1.96791,1.24822,1.24822,1.17308,1.24822,1.24822,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1.42603,1,.99862,.99862,1,.87025,.87025,.87025,.87025,1.17984,1.42603,1,1.42603,1.42603,.99862,1,1,1,1,1,1.2886,1.04315,1.15296,1.34163,1,1,1,1.10742,1.10742,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],ns={lineHeight:1.33008,lineGap:0},os=[1.76738,1,1,.98594,1.02285,1.10454,1.06234,.96927,.92037,1.19985,1.2046,.90616,.90616,1.07152,1.1714,.78032,1.20088,.78032,1.40246,.96927,.96927,.96927,.96927,.96927,.96927,.96927,.96927,.96927,.96927,.78032,.78032,1.1714,1.1714,1.1714,.80597,.94084,.96706,.85944,.85734,.97093,.75842,.79936,.88198,.9831,.95782,.71387,.86969,.84636,1.07796,1.03584,.96924,.83968,.96924,.82826,.79649,.85771,.95132,.93119,.98965,.88433,.8287,.93365,1.08612,1.3638,1.08612,1.45786,.74627,.80499,.91484,1.05707,.92383,1.05882,.9403,1.12654,1.05882,1.01756,1.09011,1.09011,.99414,1.09011,1.034,1.01756,1.05356,1.05707,1.05882,1.04399,.84863,1.21968,1.01756,.95801,1.00068,.91797,.96777,.9043,.90351,.92105,.90351,1.1714,.85337,.96927,.96927,.99912,.96927,.92105,.80597,1.2434,1.20808,1.05937,.90957,1.1714,1.20808,.75155,.94261,1.24644,1.09971,1.09971,.84751,1,.85273,.78032,.61584,1.05425,1.17914,.90957,1.08665,1.11593,1.14169,.73381,.96706,.96706,.96706,.96706,.96706,.96706,.86035,.85734,.75842,.75842,.75842,.75842,.95782,.95782,.95782,.95782,.97093,1.03584,.96924,.96924,.96924,.96924,.96924,1.1714,.96924,.95132,.95132,.95132,.95132,.8287,.83968,.89049,.91484,.91484,.91484,.91484,.91484,.91484,.93575,.92383,.9403,.9403,.9403,.9403,.8717,.8717,.8717,.8717,1.00527,1.01756,1.05356,1.05356,1.05356,1.05356,1.05356,1.24644,.95923,1.01756,1.01756,1.01756,1.01756,.96777,1.05707,.96777,.96706,.91484,.96706,.91484,.96706,.91484,.85734,.92383,.85734,.92383,.85734,.92383,.85734,.92383,.97093,1.0969,.97093,1.05882,.75842,.9403,.75842,.9403,.75842,.9403,.75842,.9403,.75842,.9403,.88198,1.05882,.88198,1.05882,.88198,1.05882,1,1,.9831,1.01756,.9831,1.01756,.95782,.8717,.95782,.8717,.95782,.8717,.95782,1.09011,.95782,.8717,.84784,1.11551,.71387,1.09011,1,1,.99414,.84636,1.09011,1,1,.84636,1.0536,.84636,.94298,.84636,1.23297,1.03584,1.01756,1,1,1.03584,1.01756,1.00323,1.03444,1.01756,.96924,1.05356,.96924,1.05356,.96924,1.05356,.93066,.98293,.82826,1.04399,1,1,.82826,1.04399,.79649,.84863,.79649,.84863,.79649,.84863,.79649,.84863,1,1,.85771,1.17318,.85771,1.21968,.95132,1.01756,.95132,1.01756,.95132,1.01756,.95132,1.01756,.95132,1.01756,.95132,1.01756,.98965,1.00068,.8287,.96777,.8287,.93365,.9043,.93365,.9043,.93365,.9043,1.08571,.96927,.96706,.91484,.86035,.93575,.96924,.95923,1,1,.85771,1.21968,1.11437,1.11437,.93109,.91202,.60411,.84164,.55572,1.01173,.97361,.81818,.81818,.96635,.78032,.72727,.92366,.98601,1.03405,.77968,1.09799,1.2,.96706,.85944,.85638,.96491,.75842,.93365,.9831,.96924,.95782,.86969,.94152,1.07796,1.03584,.78437,.96924,.98715,.83968,.83491,.85771,.8287,.94492,.88433,.9287,1.0098,.95782,.8287,1.0625,.98248,1.03424,1.2,1.01071,1.0625,.95246,1.03809,1.04912,.98248,1.00221,1.03424,1.05443,1.2,1.04785,.99609,1.00169,1.05176,.99346,1.05356,.9087,1.03004,.95542,.93117,1.23362,1.01071,1.07831,1.02512,1.05205,1.03502,1.2,1.01071,1.05356,1.01071,1.03502,.75842,1,1,1,1,1,1,1,1,1,1,1,1,1.03719,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.9403,1,1,1,1,1,1,1,1,1,1,1,1,1.04021,1,1,1,1,1,1,.98965,1.00068,.98965,1.00068,.98965,1.00068,.8287,.96777,1,1.20088,.89903,1,1,.75155,1.03077,1.03077,1.03077,1.03077,1.13196,1.13196,1.13196,.67428,.67428,1.16039,.73291,1.20996,1.22135,1.06483,.94868,.94868,.95996,1.24633,1,1.07497,.87796,.96927,1.01518,.96927,1,1,1,.77295,1,1,1.10539,1.10539,1.11358,1.06967,.86279,.94434,.86279,.94434,.86182,1,1,1.083,1,.91578,.86507,1.1714,1.18416,1.14589,.69825,.97622,1.9697,1.24822,1.24822,1.17238,1.24822,1.24822,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1.42603,1,.99862,.99862,1,.87025,.87025,.87025,.87025,1.18083,1.42603,1,1.42603,1.42603,.99862,1,1,1,1,1,1.2886,1.04315,1.15296,1.34163,1,1,1,1.10938,1.10938,1,1,1,1.05425,1.09971,1.09971,1.09971,1,1,1,1,1,1,1,1,1,1,1],gs={lineHeight:1.33008,lineGap:0},Is=getLookupTableFactory((function(e){e["MyriadPro-Regular"]=e["PdfJS-Fallback-Regular"]={name:"LiberationSans-Regular",factors:As,baseWidths:Wa,baseMapping:Xa,metrics:es};e["MyriadPro-Bold"]=e["PdfJS-Fallback-Bold"]={name:"LiberationSans-Bold",factors:ja,baseWidths:va,baseMapping:Ka,metrics:Za};e["MyriadPro-It"]=e["MyriadPro-Italic"]=e["PdfJS-Fallback-Italic"]={name:"LiberationSans-Italic",factors:_a,baseWidths:Oa,baseMapping:Pa,metrics:$a};e["MyriadPro-BoldIt"]=e["MyriadPro-BoldItalic"]=e["PdfJS-Fallback-BoldItalic"]={name:"LiberationSans-BoldItalic",factors:Va,baseWidths:Ta,baseMapping:qa,metrics:za};e.ArialMT=e.Arial=e["Arial-Regular"]={name:"LiberationSans-Regular",baseWidths:Wa,baseMapping:Xa};e["Arial-BoldMT"]=e["Arial-Bold"]={name:"LiberationSans-Bold",baseWidths:va,baseMapping:Ka};e["Arial-ItalicMT"]=e["Arial-Italic"]={name:"LiberationSans-Italic",baseWidths:Oa,baseMapping:Pa};e["Arial-BoldItalicMT"]=e["Arial-BoldItalic"]={name:"LiberationSans-BoldItalic",baseWidths:Ta,baseMapping:qa};e["Calibri-Regular"]={name:"LiberationSans-Regular",factors:Ra,baseWidths:Wa,baseMapping:Xa,metrics:Na};e["Calibri-Bold"]={name:"LiberationSans-Bold",factors:wa,baseWidths:va,baseMapping:Ka,metrics:ba};e["Calibri-Italic"]={name:"LiberationSans-Italic",factors:Sa,baseWidths:Oa,baseMapping:Pa,metrics:ka};e["Calibri-BoldItalic"]={name:"LiberationSans-BoldItalic",factors:Da,baseWidths:Ta,baseMapping:qa,metrics:Fa};e["Segoeui-Regular"]={name:"LiberationSans-Regular",factors:os,baseWidths:Wa,baseMapping:Xa,metrics:gs};e["Segoeui-Bold"]={name:"LiberationSans-Bold",factors:ts,baseWidths:va,baseMapping:Ka,metrics:is};e["Segoeui-Italic"]={name:"LiberationSans-Italic",factors:rs,baseWidths:Oa,baseMapping:Pa,metrics:ns};e["Segoeui-BoldItalic"]={name:"LiberationSans-BoldItalic",factors:as,baseWidths:Ta,baseMapping:qa,metrics:ss};e["Helvetica-Regular"]=e.Helvetica={name:"LiberationSans-Regular",factors:Ha,baseWidths:Wa,baseMapping:Xa,metrics:Ya};e["Helvetica-Bold"]={name:"LiberationSans-Bold",factors:Ga,baseWidths:va,baseMapping:Ka,metrics:xa};e["Helvetica-Italic"]={name:"LiberationSans-Italic",factors:La,baseWidths:Oa,baseMapping:Pa,metrics:Ja};e["Helvetica-BoldItalic"]={name:"LiberationSans-BoldItalic",factors:Ma,baseWidths:Ta,baseMapping:qa,metrics:Ua}}));function getXfaFontName(e){const t=normalizeFontName(e);return Is()[t]}function getXfaFontDict(e){const t=function getXfaFontWidths(e){const t=getXfaFontName(e);if(!t)return null;const{baseWidths:i,baseMapping:a,factors:s}=t,r=s?i.map(((e,t)=>e*s[t])):i;let n,o=-2;const g=[];for(const[e,t]of a.map(((e,t)=>[e,t])).sort((([e],[t])=>e-t)))if(-1!==e)if(e===o+1){n.push(r[t]);o+=1}else{o=e;n=[r[t]];g.push(e,n)}return g}(e),i=new Dict(null);i.set("BaseFont",Name.get(e));i.set("Type",Name.get("Font"));i.set("Subtype",Name.get("CIDFontType2"));i.set("Encoding",Name.get("Identity-H"));i.set("CIDToGIDMap",Name.get("Identity"));i.set("W",t);i.set("FirstChar",t[0]);i.set("LastChar",t.at(-2)+t.at(-1).length-1);const a=new Dict(null);i.set("FontDescriptor",a);const s=new Dict(null);s.set("Ordering","Identity");s.set("Registry","Adobe");s.set("Supplement",0);i.set("CIDSystemInfo",s);return i}class PostScriptParser{constructor(e){this.lexer=e;this.operators=[];this.token=null;this.prev=null}nextToken(){this.prev=this.token;this.token=this.lexer.getToken()}accept(e){if(this.token.type===e){this.nextToken();return!0}return!1}expect(e){if(this.accept(e))return!0;throw new FormatError(`Unexpected symbol: found ${this.token.type} expected ${e}.`)}parse(){this.nextToken();this.expect(cs.LBRACE);this.parseBlock();this.expect(cs.RBRACE);return this.operators}parseBlock(){for(;;)if(this.accept(cs.NUMBER))this.operators.push(this.prev.value);else if(this.accept(cs.OPERATOR))this.operators.push(this.prev.value);else{if(!this.accept(cs.LBRACE))return;this.parseCondition()}}parseCondition(){const e=this.operators.length;this.operators.push(null,null);this.parseBlock();this.expect(cs.RBRACE);if(this.accept(cs.IF)){this.operators[e]=this.operators.length;this.operators[e+1]="jz"}else{if(!this.accept(cs.LBRACE))throw new FormatError("PS Function: error parsing conditional.");{const t=this.operators.length;this.operators.push(null,null);const i=this.operators.length;this.parseBlock();this.expect(cs.RBRACE);this.expect(cs.IFELSE);this.operators[t]=this.operators.length;this.operators[t+1]="j";this.operators[e]=i;this.operators[e+1]="jz"}}}}const cs={LBRACE:0,RBRACE:1,NUMBER:2,OPERATOR:3,IF:4,IFELSE:5};class PostScriptToken{static get opCache(){return shadow(this,"opCache",Object.create(null))}constructor(e,t){this.type=e;this.value=t}static getOperator(e){return PostScriptToken.opCache[e]||=new PostScriptToken(cs.OPERATOR,e)}static get LBRACE(){return shadow(this,"LBRACE",new PostScriptToken(cs.LBRACE,"{"))}static get RBRACE(){return shadow(this,"RBRACE",new PostScriptToken(cs.RBRACE,"}"))}static get IF(){return shadow(this,"IF",new PostScriptToken(cs.IF,"IF"))}static get IFELSE(){return shadow(this,"IFELSE",new PostScriptToken(cs.IFELSE,"IFELSE"))}}class PostScriptLexer{constructor(e){this.stream=e;this.nextChar();this.strBuf=[]}nextChar(){return this.currentChar=this.stream.getByte()}getToken(){let e=!1,t=this.currentChar;for(;;){if(t<0)return pt;if(e)10!==t&&13!==t||(e=!1);else if(37===t)e=!0;else if(!isWhiteSpace(t))break;t=this.nextChar()}switch(0|t){case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:case 43:case 45:case 46:return new PostScriptToken(cs.NUMBER,this.getNumber());case 123:this.nextChar();return PostScriptToken.LBRACE;case 125:this.nextChar();return PostScriptToken.RBRACE}const i=this.strBuf;i.length=0;i[0]=String.fromCharCode(t);for(;(t=this.nextChar())>=0&&(t>=65&&t<=90||t>=97&&t<=122);)i.push(String.fromCharCode(t));const a=i.join("");switch(a.toLowerCase()){case"if":return PostScriptToken.IF;case"ifelse":return PostScriptToken.IFELSE;default:return PostScriptToken.getOperator(a)}}getNumber(){let e=this.currentChar;const t=this.strBuf;t.length=0;t[0]=String.fromCharCode(e);for(;(e=this.nextChar())>=0&&(e>=48&&e<=57||45===e||46===e);)t.push(String.fromCharCode(e));const i=parseFloat(t.join(""));if(isNaN(i))throw new FormatError(`Invalid floating point number: ${i}`);return i}}class BaseLocalCache{constructor(e){this.constructor===BaseLocalCache&&unreachable("Cannot initialize BaseLocalCache.");this._onlyRefs=!0===e?.onlyRefs;if(!this._onlyRefs){this._nameRefMap=new Map;this._imageMap=new Map}this._imageCache=new RefSetCache}getByName(e){this._onlyRefs&&unreachable("Should not call `getByName` method.");const t=this._nameRefMap.get(e);return t?this.getByRef(t):this._imageMap.get(e)||null}getByRef(e){return this._imageCache.get(e)||null}set(e,t,i){unreachable("Abstract method `set` called.")}}class LocalImageCache extends BaseLocalCache{set(e,t=null,i){if("string"!=typeof e)throw new Error('LocalImageCache.set - expected "name" argument.');if(t){if(this._imageCache.has(t))return;this._nameRefMap.set(e,t);this._imageCache.put(t,i)}else this._imageMap.has(e)||this._imageMap.set(e,i)}}class LocalColorSpaceCache extends BaseLocalCache{set(e=null,t=null,i){if("string"!=typeof e&&!t)throw new Error('LocalColorSpaceCache.set - expected "name" and/or "ref" argument.');if(t){if(this._imageCache.has(t))return;null!==e&&this._nameRefMap.set(e,t);this._imageCache.put(t,i)}else this._imageMap.has(e)||this._imageMap.set(e,i)}}class LocalFunctionCache extends BaseLocalCache{constructor(e){super({onlyRefs:!0})}set(e=null,t,i){if(!t)throw new Error('LocalFunctionCache.set - expected "ref" argument.');this._imageCache.has(t)||this._imageCache.put(t,i)}}class LocalGStateCache extends BaseLocalCache{set(e,t=null,i){if("string"!=typeof e)throw new Error('LocalGStateCache.set - expected "name" argument.');if(t){if(this._imageCache.has(t))return;this._nameRefMap.set(e,t);this._imageCache.put(t,i)}else this._imageMap.has(e)||this._imageMap.set(e,i)}}class LocalTilingPatternCache extends BaseLocalCache{constructor(e){super({onlyRefs:!0})}set(e=null,t,i){if(!t)throw new Error('LocalTilingPatternCache.set - expected "ref" argument.');this._imageCache.has(t)||this._imageCache.put(t,i)}}class RegionalImageCache extends BaseLocalCache{constructor(e){super({onlyRefs:!0})}set(e=null,t,i){if(!t)throw new Error('RegionalImageCache.set - expected "ref" argument.');this._imageCache.has(t)||this._imageCache.put(t,i)}}class GlobalImageCache{static NUM_PAGES_THRESHOLD=2;static MIN_IMAGES_TO_CACHE=10;static MAX_BYTE_SIZE=5e7;#b=new RefSet;constructor(){this._refCache=new RefSetCache;this._imageCache=new RefSetCache}get#D(){let e=0;for(const t of this._imageCache)e+=t.byteSize;return e}get#F(){return!(this._imageCache.size<GlobalImageCache.MIN_IMAGES_TO_CACHE)&&!(this.#D<GlobalImageCache.MAX_BYTE_SIZE)}shouldCache(e,t){let i=this._refCache.get(e);if(!i){i=new Set;this._refCache.put(e,i)}i.add(t);return!(i.size<GlobalImageCache.NUM_PAGES_THRESHOLD)&&!(!this._imageCache.has(e)&&this.#F)}addDecodeFailed(e){this.#b.put(e)}hasDecodeFailed(e){return this.#b.has(e)}addByteSize(e,t){const i=this._imageCache.get(e);i&&(i.byteSize||(i.byteSize=t))}getData(e,t){const i=this._refCache.get(e);if(!i)return null;if(i.size<GlobalImageCache.NUM_PAGES_THRESHOLD)return null;const a=this._imageCache.get(e);if(!a)return null;i.add(t);return a}setData(e,t){if(!this._refCache.has(e))throw new Error('GlobalImageCache.setData - expected "shouldCache" to have been called.');this._imageCache.has(e)||(this.#F?warn("GlobalImageCache.setData - cache limit reached."):this._imageCache.put(e,t))}clear(e=!1){if(!e){this.#b.clear();this._refCache.clear()}this._imageCache.clear()}}class PDFFunctionFactory{constructor({xref:e,isEvalSupported:t=!0}){this.xref=e;this.isEvalSupported=!1!==t}create(e){const t=this.getCached(e);if(t)return t;const i=PDFFunction.parse({xref:this.xref,isEvalSupported:this.isEvalSupported,fn:e instanceof Ref?this.xref.fetch(e):e});this._cache(e,i);return i}createFromArray(e){const t=this.getCached(e);if(t)return t;const i=PDFFunction.parseArray({xref:this.xref,isEvalSupported:this.isEvalSupported,fnObj:e instanceof Ref?this.xref.fetch(e):e});this._cache(e,i);return i}getCached(e){let t;e instanceof Ref?t=e:e instanceof Dict?t=e.objId:e instanceof BaseStream&&(t=e.dict?.objId);if(t){const e=this._localFunctionCache.getByRef(t);if(e)return e}return null}_cache(e,t){if(!t)throw new Error('PDFFunctionFactory._cache - expected "parsedFunction" argument.');let i;e instanceof Ref?i=e:e instanceof Dict?i=e.objId:e instanceof BaseStream&&(i=e.dict?.objId);i&&this._localFunctionCache.set(null,i,t)}get _localFunctionCache(){return shadow(this,"_localFunctionCache",new LocalFunctionCache)}}function toNumberArray(e){return Array.isArray(e)?isNumberArray(e,null)?e:e.map((e=>+e)):null}class PDFFunction{static getSampleArray(e,t,i,a){let s,r,n=1;for(s=0,r=e.length;s<r;s++)n*=e[s];n*=t;const o=new Array(n);let g=0,c=0;const h=1/(2**i-1),l=a.getBytes((n*i+7)/8);let C=0;for(s=0;s<n;s++){for(;g<i;){c<<=8;c|=l[C++];g+=8}g-=i;o[s]=(c>>g)*h;c&=(1<<g)-1}return o}static parse({xref:e,isEvalSupported:t,fn:i}){const a=i.dict||i;switch(a.get("FunctionType")){case 0:return this.constructSampled({xref:e,isEvalSupported:t,fn:i,dict:a});case 1:break;case 2:return this.constructInterpolated({xref:e,isEvalSupported:t,dict:a});case 3:return this.constructStiched({xref:e,isEvalSupported:t,dict:a});case 4:return this.constructPostScript({xref:e,isEvalSupported:t,fn:i,dict:a})}throw new FormatError("Unknown type of function")}static parseArray({xref:e,isEvalSupported:t,fnObj:i}){if(!Array.isArray(i))return this.parse({xref:e,isEvalSupported:t,fn:i});const a=[];for(const s of i)a.push(this.parse({xref:e,isEvalSupported:t,fn:e.fetchIfRef(s)}));return function(e,t,i,s){for(let r=0,n=a.length;r<n;r++)a[r](e,t,i,s+r)}}static constructSampled({xref:e,isEvalSupported:t,fn:i,dict:a}){function toMultiArray(e){const t=e.length,i=[];let a=0;for(let s=0;s<t;s+=2)i[a++]=[e[s],e[s+1]];return i}function interpolate(e,t,i,a,s){return a+(s-a)/(i-t)*(e-t)}let s=toNumberArray(a.getArray("Domain")),r=toNumberArray(a.getArray("Range"));if(!s||!r)throw new FormatError("No domain or range");const n=s.length/2,o=r.length/2;s=toMultiArray(s);r=toMultiArray(r);const g=toNumberArray(a.getArray("Size")),c=a.get("BitsPerSample"),h=a.get("Order")||1;1!==h&&info("No support for cubic spline interpolation: "+h);let l=toNumberArray(a.getArray("Encode"));if(l)l=toMultiArray(l);else{l=[];for(let e=0;e<n;++e)l.push([0,g[e]-1])}let C=toNumberArray(a.getArray("Decode"));C=C?toMultiArray(C):r;const Q=this.getSampleArray(g,o,c,i);return function constructSampledFn(e,t,i,a){const c=1<<n,h=new Float64Array(c),E=new Uint32Array(c);let u,d;for(d=0;d<c;d++)h[d]=1;let f=o,p=1;for(u=0;u<n;++u){const i=s[u][0],a=s[u][1];let r=interpolate(Math.min(Math.max(e[t+u],i),a),i,a,l[u][0],l[u][1]);const n=g[u];r=Math.min(Math.max(r,0),n-1);const o=r<n-1?Math.floor(r):r-1,C=o+1-r,Q=r-o,m=o*f,y=m+f;for(d=0;d<c;d++)if(d&p){h[d]*=Q;E[d]+=y}else{h[d]*=C;E[d]+=m}f*=n;p<<=1}for(d=0;d<o;++d){let e=0;for(u=0;u<c;u++)e+=Q[E[u]+d]*h[u];e=interpolate(e,0,1,C[d][0],C[d][1]);i[a+d]=Math.min(Math.max(e,r[d][0]),r[d][1])}}}static constructInterpolated({xref:e,isEvalSupported:t,dict:i}){const a=toNumberArray(i.getArray("C0"))||[0],s=toNumberArray(i.getArray("C1"))||[1],r=i.get("N"),n=[];for(let e=0,t=a.length;e<t;++e)n.push(s[e]-a[e]);const o=n.length;return function constructInterpolatedFn(e,t,i,s){const g=1===r?e[t]:e[t]**r;for(let e=0;e<o;++e)i[s+e]=a[e]+g*n[e]}}static constructStiched({xref:e,isEvalSupported:t,dict:i}){const a=toNumberArray(i.getArray("Domain"));if(!a)throw new FormatError("No domain");if(1!==a.length/2)throw new FormatError("Bad domain for stiched function");const s=[];for(const a of i.get("Functions"))s.push(this.parse({xref:e,isEvalSupported:t,fn:e.fetchIfRef(a)}));const r=toNumberArray(i.getArray("Bounds")),n=toNumberArray(i.getArray("Encode")),o=new Float32Array(1);return function constructStichedFn(e,t,i,g){const c=function constructStichedFromIRClip(e,t,i){e>i?e=i:e<t&&(e=t);return e}(e[t],a[0],a[1]),h=r.length;let l;for(l=0;l<h&&!(c<r[l]);++l);let C=a[0];l>0&&(C=r[l-1]);let Q=a[1];l<r.length&&(Q=r[l]);const E=n[2*l],u=n[2*l+1];o[0]=C===Q?E:E+(c-C)*(u-E)/(Q-C);s[l](o,0,i,g)}}static constructPostScript({xref:e,isEvalSupported:t,fn:i,dict:a}){const s=toNumberArray(a.getArray("Domain")),r=toNumberArray(a.getArray("Range"));if(!s)throw new FormatError("No domain.");if(!r)throw new FormatError("No range.");const n=new PostScriptLexer(i),o=new PostScriptParser(n).parse();if(t&&FeatureTest.isEvalSupported){const e=(new PostScriptCompiler).compile(o,s,r);if(e)return new Function("src","srcOffset","dest","destOffset",e)}info("Unable to compile PS function");const g=r.length>>1,c=s.length>>1,h=new PostScriptEvaluator(o),l=Object.create(null);let C=8192;const Q=new Float32Array(c);return function constructPostScriptFn(e,t,i,a){let s,n,o="";const E=Q;for(s=0;s<c;s++){n=e[t+s];E[s]=n;o+=n+"_"}const u=l[o];if(void 0!==u){i.set(u,a);return}const d=new Float32Array(g),f=h.execute(E),p=f.length-g;for(s=0;s<g;s++){n=f[p+s];let e=r[2*s];if(n<e)n=e;else{e=r[2*s+1];n>e&&(n=e)}d[s]=n}if(C>0){C--;l[o]=d}i.set(d,a)}}}function isPDFFunction(e){let t;if(e instanceof Dict)t=e;else{if(!(e instanceof BaseStream))return!1;t=e.dict}return t.has("FunctionType")}class PostScriptStack{static MAX_STACK_SIZE=100;constructor(e){this.stack=e?Array.from(e):[]}push(e){if(this.stack.length>=PostScriptStack.MAX_STACK_SIZE)throw new Error("PostScript function stack overflow.");this.stack.push(e)}pop(){if(this.stack.length<=0)throw new Error("PostScript function stack underflow.");return this.stack.pop()}copy(e){if(this.stack.length+e>=PostScriptStack.MAX_STACK_SIZE)throw new Error("PostScript function stack overflow.");const t=this.stack;for(let i=t.length-e,a=e-1;a>=0;a--,i++)t.push(t[i])}index(e){this.push(this.stack[this.stack.length-e-1])}roll(e,t){const i=this.stack,a=i.length-e,s=i.length-1,r=a+(t-Math.floor(t/e)*e);for(let e=a,t=s;e<t;e++,t--){const a=i[e];i[e]=i[t];i[t]=a}for(let e=a,t=r-1;e<t;e++,t--){const a=i[e];i[e]=i[t];i[t]=a}for(let e=r,t=s;e<t;e++,t--){const a=i[e];i[e]=i[t];i[t]=a}}}class PostScriptEvaluator{constructor(e){this.operators=e}execute(e){const t=new PostScriptStack(e);let i=0;const a=this.operators,s=a.length;let r,n,o;for(;i<s;){r=a[i++];if("number"!=typeof r)switch(r){case"jz":o=t.pop();n=t.pop();n||(i=o);break;case"j":n=t.pop();i=n;break;case"abs":n=t.pop();t.push(Math.abs(n));break;case"add":o=t.pop();n=t.pop();t.push(n+o);break;case"and":o=t.pop();n=t.pop();"boolean"==typeof n&&"boolean"==typeof o?t.push(n&&o):t.push(n&o);break;case"atan":o=t.pop();n=t.pop();n=Math.atan2(n,o)/Math.PI*180;n<0&&(n+=360);t.push(n);break;case"bitshift":o=t.pop();n=t.pop();n>0?t.push(n<<o):t.push(n>>o);break;case"ceiling":n=t.pop();t.push(Math.ceil(n));break;case"copy":n=t.pop();t.copy(n);break;case"cos":n=t.pop();t.push(Math.cos(n%360/180*Math.PI));break;case"cvi":n=0|t.pop();t.push(n);break;case"cvr":break;case"div":o=t.pop();n=t.pop();t.push(n/o);break;case"dup":t.copy(1);break;case"eq":o=t.pop();n=t.pop();t.push(n===o);break;case"exch":t.roll(2,1);break;case"exp":o=t.pop();n=t.pop();t.push(n**o);break;case"false":t.push(!1);break;case"floor":n=t.pop();t.push(Math.floor(n));break;case"ge":o=t.pop();n=t.pop();t.push(n>=o);break;case"gt":o=t.pop();n=t.pop();t.push(n>o);break;case"idiv":o=t.pop();n=t.pop();t.push(n/o|0);break;case"index":n=t.pop();t.index(n);break;case"le":o=t.pop();n=t.pop();t.push(n<=o);break;case"ln":n=t.pop();t.push(Math.log(n));break;case"log":n=t.pop();t.push(Math.log10(n));break;case"lt":o=t.pop();n=t.pop();t.push(n<o);break;case"mod":o=t.pop();n=t.pop();t.push(n%o);break;case"mul":o=t.pop();n=t.pop();t.push(n*o);break;case"ne":o=t.pop();n=t.pop();t.push(n!==o);break;case"neg":n=t.pop();t.push(-n);break;case"not":n=t.pop();"boolean"==typeof n?t.push(!n):t.push(~n);break;case"or":o=t.pop();n=t.pop();"boolean"==typeof n&&"boolean"==typeof o?t.push(n||o):t.push(n|o);break;case"pop":t.pop();break;case"roll":o=t.pop();n=t.pop();t.roll(n,o);break;case"round":n=t.pop();t.push(Math.round(n));break;case"sin":n=t.pop();t.push(Math.sin(n%360/180*Math.PI));break;case"sqrt":n=t.pop();t.push(Math.sqrt(n));break;case"sub":o=t.pop();n=t.pop();t.push(n-o);break;case"true":t.push(!0);break;case"truncate":n=t.pop();n=n<0?Math.ceil(n):Math.floor(n);t.push(n);break;case"xor":o=t.pop();n=t.pop();"boolean"==typeof n&&"boolean"==typeof o?t.push(n!==o):t.push(n^o);break;default:throw new FormatError(`Unknown operator ${r}`)}else t.push(r)}return t.stack}}class AstNode{constructor(e){this.type=e}visit(e){unreachable("abstract method")}}class AstArgument extends AstNode{constructor(e,t,i){super("args");this.index=e;this.min=t;this.max=i}visit(e){e.visitArgument(this)}}class AstLiteral extends AstNode{constructor(e){super("literal");this.number=e;this.min=e;this.max=e}visit(e){e.visitLiteral(this)}}class AstBinaryOperation extends AstNode{constructor(e,t,i,a,s){super("binary");this.op=e;this.arg1=t;this.arg2=i;this.min=a;this.max=s}visit(e){e.visitBinaryOperation(this)}}class AstMin extends AstNode{constructor(e,t){super("max");this.arg=e;this.min=e.min;this.max=t}visit(e){e.visitMin(this)}}class AstVariable extends AstNode{constructor(e,t,i){super("var");this.index=e;this.min=t;this.max=i}visit(e){e.visitVariable(this)}}class AstVariableDefinition extends AstNode{constructor(e,t){super("definition");this.variable=e;this.arg=t}visit(e){e.visitVariableDefinition(this)}}class ExpressionBuilderVisitor{constructor(){this.parts=[]}visitArgument(e){this.parts.push("Math.max(",e.min,", Math.min(",e.max,", src[srcOffset + ",e.index,"]))")}visitVariable(e){this.parts.push("v",e.index)}visitLiteral(e){this.parts.push(e.number)}visitBinaryOperation(e){this.parts.push("(");e.arg1.visit(this);this.parts.push(" ",e.op," ");e.arg2.visit(this);this.parts.push(")")}visitVariableDefinition(e){this.parts.push("var ");e.variable.visit(this);this.parts.push(" = ");e.arg.visit(this);this.parts.push(";")}visitMin(e){this.parts.push("Math.min(");e.arg.visit(this);this.parts.push(", ",e.max,")")}toString(){return this.parts.join("")}}function buildAddOperation(e,t){return"literal"===t.type&&0===t.number?e:"literal"===e.type&&0===e.number?t:"literal"===t.type&&"literal"===e.type?new AstLiteral(e.number+t.number):new AstBinaryOperation("+",e,t,e.min+t.min,e.max+t.max)}function buildMulOperation(e,t){if("literal"===t.type){if(0===t.number)return new AstLiteral(0);if(1===t.number)return e;if("literal"===e.type)return new AstLiteral(e.number*t.number)}if("literal"===e.type){if(0===e.number)return new AstLiteral(0);if(1===e.number)return t}const i=Math.min(e.min*t.min,e.min*t.max,e.max*t.min,e.max*t.max),a=Math.max(e.min*t.min,e.min*t.max,e.max*t.min,e.max*t.max);return new AstBinaryOperation("*",e,t,i,a)}function buildSubOperation(e,t){if("literal"===t.type){if(0===t.number)return e;if("literal"===e.type)return new AstLiteral(e.number-t.number)}return"binary"===t.type&&"-"===t.op&&"literal"===e.type&&1===e.number&&"literal"===t.arg1.type&&1===t.arg1.number?t.arg2:new AstBinaryOperation("-",e,t,e.min-t.max,e.max-t.min)}function buildMinOperation(e,t){return e.min>=t?new AstLiteral(t):e.max<=t?e:new AstMin(e,t)}class PostScriptCompiler{compile(e,t,i){const a=[],s=[],r=t.length>>1,n=i.length>>1;let o,g,c,h,l,C,Q,E,u=0;for(let e=0;e<r;e++)a.push(new AstArgument(e,t[2*e],t[2*e+1]));for(let t=0,i=e.length;t<i;t++){E=e[t];if("number"!=typeof E)switch(E){case"add":if(a.length<2)return null;h=a.pop();c=a.pop();a.push(buildAddOperation(c,h));break;case"cvr":if(a.length<1)return null;break;case"mul":if(a.length<2)return null;h=a.pop();c=a.pop();a.push(buildMulOperation(c,h));break;case"sub":if(a.length<2)return null;h=a.pop();c=a.pop();a.push(buildSubOperation(c,h));break;case"exch":if(a.length<2)return null;l=a.pop();C=a.pop();a.push(l,C);break;case"pop":if(a.length<1)return null;a.pop();break;case"index":if(a.length<1)return null;c=a.pop();if("literal"!==c.type)return null;o=c.number;if(o<0||!Number.isInteger(o)||a.length<o)return null;l=a[a.length-o-1];if("literal"===l.type||"var"===l.type){a.push(l);break}Q=new AstVariable(u++,l.min,l.max);a[a.length-o-1]=Q;a.push(Q);s.push(new AstVariableDefinition(Q,l));break;case"dup":if(a.length<1)return null;if("number"==typeof e[t+1]&&"gt"===e[t+2]&&e[t+3]===t+7&&"jz"===e[t+4]&&"pop"===e[t+5]&&e[t+6]===e[t+1]){c=a.pop();a.push(buildMinOperation(c,e[t+1]));t+=6;break}l=a.at(-1);if("literal"===l.type||"var"===l.type){a.push(l);break}Q=new AstVariable(u++,l.min,l.max);a[a.length-1]=Q;a.push(Q);s.push(new AstVariableDefinition(Q,l));break;case"roll":if(a.length<2)return null;h=a.pop();c=a.pop();if("literal"!==h.type||"literal"!==c.type)return null;g=h.number;o=c.number;if(o<=0||!Number.isInteger(o)||!Number.isInteger(g)||a.length<o)return null;g=(g%o+o)%o;if(0===g)break;a.push(...a.splice(a.length-o,o-g));break;default:return null}else a.push(new AstLiteral(E))}if(a.length!==n)return null;const d=[];for(const e of s){const t=new ExpressionBuilderVisitor;e.visit(t);d.push(t.toString())}for(let e=0,t=a.length;e<t;e++){const t=a[e],s=new ExpressionBuilderVisitor;t.visit(s);const r=i[2*e],n=i[2*e+1],o=[s.toString()];if(r>t.min){o.unshift("Math.max(",r,", ");o.push(")")}if(n<t.max){o.unshift("Math.min(",n,", ");o.push(")")}o.unshift("dest[destOffset + ",e,"] = ");o.push(";");d.push(o.join(""))}return d.join("\n")}}const hs=["BN","BN","BN","BN","BN","BN","BN","BN","BN","S","B","S","WS","B","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","B","B","B","S","WS","ON","ON","ET","ET","ET","ON","ON","ON","ON","ON","ES","CS","ES","CS","CS","EN","EN","EN","EN","EN","EN","EN","EN","EN","EN","CS","ON","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","ON","ON","ON","BN","BN","BN","BN","BN","BN","B","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","CS","ON","ET","ET","ET","ET","ON","ON","ON","ON","L","ON","ON","BN","ON","ON","ET","ET","EN","EN","ON","L","ON","ON","ON","EN","L","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","L","L","L","L","L","L","L","L"],ls=["AN","AN","AN","AN","AN","AN","ON","ON","AL","ET","ET","AL","CS","AL","ON","ON","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","AL","AL","","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","AN","AN","AN","AN","AN","AN","AN","AN","AN","AN","ET","AN","AN","AL","AL","AL","NSM","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","NSM","NSM","NSM","NSM","NSM","NSM","NSM","AN","ON","NSM","NSM","NSM","NSM","NSM","NSM","AL","AL","NSM","NSM","ON","NSM","NSM","NSM","NSM","AL","AL","EN","EN","EN","EN","EN","EN","EN","EN","EN","EN","AL","AL","AL","AL","AL","AL"];function isOdd(e){return 0!=(1&e)}function isEven(e){return 0==(1&e)}function findUnequal(e,t,i){let a,s;for(a=t,s=e.length;a<s;++a)if(e[a]!==i)return a;return a}function setValues(e,t,i,a){for(let s=t;s<i;++s)e[s]=a}function reverseValues(e,t,i){for(let a=t,s=i-1;a<s;++a,--s){const t=e[a];e[a]=e[s];e[s]=t}}function createBidiText(e,t,i=!1){let a="ltr";i?a="ttb":t||(a="rtl");return{str:e,dir:a}}const Cs=[],Bs=[];function bidi(e,t=-1,i=!1){let a=!0;const s=e.length;if(0===s||i)return createBidiText(e,a,i);Cs.length=s;Bs.length=s;let r,n,o=0;for(r=0;r<s;++r){Cs[r]=e.charAt(r);const t=e.charCodeAt(r);let i="L";if(t<=255)i=hs[t];else if(1424<=t&&t<=1524)i="R";else if(1536<=t&&t<=1791){i=ls[255&t];i||warn("Bidi: invalid Unicode character "+t.toString(16))}else(1792<=t&&t<=2220||64336<=t&&t<=65023||65136<=t&&t<=65279)&&(i="AL");"R"!==i&&"AL"!==i&&"AN"!==i||o++;Bs[r]=i}if(0===o){a=!0;return createBidiText(e,a)}if(-1===t)if(o/s<.3&&s>4){a=!0;t=0}else{a=!1;t=1}const g=[];for(r=0;r<s;++r)g[r]=t;const c=isOdd(t)?"R":"L",h=c,l=h;let C,Q=h;for(r=0;r<s;++r)"NSM"===Bs[r]?Bs[r]=Q:Q=Bs[r];Q=h;for(r=0;r<s;++r){C=Bs[r];"EN"===C?Bs[r]="AL"===Q?"AN":"EN":"R"!==C&&"L"!==C&&"AL"!==C||(Q=C)}for(r=0;r<s;++r){C=Bs[r];"AL"===C&&(Bs[r]="R")}for(r=1;r<s-1;++r){"ES"===Bs[r]&&"EN"===Bs[r-1]&&"EN"===Bs[r+1]&&(Bs[r]="EN");"CS"!==Bs[r]||"EN"!==Bs[r-1]&&"AN"!==Bs[r-1]||Bs[r+1]!==Bs[r-1]||(Bs[r]=Bs[r-1])}for(r=0;r<s;++r)if("EN"===Bs[r]){for(let e=r-1;e>=0&&"ET"===Bs[e];--e)Bs[e]="EN";for(let e=r+1;e<s&&"ET"===Bs[e];++e)Bs[e]="EN"}for(r=0;r<s;++r){C=Bs[r];"WS"!==C&&"ES"!==C&&"ET"!==C&&"CS"!==C||(Bs[r]="ON")}Q=h;for(r=0;r<s;++r){C=Bs[r];"EN"===C?Bs[r]="L"===Q?"L":"EN":"R"!==C&&"L"!==C||(Q=C)}for(r=0;r<s;++r)if("ON"===Bs[r]){const e=findUnequal(Bs,r+1,"ON");let t=h;r>0&&(t=Bs[r-1]);let i=l;e+1<s&&(i=Bs[e+1]);"L"!==t&&(t="R");"L"!==i&&(i="R");t===i&&setValues(Bs,r,e,t);r=e-1}for(r=0;r<s;++r)"ON"===Bs[r]&&(Bs[r]=c);for(r=0;r<s;++r){C=Bs[r];isEven(g[r])?"R"===C?g[r]+=1:"AN"!==C&&"EN"!==C||(g[r]+=2):"L"!==C&&"AN"!==C&&"EN"!==C||(g[r]+=1)}let E,u=-1,d=99;for(r=0,n=g.length;r<n;++r){E=g[r];u<E&&(u=E);d>E&&isOdd(E)&&(d=E)}for(E=u;E>=d;--E){let e=-1;for(r=0,n=g.length;r<n;++r)if(g[r]<E){if(e>=0){reverseValues(Cs,e,r);e=-1}}else e<0&&(e=r);e>=0&&reverseValues(Cs,e,g.length)}for(r=0,n=Cs.length;r<n;++r){const e=Cs[r];"<"!==e&&">"!==e||(Cs[r]="")}return createBidiText(Cs.join(""),a)}const Qs={style:"normal",weight:"normal"},Es={style:"normal",weight:"bold"},us={style:"italic",weight:"normal"},ds={style:"italic",weight:"bold"},fs=new Map([["Times-Roman",{local:["Times New Roman","Times-Roman","Times","Liberation Serif","Nimbus Roman","Nimbus Roman L","Tinos","Thorndale","TeX Gyre Termes","FreeSerif","Linux Libertine O","Libertinus Serif","DejaVu Serif","Bitstream Vera Serif","Ubuntu"],style:Qs,ultimate:"serif"}],["Times-Bold",{alias:"Times-Roman",style:Es,ultimate:"serif"}],["Times-Italic",{alias:"Times-Roman",style:us,ultimate:"serif"}],["Times-BoldItalic",{alias:"Times-Roman",style:ds,ultimate:"serif"}],["Helvetica",{local:["Helvetica","Helvetica Neue","Arial","Arial Nova","Liberation Sans","Arimo","Nimbus Sans","Nimbus Sans L","A030","TeX Gyre Heros","FreeSans","DejaVu Sans","Albany","Bitstream Vera Sans","Arial Unicode MS","Microsoft Sans Serif","Apple Symbols","Cantarell"],path:"LiberationSans-Regular.ttf",style:Qs,ultimate:"sans-serif"}],["Helvetica-Bold",{alias:"Helvetica",path:"LiberationSans-Bold.ttf",style:Es,ultimate:"sans-serif"}],["Helvetica-Oblique",{alias:"Helvetica",path:"LiberationSans-Italic.ttf",style:us,ultimate:"sans-serif"}],["Helvetica-BoldOblique",{alias:"Helvetica",path:"LiberationSans-BoldItalic.ttf",style:ds,ultimate:"sans-serif"}],["Courier",{local:["Courier","Courier New","Liberation Mono","Nimbus Mono","Nimbus Mono L","Cousine","Cumberland","TeX Gyre Cursor","FreeMono","Linux Libertine Mono O","Libertinus Mono"],style:Qs,ultimate:"monospace"}],["Courier-Bold",{alias:"Courier",style:Es,ultimate:"monospace"}],["Courier-Oblique",{alias:"Courier",style:us,ultimate:"monospace"}],["Courier-BoldOblique",{alias:"Courier",style:ds,ultimate:"monospace"}],["ArialBlack",{local:["Arial Black"],style:{style:"normal",weight:"900"},fallback:"Helvetica-Bold"}],["ArialBlack-Bold",{alias:"ArialBlack"}],["ArialBlack-Italic",{alias:"ArialBlack",style:{style:"italic",weight:"900"},fallback:"Helvetica-BoldOblique"}],["ArialBlack-BoldItalic",{alias:"ArialBlack-Italic"}],["ArialNarrow",{local:["Arial Narrow","Liberation Sans Narrow","Helvetica Condensed","Nimbus Sans Narrow","TeX Gyre Heros Cn"],style:Qs,fallback:"Helvetica"}],["ArialNarrow-Bold",{alias:"ArialNarrow",style:Es,fallback:"Helvetica-Bold"}],["ArialNarrow-Italic",{alias:"ArialNarrow",style:us,fallback:"Helvetica-Oblique"}],["ArialNarrow-BoldItalic",{alias:"ArialNarrow",style:ds,fallback:"Helvetica-BoldOblique"}],["Calibri",{local:["Calibri","Carlito"],style:Qs,fallback:"Helvetica"}],["Calibri-Bold",{alias:"Calibri",style:Es,fallback:"Helvetica-Bold"}],["Calibri-Italic",{alias:"Calibri",style:us,fallback:"Helvetica-Oblique"}],["Calibri-BoldItalic",{alias:"Calibri",style:ds,fallback:"Helvetica-BoldOblique"}],["Wingdings",{local:["Wingdings","URW Dingbats"],style:Qs}],["Wingdings-Regular",{alias:"Wingdings"}],["Wingdings-Bold",{alias:"Wingdings"}]]),ps=new Map([["Arial-Black","ArialBlack"]]);function getFamilyName(e){const t=new Set(["thin","extralight","ultralight","demilight","semilight","light","book","regular","normal","medium","demibold","semibold","bold","extrabold","ultrabold","black","heavy","extrablack","ultrablack","roman","italic","oblique","ultracondensed","extracondensed","condensed","semicondensed","normal","semiexpanded","expanded","extraexpanded","ultraexpanded","bolditalic"]);return e.split(/[- ,+]+/g).filter((e=>!t.has(e.toLowerCase()))).join(" ")}function generateFont({alias:e,local:t,path:i,fallback:a,style:s,ultimate:r},n,o,g=!0,c=!0,h=""){const l={style:null,ultimate:null};if(t){const e=h?` ${h}`:"";for(const i of t)n.push(`local(${i}${e})`)}if(e){const t=fs.get(e),r=h||function getStyleToAppend(e){switch(e){case Es:return"Bold";case us:return"Italic";case ds:return"Bold Italic";default:if("bold"===e?.weight)return"Bold";if("italic"===e?.style)return"Italic"}return""}(s);Object.assign(l,generateFont(t,n,o,g&&!a,c&&!i,r))}s&&(l.style=s);r&&(l.ultimate=r);if(g&&a){const e=fs.get(a),{ultimate:t}=generateFont(e,n,o,g,c&&!i,h);l.ultimate||=t}c&&i&&o&&n.push(`url(${o}${i})`);return l}function getFontSubstitution(e,t,i,a,s,r){if(a.startsWith("InvalidPDFjsFont_"))return null;"TrueType"!==r&&"Type1"!==r||!/^[A-Z]{6}\+/.test(a)||(a=a.slice(7));const n=a=normalizeFontName(a);let o=e.get(n);if(o)return o;let g=fs.get(a);if(!g)for(const[e,t]of ps)if(a.startsWith(e)){a=`${t}${a.substring(e.length)}`;g=fs.get(a);break}let c=!1;if(!g){g=fs.get(s);c=!0}const h=`${t.getDocId()}_s${t.createFontId()}`;if(!g){if(!validateFontName(a)){warn(`Cannot substitute the font because of its name: ${a}`);e.set(n,null);return null}const t=/bold/gi.test(a),i=/oblique|italic/gi.test(a),s=t&&i&&ds||t&&Es||i&&us||Qs;o={css:`"${getFamilyName(a)}",${h}`,guessFallback:!0,loadedName:h,baseFontName:a,src:`local(${a})`,style:s};e.set(n,o);return o}const l=[];c&&validateFontName(a)&&l.push(`local(${a})`);const{style:C,ultimate:Q}=generateFont(g,l,i),E=null===Q,u=E?"":`,${Q}`;o={css:`"${getFamilyName(a)}",${h}${u}`,guessFallback:E,loadedName:h,baseFontName:a,src:l.join(","),style:C};e.set(n,o);return o}class ImageResizer{constructor(e,t){this._imgData=e;this._isMask=t}static needsToBeResized(e,t){if(e<=this._goodSquareLength&&t<=this._goodSquareLength)return!1;const{MAX_DIM:i}=this;if(e>i||t>i)return!0;const a=e*t;if(this._hasMaxArea)return a>this.MAX_AREA;if(a<this._goodSquareLength**2)return!1;if(this._areGoodDims(e,t)){this._goodSquareLength=Math.max(this._goodSquareLength,Math.floor(Math.sqrt(e*t)));return!1}this._goodSquareLength=this._guessMax(this._goodSquareLength,i,128,0);return a>(this.MAX_AREA=this._goodSquareLength**2)}static get MAX_DIM(){return shadow(this,"MAX_DIM",this._guessMax(2048,65537,0,1))}static get MAX_AREA(){this._hasMaxArea=!0;return shadow(this,"MAX_AREA",this._guessMax(ImageResizer._goodSquareLength,this.MAX_DIM,128,0)**2)}static set MAX_AREA(e){if(e>=0){this._hasMaxArea=!0;shadow(this,"MAX_AREA",e)}}static setMaxArea(e){this._hasMaxArea||(this.MAX_AREA=e>>2)}static _areGoodDims(e,t){try{const i=new OffscreenCanvas(e,t),a=i.getContext("2d");a.fillRect(0,0,1,1);const s=a.getImageData(0,0,1,1).data[3];i.width=i.height=1;return 0!==s}catch{return!1}}static _guessMax(e,t,i,a){for(;e+i+1<t;){const i=Math.floor((e+t)/2),s=a||i;this._areGoodDims(i,s)?e=i:t=i}return e}static async createImage(e,t=!1){return new ImageResizer(e,t)._createImage()}async _createImage(){const e=this._encodeBMP(),t=new Blob([e.buffer],{type:"image/bmp"}),i=createImageBitmap(t),{MAX_AREA:a,MAX_DIM:s}=ImageResizer,{_imgData:r}=this,{width:n,height:o}=r,g=Math.max(n/s,o/s,Math.sqrt(n*o/a)),c=Math.max(g,2),h=Math.round(10*(g+1.25))/10/c,l=Math.floor(Math.log2(h)),C=new Array(l+2).fill(2);C[0]=c;C.splice(-1,1,h/(1<<l));let Q=n,E=o,u=await i;for(const e of C){const t=Q,i=E;Q=Math.floor(Q/e)-1;E=Math.floor(E/e)-1;const a=new OffscreenCanvas(Q,E);a.getContext("2d").drawImage(u,0,0,t,i,0,0,Q,E);u=a.transferToImageBitmap()}r.data=null;r.bitmap=u;r.width=Q;r.height=E;return r}_encodeBMP(){const{width:e,height:t,kind:i}=this._imgData;let a,s=this._imgData.data,r=new Uint8Array(0),n=r,o=0;switch(i){case b:{a=1;r=new Uint8Array(this._isMask?[255,255,255,255,0,0,0,0]:[0,0,0,0,255,255,255,255]);const i=e+7>>3,n=i+3&-4;if(i!==n){const e=new Uint8Array(n*t);let a=0;for(let r=0,o=t*i;r<o;r+=i,a+=n)e.set(s.subarray(r,r+i),a);s=e}break}case D:a=24;if(3&e){const i=3*e,a=i+3&-4,r=a-i,n=new Uint8Array(a*t);let o=0;for(let e=0,a=t*i;e<a;e+=i){const t=s.subarray(e,e+i);for(let e=0;e<i;e+=3){n[o++]=t[e+2];n[o++]=t[e+1];n[o++]=t[e]}o+=r}s=n}else for(let e=0,t=s.length;e<t;e+=3){const t=s[e];s[e]=s[e+2];s[e+2]=t}break;case F:a=32;o=3;n=new Uint8Array(68);const i=new DataView(n.buffer);if(FeatureTest.isLittleEndian){i.setUint32(0,255,!0);i.setUint32(4,65280,!0);i.setUint32(8,16711680,!0);i.setUint32(12,4278190080,!0)}else{i.setUint32(0,4278190080,!0);i.setUint32(4,16711680,!0);i.setUint32(8,65280,!0);i.setUint32(12,255,!0)}break;default:throw new Error("invalid format")}let g=0;const c=40+n.length,h=14+c+r.length+s.length,l=new Uint8Array(h),C=new DataView(l.buffer);C.setUint16(g,19778,!0);g+=2;C.setUint32(g,h,!0);g+=4;C.setUint32(g,0,!0);g+=4;C.setUint32(g,14+c+r.length,!0);g+=4;C.setUint32(g,c,!0);g+=4;C.setInt32(g,e,!0);g+=4;C.setInt32(g,-t,!0);g+=4;C.setUint16(g,1,!0);g+=2;C.setUint16(g,a,!0);g+=2;C.setUint32(g,o,!0);g+=4;C.setUint32(g,0,!0);g+=4;C.setInt32(g,0,!0);g+=4;C.setInt32(g,0,!0);g+=4;C.setUint32(g,r.length/4,!0);g+=4;C.setUint32(g,0,!0);g+=4;l.set(n,g);g+=n.length;l.set(r,g);g+=r.length;l.set(s,g);return l}}ImageResizer._goodSquareLength=2048;const ms=3285377520,ys=4294901760,ws=65535;class MurmurHash3_64{constructor(e){this.h1=e?4294967295&e:ms;this.h2=e?4294967295&e:ms}update(e){let t,i;if("string"==typeof e){t=new Uint8Array(2*e.length);i=0;for(let a=0,s=e.length;a<s;a++){const s=e.charCodeAt(a);if(s<=255)t[i++]=s;else{t[i++]=s>>>8;t[i++]=255&s}}}else{if(!ArrayBuffer.isView(e))throw new Error("Invalid data format, must be a string or TypedArray.");t=e.slice();i=t.byteLength}const a=i>>2,s=i-4*a,r=new Uint32Array(t.buffer,0,a);let n=0,o=0,g=this.h1,c=this.h2;const h=3432918353,l=461845907,C=11601,Q=13715;for(let e=0;e<a;e++)if(1&e){n=r[e];n=n*h&ys|n*C&ws;n=n<<15|n>>>17;n=n*l&ys|n*Q&ws;g^=n;g=g<<13|g>>>19;g=5*g+3864292196}else{o=r[e];o=o*h&ys|o*C&ws;o=o<<15|o>>>17;o=o*l&ys|o*Q&ws;c^=o;c=c<<13|c>>>19;c=5*c+3864292196}n=0;switch(s){case 3:n^=t[4*a+2]<<16;case 2:n^=t[4*a+1]<<8;case 1:n^=t[4*a];n=n*h&ys|n*C&ws;n=n<<15|n>>>17;n=n*l&ys|n*Q&ws;1&a?g^=n:c^=n}this.h1=g;this.h2=c}hexdigest(){let e=this.h1,t=this.h2;e^=t>>>1;e=3981806797*e&ys|36045*e&ws;t=4283543511*t&ys|(2950163797*(t<<16|e>>>16)&ys)>>>16;e^=t>>>1;e=444984403*e&ys|60499*e&ws;t=3301882366*t&ys|(3120437893*(t<<16|e>>>16)&ys)>>>16;e^=t>>>1;return(e>>>0).toString(16).padStart(8,"0")+(t>>>0).toString(16).padStart(8,"0")}}function addState(e,t,i,a,s){let r=e;for(let e=0,i=t.length-1;e<i;e++){const i=t[e];r=r[i]||=[]}r[t.at(-1)]={checkFn:i,iterateFn:a,processFn:s}}const bs=[];addState(bs,[GA,MA,ze,xA],null,(function iterateInlineImageGroup(e,t){const i=e.fnArray,a=(t-(e.iCurr-3))%4;switch(a){case 0:return i[t]===GA;case 1:return i[t]===MA;case 2:return i[t]===ze;case 3:return i[t]===xA}throw new Error(`iterateInlineImageGroup - invalid pos: ${a}`)}),(function foundInlineImageGroup(e,t){const i=e.fnArray,a=e.argsArray,s=e.iCurr,r=s-3,n=s-2,o=s-1,g=Math.min(Math.floor((t-r)/4),200);if(g<10)return t-(t-r)%4;let c=0;const h=[];let l=0,C=1,Q=1;for(let e=0;e<g;e++){const t=a[n+(e<<2)],i=a[o+(e<<2)][0];if(C+i.width>1e3){c=Math.max(c,C);Q+=l+2;C=0;l=0}h.push({transform:t,x:C,y:Q,w:i.width,h:i.height});C+=i.width+2;l=Math.max(l,i.height)}const E=Math.max(c,C)+1,u=Q+l+1,d=new Uint8Array(E*u*4),f=E<<2;for(let e=0;e<g;e++){const t=a[o+(e<<2)][0].data,i=h[e].w<<2;let s=0,r=h[e].x+h[e].y*E<<2;d.set(t.subarray(0,i),r-f);for(let a=0,n=h[e].h;a<n;a++){d.set(t.subarray(s,s+i),r);s+=i;r+=f}d.set(t.subarray(s-i,s),r);for(;r>=0;){t[r-4]=t[r];t[r-3]=t[r+1];t[r-2]=t[r+2];t[r-1]=t[r+3];t[r+i]=t[r+i-4];t[r+i+1]=t[r+i-3];t[r+i+2]=t[r+i-2];t[r+i+3]=t[r+i-1];r-=f}}const p={width:E,height:u};if(e.isOffscreenCanvasSupported){const e=new OffscreenCanvas(E,u);e.getContext("2d").putImageData(new ImageData(new Uint8ClampedArray(d.buffer),E,u),0,0);p.bitmap=e.transferToImageBitmap();p.data=null}else{p.kind=F;p.data=d}i.splice(r,4*g,_e);a.splice(r,4*g,[p,h]);return r+1}));addState(bs,[GA,MA,je,xA],null,(function iterateImageMaskGroup(e,t){const i=e.fnArray,a=(t-(e.iCurr-3))%4;switch(a){case 0:return i[t]===GA;case 1:return i[t]===MA;case 2:return i[t]===je;case 3:return i[t]===xA}throw new Error(`iterateImageMaskGroup - invalid pos: ${a}`)}),(function foundImageMaskGroup(e,t){const i=e.fnArray,a=e.argsArray,s=e.iCurr,r=s-3,n=s-2,o=s-1;let g=Math.floor((t-r)/4);if(g<10)return t-(t-r)%4;let c,h,l=!1;const C=a[o][0],Q=a[n][0],E=a[n][1],u=a[n][2],d=a[n][3];if(E===u){l=!0;c=n+4;let e=o+4;for(let t=1;t<g;t++,c+=4,e+=4){h=a[c];if(a[e][0]!==C||h[0]!==Q||h[1]!==E||h[2]!==u||h[3]!==d){t<10?l=!1:g=t;break}}}if(l){g=Math.min(g,1e3);const e=new Float32Array(2*g);c=n;for(let t=0;t<g;t++,c+=4){h=a[c];e[t<<1]=h[4];e[1+(t<<1)]=h[5]}i.splice(r,4*g,At);a.splice(r,4*g,[C,Q,E,u,d,e])}else{g=Math.min(g,100);const e=[];for(let t=0;t<g;t++){h=a[n+(t<<2)];const i=a[o+(t<<2)][0];e.push({data:i.data,width:i.width,height:i.height,interpolate:i.interpolate,count:i.count,transform:h})}i.splice(r,4*g,Ze);a.splice(r,4*g,[e])}return r+1}));addState(bs,[GA,MA,Ve,xA],(function(e){const t=e.argsArray,i=e.iCurr-2;return 0===t[i][1]&&0===t[i][2]}),(function iterateImageGroup(e,t){const i=e.fnArray,a=e.argsArray,s=(t-(e.iCurr-3))%4;switch(s){case 0:return i[t]===GA;case 1:if(i[t]!==MA)return!1;const s=e.iCurr-2,r=a[s][0],n=a[s][3];return a[t][0]===r&&0===a[t][1]&&0===a[t][2]&&a[t][3]===n;case 2:if(i[t]!==Ve)return!1;const o=a[e.iCurr-1][0];return a[t][0]===o;case 3:return i[t]===xA}throw new Error(`iterateImageGroup - invalid pos: ${s}`)}),(function(e,t){const i=e.fnArray,a=e.argsArray,s=e.iCurr,r=s-3,n=s-2,o=a[s-1][0],g=a[n][0],c=a[n][3],h=Math.min(Math.floor((t-r)/4),1e3);if(h<3)return t-(t-r)%4;const l=new Float32Array(2*h);let C=n;for(let e=0;e<h;e++,C+=4){const t=a[C];l[e<<1]=t[4];l[1+(e<<1)]=t[5]}const Q=[o,g,c,l];i.splice(r,4*h,$e);a.splice(r,4*h,Q);return r+1}));addState(bs,[$A,se,Ie,he,Ae],null,(function iterateShowTextGroup(e,t){const i=e.fnArray,a=e.argsArray,s=(t-(e.iCurr-4))%5;switch(s){case 0:return i[t]===$A;case 1:return i[t]===se;case 2:return i[t]===Ie;case 3:if(i[t]!==he)return!1;const s=e.iCurr-3,r=a[s][0],n=a[s][1];return a[t][0]===r&&a[t][1]===n;case 4:return i[t]===Ae}throw new Error(`iterateShowTextGroup - invalid pos: ${s}`)}),(function(e,t){const i=e.fnArray,a=e.argsArray,s=e.iCurr,r=s-4,n=s-3,o=s-2,g=s-1,c=s,h=a[n][0],l=a[n][1];let C=Math.min(Math.floor((t-r)/5),1e3);if(C<3)return t-(t-r)%5;let Q=r;if(r>=4&&i[r-4]===i[n]&&i[r-3]===i[o]&&i[r-2]===i[g]&&i[r-1]===i[c]&&a[r-4][0]===h&&a[r-4][1]===l){C++;Q-=5}let E=Q+4;for(let e=1;e<C;e++){i.splice(E,3);a.splice(E,3);E+=2}return E+1}));class NullOptimizer{constructor(e){this.queue=e}_optimize(){}push(e,t){this.queue.fnArray.push(e);this.queue.argsArray.push(t);this._optimize()}flush(){}reset(){}}class QueueOptimizer extends NullOptimizer{constructor(e){super(e);this.state=null;this.context={iCurr:0,fnArray:e.fnArray,argsArray:e.argsArray,isOffscreenCanvasSupported:!1};this.match=null;this.lastProcessed=0}set isOffscreenCanvasSupported(e){this.context.isOffscreenCanvasSupported=e}_optimize(){const e=this.queue.fnArray;let t=this.lastProcessed,i=e.length,a=this.state,s=this.match;if(!a&&!s&&t+1===i&&!bs[e[t]]){this.lastProcessed=i;return}const r=this.context;for(;t<i;){if(s){if((0,s.iterateFn)(r,t)){t++;continue}t=(0,s.processFn)(r,t+1);i=e.length;s=null;a=null;if(t>=i)break}a=(a||bs)[e[t]];if(a&&!Array.isArray(a)){r.iCurr=t;t++;if(!a.checkFn||(0,a.checkFn)(r)){s=a;a=null}else a=null}else t++}this.state=a;this.match=s;this.lastProcessed=t}flush(){for(;this.match;){const e=this.queue.fnArray.length;this.lastProcessed=(0,this.match.processFn)(this.context,e);this.match=null;this.state=null;this._optimize()}}reset(){this.state=null;this.match=null;this.lastProcessed=0}}class OperatorList{static CHUNK_SIZE=1e3;static CHUNK_SIZE_ABOUT=this.CHUNK_SIZE-5;constructor(e=0,t){this._streamSink=t;this.fnArray=[];this.argsArray=[];this.optimizer=!t||e&Q?new NullOptimizer(this):new QueueOptimizer(this);this.dependencies=new Set;this._totalLength=0;this.weight=0;this._resolved=t?null:Promise.resolve()}set isOffscreenCanvasSupported(e){this.optimizer.isOffscreenCanvasSupported=e}get length(){return this.argsArray.length}get ready(){return this._resolved||this._streamSink.ready}get totalLength(){return this._totalLength+this.length}addOp(e,t){this.optimizer.push(e,t);this.weight++;this._streamSink&&(this.weight>=OperatorList.CHUNK_SIZE||this.weight>=OperatorList.CHUNK_SIZE_ABOUT&&(e===xA||e===Ae))&&this.flush()}addImageOps(e,t,i){void 0!==i&&this.addOp(He,["OC",i]);this.addOp(e,t);void 0!==i&&this.addOp(Ye,[])}addDependency(e){if(!this.dependencies.has(e)){this.dependencies.add(e);this.addOp(yA,[e])}}addDependencies(e){for(const t of e)this.addDependency(t)}addOpList(e){if(e instanceof OperatorList){for(const t of e.dependencies)this.dependencies.add(t);for(let t=0,i=e.length;t<i;t++)this.addOp(e.fnArray[t],e.argsArray[t])}else warn('addOpList - ignoring invalid "opList" parameter.')}getIR(){return{fnArray:this.fnArray,argsArray:this.argsArray,length:this.length}}get _transfers(){const e=[],{fnArray:t,argsArray:i,length:a}=this;for(let s=0;s<a;s++)switch(t[s]){case ze:case _e:case je:const t=i[s][0];!t.cached&&t.data?.buffer instanceof ArrayBuffer&&e.push(t.data.buffer)}return e}flush(e=!1,t=null){this.optimizer.flush();const i=this.length;this._totalLength+=i;this._streamSink.enqueue({fnArray:this.fnArray,argsArray:this.argsArray,lastChunk:e,separateAnnots:t,length:i},1,this._transfers);this.dependencies.clear();this.fnArray.length=0;this.argsArray.length=0;this.weight=0;this.optimizer.reset()}}function decodeAndClamp(e,t,i,a){(e=t+e*i)<0?e=0:e>a&&(e=a);return e}function resizeImageMask(e,t,i,a,s,r){const n=s*r;let o;o=t<=8?new Uint8Array(n):t<=16?new Uint16Array(n):new Uint32Array(n);const g=i/s,c=a/r;let h,l,C,Q,E=0;const u=new Uint16Array(s),d=i;for(h=0;h<s;h++)u[h]=Math.floor(h*g);for(h=0;h<r;h++){C=Math.floor(h*c)*d;for(l=0;l<s;l++){Q=C+u[l];o[E++]=e[Q]}}return o}class PDFImage{constructor({xref:e,res:t,image:i,isInline:a=!1,smask:s=null,mask:r=null,isMask:n=!1,pdfFunctionFactory:o,localColorSpaceCache:g}){this.image=i;let c=!1;const h=i.dict,l=h.get("F","Filter");let C;if(l instanceof Name)C=l.name;else if(Array.isArray(l)){const t=e.fetchIfRef(l[0]);t instanceof Name&&(C=t.name)}switch(C){case"JPXDecode":({width:i.width,height:i.height,componentsCount:i.numComps,bitsPerComponent:i.bitsPerComponent}=JpxImage.parseImageProperties(i.stream));i.stream.reset();c=!0;break;case"JBIG2Decode":i.bitsPerComponent=1;i.numComps=1}let Q=h.get("W","Width"),E=h.get("H","Height");if(Number.isInteger(i.width)&&i.width>0&&Number.isInteger(i.height)&&i.height>0&&(i.width!==Q||i.height!==E)){warn("PDFImage - using the Width/Height of the image data, rather than the image dictionary.");Q=i.width;E=i.height}if(Q<1||E<1)throw new FormatError(`Invalid image width: ${Q} or height: ${E}`);this.width=Q;this.height=E;this.interpolate=h.get("I","Interpolate");this.imageMask=h.get("IM","ImageMask")||!1;this.matte=h.get("Matte")||!1;let u=i.bitsPerComponent;if(!u){u=h.get("BPC","BitsPerComponent");if(!u){if(!this.imageMask)throw new FormatError(`Bits per component missing in image: ${this.imageMask}`);u=1}}this.bpc=u;if(!this.imageMask){let s=h.getRaw("CS")||h.getRaw("ColorSpace");if(!s){info("JPX images (which do not require color spaces)");switch(i.numComps){case 1:s=Name.get("DeviceGray");break;case 3:s=Name.get("DeviceRGB");break;case 4:s=Name.get("DeviceCMYK");break;default:throw new Error(`JPX images with ${i.numComps} color components not supported.`)}}this.colorSpace=ColorSpace.parse({cs:s,xref:e,resources:a?t:null,pdfFunctionFactory:o,localColorSpaceCache:g});this.numComps=this.colorSpace.numComps;this.ignoreColorSpace=c&&"Indexed"===this.colorSpace.name}this.decode=h.getArray("D","Decode");this.needsDecode=!1;if(this.decode&&(this.colorSpace&&!this.colorSpace.isDefaultDecode(this.decode,u)||n&&!ColorSpace.isDefaultDecode(this.decode,1))){this.needsDecode=!0;const e=(1<<u)-1;this.decodeCoefficients=[];this.decodeAddends=[];const t="Indexed"===this.colorSpace?.name;for(let i=0,a=0;i<this.decode.length;i+=2,++a){const s=this.decode[i],r=this.decode[i+1];this.decodeCoefficients[a]=t?(r-s)/e:r-s;this.decodeAddends[a]=t?s:e*s}}if(s)this.smask=new PDFImage({xref:e,res:t,image:s,isInline:a,pdfFunctionFactory:o,localColorSpaceCache:g});else if(r)if(r instanceof BaseStream){r.dict.get("IM","ImageMask")?this.mask=new PDFImage({xref:e,res:t,image:r,isInline:a,isMask:!0,pdfFunctionFactory:o,localColorSpaceCache:g}):warn("Ignoring /Mask in image without /ImageMask.")}else this.mask=r}static async buildImage({xref:e,res:t,image:i,isInline:a=!1,pdfFunctionFactory:s,localColorSpaceCache:r}){const n=i;let o=null,g=null;const c=i.dict.get("SMask"),h=i.dict.get("Mask");c?c instanceof BaseStream?o=c:warn("Unsupported /SMask format."):h&&(h instanceof BaseStream||Array.isArray(h)?g=h:warn("Unsupported /Mask format."));return new PDFImage({xref:e,res:t,image:n,isInline:a,smask:o,mask:g,pdfFunctionFactory:s,localColorSpaceCache:r})}static createRawMask({imgArray:e,width:t,height:i,imageIsFromDecodeStream:a,inverseDecode:s,interpolate:r}){const n=(t+7>>3)*i,o=e.byteLength;let g,c;if(!a||s&&!(n===o))if(s){g=new Uint8Array(n);g.set(e);g.fill(255,o)}else g=new Uint8Array(e);else g=e;if(s)for(c=0;c<o;c++)g[c]^=255;return{data:g,width:t,height:i,interpolate:r}}static async createMask({imgArray:e,width:t,height:i,imageIsFromDecodeStream:a,inverseDecode:s,interpolate:r,isOffscreenCanvasSupported:n=!1}){const o=1===t&&1===i&&s===(0===e.length||!!(128&e[0]));if(o)return{isSingleOpaquePixel:o};if(n){if(ImageResizer.needsToBeResized(t,i)){const a=new Uint8ClampedArray(t*i*4);convertBlackAndWhiteToRGBA({src:e,dest:a,width:t,height:i,nonBlackColor:0,inverseDecode:s});return ImageResizer.createImage({kind:F,data:a,width:t,height:i,interpolate:r})}const a=new OffscreenCanvas(t,i),n=a.getContext("2d"),o=n.createImageData(t,i);convertBlackAndWhiteToRGBA({src:e,dest:o.data,width:t,height:i,nonBlackColor:0,inverseDecode:s});n.putImageData(o,0,0);return{data:null,width:t,height:i,interpolate:r,bitmap:a.transferToImageBitmap()}}return this.createRawMask({imgArray:e,width:t,height:i,inverseDecode:s,imageIsFromDecodeStream:a,interpolate:r})}get drawWidth(){return Math.max(this.width,this.smask?.width||0,this.mask?.width||0)}get drawHeight(){return Math.max(this.height,this.smask?.height||0,this.mask?.height||0)}decodeBuffer(e){const t=this.bpc,i=this.numComps,a=this.decodeAddends,s=this.decodeCoefficients,r=(1<<t)-1;let n,o;if(1===t){for(n=0,o=e.length;n<o;n++)e[n]=+!e[n];return}let g=0;for(n=0,o=this.width*this.height;n<o;n++)for(let t=0;t<i;t++){e[g]=decodeAndClamp(e[g],a[t],s[t],r);g++}}getComponents(e){const t=this.bpc;if(8===t)return e;const i=this.width,a=this.height,s=this.numComps,r=i*a*s;let n,o=0;n=t<=8?new Uint8Array(r):t<=16?new Uint16Array(r):new Uint32Array(r);const g=i*s,c=(1<<t)-1;let h,l,C=0;if(1===t){let t,i,s;for(let r=0;r<a;r++){i=C+(-8&g);s=C+g;for(;C<i;){l=e[o++];n[C]=l>>7&1;n[C+1]=l>>6&1;n[C+2]=l>>5&1;n[C+3]=l>>4&1;n[C+4]=l>>3&1;n[C+5]=l>>2&1;n[C+6]=l>>1&1;n[C+7]=1&l;C+=8}if(C<s){l=e[o++];t=128;for(;C<s;){n[C++]=+!!(l&t);t>>=1}}}}else{let i=0;l=0;for(C=0,h=r;C<h;++C){if(C%g==0){l=0;i=0}for(;i<t;){l=l<<8|e[o++];i+=8}const a=i-t;let s=l>>a;s<0?s=0:s>c&&(s=c);n[C]=s;l&=(1<<a)-1;i=a}}return n}fillOpacity(e,t,i,a,s){const r=this.smask,n=this.mask;let o,g,c,h,l,C;if(r){g=r.width;c=r.height;o=new Uint8ClampedArray(g*c);r.fillGrayBuffer(o);g===t&&c===i||(o=resizeImageMask(o,r.bpc,g,c,t,i))}else if(n)if(n instanceof PDFImage){g=n.width;c=n.height;o=new Uint8ClampedArray(g*c);n.numComps=1;n.fillGrayBuffer(o);for(h=0,l=g*c;h<l;++h)o[h]=255-o[h];g===t&&c===i||(o=resizeImageMask(o,n.bpc,g,c,t,i))}else{if(!Array.isArray(n))throw new FormatError("Unknown mask format.");{o=new Uint8ClampedArray(t*i);const e=this.numComps;for(h=0,l=t*i;h<l;++h){let t=0;const i=h*e;for(C=0;C<e;++C){const e=s[i+C],a=2*C;if(e<n[a]||e>n[a+1]){t=255;break}}o[h]=t}}}if(o)for(h=0,C=3,l=t*a;h<l;++h,C+=4)e[C]=o[h];else for(h=0,C=3,l=t*a;h<l;++h,C+=4)e[C]=255}undoPreblend(e,t,i){const a=this.smask?.matte;if(!a)return;const s=this.colorSpace.getRgb(a,0),r=s[0],n=s[1],o=s[2],g=t*i*4;for(let t=0;t<g;t+=4){const i=e[t+3];if(0===i){e[t]=255;e[t+1]=255;e[t+2]=255;continue}const a=255/i;e[t]=(e[t]-r)*a+r;e[t+1]=(e[t+1]-n)*a+n;e[t+2]=(e[t+2]-o)*a+o}}async createImageData(e=!1,t=!1){const i=this.drawWidth,a=this.drawHeight,s={width:i,height:a,interpolate:this.interpolate,kind:0,data:null},r=this.numComps,n=this.width,o=this.height,g=this.bpc,c=n*r*g+7>>3,h=t&&ImageResizer.needsToBeResized(i,a);if(!e){let e;"DeviceGray"===this.colorSpace.name&&1===g?e=b:"DeviceRGB"!==this.colorSpace.name||8!==g||this.needsDecode||(e=D);if(e&&!this.smask&&!this.mask&&i===n&&a===o){const r=this.getImageBytes(o*c,{});if(t)return h?ImageResizer.createImage({data:r,kind:e,width:i,height:a,interpolate:this.interpolate},this.needsDecode):this.createBitmap(e,n,o,r);s.kind=e;s.data=r;if(this.needsDecode){assert(e===b,"PDFImage.createImageData: The image must be grayscale.");const t=s.data;for(let e=0,i=t.length;e<i;e++)t[e]^=255}return s}if(this.image instanceof JpegStream&&!this.smask&&!this.mask&&!this.needsDecode){let e=o*c;if(t&&!h){let t=!1;switch(this.colorSpace.name){case"DeviceGray":e*=4;t=!0;break;case"DeviceRGB":e=e/3*4;t=!0;break;case"DeviceCMYK":t=!0}if(t){const t=this.getImageBytes(e,{drawWidth:i,drawHeight:a,forceRGBA:!0});return this.createBitmap(F,i,a,t)}}else switch(this.colorSpace.name){case"DeviceGray":e*=3;case"DeviceRGB":case"DeviceCMYK":s.kind=D;s.data=this.getImageBytes(e,{drawWidth:i,drawHeight:a,forceRGB:!0});return h?ImageResizer.createImage(s):s}}}const l=this.getImageBytes(o*c,{internal:!0}),C=0|l.length/c*a/o,Q=this.getComponents(l);let E,u,d,f,p,m;if(t&&!h){d=new OffscreenCanvas(i,a);f=d.getContext("2d");p=f.createImageData(i,a);m=p.data}s.kind=F;if(e||this.smask||this.mask){t&&!h||(m=new Uint8ClampedArray(i*a*4));E=1;u=!0;this.fillOpacity(m,i,a,C,Q)}else{if(!t||h){s.kind=D;m=new Uint8ClampedArray(i*a*3);E=0}else{new Uint32Array(m.buffer).fill(FeatureTest.isLittleEndian?4278190080:255);E=1}u=!1}this.needsDecode&&this.decodeBuffer(Q);this.colorSpace.fillRgb(m,n,o,i,a,C,g,Q,E);u&&this.undoPreblend(m,i,C);if(t&&!h){f.putImageData(p,0,0);return{data:null,width:i,height:a,bitmap:d.transferToImageBitmap(),interpolate:this.interpolate}}s.data=m;return h?ImageResizer.createImage(s):s}fillGrayBuffer(e){const t=this.numComps;if(1!==t)throw new FormatError(`Reading gray scale from a color image: ${t}`);const i=this.width,a=this.height,s=this.bpc,r=i*t*s+7>>3,n=this.getImageBytes(a*r,{internal:!0}),o=this.getComponents(n);let g,c;if(1===s){c=i*a;if(this.needsDecode)for(g=0;g<c;++g)e[g]=o[g]-1&255;else for(g=0;g<c;++g)e[g]=255&-o[g];return}this.needsDecode&&this.decodeBuffer(o);c=i*a;const h=255/((1<<s)-1);for(g=0;g<c;++g)e[g]=h*o[g]}createBitmap(e,t,i,a){const s=new OffscreenCanvas(t,i),r=s.getContext("2d");let n;if(e===F)n=new ImageData(a,t,i);else{n=r.createImageData(t,i);convertToRGBA({kind:e,src:a,dest:new Uint32Array(n.data.buffer),width:t,height:i,inverseDecode:this.needsDecode})}r.putImageData(n,0,0);return{data:null,width:t,height:i,bitmap:s.transferToImageBitmap(),interpolate:this.interpolate}}getImageBytes(e,{drawWidth:t,drawHeight:i,forceRGBA:a=!1,forceRGB:s=!1,internal:r=!1}){this.image.reset();this.image.drawWidth=t||this.width;this.image.drawHeight=i||this.height;this.image.forceRGBA=!!a;this.image.forceRGB=!!s;const n=this.image.getBytes(e,this.ignoreColorSpace);if(r||this.image instanceof DecodeStream)return n;assert(n instanceof Uint8Array,'PDFImage.getImageBytes: Unsupported "imageBytes" type.');return new Uint8Array(n)}}const Ds=Object.freeze({maxImageSize:-1,disableFontFace:!1,ignoreErrors:!1,isEvalSupported:!0,isOffscreenCanvasSupported:!1,canvasMaxAreaInBytes:-1,fontExtraProperties:!1,useSystemFonts:!0,cMapUrl:null,standardFontDataUrl:null}),Fs=1,Ss=2,ks=Promise.resolve();function normalizeBlendMode(e,t=!1){if(Array.isArray(e)){for(const t of e){const e=normalizeBlendMode(t,!0);if(e)return e}warn(`Unsupported blend mode Array: ${e}`);return"source-over"}if(!(e instanceof Name))return t?null:"source-over";switch(e.name){case"Normal":case"Compatible":return"source-over";case"Multiply":return"multiply";case"Screen":return"screen";case"Overlay":return"overlay";case"Darken":return"darken";case"Lighten":return"lighten";case"ColorDodge":return"color-dodge";case"ColorBurn":return"color-burn";case"HardLight":return"hard-light";case"SoftLight":return"soft-light";case"Difference":return"difference";case"Exclusion":return"exclusion";case"Hue":return"hue";case"Saturation":return"saturation";case"Color":return"color";case"Luminosity":return"luminosity"}if(t)return null;warn(`Unsupported blend mode: ${e.name}`);return"source-over"}function incrementCachedImageMaskCount(e){e.fn===je&&e.args[0]?.count>0&&e.args[0].count++}class TimeSlotManager{static TIME_SLOT_DURATION_MS=20;static CHECK_TIME_EVERY=100;constructor(){this.reset()}check(){if(++this.checked<TimeSlotManager.CHECK_TIME_EVERY)return!1;this.checked=0;return this.endTime<=Date.now()}reset(){this.endTime=Date.now()+TimeSlotManager.TIME_SLOT_DURATION_MS;this.checked=0}}class PartialEvaluator{constructor({xref:e,handler:t,pageIndex:i,idFactory:a,fontCache:s,builtInCMapCache:r,standardFontDataCache:n,globalImageCache:o,systemFontCache:g,options:c=null}){this.xref=e;this.handler=t;this.pageIndex=i;this.idFactory=a;this.fontCache=s;this.builtInCMapCache=r;this.standardFontDataCache=n;this.globalImageCache=o;this.systemFontCache=g;this.options=c||Ds;this.type3FontRefs=null;this._regionalImageCache=new RegionalImageCache;this._fetchBuiltInCMapBound=this.fetchBuiltInCMap.bind(this);ImageResizer.setMaxArea(this.options.canvasMaxAreaInBytes)}get _pdfFunctionFactory(){return shadow(this,"_pdfFunctionFactory",new PDFFunctionFactory({xref:this.xref,isEvalSupported:this.options.isEvalSupported}))}get parsingType3Font(){return!!this.type3FontRefs}clone(e=null){const t=Object.create(this);t.options=Object.assign(Object.create(null),this.options,e);return t}hasBlendModes(e,t){if(!(e instanceof Dict))return!1;if(e.objId&&t.has(e.objId))return!1;const i=new RefSet(t);e.objId&&i.put(e.objId);const a=[e],s=this.xref;for(;a.length;){const e=a.shift(),t=e.get("ExtGState");if(t instanceof Dict)for(let e of t.getRawValues()){if(e instanceof Ref){if(i.has(e))continue;try{e=s.fetch(e)}catch(t){i.put(e);info(`hasBlendModes - ignoring ExtGState: "${t}".`);continue}}if(!(e instanceof Dict))continue;e.objId&&i.put(e.objId);const t=e.get("BM");if(t instanceof Name){if("Normal"!==t.name)return!0}else if(void 0!==t&&Array.isArray(t))for(const e of t)if(e instanceof Name&&"Normal"!==e.name)return!0}const r=e.get("XObject");if(r instanceof Dict)for(let e of r.getRawValues()){if(e instanceof Ref){if(i.has(e))continue;try{e=s.fetch(e)}catch(t){i.put(e);info(`hasBlendModes - ignoring XObject: "${t}".`);continue}}if(!(e instanceof BaseStream))continue;e.dict.objId&&i.put(e.dict.objId);const t=e.dict.get("Resources");if(t instanceof Dict&&(!t.objId||!i.has(t.objId))){a.push(t);t.objId&&i.put(t.objId)}}}for(const e of i)t.put(e);return!1}async fetchBuiltInCMap(e){const t=this.builtInCMapCache.get(e);if(t)return t;let i;if(null!==this.options.cMapUrl){const t=`${this.options.cMapUrl}${e}.bcmap`,a=await fetch(t);if(!a.ok)throw new Error(`fetchBuiltInCMap: failed to fetch file "${t}" with "${a.statusText}".`);i={cMapData:new Uint8Array(await a.arrayBuffer()),compressionType:mA.BINARY}}else i=await this.handler.sendWithPromise("FetchBuiltInCMap",{name:e});i.compressionType!==mA.NONE&&this.builtInCMapCache.set(e,i);return i}async fetchStandardFontData(e){const t=this.standardFontDataCache.get(e);if(t)return new Stream(t);if(this.options.useSystemFonts&&"Symbol"!==e&&"ZapfDingbats"!==e)return null;const i=Wi()[e];let a;if(null!==this.options.standardFontDataUrl){const e=`${this.options.standardFontDataUrl}${i}`,t=await fetch(e);t.ok?a=new Uint8Array(await t.arrayBuffer()):warn(`fetchStandardFontData: failed to fetch file "${e}" with "${t.statusText}".`)}else try{a=await this.handler.sendWithPromise("FetchStandardFontData",{filename:i})}catch(e){warn(`fetchStandardFontData: failed to fetch file "${i}" with "${e}".`)}if(!a)return null;this.standardFontDataCache.set(e,a);return new Stream(a)}async buildFormXObject(e,t,i,a,s,r,n){const o=t.dict,g=lookupMatrix(o.getArray("Matrix"),null),c=lookupNormalRect(o.getArray("BBox"),null);let h,l;o.has("OC")&&(h=await this.parseMarkedContentProps(o.get("OC"),e));void 0!==h&&a.addOp(He,["OC",h]);const C=o.get("Group");if(C){l={matrix:g,bbox:c,smask:i,isolated:!1,knockout:!1};let t=null;if(isName(C.get("S"),"Transparency")){l.isolated=C.get("I")||!1;l.knockout=C.get("K")||!1;if(C.has("CS")){const i=C.getRaw("CS"),a=ColorSpace.getCached(i,this.xref,n);t=a||await this.parseColorSpace({cs:i,resources:e,localColorSpaceCache:n})}}if(i?.backdrop){t||=ColorSpace.singletons.rgb;i.backdrop=t.getRgb(i.backdrop,0)}a.addOp(Oe,[l])}const Q=C?[g,null]:[g,c];a.addOp(Te,Q);await this.getOperatorList({stream:t,task:s,resources:o.get("Resources")||e,operatorList:a,initialState:r});a.addOp(qe,[]);C&&a.addOp(Pe,[l]);void 0!==h&&a.addOp(Ye,[])}_sendImgData(e,t,i=!1){const a=t?[t.bitmap||t.data.buffer]:null;return this.parsingType3Font||i?this.handler.send("commonobj",[e,"Image",t],a):this.handler.send("obj",[e,this.pageIndex,"Image",t],a)}async buildPaintImageXObject({resources:e,image:t,isInline:i=!1,operatorList:a,cacheKey:s,localImageCache:r,localColorSpaceCache:n}){const o=t.dict,g=o.objId,c=o.get("W","Width"),h=o.get("H","Height");if(!c||"number"!=typeof c||!h||"number"!=typeof h){warn("Image dimensions are missing, or not numbers.");return}const l=this.options.maxImageSize;if(-1!==l&&c*h>l){const e="Image exceeded maximum allowed size and was removed.";if(this.options.ignoreErrors){warn(e);return}throw new Error(e)}let C;o.has("OC")&&(C=await this.parseMarkedContentProps(o.get("OC"),e));let Q,E;if(o.get("IM","ImageMask")||!1){const e=o.get("I","Interpolate"),i=c+7>>3,n=t.getBytes(i*h),l=o.getArray("D","Decode");if(this.parsingType3Font){Q=PDFImage.createRawMask({imgArray:n,width:c,height:h,imageIsFromDecodeStream:t instanceof DecodeStream,inverseDecode:l?.[0]>0,interpolate:e});Q.cached=!!s;E=[Q];a.addImageOps(je,E,C);if(s){const e={fn:je,args:E,optionalContent:C};r.set(s,g,e);g&&this._regionalImageCache.set(null,g,e)}return}Q=await PDFImage.createMask({imgArray:n,width:c,height:h,imageIsFromDecodeStream:t instanceof DecodeStream,inverseDecode:l?.[0]>0,interpolate:e,isOffscreenCanvasSupported:this.options.isOffscreenCanvasSupported});if(Q.isSingleOpaquePixel){a.addImageOps(et,[],C);if(s){const e={fn:et,args:[],optionalContent:C};r.set(s,g,e);g&&this._regionalImageCache.set(null,g,e)}return}const u=`mask_${this.idFactory.createObjId()}`;a.addDependency(u);Q.dataLen=Q.bitmap?Q.width*Q.height*4:Q.data.length;this._sendImgData(u,Q);E=[{data:u,width:Q.width,height:Q.height,interpolate:Q.interpolate,count:1}];a.addImageOps(je,E,C);if(s){const e={fn:je,args:E,optionalContent:C};r.set(s,g,e);g&&this._regionalImageCache.set(null,g,e)}return}if(i&&c+h<200&&!o.has("SMask")&&!o.has("Mask")){try{const s=new PDFImage({xref:this.xref,res:e,image:t,isInline:i,pdfFunctionFactory:this._pdfFunctionFactory,localColorSpaceCache:n});Q=await s.createImageData(!0,!1);a.isOffscreenCanvasSupported=this.options.isOffscreenCanvasSupported;a.addImageOps(ze,[Q],C)}catch(e){const t=`Unable to decode inline image: "${e}".`;if(!this.options.ignoreErrors)throw new Error(t);warn(t)}return}let u=`img_${this.idFactory.createObjId()}`,d=!1;if(this.parsingType3Font)u=`${this.idFactory.getDocId()}_type3_${u}`;else if(s&&g){d=this.globalImageCache.shouldCache(g,this.pageIndex);if(d){assert(!i,"Cannot cache an inline image globally.");u=`${this.idFactory.getDocId()}_${u}`}}a.addDependency(u);E=[u,c,h];a.addImageOps(Ve,E,C);if(d){if(this.globalImageCache.hasDecodeFailed(g)){this.globalImageCache.setData(g,{objId:u,fn:Ve,args:E,optionalContent:C,byteSize:0});this._sendImgData(u,null,d);return}if(c*h>25e4||o.has("SMask")||o.has("Mask")){const e=await this.handler.sendWithPromise("commonobj",[u,"CopyLocalImage",{imageRef:g}]);if(e){this.globalImageCache.setData(g,{objId:u,fn:Ve,args:E,optionalContent:C,byteSize:0});this.globalImageCache.addByteSize(g,e);return}}}PDFImage.buildImage({xref:this.xref,res:e,image:t,isInline:i,pdfFunctionFactory:this._pdfFunctionFactory,localColorSpaceCache:n}).then((async e=>{Q=await e.createImageData(!1,this.options.isOffscreenCanvasSupported);Q.dataLen=Q.bitmap?Q.width*Q.height*4:Q.data.length;Q.ref=g;d&&this.globalImageCache.addByteSize(g,Q.dataLen);return this._sendImgData(u,Q,d)})).catch((e=>{warn(`Unable to decode image "${u}": "${e}".`);g&&this.globalImageCache.addDecodeFailed(g);return this._sendImgData(u,null,d)}));if(s){const e={fn:Ve,args:E,optionalContent:C};r.set(s,g,e);if(g){this._regionalImageCache.set(null,g,e);d&&this.globalImageCache.setData(g,{objId:u,fn:Ve,args:E,optionalContent:C,byteSize:0})}}}handleSMask(e,t,i,a,s,r){const n=e.get("G"),o={subtype:e.get("S").name,backdrop:e.get("BC")},g=e.get("TR");if(isPDFFunction(g)){const e=this._pdfFunctionFactory.create(g),t=new Uint8Array(256),i=new Float32Array(1);for(let a=0;a<256;a++){i[0]=a/255;e(i,0,i,0);t[a]=255*i[0]|0}o.transferMap=t}return this.buildFormXObject(t,n,o,i,a,s.state.clone(),r)}handleTransferFunction(e){let t;if(Array.isArray(e))t=e;else{if(!isPDFFunction(e))return null;t=[e]}const i=[];let a=0,s=0;for(const e of t){const t=this.xref.fetchIfRef(e);a++;if(isName(t,"Identity")){i.push(null);continue}if(!isPDFFunction(t))return null;const r=this._pdfFunctionFactory.create(t),n=new Uint8Array(256),o=new Float32Array(1);for(let e=0;e<256;e++){o[0]=e/255;r(o,0,o,0);n[e]=255*o[0]|0}i.push(n);s++}return 1!==a&&4!==a||0===s?null:i}handleTilingType(e,t,i,a,s,r,n,o){const g=new OperatorList,c=Dict.merge({xref:this.xref,dictArray:[s.get("Resources"),i]});return this.getOperatorList({stream:a,task:n,resources:c,operatorList:g}).then((function(){const i=g.getIR(),a=getTilingPatternIR(i,s,t);r.addDependencies(g.dependencies);r.addOp(e,a);s.objId&&o.set(null,s.objId,{operatorListIR:i,dict:s})})).catch((e=>{if(!(e instanceof AbortException)){if(!this.options.ignoreErrors)throw e;warn(`handleTilingType - ignoring pattern: "${e}".`)}}))}async handleSetFont(e,t,i,a,s,r,n=null,o=null){const g=t?.[0]instanceof Name?t[0].name:null;let c=await this.loadFont(g,i,e,n,o);if(c.font.isType3Font)try{await c.loadType3Data(this,e,s);a.addDependencies(c.type3Dependencies)}catch(e){c=new TranslatedFont({loadedName:"g_font_error",font:new ErrorFont(`Type3 font load error: ${e}`),dict:c.font,evaluatorOptions:this.options})}r.font=c.font;c.send(this.handler);return c.loadedName}handleText(e,t){const i=t.font,a=i.charsToGlyphs(e);if(i.data){(!!(t.textRenderingMode&w)||"Pattern"===t.fillColorSpace.name||i.disableFontFace||this.options.disableFontFace)&&PartialEvaluator.buildFontPaths(i,a,this.handler,this.options)}return a}ensureStateFont(e){if(e.font)return;const t=new FormatError("Missing setFont (Tf) operator before text rendering operator.");if(!this.options.ignoreErrors)throw t;warn(`ensureStateFont: "${t}".`)}async setGState({resources:e,gState:t,operatorList:i,cacheKey:a,task:s,stateManager:r,localGStateCache:n,localColorSpaceCache:o}){const g=t.objId;let c=!0;const h=[];let l=Promise.resolve();for(const a of t.getKeys()){const n=t.get(a);switch(a){case"Type":break;case"LW":case"LC":case"LJ":case"ML":case"D":case"RI":case"FL":case"CA":case"ca":h.push([a,n]);break;case"Font":c=!1;l=l.then((()=>this.handleSetFont(e,null,n[0],i,s,r.state).then((function(e){i.addDependency(e);h.push([a,[e,n[1]]])}))));break;case"BM":h.push([a,normalizeBlendMode(n)]);break;case"SMask":if(isName(n,"None")){h.push([a,!1]);break}if(n instanceof Dict){c=!1;l=l.then((()=>this.handleSMask(n,e,i,s,r,o)));h.push([a,!0])}else warn("Unsupported SMask type");break;case"TR":const t=this.handleTransferFunction(n);h.push([a,t]);break;case"OP":case"op":case"OPM":case"BG":case"BG2":case"UCR":case"UCR2":case"TR2":case"HT":case"SM":case"SA":case"AIS":case"TK":info("graphic state operator "+a);break;default:info("Unknown graphic state operator "+a)}}await l;h.length>0&&i.addOp(NA,[h]);c&&n.set(a,g,h)}loadFont(e,t,i,a=null,s=null){const errorFont=async()=>new TranslatedFont({loadedName:"g_font_error",font:new ErrorFont(`Font "${e}" is not available.`),dict:t,evaluatorOptions:this.options});let r;if(t)t instanceof Ref&&(r=t);else{const t=i.get("Font");t&&(r=t.getRaw(e))}if(r){if(this.type3FontRefs?.has(r))return errorFont();if(this.fontCache.has(r))return this.fontCache.get(r);try{t=this.xref.fetchIfRef(r)}catch(e){warn(`loadFont - lookup failed: "${e}".`)}}if(!(t instanceof Dict)){if(!this.options.ignoreErrors&&!this.parsingType3Font){warn(`Font "${e}" is not available.`);return errorFont()}warn(`Font "${e}" is not available -- attempting to fallback to a default font.`);t=a||PartialEvaluator.fallbackFontDict}if(t.cacheKey&&this.fontCache.has(t.cacheKey))return this.fontCache.get(t.cacheKey);const{promise:n,resolve:o}=Promise.withResolvers();let g;try{g=this.preEvaluateFont(t);g.cssFontInfo=s}catch(e){warn(`loadFont - preEvaluateFont failed: "${e}".`);return errorFont()}const{descriptor:c,hash:h}=g,l=r instanceof Ref;let C;if(h&&c instanceof Dict){const e=c.fontAliases||=Object.create(null);if(e[h]){const t=e[h].aliasRef;if(l&&t&&this.fontCache.has(t)){this.fontCache.putAlias(r,t);return this.fontCache.get(r)}}else e[h]={fontID:this.idFactory.createFontId()};l&&(e[h].aliasRef=r);C=e[h].fontID}else C=this.idFactory.createFontId();assert(C?.startsWith("f"),'The "fontID" must be (correctly) defined.');if(l)this.fontCache.put(r,n);else{t.cacheKey=`cacheKey_${C}`;this.fontCache.put(t.cacheKey,n)}t.loadedName=`${this.idFactory.getDocId()}_${C}`;this.translateFont(g).then((e=>{o(new TranslatedFont({loadedName:t.loadedName,font:e,dict:t,evaluatorOptions:this.options}))})).catch((e=>{warn(`loadFont - translateFont failed: "${e}".`);o(new TranslatedFont({loadedName:t.loadedName,font:new ErrorFont(e instanceof Error?e.message:e),dict:t,evaluatorOptions:this.options}))}));return n}buildPath(e,t,i,a=!1){const s=e.length-1;i||(i=[]);if(s<0||e.fnArray[s]!==tt){if(a){warn(`Encountered path operator "${t}" inside of a text object.`);e.addOp(GA,null)}let s;switch(t){case KA:const e=i[0]+i[2],t=i[1]+i[3];s=[Math.min(i[0],e),Math.min(i[1],t),Math.max(i[0],e),Math.max(i[1],t)];break;case UA:case LA:s=[i[0],i[1],i[0],i[1]];break;default:s=[1/0,1/0,-1/0,-1/0]}e.addOp(tt,[[t],i,s]);a&&e.addOp(xA,null)}else{const a=e.argsArray[s];a[0].push(t);a[1].push(...i);const r=a[2];switch(t){case KA:const e=i[0]+i[2],t=i[1]+i[3];r[0]=Math.min(r[0],i[0],e);r[1]=Math.min(r[1],i[1],t);r[2]=Math.max(r[2],i[0],e);r[3]=Math.max(r[3],i[1],t);break;case UA:case LA:r[0]=Math.min(r[0],i[0]);r[1]=Math.min(r[1],i[1]);r[2]=Math.max(r[2],i[0]);r[3]=Math.max(r[3],i[1])}}}parseColorSpace({cs:e,resources:t,localColorSpaceCache:i}){return ColorSpace.parseAsync({cs:e,xref:this.xref,resources:t,pdfFunctionFactory:this._pdfFunctionFactory,localColorSpaceCache:i}).catch((e=>{if(e instanceof AbortException)return null;if(this.options.ignoreErrors){warn(`parseColorSpace - ignoring ColorSpace: "${e}".`);return null}throw e}))}parseShading({shading:e,resources:t,localColorSpaceCache:i,localShadingPatternCache:a}){let s,r=a.get(e);if(r)return r;try{s=Pattern.parseShading(e,this.xref,t,this._pdfFunctionFactory,i).getIR()}catch(t){if(t instanceof AbortException)return null;if(this.options.ignoreErrors){warn(`parseShading - ignoring shading: "${t}".`);a.set(e,null);return null}throw t}r=`pattern_${this.idFactory.createObjId()}`;this.parsingType3Font&&(r=`${this.idFactory.getDocId()}_type3_${r}`);a.set(e,r);this.parsingType3Font?this.handler.send("commonobj",[r,"Pattern",s]):this.handler.send("obj",[r,this.pageIndex,"Pattern",s]);return r}handleColorN(e,t,i,a,s,r,n,o,g,c){const h=i.pop();if(h instanceof Name){const l=s.getRaw(h.name),C=l instanceof Ref&&g.getByRef(l);if(C)try{const s=a.base?a.base.getRgb(i,0):null,r=getTilingPatternIR(C.operatorListIR,C.dict,s);e.addOp(t,r);return}catch{}const Q=this.xref.fetchIfRef(l);if(Q){const s=Q instanceof BaseStream?Q.dict:Q,h=s.get("PatternType");if(h===Fs){const o=a.base?a.base.getRgb(i,0):null;return this.handleTilingType(t,o,r,Q,s,e,n,g)}if(h===Ss){const i=s.get("Shading"),a=this.parseShading({shading:i,resources:r,localColorSpaceCache:o,localShadingPatternCache:c});if(a){const i=lookupMatrix(s.getArray("Matrix"),null);e.addOp(t,["Shading",a,i])}return}throw new FormatError(`Unknown PatternType: ${h}`)}}throw new FormatError(`Unknown PatternName: ${h}`)}_parseVisibilityExpression(e,t,i){if(++t>10){warn("Visibility expression is too deeply nested");return}const a=e.length,s=this.xref.fetchIfRef(e[0]);if(!(a<2)&&s instanceof Name){switch(s.name){case"And":case"Or":case"Not":i.push(s.name);break;default:warn(`Invalid operator ${s.name} in visibility expression`);return}for(let s=1;s<a;s++){const a=e[s],r=this.xref.fetchIfRef(a);if(Array.isArray(r)){const e=[];i.push(e);this._parseVisibilityExpression(r,t,e)}else a instanceof Ref&&i.push(a.toString())}}else warn("Invalid visibility expression")}async parseMarkedContentProps(e,t){let i;if(e instanceof Name){i=t.get("Properties").get(e.name)}else{if(!(e instanceof Dict))throw new FormatError("Optional content properties malformed.");i=e}const a=i.get("Type")?.name;if("OCG"===a)return{type:a,id:i.objId};if("OCMD"===a){const e=i.get("VE");if(Array.isArray(e)){const t=[];this._parseVisibilityExpression(e,0,t);if(t.length>0)return{type:"OCMD",expression:t}}const t=i.get("OCGs");if(Array.isArray(t)||t instanceof Dict){const e=[];if(Array.isArray(t))for(const i of t)e.push(i.toString());else e.push(t.objId);return{type:a,ids:e,policy:i.get("P")instanceof Name?i.get("P").name:null,expression:null}}if(t instanceof Ref)return{type:a,id:t.toString()}}return null}getOperatorList({stream:e,task:t,resources:i,operatorList:a,initialState:s=null,fallbackFontDict:r=null}){i||=Dict.empty;s||=new EvalState;if(!a)throw new Error('getOperatorList: missing "operatorList" parameter');const n=this,o=this.xref;let g=!1;const c=new LocalImageCache,h=new LocalColorSpaceCache,l=new LocalGStateCache,C=new LocalTilingPatternCache,Q=new Map,E=i.get("XObject")||Dict.empty,u=i.get("Pattern")||Dict.empty,d=new StateManager(s),f=new EvaluatorPreprocessor(e,o,d),p=new TimeSlotManager;function closePendingRestoreOPS(e){for(let e=0,t=f.savedStatesDepth;e<t;e++)a.addOp(xA,[])}return new Promise((function promiseBody(e,s){const next=function(t){Promise.all([t,a.ready]).then((function(){try{promiseBody(e,s)}catch(e){s(e)}}),s)};t.ensureNotTerminated();p.reset();const m={};let y,w,b,D,F,S;for(;!(y=p.check());){m.args=null;if(!f.read(m))break;let e=m.args,s=m.fn;switch(0|s){case Me:S=e[0]instanceof Name;F=e[0].name;if(S){const t=c.getByName(F);if(t){a.addImageOps(t.fn,t.args,t.optionalContent);incrementCachedImageMaskCount(t);e=null;continue}}next(new Promise((function(e,s){if(!S)throw new FormatError("XObject must be referred to by name.");let r=E.getRaw(F);if(r instanceof Ref){const t=c.getByRef(r)||n._regionalImageCache.getByRef(r);if(t){a.addImageOps(t.fn,t.args,t.optionalContent);incrementCachedImageMaskCount(t);e();return}const i=n.globalImageCache.getData(r,n.pageIndex);if(i){a.addDependency(i.objId);a.addImageOps(i.fn,i.args,i.optionalContent);e();return}r=o.fetch(r)}if(!(r instanceof BaseStream))throw new FormatError("XObject should be a stream");const g=r.dict.get("Subtype");if(!(g instanceof Name))throw new FormatError("XObject should have a Name subtype");if("Form"!==g.name)if("Image"!==g.name){if("PS"!==g.name)throw new FormatError(`Unhandled XObject subtype ${g.name}`);info("Ignored XObject subtype PS");e()}else n.buildPaintImageXObject({resources:i,image:r,operatorList:a,cacheKey:F,localImageCache:c,localColorSpaceCache:h}).then(e,s);else{d.save();n.buildFormXObject(i,r,null,a,t,d.state.clone(),h).then((function(){d.restore();e()}),s)}})).catch((function(e){if(!(e instanceof AbortException)){if(!n.options.ignoreErrors)throw e;warn(`getOperatorList - ignoring XObject: "${e}".`)}})));return;case se:var k=e[1];next(n.handleSetFont(i,e,null,a,t,d.state,r).then((function(e){a.addDependency(e);a.addOp(se,[e,k])})));return;case $A:g=!0;break;case Ae:g=!1;break;case xe:var R=e[0].cacheKey;if(R){const t=c.getByName(R);if(t){a.addImageOps(t.fn,t.args,t.optionalContent);incrementCachedImageMaskCount(t);e=null;continue}}next(n.buildPaintImageXObject({resources:i,image:e[0],isInline:!0,operatorList:a,cacheKey:R,localImageCache:c,localColorSpaceCache:h}));return;case he:if(!d.state.font){n.ensureStateFont(d.state);continue}e[0]=n.handleText(e[0],d.state);break;case le:if(!d.state.font){n.ensureStateFont(d.state);continue}var N=[],G=d.state;for(const t of e[0])"string"==typeof t?N.push(...n.handleText(t,G)):"number"==typeof t&&N.push(t);e[0]=N;s=he;break;case Ce:if(!d.state.font){n.ensureStateFont(d.state);continue}a.addOp(ce);e[0]=n.handleText(e[0],d.state);s=he;break;case Be:if(!d.state.font){n.ensureStateFont(d.state);continue}a.addOp(ce);a.addOp(te,[e.shift()]);a.addOp(ee,[e.shift()]);e[0]=n.handleText(e[0],d.state);s=he;break;case re:d.state.textRenderingMode=e[0];break;case de:{const t=ColorSpace.getCached(e[0],o,h);if(t){d.state.fillColorSpace=t;continue}next(n.parseColorSpace({cs:e[0],resources:i,localColorSpaceCache:h}).then((function(e){e&&(d.state.fillColorSpace=e)})));return}case ue:{const t=ColorSpace.getCached(e[0],o,h);if(t){d.state.strokeColorSpace=t;continue}next(n.parseColorSpace({cs:e[0],resources:i,localColorSpaceCache:h}).then((function(e){e&&(d.state.strokeColorSpace=e)})));return}case me:D=d.state.fillColorSpace;e=D.getRgb(e,0);s=Fe;break;case fe:D=d.state.strokeColorSpace;e=D.getRgb(e,0);s=De;break;case be:d.state.fillColorSpace=ColorSpace.singletons.gray;e=ColorSpace.singletons.gray.getRgb(e,0);s=Fe;break;case we:d.state.strokeColorSpace=ColorSpace.singletons.gray;e=ColorSpace.singletons.gray.getRgb(e,0);s=De;break;case ke:d.state.fillColorSpace=ColorSpace.singletons.cmyk;e=ColorSpace.singletons.cmyk.getRgb(e,0);s=Fe;break;case Se:d.state.strokeColorSpace=ColorSpace.singletons.cmyk;e=ColorSpace.singletons.cmyk.getRgb(e,0);s=De;break;case Fe:d.state.fillColorSpace=ColorSpace.singletons.rgb;e=ColorSpace.singletons.rgb.getRgb(e,0);break;case De:d.state.strokeColorSpace=ColorSpace.singletons.rgb;e=ColorSpace.singletons.rgb.getRgb(e,0);break;case ye:D=d.state.fillColorSpace;if("Pattern"===D.name){next(n.handleColorN(a,ye,e,D,u,i,t,h,C,Q));return}e=D.getRgb(e,0);s=Fe;break;case pe:D=d.state.strokeColorSpace;if("Pattern"===D.name){next(n.handleColorN(a,pe,e,D,u,i,t,h,C,Q));return}e=D.getRgb(e,0);s=De;break;case Re:var x=i.get("Shading");if(!x)throw new FormatError("No shading resource found");var M=x.get(e[0].name);if(!M)throw new FormatError("No shading object found");const f=n.parseShading({shading:M,resources:i,localColorSpaceCache:h,localShadingPatternCache:Q});if(!f)continue;e=[f];s=Re;break;case NA:S=e[0]instanceof Name;F=e[0].name;if(S){const t=l.getByName(F);if(t){t.length>0&&a.addOp(NA,[t]);e=null;continue}}next(new Promise((function(e,s){if(!S)throw new FormatError("GState must be referred to by name.");const r=i.get("ExtGState");if(!(r instanceof Dict))throw new FormatError("ExtGState should be a dictionary.");const o=r.get(F);if(!(o instanceof Dict))throw new FormatError("GState should be a dictionary.");n.setGState({resources:i,gState:o,operatorList:a,cacheKey:F,task:t,stateManager:d,localGStateCache:l,localColorSpaceCache:h}).then(e,s)})).catch((function(e){if(!(e instanceof AbortException)){if(!n.options.ignoreErrors)throw e;warn(`getOperatorList - ignoring ExtGState: "${e}".`)}})));return;case UA:case LA:case JA:case HA:case YA:case vA:case KA:n.buildPath(a,s,e,g);continue;case Ue:case Le:case ve:case Ke:continue;case He:if(!(e[0]instanceof Name)){warn(`Expected name for beginMarkedContentProps arg0=${e[0]}`);a.addOp(He,["OC",null]);continue}if("OC"===e[0].name){next(n.parseMarkedContentProps(e[1],i).then((e=>{a.addOp(He,["OC",e])})).catch((e=>{if(!(e instanceof AbortException)){if(!n.options.ignoreErrors)throw e;warn(`getOperatorList - ignoring beginMarkedContentProps: "${e}".`);a.addOp(He,["OC",null])}})));return}e=[e[0].name,e[1]instanceof Dict?e[1].get("MCID"):null];break;default:if(null!==e){for(w=0,b=e.length;w<b&&!(e[w]instanceof Dict);w++);if(w<b){warn("getOperatorList - ignoring operator: "+s);continue}}}a.addOp(s,e)}if(y)next(ks);else{closePendingRestoreOPS();e()}})).catch((e=>{if(!(e instanceof AbortException)){if(!this.options.ignoreErrors)throw e;warn(`getOperatorList - ignoring errors during "${t.name}" task: "${e}".`);closePendingRestoreOPS()}}))}getTextContent({stream:e,task:t,resources:s,stateManager:r=null,includeMarkedContent:n=!1,sink:o,seenStyles:g=new Set,viewBox:c,lang:h=null,markedContentData:l=null,disableNormalization:C=!1,keepWhiteSpace:Q=!1}){s||=Dict.empty;r||=new StateManager(new TextState);n&&(l||={level:0});const E={items:[],styles:Object.create(null),lang:h},u={initialized:!1,str:[],totalWidth:0,totalHeight:0,width:0,height:0,vertical:!1,prevTransform:null,textAdvanceScale:0,spaceInFlowMin:0,spaceInFlowMax:0,trackingSpaceMin:1/0,negativeSpaceMax:-1/0,notASpace:-1/0,transform:null,fontName:null,hasEOL:!1},d=[" "," "];let f=0;function saveLastChar(e){const t=(f+1)%2,i=" "!==d[f]&&" "===d[t];d[f]=e;f=t;return!Q&&i}function shouldAddWhitepsace(){return!Q&&" "!==d[f]&&" "===d[(f+1)%2]}function resetLastChars(){d[0]=d[1]=" ";f=0}const p=this,m=this.xref,y=[];let w=null;const b=new LocalImageCache,D=new LocalGStateCache,F=new EvaluatorPreprocessor(e,m,r);let S;function pushWhitespace({width:e=0,height:t=0,transform:i=u.prevTransform,fontName:a=u.fontName}){E.items.push({str:" ",dir:"ltr",width:e,height:t,transform:i,fontName:a,hasEOL:!1})}function getCurrentTextTransform(){const e=S.font,t=[S.fontSize*S.textHScale,0,0,S.fontSize,0,S.textRise];if(e.isType3Font&&(S.fontSize<=1||e.isCharBBox)&&!isArrayEqual(S.fontMatrix,a)){const i=e.bbox[3]-e.bbox[1];i>0&&(t[3]*=i*S.fontMatrix[3])}return Util.transform(S.ctm,Util.transform(S.textMatrix,t))}function ensureTextContentItem(){if(u.initialized)return u;const{font:e,loadedName:t}=S;if(!g.has(t)){g.add(t);E.styles[t]={fontFamily:e.fallbackName,ascent:e.ascent,descent:e.descent,vertical:e.vertical};if(p.options.fontExtraProperties&&e.systemFontInfo){const i=E.styles[t];i.fontSubstitution=e.systemFontInfo.css;i.fontSubstitutionLoadedName=e.systemFontInfo.loadedName}}u.fontName=t;const i=u.transform=getCurrentTextTransform();if(e.vertical){u.width=u.totalWidth=Math.hypot(i[0],i[1]);u.height=u.totalHeight=0;u.vertical=!0}else{u.width=u.totalWidth=0;u.height=u.totalHeight=Math.hypot(i[2],i[3]);u.vertical=!1}const a=Math.hypot(S.textLineMatrix[0],S.textLineMatrix[1]),s=Math.hypot(S.ctm[0],S.ctm[1]);u.textAdvanceScale=s*a;const{fontSize:r}=S;u.trackingSpaceMin=.102*r;u.notASpace=.03*r;u.negativeSpaceMax=-.2*r;u.spaceInFlowMin=.102*r;u.spaceInFlowMax=.6*r;u.hasEOL=!1;u.initialized=!0;return u}function updateAdvanceScale(){if(!u.initialized)return;const e=Math.hypot(S.textLineMatrix[0],S.textLineMatrix[1]),t=Math.hypot(S.ctm[0],S.ctm[1])*e;if(t!==u.textAdvanceScale){if(u.vertical){u.totalHeight+=u.height*u.textAdvanceScale;u.height=0}else{u.totalWidth+=u.width*u.textAdvanceScale;u.width=0}u.textAdvanceScale=t}}function runBidiTransform(e){let t=e.str.join("");C||(t=function normalizeUnicode(e){if(!gt){gt=/([\u00a0\u00b5\u037e\u0eb3\u2000-\u200a\u202f\u2126\ufb00-\ufb04\ufb06\ufb20-\ufb36\ufb38-\ufb3c\ufb3e\ufb40-\ufb41\ufb43-\ufb44\ufb46-\ufba1\ufba4-\ufba9\ufbae-\ufbb1\ufbd3-\ufbdc\ufbde-\ufbe7\ufbea-\ufbf8\ufbfc-\ufbfd\ufc00-\ufc5d\ufc64-\ufcf1\ufcf5-\ufd3d\ufd88\ufdf4\ufdfa-\ufdfb\ufe71\ufe77\ufe79\ufe7b\ufe7d]+)|(\ufb05+)/gu;It=new Map([["ſt","ſt"]])}return e.replaceAll(gt,((e,t,i)=>t?t.normalize("NFKC"):It.get(i)))}(t));const i=bidi(t,-1,e.vertical);return{str:i.str,dir:i.dir,width:Math.abs(e.totalWidth),height:Math.abs(e.totalHeight),transform:e.transform,fontName:e.fontName,hasEOL:e.hasEOL}}async function handleSetFont(e,i){const r=await p.loadFont(e,i,s);if(r.font.isType3Font)try{await r.loadType3Data(p,s,t)}catch{}S.loadedName=r.loadedName;S.font=r.font;S.fontMatrix=r.font.fontMatrix||a}function applyInverseRotation(e,t,i){const a=Math.hypot(i[0],i[1]);return[(i[0]*e+i[1]*t)/a,(i[2]*e+i[3]*t)/a]}function compareWithLastPosition(e){const t=getCurrentTextTransform();let i=t[4],a=t[5];if(S.font?.vertical){if(i<c[0]||i>c[2]||a+e<c[1]||a>c[3])return!1}else if(i+e<c[0]||i>c[2]||a<c[1]||a>c[3])return!1;if(!S.font||!u.prevTransform)return!0;let s=u.prevTransform[4],r=u.prevTransform[5];if(s===i&&r===a)return!0;let n=-1;t[0]&&0===t[1]&&0===t[2]?n=t[0]>0?0:180:t[1]&&0===t[0]&&0===t[3]&&(n=t[1]>0?90:270);switch(n){case 0:break;case 90:[i,a]=[a,i];[s,r]=[r,s];break;case 180:[i,a,s,r]=[-i,-a,-s,-r];break;case 270:[i,a]=[-a,-i];[s,r]=[-r,-s];break;default:[i,a]=applyInverseRotation(i,a,t);[s,r]=applyInverseRotation(s,r,u.prevTransform)}if(S.font.vertical){const e=(r-a)/u.textAdvanceScale,t=i-s,n=Math.sign(u.height);if(e<n*u.negativeSpaceMax){if(Math.abs(t)>.5*u.width){appendEOL();return!0}resetLastChars();flushTextContentItem();return!0}if(Math.abs(t)>u.width){appendEOL();return!0}e<=n*u.notASpace&&resetLastChars();if(e<=n*u.trackingSpaceMin)if(shouldAddWhitepsace()){resetLastChars();flushTextContentItem();pushWhitespace({height:Math.abs(e)})}else u.height+=e;else if(!addFakeSpaces(e,u.prevTransform,n))if(0===u.str.length){resetLastChars();pushWhitespace({height:Math.abs(e)})}else u.height+=e;Math.abs(t)>.25*u.width&&flushTextContentItem();return!0}const o=(i-s)/u.textAdvanceScale,g=a-r,h=Math.sign(u.width);if(o<h*u.negativeSpaceMax){if(Math.abs(g)>.5*u.height){appendEOL();return!0}resetLastChars();flushTextContentItem();return!0}if(Math.abs(g)>u.height){appendEOL();return!0}o<=h*u.notASpace&&resetLastChars();if(o<=h*u.trackingSpaceMin)if(shouldAddWhitepsace()){resetLastChars();flushTextContentItem();pushWhitespace({width:Math.abs(o)})}else u.width+=o;else if(!addFakeSpaces(o,u.prevTransform,h))if(0===u.str.length){resetLastChars();pushWhitespace({width:Math.abs(o)})}else u.width+=o;Math.abs(g)>.25*u.height&&flushTextContentItem();return!0}function buildTextContentItem({chars:e,extraSpacing:t}){const i=S.font;if(!e){const e=S.charSpacing+t;e&&(i.vertical?S.translateTextMatrix(0,-e):S.translateTextMatrix(e*S.textHScale,0));Q&&compareWithLastPosition(0);return}const a=i.charsToGlyphs(e),s=S.fontMatrix[0]*S.fontSize;for(let e=0,r=a.length;e<r;e++){const n=a[e],{category:o}=n;if(o.isInvisibleFormatMark)continue;let g=S.charSpacing+(e+1===r?t:0),c=n.width;i.vertical&&(c=n.vmetric?n.vmetric[0]:-c);let h=c*s;if(!Q&&o.isWhitespace){if(i.vertical){g+=-h+S.wordSpacing;S.translateTextMatrix(0,-g)}else{g+=h+S.wordSpacing;S.translateTextMatrix(g*S.textHScale,0)}saveLastChar(" ");continue}if(!o.isZeroWidthDiacritic&&!compareWithLastPosition(h)){i.vertical?S.translateTextMatrix(0,h):S.translateTextMatrix(h*S.textHScale,0);continue}const l=ensureTextContentItem();o.isZeroWidthDiacritic&&(h=0);if(i.vertical){S.translateTextMatrix(0,h);h=Math.abs(h);l.height+=h}else{h*=S.textHScale;S.translateTextMatrix(h,0);l.width+=h}h&&(l.prevTransform=getCurrentTextTransform());const C=n.unicode;saveLastChar(C)&&l.str.push(" ");l.str.push(C);g&&(i.vertical?S.translateTextMatrix(0,-g):S.translateTextMatrix(g*S.textHScale,0))}}function appendEOL(){resetLastChars();if(u.initialized){u.hasEOL=!0;flushTextContentItem()}else E.items.push({str:"",dir:"ltr",width:0,height:0,transform:getCurrentTextTransform(),fontName:S.loadedName,hasEOL:!0})}function addFakeSpaces(e,t,i){if(i*u.spaceInFlowMin<=e&&e<=i*u.spaceInFlowMax){if(u.initialized){resetLastChars();u.str.push(" ")}return!1}const a=u.fontName;let s=0;if(u.vertical){s=e;e=0}flushTextContentItem();resetLastChars();pushWhitespace({width:Math.abs(e),height:Math.abs(s),transform:t||getCurrentTextTransform(),fontName:a});return!0}function flushTextContentItem(){if(u.initialized&&u.str){u.vertical?u.totalHeight+=u.height*u.textAdvanceScale:u.totalWidth+=u.width*u.textAdvanceScale;E.items.push(runBidiTransform(u));u.initialized=!1;u.str.length=0}}function enqueueChunk(e=!1){const t=E.items.length;if(0!==t&&!(e&&t<10)){o.enqueue(E,t);E.items=[];E.styles=Object.create(null)}}const k=new TimeSlotManager;return new Promise((function promiseBody(e,a){const next=function(t){enqueueChunk(!0);Promise.all([t,o.ready]).then((function(){try{promiseBody(e,a)}catch(e){a(e)}}),a)};t.ensureNotTerminated();k.reset();const u={};let d,f=[];for(;!(d=k.check());){f.length=0;u.args=f;if(!F.read(u))break;const e=S;S=r.state;const a=u.fn;f=u.args;switch(0|a){case se:var R=f[0].name,N=f[1];if(S.font&&R===S.fontName&&N===S.fontSize)break;flushTextContentItem();S.fontName=R;S.fontSize=N;next(handleSetFont(R,null));return;case ne:S.textRise=f[0];break;case ie:S.textHScale=f[0]/100;break;case ae:S.leading=f[0];break;case oe:S.translateTextLineMatrix(f[0],f[1]);S.textMatrix=S.textLineMatrix.slice();break;case ge:S.leading=-f[1];S.translateTextLineMatrix(f[0],f[1]);S.textMatrix=S.textLineMatrix.slice();break;case ce:S.carriageReturn();break;case Ie:S.setTextMatrix(f[0],f[1],f[2],f[3],f[4],f[5]);S.setTextLineMatrix(f[0],f[1],f[2],f[3],f[4],f[5]);updateAdvanceScale();break;case ee:S.charSpacing=f[0];break;case te:S.wordSpacing=f[0];break;case $A:S.textMatrix=i.slice();S.textLineMatrix=i.slice();break;case le:if(!r.state.font){p.ensureStateFont(r.state);continue}const a=(S.font.vertical?1:-1)*S.fontSize/1e3,u=f[0];for(let e=0,t=u.length;e<t;e++){const t=u[e];if("string"==typeof t)y.push(t);else if("number"==typeof t&&0!==t){const e=y.join("");y.length=0;buildTextContentItem({chars:e,extraSpacing:t*a})}}if(y.length>0){const e=y.join("");y.length=0;buildTextContentItem({chars:e,extraSpacing:0})}break;case he:if(!r.state.font){p.ensureStateFont(r.state);continue}buildTextContentItem({chars:f[0],extraSpacing:0});break;case Ce:if(!r.state.font){p.ensureStateFont(r.state);continue}S.carriageReturn();buildTextContentItem({chars:f[0],extraSpacing:0});break;case Be:if(!r.state.font){p.ensureStateFont(r.state);continue}S.wordSpacing=f[0];S.charSpacing=f[1];S.carriageReturn();buildTextContentItem({chars:f[2],extraSpacing:0});break;case Me:flushTextContentItem();w||(w=s.get("XObject")||Dict.empty);var G=f[0]instanceof Name,x=f[0].name;if(G&&b.getByName(x))break;next(new Promise((function(e,i){if(!G)throw new FormatError("XObject must be referred to by name.");let a=w.getRaw(x);if(a instanceof Ref){if(b.getByRef(a)){e();return}if(p.globalImageCache.getData(a,p.pageIndex)){e();return}a=m.fetch(a)}if(!(a instanceof BaseStream))throw new FormatError("XObject should be a stream");const E=a.dict.get("Subtype");if(!(E instanceof Name))throw new FormatError("XObject should have a Name subtype");if("Form"!==E.name){b.set(x,a.dict.objId,!0);e();return}const u=r.state.clone(),d=new StateManager(u),f=lookupMatrix(a.dict.getArray("Matrix"),null);f&&d.transform(f);enqueueChunk();const y={enqueueInvoked:!1,enqueue(e,t){this.enqueueInvoked=!0;o.enqueue(e,t)},get desiredSize(){return o.desiredSize},get ready(){return o.ready}};p.getTextContent({stream:a,task:t,resources:a.dict.get("Resources")||s,stateManager:d,includeMarkedContent:n,sink:y,seenStyles:g,viewBox:c,lang:h,markedContentData:l,disableNormalization:C,keepWhiteSpace:Q}).then((function(){y.enqueueInvoked||b.set(x,a.dict.objId,!0);e()}),i)})).catch((function(e){if(!(e instanceof AbortException)){if(!p.options.ignoreErrors)throw e;warn(`getTextContent - ignoring XObject: "${e}".`)}})));return;case NA:G=f[0]instanceof Name;x=f[0].name;if(G&&D.getByName(x))break;next(new Promise((function(e,t){if(!G)throw new FormatError("GState must be referred to by name.");const i=s.get("ExtGState");if(!(i instanceof Dict))throw new FormatError("ExtGState should be a dictionary.");const a=i.get(x);if(!(a instanceof Dict))throw new FormatError("GState should be a dictionary.");const r=a.get("Font");if(r){flushTextContentItem();S.fontName=null;S.fontSize=r[1];handleSetFont(null,r[0]).then(e,t)}else{D.set(x,a.objId,!0);e()}})).catch((function(e){if(!(e instanceof AbortException)){if(!p.options.ignoreErrors)throw e;warn(`getTextContent - ignoring ExtGState: "${e}".`)}})));return;case Je:flushTextContentItem();if(n){l.level++;E.items.push({type:"beginMarkedContent",tag:f[0]instanceof Name?f[0].name:null})}break;case He:flushTextContentItem();if(n){l.level++;let e=null;f[1]instanceof Dict&&(e=f[1].get("MCID"));E.items.push({type:"beginMarkedContentProps",id:Number.isInteger(e)?`${p.idFactory.getPageObjId()}_mc${e}`:null,tag:f[0]instanceof Name?f[0].name:null})}break;case Ye:flushTextContentItem();if(n){if(0===l.level)break;l.level--;E.items.push({type:"endMarkedContent"})}break;case xA:!e||e.font===S.font&&e.fontSize===S.fontSize&&e.fontName===S.fontName||flushTextContentItem()}if(E.items.length>=o.desiredSize){d=!0;break}}if(d)next(ks);else{flushTextContentItem();enqueueChunk();e()}})).catch((e=>{if(!(e instanceof AbortException)){if(!this.options.ignoreErrors)throw e;warn(`getTextContent - ignoring errors during "${t.name}" task: "${e}".`);flushTextContentItem();enqueueChunk()}}))}async extractDataStructures(e,t){const i=this.xref;let a;const s=this.readToUnicode(t.toUnicode);if(t.composite){const i=e.get("CIDSystemInfo");i instanceof Dict&&(t.cidSystemInfo={registry:stringToPDFString(i.get("Registry")),ordering:stringToPDFString(i.get("Ordering")),supplement:i.get("Supplement")});try{const t=e.get("CIDToGIDMap");t instanceof BaseStream&&(a=t.getBytes())}catch(e){if(!this.options.ignoreErrors)throw e;warn(`extractDataStructures - ignoring CIDToGIDMap data: "${e}".`)}}const r=[];let n,o=null;if(e.has("Encoding")){n=e.get("Encoding");if(n instanceof Dict){o=n.get("BaseEncoding");o=o instanceof Name?o.name:null;if(n.has("Differences")){const e=n.get("Differences");let t=0;for(const a of e){const e=i.fetchIfRef(a);if("number"==typeof e)t=e;else{if(!(e instanceof Name))throw new FormatError(`Invalid entry in 'Differences' array: ${e}`);r[t++]=e.name}}}}else if(n instanceof Name)o=n.name;else{const e="Encoding is not a Name nor a Dict";if(!this.options.ignoreErrors)throw new FormatError(e);warn(e)}"MacRomanEncoding"!==o&&"MacExpertEncoding"!==o&&"WinAnsiEncoding"!==o&&(o=null)}const g=!t.file||t.isInternalFont,c=Zi()[t.name];o&&g&&c&&(o=null);if(o)t.defaultEncoding=getEncoding(o);else{const e=!!(t.flags&Ti),i=!!(t.flags&qi);n=fi;"TrueType"!==t.type||i||(n=pi);if(e||c){n=di;g&&(/Symbol/i.test(t.name)?n=mi:/Dingbats/i.test(t.name)?n=yi:/Wingdings/i.test(t.name)&&(n=pi))}t.defaultEncoding=n}t.differences=r;t.baseEncodingName=o;t.hasEncoding=!!o||r.length>0;t.dict=e;t.toUnicode=await s;const h=await this.buildToUnicode(t);t.toUnicode=h;a&&(t.cidToGidMap=this.readCidToGidMap(a,h));return t}_simpleFontToUnicode(e,t=!1){assert(!e.composite,"Must be a simple font.");const i=[],a=e.defaultEncoding.slice(),s=e.baseEncodingName,r=e.differences;for(const e in r){const t=r[e];".notdef"!==t&&(a[e]=t)}const n=Ni();for(const r in a){let o=a[r];if(""===o)continue;let g=n[o];if(void 0!==g){i[r]=String.fromCharCode(g);continue}let c=0;switch(o[0]){case"G":3===o.length&&(c=parseInt(o.substring(1),16));break;case"g":5===o.length&&(c=parseInt(o.substring(1),16));break;case"C":case"c":if(o.length>=3&&o.length<=4){const i=o.substring(1);if(t){c=parseInt(i,16);break}c=+i;if(Number.isNaN(c)&&Number.isInteger(parseInt(i,16)))return this._simpleFontToUnicode(e,!0)}break;case"u":g=getUnicodeForGlyph(o,n);-1!==g&&(c=g);break;default:switch(o){case"f_h":case"f_t":case"T_h":i[r]=o.replaceAll("_","");continue}}if(c>0&&c<=1114111&&Number.isInteger(c)){if(s&&c===+r){const e=getEncoding(s);if(e&&(o=e[r])){i[r]=String.fromCharCode(n[o]);continue}}i[r]=String.fromCodePoint(c)}}return i}async buildToUnicode(e){e.hasIncludedToUnicodeMap=e.toUnicode?.length>0;if(e.hasIncludedToUnicodeMap){!e.composite&&e.hasEncoding&&(e.fallbackToUnicode=this._simpleFontToUnicode(e));return e.toUnicode}if(!e.composite)return new ToUnicodeMap(this._simpleFontToUnicode(e));if(e.composite&&(e.cMap.builtInCMap&&!(e.cMap instanceof IdentityCMap)||"Adobe"===e.cidSystemInfo?.registry&&("GB1"===e.cidSystemInfo.ordering||"CNS1"===e.cidSystemInfo.ordering||"Japan1"===e.cidSystemInfo.ordering||"Korea1"===e.cidSystemInfo.ordering))){const{registry:t,ordering:i}=e.cidSystemInfo,a=Name.get(`${t}-${i}-UCS2`),s=await CMapFactory.create({encoding:a,fetchBuiltInCMap:this._fetchBuiltInCMapBound,useCMap:null}),r=[],n=[];e.cMap.forEach((function(e,t){if(t>65535)throw new FormatError("Max size of CID is 65,535");const i=s.lookup(t);if(i){n.length=0;for(let e=0,t=i.length;e<t;e+=2)n.push((i.charCodeAt(e)<<8)+i.charCodeAt(e+1));r[e]=String.fromCharCode(...n)}}));return new ToUnicodeMap(r)}return new IdentityToUnicodeMap(e.firstChar,e.lastChar)}async readToUnicode(e){if(!e)return null;if(e instanceof Name){const t=await CMapFactory.create({encoding:e,fetchBuiltInCMap:this._fetchBuiltInCMapBound,useCMap:null});return t instanceof IdentityCMap?new IdentityToUnicodeMap(0,65535):new ToUnicodeMap(t.getMap())}if(e instanceof BaseStream)try{const t=await CMapFactory.create({encoding:e,fetchBuiltInCMap:this._fetchBuiltInCMapBound,useCMap:null});if(t instanceof IdentityCMap)return new IdentityToUnicodeMap(0,65535);const i=new Array(t.length);t.forEach((function(e,t){if("number"==typeof t){i[e]=String.fromCodePoint(t);return}const a=[];for(let e=0;e<t.length;e+=2){const i=t.charCodeAt(e)<<8|t.charCodeAt(e+1);if(55296!=(63488&i)){a.push(i);continue}e+=2;const s=t.charCodeAt(e)<<8|t.charCodeAt(e+1);a.push(((1023&i)<<10)+(1023&s)+65536)}i[e]=String.fromCodePoint(...a)}));return new ToUnicodeMap(i)}catch(e){if(e instanceof AbortException)return null;if(this.options.ignoreErrors){warn(`readToUnicode - ignoring ToUnicode data: "${e}".`);return null}throw e}return null}readCidToGidMap(e,t){const i=[];for(let a=0,s=e.length;a<s;a++){const s=e[a++]<<8|e[a],r=a>>1;(0!==s||t.has(r))&&(i[r]=s)}return i}extractWidths(e,t,i){const a=this.xref;let s=[],r=0;const n=[];let o;if(i.composite){const t=e.get("DW");r=Number.isInteger(t)?t:1e3;const g=e.get("W");if(Array.isArray(g))for(let e=0,t=g.length;e<t;e++){let t=a.fetchIfRef(g[e++]);if(!Number.isInteger(t))break;const i=a.fetchIfRef(g[e]);if(Array.isArray(i))for(const e of i){const i=a.fetchIfRef(e);"number"==typeof i&&(s[t]=i);t++}else{if(!Number.isInteger(i))break;{const r=a.fetchIfRef(g[++e]);if("number"!=typeof r)continue;for(let e=t;e<=i;e++)s[e]=r}}}if(i.vertical){const t=e.getArray("DW2");let i=isNumberArray(t,2)?t:[880,-1e3];o=[i[1],.5*r,i[0]];i=e.get("W2");if(Array.isArray(i))for(let e=0,t=i.length;e<t;e++){let t=a.fetchIfRef(i[e++]);if(!Number.isInteger(t))break;const s=a.fetchIfRef(i[e]);if(Array.isArray(s))for(let e=0,i=s.length;e<i;e++){const i=[a.fetchIfRef(s[e++]),a.fetchIfRef(s[e++]),a.fetchIfRef(s[e])];isNumberArray(i,null)&&(n[t]=i);t++}else{if(!Number.isInteger(s))break;{const r=[a.fetchIfRef(i[++e]),a.fetchIfRef(i[++e]),a.fetchIfRef(i[++e])];if(!isNumberArray(r,null))continue;for(let e=t;e<=s;e++)n[e]=r}}}}}else{const n=e.get("Widths");if(Array.isArray(n)){let e=i.firstChar;for(const t of n){const i=a.fetchIfRef(t);"number"==typeof i&&(s[e]=i);e++}const o=t.get("MissingWidth");r="number"==typeof o?o:0}else{const t=e.get("BaseFont");if(t instanceof Name){const e=this.getBaseFontMetrics(t.name);s=this.buildCharCodeToWidth(e.widths,i);r=e.defaultWidth}}}let g=!0,c=r;for(const e in s){const t=s[e];if(t)if(c){if(c!==t){g=!1;break}}else c=t}g?i.flags|=vi:i.flags&=~vi;i.defaultWidth=r;i.widths=s;i.defaultVMetrics=o;i.vmetrics=n}isSerifFont(e){const t=e.split("-",1)[0];return t in ji()||/serif/gi.test(t)}getBaseFontMetrics(e){let t=0,i=Object.create(null),a=!1;let s=Pi()[e]||e;const r=Aa();s in r||(s=this.isSerifFont(e)?"Times-Roman":"Helvetica");const n=r[s];if("number"==typeof n){t=n;a=!0}else i=n();return{defaultWidth:t,monospace:a,widths:i}}buildCharCodeToWidth(e,t){const i=Object.create(null),a=t.differences,s=t.defaultEncoding;for(let t=0;t<256;t++)t in a&&e[a[t]]?i[t]=e[a[t]]:t in s&&e[s[t]]&&(i[t]=e[s[t]]);return i}preEvaluateFont(e){const t=e;let i=e.get("Subtype");if(!(i instanceof Name))throw new FormatError("invalid font Subtype");let a,s=!1;if("Type0"===i.name){const t=e.get("DescendantFonts");if(!t)throw new FormatError("Descendant fonts are not specified");if(!((e=Array.isArray(t)?this.xref.fetchIfRef(t[0]):t)instanceof Dict))throw new FormatError("Descendant font is not a dictionary.");i=e.get("Subtype");if(!(i instanceof Name))throw new FormatError("invalid font Subtype");s=!0}let r=e.get("FirstChar");Number.isInteger(r)||(r=0);let n=e.get("LastChar");Number.isInteger(n)||(n=s?65535:255);const o=e.get("FontDescriptor"),g=e.get("ToUnicode")||t.get("ToUnicode");if(o){a=new MurmurHash3_64;const i=t.getRaw("Encoding");if(i instanceof Name)a.update(i.name);else if(i instanceof Ref)a.update(i.toString());else if(i instanceof Dict)for(const e of i.getRawValues())if(e instanceof Name)a.update(e.name);else if(e instanceof Ref)a.update(e.toString());else if(Array.isArray(e)){const t=e.length,i=new Array(t);for(let a=0;a<t;a++){const t=e[a];t instanceof Name?i[a]=t.name:("number"==typeof t||t instanceof Ref)&&(i[a]=t.toString())}a.update(i.join())}a.update(`${r}-${n}`);if(g instanceof BaseStream){const e=g.str||g,t=e.buffer?new Uint8Array(e.buffer.buffer,0,e.bufferLength):new Uint8Array(e.bytes.buffer,e.start,e.end-e.start);a.update(t)}else g instanceof Name&&a.update(g.name);const o=e.get("Widths")||t.get("Widths");if(Array.isArray(o)){const e=[];for(const t of o)("number"==typeof t||t instanceof Ref)&&e.push(t.toString());a.update(e.join())}if(s){a.update("compositeFont");const i=e.get("W")||t.get("W");if(Array.isArray(i)){const e=[];for(const t of i)if("number"==typeof t||t instanceof Ref)e.push(t.toString());else if(Array.isArray(t)){const i=[];for(const e of t)("number"==typeof e||e instanceof Ref)&&i.push(e.toString());e.push(`[${i.join()}]`)}a.update(e.join())}const s=e.getRaw("CIDToGIDMap")||t.getRaw("CIDToGIDMap");s instanceof Name?a.update(s.name):s instanceof Ref?a.update(s.toString()):s instanceof BaseStream&&a.update(s.peekBytes())}}return{descriptor:o,dict:e,baseDict:t,composite:s,type:i.name,firstChar:r,lastChar:n,toUnicode:g,hash:a?a.hexdigest():""}}async translateFont({descriptor:e,dict:t,baseDict:i,composite:s,type:r,firstChar:n,lastChar:o,toUnicode:g,cssFontInfo:c}){const h="Type3"===r;if(!e){if(!h){let e=t.get("BaseFont");if(!(e instanceof Name))throw new FormatError("Base font is not specified");e=e.name.replaceAll(/[,_]/g,"-");const a=this.getBaseFontMetrics(e),s=e.split("-",1)[0],c=(this.isSerifFont(s)?Ki:0)|(a.monospace?vi:0)|(Zi()[s]?Ti:qi),l={type:r,name:e,loadedName:i.loadedName,systemFontInfo:null,widths:a.widths,defaultWidth:a.defaultWidth,isSimulatedFlags:!0,flags:c,firstChar:n,lastChar:o,toUnicode:g,xHeight:0,capHeight:0,italicAngle:0,isType3Font:h},C=t.get("Widths"),Q=getStandardFontName(e);let E=null;if(Q){E=await this.fetchStandardFontData(Q);l.isInternalFont=!!E}!l.isInternalFont&&this.options.useSystemFonts&&(l.systemFontInfo=getFontSubstitution(this.systemFontCache,this.idFactory,this.options.standardFontDataUrl,e,Q,r));const u=await this.extractDataStructures(t,l);if(Array.isArray(C)){const e=[];let t=n;for(const i of C){const a=this.xref.fetchIfRef(i);"number"==typeof a&&(e[t]=a);t++}u.widths=e}else u.widths=this.buildCharCodeToWidth(a.widths,u);return new Font(e,E,u)}{const i=lookupNormalRect(t.getArray("FontBBox"),[0,0,0,0]);(e=new Dict(null)).set("FontName",Name.get(r));e.set("FontBBox",i)}}let l=e.get("FontName"),C=t.get("BaseFont");"string"==typeof l&&(l=Name.get(l));"string"==typeof C&&(C=Name.get(C));const Q=l?.name,E=C?.name;if(!h&&Q!==E){info(`The FontDescriptor's FontName is "${Q}" but should be the same as the Font's BaseFont "${E}".`);Q&&E&&(E.startsWith(Q)||!isKnownFontName(Q)&&isKnownFontName(E))&&(l=null)}l||=C;if(!(l instanceof Name))throw new FormatError("invalid font name");let u,d,f,p,m;try{u=e.get("FontFile","FontFile2","FontFile3")}catch(e){if(!this.options.ignoreErrors)throw e;warn(`translateFont - fetching "${l.name}" font file: "${e}".`);u=new NullStream}let y=!1,w=null,b=null;if(u){if(u.dict){const e=u.dict.get("Subtype");e instanceof Name&&(d=e.name);f=u.dict.get("Length1");p=u.dict.get("Length2");m=u.dict.get("Length3")}}else if(c){const e=getXfaFontName(l.name);if(e){c.fontFamily=`${c.fontFamily}-PdfJS-XFA`;c.metrics=e.metrics||null;w=e.factors||null;u=await this.fetchStandardFontData(e.name);y=!!u;i=t=getXfaFontDict(l.name);s=!0}}else if(!h){const e=getStandardFontName(l.name);if(e){u=await this.fetchStandardFontData(e);y=!!u}!y&&this.options.useSystemFonts&&(b=getFontSubstitution(this.systemFontCache,this.idFactory,this.options.standardFontDataUrl,l.name,e,r))}const D=lookupMatrix(t.getArray("FontMatrix"),a),F=lookupNormalRect(e.getArray("FontBBox")||t.getArray("FontBBox"),void 0);let S=e.get("Ascent");"number"!=typeof S&&(S=void 0);let k=e.get("Descent");"number"!=typeof k&&(k=void 0);let R=e.get("XHeight");"number"!=typeof R&&(R=0);let N=e.get("CapHeight");"number"!=typeof N&&(N=0);let G=e.get("Flags");Number.isInteger(G)||(G=0);let x=e.get("ItalicAngle");"number"!=typeof x&&(x=0);const M={type:r,name:l.name,subtype:d,file:u,length1:f,length2:p,length3:m,isInternalFont:y,loadedName:i.loadedName,composite:s,fixedPitch:!1,fontMatrix:D,firstChar:n,lastChar:o,toUnicode:g,bbox:F,ascent:S,descent:k,xHeight:R,capHeight:N,flags:G,italicAngle:x,isType3Font:h,cssFontInfo:c,scaleFactors:w,systemFontInfo:b};if(s){const e=i.get("Encoding");e instanceof Name&&(M.cidEncoding=e.name);const t=await CMapFactory.create({encoding:e,fetchBuiltInCMap:this._fetchBuiltInCMapBound,useCMap:null});M.cMap=t;M.vertical=M.cMap.vertical}const U=await this.extractDataStructures(t,M);this.extractWidths(t,e,U);return new Font(l.name,u,U)}static buildFontPaths(e,t,i,a){function buildPath(t){const s=`${e.loadedName}_path_${t}`;try{if(e.renderer.hasBuiltPath(t))return;i.send("commonobj",[s,"FontPath",e.renderer.getPathJs(t)])}catch(e){if(a.ignoreErrors){warn(`buildFontPaths - ignoring ${s} glyph: "${e}".`);return}throw e}}for(const e of t){buildPath(e.fontChar);const t=e.accent;t?.fontChar&&buildPath(t.fontChar)}}static get fallbackFontDict(){const e=new Dict;e.set("BaseFont",Name.get("Helvetica"));e.set("Type",Name.get("FallbackType"));e.set("Subtype",Name.get("FallbackType"));e.set("Encoding",Name.get("WinAnsiEncoding"));return shadow(this,"fallbackFontDict",e)}}class TranslatedFont{constructor({loadedName:e,font:t,dict:i,evaluatorOptions:a}){this.loadedName=e;this.font=t;this.dict=i;this._evaluatorOptions=a||Ds;this.type3Loaded=null;this.type3Dependencies=t.isType3Font?new Set:null;this.sent=!1}send(e){if(!this.sent){this.sent=!0;e.send("commonobj",[this.loadedName,"Font",this.font.exportData(this._evaluatorOptions.fontExtraProperties)])}}fallback(e){if(this.font.data){this.font.disableFontFace=!0;PartialEvaluator.buildFontPaths(this.font,this.font.glyphCacheValues,e,this._evaluatorOptions)}}loadType3Data(e,t,i){if(this.type3Loaded)return this.type3Loaded;if(!this.font.isType3Font)throw new Error("Must be a Type3 font.");const a=e.clone({ignoreErrors:!1}),s=new RefSet(e.type3FontRefs);this.dict.objId&&!s.has(this.dict.objId)&&s.put(this.dict.objId);a.type3FontRefs=s;const r=this.font,n=this.type3Dependencies;let o=Promise.resolve();const g=this.dict.get("CharProcs"),c=this.dict.get("Resources")||t,h=Object.create(null),l=Util.normalizeRect(r.bbox||[0,0,0,0]),C=l[2]-l[0],Q=l[3]-l[1],E=Math.hypot(C,Q);for(const e of g.getKeys())o=o.then((()=>{const t=g.get(e),s=new OperatorList;return a.getOperatorList({stream:t,task:i,resources:c,operatorList:s}).then((()=>{s.fnArray[0]===Ee&&this._removeType3ColorOperators(s,E);h[e]=s.getIR();for(const e of s.dependencies)n.add(e)})).catch((function(t){warn(`Type3 font resource "${e}" is not available.`);const i=new OperatorList;h[e]=i.getIR()}))}));this.type3Loaded=o.then((()=>{r.charProcOperatorList=h;if(this._bbox){r.isCharBBox=!0;r.bbox=this._bbox}}));return this.type3Loaded}_removeType3ColorOperators(e,t=NaN){const i=Util.normalizeRect(e.argsArray[0].slice(2)),a=i[2]-i[0],s=i[3]-i[1],r=Math.hypot(a,s);if(0===a||0===s){e.fnArray.splice(0,1);e.argsArray.splice(0,1)}else if(0===t||Math.round(r/t)>=10){this._bbox||(this._bbox=[1/0,1/0,-1/0,-1/0]);this._bbox[0]=Math.min(this._bbox[0],i[0]);this._bbox[1]=Math.min(this._bbox[1],i[1]);this._bbox[2]=Math.max(this._bbox[2],i[2]);this._bbox[3]=Math.max(this._bbox[3],i[3])}let n=0,o=e.length;for(;n<o;){switch(e.fnArray[n]){case Ee:break;case ue:case de:case fe:case pe:case me:case ye:case we:case be:case De:case Fe:case Se:case ke:case Re:case kA:e.fnArray.splice(n,1);e.argsArray.splice(n,1);o--;continue;case NA:const[t]=e.argsArray[n];let i=0,a=t.length;for(;i<a;){const[e]=t[i];switch(e){case"TR":case"TR2":case"HT":case"BG":case"BG2":case"UCR":case"UCR2":t.splice(i,1);a--;continue}i++}}n++}}}class StateManager{constructor(e=new EvalState){this.state=e;this.stateStack=[]}save(){const e=this.state;this.stateStack.push(this.state);this.state=e.clone()}restore(){const e=this.stateStack.pop();e&&(this.state=e)}transform(e){this.state.ctm=Util.transform(this.state.ctm,e)}}class TextState{constructor(){this.ctm=new Float32Array(i);this.fontName=null;this.fontSize=0;this.loadedName=null;this.font=null;this.fontMatrix=a;this.textMatrix=i.slice();this.textLineMatrix=i.slice();this.charSpacing=0;this.wordSpacing=0;this.leading=0;this.textHScale=1;this.textRise=0}setTextMatrix(e,t,i,a,s,r){const n=this.textMatrix;n[0]=e;n[1]=t;n[2]=i;n[3]=a;n[4]=s;n[5]=r}setTextLineMatrix(e,t,i,a,s,r){const n=this.textLineMatrix;n[0]=e;n[1]=t;n[2]=i;n[3]=a;n[4]=s;n[5]=r}translateTextMatrix(e,t){const i=this.textMatrix;i[4]=i[0]*e+i[2]*t+i[4];i[5]=i[1]*e+i[3]*t+i[5]}translateTextLineMatrix(e,t){const i=this.textLineMatrix;i[4]=i[0]*e+i[2]*t+i[4];i[5]=i[1]*e+i[3]*t+i[5]}carriageReturn(){this.translateTextLineMatrix(0,-this.leading);this.textMatrix=this.textLineMatrix.slice()}clone(){const e=Object.create(this);e.textMatrix=this.textMatrix.slice();e.textLineMatrix=this.textLineMatrix.slice();e.fontMatrix=this.fontMatrix.slice();return e}}class EvalState{constructor(){this.ctm=new Float32Array(i);this.font=null;this.textRenderingMode=y;this.fillColorSpace=ColorSpace.singletons.gray;this.strokeColorSpace=ColorSpace.singletons.gray}clone(){return Object.create(this)}}class EvaluatorPreprocessor{static get opMap(){return shadow(this,"opMap",Object.assign(Object.create(null),{w:{id:wA,numArgs:1,variableArgs:!1},J:{id:bA,numArgs:1,variableArgs:!1},j:{id:DA,numArgs:1,variableArgs:!1},M:{id:FA,numArgs:1,variableArgs:!1},d:{id:SA,numArgs:2,variableArgs:!1},ri:{id:kA,numArgs:1,variableArgs:!1},i:{id:RA,numArgs:1,variableArgs:!1},gs:{id:NA,numArgs:1,variableArgs:!1},q:{id:GA,numArgs:0,variableArgs:!1},Q:{id:xA,numArgs:0,variableArgs:!1},cm:{id:MA,numArgs:6,variableArgs:!1},m:{id:UA,numArgs:2,variableArgs:!1},l:{id:LA,numArgs:2,variableArgs:!1},c:{id:JA,numArgs:6,variableArgs:!1},v:{id:HA,numArgs:4,variableArgs:!1},y:{id:YA,numArgs:4,variableArgs:!1},h:{id:vA,numArgs:0,variableArgs:!1},re:{id:KA,numArgs:4,variableArgs:!1},S:{id:TA,numArgs:0,variableArgs:!1},s:{id:qA,numArgs:0,variableArgs:!1},f:{id:OA,numArgs:0,variableArgs:!1},F:{id:OA,numArgs:0,variableArgs:!1},"f*":{id:PA,numArgs:0,variableArgs:!1},B:{id:WA,numArgs:0,variableArgs:!1},"B*":{id:XA,numArgs:0,variableArgs:!1},b:{id:jA,numArgs:0,variableArgs:!1},"b*":{id:ZA,numArgs:0,variableArgs:!1},n:{id:VA,numArgs:0,variableArgs:!1},W:{id:zA,numArgs:0,variableArgs:!1},"W*":{id:_A,numArgs:0,variableArgs:!1},BT:{id:$A,numArgs:0,variableArgs:!1},ET:{id:Ae,numArgs:0,variableArgs:!1},Tc:{id:ee,numArgs:1,variableArgs:!1},Tw:{id:te,numArgs:1,variableArgs:!1},Tz:{id:ie,numArgs:1,variableArgs:!1},TL:{id:ae,numArgs:1,variableArgs:!1},Tf:{id:se,numArgs:2,variableArgs:!1},Tr:{id:re,numArgs:1,variableArgs:!1},Ts:{id:ne,numArgs:1,variableArgs:!1},Td:{id:oe,numArgs:2,variableArgs:!1},TD:{id:ge,numArgs:2,variableArgs:!1},Tm:{id:Ie,numArgs:6,variableArgs:!1},"T*":{id:ce,numArgs:0,variableArgs:!1},Tj:{id:he,numArgs:1,variableArgs:!1},TJ:{id:le,numArgs:1,variableArgs:!1},"'":{id:Ce,numArgs:1,variableArgs:!1},'"':{id:Be,numArgs:3,variableArgs:!1},d0:{id:Qe,numArgs:2,variableArgs:!1},d1:{id:Ee,numArgs:6,variableArgs:!1},CS:{id:ue,numArgs:1,variableArgs:!1},cs:{id:de,numArgs:1,variableArgs:!1},SC:{id:fe,numArgs:4,variableArgs:!0},SCN:{id:pe,numArgs:33,variableArgs:!0},sc:{id:me,numArgs:4,variableArgs:!0},scn:{id:ye,numArgs:33,variableArgs:!0},G:{id:we,numArgs:1,variableArgs:!1},g:{id:be,numArgs:1,variableArgs:!1},RG:{id:De,numArgs:3,variableArgs:!1},rg:{id:Fe,numArgs:3,variableArgs:!1},K:{id:Se,numArgs:4,variableArgs:!1},k:{id:ke,numArgs:4,variableArgs:!1},sh:{id:Re,numArgs:1,variableArgs:!1},BI:{id:Ne,numArgs:0,variableArgs:!1},ID:{id:Ge,numArgs:0,variableArgs:!1},EI:{id:xe,numArgs:1,variableArgs:!1},Do:{id:Me,numArgs:1,variableArgs:!1},MP:{id:Ue,numArgs:1,variableArgs:!1},DP:{id:Le,numArgs:2,variableArgs:!1},BMC:{id:Je,numArgs:1,variableArgs:!1},BDC:{id:He,numArgs:2,variableArgs:!1},EMC:{id:Ye,numArgs:0,variableArgs:!1},BX:{id:ve,numArgs:0,variableArgs:!1},EX:{id:Ke,numArgs:0,variableArgs:!1},BM:null,BD:null,true:null,fa:null,fal:null,fals:null,false:null,nu:null,nul:null,null:null}))}static MAX_INVALID_PATH_OPS=10;constructor(e,t,i=new StateManager){this.parser=new Parser({lexer:new Lexer(e,EvaluatorPreprocessor.opMap),xref:t});this.stateManager=i;this.nonProcessedArgs=[];this._isPathOp=!1;this._numInvalidPathOPS=0}get savedStatesDepth(){return this.stateManager.stateStack.length}read(e){let t=e.args;for(;;){const i=this.parser.getObj();if(i instanceof Cmd){const a=i.cmd,s=EvaluatorPreprocessor.opMap[a];if(!s){warn(`Unknown command "${a}".`);continue}const r=s.id,n=s.numArgs;let o=null!==t?t.length:0;this._isPathOp||(this._numInvalidPathOPS=0);this._isPathOp=r>=UA&&r<=VA;if(s.variableArgs)o>n&&info(`Command ${a}: expected [0, ${n}] args, but received ${o} args.`);else{if(o!==n){const e=this.nonProcessedArgs;for(;o>n;){e.push(t.shift());o--}for(;o<n&&0!==e.length;){null===t&&(t=[]);t.unshift(e.pop());o++}}if(o<n){const e=`command ${a}: expected ${n} args, but received ${o} args.`;if(this._isPathOp&&++this._numInvalidPathOPS>EvaluatorPreprocessor.MAX_INVALID_PATH_OPS)throw new FormatError(`Invalid ${e}`);warn(`Skipping ${e}`);null!==t&&(t.length=0);continue}}this.preprocessCommand(r,t);e.fn=r;e.args=t;return!0}if(i===pt)return!1;if(null!==i){null===t&&(t=[]);t.push(i);if(t.length>33)throw new FormatError("Too many arguments")}}}preprocessCommand(e,t){switch(0|e){case GA:this.stateManager.save();break;case xA:this.stateManager.restore();break;case MA:this.stateManager.transform(t)}}}class DefaultAppearanceEvaluator extends EvaluatorPreprocessor{constructor(e){super(new StringStream(e))}parse(){const e={fn:0,args:[]},t={fontSize:0,fontName:"",fontColor:new Uint8ClampedArray(3)};try{for(;;){e.args.length=0;if(!this.read(e))break;if(0!==this.savedStatesDepth)continue;const{fn:i,args:a}=e;switch(0|i){case se:const[e,i]=a;e instanceof Name&&(t.fontName=e.name);"number"==typeof i&&i>0&&(t.fontSize=i);break;case Fe:ColorSpace.singletons.rgb.getRgbItem(a,0,t.fontColor,0);break;case be:ColorSpace.singletons.gray.getRgbItem(a,0,t.fontColor,0);break;case ke:ColorSpace.singletons.cmyk.getRgbItem(a,0,t.fontColor,0)}}}catch(e){warn(`parseDefaultAppearance - ignoring errors: "${e}".`)}return t}}function parseDefaultAppearance(e){return new DefaultAppearanceEvaluator(e).parse()}class AppearanceStreamEvaluator extends EvaluatorPreprocessor{constructor(e,t,i){super(e);this.stream=e;this.evaluatorOptions=t;this.xref=i;this.resources=e.dict?.get("Resources")}parse(){const e={fn:0,args:[]};let t={scaleFactor:1,fontSize:0,fontName:"",fontColor:new Uint8ClampedArray(3),fillColorSpace:ColorSpace.singletons.gray},i=!1;const a=[];try{for(;;){e.args.length=0;if(i||!this.read(e))break;const{fn:s,args:r}=e;switch(0|s){case GA:a.push({scaleFactor:t.scaleFactor,fontSize:t.fontSize,fontName:t.fontName,fontColor:t.fontColor.slice(),fillColorSpace:t.fillColorSpace});break;case xA:t=a.pop()||t;break;case Ie:t.scaleFactor*=Math.hypot(r[0],r[1]);break;case se:const[e,s]=r;e instanceof Name&&(t.fontName=e.name);"number"==typeof s&&s>0&&(t.fontSize=s*t.scaleFactor);break;case de:t.fillColorSpace=ColorSpace.parse({cs:r[0],xref:this.xref,resources:this.resources,pdfFunctionFactory:this._pdfFunctionFactory,localColorSpaceCache:this._localColorSpaceCache});break;case me:t.fillColorSpace.getRgbItem(r,0,t.fontColor,0);break;case Fe:ColorSpace.singletons.rgb.getRgbItem(r,0,t.fontColor,0);break;case be:ColorSpace.singletons.gray.getRgbItem(r,0,t.fontColor,0);break;case ke:ColorSpace.singletons.cmyk.getRgbItem(r,0,t.fontColor,0);break;case he:case le:case Ce:case Be:i=!0}}}catch(e){warn(`parseAppearanceStream - ignoring errors: "${e}".`)}this.stream.reset();delete t.scaleFactor;delete t.fillColorSpace;return t}get _localColorSpaceCache(){return shadow(this,"_localColorSpaceCache",new LocalColorSpaceCache)}get _pdfFunctionFactory(){return shadow(this,"_pdfFunctionFactory",new PDFFunctionFactory({xref:this.xref,isEvalSupported:this.evaluatorOptions.isEvalSupported}))}}function getPdfColor(e,t){if(e[0]===e[1]&&e[1]===e[2]){return`${numberToString(e[0]/255)} ${t?"g":"G"}`}return Array.from(e,(e=>numberToString(e/255))).join(" ")+" "+(t?"rg":"RG")}class FakeUnicodeFont{constructor(e,t){this.xref=e;this.widths=null;this.firstChar=1/0;this.lastChar=-1/0;this.fontFamily=t;const i=new OffscreenCanvas(1,1);this.ctxMeasure=i.getContext("2d");FakeUnicodeFont._fontNameId||(FakeUnicodeFont._fontNameId=1);this.fontName=Name.get(`InvalidPDFjsFont_${t}_${FakeUnicodeFont._fontNameId++}`)}get fontDescriptorRef(){if(!FakeUnicodeFont._fontDescriptorRef){const e=new Dict(this.xref);e.set("Type",Name.get("FontDescriptor"));e.set("FontName",this.fontName);e.set("FontFamily","MyriadPro Regular");e.set("FontBBox",[0,0,0,0]);e.set("FontStretch",Name.get("Normal"));e.set("FontWeight",400);e.set("ItalicAngle",0);FakeUnicodeFont._fontDescriptorRef=this.xref.getNewPersistentRef(e)}return FakeUnicodeFont._fontDescriptorRef}get descendantFontRef(){const e=new Dict(this.xref);e.set("BaseFont",this.fontName);e.set("Type",Name.get("Font"));e.set("Subtype",Name.get("CIDFontType0"));e.set("CIDToGIDMap",Name.get("Identity"));e.set("FirstChar",this.firstChar);e.set("LastChar",this.lastChar);e.set("FontDescriptor",this.fontDescriptorRef);e.set("DW",1e3);const t=[],i=[...this.widths.entries()].sort();let a=null,s=null;for(const[e,r]of i)if(a)if(e===a+s.length)s.push(r);else{t.push(a,s);a=e;s=[r]}else{a=e;s=[r]}a&&t.push(a,s);e.set("W",t);const r=new Dict(this.xref);r.set("Ordering","Identity");r.set("Registry","Adobe");r.set("Supplement",0);e.set("CIDSystemInfo",r);return this.xref.getNewPersistentRef(e)}get baseFontRef(){const e=new Dict(this.xref);e.set("BaseFont",this.fontName);e.set("Type",Name.get("Font"));e.set("Subtype",Name.get("Type0"));e.set("Encoding",Name.get("Identity-H"));e.set("DescendantFonts",[this.descendantFontRef]);e.set("ToUnicode",Name.get("Identity-H"));return this.xref.getNewPersistentRef(e)}get resources(){const e=new Dict(this.xref),t=new Dict(this.xref);t.set(this.fontName.name,this.baseFontRef);e.set("Font",t);return e}_createContext(){this.widths=new Map;this.ctxMeasure.font=`1000px ${this.fontFamily}`;return this.ctxMeasure}createFontResources(e){const t=this._createContext();for(const i of e.split(/\r\n?|\n/))for(const e of i.split("")){const i=e.charCodeAt(0);if(this.widths.has(i))continue;const a=t.measureText(e),s=Math.ceil(a.width);this.widths.set(i,s);this.firstChar=Math.min(i,this.firstChar);this.lastChar=Math.max(i,this.lastChar)}return this.resources}static getFirstPositionInfo(e,t,i){const[a,n,o,g]=e;let c=o-a,h=g-n;t%180!=0&&([c,h]=[h,c]);const l=s*i;return{coords:[0,h+r*i-l],bbox:[0,0,c,h],matrix:0!==t?getRotationMatrix(t,h,l):void 0}}createAppearance(e,t,i,a,n,o){const g=this._createContext(),c=[];let h=-1/0;for(const t of e.split(/\r\n?|\n/)){c.push(t);const e=g.measureText(t).width;h=Math.max(h,e);for(const e of codePointIter(t)){const t=String.fromCodePoint(e);let i=this.widths.get(e);if(void 0===i){const a=g.measureText(t);i=Math.ceil(a.width);this.widths.set(e,i);this.firstChar=Math.min(e,this.firstChar);this.lastChar=Math.max(e,this.lastChar)}}}h*=a/1e3;const[l,C,Q,E]=t;let u=Q-l,d=E-C;i%180!=0&&([u,d]=[d,u]);let f=1;h>u&&(f=u/h);let p=1;const m=s*a,y=r*a,w=m*c.length;w>d&&(p=d/w);const b=a*Math.min(f,p),D=["q",`0 0 ${numberToString(u)} ${numberToString(d)} re W n`,"BT",`1 0 0 1 0 ${numberToString(d+y)} Tm 0 Tc ${getPdfColor(n,!0)}`,`/${this.fontName.name} ${numberToString(b)} Tf`],{resources:F}=this;if(1!==(o="number"==typeof o&&o>=0&&o<=1?o:1)){D.push("/R0 gs");const e=new Dict(this.xref),t=new Dict(this.xref);t.set("ca",o);t.set("CA",o);t.set("Type",Name.get("ExtGState"));e.set("R0",t);F.set("ExtGState",e)}const S=numberToString(m);for(const e of c)D.push(`0 -${S} Td <${stringToUTF16HexString(e)}> Tj`);D.push("ET","Q");const k=D.join("\n"),R=new Dict(this.xref);R.set("Subtype",Name.get("Form"));R.set("Type",Name.get("XObject"));R.set("BBox",[0,0,u,d]);R.set("Length",k.length);R.set("Resources",F);if(i){const e=getRotationMatrix(i,u,d);R.set("Matrix",e)}const N=new StringStream(k);N.dict=R;return N}}class NameOrNumberTree{constructor(e,t,i){this.constructor===NameOrNumberTree&&unreachable("Cannot initialize NameOrNumberTree.");this.root=e;this.xref=t;this._type=i}getAll(){const e=new Map;if(!this.root)return e;const t=this.xref,i=new RefSet;i.put(this.root);const a=[this.root];for(;a.length>0;){const s=t.fetchIfRef(a.shift());if(!(s instanceof Dict))continue;if(s.has("Kids")){const e=s.get("Kids");if(!Array.isArray(e))continue;for(const t of e){if(i.has(t))throw new FormatError(`Duplicate entry in "${this._type}" tree.`);a.push(t);i.put(t)}continue}const r=s.get(this._type);if(Array.isArray(r))for(let i=0,a=r.length;i<a;i+=2)e.set(t.fetchIfRef(r[i]),t.fetchIfRef(r[i+1]))}return e}get(e){if(!this.root)return null;const t=this.xref;let i=t.fetchIfRef(this.root),a=0;for(;i.has("Kids");){if(++a>10){warn(`Search depth limit reached for "${this._type}" tree.`);return null}const s=i.get("Kids");if(!Array.isArray(s))return null;let r=0,n=s.length-1;for(;r<=n;){const a=r+n>>1,o=t.fetchIfRef(s[a]),g=o.get("Limits");if(e<t.fetchIfRef(g[0]))n=a-1;else{if(!(e>t.fetchIfRef(g[1]))){i=o;break}r=a+1}}if(r>n)return null}const s=i.get(this._type);if(Array.isArray(s)){let i=0,a=s.length-2;for(;i<=a;){const r=i+a>>1,n=r+(1&r),o=t.fetchIfRef(s[n]);if(e<o)a=n-2;else{if(!(e>o))return t.fetchIfRef(s[n+1]);i=n+2}}}return null}}class NameTree extends NameOrNumberTree{constructor(e,t){super(e,t,"Names")}}class NumberTree extends NameOrNumberTree{constructor(e,t){super(e,t,"Nums")}}function clearGlobalCaches(){!function clearPatternCaches(){ya=Object.create(null)}();!function clearPrimitiveCaches(){mt=Object.create(null);yt=Object.create(null);wt=Object.create(null)}();!function clearUnicodeCaches(){Hi.clear()}();JpxImage.cleanup()}function pickPlatformItem(e){return e instanceof Dict?e.has("UF")?e.get("UF"):e.has("F")?e.get("F"):e.has("Unix")?e.get("Unix"):e.has("Mac")?e.get("Mac"):e.has("DOS")?e.get("DOS"):null:null}class FileSpec{#S=!1;constructor(e,t,i=!1){if(e instanceof Dict){this.xref=t;this.root=e;e.has("FS")&&(this.fs=e.get("FS"));e.has("RF")&&warn("Related file specifications are not supported");i||(e.has("EF")?this.#S=!0:warn("Non-embedded file specifications are not supported"))}}get filename(){let e="";const t=pickPlatformItem(this.root);t&&"string"==typeof t&&(e=stringToPDFString(t).replaceAll("\\\\","\\").replaceAll("\\/","/").replaceAll("\\","/"));return shadow(this,"filename",e||"unnamed")}get content(){if(!this.#S)return null;this._contentRef||=pickPlatformItem(this.root?.get("EF"));let e=null;if(this._contentRef){const t=this.xref.fetchIfRef(this._contentRef);t instanceof BaseStream?e=t.getBytes():warn("Embedded file specification points to non-existing/invalid content")}else warn("Embedded file specification does not have any content");return e}get description(){let e="";const t=this.root?.get("Desc");t&&"string"==typeof t&&(e=stringToPDFString(t));return shadow(this,"description",e)}get serializable(){return{rawFilename:this.filename,filename:(e=this.filename,e.substring(e.lastIndexOf("/")+1)),content:this.content,description:this.description};var e}}const Rs=0,Ns=-2,Gs=-3,xs=-4,Ms=-5,Us=-6,Ls=-9;function isWhitespace(e,t){const i=e[t];return" "===i||"\n"===i||"\r"===i||"\t"===i}class XMLParserBase{_resolveEntities(e){return e.replaceAll(/&([^;]+);/g,((e,t)=>{if("#x"===t.substring(0,2))return String.fromCodePoint(parseInt(t.substring(2),16));if("#"===t.substring(0,1))return String.fromCodePoint(parseInt(t.substring(1),10));switch(t){case"lt":return"<";case"gt":return">";case"amp":return"&";case"quot":return'"';case"apos":return"'"}return this.onResolveEntity(t)}))}_parseContent(e,t){const i=[];let a=t;function skipWs(){for(;a<e.length&&isWhitespace(e,a);)++a}for(;a<e.length&&!isWhitespace(e,a)&&">"!==e[a]&&"/"!==e[a];)++a;const s=e.substring(t,a);skipWs();for(;a<e.length&&">"!==e[a]&&"/"!==e[a]&&"?"!==e[a];){skipWs();let t="",s="";for(;a<e.length&&!isWhitespace(e,a)&&"="!==e[a];){t+=e[a];++a}skipWs();if("="!==e[a])return null;++a;skipWs();const r=e[a];if('"'!==r&&"'"!==r)return null;const n=e.indexOf(r,++a);if(n<0)return null;s=e.substring(a,n);i.push({name:t,value:this._resolveEntities(s)});a=n+1;skipWs()}return{name:s,attributes:i,parsed:a-t}}_parseProcessingInstruction(e,t){let i=t;for(;i<e.length&&!isWhitespace(e,i)&&">"!==e[i]&&"?"!==e[i]&&"/"!==e[i];)++i;const a=e.substring(t,i);!function skipWs(){for(;i<e.length&&isWhitespace(e,i);)++i}();const s=i;for(;i<e.length&&("?"!==e[i]||">"!==e[i+1]);)++i;return{name:a,value:e.substring(s,i),parsed:i-t}}parseXml(e){let t=0;for(;t<e.length;){let i=t;if("<"===e[t]){++i;let t;switch(e[i]){case"/":++i;t=e.indexOf(">",i);if(t<0){this.onError(Ls);return}this.onEndElement(e.substring(i,t));i=t+1;break;case"?":++i;const a=this._parseProcessingInstruction(e,i);if("?>"!==e.substring(i+a.parsed,i+a.parsed+2)){this.onError(Gs);return}this.onPi(a.name,a.value);i+=a.parsed+2;break;case"!":if("--"===e.substring(i+1,i+3)){t=e.indexOf("--\x3e",i+3);if(t<0){this.onError(Ms);return}this.onComment(e.substring(i+3,t));i=t+3}else if("[CDATA["===e.substring(i+1,i+8)){t=e.indexOf("]]>",i+8);if(t<0){this.onError(Ns);return}this.onCdata(e.substring(i+8,t));i=t+3}else{if("DOCTYPE"!==e.substring(i+1,i+8)){this.onError(Us);return}{const a=e.indexOf("[",i+8);let s=!1;t=e.indexOf(">",i+8);if(t<0){this.onError(xs);return}if(a>0&&t>a){t=e.indexOf("]>",i+8);if(t<0){this.onError(xs);return}s=!0}const r=e.substring(i+8,t+(s?1:0));this.onDoctype(r);i=t+(s?2:1)}}break;default:const s=this._parseContent(e,i);if(null===s){this.onError(Us);return}let r=!1;if("/>"===e.substring(i+s.parsed,i+s.parsed+2))r=!0;else if(">"!==e.substring(i+s.parsed,i+s.parsed+1)){this.onError(Ls);return}this.onBeginElement(s.name,s.attributes,r);i+=s.parsed+(r?2:1)}}else{for(;i<e.length&&"<"!==e[i];)i++;const a=e.substring(t,i);this.onText(this._resolveEntities(a))}t=i}}onResolveEntity(e){return`&${e};`}onPi(e,t){}onComment(e){}onCdata(e){}onDoctype(e){}onText(e){}onBeginElement(e,t,i){}onEndElement(e){}onError(e){}}class SimpleDOMNode{constructor(e,t){this.nodeName=e;this.nodeValue=t;Object.defineProperty(this,"parentNode",{value:null,writable:!0})}get firstChild(){return this.childNodes?.[0]}get nextSibling(){const e=this.parentNode.childNodes;if(!e)return;const t=e.indexOf(this);return-1!==t?e[t+1]:void 0}get textContent(){return this.childNodes?this.childNodes.map((function(e){return e.textContent})).join(""):this.nodeValue||""}get children(){return this.childNodes||[]}hasChildNodes(){return this.childNodes?.length>0}searchNode(e,t){if(t>=e.length)return this;const i=e[t];if(i.name.startsWith("#")&&t<e.length-1)return this.searchNode(e,t+1);const a=[];let s=this;for(;;){if(i.name===s.nodeName){if(0!==i.pos){if(0===a.length)return null;{const[r]=a.pop();let n=0;for(const a of r.childNodes)if(i.name===a.nodeName){if(n===i.pos)return a.searchNode(e,t+1);n++}return s.searchNode(e,t+1)}}{const i=s.searchNode(e,t+1);if(null!==i)return i}}if(s.childNodes?.length>0){a.push([s,0]);s=s.childNodes[0]}else{if(0===a.length)return null;for(;0!==a.length;){const[e,t]=a.pop(),i=t+1;if(i<e.childNodes.length){a.push([e,i]);s=e.childNodes[i];break}}if(0===a.length)return null}}}dump(e){if("#text"!==this.nodeName){e.push(`<${this.nodeName}`);if(this.attributes)for(const t of this.attributes)e.push(` ${t.name}="${encodeToXmlString(t.value)}"`);if(this.hasChildNodes()){e.push(">");for(const t of this.childNodes)t.dump(e);e.push(`</${this.nodeName}>`)}else this.nodeValue?e.push(`>${encodeToXmlString(this.nodeValue)}</${this.nodeName}>`):e.push("/>")}else e.push(encodeToXmlString(this.nodeValue))}}class SimpleXMLParser extends XMLParserBase{constructor({hasAttributes:e=!1,lowerCaseName:t=!1}){super();this._currentFragment=null;this._stack=null;this._errorCode=Rs;this._hasAttributes=e;this._lowerCaseName=t}parseFromString(e){this._currentFragment=[];this._stack=[];this._errorCode=Rs;this.parseXml(e);if(this._errorCode!==Rs)return;const[t]=this._currentFragment;return t?{documentElement:t}:void 0}onText(e){if(function isWhitespaceString(e){for(let t=0,i=e.length;t<i;t++)if(!isWhitespace(e,t))return!1;return!0}(e))return;const t=new SimpleDOMNode("#text",e);this._currentFragment.push(t)}onCdata(e){const t=new SimpleDOMNode("#text",e);this._currentFragment.push(t)}onBeginElement(e,t,i){this._lowerCaseName&&(e=e.toLowerCase());const a=new SimpleDOMNode(e);a.childNodes=[];this._hasAttributes&&(a.attributes=t);this._currentFragment.push(a);if(!i){this._stack.push(this._currentFragment);this._currentFragment=a.childNodes}}onEndElement(e){this._currentFragment=this._stack.pop()||[];const t=this._currentFragment.at(-1);if(!t)return null;for(const e of t.childNodes)e.parentNode=t;return t}onError(e){this._errorCode=e}}class MetadataParser{constructor(e){e=this._repair(e);const t=new SimpleXMLParser({lowerCaseName:!0}).parseFromString(e);this._metadataMap=new Map;this._data=e;t&&this._parse(t)}_repair(e){return e.replace(/^[^<]+/,"").replaceAll(/>\\376\\377([^<]+)/g,(function(e,t){const i=t.replaceAll(/\\([0-3])([0-7])([0-7])/g,(function(e,t,i,a){return String.fromCharCode(64*t+8*i+1*a)})).replaceAll(/&(amp|apos|gt|lt|quot);/g,(function(e,t){switch(t){case"amp":return"&";case"apos":return"'";case"gt":return">";case"lt":return"<";case"quot":return'"'}throw new Error(`_repair: ${t} isn't defined.`)})),a=[">"];for(let e=0,t=i.length;e<t;e+=2){const t=256*i.charCodeAt(e)+i.charCodeAt(e+1);t>=32&&t<127&&60!==t&&62!==t&&38!==t?a.push(String.fromCharCode(t)):a.push("&#x"+(65536+t).toString(16).substring(1)+";")}return a.join("")}))}_getSequence(e){const t=e.nodeName;return"rdf:bag"!==t&&"rdf:seq"!==t&&"rdf:alt"!==t?null:e.childNodes.filter((e=>"rdf:li"===e.nodeName))}_parseArray(e){if(!e.hasChildNodes())return;const[t]=e.childNodes,i=this._getSequence(t)||[];this._metadataMap.set(e.nodeName,i.map((e=>e.textContent.trim())))}_parse(e){let t=e.documentElement;if("rdf:rdf"!==t.nodeName){t=t.firstChild;for(;t&&"rdf:rdf"!==t.nodeName;)t=t.nextSibling}if(t&&"rdf:rdf"===t.nodeName&&t.hasChildNodes())for(const e of t.childNodes)if("rdf:description"===e.nodeName)for(const t of e.childNodes){const e=t.nodeName;switch(e){case"#text":continue;case"dc:creator":case"dc:subject":this._parseArray(t);continue}this._metadataMap.set(e,t.textContent.trim())}}get serializable(){return{parsedData:this._metadataMap,rawData:this._data}}}class DecryptStream extends DecodeStream{constructor(e,t,i){super(t);this.str=e;this.dict=e.dict;this.decrypt=i;this.nextChunk=null;this.initialized=!1}readBlock(){let e;if(this.initialized)e=this.nextChunk;else{e=this.str.getBytes(512);this.initialized=!0}if(!e||0===e.length){this.eof=!0;return}this.nextChunk=this.str.getBytes(512);const t=this.nextChunk?.length>0;e=(0,this.decrypt)(e,!t);const i=this.bufferLength,a=i+e.length;this.ensureBuffer(a).set(e,i);this.bufferLength=a}}class ARCFourCipher{constructor(e){this.a=0;this.b=0;const t=new Uint8Array(256),i=e.length;for(let e=0;e<256;++e)t[e]=e;for(let a=0,s=0;a<256;++a){const r=t[a];s=s+r+e[a%i]&255;t[a]=t[s];t[s]=r}this.s=t}encryptBlock(e){let t=this.a,i=this.b;const a=this.s,s=e.length,r=new Uint8Array(s);for(let n=0;n<s;++n){t=t+1&255;const s=a[t];i=i+s&255;const o=a[i];a[t]=o;a[i]=s;r[n]=e[n]^a[s+o&255]}this.a=t;this.b=i;return r}decryptBlock(e){return this.encryptBlock(e)}encrypt(e){return this.encryptBlock(e)}}const Js=function calculateMD5Closure(){const e=new Uint8Array([7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21]),t=new Int32Array([-680876936,-389564586,606105819,-1044525330,-176418897,1200080426,-1473231341,-45705983,1770035416,-1958414417,-42063,-1990404162,1804603682,-40341101,-1502002290,1236535329,-165796510,-1069501632,643717713,-373897302,-701558691,38016083,-660478335,-405537848,568446438,-1019803690,-187363961,1163531501,-1444681467,-51403784,1735328473,-1926607734,-378558,-2022574463,1839030562,-35309556,-1530992060,1272893353,-155497632,-1094730640,681279174,-358537222,-722521979,76029189,-640364487,-421815835,530742520,-995338651,-198630844,1126891415,-1416354905,-57434055,1700485571,-1894986606,-1051523,-2054922799,1873313359,-30611744,-1560198380,1309151649,-145523070,-1120210379,718787259,-343485551]);return function hash(i,a,s){let r=1732584193,n=-271733879,o=-1732584194,g=271733878;const c=s+72&-64,h=new Uint8Array(c);let l,C;for(l=0;l<s;++l)h[l]=i[a++];h[l++]=128;const Q=c-8;for(;l<Q;)h[l++]=0;h[l++]=s<<3&255;h[l++]=s>>5&255;h[l++]=s>>13&255;h[l++]=s>>21&255;h[l++]=s>>>29&255;h[l++]=0;h[l++]=0;h[l++]=0;const E=new Int32Array(16);for(l=0;l<c;){for(C=0;C<16;++C,l+=4)E[C]=h[l]|h[l+1]<<8|h[l+2]<<16|h[l+3]<<24;let i,a,s=r,c=n,Q=o,u=g;for(C=0;C<64;++C){if(C<16){i=c&Q|~c&u;a=C}else if(C<32){i=u&c|~u&Q;a=5*C+1&15}else if(C<48){i=c^Q^u;a=3*C+5&15}else{i=Q^(c|~u);a=7*C&15}const r=u,n=s+i+t[C]+E[a]|0,o=e[C];u=Q;Q=c;c=c+(n<<o|n>>>32-o)|0;s=r}r=r+s|0;n=n+c|0;o=o+Q|0;g=g+u|0}return new Uint8Array([255&r,r>>8&255,r>>16&255,r>>>24&255,255&n,n>>8&255,n>>16&255,n>>>24&255,255&o,o>>8&255,o>>16&255,o>>>24&255,255&g,g>>8&255,g>>16&255,g>>>24&255])}}();class Word64{constructor(e,t){this.high=0|e;this.low=0|t}and(e){this.high&=e.high;this.low&=e.low}xor(e){this.high^=e.high;this.low^=e.low}or(e){this.high|=e.high;this.low|=e.low}shiftRight(e){if(e>=32){this.low=this.high>>>e-32|0;this.high=0}else{this.low=this.low>>>e|this.high<<32-e;this.high=this.high>>>e|0}}shiftLeft(e){if(e>=32){this.high=this.low<<e-32;this.low=0}else{this.high=this.high<<e|this.low>>>32-e;this.low<<=e}}rotateRight(e){let t,i;if(32&e){i=this.low;t=this.high}else{t=this.low;i=this.high}e&=31;this.low=t>>>e|i<<32-e;this.high=i>>>e|t<<32-e}not(){this.high=~this.high;this.low=~this.low}add(e){const t=(this.low>>>0)+(e.low>>>0);let i=(this.high>>>0)+(e.high>>>0);t>4294967295&&(i+=1);this.low=0|t;this.high=0|i}copyTo(e,t){e[t]=this.high>>>24&255;e[t+1]=this.high>>16&255;e[t+2]=this.high>>8&255;e[t+3]=255&this.high;e[t+4]=this.low>>>24&255;e[t+5]=this.low>>16&255;e[t+6]=this.low>>8&255;e[t+7]=255&this.low}assign(e){this.high=e.high;this.low=e.low}}const Hs=function calculateSHA256Closure(){function rotr(e,t){return e>>>t|e<<32-t}function ch(e,t,i){return e&t^~e&i}function maj(e,t,i){return e&t^e&i^t&i}function sigma(e){return rotr(e,2)^rotr(e,13)^rotr(e,22)}function sigmaPrime(e){return rotr(e,6)^rotr(e,11)^rotr(e,25)}function littleSigma(e){return rotr(e,7)^rotr(e,18)^e>>>3}const e=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];return function hash(t,i,a){let s=1779033703,r=3144134277,n=1013904242,o=2773480762,g=1359893119,c=2600822924,h=528734635,l=1541459225;const C=64*Math.ceil((a+9)/64),Q=new Uint8Array(C);let E,u;for(E=0;E<a;++E)Q[E]=t[i++];Q[E++]=128;const d=C-8;for(;E<d;)Q[E++]=0;Q[E++]=0;Q[E++]=0;Q[E++]=0;Q[E++]=a>>>29&255;Q[E++]=a>>21&255;Q[E++]=a>>13&255;Q[E++]=a>>5&255;Q[E++]=a<<3&255;const f=new Uint32Array(64);for(E=0;E<C;){for(u=0;u<16;++u){f[u]=Q[E]<<24|Q[E+1]<<16|Q[E+2]<<8|Q[E+3];E+=4}for(u=16;u<64;++u)f[u]=(rotr(p=f[u-2],17)^rotr(p,19)^p>>>10)+f[u-7]+littleSigma(f[u-15])+f[u-16]|0;let t,i,a=s,C=r,d=n,m=o,y=g,w=c,b=h,D=l;for(u=0;u<64;++u){t=D+sigmaPrime(y)+ch(y,w,b)+e[u]+f[u];i=sigma(a)+maj(a,C,d);D=b;b=w;w=y;y=m+t|0;m=d;d=C;C=a;a=t+i|0}s=s+a|0;r=r+C|0;n=n+d|0;o=o+m|0;g=g+y|0;c=c+w|0;h=h+b|0;l=l+D|0}var p;return new Uint8Array([s>>24&255,s>>16&255,s>>8&255,255&s,r>>24&255,r>>16&255,r>>8&255,255&r,n>>24&255,n>>16&255,n>>8&255,255&n,o>>24&255,o>>16&255,o>>8&255,255&o,g>>24&255,g>>16&255,g>>8&255,255&g,c>>24&255,c>>16&255,c>>8&255,255&c,h>>24&255,h>>16&255,h>>8&255,255&h,l>>24&255,l>>16&255,l>>8&255,255&l])}}(),Ys=function calculateSHA512Closure(){function ch(e,t,i,a,s){e.assign(t);e.and(i);s.assign(t);s.not();s.and(a);e.xor(s)}function maj(e,t,i,a,s){e.assign(t);e.and(i);s.assign(t);s.and(a);e.xor(s);s.assign(i);s.and(a);e.xor(s)}function sigma(e,t,i){e.assign(t);e.rotateRight(28);i.assign(t);i.rotateRight(34);e.xor(i);i.assign(t);i.rotateRight(39);e.xor(i)}function sigmaPrime(e,t,i){e.assign(t);e.rotateRight(14);i.assign(t);i.rotateRight(18);e.xor(i);i.assign(t);i.rotateRight(41);e.xor(i)}function littleSigma(e,t,i){e.assign(t);e.rotateRight(1);i.assign(t);i.rotateRight(8);e.xor(i);i.assign(t);i.shiftRight(7);e.xor(i)}function littleSigmaPrime(e,t,i){e.assign(t);e.rotateRight(19);i.assign(t);i.rotateRight(61);e.xor(i);i.assign(t);i.shiftRight(6);e.xor(i)}const e=[new Word64(1116352408,3609767458),new Word64(1899447441,602891725),new Word64(3049323471,3964484399),new Word64(3921009573,2173295548),new Word64(961987163,4081628472),new Word64(1508970993,3053834265),new Word64(2453635748,2937671579),new Word64(2870763221,3664609560),new Word64(3624381080,2734883394),new Word64(310598401,1164996542),new Word64(607225278,1323610764),new Word64(1426881987,3590304994),new Word64(1925078388,4068182383),new Word64(2162078206,991336113),new Word64(2614888103,633803317),new Word64(3248222580,3479774868),new Word64(3835390401,2666613458),new Word64(4022224774,944711139),new Word64(264347078,2341262773),new Word64(604807628,2007800933),new Word64(770255983,1495990901),new Word64(1249150122,1856431235),new Word64(1555081692,3175218132),new Word64(1996064986,2198950837),new Word64(2554220882,3999719339),new Word64(2821834349,766784016),new Word64(2952996808,2566594879),new Word64(3210313671,3203337956),new Word64(3336571891,1034457026),new Word64(3584528711,2466948901),new Word64(113926993,3758326383),new Word64(338241895,168717936),new Word64(666307205,1188179964),new Word64(773529912,1546045734),new Word64(1294757372,1522805485),new Word64(1396182291,2643833823),new Word64(1695183700,2343527390),new Word64(1986661051,1014477480),new Word64(2177026350,1206759142),new Word64(2456956037,344077627),new Word64(2730485921,1290863460),new Word64(2820302411,3158454273),new Word64(3259730800,3505952657),new Word64(3345764771,106217008),new Word64(3516065817,3606008344),new Word64(3600352804,1432725776),new Word64(4094571909,1467031594),new Word64(275423344,851169720),new Word64(430227734,3100823752),new Word64(506948616,1363258195),new Word64(659060556,3750685593),new Word64(883997877,3785050280),new Word64(958139571,3318307427),new Word64(1322822218,3812723403),new Word64(1537002063,2003034995),new Word64(1747873779,3602036899),new Word64(1955562222,1575990012),new Word64(2024104815,1125592928),new Word64(2227730452,2716904306),new Word64(2361852424,442776044),new Word64(2428436474,593698344),new Word64(2756734187,3733110249),new Word64(3204031479,2999351573),new Word64(3329325298,3815920427),new Word64(3391569614,3928383900),new Word64(3515267271,566280711),new Word64(3940187606,3454069534),new Word64(4118630271,4000239992),new Word64(116418474,1914138554),new Word64(174292421,2731055270),new Word64(289380356,3203993006),new Word64(460393269,320620315),new Word64(685471733,587496836),new Word64(852142971,1086792851),new Word64(1017036298,365543100),new Word64(1126000580,2618297676),new Word64(1288033470,3409855158),new Word64(1501505948,4234509866),new Word64(1607167915,987167468),new Word64(1816402316,1246189591)];return function hash(t,i,a,s=!1){let r,n,o,g,c,h,l,C;if(s){r=new Word64(3418070365,3238371032);n=new Word64(1654270250,914150663);o=new Word64(2438529370,812702999);g=new Word64(355462360,4144912697);c=new Word64(1731405415,4290775857);h=new Word64(2394180231,1750603025);l=new Word64(3675008525,1694076839);C=new Word64(1203062813,3204075428)}else{r=new Word64(1779033703,4089235720);n=new Word64(3144134277,2227873595);o=new Word64(1013904242,4271175723);g=new Word64(2773480762,1595750129);c=new Word64(1359893119,2917565137);h=new Word64(2600822924,725511199);l=new Word64(528734635,4215389547);C=new Word64(1541459225,327033209)}const Q=128*Math.ceil((a+17)/128),E=new Uint8Array(Q);let u,d;for(u=0;u<a;++u)E[u]=t[i++];E[u++]=128;const f=Q-16;for(;u<f;)E[u++]=0;E[u++]=0;E[u++]=0;E[u++]=0;E[u++]=0;E[u++]=0;E[u++]=0;E[u++]=0;E[u++]=0;E[u++]=0;E[u++]=0;E[u++]=0;E[u++]=a>>>29&255;E[u++]=a>>21&255;E[u++]=a>>13&255;E[u++]=a>>5&255;E[u++]=a<<3&255;const p=new Array(80);for(u=0;u<80;u++)p[u]=new Word64(0,0);let m=new Word64(0,0),y=new Word64(0,0),w=new Word64(0,0),b=new Word64(0,0),D=new Word64(0,0),F=new Word64(0,0),S=new Word64(0,0),k=new Word64(0,0);const R=new Word64(0,0),N=new Word64(0,0),G=new Word64(0,0),x=new Word64(0,0);let M,U;for(u=0;u<Q;){for(d=0;d<16;++d){p[d].high=E[u]<<24|E[u+1]<<16|E[u+2]<<8|E[u+3];p[d].low=E[u+4]<<24|E[u+5]<<16|E[u+6]<<8|E[u+7];u+=8}for(d=16;d<80;++d){M=p[d];littleSigmaPrime(M,p[d-2],x);M.add(p[d-7]);littleSigma(G,p[d-15],x);M.add(G);M.add(p[d-16])}m.assign(r);y.assign(n);w.assign(o);b.assign(g);D.assign(c);F.assign(h);S.assign(l);k.assign(C);for(d=0;d<80;++d){R.assign(k);sigmaPrime(G,D,x);R.add(G);ch(G,D,F,S,x);R.add(G);R.add(e[d]);R.add(p[d]);sigma(N,m,x);maj(G,m,y,w,x);N.add(G);M=k;k=S;S=F;F=D;b.add(R);D=b;b=w;w=y;y=m;M.assign(R);M.add(N);m=M}r.add(m);n.add(y);o.add(w);g.add(b);c.add(D);h.add(F);l.add(S);C.add(k)}if(s){U=new Uint8Array(48);r.copyTo(U,0);n.copyTo(U,8);o.copyTo(U,16);g.copyTo(U,24);c.copyTo(U,32);h.copyTo(U,40)}else{U=new Uint8Array(64);r.copyTo(U,0);n.copyTo(U,8);o.copyTo(U,16);g.copyTo(U,24);c.copyTo(U,32);h.copyTo(U,40);l.copyTo(U,48);C.copyTo(U,56)}return U}}();class NullCipher{decryptBlock(e){return e}encrypt(e){return e}}class AESBaseCipher{constructor(){this.constructor===AESBaseCipher&&unreachable("Cannot initialize AESBaseCipher.");this._s=new Uint8Array([99,124,119,123,242,107,111,197,48,1,103,43,254,215,171,118,202,130,201,125,250,89,71,240,173,212,162,175,156,164,114,192,183,253,147,38,54,63,247,204,52,165,229,241,113,216,49,21,4,199,35,195,24,150,5,154,7,18,128,226,235,39,178,117,9,131,44,26,27,110,90,160,82,59,214,179,41,227,47,132,83,209,0,237,32,252,177,91,106,203,190,57,74,76,88,207,208,239,170,251,67,77,51,133,69,249,2,127,80,60,159,168,81,163,64,143,146,157,56,245,188,182,218,33,16,255,243,210,205,12,19,236,95,151,68,23,196,167,126,61,100,93,25,115,96,129,79,220,34,42,144,136,70,238,184,20,222,94,11,219,224,50,58,10,73,6,36,92,194,211,172,98,145,149,228,121,231,200,55,109,141,213,78,169,108,86,244,234,101,122,174,8,186,120,37,46,28,166,180,198,232,221,116,31,75,189,139,138,112,62,181,102,72,3,246,14,97,53,87,185,134,193,29,158,225,248,152,17,105,217,142,148,155,30,135,233,206,85,40,223,140,161,137,13,191,230,66,104,65,153,45,15,176,84,187,22]);this._inv_s=new Uint8Array([82,9,106,213,48,54,165,56,191,64,163,158,129,243,215,251,124,227,57,130,155,47,255,135,52,142,67,68,196,222,233,203,84,123,148,50,166,194,35,61,238,76,149,11,66,250,195,78,8,46,161,102,40,217,36,178,118,91,162,73,109,139,209,37,114,248,246,100,134,104,152,22,212,164,92,204,93,101,182,146,108,112,72,80,253,237,185,218,94,21,70,87,167,141,157,132,144,216,171,0,140,188,211,10,247,228,88,5,184,179,69,6,208,44,30,143,202,63,15,2,193,175,189,3,1,19,138,107,58,145,17,65,79,103,220,234,151,242,207,206,240,180,230,115,150,172,116,34,231,173,53,133,226,249,55,232,28,117,223,110,71,241,26,113,29,41,197,137,111,183,98,14,170,24,190,27,252,86,62,75,198,210,121,32,154,219,192,254,120,205,90,244,31,221,168,51,136,7,199,49,177,18,16,89,39,128,236,95,96,81,127,169,25,181,74,13,45,229,122,159,147,201,156,239,160,224,59,77,174,42,245,176,200,235,187,60,131,83,153,97,23,43,4,126,186,119,214,38,225,105,20,99,85,33,12,125]);this._mix=new Uint32Array([0,235474187,470948374,303765277,941896748,908933415,607530554,708780849,1883793496,2118214995,1817866830,1649639237,1215061108,1181045119,1417561698,1517767529,3767586992,4003061179,4236429990,4069246893,3635733660,3602770327,3299278474,3400528769,2430122216,2664543715,2362090238,2193862645,2835123396,2801107407,3035535058,3135740889,3678124923,3576870512,3341394285,3374361702,3810496343,3977675356,4279080257,4043610186,2876494627,2776292904,3076639029,3110650942,2472011535,2640243204,2403728665,2169303058,1001089995,899835584,666464733,699432150,59727847,226906860,530400753,294930682,1273168787,1172967064,1475418501,1509430414,1942435775,2110667444,1876241833,1641816226,2910219766,2743034109,2976151520,3211623147,2505202138,2606453969,2302690252,2269728455,3711829422,3543599269,3240894392,3475313331,3843699074,3943906441,4178062228,4144047775,1306967366,1139781709,1374988112,1610459739,1975683434,2076935265,1775276924,1742315127,1034867998,866637845,566021896,800440835,92987698,193195065,429456164,395441711,1984812685,2017778566,1784663195,1683407248,1315562145,1080094634,1383856311,1551037884,101039829,135050206,437757123,337553864,1042385657,807962610,573804783,742039012,2531067453,2564033334,2328828971,2227573024,2935566865,2700099354,3001755655,3168937228,3868552805,3902563182,4203181171,4102977912,3736164937,3501741890,3265478751,3433712980,1106041591,1340463100,1576976609,1408749034,2043211483,2009195472,1708848333,1809054150,832877231,1068351396,766945465,599762354,159417987,126454664,361929877,463180190,2709260871,2943682380,3178106961,3009879386,2572697195,2538681184,2236228733,2336434550,3509871135,3745345300,3441850377,3274667266,3910161971,3877198648,4110568485,4211818798,2597806476,2497604743,2261089178,2295101073,2733856160,2902087851,3202437046,2968011453,3936291284,3835036895,4136440770,4169408201,3535486456,3702665459,3467192302,3231722213,2051518780,1951317047,1716890410,1750902305,1113818384,1282050075,1584504582,1350078989,168810852,67556463,371049330,404016761,841739592,1008918595,775550814,540080725,3969562369,3801332234,4035489047,4269907996,3569255213,3669462566,3366754619,3332740144,2631065433,2463879762,2160117071,2395588676,2767645557,2868897406,3102011747,3069049960,202008497,33778362,270040487,504459436,875451293,975658646,675039627,641025152,2084704233,1917518562,1615861247,1851332852,1147550661,1248802510,1484005843,1451044056,933301370,967311729,733156972,632953703,260388950,25965917,328671808,496906059,1206477858,1239443753,1543208500,1441952575,2144161806,1908694277,1675577880,1842759443,3610369226,3644379585,3408119516,3307916247,4011190502,3776767469,4077384432,4245618683,2809771154,2842737049,3144396420,3043140495,2673705150,2438237621,2203032232,2370213795]);this._mixCol=new Uint8Array(256);for(let e=0;e<256;e++)this._mixCol[e]=e<128?e<<1:e<<1^27;this.buffer=new Uint8Array(16);this.bufferPosition=0}_expandKey(e){unreachable("Cannot call `_expandKey` on the base class")}_decrypt(e,t){let i,a,s;const r=new Uint8Array(16);r.set(e);for(let e=0,i=this._keySize;e<16;++e,++i)r[e]^=t[i];for(let e=this._cyclesOfRepetition-1;e>=1;--e){i=r[13];r[13]=r[9];r[9]=r[5];r[5]=r[1];r[1]=i;i=r[14];a=r[10];r[14]=r[6];r[10]=r[2];r[6]=i;r[2]=a;i=r[15];a=r[11];s=r[7];r[15]=r[3];r[11]=i;r[7]=a;r[3]=s;for(let e=0;e<16;++e)r[e]=this._inv_s[r[e]];for(let i=0,a=16*e;i<16;++i,++a)r[i]^=t[a];for(let e=0;e<16;e+=4){const t=this._mix[r[e]],a=this._mix[r[e+1]],s=this._mix[r[e+2]],n=this._mix[r[e+3]];i=t^a>>>8^a<<24^s>>>16^s<<16^n>>>24^n<<8;r[e]=i>>>24&255;r[e+1]=i>>16&255;r[e+2]=i>>8&255;r[e+3]=255&i}}i=r[13];r[13]=r[9];r[9]=r[5];r[5]=r[1];r[1]=i;i=r[14];a=r[10];r[14]=r[6];r[10]=r[2];r[6]=i;r[2]=a;i=r[15];a=r[11];s=r[7];r[15]=r[3];r[11]=i;r[7]=a;r[3]=s;for(let e=0;e<16;++e){r[e]=this._inv_s[r[e]];r[e]^=t[e]}return r}_encrypt(e,t){const i=this._s;let a,s,r;const n=new Uint8Array(16);n.set(e);for(let e=0;e<16;++e)n[e]^=t[e];for(let e=1;e<this._cyclesOfRepetition;e++){for(let e=0;e<16;++e)n[e]=i[n[e]];r=n[1];n[1]=n[5];n[5]=n[9];n[9]=n[13];n[13]=r;r=n[2];s=n[6];n[2]=n[10];n[6]=n[14];n[10]=r;n[14]=s;r=n[3];s=n[7];a=n[11];n[3]=n[15];n[7]=r;n[11]=s;n[15]=a;for(let e=0;e<16;e+=4){const t=n[e+0],i=n[e+1],s=n[e+2],r=n[e+3];a=t^i^s^r;n[e+0]^=a^this._mixCol[t^i];n[e+1]^=a^this._mixCol[i^s];n[e+2]^=a^this._mixCol[s^r];n[e+3]^=a^this._mixCol[r^t]}for(let i=0,a=16*e;i<16;++i,++a)n[i]^=t[a]}for(let e=0;e<16;++e)n[e]=i[n[e]];r=n[1];n[1]=n[5];n[5]=n[9];n[9]=n[13];n[13]=r;r=n[2];s=n[6];n[2]=n[10];n[6]=n[14];n[10]=r;n[14]=s;r=n[3];s=n[7];a=n[11];n[3]=n[15];n[7]=r;n[11]=s;n[15]=a;for(let e=0,i=this._keySize;e<16;++e,++i)n[e]^=t[i];return n}_decryptBlock2(e,t){const i=e.length;let a=this.buffer,s=this.bufferPosition;const r=[];let n=this.iv;for(let t=0;t<i;++t){a[s]=e[t];++s;if(s<16)continue;const i=this._decrypt(a,this._key);for(let e=0;e<16;++e)i[e]^=n[e];n=a;r.push(i);a=new Uint8Array(16);s=0}this.buffer=a;this.bufferLength=s;this.iv=n;if(0===r.length)return new Uint8Array(0);let o=16*r.length;if(t){const e=r.at(-1);let t=e[15];if(t<=16){for(let i=15,a=16-t;i>=a;--i)if(e[i]!==t){t=0;break}o-=t;r[r.length-1]=e.subarray(0,16-t)}}const g=new Uint8Array(o);for(let e=0,t=0,i=r.length;e<i;++e,t+=16)g.set(r[e],t);return g}decryptBlock(e,t,i=null){const a=e.length,s=this.buffer;let r=this.bufferPosition;if(i)this.iv=i;else{for(let t=0;r<16&&t<a;++t,++r)s[r]=e[t];if(r<16){this.bufferLength=r;return new Uint8Array(0)}this.iv=s;e=e.subarray(16)}this.buffer=new Uint8Array(16);this.bufferLength=0;this.decryptBlock=this._decryptBlock2;return this.decryptBlock(e,t)}encrypt(e,t){const i=e.length;let a=this.buffer,s=this.bufferPosition;const r=[];t||(t=new Uint8Array(16));for(let n=0;n<i;++n){a[s]=e[n];++s;if(s<16)continue;for(let e=0;e<16;++e)a[e]^=t[e];const i=this._encrypt(a,this._key);t=i;r.push(i);a=new Uint8Array(16);s=0}this.buffer=a;this.bufferLength=s;this.iv=t;if(0===r.length)return new Uint8Array(0);const n=16*r.length,o=new Uint8Array(n);for(let e=0,t=0,i=r.length;e<i;++e,t+=16)o.set(r[e],t);return o}}class AES128Cipher extends AESBaseCipher{constructor(e){super();this._cyclesOfRepetition=10;this._keySize=160;this._rcon=new Uint8Array([141,1,2,4,8,16,32,64,128,27,54,108,216,171,77,154,47,94,188,99,198,151,53,106,212,179,125,250,239,197,145,57,114,228,211,189,97,194,159,37,74,148,51,102,204,131,29,58,116,232,203,141,1,2,4,8,16,32,64,128,27,54,108,216,171,77,154,47,94,188,99,198,151,53,106,212,179,125,250,239,197,145,57,114,228,211,189,97,194,159,37,74,148,51,102,204,131,29,58,116,232,203,141,1,2,4,8,16,32,64,128,27,54,108,216,171,77,154,47,94,188,99,198,151,53,106,212,179,125,250,239,197,145,57,114,228,211,189,97,194,159,37,74,148,51,102,204,131,29,58,116,232,203,141,1,2,4,8,16,32,64,128,27,54,108,216,171,77,154,47,94,188,99,198,151,53,106,212,179,125,250,239,197,145,57,114,228,211,189,97,194,159,37,74,148,51,102,204,131,29,58,116,232,203,141,1,2,4,8,16,32,64,128,27,54,108,216,171,77,154,47,94,188,99,198,151,53,106,212,179,125,250,239,197,145,57,114,228,211,189,97,194,159,37,74,148,51,102,204,131,29,58,116,232,203,141]);this._key=this._expandKey(e)}_expandKey(e){const t=this._s,i=this._rcon,a=new Uint8Array(176);a.set(e);for(let e=16,s=1;e<176;++s){let r=a[e-3],n=a[e-2],o=a[e-1],g=a[e-4];r=t[r];n=t[n];o=t[o];g=t[g];r^=i[s];for(let t=0;t<4;++t){a[e]=r^=a[e-16];e++;a[e]=n^=a[e-16];e++;a[e]=o^=a[e-16];e++;a[e]=g^=a[e-16];e++}}return a}}class AES256Cipher extends AESBaseCipher{constructor(e){super();this._cyclesOfRepetition=14;this._keySize=224;this._key=this._expandKey(e)}_expandKey(e){const t=this._s,i=new Uint8Array(240);i.set(e);let a,s,r,n,o=1;for(let e=32,g=1;e<240;++g){if(e%32==16){a=t[a];s=t[s];r=t[r];n=t[n]}else if(e%32==0){a=i[e-3];s=i[e-2];r=i[e-1];n=i[e-4];a=t[a];s=t[s];r=t[r];n=t[n];a^=o;(o<<=1)>=256&&(o=255&(27^o))}for(let t=0;t<4;++t){i[e]=a^=i[e-32];e++;i[e]=s^=i[e-32];e++;i[e]=r^=i[e-32];e++;i[e]=n^=i[e-32];e++}}return i}}class PDF17{checkOwnerPassword(e,t,i,a){const s=new Uint8Array(e.length+56);s.set(e,0);s.set(t,e.length);s.set(i,e.length+t.length);return isArrayEqual(Hs(s,0,s.length),a)}checkUserPassword(e,t,i){const a=new Uint8Array(e.length+8);a.set(e,0);a.set(t,e.length);return isArrayEqual(Hs(a,0,a.length),i)}getOwnerKey(e,t,i,a){const s=new Uint8Array(e.length+56);s.set(e,0);s.set(t,e.length);s.set(i,e.length+t.length);const r=Hs(s,0,s.length);return new AES256Cipher(r).decryptBlock(a,!1,new Uint8Array(16))}getUserKey(e,t,i){const a=new Uint8Array(e.length+8);a.set(e,0);a.set(t,e.length);const s=Hs(a,0,a.length);return new AES256Cipher(s).decryptBlock(i,!1,new Uint8Array(16))}}class PDF20{_hash(e,t,i){let a=Hs(t,0,t.length).subarray(0,32),s=[0],r=0;for(;r<64||s.at(-1)>r-32;){const t=e.length+a.length+i.length,c=new Uint8Array(t);let h=0;c.set(e,h);h+=e.length;c.set(a,h);h+=a.length;c.set(i,h);const l=new Uint8Array(64*t);for(let e=0,i=0;e<64;e++,i+=t)l.set(c,i);s=new AES128Cipher(a.subarray(0,16)).encrypt(l,a.subarray(16,32));const C=s.slice(0,16).reduce(((e,t)=>e+t),0)%3;0===C?a=Hs(s,0,s.length):1===C?a=(n=s,o=0,g=s.length,Ys(n,o,g,!0)):2===C&&(a=Ys(s,0,s.length));r++}var n,o,g;return a.subarray(0,32)}checkOwnerPassword(e,t,i,a){const s=new Uint8Array(e.length+56);s.set(e,0);s.set(t,e.length);s.set(i,e.length+t.length);return isArrayEqual(this._hash(e,s,i),a)}checkUserPassword(e,t,i){const a=new Uint8Array(e.length+8);a.set(e,0);a.set(t,e.length);return isArrayEqual(this._hash(e,a,[]),i)}getOwnerKey(e,t,i,a){const s=new Uint8Array(e.length+56);s.set(e,0);s.set(t,e.length);s.set(i,e.length+t.length);const r=this._hash(e,s,i);return new AES256Cipher(r).decryptBlock(a,!1,new Uint8Array(16))}getUserKey(e,t,i){const a=new Uint8Array(e.length+8);a.set(e,0);a.set(t,e.length);const s=this._hash(e,a,[]);return new AES256Cipher(s).decryptBlock(i,!1,new Uint8Array(16))}}class CipherTransform{constructor(e,t){this.StringCipherConstructor=e;this.StreamCipherConstructor=t}createStream(e,t){const i=new this.StreamCipherConstructor;return new DecryptStream(e,t,(function cipherTransformDecryptStream(e,t){return i.decryptBlock(e,t)}))}decryptString(e){const t=new this.StringCipherConstructor;let i=stringToBytes(e);i=t.decryptBlock(i,!0);return bytesToString(i)}encryptString(e){const t=new this.StringCipherConstructor;if(t instanceof AESBaseCipher){const i=16-e.length%16;e+=String.fromCharCode(i).repeat(i);const a=new Uint8Array(16);if("undefined"!=typeof crypto)crypto.getRandomValues(a);else for(let e=0;e<16;e++)a[e]=Math.floor(256*Math.random());let s=stringToBytes(e);s=t.encrypt(s,a);const r=new Uint8Array(16+s.length);r.set(a);r.set(s,16);return bytesToString(r)}let i=stringToBytes(e);i=t.encrypt(i);return bytesToString(i)}}class CipherTransformFactory{static#k=new Uint8Array([40,191,78,94,78,117,138,65,100,0,78,86,255,250,1,8,46,46,0,182,208,104,62,128,47,12,169,254,100,83,105,122]);#R(e,t,i,a,s,r,n,o,g,c,h,l){if(t){const e=Math.min(127,t.length);t=t.subarray(0,e)}else t=[];const C=6===e?new PDF20:new PDF17;return C.checkUserPassword(t,o,n)?C.getUserKey(t,g,h):t.length&&C.checkOwnerPassword(t,a,r,i)?C.getOwnerKey(t,s,r,c):null}#N(e,t,i,a,s,r,n,o){const g=40+i.length+e.length,c=new Uint8Array(g);let h,l,C=0;if(t){l=Math.min(32,t.length);for(;C<l;++C)c[C]=t[C]}h=0;for(;C<32;)c[C++]=CipherTransformFactory.#k[h++];for(h=0,l=i.length;h<l;++h)c[C++]=i[h];c[C++]=255&s;c[C++]=s>>8&255;c[C++]=s>>16&255;c[C++]=s>>>24&255;for(h=0,l=e.length;h<l;++h)c[C++]=e[h];if(r>=4&&!o){c[C++]=255;c[C++]=255;c[C++]=255;c[C++]=255}let Q=Js(c,0,C);const E=n>>3;if(r>=3)for(h=0;h<50;++h)Q=Js(Q,0,E);const u=Q.subarray(0,E);let d,f;if(r>=3){for(C=0;C<32;++C)c[C]=CipherTransformFactory.#k[C];for(h=0,l=e.length;h<l;++h)c[C++]=e[h];d=new ARCFourCipher(u);f=d.encryptBlock(Js(c,0,C));l=u.length;const t=new Uint8Array(l);for(h=1;h<=19;++h){for(let e=0;e<l;++e)t[e]=u[e]^h;d=new ARCFourCipher(t);f=d.encryptBlock(f)}for(h=0,l=f.length;h<l;++h)if(a[h]!==f[h])return null}else{d=new ARCFourCipher(u);f=d.encryptBlock(CipherTransformFactory.#k);for(h=0,l=f.length;h<l;++h)if(a[h]!==f[h])return null}return u}#G(e,t,i,a){const s=new Uint8Array(32);let r=0;const n=Math.min(32,e.length);for(;r<n;++r)s[r]=e[r];let o=0;for(;r<32;)s[r++]=CipherTransformFactory.#k[o++];let g=Js(s,0,r);const c=a>>3;if(i>=3)for(o=0;o<50;++o)g=Js(g,0,g.length);let h,l;if(i>=3){l=t;const e=new Uint8Array(c);for(o=19;o>=0;o--){for(let t=0;t<c;++t)e[t]=g[t]^o;h=new ARCFourCipher(e);l=h.encryptBlock(l)}}else{h=new ARCFourCipher(g.subarray(0,c));l=h.encryptBlock(t)}return l}#x(e,t,i,a=!1){const s=new Uint8Array(i.length+9),r=i.length;let n;for(n=0;n<r;++n)s[n]=i[n];s[n++]=255&e;s[n++]=e>>8&255;s[n++]=e>>16&255;s[n++]=255&t;s[n++]=t>>8&255;if(a){s[n++]=115;s[n++]=65;s[n++]=108;s[n++]=84}return Js(s,0,n).subarray(0,Math.min(i.length+5,16))}#M(e,t,i,a,s){if(!(t instanceof Name))throw new FormatError("Invalid crypt filter name.");const r=this,n=e.get(t.name),o=n?.get("CFM");if(!o||"None"===o.name)return function(){return new NullCipher};if("V2"===o.name)return function(){return new ARCFourCipher(r.#x(i,a,s,!1))};if("AESV2"===o.name)return function(){return new AES128Cipher(r.#x(i,a,s,!0))};if("AESV3"===o.name)return function(){return new AES256Cipher(s)};throw new FormatError("Unknown crypto method")}constructor(e,t,i){const a=e.get("Filter");if(!isName(a,"Standard"))throw new FormatError("unknown encryption method");this.filterName=a.name;this.dict=e;const s=e.get("V");if(!Number.isInteger(s)||1!==s&&2!==s&&4!==s&&5!==s)throw new FormatError("unsupported encryption algorithm");this.algorithm=s;let r=e.get("Length");if(!r)if(s<=3)r=40;else{const t=e.get("CF"),i=e.get("StmF");if(t instanceof Dict&&i instanceof Name){t.suppressEncryption=!0;const e=t.get(i.name);r=e?.get("Length")||128;r<40&&(r<<=3)}}if(!Number.isInteger(r)||r<40||r%8!=0)throw new FormatError("invalid key length");const n=stringToBytes(e.get("O")),o=stringToBytes(e.get("U")),g=n.subarray(0,32),c=o.subarray(0,32),h=e.get("P"),l=e.get("R"),C=(4===s||5===s)&&!1!==e.get("EncryptMetadata");this.encryptMetadata=C;const Q=stringToBytes(t);let E,u;if(i){if(6===l)try{i=utf8StringToString(i)}catch{warn("CipherTransformFactory: Unable to convert UTF8 encoded password.")}E=stringToBytes(i)}if(5!==s)u=this.#N(Q,E,g,c,h,l,r,C);else{const t=n.subarray(32,40),i=n.subarray(40,48),a=o.subarray(0,48),s=o.subarray(32,40),r=o.subarray(40,48),h=stringToBytes(e.get("OE")),C=stringToBytes(e.get("UE")),Q=stringToBytes(e.get("Perms"));u=this.#R(l,E,g,t,i,a,c,s,r,h,C,Q)}if(!u&&!i)throw new PasswordException("No password given",it);if(!u&&i){const e=this.#G(E,g,l,r);u=this.#N(Q,e,g,c,h,l,r,C)}if(!u)throw new PasswordException("Incorrect Password",at);this.encryptionKey=u;if(s>=4){const t=e.get("CF");t instanceof Dict&&(t.suppressEncryption=!0);this.cf=t;this.stmf=e.get("StmF")||Name.get("Identity");this.strf=e.get("StrF")||Name.get("Identity");this.eff=e.get("EFF")||this.stmf}}createCipherTransform(e,t){if(4===this.algorithm||5===this.algorithm)return new CipherTransform(this.#M(this.cf,this.strf,e,t,this.encryptionKey),this.#M(this.cf,this.stmf,e,t,this.encryptionKey));const i=this.#x(e,t,this.encryptionKey,!1),cipherConstructor=function(){return new ARCFourCipher(i)};return new CipherTransform(cipherConstructor,cipherConstructor)}}async function writeObject(e,t,i,{encrypt:a=null}){const s=a?.createCipherTransform(e.num,e.gen);i.push(`${e.num} ${e.gen} obj\n`);t instanceof Dict?await writeDict(t,i,s):t instanceof BaseStream?await writeStream(t,i,s):(Array.isArray(t)||ArrayBuffer.isView(t))&&await writeArray(t,i,s);i.push("\nendobj\n")}async function writeDict(e,t,i){t.push("<<");for(const a of e.getKeys()){t.push(` /${escapePDFName(a)} `);await writeValue(e.getRaw(a),t,i)}t.push(">>")}async function writeStream(e,t,i){let a=e.getBytes();const{dict:s}=e,[r,n]=await Promise.all([s.getAsync("Filter"),s.getAsync("DecodeParms")]),o=isName(Array.isArray(r)?await s.xref.fetchIfRefAsync(r[0]):r,"FlateDecode");if(a.length>=256||o)try{const e=new CompressionStream("deflate"),t=e.writable.getWriter();t.write(a);t.close();const i=await new Response(e.readable).arrayBuffer();a=new Uint8Array(i);let g,c;if(r){if(!o){g=Array.isArray(r)?[Name.get("FlateDecode"),...r]:[Name.get("FlateDecode"),r];n&&(c=Array.isArray(n)?[null,...n]:[null,n])}}else g=Name.get("FlateDecode");g&&s.set("Filter",g);c&&s.set("DecodeParms",c)}catch(e){info(`writeStream - cannot compress data: "${e}".`)}let g=bytesToString(a);i&&(g=i.encryptString(g));s.set("Length",g.length);await writeDict(s,t,i);t.push(" stream\n",g,"\nendstream")}async function writeArray(e,t,i){t.push("[");let a=!0;for(const s of e){a?a=!1:t.push(" ");await writeValue(s,t,i)}t.push("]")}async function writeValue(e,t,i){if(e instanceof Name)t.push(`/${escapePDFName(e.name)}`);else if(e instanceof Ref)t.push(`${e.num} ${e.gen} R`);else if(Array.isArray(e)||ArrayBuffer.isView(e))await writeArray(e,t,i);else if("string"==typeof e){i&&(e=i.encryptString(e));t.push(`(${escapeString(e)})`)}else"number"==typeof e?t.push(numberToString(e)):"boolean"==typeof e?t.push(e.toString()):e instanceof Dict?await writeDict(e,t,i):e instanceof BaseStream?await writeStream(e,t,i):null===e?t.push("null"):warn(`Unhandled value in writer: ${typeof e}, please file a bug.`)}function writeInt(e,t,i,a){for(let s=t+i-1;s>i-1;s--){a[s]=255&e;e>>=8}return i+t}function writeString(e,t,i){for(let a=0,s=e.length;a<s;a++)i[t+a]=255&e.charCodeAt(a)}function updateXFA({xfaData:e,xfaDatasetsRef:t,newRefs:i,xref:a}){if(null===e){e=function writeXFADataForAcroform(e,t){const i=new SimpleXMLParser({hasAttributes:!0}).parseFromString(e);for(const{xfa:e}of t){if(!e)continue;const{path:t,value:a}=e;if(!t)continue;const s=parseXFAPath(t);let r=i.documentElement.searchNode(s,0);!r&&s.length>1&&(r=i.documentElement.searchNode([s.at(-1)],0));r?r.childNodes=Array.isArray(a)?a.map((e=>new SimpleDOMNode("value",e))):[new SimpleDOMNode("#text",a)]:warn(`Node not found for path: ${t}`)}const a=[];i.documentElement.dump(a);return a.join("")}(a.fetchIfRef(t).getString(),i)}const s=a.encrypt;if(s){e=s.createCipherTransform(t.num,t.gen).encryptString(e)}const r=`${t.num} ${t.gen} obj\n<< /Type /EmbeddedFile /Length ${e.length}>>\nstream\n`+e+"\nendstream\nendobj\n";i.push({ref:t,data:r})}function getIndexes(e){const t=[];for(const{ref:i}of e)i.num===t.at(-2)+t.at(-1)?t[t.length-1]+=1:t.push(i.num,1);return t}function computeIDs(e,t,i){if(Array.isArray(t.fileIds)&&t.fileIds.length>0){const a=function computeMD5(e,t){const i=Math.floor(Date.now()/1e3),a=t.filename||"",s=[i.toString(),a,e.toString()];let r=s.reduce(((e,t)=>e+t.length),0);for(const e of Object.values(t.info)){s.push(e);r+=e.length}const n=new Uint8Array(r);let o=0;for(const e of s){writeString(e,o,n);o+=e.length}return bytesToString(Js(n))}(e,t);i.set("ID",[t.fileIds[0],a])}}async function incrementalUpdate({originalData:e,xrefInfo:t,newRefs:i,xref:a=null,hasXfa:s=!1,xfaDatasetsRef:r=null,hasXfaDatasetsEntry:n=!1,needAppearances:o,acroFormRef:g=null,acroForm:c=null,xfaData:h=null,useXrefStream:l=!1}){await async function updateAcroform({xref:e,acroForm:t,acroFormRef:i,hasXfa:a,hasXfaDatasetsEntry:s,xfaDatasetsRef:r,needAppearances:n,newRefs:o}){!a||s||r||warn("XFA - Cannot save it");if(!n&&(!a||!r||s))return;const g=t.clone();if(a&&!s){const e=t.get("XFA").slice();e.splice(2,0,"datasets");e.splice(3,0,r);g.set("XFA",e)}n&&g.set("NeedAppearances",!0);const c=[];await writeObject(i,g,c,e);o.push({ref:i,data:c.join("")})}({xref:a,acroForm:c,acroFormRef:g,hasXfa:s,hasXfaDatasetsEntry:n,xfaDatasetsRef:r,needAppearances:o,newRefs:i});s&&updateXFA({xfaData:h,xfaDatasetsRef:r,newRefs:i,xref:a});const C=[];let Q=e.length;const E=e.at(-1);if(10!==E&&13!==E){C.push("\n");Q+=1}const u=function getTrailerDict(e,t,i){const a=new Dict(null);a.set("Prev",e.startXRef);const s=e.newRef;if(i){t.push({ref:s,data:""});a.set("Size",s.num+1);a.set("Type",Name.get("XRef"))}else a.set("Size",s.num);null!==e.rootRef&&a.set("Root",e.rootRef);null!==e.infoRef&&a.set("Info",e.infoRef);null!==e.encryptRef&&a.set("Encrypt",e.encryptRef);return a}(t,i,l);i=i.sort(((e,t)=>e.ref.num-t.ref.num));for(const{data:e}of i)null!==e&&C.push(e);await(l?async function getXRefStreamTable(e,t,i,a,s){const r=[];let n=0,o=0;for(const{ref:e,data:a}of i){let i;n=Math.max(n,t);if(null!==a){i=Math.min(e.gen,65535);r.push([1,t,i]);t+=a.length}else{i=Math.min(e.gen+1,65535);r.push([0,0,i])}o=Math.max(o,i)}a.set("Index",getIndexes(i));const g=[1,getSizeInBytes(n),getSizeInBytes(o)];a.set("W",g);computeIDs(t,e,a);const c=g.reduce(((e,t)=>e+t),0),h=new Uint8Array(c*r.length),l=new Stream(h);l.dict=a;let C=0;for(const[e,t,i]of r){C=writeInt(e,g[0],C,h);C=writeInt(t,g[1],C,h);C=writeInt(i,g[2],C,h)}await writeObject(e.newRef,l,s,{});s.push("startxref\n",t.toString(),"\n%%EOF\n")}(t,Q,i,u,C):async function getXRefTable(e,t,i,a,s){s.push("xref\n");const r=getIndexes(i);let n=0;for(const{ref:e,data:a}of i){if(e.num===r[n]){s.push(`${r[n]} ${r[n+1]}\n`);n+=2}if(null!==a){s.push(`${t.toString().padStart(10,"0")} ${Math.min(e.gen,65535).toString().padStart(5,"0")} n\r\n`);t+=a.length}else s.push(`0000000000 ${Math.min(e.gen+1,65535).toString().padStart(5,"0")} f\r\n`)}computeIDs(t,e,a);s.push("trailer\n");await writeDict(a,s);s.push("\nstartxref\n",t.toString(),"\n%%EOF\n")}(t,Q,i,u,C));const d=C.reduce(((e,t)=>e+t.length),e.length),f=new Uint8Array(d);f.set(e);let p=e.length;for(const e of C){writeString(e,p,f);p+=e.length}return f}const vs=1,Ks=2,Ts=3,qs=4,Os=5;class StructTreeRoot{constructor(e,t){this.dict=e;this.ref=t instanceof Ref?t:null;this.roleMap=new Map;this.structParentIds=null}init(){this.readRoleMap()}#U(e,t,i){if(!(e instanceof Ref)||t<0)return;this.structParentIds||=new RefSetCache;let a=this.structParentIds.get(e);if(!a){a=[];this.structParentIds.put(e,a)}a.push([t,i])}addAnnotationIdToPage(e,t){this.#U(e,t,qs)}readRoleMap(){const e=this.dict.get("RoleMap");e instanceof Dict&&e.forEach(((e,t)=>{t instanceof Name&&this.roleMap.set(e,t.name)}))}static async canCreateStructureTree({catalogRef:e,pdfManager:t,newAnnotationsByPage:i}){if(!(e instanceof Ref)){warn("Cannot save the struct tree: no catalog reference.");return!1}let a=0,s=!0;for(const[e,r]of i){const{ref:i}=await t.getPage(e);if(!(i instanceof Ref)){warn(`Cannot save the struct tree: page ${e} has no ref.`);s=!0;break}for(const e of r)if(e.accessibilityData?.type){e.parentTreeId=a++;s=!1}}if(s){for(const e of i.values())for(const t of e)delete t.parentTreeId;return!1}return!0}static async createStructureTree({newAnnotationsByPage:e,xref:t,catalogRef:i,pdfManager:a,newRefs:s}){const r=a.catalog.cloneDict(),n=new RefSetCache;n.put(i,r);const o=t.getNewTemporaryRef();r.set("StructTreeRoot",o);const g=new Dict(t);g.set("Type",Name.get("StructTreeRoot"));const c=t.getNewTemporaryRef();g.set("ParentTree",c);const h=[];g.set("K",h);n.put(o,g);const l=new Dict(t),C=[];l.set("Nums",C);const Q=await this.#L({newAnnotationsByPage:e,structTreeRootRef:o,kids:h,nums:C,xref:t,pdfManager:a,cache:n});g.set("ParentTreeNextKey",Q);n.put(c,l);const E=[];for(const[e,i]of n.items()){E.length=0;await writeObject(e,i,E,t);s.push({ref:e,data:E.join("")})}}async canUpdateStructTree({pdfManager:e,xref:t,newAnnotationsByPage:i}){if(!this.ref){warn("Cannot update the struct tree: no root reference.");return!1}let a=this.dict.get("ParentTreeNextKey");if(!Number.isInteger(a)||a<0){warn("Cannot update the struct tree: invalid next key.");return!1}const s=this.dict.get("ParentTree");if(!(s instanceof Dict)){warn("Cannot update the struct tree: ParentTree isn't a dict.");return!1}const r=s.get("Nums");if(!Array.isArray(r)){warn("Cannot update the struct tree: nums isn't an array.");return!1}const n=new NumberTree(s,t);for(const t of i.keys()){const{pageDict:i}=await e.getPage(t);if(!i.has("StructParents"))continue;const a=i.get("StructParents");if(!Number.isInteger(a)||!Array.isArray(n.get(a))){warn(`Cannot save the struct tree: page ${t} has a wrong id.`);return!1}}let o=!0;for(const[t,s]of i){const{pageDict:i}=await e.getPage(t);StructTreeRoot.#J({elements:s,xref:this.dict.xref,pageDict:i,numberTree:n});for(const e of s)if(e.accessibilityData?.type){e.parentTreeId=a++;o=!1}}if(o){for(const e of i.values())for(const t of e){delete t.parentTreeId;delete t.structTreeParent}return!1}return!0}async updateStructureTree({newAnnotationsByPage:e,pdfManager:t,newRefs:i}){const a=this.dict.xref,s=this.dict.clone(),r=this.ref,n=new RefSetCache;n.put(r,s);let o,g=s.getRaw("ParentTree");if(g instanceof Ref)o=a.fetch(g);else{o=g;g=a.getNewTemporaryRef();s.set("ParentTree",g)}o=o.clone();n.put(g,o);let c=o.getRaw("Nums"),h=null;if(c instanceof Ref){h=c;c=a.fetch(h)}c=c.slice();h||o.set("Nums",c);const l=await StructTreeRoot.#L({newAnnotationsByPage:e,structTreeRootRef:r,kids:null,nums:c,xref:a,pdfManager:t,cache:n});s.set("ParentTreeNextKey",l);h&&n.put(h,c);const C=[];for(const[e,t]of n.items()){C.length=0;await writeObject(e,t,C,a);i.push({ref:e,data:C.join("")})}}static async#L({newAnnotationsByPage:e,structTreeRootRef:t,kids:i,nums:a,xref:s,pdfManager:r,cache:n}){const o=Name.get("OBJR");let g=-1/0;for(const[c,h]of e){const{ref:e}=await r.getPage(c),l=e instanceof Ref;for(const{accessibilityData:r,ref:c,parentTreeId:C,structTreeParent:Q}of h){if(!r?.type)continue;const{type:h,title:E,lang:u,alt:d,expanded:f,actualText:p}=r;g=Math.max(g,C);const m=s.getNewTemporaryRef(),y=new Dict(s);y.set("S",Name.get(h));E&&y.set("T",E);u&&y.set("Lang",u);d&&y.set("Alt",d);f&&y.set("E",f);p&&y.set("ActualText",p);await this.#H({structTreeParent:Q,tagDict:y,newTagRef:m,structTreeRootRef:t,fallbackKids:i,xref:s,cache:n});const w=new Dict(s);y.set("K",w);w.set("Type",o);l&&w.set("Pg",e);w.set("Obj",c);n.put(m,y);a.push(C,m)}}return g+1}static#J({elements:e,xref:t,pageDict:i,numberTree:a}){const s=new Map;for(const t of e)if(t.structTreeParentId){const e=parseInt(t.structTreeParentId.split("_mc")[1],10);let i=s.get(e);if(!i){i=[];s.set(e,i)}i.push(t)}const r=i.get("StructParents");if(!Number.isInteger(r))return;const n=a.get(r),updateElement=(e,i,a)=>{const r=s.get(e);if(r){const e=i.getRaw("P"),s=t.fetchIfRef(e);if(e instanceof Ref&&s instanceof Dict){const e={ref:a,dict:i};for(const t of r)t.structTreeParent=e}return!0}return!1};for(const e of n){if(!(e instanceof Ref))continue;const i=t.fetch(e),a=i.get("K");if(Number.isInteger(a))updateElement(a,i,e);else if(Array.isArray(a))for(let s of a){s=t.fetchIfRef(s);if(Number.isInteger(s)&&updateElement(s,i,e))break;if(!(s instanceof Dict))continue;if(!isName(s.get("Type"),"MCR"))break;const a=s.get("MCID");if(Number.isInteger(a)&&updateElement(a,i,e))break}}}static async#H({structTreeParent:e,tagDict:t,newTagRef:i,structTreeRootRef:a,fallbackKids:s,xref:r,cache:n}){let o,g=null;if(e){({ref:g}=e);o=e.dict.getRaw("P")||a}else o=a;t.set("P",o);const c=r.fetchIfRef(o);if(!c){s.push(i);return}let h=n.get(o);if(!h){h=c.clone();n.put(o,h)}const l=h.getRaw("K");let C=l instanceof Ref?n.get(l):null;if(!C){C=r.fetchIfRef(l);C=Array.isArray(C)?C.slice():[l];const e=r.getNewTemporaryRef();h.set("K",e);n.put(e,C)}const Q=C.indexOf(g);C.splice(Q>=0?Q+1:C.length,0,i)}}class StructElementNode{constructor(e,t){this.tree=e;this.dict=t;this.kids=[];this.parseKids()}get role(){const e=this.dict.get("S"),t=e instanceof Name?e.name:"",{root:i}=this.tree;return i.roleMap.has(t)?i.roleMap.get(t):t}parseKids(){let e=null;const t=this.dict.getRaw("Pg");t instanceof Ref&&(e=t.toString());const i=this.dict.get("K");if(Array.isArray(i))for(const t of i){const i=this.parseKid(e,t);i&&this.kids.push(i)}else{const t=this.parseKid(e,i);t&&this.kids.push(t)}}parseKid(e,t){if(Number.isInteger(t))return this.tree.pageDict.objId!==e?null:new StructElement({type:vs,mcid:t,pageObjId:e});let i=null;t instanceof Ref?i=this.dict.xref.fetch(t):t instanceof Dict&&(i=t);if(!i)return null;const a=i.getRaw("Pg");a instanceof Ref&&(e=a.toString());const s=i.get("Type")instanceof Name?i.get("Type").name:null;if("MCR"===s){if(this.tree.pageDict.objId!==e)return null;const t=i.getRaw("Stm");return new StructElement({type:Ks,refObjId:t instanceof Ref?t.toString():null,pageObjId:e,mcid:i.get("MCID")})}if("OBJR"===s){if(this.tree.pageDict.objId!==e)return null;const t=i.getRaw("Obj");return new StructElement({type:Ts,refObjId:t instanceof Ref?t.toString():null,pageObjId:e})}return new StructElement({type:Os,dict:i})}}class StructElement{constructor({type:e,dict:t=null,mcid:i=null,pageObjId:a=null,refObjId:s=null}){this.type=e;this.dict=t;this.mcid=i;this.pageObjId=a;this.refObjId=s;this.parentNode=null}}class StructTreePage{constructor(e,t){this.root=e;this.rootDict=e?e.dict:null;this.pageDict=t;this.nodes=[]}parse(e){if(!this.root||!this.rootDict)return;const t=this.rootDict.get("ParentTree");if(!t)return;const i=this.pageDict.get("StructParents"),a=e instanceof Ref&&this.root.structParentIds?.get(e);if(!Number.isInteger(i)&&!a)return;const s=new Map,r=new NumberTree(t,this.rootDict.xref);if(Number.isInteger(i)){const e=r.get(i);if(Array.isArray(e))for(const t of e)t instanceof Ref&&this.addNode(this.rootDict.xref.fetch(t),s)}if(a)for(const[e,t]of a){const i=r.get(e);if(i){const e=this.addNode(this.rootDict.xref.fetchIfRef(i),s);1===e?.kids?.length&&e.kids[0].type===Ts&&(e.kids[0].type=t)}}}addNode(e,t,i=0){if(i>40){warn("StructTree MAX_DEPTH reached.");return null}if(t.has(e))return t.get(e);const a=new StructElementNode(this,e);t.set(e,a);const s=e.get("P");if(!s||isName(s.get("Type"),"StructTreeRoot")){this.addTopLevelNode(e,a)||t.delete(e);return a}const r=this.addNode(s,t,i+1);if(!r)return a;let n=!1;for(const t of r.kids)if(t.type===Os&&t.dict===e){t.parentNode=a;n=!0}n||t.delete(e);return a}addTopLevelNode(e,t){const i=this.rootDict.get("K");if(!i)return!1;if(i instanceof Dict){if(i.objId!==e.objId)return!1;this.nodes[0]=t;return!0}if(!Array.isArray(i))return!0;let a=!1;for(let s=0;s<i.length;s++){const r=i[s];if(r?.toString()===e.objId){this.nodes[s]=t;a=!0}}return a}get serializable(){function nodeToSerializable(e,t,i=0){if(i>40){warn("StructTree too deep to be fully serialized.");return}const a=Object.create(null);a.role=e.role;a.children=[];t.children.push(a);const s=e.dict.get("Alt");"string"==typeof s&&(a.alt=stringToPDFString(s));const r=e.dict.get("Lang");"string"==typeof r&&(a.lang=stringToPDFString(r));for(const t of e.kids){const e=t.type===Os?t.parentNode:null;e?nodeToSerializable(e,a,i+1):t.type===vs||t.type===Ks?a.children.push({type:"content",id:`p${t.pageObjId}_mc${t.mcid}`}):t.type===Ts?a.children.push({type:"object",id:t.refObjId}):t.type===qs&&a.children.push({type:"annotation",id:`pdfjs_internal_id_${t.refObjId}`})}}const e=Object.create(null);e.children=[];e.role="Root";for(const t of this.nodes)t&&nodeToSerializable(t,e);return e}}function isValidExplicitDest(e){if(!Array.isArray(e)||e.length<2)return!1;const[t,i,...a]=e;if(!(t instanceof Ref||Number.isInteger(t)))return!1;if(!(i instanceof Name))return!1;let s=!0;switch(i.name){case"XYZ":if(3!==a.length)return!1;break;case"Fit":case"FitB":return 0===a.length;case"FitH":case"FitBH":case"FitV":case"FitBV":if(1!==a.length)return!1;break;case"FitR":if(4!==a.length)return!1;s=!1;break;default:return!1}for(const e of a)if(!("number"==typeof e||s&&null===e))return!1;return!0}function fetchDest(e){e instanceof Dict&&(e=e.get("D"));return isValidExplicitDest(e)?e:null}function fetchRemoteDest(e){let t=e.get("D");if(t){t instanceof Name&&(t=t.name);if("string"==typeof t)return stringToPDFString(t);if(isValidExplicitDest(t))return JSON.stringify(t)}return null}class Catalog{constructor(e,t){this.pdfManager=e;this.xref=t;this._catDict=t.getCatalogObj();if(!(this._catDict instanceof Dict))throw new FormatError("Catalog object is not a dictionary.");this.toplevelPagesDict;this._actualNumPages=null;this.fontCache=new RefSetCache;this.builtInCMapCache=new Map;this.standardFontDataCache=new Map;this.globalImageCache=new GlobalImageCache;this.pageKidsCountCache=new RefSetCache;this.pageIndexCache=new RefSetCache;this.nonBlendModesSet=new RefSet;this.systemFontCache=new Map}cloneDict(){return this._catDict.clone()}get version(){const e=this._catDict.get("Version");if(e instanceof Name){if(Dt.test(e.name))return shadow(this,"version",e.name);warn(`Invalid PDF catalog version: ${e.name}`)}return shadow(this,"version",null)}get lang(){const e=this._catDict.get("Lang");return shadow(this,"lang",e&&"string"==typeof e?stringToPDFString(e):null)}get needsRendering(){const e=this._catDict.get("NeedsRendering");return shadow(this,"needsRendering","boolean"==typeof e&&e)}get collection(){let e=null;try{const t=this._catDict.get("Collection");t instanceof Dict&&t.size>0&&(e=t)}catch(e){if(e instanceof MissingDataException)throw e;info("Cannot fetch Collection entry; assuming no collection is present.")}return shadow(this,"collection",e)}get acroForm(){let e=null;try{const t=this._catDict.get("AcroForm");t instanceof Dict&&t.size>0&&(e=t)}catch(e){if(e instanceof MissingDataException)throw e;info("Cannot fetch AcroForm entry; assuming no forms are present.")}return shadow(this,"acroForm",e)}get acroFormRef(){const e=this._catDict.getRaw("AcroForm");return shadow(this,"acroFormRef",e instanceof Ref?e:null)}get metadata(){const e=this._catDict.getRaw("Metadata");if(!(e instanceof Ref))return shadow(this,"metadata",null);let t=null;try{const i=this.xref.fetch(e,!this.xref.encrypt?.encryptMetadata);if(i instanceof BaseStream&&i.dict instanceof Dict){const e=i.dict.get("Type"),a=i.dict.get("Subtype");if(isName(e,"Metadata")&&isName(a,"XML")){const e=stringToUTF8String(i.getString());e&&(t=new MetadataParser(e).serializable)}}}catch(e){if(e instanceof MissingDataException)throw e;info(`Skipping invalid Metadata: "${e}".`)}return shadow(this,"metadata",t)}get markInfo(){let e=null;try{e=this._readMarkInfo()}catch(e){if(e instanceof MissingDataException)throw e;warn("Unable to read mark info.")}return shadow(this,"markInfo",e)}_readMarkInfo(){const e=this._catDict.get("MarkInfo");if(!(e instanceof Dict))return null;const t={Marked:!1,UserProperties:!1,Suspects:!1};for(const i in t){const a=e.get(i);"boolean"==typeof a&&(t[i]=a)}return t}get structTreeRoot(){let e=null;try{e=this._readStructTreeRoot()}catch(e){if(e instanceof MissingDataException)throw e;warn("Unable read to structTreeRoot info.")}return shadow(this,"structTreeRoot",e)}_readStructTreeRoot(){const e=this._catDict.getRaw("StructTreeRoot"),t=this.xref.fetchIfRef(e);if(!(t instanceof Dict))return null;const i=new StructTreeRoot(t,e);i.init();return i}get toplevelPagesDict(){const e=this._catDict.get("Pages");if(!(e instanceof Dict))throw new FormatError("Invalid top-level pages dictionary.");return shadow(this,"toplevelPagesDict",e)}get documentOutline(){let e=null;try{e=this._readDocumentOutline()}catch(e){if(e instanceof MissingDataException)throw e;warn("Unable to read document outline.")}return shadow(this,"documentOutline",e)}_readDocumentOutline(){let e=this._catDict.get("Outlines");if(!(e instanceof Dict))return null;e=e.getRaw("First");if(!(e instanceof Ref))return null;const t={items:[]},i=[{obj:e,parent:t}],a=new RefSet;a.put(e);const s=this.xref,r=new Uint8ClampedArray(3);for(;i.length>0;){const t=i.shift(),n=s.fetchIfRef(t.obj);if(null===n)continue;n.has("Title")||warn("Invalid outline item encountered.");const o={url:null,dest:null,action:null};Catalog.parseDestDictionary({destDict:n,resultObj:o,docBaseUrl:this.baseUrl,docAttachments:this.attachments});const g=n.get("Title"),c=n.get("F")||0,h=n.getArray("C"),l=n.get("Count");let C=r;!isNumberArray(h,3)||0===h[0]&&0===h[1]&&0===h[2]||(C=ColorSpace.singletons.rgb.getRgb(h,0));const Q={action:o.action,attachment:o.attachment,dest:o.dest,url:o.url,unsafeUrl:o.unsafeUrl,newWindow:o.newWindow,setOCGState:o.setOCGState,title:"string"==typeof g?stringToPDFString(g):"",color:C,count:Number.isInteger(l)?l:void 0,bold:!!(2&c),italic:!!(1&c),items:[]};t.parent.items.push(Q);e=n.getRaw("First");if(e instanceof Ref&&!a.has(e)){i.push({obj:e,parent:Q});a.put(e)}e=n.getRaw("Next");if(e instanceof Ref&&!a.has(e)){i.push({obj:e,parent:t.parent});a.put(e)}}return t.items.length>0?t.items:null}get permissions(){let e=null;try{e=this._readPermissions()}catch(e){if(e instanceof MissingDataException)throw e;warn("Unable to read permissions.")}return shadow(this,"permissions",e)}_readPermissions(){const e=this.xref.trailer.get("Encrypt");if(!(e instanceof Dict))return null;let t=e.get("P");if("number"!=typeof t)return null;t+=2**32;const i=[];for(const e in m){const a=m[e];t&a&&i.push(a)}return i}get optionalContentConfig(){let e=null;try{const t=this._catDict.get("OCProperties");if(!t)return shadow(this,"optionalContentConfig",null);const i=t.get("D");if(!i)return shadow(this,"optionalContentConfig",null);const a=t.get("OCGs");if(!Array.isArray(a))return shadow(this,"optionalContentConfig",null);const s=[],r=new RefSet;for(const e of a)if(e instanceof Ref&&!r.has(e)){r.put(e);s.push(this.#Y(e))}e=this.#v(i,r);e.groups=s}catch(e){if(e instanceof MissingDataException)throw e;warn(`Unable to read optional content config: ${e}`)}return shadow(this,"optionalContentConfig",e)}#Y(e){const t=this.xref.fetch(e),i={id:e.toString(),name:null,intent:null,usage:{print:null,view:null}},a=t.get("Name");"string"==typeof a&&(i.name=stringToPDFString(a));let s=t.getArray("Intent");Array.isArray(s)||(s=[s]);s.every((e=>e instanceof Name))&&(i.intent=s.map((e=>e.name)));const r=t.get("Usage");if(!(r instanceof Dict))return i;const n=i.usage,o=r.get("Print");if(o instanceof Dict){const e=o.get("PrintState");if(e instanceof Name)switch(e.name){case"ON":case"OFF":n.print={printState:e.name}}}const g=r.get("View");if(g instanceof Dict){const e=g.get("ViewState");if(e instanceof Name)switch(e.name){case"ON":case"OFF":n.view={viewState:e.name}}}return i}#v(e,t){function parseOnOff(e){const i=[];if(Array.isArray(e))for(const a of e)a instanceof Ref&&t.has(a)&&i.push(a.toString());return i}function parseOrder(e,i=0){if(!Array.isArray(e))return null;const s=[];for(const r of e){if(r instanceof Ref&&t.has(r)){a.put(r);s.push(r.toString());continue}const e=parseNestedOrder(r,i);e&&s.push(e)}if(i>0)return s;const r=[];for(const e of t)a.has(e)||r.push(e.toString());r.length&&s.push({name:null,order:r});return s}function parseNestedOrder(e,t){if(++t>s){warn("parseNestedOrder - reached MAX_NESTED_LEVELS.");return null}const a=i.fetchIfRef(e);if(!Array.isArray(a))return null;const r=i.fetchIfRef(a[0]);if("string"!=typeof r)return null;const n=parseOrder(a.slice(1),t);return n&&n.length?{name:stringToPDFString(r),order:n}:null}const i=this.xref,a=new RefSet,s=10;return{name:"string"==typeof e.get("Name")?stringToPDFString(e.get("Name")):null,creator:"string"==typeof e.get("Creator")?stringToPDFString(e.get("Creator")):null,baseState:e.get("BaseState")instanceof Name?e.get("BaseState").name:null,on:parseOnOff(e.get("ON")),off:parseOnOff(e.get("OFF")),order:parseOrder(e.get("Order")),groups:null}}setActualNumPages(e=null){this._actualNumPages=e}get hasActualNumPages(){return null!==this._actualNumPages}get _pagesCount(){const e=this.toplevelPagesDict.get("Count");if(!Number.isInteger(e))throw new FormatError("Page count in top-level pages dictionary is not an integer.");return shadow(this,"_pagesCount",e)}get numPages(){return this.hasActualNumPages?this._actualNumPages:this._pagesCount}get destinations(){const e=this._readDests(),t=Object.create(null);if(e instanceof NameTree)for(const[i,a]of e.getAll()){const e=fetchDest(a);e&&(t[stringToPDFString(i)]=e)}else e instanceof Dict&&e.forEach((function(e,i){const a=fetchDest(i);a&&(t[e]=a)}));return shadow(this,"destinations",t)}getDestination(e){const t=this._readDests();if(t instanceof NameTree){const i=fetchDest(t.get(e));if(i)return i;const a=this.destinations[e];if(a){warn(`Found "${e}" at an incorrect position in the NameTree.`);return a}}else if(t instanceof Dict){const i=fetchDest(t.get(e));if(i)return i}return null}_readDests(){const e=this._catDict.get("Names");return e?.has("Dests")?new NameTree(e.getRaw("Dests"),this.xref):this._catDict.has("Dests")?this._catDict.get("Dests"):void 0}get pageLabels(){let e=null;try{e=this._readPageLabels()}catch(e){if(e instanceof MissingDataException)throw e;warn("Unable to read page labels.")}return shadow(this,"pageLabels",e)}_readPageLabels(){const e=this._catDict.getRaw("PageLabels");if(!e)return null;const t=new Array(this.numPages);let i=null,a="";const s=new NumberTree(e,this.xref).getAll();let r="",n=1;for(let e=0,o=this.numPages;e<o;e++){const o=s.get(e);if(void 0!==o){if(!(o instanceof Dict))throw new FormatError("PageLabel is not a dictionary.");if(o.has("Type")&&!isName(o.get("Type"),"PageLabel"))throw new FormatError("Invalid type in PageLabel dictionary.");if(o.has("S")){const e=o.get("S");if(!(e instanceof Name))throw new FormatError("Invalid style in PageLabel dictionary.");i=e.name}else i=null;if(o.has("P")){const e=o.get("P");if("string"!=typeof e)throw new FormatError("Invalid prefix in PageLabel dictionary.");a=stringToPDFString(e)}else a="";if(o.has("St")){const e=o.get("St");if(!(Number.isInteger(e)&&e>=1))throw new FormatError("Invalid start in PageLabel dictionary.");n=e}else n=1}switch(i){case"D":r=n;break;case"R":case"r":r=toRomanNumerals(n,"r"===i);break;case"A":case"a":const e=26,t="a"===i?97:65,a=n-1;r=String.fromCharCode(t+a%e).repeat(Math.floor(a/e)+1);break;default:if(i)throw new FormatError(`Invalid style "${i}" in PageLabel dictionary.`);r=""}t[e]=a+r;n++}return t}get pageLayout(){const e=this._catDict.get("PageLayout");let t="";if(e instanceof Name)switch(e.name){case"SinglePage":case"OneColumn":case"TwoColumnLeft":case"TwoColumnRight":case"TwoPageLeft":case"TwoPageRight":t=e.name}return shadow(this,"pageLayout",t)}get pageMode(){const e=this._catDict.get("PageMode");let t="UseNone";if(e instanceof Name)switch(e.name){case"UseNone":case"UseOutlines":case"UseThumbs":case"FullScreen":case"UseOC":case"UseAttachments":t=e.name}return shadow(this,"pageMode",t)}get viewerPreferences(){const e=this._catDict.get("ViewerPreferences");if(!(e instanceof Dict))return shadow(this,"viewerPreferences",null);let t=null;for(const i of e.getKeys()){const a=e.get(i);let s;switch(i){case"HideToolbar":case"HideMenubar":case"HideWindowUI":case"FitWindow":case"CenterWindow":case"DisplayDocTitle":case"PickTrayByPDFSize":"boolean"==typeof a&&(s=a);break;case"NonFullScreenPageMode":if(a instanceof Name)switch(a.name){case"UseNone":case"UseOutlines":case"UseThumbs":case"UseOC":s=a.name;break;default:s="UseNone"}break;case"Direction":if(a instanceof Name)switch(a.name){case"L2R":case"R2L":s=a.name;break;default:s="L2R"}break;case"ViewArea":case"ViewClip":case"PrintArea":case"PrintClip":if(a instanceof Name)switch(a.name){case"MediaBox":case"CropBox":case"BleedBox":case"TrimBox":case"ArtBox":s=a.name;break;default:s="CropBox"}break;case"PrintScaling":if(a instanceof Name)switch(a.name){case"None":case"AppDefault":s=a.name;break;default:s="AppDefault"}break;case"Duplex":if(a instanceof Name)switch(a.name){case"Simplex":case"DuplexFlipShortEdge":case"DuplexFlipLongEdge":s=a.name;break;default:s="None"}break;case"PrintPageRange":if(Array.isArray(a)&&a.length%2==0){a.every(((e,t,i)=>Number.isInteger(e)&&e>0&&(0===t||e>=i[t-1])&&e<=this.numPages))&&(s=a)}break;case"NumCopies":Number.isInteger(a)&&a>0&&(s=a);break;default:warn(`Ignoring non-standard key in ViewerPreferences: ${i}.`);continue}if(void 0!==s){t||(t=Object.create(null));t[i]=s}else warn(`Bad value, for key "${i}", in ViewerPreferences: ${a}.`)}return shadow(this,"viewerPreferences",t)}get openAction(){const e=this._catDict.get("OpenAction"),t=Object.create(null);if(e instanceof Dict){const i=new Dict(this.xref);i.set("A",e);const a={url:null,dest:null,action:null};Catalog.parseDestDictionary({destDict:i,resultObj:a});Array.isArray(a.dest)?t.dest=a.dest:a.action&&(t.action=a.action)}else Array.isArray(e)&&(t.dest=e);return shadow(this,"openAction",objectSize(t)>0?t:null)}get attachments(){const e=this._catDict.get("Names");let t=null;if(e instanceof Dict&&e.has("EmbeddedFiles")){const i=new NameTree(e.getRaw("EmbeddedFiles"),this.xref);for(const[e,a]of i.getAll()){const i=new FileSpec(a,this.xref);t||(t=Object.create(null));t[stringToPDFString(e)]=i.serializable}}return shadow(this,"attachments",t)}get xfaImages(){const e=this._catDict.get("Names");let t=null;if(e instanceof Dict&&e.has("XFAImages")){const i=new NameTree(e.getRaw("XFAImages"),this.xref);for(const[e,a]of i.getAll()){t||(t=new Dict(this.xref));t.set(stringToPDFString(e),a)}}return shadow(this,"xfaImages",t)}_collectJavaScript(){const e=this._catDict.get("Names");let t=null;function appendIfJavaScriptDict(e,i){if(!(i instanceof Dict))return;if(!isName(i.get("S"),"JavaScript"))return;let a=i.get("JS");if(a instanceof BaseStream)a=a.getString();else if("string"!=typeof a)return;a=stringToPDFString(a).replaceAll("\0","");a&&(t||=new Map).set(e,a)}if(e instanceof Dict&&e.has("JavaScript")){const t=new NameTree(e.getRaw("JavaScript"),this.xref);for(const[e,i]of t.getAll())appendIfJavaScriptDict(stringToPDFString(e),i)}const i=this._catDict.get("OpenAction");i&&appendIfJavaScriptDict("OpenAction",i);return t}get jsActions(){const e=this._collectJavaScript();let t=collectActions(this.xref,this._catDict,dA);if(e){t||=Object.create(null);for(const[i,a]of e)i in t?t[i].push(a):t[i]=[a]}return shadow(this,"jsActions",t)}async fontFallback(e,t){const i=await Promise.all(this.fontCache);for(const a of i)if(a.loadedName===e){a.fallback(t);return}}async cleanup(e=!1){clearGlobalCaches();this.globalImageCache.clear(e);this.pageKidsCountCache.clear();this.pageIndexCache.clear();this.nonBlendModesSet.clear();const t=await Promise.all(this.fontCache);for(const{dict:e}of t)delete e.cacheKey;this.fontCache.clear();this.builtInCMapCache.clear();this.standardFontDataCache.clear();this.systemFontCache.clear()}async getPageDict(e){const t=[this.toplevelPagesDict],i=new RefSet,a=this._catDict.getRaw("Pages");a instanceof Ref&&i.put(a);const s=this.xref,r=this.pageKidsCountCache,n=this.pageIndexCache;let o=0;for(;t.length;){const a=t.pop();if(a instanceof Ref){const g=r.get(a);if(g>=0&&o+g<=e){o+=g;continue}if(i.has(a))throw new FormatError("Pages tree contains circular reference.");i.put(a);const c=await s.fetchAsync(a);if(c instanceof Dict){let t=c.getRaw("Type");t instanceof Ref&&(t=await s.fetchAsync(t));if(isName(t,"Page")||!c.has("Kids")){r.has(a)||r.put(a,1);n.has(a)||n.put(a,o);if(o===e)return[c,a];o++;continue}}t.push(c);continue}if(!(a instanceof Dict))throw new FormatError("Page dictionary kid reference points to wrong type of object.");const{objId:g}=a;let c=a.getRaw("Count");c instanceof Ref&&(c=await s.fetchAsync(c));if(Number.isInteger(c)&&c>=0){g&&!r.has(g)&&r.put(g,c);if(o+c<=e){o+=c;continue}}let h=a.getRaw("Kids");h instanceof Ref&&(h=await s.fetchAsync(h));if(!Array.isArray(h)){let t=a.getRaw("Type");t instanceof Ref&&(t=await s.fetchAsync(t));if(isName(t,"Page")||!a.has("Kids")){if(o===e)return[a,null];o++;continue}throw new FormatError("Page dictionary kids object is not an array.")}for(let e=h.length-1;e>=0;e--)t.push(h[e])}throw new Error(`Page index ${e} not found.`)}async getAllPageDicts(e=!1){const{ignoreErrors:t}=this.pdfManager.evaluatorOptions,i=[{currentNode:this.toplevelPagesDict,posInKids:0}],a=new RefSet,s=this._catDict.getRaw("Pages");s instanceof Ref&&a.put(s);const r=new Map,n=this.xref,o=this.pageIndexCache;let g=0;function addPageDict(e,t){t&&!o.has(t)&&o.put(t,g);r.set(g++,[e,t])}function addPageError(i){if(i instanceof XRefEntryException&&!e)throw i;if(e&&t&&0===g){warn(`getAllPageDicts - Skipping invalid first page: "${i}".`);i=Dict.empty}r.set(g++,[i,null])}for(;i.length>0;){const e=i.at(-1),{currentNode:t,posInKids:s}=e;let r=t.getRaw("Kids");if(r instanceof Ref)try{r=await n.fetchAsync(r)}catch(e){addPageError(e);break}if(!Array.isArray(r)){addPageError(new FormatError("Page dictionary kids object is not an array."));break}if(s>=r.length){i.pop();continue}const o=r[s];let g;if(o instanceof Ref){if(a.has(o)){addPageError(new FormatError("Pages tree contains circular reference."));break}a.put(o);try{g=await n.fetchAsync(o)}catch(e){addPageError(e);break}}else g=o;if(!(g instanceof Dict)){addPageError(new FormatError("Page dictionary kid reference points to wrong type of object."));break}let c=g.getRaw("Type");if(c instanceof Ref)try{c=await n.fetchAsync(c)}catch(e){addPageError(e);break}isName(c,"Page")||!g.has("Kids")?addPageDict(g,o instanceof Ref?o:null):i.push({currentNode:g,posInKids:0});e.posInKids++}return r}getPageIndex(e){const t=this.pageIndexCache.get(e);if(void 0!==t)return Promise.resolve(t);const i=this.xref;let a=0;const next=t=>function pagesBeforeRef(t){let a,s=0;return i.fetchAsync(t).then((function(i){if(isRefsEqual(t,e)&&!isDict(i,"Page")&&!(i instanceof Dict&&!i.has("Type")&&i.has("Contents")))throw new FormatError("The reference does not point to a /Page dictionary.");if(!i)return null;if(!(i instanceof Dict))throw new FormatError("Node must be a dictionary.");a=i.getRaw("Parent");return i.getAsync("Parent")})).then((function(e){if(!e)return null;if(!(e instanceof Dict))throw new FormatError("Parent must be a dictionary.");return e.getAsync("Kids")})).then((function(e){if(!e)return null;const r=[];let n=!1;for(const a of e){if(!(a instanceof Ref))throw new FormatError("Kid must be a reference.");if(isRefsEqual(a,t)){n=!0;break}r.push(i.fetchAsync(a).then((function(e){if(!(e instanceof Dict))throw new FormatError("Kid node must be a dictionary.");e.has("Count")?s+=e.get("Count"):s++})))}if(!n)throw new FormatError("Kid reference not found in parent's kids.");return Promise.all(r).then((function(){return[s,a]}))}))}(t).then((t=>{if(!t){this.pageIndexCache.put(e,a);return a}const[i,s]=t;a+=i;return next(s)}));return next(e)}get baseUrl(){const e=this._catDict.get("URI");if(e instanceof Dict){const t=e.get("Base");if("string"==typeof t){const e=createValidAbsoluteUrl(t,null,{tryConvertEncoding:!0});if(e)return shadow(this,"baseUrl",e.href)}}return shadow(this,"baseUrl",this.pdfManager.docBaseUrl)}static parseDestDictionary({destDict:e,resultObj:t,docBaseUrl:i=null,docAttachments:a=null}){if(!(e instanceof Dict)){warn("parseDestDictionary: `destDict` must be a dictionary.");return}let s,r,n=e.get("A");if(!(n instanceof Dict))if(e.has("Dest"))n=e.get("Dest");else{n=e.get("AA");n instanceof Dict&&(n.has("D")?n=n.get("D"):n.has("U")&&(n=n.get("U")))}if(n instanceof Dict){const e=n.get("S");if(!(e instanceof Name)){warn("parseDestDictionary: Invalid type in Action dictionary.");return}const i=e.name;switch(i){case"ResetForm":const e=n.get("Flags"),o=0==(1&("number"==typeof e?e:0)),g=[],c=[];for(const e of n.get("Fields")||[])e instanceof Ref?c.push(e.toString()):"string"==typeof e&&g.push(stringToPDFString(e));t.resetForm={fields:g,refs:c,include:o};break;case"URI":s=n.get("URI");s instanceof Name&&(s="/"+s.name);break;case"GoTo":r=n.get("D");break;case"Launch":case"GoToR":const h=n.get("F");if(h instanceof Dict){const e=new FileSpec(h,null,!0),{rawFilename:t}=e.serializable;s=t}else"string"==typeof h&&(s=h);const l=fetchRemoteDest(n);l&&"string"==typeof s&&(s=s.split("#",1)[0]+"#"+l);const C=n.get("NewWindow");"boolean"==typeof C&&(t.newWindow=C);break;case"GoToE":const Q=n.get("T");let E;if(a&&Q instanceof Dict){const e=Q.get("R"),t=Q.get("N");isName(e,"C")&&"string"==typeof t&&(E=a[stringToPDFString(t)])}if(E){t.attachment=E;const e=fetchRemoteDest(n);e&&(t.attachmentDest=e)}else warn('parseDestDictionary - unimplemented "GoToE" action.');break;case"Named":const u=n.get("N");u instanceof Name&&(t.action=u.name);break;case"SetOCGState":const d=n.get("State"),f=n.get("PreserveRB");if(!Array.isArray(d)||0===d.length)break;const p=[];for(const e of d)if(e instanceof Name)switch(e.name){case"ON":case"OFF":case"Toggle":p.push(e.name)}else e instanceof Ref&&p.push(e.toString());if(p.length!==d.length)break;t.setOCGState={state:p,preserveRB:"boolean"!=typeof f||f};break;case"JavaScript":const m=n.get("JS");let y;m instanceof BaseStream?y=m.getString():"string"==typeof m&&(y=m);const w=y&&recoverJsURL(stringToPDFString(y));if(w){s=w.url;t.newWindow=w.newWindow;break}default:if("JavaScript"===i||"SubmitForm"===i)break;warn(`parseDestDictionary - unsupported action: "${i}".`)}}else e.has("Dest")&&(r=e.get("Dest"));if("string"==typeof s){const e=createValidAbsoluteUrl(s,i,{addDefaultProtocol:!0,tryConvertEncoding:!0});e&&(t.url=e.href);t.unsafeUrl=s}if(r){r instanceof Name&&(r=r.name);"string"==typeof r?t.dest=stringToPDFString(r):isValidExplicitDest(r)&&(t.dest=r)}}}function addChildren(e,t){if(e instanceof Dict)e=e.getRawValues();else if(e instanceof BaseStream)e=e.dict.getRawValues();else if(!Array.isArray(e))return;for(const a of e)((i=a)instanceof Ref||i instanceof Dict||i instanceof BaseStream||Array.isArray(i))&&t.push(a);var i}class ObjectLoader{constructor(e,t,i){this.dict=e;this.keys=t;this.xref=i;this.refSet=null}async load(){if(this.xref.stream.isDataLoaded)return;const{keys:e,dict:t}=this;this.refSet=new RefSet;const i=[];for(const a of e){const e=t.getRaw(a);void 0!==e&&i.push(e)}return this._walk(i)}async _walk(e){const t=[],i=[];for(;e.length;){let a=e.pop();if(a instanceof Ref){if(this.refSet.has(a))continue;try{this.refSet.put(a);a=this.xref.fetch(a)}catch(e){if(!(e instanceof MissingDataException)){warn(`ObjectLoader._walk - requesting all data: "${e}".`);this.refSet=null;const{manager:t}=this.xref.stream;return t.requestAllChunks()}t.push(a);i.push({begin:e.begin,end:e.end})}}if(a instanceof BaseStream){const e=a.getBaseStreams();if(e){let s=!1;for(const t of e)if(!t.isDataLoaded){s=!0;i.push({begin:t.start,end:t.end})}s&&t.push(a)}}addChildren(a,e)}if(i.length){await this.xref.stream.manager.requestRanges(i);for(const e of t)e instanceof Ref&&this.refSet.remove(e);return this._walk(t)}this.refSet=null}}const Ws=Symbol(),Xs=Symbol(),js=Symbol(),Zs=Symbol(),Vs=Symbol(),zs=Symbol(),_s=Symbol(),$s=Symbol(),Ar=Symbol(),er=Symbol("content"),tr=Symbol("data"),ir=Symbol(),ar=Symbol("extra"),sr=Symbol(),rr=Symbol(),nr=Symbol(),or=Symbol(),gr=Symbol(),Ir=Symbol(),cr=Symbol(),hr=Symbol(),lr=Symbol(),Cr=Symbol(),Qr=Symbol(),Er=Symbol(),ur=Symbol(),dr=Symbol(),fr=Symbol(),pr=Symbol(),mr=Symbol(),yr=Symbol(),wr=Symbol(),br=Symbol(),Dr=Symbol(),Fr=Symbol(),Sr=Symbol(),kr=Symbol(),Rr=Symbol(),Nr=Symbol(),Gr=Symbol(),xr=Symbol(),Mr=Symbol(),Ur=Symbol(),Lr=Symbol(),Jr=Symbol(),Hr=Symbol("namespaceId"),Yr=Symbol("nodeName"),vr=Symbol(),Kr=Symbol(),Tr=Symbol(),qr=Symbol(),Or=Symbol(),Pr=Symbol(),Wr=Symbol(),Xr=Symbol(),jr=Symbol("root"),Zr=Symbol(),Vr=Symbol(),zr=Symbol(),_r=Symbol(),$r=Symbol(),An=Symbol(),en=Symbol(),tn=Symbol(),an=Symbol(),sn=Symbol(),rn=Symbol(),nn=Symbol("uid"),on=Symbol(),gn={config:{id:0,check:e=>e.startsWith("http://www.xfa.org/schema/xci/")},connectionSet:{id:1,check:e=>e.startsWith("http://www.xfa.org/schema/xfa-connection-set/")},datasets:{id:2,check:e=>e.startsWith("http://www.xfa.org/schema/xfa-data/")},form:{id:3,check:e=>e.startsWith("http://www.xfa.org/schema/xfa-form/")},localeSet:{id:4,check:e=>e.startsWith("http://www.xfa.org/schema/xfa-locale-set/")},pdf:{id:5,check:e=>"http://ns.adobe.com/xdp/pdf/"===e},signature:{id:6,check:e=>"http://www.w3.org/2000/09/xmldsig#"===e},sourceSet:{id:7,check:e=>e.startsWith("http://www.xfa.org/schema/xfa-source-set/")},stylesheet:{id:8,check:e=>"http://www.w3.org/1999/XSL/Transform"===e},template:{id:9,check:e=>e.startsWith("http://www.xfa.org/schema/xfa-template/")},xdc:{id:10,check:e=>e.startsWith("http://www.xfa.org/schema/xdc/")},xdp:{id:11,check:e=>"http://ns.adobe.com/xdp/"===e},xfdf:{id:12,check:e=>"http://ns.adobe.com/xfdf/"===e},xhtml:{id:13,check:e=>"http://www.w3.org/1999/xhtml"===e},xmpmeta:{id:14,check:e=>"http://ns.adobe.com/xmpmeta/"===e}},In={pt:e=>e,cm:e=>e/2.54*72,mm:e=>e/25.4*72,in:e=>72*e,px:e=>e},cn=/([+-]?\d+\.?\d*)(.*)/;function stripQuotes(e){return e.startsWith("'")||e.startsWith('"')?e.slice(1,-1):e}function getInteger({data:e,defaultValue:t,validate:i}){if(!e)return t;e=e.trim();const a=parseInt(e,10);return!isNaN(a)&&i(a)?a:t}function getFloat({data:e,defaultValue:t,validate:i}){if(!e)return t;e=e.trim();const a=parseFloat(e);return!isNaN(a)&&i(a)?a:t}function getKeyword({data:e,defaultValue:t,validate:i}){return e&&i(e=e.trim())?e:t}function getStringOption(e,t){return getKeyword({data:e,defaultValue:t[0],validate:e=>t.includes(e)})}function getMeasurement(e,t="0"){t||="0";if(!e)return getMeasurement(t);const i=e.trim().match(cn);if(!i)return getMeasurement(t);const[,a,s]=i,r=parseFloat(a);if(isNaN(r))return getMeasurement(t);if(0===r)return 0;const n=In[s];return n?n(r):r}function getRatio(e){if(!e)return{num:1,den:1};const t=e.trim().split(/\s*:\s*/).map((e=>parseFloat(e))).filter((e=>!isNaN(e)));1===t.length&&t.push(1);if(0===t.length)return{num:1,den:1};const[i,a]=t;return{num:i,den:a}}function getRelevant(e){return e?e.trim().split(/\s+/).map((e=>({excluded:"-"===e[0],viewname:e.substring(1)}))):[]}class HTMLResult{static get FAILURE(){return shadow(this,"FAILURE",new HTMLResult(!1,null,null,null))}static get EMPTY(){return shadow(this,"EMPTY",new HTMLResult(!0,null,null,null))}constructor(e,t,i,a){this.success=e;this.html=t;this.bbox=i;this.breakNode=a}isBreak(){return!!this.breakNode}static breakNode(e){return new HTMLResult(!1,null,null,e)}static success(e,t=null){return new HTMLResult(!0,e,t,null)}}class FontFinder{constructor(e){this.fonts=new Map;this.cache=new Map;this.warned=new Set;this.defaultFont=null;this.add(e)}add(e,t=null){for(const t of e)this.addPdfFont(t);for(const e of this.fonts.values())e.regular||(e.regular=e.italic||e.bold||e.bolditalic);if(!t||0===t.size)return;const i=this.fonts.get("PdfJS-Fallback-PdfJS-XFA");for(const e of t)this.fonts.set(e,i)}addPdfFont(e){const t=e.cssFontInfo,i=t.fontFamily;let a=this.fonts.get(i);if(!a){a=Object.create(null);this.fonts.set(i,a);this.defaultFont||(this.defaultFont=a)}let s="";const r=parseFloat(t.fontWeight);0!==parseFloat(t.italicAngle)?s=r>=700?"bolditalic":"italic":r>=700&&(s="bold");if(!s){(e.name.includes("Bold")||e.psName?.includes("Bold"))&&(s="bold");(e.name.includes("Italic")||e.name.endsWith("It")||e.psName?.includes("Italic")||e.psName?.endsWith("It"))&&(s+="italic")}s||(s="regular");a[s]=e}getDefault(){return this.defaultFont}find(e,t=!0){let i=this.fonts.get(e)||this.cache.get(e);if(i)return i;const a=/,|-|_| |bolditalic|bold|italic|regular|it/gi;let s=e.replaceAll(a,"");i=this.fonts.get(s);if(i){this.cache.set(e,i);return i}s=s.toLowerCase();const r=[];for(const[e,t]of this.fonts.entries())e.replaceAll(a,"").toLowerCase().startsWith(s)&&r.push(t);if(0===r.length)for(const[,e]of this.fonts.entries())e.regular.name?.replaceAll(a,"").toLowerCase().startsWith(s)&&r.push(e);if(0===r.length){s=s.replaceAll(/psmt|mt/gi,"");for(const[e,t]of this.fonts.entries())e.replaceAll(a,"").toLowerCase().startsWith(s)&&r.push(t)}if(0===r.length)for(const e of this.fonts.values())e.regular.name?.replaceAll(a,"").toLowerCase().startsWith(s)&&r.push(e);if(r.length>=1){1!==r.length&&t&&warn(`XFA - Too many choices to guess the correct font: ${e}`);this.cache.set(e,r[0]);return r[0]}if(t&&!this.warned.has(e)){this.warned.add(e);warn(`XFA - Cannot find the font: ${e}`)}return null}}function selectFont(e,t){return"italic"===e.posture?"bold"===e.weight?t.bolditalic:t.italic:"bold"===e.weight?t.bold:t.regular}class FontInfo{constructor(e,t,i,a){this.lineHeight=i;this.paraMargin=t||{top:0,bottom:0,left:0,right:0};if(!e){[this.pdfFont,this.xfaFont]=this.defaultFont(a);return}this.xfaFont={typeface:e.typeface,posture:e.posture,weight:e.weight,size:e.size,letterSpacing:e.letterSpacing};const s=a.find(e.typeface);if(s){this.pdfFont=selectFont(e,s);this.pdfFont||([this.pdfFont,this.xfaFont]=this.defaultFont(a))}else[this.pdfFont,this.xfaFont]=this.defaultFont(a)}defaultFont(e){const t=e.find("Helvetica",!1)||e.find("Myriad Pro",!1)||e.find("Arial",!1)||e.getDefault();if(t?.regular){const e=t.regular;return[e,{typeface:e.cssFontInfo.fontFamily,posture:"normal",weight:"normal",size:10,letterSpacing:0}]}return[null,{typeface:"Courier",posture:"normal",weight:"normal",size:10,letterSpacing:0}]}}class FontSelector{constructor(e,t,i,a){this.fontFinder=a;this.stack=[new FontInfo(e,t,i,a)]}pushData(e,t,i){const a=this.stack.at(-1);for(const t of["typeface","posture","weight","size","letterSpacing"])e[t]||(e[t]=a.xfaFont[t]);for(const e of["top","bottom","left","right"])isNaN(t[e])&&(t[e]=a.paraMargin[e]);const s=new FontInfo(e,t,i||a.lineHeight,this.fontFinder);s.pdfFont||(s.pdfFont=a.pdfFont);this.stack.push(s)}popFont(){this.stack.pop()}topFont(){return this.stack.at(-1)}}class TextMeasure{constructor(e,t,i,a){this.glyphs=[];this.fontSelector=new FontSelector(e,t,i,a);this.extraHeight=0}pushData(e,t,i){this.fontSelector.pushData(e,t,i)}popFont(e){return this.fontSelector.popFont()}addPara(){const e=this.fontSelector.topFont();this.extraHeight+=e.paraMargin.top+e.paraMargin.bottom}addString(e){if(!e)return;const t=this.fontSelector.topFont(),i=t.xfaFont.size;if(t.pdfFont){const a=t.xfaFont.letterSpacing,s=t.pdfFont,r=s.lineHeight||1.2,n=t.lineHeight||Math.max(1.2,r)*i,o=r-(void 0===s.lineGap?.2:s.lineGap),g=Math.max(1,o)*i,c=i/1e3,h=s.defaultWidth||s.charsToGlyphs(" ")[0].width;for(const t of e.split(/[\u2029\n]/)){const e=s.encodeString(t).join(""),i=s.charsToGlyphs(e);for(const e of i){const t=e.width||h;this.glyphs.push([t*c+a,n,g,e.unicode,!1])}this.glyphs.push([0,0,0,"\n",!0])}this.glyphs.pop()}else{for(const t of e.split(/[\u2029\n]/)){for(const e of t.split(""))this.glyphs.push([i,1.2*i,i,e,!1]);this.glyphs.push([0,0,0,"\n",!0])}this.glyphs.pop()}}compute(e){let t=-1,i=0,a=0,s=0,r=0,n=0,o=!1,g=!0;for(let c=0,h=this.glyphs.length;c<h;c++){const[h,l,C,Q,E]=this.glyphs[c],u=" "===Q,d=g?C:l;if(E){a=Math.max(a,r);r=0;s+=n;n=d;t=-1;i=0;g=!1}else if(u)if(r+h>e){a=Math.max(a,r);r=0;s+=n;n=d;t=-1;i=0;o=!0;g=!1}else{n=Math.max(d,n);i=r;r+=h;t=c}else if(r+h>e){s+=n;n=d;if(-1!==t){c=t;a=Math.max(a,i);r=0;t=-1;i=0}else{a=Math.max(a,r);r=h}o=!0;g=!1}else{r+=h;n=Math.max(d,n)}}a=Math.max(a,r);s+=n+this.extraHeight;return{width:1.02*a,height:s,isBroken:o}}}const hn=/^[^.[]+/,ln=/^[^\]]+/,Cn={dot:0,dotDot:1,dotHash:2,dotBracket:3,dotParen:4},Bn=new Map([["$data",(e,t)=>e.datasets?e.datasets.data:e],["$record",(e,t)=>(e.datasets?e.datasets.data:e)[Er]()[0]],["$template",(e,t)=>e.template],["$connectionSet",(e,t)=>e.connectionSet],["$form",(e,t)=>e.form],["$layout",(e,t)=>e.layout],["$host",(e,t)=>e.host],["$dataWindow",(e,t)=>e.dataWindow],["$event",(e,t)=>e.event],["!",(e,t)=>e.datasets],["$xfa",(e,t)=>e],["xfa",(e,t)=>e],["$",(e,t)=>t]]),Qn=new WeakMap;function parseExpression(e,t,i=!0){let a=e.match(hn);if(!a)return null;let[s]=a;const r=[{name:s,cacheName:"."+s,index:0,js:null,formCalc:null,operator:Cn.dot}];let n=s.length;for(;n<e.length;){const g=n;if("["===e.charAt(n++)){a=e.slice(n).match(ln);if(!a){warn("XFA - Invalid index in SOM expression");return null}r.at(-1).index="*"===(o=(o=a[0]).trim())?1/0:parseInt(o,10)||0;n+=a[0].length+1;continue}let c;switch(e.charAt(n)){case".":if(!t)return null;n++;c=Cn.dotDot;break;case"#":n++;c=Cn.dotHash;break;case"[":if(i){warn("XFA - SOM expression contains a FormCalc subexpression which is not supported for now.");return null}c=Cn.dotBracket;break;case"(":if(i){warn("XFA - SOM expression contains a JavaScript subexpression which is not supported for now.");return null}c=Cn.dotParen;break;default:c=Cn.dot}a=e.slice(n).match(hn);if(!a)break;[s]=a;n+=s.length;r.push({name:s,cacheName:e.slice(g,n),operator:c,index:0,js:null,formCalc:null})}var o;return r}function searchNode(e,t,i,a=!0,s=!0){const r=parseExpression(i,a);if(!r)return null;const n=Bn.get(r[0].name);let o,g=0;if(n){o=!0;e=[n(e,t)];g=1}else{o=null===t;e=[t||e]}for(let i=r.length;g<i;g++){const{name:i,cacheName:a,operator:n,index:c}=r[g],h=[];for(const t of e){if(!t.isXFAObject)continue;let e,r;if(s){r=Qn.get(t);if(!r){r=new Map;Qn.set(t,r)}e=r.get(a)}if(!e){switch(n){case Cn.dot:e=t[cr](i,!1);break;case Cn.dotDot:e=t[cr](i,!0);break;case Cn.dotHash:e=t[Ir](i);e=e.isXFAObjectArray?e.children:[e]}s&&r.set(a,e)}e.length>0&&h.push(e)}if(0!==h.length||o||0!==g)e=isFinite(c)?h.filter((e=>c<e.length)).map((e=>e[c])):h.flat();else{const i=t[pr]();if(!(t=i))return null;g=-1;e=[t]}}return 0===e.length?null:e}function createDataNode(e,t,i){const a=parseExpression(i);if(!a)return null;if(a.some((e=>e.operator===Cn.dotDot)))return null;const s=Bn.get(a[0].name);let r=0;if(s){e=s(e,t);r=1}else e=t||e;for(let t=a.length;r<t;r++){const{name:t,operator:i,index:s}=a[r];if(!isFinite(s)){a[r].index=0;return e.createNodes(a.slice(r))}let n;switch(i){case Cn.dot:n=e[cr](t,!1);break;case Cn.dotDot:n=e[cr](t,!0);break;case Cn.dotHash:n=e[Ir](t);n=n.isXFAObjectArray?n.children:[n]}if(0===n.length)return e.createNodes(a.slice(r));if(!(s<n.length)){a[r].index=s-n.length;return e.createNodes(a.slice(r))}{const t=n[s];if(!t.isXFAObject){warn("XFA - Cannot create a node.");return null}e=t}}return null}const En=Symbol(),un=Symbol(),dn=Symbol(),fn=Symbol("_children"),pn=Symbol(),mn=Symbol(),yn=Symbol(),wn=Symbol(),bn=Symbol(),Dn=Symbol(),Fn=Symbol(),Sn=Symbol(),kn=Symbol(),Rn=Symbol("parent"),Nn=Symbol(),Gn=Symbol(),xn=Symbol();let Mn=0;const Un=gn.datasets.id;class XFAObject{constructor(e,t,i=!1){this[Hr]=e;this[Yr]=t;this[Fn]=i;this[Rn]=null;this[fn]=[];this[nn]=`${t}${Mn++}`;this[yr]=null}get isXFAObject(){return!0}get isXFAObjectArray(){return!1}createNodes(e){let t=this,i=null;for(const{name:a,index:s}of e){for(let e=0,r=isFinite(s)?s:0;e<=r;e++){const e=t[Hr]===Un?-1:t[Hr];i=new XmlObject(e,a);t[js](i)}t=i}return i}[Kr](e){if(!this[Fn]||!this[Tr](e))return!1;const t=e[Yr],i=this[t];if(!(i instanceof XFAObjectArray)){null!==i&&this[Xr](i);this[t]=e;this[js](e);return!0}if(i.push(e)){this[js](e);return!0}let a="";this.id?a=` (id: ${this.id})`:this.name&&(a=` (name: ${this.name} ${this.h.value})`);warn(`XFA - node "${this[Yr]}"${a} has already enough "${t}"!`);return!1}[Tr](e){return this.hasOwnProperty(e[Yr])&&e[Hr]===this[Hr]}[Gr](){return!1}[Ws](){return!1}[Sr](){return!1}[kr](){return!1}[Pr](){this.para&&this[mr]()[ar].paraStack.pop()}[Wr](){this[mr]()[ar].paraStack.push(this.para)}[zr](e){this.id&&this[Hr]===gn.template.id&&e.set(this.id,this)}[mr](){return this[yr].template}[xr](){return!1}[Mr](){return!1}[js](e){e[Rn]=this;this[fn].push(e);!e[yr]&&this[yr]&&(e[yr]=this[yr])}[Xr](e){const t=this[fn].indexOf(e);this[fn].splice(t,1)}[wr](){return this.hasOwnProperty("value")}[$r](e){}[qr](e){}[sr](){}[Vs](e){delete this[Fn];if(this[_s]){e.clean(this[_s]);delete this[_s]}}[Dr](e){return this[fn].indexOf(e)}[Fr](e,t){t[Rn]=this;this[fn].splice(e,0,t);!t[yr]&&this[yr]&&(t[yr]=this[yr])}[Ur](){return!this.name}[Jr](){return""}[en](){return 0===this[fn].length?this[er]:this[fn].map((e=>e[en]())).join("")}get[dn](){const e=Object.getPrototypeOf(this);if(!e._attributes){const t=e._attributes=new Set;for(const e of Object.getOwnPropertyNames(this)){if(null===this[e]||this[e]instanceof XFAObject||this[e]instanceof XFAObjectArray)break;t.add(e)}}return shadow(this,dn,e._attributes)}[Nr](e){let t=this;for(;t;){if(t===e)return!0;t=t[pr]()}return!1}[pr](){return this[Rn]}[fr](){return this[pr]()}[Er](e=null){return e?this[e]:this[fn]}[ir](){const e=Object.create(null);this[er]&&(e.$content=this[er]);for(const t of Object.getOwnPropertyNames(this)){const i=this[t];null!==i&&(i instanceof XFAObject?e[t]=i[ir]():i instanceof XFAObjectArray?i.isEmpty()||(e[t]=i.dump()):e[t]=i)}return e}[rn](){return null}[an](){return HTMLResult.EMPTY}*[ur](){for(const e of this[Er]())yield e}*[wn](e,t){for(const i of this[ur]())if(!e||t===e.has(i[Yr])){const e=this[gr](),t=i[an](e);t.success||(this[ar].failingNode=i);yield t}}[rr](){return null}[Xs](e,t){this[ar].children.push(e)}[gr](){}[Zs]({filter:e=null,include:t=!0}){if(this[ar].generator){const e=this[gr](),t=this[ar].failingNode[an](e);if(!t.success)return t;t.html&&this[Xs](t.html,t.bbox);delete this[ar].failingNode}else this[ar].generator=this[wn](e,t);for(;;){const e=this[ar].generator.next();if(e.done)break;const t=e.value;if(!t.success)return t;t.html&&this[Xs](t.html,t.bbox)}this[ar].generator=null;return HTMLResult.EMPTY}[_r](e){this[Gn]=new Set(Object.keys(e))}[Dn](e){const t=this[dn],i=this[Gn];return[...e].filter((e=>t.has(e)&&!i.has(e)))}[Zr](e,t=new Set){for(const i of this[fn])i[Nn](e,t)}[Nn](e,t){const i=this[bn](e,t);i?this[En](i,e,t):this[Zr](e,t)}[bn](e,t){const{use:i,usehref:a}=this;if(!i&&!a)return null;let s=null,r=null,n=null,o=i;if(a){o=a;a.startsWith("#som(")&&a.endsWith(")")?r=a.slice(5,-1):a.startsWith(".#som(")&&a.endsWith(")")?r=a.slice(6,-1):a.startsWith("#")?n=a.slice(1):a.startsWith(".#")&&(n=a.slice(2))}else i.startsWith("#")?n=i.slice(1):r=i;this.use=this.usehref="";if(n)s=e.get(n);else{s=searchNode(e.get(jr),this,r,!0,!1);s&&(s=s[0])}if(!s){warn(`XFA - Invalid prototype reference: ${o}.`);return null}if(s[Yr]!==this[Yr]){warn(`XFA - Incompatible prototype: ${s[Yr]} !== ${this[Yr]}.`);return null}if(t.has(s)){warn("XFA - Cycle detected in prototypes use.");return null}t.add(s);const g=s[bn](e,t);g&&s[En](g,e,t);s[Zr](e,t);t.delete(s);return s}[En](e,t,i){if(i.has(e)){warn("XFA - Cycle detected in prototypes use.");return}!this[er]&&e[er]&&(this[er]=e[er]);new Set(i).add(e);for(const t of this[Dn](e[Gn])){this[t]=e[t];this[Gn]&&this[Gn].add(t)}for(const a of Object.getOwnPropertyNames(this)){if(this[dn].has(a))continue;const s=this[a],r=e[a];if(s instanceof XFAObjectArray){for(const e of s[fn])e[Nn](t,i);for(let a=s[fn].length,n=r[fn].length;a<n;a++){const r=e[fn][a][$s]();if(!s.push(r))break;r[Rn]=this;this[fn].push(r);r[Nn](t,i)}}else if(null===s){if(null!==r){const e=r[$s]();e[Rn]=this;this[a]=e;this[fn].push(e);e[Nn](t,i)}}else{s[Zr](t,i);r&&s[En](r,t,i)}}}static[pn](e){return Array.isArray(e)?e.map((e=>XFAObject[pn](e))):"object"==typeof e&&null!==e?Object.assign({},e):e}[$s](){const e=Object.create(Object.getPrototypeOf(this));for(const t of Object.getOwnPropertySymbols(this))try{e[t]=this[t]}catch{shadow(e,t,this[t])}e[nn]=`${e[Yr]}${Mn++}`;e[fn]=[];for(const t of Object.getOwnPropertyNames(this)){if(this[dn].has(t)){e[t]=XFAObject[pn](this[t]);continue}const i=this[t];e[t]=i instanceof XFAObjectArray?new XFAObjectArray(i[Sn]):null}for(const t of this[fn]){const i=t[Yr],a=t[$s]();e[fn].push(a);a[Rn]=e;null===e[i]?e[i]=a:e[i][fn].push(a)}return e}[Er](e=null){return e?this[fn].filter((t=>t[Yr]===e)):this[fn]}[Ir](e){return this[e]}[cr](e,t,i=!0){return Array.from(this[hr](e,t,i))}*[hr](e,t,i=!0){if("parent"!==e){for(const i of this[fn]){i[Yr]===e&&(yield i);i.name===e&&(yield i);(t||i[Ur]())&&(yield*i[hr](e,t,!1))}i&&this[dn].has(e)&&(yield new XFAAttribute(this,e,this[e]))}else yield this[Rn]}}class XFAObjectArray{constructor(e=1/0){this[Sn]=e;this[fn]=[]}get isXFAObject(){return!1}get isXFAObjectArray(){return!0}push(e){if(this[fn].length<=this[Sn]){this[fn].push(e);return!0}warn(`XFA - node "${e[Yr]}" accepts no more than ${this[Sn]} children`);return!1}isEmpty(){return 0===this[fn].length}dump(){return 1===this[fn].length?this[fn][0][ir]():this[fn].map((e=>e[ir]()))}[$s](){const e=new XFAObjectArray(this[Sn]);e[fn]=this[fn].map((e=>e[$s]()));return e}get children(){return this[fn]}clear(){this[fn].length=0}}class XFAAttribute{constructor(e,t,i){this[Rn]=e;this[Yr]=t;this[er]=i;this[Ar]=!1;this[nn]="attribute"+Mn++}[pr](){return this[Rn]}[Rr](){return!0}[lr](){return this[er].trim()}[$r](e){e=e.value||"";this[er]=e.toString()}[en](){return this[er]}[Nr](e){return this[Rn]===e||this[Rn][Nr](e)}}class XmlObject extends XFAObject{constructor(e,t,i={}){super(e,t);this[er]="";this[mn]=null;if("#text"!==t){const e=new Map;this[un]=e;for(const[t,a]of Object.entries(i))e.set(t,new XFAAttribute(this,t,a));if(i.hasOwnProperty(vr)){const e=i[vr].xfa.dataNode;void 0!==e&&("dataGroup"===e?this[mn]=!1:"dataValue"===e&&(this[mn]=!0))}}this[Ar]=!1}[sn](e){const t=this[Yr];if("#text"===t){e.push(encodeToXmlString(this[er]));return}const i=utf8StringToString(t),a=this[Hr]===Un?"xfa:":"";e.push(`<${a}${i}`);for(const[t,i]of this[un].entries()){const a=utf8StringToString(t);e.push(` ${a}="${encodeToXmlString(i[er])}"`)}null!==this[mn]&&(this[mn]?e.push(' xfa:dataNode="dataValue"'):e.push(' xfa:dataNode="dataGroup"'));if(this[er]||0!==this[fn].length){e.push(">");if(this[er])"string"==typeof this[er]?e.push(encodeToXmlString(this[er])):this[er][sn](e);else for(const t of this[fn])t[sn](e);e.push(`</${a}${i}>`)}else e.push("/>")}[Kr](e){if(this[er]){const e=new XmlObject(this[Hr],"#text");this[js](e);e[er]=this[er];this[er]=""}this[js](e);return!0}[qr](e){this[er]+=e}[sr](){if(this[er]&&this[fn].length>0){const e=new XmlObject(this[Hr],"#text");this[js](e);e[er]=this[er];delete this[er]}}[an](){return"#text"===this[Yr]?HTMLResult.success({name:"#text",value:this[er]}):HTMLResult.EMPTY}[Er](e=null){return e?this[fn].filter((t=>t[Yr]===e)):this[fn]}[or](){return this[un]}[Ir](e){const t=this[un].get(e);return void 0!==t?t:this[Er](e)}*[hr](e,t){const i=this[un].get(e);i&&(yield i);for(const i of this[fn]){i[Yr]===e&&(yield i);t&&(yield*i[hr](e,t))}}*[nr](e,t){const i=this[un].get(e);!i||t&&i[Ar]||(yield i);for(const i of this[fn])yield*i[nr](e,t)}*[Qr](e,t,i){for(const a of this[fn]){a[Yr]!==e||i&&a[Ar]||(yield a);t&&(yield*a[Qr](e,t,i))}}[Rr](){return null===this[mn]?0===this[fn].length||this[fn][0][Hr]===gn.xhtml.id:this[mn]}[lr](){return null===this[mn]?0===this[fn].length?this[er].trim():this[fn][0][Hr]===gn.xhtml.id?this[fn][0][en]().trim():null:this[er].trim()}[$r](e){e=e.value||"";this[er]=e.toString()}[ir](e=!1){const t=Object.create(null);e&&(t.$ns=this[Hr]);this[er]&&(t.$content=this[er]);t.$name=this[Yr];t.children=[];for(const i of this[fn])t.children.push(i[ir](e));t.attributes=Object.create(null);for(const[e,i]of this[un])t.attributes[e]=i[er];return t}}class ContentObject extends XFAObject{constructor(e,t){super(e,t);this[er]=""}[qr](e){this[er]+=e}[sr](){}}class OptionObject extends ContentObject{constructor(e,t,i){super(e,t);this[kn]=i}[sr](){this[er]=getKeyword({data:this[er],defaultValue:this[kn][0],validate:e=>this[kn].includes(e)})}[Vs](e){super[Vs](e);delete this[kn]}}class StringObject extends ContentObject{[sr](){this[er]=this[er].trim()}}class IntegerObject extends ContentObject{constructor(e,t,i,a){super(e,t);this[yn]=i;this[xn]=a}[sr](){this[er]=getInteger({data:this[er],defaultValue:this[yn],validate:this[xn]})}[Vs](e){super[Vs](e);delete this[yn];delete this[xn]}}class Option01 extends IntegerObject{constructor(e,t){super(e,t,0,(e=>1===e))}}class Option10 extends IntegerObject{constructor(e,t){super(e,t,1,(e=>0===e))}}function measureToString(e){return"string"==typeof e?"0px":Number.isInteger(e)?`${e}px`:`${e.toFixed(2)}px`}const Ln={anchorType(e,t){const i=e[fr]();if(i&&(!i.layout||"position"===i.layout)){"transform"in t||(t.transform="");switch(e.anchorType){case"bottomCenter":t.transform+="translate(-50%, -100%)";break;case"bottomLeft":t.transform+="translate(0,-100%)";break;case"bottomRight":t.transform+="translate(-100%,-100%)";break;case"middleCenter":t.transform+="translate(-50%,-50%)";break;case"middleLeft":t.transform+="translate(0,-50%)";break;case"middleRight":t.transform+="translate(-100%,-50%)";break;case"topCenter":t.transform+="translate(-50%,0)";break;case"topRight":t.transform+="translate(-100%,0)"}}},dimensions(e,t){const i=e[fr]();let a=e.w;const s=e.h;if(i.layout?.includes("row")){const t=i[ar],s=e.colSpan;let r;if(-1===s){r=t.columnWidths.slice(t.currentColumn).reduce(((e,t)=>e+t),0);t.currentColumn=0}else{r=t.columnWidths.slice(t.currentColumn,t.currentColumn+s).reduce(((e,t)=>e+t),0);t.currentColumn=(t.currentColumn+e.colSpan)%t.columnWidths.length}isNaN(r)||(a=e.w=r)}t.width=""!==a?measureToString(a):"auto";t.height=""!==s?measureToString(s):"auto"},position(e,t){const i=e[fr]();if(!i?.layout||"position"===i.layout){t.position="absolute";t.left=measureToString(e.x);t.top=measureToString(e.y)}},rotate(e,t){if(e.rotate){"transform"in t||(t.transform="");t.transform+=`rotate(-${e.rotate}deg)`;t.transformOrigin="top left"}},presence(e,t){switch(e.presence){case"invisible":t.visibility="hidden";break;case"hidden":case"inactive":t.display="none"}},hAlign(e,t){if("para"===e[Yr])switch(e.hAlign){case"justifyAll":t.textAlign="justify-all";break;case"radix":t.textAlign="left";break;default:t.textAlign=e.hAlign}else switch(e.hAlign){case"left":t.alignSelf="start";break;case"center":t.alignSelf="center";break;case"right":t.alignSelf="end"}},margin(e,t){e.margin&&(t.margin=e.margin[rn]().margin)}};function setMinMaxDimensions(e,t){if("position"===e[fr]().layout){e.minW>0&&(t.minWidth=measureToString(e.minW));e.maxW>0&&(t.maxWidth=measureToString(e.maxW));e.minH>0&&(t.minHeight=measureToString(e.minH));e.maxH>0&&(t.maxHeight=measureToString(e.maxH))}}function layoutText(e,t,i,a,s,r){const n=new TextMeasure(t,i,a,s);"string"==typeof e?n.addString(e):e[Or](n);return n.compute(r)}function layoutNode(e,t){let i=null,a=null,s=!1;if((!e.w||!e.h)&&e.value){let r=0,n=0;if(e.margin){r=e.margin.leftInset+e.margin.rightInset;n=e.margin.topInset+e.margin.bottomInset}let o=null,g=null;if(e.para){g=Object.create(null);o=""===e.para.lineHeight?null:e.para.lineHeight;g.top=""===e.para.spaceAbove?0:e.para.spaceAbove;g.bottom=""===e.para.spaceBelow?0:e.para.spaceBelow;g.left=""===e.para.marginLeft?0:e.para.marginLeft;g.right=""===e.para.marginRight?0:e.para.marginRight}let c=e.font;if(!c){const t=e[mr]();let i=e[pr]();for(;i&&i!==t;){if(i.font){c=i.font;break}i=i[pr]()}}const h=(e.w||t.width)-r,l=e[yr].fontFinder;if(e.value.exData&&e.value.exData[er]&&"text/html"===e.value.exData.contentType){const t=layoutText(e.value.exData[er],c,g,o,l,h);a=t.width;i=t.height;s=t.isBroken}else{const t=e.value[en]();if(t){const e=layoutText(t,c,g,o,l,h);a=e.width;i=e.height;s=e.isBroken}}null===a||e.w||(a+=r);null===i||e.h||(i+=n)}return{w:a,h:i,isBroken:s}}function computeBbox(e,t,i){let a;if(""!==e.w&&""!==e.h)a=[e.x,e.y,e.w,e.h];else{if(!i)return null;let s=e.w;if(""===s){if(0===e.maxW){const t=e[fr]();s="position"===t.layout&&""!==t.w?0:e.minW}else s=Math.min(e.maxW,i.width);t.attributes.style.width=measureToString(s)}let r=e.h;if(""===r){if(0===e.maxH){const t=e[fr]();r="position"===t.layout&&""!==t.h?0:e.minH}else r=Math.min(e.maxH,i.height);t.attributes.style.height=measureToString(r)}a=[e.x,e.y,s,r]}return a}function fixDimensions(e){const t=e[fr]();if(t.layout?.includes("row")){const i=t[ar],a=e.colSpan;let s;s=-1===a?i.columnWidths.slice(i.currentColumn).reduce(((e,t)=>e+t),0):i.columnWidths.slice(i.currentColumn,i.currentColumn+a).reduce(((e,t)=>e+t),0);isNaN(s)||(e.w=s)}t.layout&&"position"!==t.layout&&(e.x=e.y=0);"table"===e.layout&&""===e.w&&Array.isArray(e.columnWidths)&&(e.w=e.columnWidths.reduce(((e,t)=>e+t),0))}function layoutClass(e){switch(e.layout){case"position":default:return"xfaPosition";case"lr-tb":return"xfaLrTb";case"rl-row":return"xfaRlRow";case"rl-tb":return"xfaRlTb";case"row":return"xfaRow";case"table":return"xfaTable";case"tb":return"xfaTb"}}function toStyle(e,...t){const i=Object.create(null);for(const a of t){const t=e[a];if(null!==t)if(Ln.hasOwnProperty(a))Ln[a](e,i);else if(t instanceof XFAObject){const e=t[rn]();e?Object.assign(i,e):warn(`(DEBUG) - XFA - style for ${a} not implemented yet`)}}return i}function createWrapper(e,t){const{attributes:i}=t,{style:a}=i,s={name:"div",attributes:{class:["xfaWrapper"],style:Object.create(null)},children:[]};i.class.push("xfaWrapped");if(e.border){const{widths:i,insets:r}=e.border[ar];let n,o,g=r[0],c=r[3];const h=r[0]+r[2],l=r[1]+r[3];switch(e.border.hand){case"even":g-=i[0]/2;c-=i[3]/2;n=`calc(100% + ${(i[1]+i[3])/2-l}px)`;o=`calc(100% + ${(i[0]+i[2])/2-h}px)`;break;case"left":g-=i[0];c-=i[3];n=`calc(100% + ${i[1]+i[3]-l}px)`;o=`calc(100% + ${i[0]+i[2]-h}px)`;break;case"right":n=l?`calc(100% - ${l}px)`:"100%";o=h?`calc(100% - ${h}px)`:"100%"}const C=["xfaBorder"];isPrintOnly(e.border)&&C.push("xfaPrintOnly");const Q={name:"div",attributes:{class:C,style:{top:`${g}px`,left:`${c}px`,width:n,height:o}},children:[]};for(const e of["border","borderWidth","borderColor","borderRadius","borderStyle"])if(void 0!==a[e]){Q.attributes.style[e]=a[e];delete a[e]}s.children.push(Q,t)}else s.children.push(t);for(const e of["background","backgroundClip","top","left","width","height","minWidth","minHeight","maxWidth","maxHeight","transform","transformOrigin","visibility"])if(void 0!==a[e]){s.attributes.style[e]=a[e];delete a[e]}s.attributes.style.position="absolute"===a.position?"absolute":"relative";delete a.position;if(a.alignSelf){s.attributes.style.alignSelf=a.alignSelf;delete a.alignSelf}return s}function fixTextIndent(e){const t=getMeasurement(e.textIndent,"0px");if(t>=0)return;const i="padding"+("left"===("right"===e.textAlign?"right":"left")?"Left":"Right"),a=getMeasurement(e[i],"0px");e[i]=a-t+"px"}function setAccess(e,t){switch(e.access){case"nonInteractive":t.push("xfaNonInteractive");break;case"readOnly":t.push("xfaReadOnly");break;case"protected":t.push("xfaDisabled")}}function isPrintOnly(e){return e.relevant.length>0&&!e.relevant[0].excluded&&"print"===e.relevant[0].viewname}function getCurrentPara(e){const t=e[mr]()[ar].paraStack;return t.length?t.at(-1):null}function setPara(e,t,i){if(i.attributes.class?.includes("xfaRich")){if(t){""===e.h&&(t.height="auto");""===e.w&&(t.width="auto")}const a=getCurrentPara(e);if(a){const e=i.attributes.style;e.display="flex";e.flexDirection="column";switch(a.vAlign){case"top":e.justifyContent="start";break;case"bottom":e.justifyContent="end";break;case"middle":e.justifyContent="center"}const t=a[rn]();for(const[i,a]of Object.entries(t))i in e||(e[i]=a)}}}function setFontFamily(e,t,i,a){if(!i){delete a.fontFamily;return}const s=stripQuotes(e.typeface);a.fontFamily=`"${s}"`;const r=i.find(s);if(r){const{fontFamily:i}=r.regular.cssFontInfo;i!==s&&(a.fontFamily=`"${i}"`);const n=getCurrentPara(t);if(n&&""!==n.lineHeight)return;if(a.lineHeight)return;const o=selectFont(e,r);o&&(a.lineHeight=Math.max(1.2,o.lineHeight))}}function fixURL(e){const t=createValidAbsoluteUrl(e,null,{addDefaultProtocol:!0,tryConvertEncoding:!0});return t?t.href:null}function createLine(e,t){return{name:"div",attributes:{class:["lr-tb"===e.layout?"xfaLr":"xfaRl"]},children:t}}function flushHTML(e){if(!e[ar])return null;const t={name:"div",attributes:e[ar].attributes,children:e[ar].children};if(e[ar].failingNode){const i=e[ar].failingNode[rr]();i&&(e.layout.endsWith("-tb")?t.children.push(createLine(e,[i])):t.children.push(i))}return 0===t.children.length?null:t}function addHTML(e,t,i){const a=e[ar],s=a.availableSpace,[r,n,o,g]=i;switch(e.layout){case"position":a.width=Math.max(a.width,r+o);a.height=Math.max(a.height,n+g);a.children.push(t);break;case"lr-tb":case"rl-tb":if(!a.line||1===a.attempt){a.line=createLine(e,[]);a.children.push(a.line);a.numberInLine=0}a.numberInLine+=1;a.line.children.push(t);if(0===a.attempt){a.currentWidth+=o;a.height=Math.max(a.height,a.prevHeight+g)}else{a.currentWidth=o;a.prevHeight=a.height;a.height+=g;a.attempt=0}a.width=Math.max(a.width,a.currentWidth);break;case"rl-row":case"row":{a.children.push(t);a.width+=o;a.height=Math.max(a.height,g);const e=measureToString(a.height);for(const t of a.children)t.attributes.style.height=e;break}case"table":case"tb":a.width=Math.min(s.width,Math.max(a.width,o));a.height+=g;a.children.push(t)}}function getAvailableSpace(e){const t=e[ar].availableSpace,i=e.margin?e.margin.topInset+e.margin.bottomInset:0,a=e.margin?e.margin.leftInset+e.margin.rightInset:0;switch(e.layout){case"lr-tb":case"rl-tb":return 0===e[ar].attempt?{width:t.width-a-e[ar].currentWidth,height:t.height-i-e[ar].prevHeight}:{width:t.width-a,height:t.height-i-e[ar].height};case"rl-row":case"row":return{width:e[ar].columnWidths.slice(e[ar].currentColumn).reduce(((e,t)=>e+t)),height:t.height-a};case"table":case"tb":return{width:t.width-a,height:t.height-i-e[ar].height};default:return t}}function checkDimensions(e,t){if(null===e[mr]()[ar].firstUnsplittable)return!0;if(0===e.w||0===e.h)return!0;const i=e[fr](),a=i[ar]?.attempt||0,[,s,r,n]=function getTransformedBBox(e){let t,i,a=""===e.w?NaN:e.w,s=""===e.h?NaN:e.h,[r,n]=[0,0];switch(e.anchorType||""){case"bottomCenter":[r,n]=[a/2,s];break;case"bottomLeft":[r,n]=[0,s];break;case"bottomRight":[r,n]=[a,s];break;case"middleCenter":[r,n]=[a/2,s/2];break;case"middleLeft":[r,n]=[0,s/2];break;case"middleRight":[r,n]=[a,s/2];break;case"topCenter":[r,n]=[a/2,0];break;case"topRight":[r,n]=[a,0]}switch(e.rotate||0){case 0:[t,i]=[-r,-n];break;case 90:[t,i]=[-n,r];[a,s]=[s,-a];break;case 180:[t,i]=[r,n];[a,s]=[-a,-s];break;case 270:[t,i]=[n,-r];[a,s]=[-s,a]}return[e.x+t+Math.min(0,a),e.y+i+Math.min(0,s),Math.abs(a),Math.abs(s)]}(e);switch(i.layout){case"lr-tb":case"rl-tb":return 0===a?e[mr]()[ar].noLayoutFailure?""!==e.w?Math.round(r-t.width)<=2:t.width>2:!(""!==e.h&&Math.round(n-t.height)>2)&&(""!==e.w?Math.round(r-t.width)<=2||0===i[ar].numberInLine&&t.height>2:t.width>2):!!e[mr]()[ar].noLayoutFailure||!(""!==e.h&&Math.round(n-t.height)>2)&&((""===e.w||Math.round(r-t.width)<=2||!i[Mr]())&&t.height>2);case"table":case"tb":return!!e[mr]()[ar].noLayoutFailure||(""===e.h||e[xr]()?(""===e.w||Math.round(r-t.width)<=2||!i[Mr]())&&t.height>2:Math.round(n-t.height)<=2);case"position":if(e[mr]()[ar].noLayoutFailure)return!0;if(""===e.h||Math.round(n+s-t.height)<=2)return!0;return n+s>e[mr]()[ar].currentContentArea.h;case"rl-row":case"row":return!!e[mr]()[ar].noLayoutFailure||(""===e.h||Math.round(n-t.height)<=2);default:return!0}}const Jn=gn.template.id,Hn="http://www.w3.org/2000/svg",Yn=/^H(\d+)$/,vn=new Set(["image/gif","image/jpeg","image/jpg","image/pjpeg","image/png","image/apng","image/x-png","image/bmp","image/x-ms-bmp","image/tiff","image/tif","application/octet-stream"]),Kn=[[[66,77],"image/bmp"],[[255,216,255],"image/jpeg"],[[73,73,42,0],"image/tiff"],[[77,77,0,42],"image/tiff"],[[71,73,70,56,57,97],"image/gif"],[[137,80,78,71,13,10,26,10],"image/png"]];function getBorderDims(e){if(!e||!e.border)return{w:0,h:0};const t=e.border[Cr]();return t?{w:t.widths[0]+t.widths[2]+t.insets[0]+t.insets[2],h:t.widths[1]+t.widths[3]+t.insets[1]+t.insets[3]}:{w:0,h:0}}function hasMargin(e){return e.margin&&(e.margin.topInset||e.margin.rightInset||e.margin.bottomInset||e.margin.leftInset)}function _setValue(e,t){if(!e.value){const t=new Value({});e[js](t);e.value=t}e.value[$r](t)}function*getContainedChildren(e){for(const t of e[Er]())t instanceof SubformSet?yield*t[ur]():yield t}function isRequired(e){return"error"===e.validate?.nullTest}function setTabIndex(e){for(;e;){if(!e.traversal){e[An]=e[pr]()[An];return}if(e[An])return;let t=null;for(const i of e.traversal[Er]())if("next"===i.operation){t=i;break}if(!t||!t.ref){e[An]=e[pr]()[An];return}const i=e[mr]();e[An]=++i[An];const a=i[Vr](t.ref,e);if(!a)return;e=a[0]}}function applyAssist(e,t){const i=e.assist;if(i){const e=i[an]();e&&(t.title=e);const a=i.role.match(Yn);if(a){const e="heading",i=a[1];t.role=e;t["aria-level"]=i}}if("table"===e.layout)t.role="table";else if("row"===e.layout)t.role="row";else{const i=e[pr]();"row"===i.layout&&(t.role="TH"===i.assist?.role?"columnheader":"cell")}}function ariaLabel(e){if(!e.assist)return null;const t=e.assist;return t.speak&&""!==t.speak[er]?t.speak[er]:t.toolTip?t.toolTip[er]:null}function valueToHtml(e){return HTMLResult.success({name:"div",attributes:{class:["xfaRich"],style:Object.create(null)},children:[{name:"span",attributes:{style:Object.create(null)},value:e}]})}function setFirstUnsplittable(e){const t=e[mr]();if(null===t[ar].firstUnsplittable){t[ar].firstUnsplittable=e;t[ar].noLayoutFailure=!0}}function unsetFirstUnsplittable(e){const t=e[mr]();t[ar].firstUnsplittable===e&&(t[ar].noLayoutFailure=!1)}function handleBreak(e){if(e[ar])return!1;e[ar]=Object.create(null);if("auto"===e.targetType)return!1;const t=e[mr]();let i=null;if(e.target){i=t[Vr](e.target,e[pr]());if(!i)return!1;i=i[0]}const{currentPageArea:a,currentContentArea:s}=t[ar];if("pageArea"===e.targetType){i instanceof PageArea||(i=null);if(e.startNew){e[ar].target=i||a;return!0}if(i&&i!==a){e[ar].target=i;return!0}return!1}i instanceof ContentArea||(i=null);const r=i&&i[pr]();let n,o=r;if(e.startNew)if(i){const e=r.contentArea.children,t=e.indexOf(s),a=e.indexOf(i);-1!==t&&t<a&&(o=null);n=a-1}else n=a.contentArea.children.indexOf(s);else{if(!i||i===s)return!1;n=r.contentArea.children.indexOf(i)-1;o=r===a?null:r}e[ar].target=o;e[ar].index=n;return!0}function handleOverflow(e,t,i){const a=e[mr](),s=a[ar].noLayoutFailure,r=t[fr];t[fr]=()=>e;a[ar].noLayoutFailure=!0;const n=t[an](i);e[Xs](n.html,n.bbox);a[ar].noLayoutFailure=s;t[fr]=r}class AppearanceFilter extends StringObject{constructor(e){super(Jn,"appearanceFilter");this.id=e.id||"";this.type=getStringOption(e.type,["optional","required"]);this.use=e.use||"";this.usehref=e.usehref||""}}class Arc extends XFAObject{constructor(e){super(Jn,"arc",!0);this.circular=getInteger({data:e.circular,defaultValue:0,validate:e=>1===e});this.hand=getStringOption(e.hand,["even","left","right"]);this.id=e.id||"";this.startAngle=getFloat({data:e.startAngle,defaultValue:0,validate:e=>!0});this.sweepAngle=getFloat({data:e.sweepAngle,defaultValue:360,validate:e=>!0});this.use=e.use||"";this.usehref=e.usehref||"";this.edge=null;this.fill=null}[an](){const e=this.edge||new Edge({}),t=e[rn](),i=Object.create(null);"visible"===this.fill?.presence?Object.assign(i,this.fill[rn]()):i.fill="transparent";i.strokeWidth=measureToString("visible"===e.presence?e.thickness:0);i.stroke=t.color;let a;const s={xmlns:Hn,style:{width:"100%",height:"100%",overflow:"visible"}};if(360===this.sweepAngle)a={name:"ellipse",attributes:{xmlns:Hn,cx:"50%",cy:"50%",rx:"50%",ry:"50%",style:i}};else{const e=this.startAngle*Math.PI/180,t=this.sweepAngle*Math.PI/180,r=this.sweepAngle>180?1:0,[n,o,g,c]=[50*(1+Math.cos(e)),50*(1-Math.sin(e)),50*(1+Math.cos(e+t)),50*(1-Math.sin(e+t))];a={name:"path",attributes:{xmlns:Hn,d:`M ${n} ${o} A 50 50 0 ${r} 0 ${g} ${c}`,vectorEffect:"non-scaling-stroke",style:i}};Object.assign(s,{viewBox:"0 0 100 100",preserveAspectRatio:"none"})}const r={name:"svg",children:[a],attributes:s};if(hasMargin(this[pr]()[pr]()))return HTMLResult.success({name:"div",attributes:{style:{display:"inline",width:"100%",height:"100%"}},children:[r]});r.attributes.style.position="absolute";return HTMLResult.success(r)}}class Area extends XFAObject{constructor(e){super(Jn,"area",!0);this.colSpan=getInteger({data:e.colSpan,defaultValue:1,validate:e=>e>=1||-1===e});this.id=e.id||"";this.name=e.name||"";this.relevant=getRelevant(e.relevant);this.use=e.use||"";this.usehref=e.usehref||"";this.x=getMeasurement(e.x,"0pt");this.y=getMeasurement(e.y,"0pt");this.desc=null;this.extras=null;this.area=new XFAObjectArray;this.draw=new XFAObjectArray;this.exObject=new XFAObjectArray;this.exclGroup=new XFAObjectArray;this.field=new XFAObjectArray;this.subform=new XFAObjectArray;this.subformSet=new XFAObjectArray}*[ur](){yield*getContainedChildren(this)}[Ur](){return!0}[kr](){return!0}[Xs](e,t){const[i,a,s,r]=t;this[ar].width=Math.max(this[ar].width,i+s);this[ar].height=Math.max(this[ar].height,a+r);this[ar].children.push(e)}[gr](){return this[ar].availableSpace}[an](e){const t=toStyle(this,"position"),i={style:t,id:this[nn],class:["xfaArea"]};isPrintOnly(this)&&i.class.push("xfaPrintOnly");this.name&&(i.xfaName=this.name);const a=[];this[ar]={children:a,width:0,height:0,availableSpace:e};const s=this[Zs]({filter:new Set(["area","draw","field","exclGroup","subform","subformSet"]),include:!0});if(!s.success){if(s.isBreak())return s;delete this[ar];return HTMLResult.FAILURE}t.width=measureToString(this[ar].width);t.height=measureToString(this[ar].height);const r={name:"div",attributes:i,children:a},n=[this.x,this.y,this[ar].width,this[ar].height];delete this[ar];return HTMLResult.success(r,n)}}class Assist extends XFAObject{constructor(e){super(Jn,"assist",!0);this.id=e.id||"";this.role=e.role||"";this.use=e.use||"";this.usehref=e.usehref||"";this.speak=null;this.toolTip=null}[an](){return this.toolTip?.[er]||null}}class Barcode extends XFAObject{constructor(e){super(Jn,"barcode",!0);this.charEncoding=getKeyword({data:e.charEncoding?e.charEncoding.toLowerCase():"",defaultValue:"",validate:e=>["utf-8","big-five","fontspecific","gbk","gb-18030","gb-2312","ksc-5601","none","shift-jis","ucs-2","utf-16"].includes(e)||e.match(/iso-8859-\d{2}/)});this.checksum=getStringOption(e.checksum,["none","1mod10","1mod10_1mod11","2mod10","auto"]);this.dataColumnCount=getInteger({data:e.dataColumnCount,defaultValue:-1,validate:e=>e>=0});this.dataLength=getInteger({data:e.dataLength,defaultValue:-1,validate:e=>e>=0});this.dataPrep=getStringOption(e.dataPrep,["none","flateCompress"]);this.dataRowCount=getInteger({data:e.dataRowCount,defaultValue:-1,validate:e=>e>=0});this.endChar=e.endChar||"";this.errorCorrectionLevel=getInteger({data:e.errorCorrectionLevel,defaultValue:-1,validate:e=>e>=0&&e<=8});this.id=e.id||"";this.moduleHeight=getMeasurement(e.moduleHeight,"5mm");this.moduleWidth=getMeasurement(e.moduleWidth,"0.25mm");this.printCheckDigit=getInteger({data:e.printCheckDigit,defaultValue:0,validate:e=>1===e});this.rowColumnRatio=getRatio(e.rowColumnRatio);this.startChar=e.startChar||"";this.textLocation=getStringOption(e.textLocation,["below","above","aboveEmbedded","belowEmbedded","none"]);this.truncate=getInteger({data:e.truncate,defaultValue:0,validate:e=>1===e});this.type=getStringOption(e.type?e.type.toLowerCase():"",["aztec","codabar","code2of5industrial","code2of5interleaved","code2of5matrix","code2of5standard","code3of9","code3of9extended","code11","code49","code93","code128","code128a","code128b","code128c","code128sscc","datamatrix","ean8","ean8add2","ean8add5","ean13","ean13add2","ean13add5","ean13pwcd","fim","logmars","maxicode","msi","pdf417","pdf417macro","plessey","postauscust2","postauscust3","postausreplypaid","postausstandard","postukrm4scc","postusdpbc","postusimb","postusstandard","postus5zip","qrcode","rfid","rss14","rss14expanded","rss14limited","rss14stacked","rss14stackedomni","rss14truncated","telepen","ucc128","ucc128random","ucc128sscc","upca","upcaadd2","upcaadd5","upcapwcd","upce","upceadd2","upceadd5","upcean2","upcean5","upsmaxicode"]);this.upsMode=getStringOption(e.upsMode,["usCarrier","internationalCarrier","secureSymbol","standardSymbol"]);this.use=e.use||"";this.usehref=e.usehref||"";this.wideNarrowRatio=getRatio(e.wideNarrowRatio);this.encrypt=null;this.extras=null}}class Bind extends XFAObject{constructor(e){super(Jn,"bind",!0);this.match=getStringOption(e.match,["once","dataRef","global","none"]);this.ref=e.ref||"";this.picture=null}}class BindItems extends XFAObject{constructor(e){super(Jn,"bindItems");this.connection=e.connection||"";this.labelRef=e.labelRef||"";this.ref=e.ref||"";this.valueRef=e.valueRef||""}}class Bookend extends XFAObject{constructor(e){super(Jn,"bookend");this.id=e.id||"";this.leader=e.leader||"";this.trailer=e.trailer||"";this.use=e.use||"";this.usehref=e.usehref||""}}class BooleanElement extends Option01{constructor(e){super(Jn,"boolean");this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}[an](e){return valueToHtml(1===this[er]?"1":"0")}}class Border extends XFAObject{constructor(e){super(Jn,"border",!0);this.break=getStringOption(e.break,["close","open"]);this.hand=getStringOption(e.hand,["even","left","right"]);this.id=e.id||"";this.presence=getStringOption(e.presence,["visible","hidden","inactive","invisible"]);this.relevant=getRelevant(e.relevant);this.use=e.use||"";this.usehref=e.usehref||"";this.corner=new XFAObjectArray(4);this.edge=new XFAObjectArray(4);this.extras=null;this.fill=null;this.margin=null}[Cr](){if(!this[ar]){const e=this.edge.children.slice();if(e.length<4){const t=e.at(-1)||new Edge({});for(let i=e.length;i<4;i++)e.push(t)}const t=e.map((e=>e.thickness)),i=[0,0,0,0];if(this.margin){i[0]=this.margin.topInset;i[1]=this.margin.rightInset;i[2]=this.margin.bottomInset;i[3]=this.margin.leftInset}this[ar]={widths:t,insets:i,edges:e}}return this[ar]}[rn](){const{edges:e}=this[Cr](),t=e.map((e=>{const t=e[rn]();t.color||="#000000";return t})),i=Object.create(null);this.margin&&Object.assign(i,this.margin[rn]());"visible"===this.fill?.presence&&Object.assign(i,this.fill[rn]());if(this.corner.children.some((e=>0!==e.radius))){const e=this.corner.children.map((e=>e[rn]()));if(2===e.length||3===e.length){const t=e.at(-1);for(let i=e.length;i<4;i++)e.push(t)}i.borderRadius=e.map((e=>e.radius)).join(" ")}switch(this.presence){case"invisible":case"hidden":i.borderStyle="";break;case"inactive":i.borderStyle="none";break;default:i.borderStyle=t.map((e=>e.style)).join(" ")}i.borderWidth=t.map((e=>e.width)).join(" ");i.borderColor=t.map((e=>e.color)).join(" ");return i}}class Break extends XFAObject{constructor(e){super(Jn,"break",!0);this.after=getStringOption(e.after,["auto","contentArea","pageArea","pageEven","pageOdd"]);this.afterTarget=e.afterTarget||"";this.before=getStringOption(e.before,["auto","contentArea","pageArea","pageEven","pageOdd"]);this.beforeTarget=e.beforeTarget||"";this.bookendLeader=e.bookendLeader||"";this.bookendTrailer=e.bookendTrailer||"";this.id=e.id||"";this.overflowLeader=e.overflowLeader||"";this.overflowTarget=e.overflowTarget||"";this.overflowTrailer=e.overflowTrailer||"";this.startNew=getInteger({data:e.startNew,defaultValue:0,validate:e=>1===e});this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null}}class BreakAfter extends XFAObject{constructor(e){super(Jn,"breakAfter",!0);this.id=e.id||"";this.leader=e.leader||"";this.startNew=getInteger({data:e.startNew,defaultValue:0,validate:e=>1===e});this.target=e.target||"";this.targetType=getStringOption(e.targetType,["auto","contentArea","pageArea"]);this.trailer=e.trailer||"";this.use=e.use||"";this.usehref=e.usehref||"";this.script=null}}class BreakBefore extends XFAObject{constructor(e){super(Jn,"breakBefore",!0);this.id=e.id||"";this.leader=e.leader||"";this.startNew=getInteger({data:e.startNew,defaultValue:0,validate:e=>1===e});this.target=e.target||"";this.targetType=getStringOption(e.targetType,["auto","contentArea","pageArea"]);this.trailer=e.trailer||"";this.use=e.use||"";this.usehref=e.usehref||"";this.script=null}[an](e){this[ar]={};return HTMLResult.FAILURE}}class Button extends XFAObject{constructor(e){super(Jn,"button",!0);this.highlight=getStringOption(e.highlight,["inverted","none","outline","push"]);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null}[an](e){const t=this[pr]()[pr](),i={name:"button",attributes:{id:this[nn],class:["xfaButton"],style:{}},children:[]};for(const e of t.event.children){if("click"!==e.activity||!e.script)continue;const t=recoverJsURL(e.script[er]);if(!t)continue;const a=fixURL(t.url);a&&i.children.push({name:"a",attributes:{id:"link"+this[nn],href:a,newWindow:t.newWindow,class:["xfaLink"],style:{}},children:[]})}return HTMLResult.success(i)}}class Calculate extends XFAObject{constructor(e){super(Jn,"calculate",!0);this.id=e.id||"";this.override=getStringOption(e.override,["disabled","error","ignore","warning"]);this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null;this.message=null;this.script=null}}class Caption extends XFAObject{constructor(e){super(Jn,"caption",!0);this.id=e.id||"";this.placement=getStringOption(e.placement,["left","bottom","inline","right","top"]);this.presence=getStringOption(e.presence,["visible","hidden","inactive","invisible"]);this.reserve=Math.ceil(getMeasurement(e.reserve));this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null;this.font=null;this.margin=null;this.para=null;this.value=null}[$r](e){_setValue(this,e)}[Cr](e){if(!this[ar]){let{width:t,height:i}=e;switch(this.placement){case"left":case"right":case"inline":t=this.reserve<=0?t:this.reserve;break;case"top":case"bottom":i=this.reserve<=0?i:this.reserve}this[ar]=layoutNode(this,{width:t,height:i})}return this[ar]}[an](e){if(!this.value)return HTMLResult.EMPTY;this[Wr]();const t=this.value[an](e).html;if(!t){this[Pr]();return HTMLResult.EMPTY}const i=this.reserve;if(this.reserve<=0){const{w:t,h:i}=this[Cr](e);switch(this.placement){case"left":case"right":case"inline":this.reserve=t;break;case"top":case"bottom":this.reserve=i}}const a=[];"string"==typeof t?a.push({name:"#text",value:t}):a.push(t);const s=toStyle(this,"font","margin","visibility");switch(this.placement){case"left":case"right":this.reserve>0&&(s.width=measureToString(this.reserve));break;case"top":case"bottom":this.reserve>0&&(s.height=measureToString(this.reserve))}setPara(this,null,t);this[Pr]();this.reserve=i;return HTMLResult.success({name:"div",attributes:{style:s,class:["xfaCaption"]},children:a})}}class Certificate extends StringObject{constructor(e){super(Jn,"certificate");this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}}class Certificates extends XFAObject{constructor(e){super(Jn,"certificates",!0);this.credentialServerPolicy=getStringOption(e.credentialServerPolicy,["optional","required"]);this.id=e.id||"";this.url=e.url||"";this.urlPolicy=e.urlPolicy||"";this.use=e.use||"";this.usehref=e.usehref||"";this.encryption=null;this.issuers=null;this.keyUsage=null;this.oids=null;this.signing=null;this.subjectDNs=null}}class CheckButton extends XFAObject{constructor(e){super(Jn,"checkButton",!0);this.id=e.id||"";this.mark=getStringOption(e.mark,["default","check","circle","cross","diamond","square","star"]);this.shape=getStringOption(e.shape,["square","round"]);this.size=getMeasurement(e.size,"10pt");this.use=e.use||"";this.usehref=e.usehref||"";this.border=null;this.extras=null;this.margin=null}[an](e){const t=toStyle("margin"),i=measureToString(this.size);t.width=t.height=i;let a,s,r;const n=this[pr]()[pr](),o=n.items.children.length&&n.items.children[0][an]().html||[],g={on:(void 0!==o[0]?o[0]:"on").toString(),off:(void 0!==o[1]?o[1]:"off").toString()},c=(n.value?.[en]()||"off")===g.on||void 0,h=n[fr](),l=n[nn];let C;if(h instanceof ExclGroup){r=h[nn];a="radio";s="xfaRadio";C=h[tr]?.[nn]||h[nn]}else{a="checkbox";s="xfaCheckbox";C=n[tr]?.[nn]||n[nn]}const Q={name:"input",attributes:{class:[s],style:t,fieldId:l,dataId:C,type:a,checked:c,xfaOn:g.on,xfaOff:g.off,"aria-label":ariaLabel(n),"aria-required":!1}};r&&(Q.attributes.name=r);if(isRequired(n)){Q.attributes["aria-required"]=!0;Q.attributes.required=!0}return HTMLResult.success({name:"label",attributes:{class:["xfaLabel"]},children:[Q]})}}class ChoiceList extends XFAObject{constructor(e){super(Jn,"choiceList",!0);this.commitOn=getStringOption(e.commitOn,["select","exit"]);this.id=e.id||"";this.open=getStringOption(e.open,["userControl","always","multiSelect","onEntry"]);this.textEntry=getInteger({data:e.textEntry,defaultValue:0,validate:e=>1===e});this.use=e.use||"";this.usehref=e.usehref||"";this.border=null;this.extras=null;this.margin=null}[an](e){const t=toStyle(this,"border","margin"),i=this[pr]()[pr](),a={fontSize:`calc(${i.font?.size||10}px * var(--scale-factor))`},s=[];if(i.items.children.length>0){const e=i.items;let t=0,r=0;if(2===e.children.length){t=e.children[0].save;r=1-t}const n=e.children[t][an]().html,o=e.children[r][an]().html;let g=!1;const c=i.value?.[en]()||"";for(let e=0,t=n.length;e<t;e++){const t={name:"option",attributes:{value:o[e]||n[e],style:a},value:n[e]};o[e]===c&&(t.attributes.selected=g=!0);s.push(t)}g||s.splice(0,0,{name:"option",attributes:{hidden:!0,selected:!0},value:" "})}const r={class:["xfaSelect"],fieldId:i[nn],dataId:i[tr]?.[nn]||i[nn],style:t,"aria-label":ariaLabel(i),"aria-required":!1};if(isRequired(i)){r["aria-required"]=!0;r.required=!0}"multiSelect"===this.open&&(r.multiple=!0);return HTMLResult.success({name:"label",attributes:{class:["xfaLabel"]},children:[{name:"select",children:s,attributes:r}]})}}class Color extends XFAObject{constructor(e){super(Jn,"color",!0);this.cSpace=getStringOption(e.cSpace,["SRGB"]);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||"";this.value=e.value?function getColor(e,t=[0,0,0]){let[i,a,s]=t;if(!e)return{r:i,g:a,b:s};const r=e.trim().split(/\s*,\s*/).map((e=>Math.min(Math.max(0,parseInt(e.trim(),10)),255))).map((e=>isNaN(e)?0:e));if(r.length<3)return{r:i,g:a,b:s};[i,a,s]=r;return{r:i,g:a,b:s}}(e.value):"";this.extras=null}[wr](){return!1}[rn](){return this.value?Util.makeHexColor(this.value.r,this.value.g,this.value.b):null}}class Comb extends XFAObject{constructor(e){super(Jn,"comb");this.id=e.id||"";this.numberOfCells=getInteger({data:e.numberOfCells,defaultValue:0,validate:e=>e>=0});this.use=e.use||"";this.usehref=e.usehref||""}}class Connect extends XFAObject{constructor(e){super(Jn,"connect",!0);this.connection=e.connection||"";this.id=e.id||"";this.ref=e.ref||"";this.usage=getStringOption(e.usage,["exportAndImport","exportOnly","importOnly"]);this.use=e.use||"";this.usehref=e.usehref||"";this.picture=null}}class ContentArea extends XFAObject{constructor(e){super(Jn,"contentArea",!0);this.h=getMeasurement(e.h);this.id=e.id||"";this.name=e.name||"";this.relevant=getRelevant(e.relevant);this.use=e.use||"";this.usehref=e.usehref||"";this.w=getMeasurement(e.w);this.x=getMeasurement(e.x,"0pt");this.y=getMeasurement(e.y,"0pt");this.desc=null;this.extras=null}[an](e){const t={left:measureToString(this.x),top:measureToString(this.y),width:measureToString(this.w),height:measureToString(this.h)},i=["xfaContentarea"];isPrintOnly(this)&&i.push("xfaPrintOnly");return HTMLResult.success({name:"div",children:[],attributes:{style:t,class:i,id:this[nn]}})}}class Corner extends XFAObject{constructor(e){super(Jn,"corner",!0);this.id=e.id||"";this.inverted=getInteger({data:e.inverted,defaultValue:0,validate:e=>1===e});this.join=getStringOption(e.join,["square","round"]);this.presence=getStringOption(e.presence,["visible","hidden","inactive","invisible"]);this.radius=getMeasurement(e.radius);this.stroke=getStringOption(e.stroke,["solid","dashDot","dashDotDot","dashed","dotted","embossed","etched","lowered","raised"]);this.thickness=getMeasurement(e.thickness,"0.5pt");this.use=e.use||"";this.usehref=e.usehref||"";this.color=null;this.extras=null}[rn](){const e=toStyle(this,"visibility");e.radius=measureToString("square"===this.join?0:this.radius);return e}}class DateElement extends ContentObject{constructor(e){super(Jn,"date");this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}[sr](){const e=this[er].trim();this[er]=e?new Date(e):null}[an](e){return valueToHtml(this[er]?this[er].toString():"")}}class DateTime extends ContentObject{constructor(e){super(Jn,"dateTime");this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}[sr](){const e=this[er].trim();this[er]=e?new Date(e):null}[an](e){return valueToHtml(this[er]?this[er].toString():"")}}class DateTimeEdit extends XFAObject{constructor(e){super(Jn,"dateTimeEdit",!0);this.hScrollPolicy=getStringOption(e.hScrollPolicy,["auto","off","on"]);this.id=e.id||"";this.picker=getStringOption(e.picker,["host","none"]);this.use=e.use||"";this.usehref=e.usehref||"";this.border=null;this.comb=null;this.extras=null;this.margin=null}[an](e){const t=toStyle(this,"border","font","margin"),i=this[pr]()[pr](),a={name:"input",attributes:{type:"text",fieldId:i[nn],dataId:i[tr]?.[nn]||i[nn],class:["xfaTextfield"],style:t,"aria-label":ariaLabel(i),"aria-required":!1}};if(isRequired(i)){a.attributes["aria-required"]=!0;a.attributes.required=!0}return HTMLResult.success({name:"label",attributes:{class:["xfaLabel"]},children:[a]})}}class Decimal extends ContentObject{constructor(e){super(Jn,"decimal");this.fracDigits=getInteger({data:e.fracDigits,defaultValue:2,validate:e=>!0});this.id=e.id||"";this.leadDigits=getInteger({data:e.leadDigits,defaultValue:-1,validate:e=>!0});this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}[sr](){const e=parseFloat(this[er].trim());this[er]=isNaN(e)?null:e}[an](e){return valueToHtml(null!==this[er]?this[er].toString():"")}}class DefaultUi extends XFAObject{constructor(e){super(Jn,"defaultUi",!0);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null}}class Desc extends XFAObject{constructor(e){super(Jn,"desc",!0);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||"";this.boolean=new XFAObjectArray;this.date=new XFAObjectArray;this.dateTime=new XFAObjectArray;this.decimal=new XFAObjectArray;this.exData=new XFAObjectArray;this.float=new XFAObjectArray;this.image=new XFAObjectArray;this.integer=new XFAObjectArray;this.text=new XFAObjectArray;this.time=new XFAObjectArray}}class DigestMethod extends OptionObject{constructor(e){super(Jn,"digestMethod",["","SHA1","SHA256","SHA512","RIPEMD160"]);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||""}}class DigestMethods extends XFAObject{constructor(e){super(Jn,"digestMethods",!0);this.id=e.id||"";this.type=getStringOption(e.type,["optional","required"]);this.use=e.use||"";this.usehref=e.usehref||"";this.digestMethod=new XFAObjectArray}}class Draw extends XFAObject{constructor(e){super(Jn,"draw",!0);this.anchorType=getStringOption(e.anchorType,["topLeft","bottomCenter","bottomLeft","bottomRight","middleCenter","middleLeft","middleRight","topCenter","topRight"]);this.colSpan=getInteger({data:e.colSpan,defaultValue:1,validate:e=>e>=1||-1===e});this.h=e.h?getMeasurement(e.h):"";this.hAlign=getStringOption(e.hAlign,["left","center","justify","justifyAll","radix","right"]);this.id=e.id||"";this.locale=e.locale||"";this.maxH=getMeasurement(e.maxH,"0pt");this.maxW=getMeasurement(e.maxW,"0pt");this.minH=getMeasurement(e.minH,"0pt");this.minW=getMeasurement(e.minW,"0pt");this.name=e.name||"";this.presence=getStringOption(e.presence,["visible","hidden","inactive","invisible"]);this.relevant=getRelevant(e.relevant);this.rotate=getInteger({data:e.rotate,defaultValue:0,validate:e=>e%90==0});this.use=e.use||"";this.usehref=e.usehref||"";this.w=e.w?getMeasurement(e.w):"";this.x=getMeasurement(e.x,"0pt");this.y=getMeasurement(e.y,"0pt");this.assist=null;this.border=null;this.caption=null;this.desc=null;this.extras=null;this.font=null;this.keep=null;this.margin=null;this.para=null;this.traversal=null;this.ui=null;this.value=null;this.setProperty=new XFAObjectArray}[$r](e){_setValue(this,e)}[an](e){setTabIndex(this);if("hidden"===this.presence||"inactive"===this.presence)return HTMLResult.EMPTY;fixDimensions(this);this[Wr]();const t=this.w,i=this.h,{w:a,h:s,isBroken:r}=layoutNode(this,e);if(a&&""===this.w){if(r&&this[fr]()[Mr]()){this[Pr]();return HTMLResult.FAILURE}this.w=a}s&&""===this.h&&(this.h=s);setFirstUnsplittable(this);if(!checkDimensions(this,e)){this.w=t;this.h=i;this[Pr]();return HTMLResult.FAILURE}unsetFirstUnsplittable(this);const n=toStyle(this,"font","hAlign","dimensions","position","presence","rotate","anchorType","border","margin");setMinMaxDimensions(this,n);if(n.margin){n.padding=n.margin;delete n.margin}const o=["xfaDraw"];this.font&&o.push("xfaFont");isPrintOnly(this)&&o.push("xfaPrintOnly");const g={style:n,id:this[nn],class:o};this.name&&(g.xfaName=this.name);const c={name:"div",attributes:g,children:[]};applyAssist(this,g);const h=computeBbox(this,c,e),l=this.value?this.value[an](e).html:null;if(null===l){this.w=t;this.h=i;this[Pr]();return HTMLResult.success(createWrapper(this,c),h)}c.children.push(l);setPara(this,n,l);this.w=t;this.h=i;this[Pr]();return HTMLResult.success(createWrapper(this,c),h)}}class Edge extends XFAObject{constructor(e){super(Jn,"edge",!0);this.cap=getStringOption(e.cap,["square","butt","round"]);this.id=e.id||"";this.presence=getStringOption(e.presence,["visible","hidden","inactive","invisible"]);this.stroke=getStringOption(e.stroke,["solid","dashDot","dashDotDot","dashed","dotted","embossed","etched","lowered","raised"]);this.thickness=getMeasurement(e.thickness,"0.5pt");this.use=e.use||"";this.usehref=e.usehref||"";this.color=null;this.extras=null}[rn](){const e=toStyle(this,"visibility");Object.assign(e,{linecap:this.cap,width:measureToString(this.thickness),color:this.color?this.color[rn]():"#000000",style:""});if("visible"!==this.presence)e.style="none";else switch(this.stroke){case"solid":e.style="solid";break;case"dashDot":case"dashDotDot":case"dashed":e.style="dashed";break;case"dotted":e.style="dotted";break;case"embossed":e.style="ridge";break;case"etched":e.style="groove";break;case"lowered":e.style="inset";break;case"raised":e.style="outset"}return e}}class Encoding extends OptionObject{constructor(e){super(Jn,"encoding",["adbe.x509.rsa_sha1","adbe.pkcs7.detached","adbe.pkcs7.sha1"]);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||""}}class Encodings extends XFAObject{constructor(e){super(Jn,"encodings",!0);this.id=e.id||"";this.type=getStringOption(e.type,["optional","required"]);this.use=e.use||"";this.usehref=e.usehref||"";this.encoding=new XFAObjectArray}}class Encrypt extends XFAObject{constructor(e){super(Jn,"encrypt",!0);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||"";this.certificate=null}}class EncryptData extends XFAObject{constructor(e){super(Jn,"encryptData",!0);this.id=e.id||"";this.operation=getStringOption(e.operation,["encrypt","decrypt"]);this.target=e.target||"";this.use=e.use||"";this.usehref=e.usehref||"";this.filter=null;this.manifest=null}}class Encryption extends XFAObject{constructor(e){super(Jn,"encryption",!0);this.id=e.id||"";this.type=getStringOption(e.type,["optional","required"]);this.use=e.use||"";this.usehref=e.usehref||"";this.certificate=new XFAObjectArray}}class EncryptionMethod extends OptionObject{constructor(e){super(Jn,"encryptionMethod",["","AES256-CBC","TRIPLEDES-CBC","AES128-CBC","AES192-CBC"]);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||""}}class EncryptionMethods extends XFAObject{constructor(e){super(Jn,"encryptionMethods",!0);this.id=e.id||"";this.type=getStringOption(e.type,["optional","required"]);this.use=e.use||"";this.usehref=e.usehref||"";this.encryptionMethod=new XFAObjectArray}}class Event extends XFAObject{constructor(e){super(Jn,"event",!0);this.activity=getStringOption(e.activity,["click","change","docClose","docReady","enter","exit","full","indexChange","initialize","mouseDown","mouseEnter","mouseExit","mouseUp","postExecute","postOpen","postPrint","postSave","postSign","postSubmit","preExecute","preOpen","prePrint","preSave","preSign","preSubmit","ready","validationState"]);this.id=e.id||"";this.listen=getStringOption(e.listen,["refOnly","refAndDescendents"]);this.name=e.name||"";this.ref=e.ref||"";this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null;this.encryptData=null;this.execute=null;this.script=null;this.signData=null;this.submit=null}}class ExData extends ContentObject{constructor(e){super(Jn,"exData");this.contentType=e.contentType||"";this.href=e.href||"";this.id=e.id||"";this.maxLength=getInteger({data:e.maxLength,defaultValue:-1,validate:e=>e>=-1});this.name=e.name||"";this.rid=e.rid||"";this.transferEncoding=getStringOption(e.transferEncoding,["none","base64","package"]);this.use=e.use||"";this.usehref=e.usehref||""}[Sr](){return"text/html"===this.contentType}[Kr](e){if("text/html"===this.contentType&&e[Hr]===gn.xhtml.id){this[er]=e;return!0}if("text/xml"===this.contentType){this[er]=e;return!0}return!1}[an](e){return"text/html"===this.contentType&&this[er]?this[er][an](e):HTMLResult.EMPTY}}class ExObject extends XFAObject{constructor(e){super(Jn,"exObject",!0);this.archive=e.archive||"";this.classId=e.classId||"";this.codeBase=e.codeBase||"";this.codeType=e.codeType||"";this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null;this.boolean=new XFAObjectArray;this.date=new XFAObjectArray;this.dateTime=new XFAObjectArray;this.decimal=new XFAObjectArray;this.exData=new XFAObjectArray;this.exObject=new XFAObjectArray;this.float=new XFAObjectArray;this.image=new XFAObjectArray;this.integer=new XFAObjectArray;this.text=new XFAObjectArray;this.time=new XFAObjectArray}}class ExclGroup extends XFAObject{constructor(e){super(Jn,"exclGroup",!0);this.access=getStringOption(e.access,["open","nonInteractive","protected","readOnly"]);this.accessKey=e.accessKey||"";this.anchorType=getStringOption(e.anchorType,["topLeft","bottomCenter","bottomLeft","bottomRight","middleCenter","middleLeft","middleRight","topCenter","topRight"]);this.colSpan=getInteger({data:e.colSpan,defaultValue:1,validate:e=>e>=1||-1===e});this.h=e.h?getMeasurement(e.h):"";this.hAlign=getStringOption(e.hAlign,["left","center","justify","justifyAll","radix","right"]);this.id=e.id||"";this.layout=getStringOption(e.layout,["position","lr-tb","rl-row","rl-tb","row","table","tb"]);this.maxH=getMeasurement(e.maxH,"0pt");this.maxW=getMeasurement(e.maxW,"0pt");this.minH=getMeasurement(e.minH,"0pt");this.minW=getMeasurement(e.minW,"0pt");this.name=e.name||"";this.presence=getStringOption(e.presence,["visible","hidden","inactive","invisible"]);this.relevant=getRelevant(e.relevant);this.use=e.use||"";this.usehref=e.usehref||"";this.w=e.w?getMeasurement(e.w):"";this.x=getMeasurement(e.x,"0pt");this.y=getMeasurement(e.y,"0pt");this.assist=null;this.bind=null;this.border=null;this.calculate=null;this.caption=null;this.desc=null;this.extras=null;this.margin=null;this.para=null;this.traversal=null;this.validate=null;this.connect=new XFAObjectArray;this.event=new XFAObjectArray;this.field=new XFAObjectArray;this.setProperty=new XFAObjectArray}[kr](){return!0}[wr](){return!0}[$r](e){for(const t of this.field.children){if(!t.value){const e=new Value({});t[js](e);t.value=e}t.value[$r](e)}}[Mr](){return this.layout.endsWith("-tb")&&0===this[ar].attempt&&this[ar].numberInLine>0||this[pr]()[Mr]()}[xr](){const e=this[fr]();if(!e[xr]())return!1;if(void 0!==this[ar]._isSplittable)return this[ar]._isSplittable;if("position"===this.layout||this.layout.includes("row")){this[ar]._isSplittable=!1;return!1}if(e.layout?.endsWith("-tb")&&0!==e[ar].numberInLine)return!1;this[ar]._isSplittable=!0;return!0}[rr](){return flushHTML(this)}[Xs](e,t){addHTML(this,e,t)}[gr](){return getAvailableSpace(this)}[an](e){setTabIndex(this);if("hidden"===this.presence||"inactive"===this.presence||0===this.h||0===this.w)return HTMLResult.EMPTY;fixDimensions(this);const t=[],i={id:this[nn],class:[]};setAccess(this,i.class);this[ar]||(this[ar]=Object.create(null));Object.assign(this[ar],{children:t,attributes:i,attempt:0,line:null,numberInLine:0,availableSpace:{width:Math.min(this.w||1/0,e.width),height:Math.min(this.h||1/0,e.height)},width:0,height:0,prevHeight:0,currentWidth:0});const a=this[xr]();a||setFirstUnsplittable(this);if(!checkDimensions(this,e))return HTMLResult.FAILURE;const s=new Set(["field"]);if(this.layout.includes("row")){const e=this[fr]().columnWidths;if(Array.isArray(e)&&e.length>0){this[ar].columnWidths=e;this[ar].currentColumn=0}}const r=toStyle(this,"anchorType","dimensions","position","presence","border","margin","hAlign"),n=["xfaExclgroup"],o=layoutClass(this);o&&n.push(o);isPrintOnly(this)&&n.push("xfaPrintOnly");i.style=r;i.class=n;this.name&&(i.xfaName=this.name);this[Wr]();const g="lr-tb"===this.layout||"rl-tb"===this.layout,c=g?2:1;for(;this[ar].attempt<c;this[ar].attempt++){g&&1===this[ar].attempt&&(this[ar].numberInLine=0);const e=this[Zs]({filter:s,include:!0});if(e.success)break;if(e.isBreak()){this[Pr]();return e}if(g&&0===this[ar].attempt&&0===this[ar].numberInLine&&!this[mr]()[ar].noLayoutFailure){this[ar].attempt=c;break}}this[Pr]();a||unsetFirstUnsplittable(this);if(this[ar].attempt===c){a||delete this[ar];return HTMLResult.FAILURE}let h=0,l=0;if(this.margin){h=this.margin.leftInset+this.margin.rightInset;l=this.margin.topInset+this.margin.bottomInset}const C=Math.max(this[ar].width+h,this.w||0),Q=Math.max(this[ar].height+l,this.h||0),E=[this.x,this.y,C,Q];""===this.w&&(r.width=measureToString(C));""===this.h&&(r.height=measureToString(Q));const u={name:"div",attributes:i,children:t};applyAssist(this,i);delete this[ar];return HTMLResult.success(createWrapper(this,u),E)}}class Execute extends XFAObject{constructor(e){super(Jn,"execute");this.connection=e.connection||"";this.executeType=getStringOption(e.executeType,["import","remerge"]);this.id=e.id||"";this.runAt=getStringOption(e.runAt,["client","both","server"]);this.use=e.use||"";this.usehref=e.usehref||""}}class Extras extends XFAObject{constructor(e){super(Jn,"extras",!0);this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||"";this.boolean=new XFAObjectArray;this.date=new XFAObjectArray;this.dateTime=new XFAObjectArray;this.decimal=new XFAObjectArray;this.exData=new XFAObjectArray;this.extras=new XFAObjectArray;this.float=new XFAObjectArray;this.image=new XFAObjectArray;this.integer=new XFAObjectArray;this.text=new XFAObjectArray;this.time=new XFAObjectArray}}class Field extends XFAObject{constructor(e){super(Jn,"field",!0);this.access=getStringOption(e.access,["open","nonInteractive","protected","readOnly"]);this.accessKey=e.accessKey||"";this.anchorType=getStringOption(e.anchorType,["topLeft","bottomCenter","bottomLeft","bottomRight","middleCenter","middleLeft","middleRight","topCenter","topRight"]);this.colSpan=getInteger({data:e.colSpan,defaultValue:1,validate:e=>e>=1||-1===e});this.h=e.h?getMeasurement(e.h):"";this.hAlign=getStringOption(e.hAlign,["left","center","justify","justifyAll","radix","right"]);this.id=e.id||"";this.locale=e.locale||"";this.maxH=getMeasurement(e.maxH,"0pt");this.maxW=getMeasurement(e.maxW,"0pt");this.minH=getMeasurement(e.minH,"0pt");this.minW=getMeasurement(e.minW,"0pt");this.name=e.name||"";this.presence=getStringOption(e.presence,["visible","hidden","inactive","invisible"]);this.relevant=getRelevant(e.relevant);this.rotate=getInteger({data:e.rotate,defaultValue:0,validate:e=>e%90==0});this.use=e.use||"";this.usehref=e.usehref||"";this.w=e.w?getMeasurement(e.w):"";this.x=getMeasurement(e.x,"0pt");this.y=getMeasurement(e.y,"0pt");this.assist=null;this.bind=null;this.border=null;this.calculate=null;this.caption=null;this.desc=null;this.extras=null;this.font=null;this.format=null;this.items=new XFAObjectArray(2);this.keep=null;this.margin=null;this.para=null;this.traversal=null;this.ui=null;this.validate=null;this.value=null;this.bindItems=new XFAObjectArray;this.connect=new XFAObjectArray;this.event=new XFAObjectArray;this.setProperty=new XFAObjectArray}[kr](){return!0}[$r](e){_setValue(this,e)}[an](e){setTabIndex(this);if(!this.ui){this.ui=new Ui({});this.ui[yr]=this[yr];this[js](this.ui);let e;switch(this.items.children.length){case 0:e=new TextEdit({});this.ui.textEdit=e;break;case 1:e=new CheckButton({});this.ui.checkButton=e;break;case 2:e=new ChoiceList({});this.ui.choiceList=e}this.ui[js](e)}if(!this.ui||"hidden"===this.presence||"inactive"===this.presence||0===this.h||0===this.w)return HTMLResult.EMPTY;this.caption&&delete this.caption[ar];this[Wr]();const t=this.caption?this.caption[an](e).html:null,i=this.w,a=this.h;let s=0,r=0;if(this.margin){s=this.margin.leftInset+this.margin.rightInset;r=this.margin.topInset+this.margin.bottomInset}let n=null;if(""===this.w||""===this.h){let t=null,i=null,a=0,o=0;if(this.ui.checkButton)a=o=this.ui.checkButton.size;else{const{w:t,h:i}=layoutNode(this,e);if(null!==t){a=t;o=i}else o=function fonts_getMetrics(e,t=!1){let i=null;if(e){const t=stripQuotes(e.typeface),a=e[yr].fontFinder.find(t);i=selectFont(e,a)}if(!i)return{lineHeight:12,lineGap:2,lineNoGap:10};const a=e.size||10,s=i.lineHeight?Math.max(t?0:1.2,i.lineHeight):1.2,r=void 0===i.lineGap?.2:i.lineGap;return{lineHeight:s*a,lineGap:r*a,lineNoGap:Math.max(1,s-r)*a}}(this.font,!0).lineNoGap}n=getBorderDims(this.ui[Cr]());a+=n.w;o+=n.h;if(this.caption){const{w:s,h:r,isBroken:n}=this.caption[Cr](e);if(n&&this[fr]()[Mr]()){this[Pr]();return HTMLResult.FAILURE}t=s;i=r;switch(this.caption.placement){case"left":case"right":case"inline":t+=a;break;case"top":case"bottom":i+=o}}else{t=a;i=o}if(t&&""===this.w){t+=s;this.w=Math.min(this.maxW<=0?1/0:this.maxW,this.minW+1<t?t:this.minW)}if(i&&""===this.h){i+=r;this.h=Math.min(this.maxH<=0?1/0:this.maxH,this.minH+1<i?i:this.minH)}}this[Pr]();fixDimensions(this);setFirstUnsplittable(this);if(!checkDimensions(this,e)){this.w=i;this.h=a;this[Pr]();return HTMLResult.FAILURE}unsetFirstUnsplittable(this);const o=toStyle(this,"font","dimensions","position","rotate","anchorType","presence","margin","hAlign");setMinMaxDimensions(this,o);const g=["xfaField"];this.font&&g.push("xfaFont");isPrintOnly(this)&&g.push("xfaPrintOnly");const c={style:o,id:this[nn],class:g};if(o.margin){o.padding=o.margin;delete o.margin}setAccess(this,g);this.name&&(c.xfaName=this.name);const h=[],l={name:"div",attributes:c,children:h};applyAssist(this,c);const C=this.border?this.border[rn]():null,Q=computeBbox(this,l,e),E=this.ui[an]().html;if(!E){Object.assign(o,C);return HTMLResult.success(createWrapper(this,l),Q)}this[An]&&(E.children?.[0]?E.children[0].attributes.tabindex=this[An]:E.attributes.tabindex=this[An]);E.attributes.style||(E.attributes.style=Object.create(null));let u=null;if(this.ui.button){1===E.children.length&&([u]=E.children.splice(0,1));Object.assign(E.attributes.style,C)}else Object.assign(o,C);h.push(E);if(this.value)if(this.ui.imageEdit)E.children.push(this.value[an]().html);else if(!this.ui.button){let e="";if(this.value.exData)e=this.value.exData[en]();else if(this.value.text)e=this.value.text[Cr]();else{const t=this.value[an]().html;null!==t&&(e=t.children[0].value)}this.ui.textEdit&&this.value.text?.maxChars&&(E.children[0].attributes.maxLength=this.value.text.maxChars);if(e){if(this.ui.numericEdit){e=parseFloat(e);e=isNaN(e)?"":e.toString()}"textarea"===E.children[0].name?E.children[0].attributes.textContent=e:E.children[0].attributes.value=e}}if(!this.ui.imageEdit&&E.children?.[0]&&this.h){n=n||getBorderDims(this.ui[Cr]());let t=0;if(this.caption&&["top","bottom"].includes(this.caption.placement)){t=this.caption.reserve;t<=0&&(t=this.caption[Cr](e).h);const i=this.h-t-r-n.h;E.children[0].attributes.style.height=measureToString(i)}else E.children[0].attributes.style.height="100%"}u&&E.children.push(u);if(!t){E.attributes.class&&E.attributes.class.push("xfaLeft");this.w=i;this.h=a;return HTMLResult.success(createWrapper(this,l),Q)}if(this.ui.button){o.padding&&delete o.padding;"div"===t.name&&(t.name="span");E.children.push(t);return HTMLResult.success(l,Q)}this.ui.checkButton&&(t.attributes.class[0]="xfaCaptionForCheckButton");E.attributes.class||(E.attributes.class=[]);E.children.splice(0,0,t);switch(this.caption.placement){case"left":case"inline":E.attributes.class.push("xfaLeft");break;case"right":E.attributes.class.push("xfaRight");break;case"top":E.attributes.class.push("xfaTop");break;case"bottom":E.attributes.class.push("xfaBottom")}this.w=i;this.h=a;return HTMLResult.success(createWrapper(this,l),Q)}}class Fill extends XFAObject{constructor(e){super(Jn,"fill",!0);this.id=e.id||"";this.presence=getStringOption(e.presence,["visible","hidden","inactive","invisible"]);this.use=e.use||"";this.usehref=e.usehref||"";this.color=null;this.extras=null;this.linear=null;this.pattern=null;this.radial=null;this.solid=null;this.stipple=null}[rn](){const e=this[pr](),t=e[pr]()[pr](),i=Object.create(null);let a="color",s=a;if(e instanceof Border){a="background-color";s="background";t instanceof Ui&&(i.backgroundColor="white")}if(e instanceof Rectangle||e instanceof Arc){a=s="fill";i.fill="white"}for(const e of Object.getOwnPropertyNames(this)){if("extras"===e||"color"===e)continue;const t=this[e];if(!(t instanceof XFAObject))continue;const r=t[rn](this.color);r&&(i[r.startsWith("#")?a:s]=r);return i}if(this.color?.value){const e=this.color[rn]();i[e.startsWith("#")?a:s]=e}return i}}class Filter extends XFAObject{constructor(e){super(Jn,"filter",!0);this.addRevocationInfo=getStringOption(e.addRevocationInfo,["","required","optional","none"]);this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||"";this.version=getInteger({data:this.version,defaultValue:5,validate:e=>e>=1&&e<=5});this.appearanceFilter=null;this.certificates=null;this.digestMethods=null;this.encodings=null;this.encryptionMethods=null;this.handler=null;this.lockDocument=null;this.mdp=null;this.reasons=null;this.timeStamp=null}}class Float extends ContentObject{constructor(e){super(Jn,"float");this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}[sr](){const e=parseFloat(this[er].trim());this[er]=isNaN(e)?null:e}[an](e){return valueToHtml(null!==this[er]?this[er].toString():"")}}class template_Font extends XFAObject{constructor(e){super(Jn,"font",!0);this.baselineShift=getMeasurement(e.baselineShift);this.fontHorizontalScale=getFloat({data:e.fontHorizontalScale,defaultValue:100,validate:e=>e>=0});this.fontVerticalScale=getFloat({data:e.fontVerticalScale,defaultValue:100,validate:e=>e>=0});this.id=e.id||"";this.kerningMode=getStringOption(e.kerningMode,["none","pair"]);this.letterSpacing=getMeasurement(e.letterSpacing,"0");this.lineThrough=getInteger({data:e.lineThrough,defaultValue:0,validate:e=>1===e||2===e});this.lineThroughPeriod=getStringOption(e.lineThroughPeriod,["all","word"]);this.overline=getInteger({data:e.overline,defaultValue:0,validate:e=>1===e||2===e});this.overlinePeriod=getStringOption(e.overlinePeriod,["all","word"]);this.posture=getStringOption(e.posture,["normal","italic"]);this.size=getMeasurement(e.size,"10pt");this.typeface=e.typeface||"Courier";this.underline=getInteger({data:e.underline,defaultValue:0,validate:e=>1===e||2===e});this.underlinePeriod=getStringOption(e.underlinePeriod,["all","word"]);this.use=e.use||"";this.usehref=e.usehref||"";this.weight=getStringOption(e.weight,["normal","bold"]);this.extras=null;this.fill=null}[Vs](e){super[Vs](e);this[yr].usedTypefaces.add(this.typeface)}[rn](){const e=toStyle(this,"fill"),t=e.color;if(t)if("#000000"===t)delete e.color;else if(!t.startsWith("#")){e.background=t;e.backgroundClip="text";e.color="transparent"}this.baselineShift&&(e.verticalAlign=measureToString(this.baselineShift));e.fontKerning="none"===this.kerningMode?"none":"normal";e.letterSpacing=measureToString(this.letterSpacing);if(0!==this.lineThrough){e.textDecoration="line-through";2===this.lineThrough&&(e.textDecorationStyle="double")}if(0!==this.overline){e.textDecoration="overline";2===this.overline&&(e.textDecorationStyle="double")}e.fontStyle=this.posture;e.fontSize=measureToString(.99*this.size);setFontFamily(this,this,this[yr].fontFinder,e);if(0!==this.underline){e.textDecoration="underline";2===this.underline&&(e.textDecorationStyle="double")}e.fontWeight=this.weight;return e}}class Format extends XFAObject{constructor(e){super(Jn,"format",!0);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null;this.picture=null}}class Handler extends StringObject{constructor(e){super(Jn,"handler");this.id=e.id||"";this.type=getStringOption(e.type,["optional","required"]);this.use=e.use||"";this.usehref=e.usehref||""}}class Hyphenation extends XFAObject{constructor(e){super(Jn,"hyphenation");this.excludeAllCaps=getInteger({data:e.excludeAllCaps,defaultValue:0,validate:e=>1===e});this.excludeInitialCap=getInteger({data:e.excludeInitialCap,defaultValue:0,validate:e=>1===e});this.hyphenate=getInteger({data:e.hyphenate,defaultValue:0,validate:e=>1===e});this.id=e.id||"";this.pushCharacterCount=getInteger({data:e.pushCharacterCount,defaultValue:3,validate:e=>e>=0});this.remainCharacterCount=getInteger({data:e.remainCharacterCount,defaultValue:3,validate:e=>e>=0});this.use=e.use||"";this.usehref=e.usehref||"";this.wordCharacterCount=getInteger({data:e.wordCharacterCount,defaultValue:7,validate:e=>e>=0})}}class Image extends StringObject{constructor(e){super(Jn,"image");this.aspect=getStringOption(e.aspect,["fit","actual","height","none","width"]);this.contentType=e.contentType||"";this.href=e.href||"";this.id=e.id||"";this.name=e.name||"";this.transferEncoding=getStringOption(e.transferEncoding,["base64","none","package"]);this.use=e.use||"";this.usehref=e.usehref||""}[an](){if(this.contentType&&!vn.has(this.contentType.toLowerCase()))return HTMLResult.EMPTY;let e=this[yr].images&&this[yr].images.get(this.href);if(!e&&(this.href||!this[er]))return HTMLResult.EMPTY;e||"base64"!==this.transferEncoding||(e=stringToBytes(atob(this[er])));if(!e)return HTMLResult.EMPTY;if(!this.contentType){for(const[t,i]of Kn)if(e.length>t.length&&t.every(((t,i)=>t===e[i]))){this.contentType=i;break}if(!this.contentType)return HTMLResult.EMPTY}const t=new Blob([e],{type:this.contentType});let i;switch(this.aspect){case"fit":case"actual":break;case"height":i={height:"100%",objectFit:"fill"};break;case"none":i={width:"100%",height:"100%",objectFit:"fill"};break;case"width":i={width:"100%",objectFit:"fill"}}const a=this[pr]();return HTMLResult.success({name:"img",attributes:{class:["xfaImage"],style:i,src:URL.createObjectURL(t),alt:a?ariaLabel(a[pr]()):null}})}}class ImageEdit extends XFAObject{constructor(e){super(Jn,"imageEdit",!0);this.data=getStringOption(e.data,["link","embed"]);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||"";this.border=null;this.extras=null;this.margin=null}[an](e){return"embed"===this.data?HTMLResult.success({name:"div",children:[],attributes:{}}):HTMLResult.EMPTY}}class Integer extends ContentObject{constructor(e){super(Jn,"integer");this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}[sr](){const e=parseInt(this[er].trim(),10);this[er]=isNaN(e)?null:e}[an](e){return valueToHtml(null!==this[er]?this[er].toString():"")}}class Issuers extends XFAObject{constructor(e){super(Jn,"issuers",!0);this.id=e.id||"";this.type=getStringOption(e.type,["optional","required"]);this.use=e.use||"";this.usehref=e.usehref||"";this.certificate=new XFAObjectArray}}class Items extends XFAObject{constructor(e){super(Jn,"items",!0);this.id=e.id||"";this.name=e.name||"";this.presence=getStringOption(e.presence,["visible","hidden","inactive","invisible"]);this.ref=e.ref||"";this.save=getInteger({data:e.save,defaultValue:0,validate:e=>1===e});this.use=e.use||"";this.usehref=e.usehref||"";this.boolean=new XFAObjectArray;this.date=new XFAObjectArray;this.dateTime=new XFAObjectArray;this.decimal=new XFAObjectArray;this.exData=new XFAObjectArray;this.float=new XFAObjectArray;this.image=new XFAObjectArray;this.integer=new XFAObjectArray;this.text=new XFAObjectArray;this.time=new XFAObjectArray}[an](){const e=[];for(const t of this[Er]())e.push(t[en]());return HTMLResult.success(e)}}class Keep extends XFAObject{constructor(e){super(Jn,"keep",!0);this.id=e.id||"";const t=["none","contentArea","pageArea"];this.intact=getStringOption(e.intact,t);this.next=getStringOption(e.next,t);this.previous=getStringOption(e.previous,t);this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null}}class KeyUsage extends XFAObject{constructor(e){super(Jn,"keyUsage");const t=["","yes","no"];this.crlSign=getStringOption(e.crlSign,t);this.dataEncipherment=getStringOption(e.dataEncipherment,t);this.decipherOnly=getStringOption(e.decipherOnly,t);this.digitalSignature=getStringOption(e.digitalSignature,t);this.encipherOnly=getStringOption(e.encipherOnly,t);this.id=e.id||"";this.keyAgreement=getStringOption(e.keyAgreement,t);this.keyCertSign=getStringOption(e.keyCertSign,t);this.keyEncipherment=getStringOption(e.keyEncipherment,t);this.nonRepudiation=getStringOption(e.nonRepudiation,t);this.type=getStringOption(e.type,["optional","required"]);this.use=e.use||"";this.usehref=e.usehref||""}}class Line extends XFAObject{constructor(e){super(Jn,"line",!0);this.hand=getStringOption(e.hand,["even","left","right"]);this.id=e.id||"";this.slope=getStringOption(e.slope,["\\","/"]);this.use=e.use||"";this.usehref=e.usehref||"";this.edge=null}[an](){const e=this[pr]()[pr](),t=this.edge||new Edge({}),i=t[rn](),a=Object.create(null),s="visible"===t.presence?t.thickness:0;a.strokeWidth=measureToString(s);a.stroke=i.color;let r,n,o,g,c="100%",h="100%";if(e.w<=s){[r,n,o,g]=["50%",0,"50%","100%"];c=a.strokeWidth}else if(e.h<=s){[r,n,o,g]=[0,"50%","100%","50%"];h=a.strokeWidth}else"\\"===this.slope?[r,n,o,g]=[0,0,"100%","100%"]:[r,n,o,g]=[0,"100%","100%",0];const l={name:"svg",children:[{name:"line",attributes:{xmlns:Hn,x1:r,y1:n,x2:o,y2:g,style:a}}],attributes:{xmlns:Hn,width:c,height:h,style:{overflow:"visible"}}};if(hasMargin(e))return HTMLResult.success({name:"div",attributes:{style:{display:"inline",width:"100%",height:"100%"}},children:[l]});l.attributes.style.position="absolute";return HTMLResult.success(l)}}class Linear extends XFAObject{constructor(e){super(Jn,"linear",!0);this.id=e.id||"";this.type=getStringOption(e.type,["toRight","toBottom","toLeft","toTop"]);this.use=e.use||"";this.usehref=e.usehref||"";this.color=null;this.extras=null}[rn](e){e=e?e[rn]():"#FFFFFF";return`linear-gradient(${this.type.replace(/([RBLT])/," $1").toLowerCase()}, ${e}, ${this.color?this.color[rn]():"#000000"})`}}class LockDocument extends ContentObject{constructor(e){super(Jn,"lockDocument");this.id=e.id||"";this.type=getStringOption(e.type,["optional","required"]);this.use=e.use||"";this.usehref=e.usehref||""}[sr](){this[er]=getStringOption(this[er],["auto","0","1"])}}class Manifest extends XFAObject{constructor(e){super(Jn,"manifest",!0);this.action=getStringOption(e.action,["include","all","exclude"]);this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null;this.ref=new XFAObjectArray}}class Margin extends XFAObject{constructor(e){super(Jn,"margin",!0);this.bottomInset=getMeasurement(e.bottomInset,"0");this.id=e.id||"";this.leftInset=getMeasurement(e.leftInset,"0");this.rightInset=getMeasurement(e.rightInset,"0");this.topInset=getMeasurement(e.topInset,"0");this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null}[rn](){return{margin:measureToString(this.topInset)+" "+measureToString(this.rightInset)+" "+measureToString(this.bottomInset)+" "+measureToString(this.leftInset)}}}class Mdp extends XFAObject{constructor(e){super(Jn,"mdp");this.id=e.id||"";this.permissions=getInteger({data:e.permissions,defaultValue:2,validate:e=>1===e||3===e});this.signatureType=getStringOption(e.signatureType,["filler","author"]);this.use=e.use||"";this.usehref=e.usehref||""}}class Medium extends XFAObject{constructor(e){super(Jn,"medium");this.id=e.id||"";this.imagingBBox=function getBBox(e){const t=-1;if(!e)return{x:t,y:t,width:t,height:t};const i=e.trim().split(/\s*,\s*/).map((e=>getMeasurement(e,"-1")));if(i.length<4||i[2]<0||i[3]<0)return{x:t,y:t,width:t,height:t};const[a,s,r,n]=i;return{x:a,y:s,width:r,height:n}}(e.imagingBBox);this.long=getMeasurement(e.long);this.orientation=getStringOption(e.orientation,["portrait","landscape"]);this.short=getMeasurement(e.short);this.stock=e.stock||"";this.trayIn=getStringOption(e.trayIn,["auto","delegate","pageFront"]);this.trayOut=getStringOption(e.trayOut,["auto","delegate"]);this.use=e.use||"";this.usehref=e.usehref||""}}class Message extends XFAObject{constructor(e){super(Jn,"message",!0);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||"";this.text=new XFAObjectArray}}class NumericEdit extends XFAObject{constructor(e){super(Jn,"numericEdit",!0);this.hScrollPolicy=getStringOption(e.hScrollPolicy,["auto","off","on"]);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||"";this.border=null;this.comb=null;this.extras=null;this.margin=null}[an](e){const t=toStyle(this,"border","font","margin"),i=this[pr]()[pr](),a={name:"input",attributes:{type:"text",fieldId:i[nn],dataId:i[tr]?.[nn]||i[nn],class:["xfaTextfield"],style:t,"aria-label":ariaLabel(i),"aria-required":!1}};if(isRequired(i)){a.attributes["aria-required"]=!0;a.attributes.required=!0}return HTMLResult.success({name:"label",attributes:{class:["xfaLabel"]},children:[a]})}}class Occur extends XFAObject{constructor(e){super(Jn,"occur",!0);this.id=e.id||"";this.initial=""!==e.initial?getInteger({data:e.initial,defaultValue:"",validate:e=>!0}):"";this.max=""!==e.max?getInteger({data:e.max,defaultValue:1,validate:e=>!0}):"";this.min=""!==e.min?getInteger({data:e.min,defaultValue:1,validate:e=>!0}):"";this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null}[Vs](){const e=this[pr](),t=this.min;""===this.min&&(this.min=e instanceof PageArea||e instanceof PageSet?0:1);""===this.max&&(this.max=""===t?e instanceof PageArea||e instanceof PageSet?-1:1:this.min);-1!==this.max&&this.max<this.min&&(this.max=this.min);""===this.initial&&(this.initial=e instanceof Template?1:this.min)}}class Oid extends StringObject{constructor(e){super(Jn,"oid");this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}}class Oids extends XFAObject{constructor(e){super(Jn,"oids",!0);this.id=e.id||"";this.type=getStringOption(e.type,["optional","required"]);this.use=e.use||"";this.usehref=e.usehref||"";this.oid=new XFAObjectArray}}class Overflow extends XFAObject{constructor(e){super(Jn,"overflow");this.id=e.id||"";this.leader=e.leader||"";this.target=e.target||"";this.trailer=e.trailer||"";this.use=e.use||"";this.usehref=e.usehref||""}[Cr](){if(!this[ar]){const e=this[pr](),t=this[mr](),i=t[Vr](this.target,e),a=t[Vr](this.leader,e),s=t[Vr](this.trailer,e);this[ar]={target:i?.[0]||null,leader:a?.[0]||null,trailer:s?.[0]||null,addLeader:!1,addTrailer:!1}}return this[ar]}}class PageArea extends XFAObject{constructor(e){super(Jn,"pageArea",!0);this.blankOrNotBlank=getStringOption(e.blankOrNotBlank,["any","blank","notBlank"]);this.id=e.id||"";this.initialNumber=getInteger({data:e.initialNumber,defaultValue:1,validate:e=>!0});this.name=e.name||"";this.numbered=getInteger({data:e.numbered,defaultValue:1,validate:e=>!0});this.oddOrEven=getStringOption(e.oddOrEven,["any","even","odd"]);this.pagePosition=getStringOption(e.pagePosition,["any","first","last","only","rest"]);this.relevant=getRelevant(e.relevant);this.use=e.use||"";this.usehref=e.usehref||"";this.desc=null;this.extras=null;this.medium=null;this.occur=null;this.area=new XFAObjectArray;this.contentArea=new XFAObjectArray;this.draw=new XFAObjectArray;this.exclGroup=new XFAObjectArray;this.field=new XFAObjectArray;this.subform=new XFAObjectArray}[Lr](){if(!this[ar]){this[ar]={numberOfUse:0};return!0}return!this.occur||-1===this.occur.max||this[ar].numberOfUse<this.occur.max}[zs](){delete this[ar]}[dr](){this[ar]||(this[ar]={numberOfUse:0});const e=this[pr]();if("orderedOccurrence"===e.relation&&this[Lr]()){this[ar].numberOfUse+=1;return this}return e[dr]()}[gr](){return this[ar].space||{width:0,height:0}}[an](){this[ar]||(this[ar]={numberOfUse:1});const e=[];this[ar].children=e;const t=Object.create(null);if(this.medium&&this.medium.short&&this.medium.long){t.width=measureToString(this.medium.short);t.height=measureToString(this.medium.long);this[ar].space={width:this.medium.short,height:this.medium.long};if("landscape"===this.medium.orientation){const e=t.width;t.width=t.height;t.height=e;this[ar].space={width:this.medium.long,height:this.medium.short}}}else warn("XFA - No medium specified in pageArea: please file a bug.");this[Zs]({filter:new Set(["area","draw","field","subform"]),include:!0});this[Zs]({filter:new Set(["contentArea"]),include:!0});return HTMLResult.success({name:"div",children:e,attributes:{class:["xfaPage"],id:this[nn],style:t,xfaName:this.name}})}}class PageSet extends XFAObject{constructor(e){super(Jn,"pageSet",!0);this.duplexImposition=getStringOption(e.duplexImposition,["longEdge","shortEdge"]);this.id=e.id||"";this.name=e.name||"";this.relation=getStringOption(e.relation,["orderedOccurrence","duplexPaginated","simplexPaginated"]);this.relevant=getRelevant(e.relevant);this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null;this.occur=null;this.pageArea=new XFAObjectArray;this.pageSet=new XFAObjectArray}[zs](){for(const e of this.pageArea.children)e[zs]();for(const e of this.pageSet.children)e[zs]()}[Lr](){return!this.occur||-1===this.occur.max||this[ar].numberOfUse<this.occur.max}[dr](){this[ar]||(this[ar]={numberOfUse:1,pageIndex:-1,pageSetIndex:-1});if("orderedOccurrence"===this.relation){if(this[ar].pageIndex+1<this.pageArea.children.length){this[ar].pageIndex+=1;return this.pageArea.children[this[ar].pageIndex][dr]()}if(this[ar].pageSetIndex+1<this.pageSet.children.length){this[ar].pageSetIndex+=1;return this.pageSet.children[this[ar].pageSetIndex][dr]()}if(this[Lr]()){this[ar].numberOfUse+=1;this[ar].pageIndex=-1;this[ar].pageSetIndex=-1;return this[dr]()}const e=this[pr]();if(e instanceof PageSet)return e[dr]();this[zs]();return this[dr]()}const e=this[mr]()[ar].pageNumber,t=e%2==0?"even":"odd",i=0===e?"first":"rest";let a=this.pageArea.children.find((e=>e.oddOrEven===t&&e.pagePosition===i));if(a)return a;a=this.pageArea.children.find((e=>"any"===e.oddOrEven&&e.pagePosition===i));if(a)return a;a=this.pageArea.children.find((e=>"any"===e.oddOrEven&&"any"===e.pagePosition));return a||this.pageArea.children[0]}}class Para extends XFAObject{constructor(e){super(Jn,"para",!0);this.hAlign=getStringOption(e.hAlign,["left","center","justify","justifyAll","radix","right"]);this.id=e.id||"";this.lineHeight=e.lineHeight?getMeasurement(e.lineHeight,"0pt"):"";this.marginLeft=e.marginLeft?getMeasurement(e.marginLeft,"0pt"):"";this.marginRight=e.marginRight?getMeasurement(e.marginRight,"0pt"):"";this.orphans=getInteger({data:e.orphans,defaultValue:0,validate:e=>e>=0});this.preserve=e.preserve||"";this.radixOffset=e.radixOffset?getMeasurement(e.radixOffset,"0pt"):"";this.spaceAbove=e.spaceAbove?getMeasurement(e.spaceAbove,"0pt"):"";this.spaceBelow=e.spaceBelow?getMeasurement(e.spaceBelow,"0pt"):"";this.tabDefault=e.tabDefault?getMeasurement(this.tabDefault):"";this.tabStops=(e.tabStops||"").trim().split(/\s+/).map(((e,t)=>t%2==1?getMeasurement(e):e));this.textIndent=e.textIndent?getMeasurement(e.textIndent,"0pt"):"";this.use=e.use||"";this.usehref=e.usehref||"";this.vAlign=getStringOption(e.vAlign,["top","bottom","middle"]);this.widows=getInteger({data:e.widows,defaultValue:0,validate:e=>e>=0});this.hyphenation=null}[rn](){const e=toStyle(this,"hAlign");""!==this.marginLeft&&(e.paddingLeft=measureToString(this.marginLeft));""!==this.marginRight&&(e.paddingight=measureToString(this.marginRight));""!==this.spaceAbove&&(e.paddingTop=measureToString(this.spaceAbove));""!==this.spaceBelow&&(e.paddingBottom=measureToString(this.spaceBelow));if(""!==this.textIndent){e.textIndent=measureToString(this.textIndent);fixTextIndent(e)}this.lineHeight>0&&(e.lineHeight=measureToString(this.lineHeight));""!==this.tabDefault&&(e.tabSize=measureToString(this.tabDefault));this.tabStops.length;this.hyphenatation&&Object.assign(e,this.hyphenatation[rn]());return e}}class PasswordEdit extends XFAObject{constructor(e){super(Jn,"passwordEdit",!0);this.hScrollPolicy=getStringOption(e.hScrollPolicy,["auto","off","on"]);this.id=e.id||"";this.passwordChar=e.passwordChar||"*";this.use=e.use||"";this.usehref=e.usehref||"";this.border=null;this.extras=null;this.margin=null}}class template_Pattern extends XFAObject{constructor(e){super(Jn,"pattern",!0);this.id=e.id||"";this.type=getStringOption(e.type,["crossHatch","crossDiagonal","diagonalLeft","diagonalRight","horizontal","vertical"]);this.use=e.use||"";this.usehref=e.usehref||"";this.color=null;this.extras=null}[rn](e){e=e?e[rn]():"#FFFFFF";const t=this.color?this.color[rn]():"#000000",i="repeating-linear-gradient",a=`${e},${e} 5px,${t} 5px,${t} 10px`;switch(this.type){case"crossHatch":return`${i}(to top,${a}) ${i}(to right,${a})`;case"crossDiagonal":return`${i}(45deg,${a}) ${i}(-45deg,${a})`;case"diagonalLeft":return`${i}(45deg,${a})`;case"diagonalRight":return`${i}(-45deg,${a})`;case"horizontal":return`${i}(to top,${a})`;case"vertical":return`${i}(to right,${a})`}return""}}class Picture extends StringObject{constructor(e){super(Jn,"picture");this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||""}}class Proto extends XFAObject{constructor(e){super(Jn,"proto",!0);this.appearanceFilter=new XFAObjectArray;this.arc=new XFAObjectArray;this.area=new XFAObjectArray;this.assist=new XFAObjectArray;this.barcode=new XFAObjectArray;this.bindItems=new XFAObjectArray;this.bookend=new XFAObjectArray;this.boolean=new XFAObjectArray;this.border=new XFAObjectArray;this.break=new XFAObjectArray;this.breakAfter=new XFAObjectArray;this.breakBefore=new XFAObjectArray;this.button=new XFAObjectArray;this.calculate=new XFAObjectArray;this.caption=new XFAObjectArray;this.certificate=new XFAObjectArray;this.certificates=new XFAObjectArray;this.checkButton=new XFAObjectArray;this.choiceList=new XFAObjectArray;this.color=new XFAObjectArray;this.comb=new XFAObjectArray;this.connect=new XFAObjectArray;this.contentArea=new XFAObjectArray;this.corner=new XFAObjectArray;this.date=new XFAObjectArray;this.dateTime=new XFAObjectArray;this.dateTimeEdit=new XFAObjectArray;this.decimal=new XFAObjectArray;this.defaultUi=new XFAObjectArray;this.desc=new XFAObjectArray;this.digestMethod=new XFAObjectArray;this.digestMethods=new XFAObjectArray;this.draw=new XFAObjectArray;this.edge=new XFAObjectArray;this.encoding=new XFAObjectArray;this.encodings=new XFAObjectArray;this.encrypt=new XFAObjectArray;this.encryptData=new XFAObjectArray;this.encryption=new XFAObjectArray;this.encryptionMethod=new XFAObjectArray;this.encryptionMethods=new XFAObjectArray;this.event=new XFAObjectArray;this.exData=new XFAObjectArray;this.exObject=new XFAObjectArray;this.exclGroup=new XFAObjectArray;this.execute=new XFAObjectArray;this.extras=new XFAObjectArray;this.field=new XFAObjectArray;this.fill=new XFAObjectArray;this.filter=new XFAObjectArray;this.float=new XFAObjectArray;this.font=new XFAObjectArray;this.format=new XFAObjectArray;this.handler=new XFAObjectArray;this.hyphenation=new XFAObjectArray;this.image=new XFAObjectArray;this.imageEdit=new XFAObjectArray;this.integer=new XFAObjectArray;this.issuers=new XFAObjectArray;this.items=new XFAObjectArray;this.keep=new XFAObjectArray;this.keyUsage=new XFAObjectArray;this.line=new XFAObjectArray;this.linear=new XFAObjectArray;this.lockDocument=new XFAObjectArray;this.manifest=new XFAObjectArray;this.margin=new XFAObjectArray;this.mdp=new XFAObjectArray;this.medium=new XFAObjectArray;this.message=new XFAObjectArray;this.numericEdit=new XFAObjectArray;this.occur=new XFAObjectArray;this.oid=new XFAObjectArray;this.oids=new XFAObjectArray;this.overflow=new XFAObjectArray;this.pageArea=new XFAObjectArray;this.pageSet=new XFAObjectArray;this.para=new XFAObjectArray;this.passwordEdit=new XFAObjectArray;this.pattern=new XFAObjectArray;this.picture=new XFAObjectArray;this.radial=new XFAObjectArray;this.reason=new XFAObjectArray;this.reasons=new XFAObjectArray;this.rectangle=new XFAObjectArray;this.ref=new XFAObjectArray;this.script=new XFAObjectArray;this.setProperty=new XFAObjectArray;this.signData=new XFAObjectArray;this.signature=new XFAObjectArray;this.signing=new XFAObjectArray;this.solid=new XFAObjectArray;this.speak=new XFAObjectArray;this.stipple=new XFAObjectArray;this.subform=new XFAObjectArray;this.subformSet=new XFAObjectArray;this.subjectDN=new XFAObjectArray;this.subjectDNs=new XFAObjectArray;this.submit=new XFAObjectArray;this.text=new XFAObjectArray;this.textEdit=new XFAObjectArray;this.time=new XFAObjectArray;this.timeStamp=new XFAObjectArray;this.toolTip=new XFAObjectArray;this.traversal=new XFAObjectArray;this.traverse=new XFAObjectArray;this.ui=new XFAObjectArray;this.validate=new XFAObjectArray;this.value=new XFAObjectArray;this.variables=new XFAObjectArray}}class Radial extends XFAObject{constructor(e){super(Jn,"radial",!0);this.id=e.id||"";this.type=getStringOption(e.type,["toEdge","toCenter"]);this.use=e.use||"";this.usehref=e.usehref||"";this.color=null;this.extras=null}[rn](e){e=e?e[rn]():"#FFFFFF";const t=this.color?this.color[rn]():"#000000";return`radial-gradient(circle at center, ${"toEdge"===this.type?`${e},${t}`:`${t},${e}`})`}}class Reason extends StringObject{constructor(e){super(Jn,"reason");this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}}class Reasons extends XFAObject{constructor(e){super(Jn,"reasons",!0);this.id=e.id||"";this.type=getStringOption(e.type,["optional","required"]);this.use=e.use||"";this.usehref=e.usehref||"";this.reason=new XFAObjectArray}}class Rectangle extends XFAObject{constructor(e){super(Jn,"rectangle",!0);this.hand=getStringOption(e.hand,["even","left","right"]);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||"";this.corner=new XFAObjectArray(4);this.edge=new XFAObjectArray(4);this.fill=null}[an](){const e=this.edge.children.length?this.edge.children[0]:new Edge({}),t=e[rn](),i=Object.create(null);"visible"===this.fill?.presence?Object.assign(i,this.fill[rn]()):i.fill="transparent";i.strokeWidth=measureToString("visible"===e.presence?e.thickness:0);i.stroke=t.color;const a=(this.corner.children.length?this.corner.children[0]:new Corner({}))[rn](),s={name:"svg",children:[{name:"rect",attributes:{xmlns:Hn,width:"100%",height:"100%",x:0,y:0,rx:a.radius,ry:a.radius,style:i}}],attributes:{xmlns:Hn,style:{overflow:"visible"},width:"100%",height:"100%"}};if(hasMargin(this[pr]()[pr]()))return HTMLResult.success({name:"div",attributes:{style:{display:"inline",width:"100%",height:"100%"}},children:[s]});s.attributes.style.position="absolute";return HTMLResult.success(s)}}class RefElement extends StringObject{constructor(e){super(Jn,"ref");this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||""}}class Script extends StringObject{constructor(e){super(Jn,"script");this.binding=e.binding||"";this.contentType=e.contentType||"";this.id=e.id||"";this.name=e.name||"";this.runAt=getStringOption(e.runAt,["client","both","server"]);this.use=e.use||"";this.usehref=e.usehref||""}}class SetProperty extends XFAObject{constructor(e){super(Jn,"setProperty");this.connection=e.connection||"";this.ref=e.ref||"";this.target=e.target||""}}class SignData extends XFAObject{constructor(e){super(Jn,"signData",!0);this.id=e.id||"";this.operation=getStringOption(e.operation,["sign","clear","verify"]);this.ref=e.ref||"";this.target=e.target||"";this.use=e.use||"";this.usehref=e.usehref||"";this.filter=null;this.manifest=null}}class Signature extends XFAObject{constructor(e){super(Jn,"signature",!0);this.id=e.id||"";this.type=getStringOption(e.type,["PDF1.3","PDF1.6"]);this.use=e.use||"";this.usehref=e.usehref||"";this.border=null;this.extras=null;this.filter=null;this.manifest=null;this.margin=null}}class Signing extends XFAObject{constructor(e){super(Jn,"signing",!0);this.id=e.id||"";this.type=getStringOption(e.type,["optional","required"]);this.use=e.use||"";this.usehref=e.usehref||"";this.certificate=new XFAObjectArray}}class Solid extends XFAObject{constructor(e){super(Jn,"solid",!0);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null}[rn](e){return e?e[rn]():"#FFFFFF"}}class Speak extends StringObject{constructor(e){super(Jn,"speak");this.disable=getInteger({data:e.disable,defaultValue:0,validate:e=>1===e});this.id=e.id||"";this.priority=getStringOption(e.priority,["custom","caption","name","toolTip"]);this.rid=e.rid||"";this.use=e.use||"";this.usehref=e.usehref||""}}class Stipple extends XFAObject{constructor(e){super(Jn,"stipple",!0);this.id=e.id||"";this.rate=getInteger({data:e.rate,defaultValue:50,validate:e=>e>=0&&e<=100});this.use=e.use||"";this.usehref=e.usehref||"";this.color=null;this.extras=null}[rn](e){const t=this.rate/100;return Util.makeHexColor(Math.round(e.value.r*(1-t)+this.value.r*t),Math.round(e.value.g*(1-t)+this.value.g*t),Math.round(e.value.b*(1-t)+this.value.b*t))}}class Subform extends XFAObject{constructor(e){super(Jn,"subform",!0);this.access=getStringOption(e.access,["open","nonInteractive","protected","readOnly"]);this.allowMacro=getInteger({data:e.allowMacro,defaultValue:0,validate:e=>1===e});this.anchorType=getStringOption(e.anchorType,["topLeft","bottomCenter","bottomLeft","bottomRight","middleCenter","middleLeft","middleRight","topCenter","topRight"]);this.colSpan=getInteger({data:e.colSpan,defaultValue:1,validate:e=>e>=1||-1===e});this.columnWidths=(e.columnWidths||"").trim().split(/\s+/).map((e=>"-1"===e?-1:getMeasurement(e)));this.h=e.h?getMeasurement(e.h):"";this.hAlign=getStringOption(e.hAlign,["left","center","justify","justifyAll","radix","right"]);this.id=e.id||"";this.layout=getStringOption(e.layout,["position","lr-tb","rl-row","rl-tb","row","table","tb"]);this.locale=e.locale||"";this.maxH=getMeasurement(e.maxH,"0pt");this.maxW=getMeasurement(e.maxW,"0pt");this.mergeMode=getStringOption(e.mergeMode,["consumeData","matchTemplate"]);this.minH=getMeasurement(e.minH,"0pt");this.minW=getMeasurement(e.minW,"0pt");this.name=e.name||"";this.presence=getStringOption(e.presence,["visible","hidden","inactive","invisible"]);this.relevant=getRelevant(e.relevant);this.restoreState=getStringOption(e.restoreState,["manual","auto"]);this.scope=getStringOption(e.scope,["name","none"]);this.use=e.use||"";this.usehref=e.usehref||"";this.w=e.w?getMeasurement(e.w):"";this.x=getMeasurement(e.x,"0pt");this.y=getMeasurement(e.y,"0pt");this.assist=null;this.bind=null;this.bookend=null;this.border=null;this.break=null;this.calculate=null;this.desc=null;this.extras=null;this.keep=null;this.margin=null;this.occur=null;this.overflow=null;this.pageSet=null;this.para=null;this.traversal=null;this.validate=null;this.variables=null;this.area=new XFAObjectArray;this.breakAfter=new XFAObjectArray;this.breakBefore=new XFAObjectArray;this.connect=new XFAObjectArray;this.draw=new XFAObjectArray;this.event=new XFAObjectArray;this.exObject=new XFAObjectArray;this.exclGroup=new XFAObjectArray;this.field=new XFAObjectArray;this.proto=new XFAObjectArray;this.setProperty=new XFAObjectArray;this.subform=new XFAObjectArray;this.subformSet=new XFAObjectArray}[fr](){const e=this[pr]();return e instanceof SubformSet?e[fr]():e}[kr](){return!0}[Mr](){return this.layout.endsWith("-tb")&&0===this[ar].attempt&&this[ar].numberInLine>0||this[pr]()[Mr]()}*[ur](){yield*getContainedChildren(this)}[rr](){return flushHTML(this)}[Xs](e,t){addHTML(this,e,t)}[gr](){return getAvailableSpace(this)}[xr](){const e=this[fr]();if(!e[xr]())return!1;if(void 0!==this[ar]._isSplittable)return this[ar]._isSplittable;if("position"===this.layout||this.layout.includes("row")){this[ar]._isSplittable=!1;return!1}if(this.keep&&"none"!==this.keep.intact){this[ar]._isSplittable=!1;return!1}if(e.layout?.endsWith("-tb")&&0!==e[ar].numberInLine)return!1;this[ar]._isSplittable=!0;return!0}[an](e){setTabIndex(this);if(this.break){if("auto"!==this.break.after||""!==this.break.afterTarget){const e=new BreakAfter({targetType:this.break.after,target:this.break.afterTarget,startNew:this.break.startNew.toString()});e[yr]=this[yr];this[js](e);this.breakAfter.push(e)}if("auto"!==this.break.before||""!==this.break.beforeTarget){const e=new BreakBefore({targetType:this.break.before,target:this.break.beforeTarget,startNew:this.break.startNew.toString()});e[yr]=this[yr];this[js](e);this.breakBefore.push(e)}if(""!==this.break.overflowTarget){const e=new Overflow({target:this.break.overflowTarget,leader:this.break.overflowLeader,trailer:this.break.overflowTrailer});e[yr]=this[yr];this[js](e);this.overflow.push(e)}this[Xr](this.break);this.break=null}if("hidden"===this.presence||"inactive"===this.presence)return HTMLResult.EMPTY;(this.breakBefore.children.length>1||this.breakAfter.children.length>1)&&warn("XFA - Several breakBefore or breakAfter in subforms: please file a bug.");if(this.breakBefore.children.length>=1){const e=this.breakBefore.children[0];if(handleBreak(e))return HTMLResult.breakNode(e)}if(this[ar]?.afterBreakAfter)return HTMLResult.EMPTY;fixDimensions(this);const t=[],i={id:this[nn],class:[]};setAccess(this,i.class);this[ar]||(this[ar]=Object.create(null));Object.assign(this[ar],{children:t,line:null,attributes:i,attempt:0,numberInLine:0,availableSpace:{width:Math.min(this.w||1/0,e.width),height:Math.min(this.h||1/0,e.height)},width:0,height:0,prevHeight:0,currentWidth:0});const a=this[mr](),s=a[ar].noLayoutFailure,r=this[xr]();r||setFirstUnsplittable(this);if(!checkDimensions(this,e))return HTMLResult.FAILURE;const n=new Set(["area","draw","exclGroup","field","subform","subformSet"]);if(this.layout.includes("row")){const e=this[fr]().columnWidths;if(Array.isArray(e)&&e.length>0){this[ar].columnWidths=e;this[ar].currentColumn=0}}const o=toStyle(this,"anchorType","dimensions","position","presence","border","margin","hAlign"),g=["xfaSubform"],c=layoutClass(this);c&&g.push(c);i.style=o;i.class=g;this.name&&(i.xfaName=this.name);if(this.overflow){const t=this.overflow[Cr]();if(t.addLeader){t.addLeader=!1;handleOverflow(this,t.leader,e)}}this[Wr]();const h="lr-tb"===this.layout||"rl-tb"===this.layout,l=h?2:1;for(;this[ar].attempt<l;this[ar].attempt++){h&&1===this[ar].attempt&&(this[ar].numberInLine=0);const e=this[Zs]({filter:n,include:!0});if(e.success)break;if(e.isBreak()){this[Pr]();return e}if(h&&0===this[ar].attempt&&0===this[ar].numberInLine&&!a[ar].noLayoutFailure){this[ar].attempt=l;break}}this[Pr]();r||unsetFirstUnsplittable(this);a[ar].noLayoutFailure=s;if(this[ar].attempt===l){this.overflow&&(this[mr]()[ar].overflowNode=this.overflow);r||delete this[ar];return HTMLResult.FAILURE}if(this.overflow){const t=this.overflow[Cr]();if(t.addTrailer){t.addTrailer=!1;handleOverflow(this,t.trailer,e)}}let C=0,Q=0;if(this.margin){C=this.margin.leftInset+this.margin.rightInset;Q=this.margin.topInset+this.margin.bottomInset}const E=Math.max(this[ar].width+C,this.w||0),u=Math.max(this[ar].height+Q,this.h||0),d=[this.x,this.y,E,u];""===this.w&&(o.width=measureToString(E));""===this.h&&(o.height=measureToString(u));if(("0px"===o.width||"0px"===o.height)&&0===t.length)return HTMLResult.EMPTY;const f={name:"div",attributes:i,children:t};applyAssist(this,i);const p=HTMLResult.success(createWrapper(this,f),d);if(this.breakAfter.children.length>=1){const e=this.breakAfter.children[0];if(handleBreak(e)){this[ar].afterBreakAfter=p;return HTMLResult.breakNode(e)}}delete this[ar];return p}}class SubformSet extends XFAObject{constructor(e){super(Jn,"subformSet",!0);this.id=e.id||"";this.name=e.name||"";this.relation=getStringOption(e.relation,["ordered","choice","unordered"]);this.relevant=getRelevant(e.relevant);this.use=e.use||"";this.usehref=e.usehref||"";this.bookend=null;this.break=null;this.desc=null;this.extras=null;this.occur=null;this.overflow=null;this.breakAfter=new XFAObjectArray;this.breakBefore=new XFAObjectArray;this.subform=new XFAObjectArray;this.subformSet=new XFAObjectArray}*[ur](){yield*getContainedChildren(this)}[fr](){let e=this[pr]();for(;!(e instanceof Subform);)e=e[pr]();return e}[kr](){return!0}}class SubjectDN extends ContentObject{constructor(e){super(Jn,"subjectDN");this.delimiter=e.delimiter||",";this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}[sr](){this[er]=new Map(this[er].split(this.delimiter).map((e=>{(e=e.split("=",2))[0]=e[0].trim();return e})))}}class SubjectDNs extends XFAObject{constructor(e){super(Jn,"subjectDNs",!0);this.id=e.id||"";this.type=getStringOption(e.type,["optional","required"]);this.use=e.use||"";this.usehref=e.usehref||"";this.subjectDN=new XFAObjectArray}}class Submit extends XFAObject{constructor(e){super(Jn,"submit",!0);this.embedPDF=getInteger({data:e.embedPDF,defaultValue:0,validate:e=>1===e});this.format=getStringOption(e.format,["xdp","formdata","pdf","urlencoded","xfd","xml"]);this.id=e.id||"";this.target=e.target||"";this.textEncoding=getKeyword({data:e.textEncoding?e.textEncoding.toLowerCase():"",defaultValue:"",validate:e=>["utf-8","big-five","fontspecific","gbk","gb-18030","gb-2312","ksc-5601","none","shift-jis","ucs-2","utf-16"].includes(e)||e.match(/iso-8859-\d{2}/)});this.use=e.use||"";this.usehref=e.usehref||"";this.xdpContent=e.xdpContent||"";this.encrypt=null;this.encryptData=new XFAObjectArray;this.signData=new XFAObjectArray}}class Template extends XFAObject{constructor(e){super(Jn,"template",!0);this.baseProfile=getStringOption(e.baseProfile,["full","interactiveForms"]);this.extras=null;this.subform=new XFAObjectArray}[sr](){0===this.subform.children.length&&warn("XFA - No subforms in template node.");this.subform.children.length>=2&&warn("XFA - Several subforms in template node: please file a bug.");this[An]=5e3}[xr](){return!0}[Vr](e,t){return e.startsWith("#")?[this[br].get(e.slice(1))]:searchNode(this,t,e,!0,!0)}*[tn](){if(!this.subform.children.length)return HTMLResult.success({name:"div",children:[]});this[ar]={overflowNode:null,firstUnsplittable:null,currentContentArea:null,currentPageArea:null,noLayoutFailure:!1,pageNumber:1,pagePosition:"first",oddOrEven:"odd",blankOrNotBlank:"nonBlank",paraStack:[]};const e=this.subform.children[0];e.pageSet[zs]();const t=e.pageSet.pageArea.children,i={name:"div",children:[]};let a=null,s=null,r=null;if(e.breakBefore.children.length>=1){s=e.breakBefore.children[0];r=s.target}else if(e.subform.children.length>=1&&e.subform.children[0].breakBefore.children.length>=1){s=e.subform.children[0].breakBefore.children[0];r=s.target}else if(e.break?.beforeTarget){s=e.break;r=s.beforeTarget}else if(e.subform.children.length>=1&&e.subform.children[0].break?.beforeTarget){s=e.subform.children[0].break;r=s.beforeTarget}if(s){const e=this[Vr](r,s[pr]());if(e instanceof PageArea){a=e;s[ar]={}}}a||(a=t[0]);a[ar]={numberOfUse:1};const n=a[pr]();n[ar]={numberOfUse:1,pageIndex:n.pageArea.children.indexOf(a),pageSetIndex:0};let o,g=null,c=null,h=!0,l=0,C=0;for(;;){if(h)l=0;else{i.children.pop();if(3==++l){warn("XFA - Something goes wrong: please file a bug.");return i}}o=null;this[ar].currentPageArea=a;const t=a[an]().html;i.children.push(t);if(g){this[ar].noLayoutFailure=!0;t.children.push(g[an](a[ar].space).html);g=null}if(c){this[ar].noLayoutFailure=!0;t.children.push(c[an](a[ar].space).html);c=null}const s=a.contentArea.children,r=t.children.filter((e=>e.attributes.class.includes("xfaContentarea")));h=!1;this[ar].firstUnsplittable=null;this[ar].noLayoutFailure=!1;const flush=t=>{const i=e[rr]();if(i){h||=i.children?.length>0;r[t].children.push(i)}};for(let t=C,a=s.length;t<a;t++){const a=this[ar].currentContentArea=s[t],n={width:a.w,height:a.h};C=0;if(g){r[t].children.push(g[an](n).html);g=null}if(c){r[t].children.push(c[an](n).html);c=null}const l=e[an](n);if(l.success){if(l.html){h||=l.html.children?.length>0;r[t].children.push(l.html)}else!h&&i.children.length>1&&i.children.pop();return i}if(l.isBreak()){const e=l.breakNode;flush(t);if("auto"===e.targetType)continue;if(e.leader){g=this[Vr](e.leader,e[pr]());g=g?g[0]:null}if(e.trailer){c=this[Vr](e.trailer,e[pr]());c=c?c[0]:null}if("pageArea"===e.targetType){o=e[ar].target;t=1/0}else if(e[ar].target){o=e[ar].target;C=e[ar].index+1;t=1/0}else t=e[ar].index}else if(this[ar].overflowNode){const e=this[ar].overflowNode;this[ar].overflowNode=null;const i=e[Cr](),a=i.target;i.addLeader=null!==i.leader;i.addTrailer=null!==i.trailer;flush(t);const r=t;t=1/0;if(a instanceof PageArea)o=a;else if(a instanceof ContentArea){const e=s.indexOf(a);if(-1!==e)e>r?t=e-1:C=e;else{o=a[pr]();C=o.contentArea.children.indexOf(a)}}}else flush(t)}this[ar].pageNumber+=1;o&&(o[Lr]()?o[ar].numberOfUse+=1:o=null);a=o||a[dr]();yield null}}}class Text extends ContentObject{constructor(e){super(Jn,"text");this.id=e.id||"";this.maxChars=getInteger({data:e.maxChars,defaultValue:0,validate:e=>e>=0});this.name=e.name||"";this.rid=e.rid||"";this.use=e.use||"";this.usehref=e.usehref||""}[Ws](){return!0}[Kr](e){if(e[Hr]===gn.xhtml.id){this[er]=e;return!0}warn(`XFA - Invalid content in Text: ${e[Yr]}.`);return!1}[qr](e){this[er]instanceof XFAObject||super[qr](e)}[sr](){"string"==typeof this[er]&&(this[er]=this[er].replaceAll("\r\n","\n"))}[Cr](){return"string"==typeof this[er]?this[er].split(/[\u2029\u2028\n]/).reduce(((e,t)=>{t&&e.push(t);return e}),[]).join("\n"):this[er][en]()}[an](e){if("string"==typeof this[er]){const e=valueToHtml(this[er]).html;if(this[er].includes("\u2029")){e.name="div";e.children=[];this[er].split("\u2029").map((e=>e.split(/[\u2028\n]/).reduce(((e,t)=>{e.push({name:"span",value:t},{name:"br"});return e}),[]))).forEach((t=>{e.children.push({name:"p",children:t})}))}else if(/[\u2028\n]/.test(this[er])){e.name="div";e.children=[];this[er].split(/[\u2028\n]/).forEach((t=>{e.children.push({name:"span",value:t},{name:"br"})}))}return HTMLResult.success(e)}return this[er][an](e)}}class TextEdit extends XFAObject{constructor(e){super(Jn,"textEdit",!0);this.allowRichText=getInteger({data:e.allowRichText,defaultValue:0,validate:e=>1===e});this.hScrollPolicy=getStringOption(e.hScrollPolicy,["auto","off","on"]);this.id=e.id||"";this.multiLine=getInteger({data:e.multiLine,defaultValue:"",validate:e=>0===e||1===e});this.use=e.use||"";this.usehref=e.usehref||"";this.vScrollPolicy=getStringOption(e.vScrollPolicy,["auto","off","on"]);this.border=null;this.comb=null;this.extras=null;this.margin=null}[an](e){const t=toStyle(this,"border","font","margin");let i;const a=this[pr]()[pr]();""===this.multiLine&&(this.multiLine=a instanceof Draw?1:0);i=1===this.multiLine?{name:"textarea",attributes:{dataId:a[tr]?.[nn]||a[nn],fieldId:a[nn],class:["xfaTextfield"],style:t,"aria-label":ariaLabel(a),"aria-required":!1}}:{name:"input",attributes:{type:"text",dataId:a[tr]?.[nn]||a[nn],fieldId:a[nn],class:["xfaTextfield"],style:t,"aria-label":ariaLabel(a),"aria-required":!1}};if(isRequired(a)){i.attributes["aria-required"]=!0;i.attributes.required=!0}return HTMLResult.success({name:"label",attributes:{class:["xfaLabel"]},children:[i]})}}class Time extends StringObject{constructor(e){super(Jn,"time");this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}[sr](){const e=this[er].trim();this[er]=e?new Date(e):null}[an](e){return valueToHtml(this[er]?this[er].toString():"")}}class TimeStamp extends XFAObject{constructor(e){super(Jn,"timeStamp");this.id=e.id||"";this.server=e.server||"";this.type=getStringOption(e.type,["optional","required"]);this.use=e.use||"";this.usehref=e.usehref||""}}class ToolTip extends StringObject{constructor(e){super(Jn,"toolTip");this.id=e.id||"";this.rid=e.rid||"";this.use=e.use||"";this.usehref=e.usehref||""}}class Traversal extends XFAObject{constructor(e){super(Jn,"traversal",!0);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null;this.traverse=new XFAObjectArray}}class Traverse extends XFAObject{constructor(e){super(Jn,"traverse",!0);this.id=e.id||"";this.operation=getStringOption(e.operation,["next","back","down","first","left","right","up"]);this.ref=e.ref||"";this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null;this.script=null}get name(){return this.operation}[Ur](){return!1}}class Ui extends XFAObject{constructor(e){super(Jn,"ui",!0);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null;this.picture=null;this.barcode=null;this.button=null;this.checkButton=null;this.choiceList=null;this.dateTimeEdit=null;this.defaultUi=null;this.imageEdit=null;this.numericEdit=null;this.passwordEdit=null;this.signature=null;this.textEdit=null}[Cr](){if(void 0===this[ar]){for(const e of Object.getOwnPropertyNames(this)){if("extras"===e||"picture"===e)continue;const t=this[e];if(t instanceof XFAObject){this[ar]=t;return t}}this[ar]=null}return this[ar]}[an](e){const t=this[Cr]();return t?t[an](e):HTMLResult.EMPTY}}class Validate extends XFAObject{constructor(e){super(Jn,"validate",!0);this.formatTest=getStringOption(e.formatTest,["warning","disabled","error"]);this.id=e.id||"";this.nullTest=getStringOption(e.nullTest,["disabled","error","warning"]);this.scriptTest=getStringOption(e.scriptTest,["error","disabled","warning"]);this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null;this.message=null;this.picture=null;this.script=null}}class Value extends XFAObject{constructor(e){super(Jn,"value",!0);this.id=e.id||"";this.override=getInteger({data:e.override,defaultValue:0,validate:e=>1===e});this.relevant=getRelevant(e.relevant);this.use=e.use||"";this.usehref=e.usehref||"";this.arc=null;this.boolean=null;this.date=null;this.dateTime=null;this.decimal=null;this.exData=null;this.float=null;this.image=null;this.integer=null;this.line=null;this.rectangle=null;this.text=null;this.time=null}[$r](e){const t=this[pr]();if(t instanceof Field&&t.ui?.imageEdit){if(!this.image){this.image=new Image({});this[js](this.image)}this.image[er]=e[er];return}const i=e[Yr];if(null===this[i]){for(const e of Object.getOwnPropertyNames(this)){const t=this[e];if(t instanceof XFAObject){this[e]=null;this[Xr](t)}}this[e[Yr]]=e;this[js](e)}else this[i][er]=e[er]}[en](){if(this.exData)return"string"==typeof this.exData[er]?this.exData[er].trim():this.exData[er][en]().trim();for(const e of Object.getOwnPropertyNames(this)){if("image"===e)continue;const t=this[e];if(t instanceof XFAObject)return(t[er]||"").toString().trim()}return null}[an](e){for(const t of Object.getOwnPropertyNames(this)){const i=this[t];if(i instanceof XFAObject)return i[an](e)}return HTMLResult.EMPTY}}class Variables extends XFAObject{constructor(e){super(Jn,"variables",!0);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||"";this.boolean=new XFAObjectArray;this.date=new XFAObjectArray;this.dateTime=new XFAObjectArray;this.decimal=new XFAObjectArray;this.exData=new XFAObjectArray;this.float=new XFAObjectArray;this.image=new XFAObjectArray;this.integer=new XFAObjectArray;this.manifest=new XFAObjectArray;this.script=new XFAObjectArray;this.text=new XFAObjectArray;this.time=new XFAObjectArray}[Ur](){return!0}}class TemplateNamespace{static[on](e,t){if(TemplateNamespace.hasOwnProperty(e)){const i=TemplateNamespace[e](t);i[_r](t);return i}}static appearanceFilter(e){return new AppearanceFilter(e)}static arc(e){return new Arc(e)}static area(e){return new Area(e)}static assist(e){return new Assist(e)}static barcode(e){return new Barcode(e)}static bind(e){return new Bind(e)}static bindItems(e){return new BindItems(e)}static bookend(e){return new Bookend(e)}static boolean(e){return new BooleanElement(e)}static border(e){return new Border(e)}static break(e){return new Break(e)}static breakAfter(e){return new BreakAfter(e)}static breakBefore(e){return new BreakBefore(e)}static button(e){return new Button(e)}static calculate(e){return new Calculate(e)}static caption(e){return new Caption(e)}static certificate(e){return new Certificate(e)}static certificates(e){return new Certificates(e)}static checkButton(e){return new CheckButton(e)}static choiceList(e){return new ChoiceList(e)}static color(e){return new Color(e)}static comb(e){return new Comb(e)}static connect(e){return new Connect(e)}static contentArea(e){return new ContentArea(e)}static corner(e){return new Corner(e)}static date(e){return new DateElement(e)}static dateTime(e){return new DateTime(e)}static dateTimeEdit(e){return new DateTimeEdit(e)}static decimal(e){return new Decimal(e)}static defaultUi(e){return new DefaultUi(e)}static desc(e){return new Desc(e)}static digestMethod(e){return new DigestMethod(e)}static digestMethods(e){return new DigestMethods(e)}static draw(e){return new Draw(e)}static edge(e){return new Edge(e)}static encoding(e){return new Encoding(e)}static encodings(e){return new Encodings(e)}static encrypt(e){return new Encrypt(e)}static encryptData(e){return new EncryptData(e)}static encryption(e){return new Encryption(e)}static encryptionMethod(e){return new EncryptionMethod(e)}static encryptionMethods(e){return new EncryptionMethods(e)}static event(e){return new Event(e)}static exData(e){return new ExData(e)}static exObject(e){return new ExObject(e)}static exclGroup(e){return new ExclGroup(e)}static execute(e){return new Execute(e)}static extras(e){return new Extras(e)}static field(e){return new Field(e)}static fill(e){return new Fill(e)}static filter(e){return new Filter(e)}static float(e){return new Float(e)}static font(e){return new template_Font(e)}static format(e){return new Format(e)}static handler(e){return new Handler(e)}static hyphenation(e){return new Hyphenation(e)}static image(e){return new Image(e)}static imageEdit(e){return new ImageEdit(e)}static integer(e){return new Integer(e)}static issuers(e){return new Issuers(e)}static items(e){return new Items(e)}static keep(e){return new Keep(e)}static keyUsage(e){return new KeyUsage(e)}static line(e){return new Line(e)}static linear(e){return new Linear(e)}static lockDocument(e){return new LockDocument(e)}static manifest(e){return new Manifest(e)}static margin(e){return new Margin(e)}static mdp(e){return new Mdp(e)}static medium(e){return new Medium(e)}static message(e){return new Message(e)}static numericEdit(e){return new NumericEdit(e)}static occur(e){return new Occur(e)}static oid(e){return new Oid(e)}static oids(e){return new Oids(e)}static overflow(e){return new Overflow(e)}static pageArea(e){return new PageArea(e)}static pageSet(e){return new PageSet(e)}static para(e){return new Para(e)}static passwordEdit(e){return new PasswordEdit(e)}static pattern(e){return new template_Pattern(e)}static picture(e){return new Picture(e)}static proto(e){return new Proto(e)}static radial(e){return new Radial(e)}static reason(e){return new Reason(e)}static reasons(e){return new Reasons(e)}static rectangle(e){return new Rectangle(e)}static ref(e){return new RefElement(e)}static script(e){return new Script(e)}static setProperty(e){return new SetProperty(e)}static signData(e){return new SignData(e)}static signature(e){return new Signature(e)}static signing(e){return new Signing(e)}static solid(e){return new Solid(e)}static speak(e){return new Speak(e)}static stipple(e){return new Stipple(e)}static subform(e){return new Subform(e)}static subformSet(e){return new SubformSet(e)}static subjectDN(e){return new SubjectDN(e)}static subjectDNs(e){return new SubjectDNs(e)}static submit(e){return new Submit(e)}static template(e){return new Template(e)}static text(e){return new Text(e)}static textEdit(e){return new TextEdit(e)}static time(e){return new Time(e)}static timeStamp(e){return new TimeStamp(e)}static toolTip(e){return new ToolTip(e)}static traversal(e){return new Traversal(e)}static traverse(e){return new Traverse(e)}static ui(e){return new Ui(e)}static validate(e){return new Validate(e)}static value(e){return new Value(e)}static variables(e){return new Variables(e)}}const Tn=gn.datasets.id;function createText(e){const t=new Text({});t[er]=e;return t}class Binder{constructor(e){this.root=e;this.datasets=e.datasets;this.data=e.datasets?.data||new XmlObject(gn.datasets.id,"data");this.emptyMerge=0===this.data[Er]().length;this.root.form=this.form=e.template[$s]()}_isConsumeData(){return!this.emptyMerge&&this._mergeMode}_isMatchTemplate(){return!this._isConsumeData()}bind(){this._bindElement(this.form,this.data);return this.form}getData(){return this.data}_bindValue(e,t,i){e[tr]=t;if(e[wr]())if(t[Rr]()){const i=t[lr]();e[$r](createText(i))}else if(e instanceof Field&&"multiSelect"===e.ui?.choiceList?.open){const i=t[Er]().map((e=>e[er].trim())).join("\n");e[$r](createText(i))}else this._isConsumeData()&&warn("XFA - Nodes haven't the same type.");else!t[Rr]()||this._isMatchTemplate()?this._bindElement(e,t):warn("XFA - Nodes haven't the same type.")}_findDataByNameToConsume(e,t,i,a){if(!e)return null;let s,r;for(let a=0;a<3;a++){s=i[Qr](e,!1,!0);for(;;){r=s.next().value;if(!r)break;if(t===r[Rr]())return r}if(i[Hr]===gn.datasets.id&&"data"===i[Yr])break;i=i[pr]()}if(!a)return null;s=this.data[Qr](e,!0,!1);r=s.next().value;if(r)return r;s=this.data[nr](e,!0);r=s.next().value;return r?.[Rr]()?r:null}_setProperties(e,t){if(e.hasOwnProperty("setProperty"))for(const{ref:i,target:a,connection:s}of e.setProperty.children){if(s)continue;if(!i)continue;const r=searchNode(this.root,t,i,!1,!1);if(!r){warn(`XFA - Invalid reference: ${i}.`);continue}const[n]=r;if(!n[Nr](this.data)){warn("XFA - Invalid node: must be a data node.");continue}const o=searchNode(this.root,e,a,!1,!1);if(!o){warn(`XFA - Invalid target: ${a}.`);continue}const[g]=o;if(!g[Nr](e)){warn("XFA - Invalid target: must be a property or subproperty.");continue}const c=g[pr]();if(g instanceof SetProperty||c instanceof SetProperty){warn("XFA - Invalid target: cannot be a setProperty or one of its properties.");continue}if(g instanceof BindItems||c instanceof BindItems){warn("XFA - Invalid target: cannot be a bindItems or one of its properties.");continue}const h=n[en](),l=g[Yr];if(g instanceof XFAAttribute){const e=Object.create(null);e[l]=h;const t=Reflect.construct(Object.getPrototypeOf(c).constructor,[e]);c[l]=t[l]}else if(g.hasOwnProperty(er)){g[tr]=n;g[er]=h;g[sr]()}else warn("XFA - Invalid node to use in setProperty")}}_bindItems(e,t){if(!e.hasOwnProperty("items")||!e.hasOwnProperty("bindItems")||e.bindItems.isEmpty())return;for(const t of e.items.children)e[Xr](t);e.items.clear();const i=new Items({}),a=new Items({});e[js](i);e.items.push(i);e[js](a);e.items.push(a);for(const{ref:s,labelRef:r,valueRef:n,connection:o}of e.bindItems.children){if(o)continue;if(!s)continue;const e=searchNode(this.root,t,s,!1,!1);if(e)for(const t of e){if(!t[Nr](this.datasets)){warn(`XFA - Invalid ref (${s}): must be a datasets child.`);continue}const e=searchNode(this.root,t,r,!0,!1);if(!e){warn(`XFA - Invalid label: ${r}.`);continue}const[o]=e;if(!o[Nr](this.datasets)){warn("XFA - Invalid label: must be a datasets child.");continue}const g=searchNode(this.root,t,n,!0,!1);if(!g){warn(`XFA - Invalid value: ${n}.`);continue}const[c]=g;if(!c[Nr](this.datasets)){warn("XFA - Invalid value: must be a datasets child.");continue}const h=createText(o[en]()),l=createText(c[en]());i[js](h);i.text.push(h);a[js](l);a.text.push(l)}else warn(`XFA - Invalid reference: ${s}.`)}}_bindOccurrences(e,t,i){let a;if(t.length>1){a=e[$s]();a[Xr](a.occur);a.occur=null}this._bindValue(e,t[0],i);this._setProperties(e,t[0]);this._bindItems(e,t[0]);if(1===t.length)return;const s=e[pr](),r=e[Yr],n=s[Dr](e);for(let e=1,o=t.length;e<o;e++){const o=t[e],g=a[$s]();s[r].push(g);s[Fr](n+e,g);this._bindValue(g,o,i);this._setProperties(g,o);this._bindItems(g,o)}}_createOccurrences(e){if(!this.emptyMerge)return;const{occur:t}=e;if(!t||t.initial<=1)return;const i=e[pr](),a=e[Yr];if(!(i[a]instanceof XFAObjectArray))return;let s;s=e.name?i[a].children.filter((t=>t.name===e.name)).length:i[a].children.length;const r=i[Dr](e)+1,n=t.initial-s;if(n){const t=e[$s]();t[Xr](t.occur);t.occur=null;i[a].push(t);i[Fr](r,t);for(let e=1;e<n;e++){const s=t[$s]();i[a].push(s);i[Fr](r+e,s)}}}_getOccurInfo(e){const{name:t,occur:i}=e;if(!i||!t)return[1,1];const a=-1===i.max?1/0:i.max;return[i.min,a]}_setAndBind(e,t){this._setProperties(e,t);this._bindItems(e,t);this._bindElement(e,t)}_bindElement(e,t){const i=[];this._createOccurrences(e);for(const a of e[Er]()){if(a[tr])continue;if(void 0===this._mergeMode&&"subform"===a[Yr]){this._mergeMode="consumeData"===a.mergeMode;const e=t[Er]();if(e.length>0)this._bindOccurrences(a,[e[0]],null);else if(this.emptyMerge){const e=t[Hr]===Tn?-1:t[Hr],i=a[tr]=new XmlObject(e,a.name||"root");t[js](i);this._bindElement(a,i)}continue}if(!a[kr]())continue;let e=!1,s=null,r=null,n=null;if(a.bind){switch(a.bind.match){case"none":this._setAndBind(a,t);continue;case"global":e=!0;break;case"dataRef":if(!a.bind.ref){warn(`XFA - ref is empty in node ${a[Yr]}.`);this._setAndBind(a,t);continue}r=a.bind.ref}a.bind.picture&&(s=a.bind.picture[er])}const[o,g]=this._getOccurInfo(a);if(r){n=searchNode(this.root,t,r,!0,!1);if(null===n){n=createDataNode(this.data,t,r);if(!n)continue;this._isConsumeData()&&(n[Ar]=!0);this._setAndBind(a,n);continue}this._isConsumeData()&&(n=n.filter((e=>!e[Ar])));n.length>g?n=n.slice(0,g):0===n.length&&(n=null);n&&this._isConsumeData()&&n.forEach((e=>{e[Ar]=!0}))}else{if(!a.name){this._setAndBind(a,t);continue}if(this._isConsumeData()){const i=[];for(;i.length<g;){const s=this._findDataByNameToConsume(a.name,a[wr](),t,e);if(!s)break;s[Ar]=!0;i.push(s)}n=i.length>0?i:null}else{n=t[Qr](a.name,!1,this.emptyMerge).next().value;if(!n){if(0===o){i.push(a);continue}const e=t[Hr]===Tn?-1:t[Hr];n=a[tr]=new XmlObject(e,a.name);this.emptyMerge&&(n[Ar]=!0);t[js](n);this._setAndBind(a,n);continue}this.emptyMerge&&(n[Ar]=!0);n=[n]}}n?this._bindOccurrences(a,n,s):o>0?this._setAndBind(a,t):i.push(a)}i.forEach((e=>e[pr]()[Xr](e)))}}class DataHandler{constructor(e,t){this.data=t;this.dataset=e.datasets||null}serialize(e){const t=[[-1,this.data[Er]()]];for(;t.length>0;){const i=t.at(-1),[a,s]=i;if(a+1===s.length){t.pop();continue}const r=s[++i[0]],n=e.get(r[nn]);if(n)r[$r](n);else{const t=r[or]();for(const i of t.values()){const t=e.get(i[nn]);if(t){i[$r](t);break}}}const o=r[Er]();o.length>0&&t.push([-1,o])}const i=['<xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">'];if(this.dataset)for(const e of this.dataset[Er]())"data"!==e[Yr]&&e[sn](i);this.data[sn](i);i.push("</xfa:datasets>");return i.join("")}}const qn=gn.config.id;class Acrobat extends XFAObject{constructor(e){super(qn,"acrobat",!0);this.acrobat7=null;this.autoSave=null;this.common=null;this.validate=null;this.validateApprovalSignatures=null;this.submitUrl=new XFAObjectArray}}class Acrobat7 extends XFAObject{constructor(e){super(qn,"acrobat7",!0);this.dynamicRender=null}}class ADBE_JSConsole extends OptionObject{constructor(e){super(qn,"ADBE_JSConsole",["delegate","Enable","Disable"])}}class ADBE_JSDebugger extends OptionObject{constructor(e){super(qn,"ADBE_JSDebugger",["delegate","Enable","Disable"])}}class AddSilentPrint extends Option01{constructor(e){super(qn,"addSilentPrint")}}class AddViewerPreferences extends Option01{constructor(e){super(qn,"addViewerPreferences")}}class AdjustData extends Option10{constructor(e){super(qn,"adjustData")}}class AdobeExtensionLevel extends IntegerObject{constructor(e){super(qn,"adobeExtensionLevel",0,(e=>e>=1&&e<=8))}}class Agent extends XFAObject{constructor(e){super(qn,"agent",!0);this.name=e.name?e.name.trim():"";this.common=new XFAObjectArray}}class AlwaysEmbed extends ContentObject{constructor(e){super(qn,"alwaysEmbed")}}class Amd extends StringObject{constructor(e){super(qn,"amd")}}class config_Area extends XFAObject{constructor(e){super(qn,"area");this.level=getInteger({data:e.level,defaultValue:0,validate:e=>e>=1&&e<=3});this.name=getStringOption(e.name,["","barcode","coreinit","deviceDriver","font","general","layout","merge","script","signature","sourceSet","templateCache"])}}class Attributes extends OptionObject{constructor(e){super(qn,"attributes",["preserve","delegate","ignore"])}}class AutoSave extends OptionObject{constructor(e){super(qn,"autoSave",["disabled","enabled"])}}class Base extends StringObject{constructor(e){super(qn,"base")}}class BatchOutput extends XFAObject{constructor(e){super(qn,"batchOutput");this.format=getStringOption(e.format,["none","concat","zip","zipCompress"])}}class BehaviorOverride extends ContentObject{constructor(e){super(qn,"behaviorOverride")}[sr](){this[er]=new Map(this[er].trim().split(/\s+/).filter((e=>e.includes(":"))).map((e=>e.split(":",2))))}}class Cache extends XFAObject{constructor(e){super(qn,"cache",!0);this.templateCache=null}}class Change extends Option01{constructor(e){super(qn,"change")}}class Common extends XFAObject{constructor(e){super(qn,"common",!0);this.data=null;this.locale=null;this.localeSet=null;this.messaging=null;this.suppressBanner=null;this.template=null;this.validationMessaging=null;this.versionControl=null;this.log=new XFAObjectArray}}class Compress extends XFAObject{constructor(e){super(qn,"compress");this.scope=getStringOption(e.scope,["imageOnly","document"])}}class CompressLogicalStructure extends Option01{constructor(e){super(qn,"compressLogicalStructure")}}class CompressObjectStream extends Option10{constructor(e){super(qn,"compressObjectStream")}}class Compression extends XFAObject{constructor(e){super(qn,"compression",!0);this.compressLogicalStructure=null;this.compressObjectStream=null;this.level=null;this.type=null}}class Config extends XFAObject{constructor(e){super(qn,"config",!0);this.acrobat=null;this.present=null;this.trace=null;this.agent=new XFAObjectArray}}class Conformance extends OptionObject{constructor(e){super(qn,"conformance",["A","B"])}}class ContentCopy extends Option01{constructor(e){super(qn,"contentCopy")}}class Copies extends IntegerObject{constructor(e){super(qn,"copies",1,(e=>e>=1))}}class Creator extends StringObject{constructor(e){super(qn,"creator")}}class CurrentPage extends IntegerObject{constructor(e){super(qn,"currentPage",0,(e=>e>=0))}}class Data extends XFAObject{constructor(e){super(qn,"data",!0);this.adjustData=null;this.attributes=null;this.incrementalLoad=null;this.outputXSL=null;this.range=null;this.record=null;this.startNode=null;this.uri=null;this.window=null;this.xsl=null;this.excludeNS=new XFAObjectArray;this.transform=new XFAObjectArray}}class Debug extends XFAObject{constructor(e){super(qn,"debug",!0);this.uri=null}}class DefaultTypeface extends ContentObject{constructor(e){super(qn,"defaultTypeface");this.writingScript=getStringOption(e.writingScript,["*","Arabic","Cyrillic","EastEuropeanRoman","Greek","Hebrew","Japanese","Korean","Roman","SimplifiedChinese","Thai","TraditionalChinese","Vietnamese"])}}class Destination extends OptionObject{constructor(e){super(qn,"destination",["pdf","pcl","ps","webClient","zpl"])}}class DocumentAssembly extends Option01{constructor(e){super(qn,"documentAssembly")}}class Driver extends XFAObject{constructor(e){super(qn,"driver",!0);this.name=e.name?e.name.trim():"";this.fontInfo=null;this.xdc=null}}class DuplexOption extends OptionObject{constructor(e){super(qn,"duplexOption",["simplex","duplexFlipLongEdge","duplexFlipShortEdge"])}}class DynamicRender extends OptionObject{constructor(e){super(qn,"dynamicRender",["forbidden","required"])}}class Embed extends Option01{constructor(e){super(qn,"embed")}}class config_Encrypt extends Option01{constructor(e){super(qn,"encrypt")}}class config_Encryption extends XFAObject{constructor(e){super(qn,"encryption",!0);this.encrypt=null;this.encryptionLevel=null;this.permissions=null}}class EncryptionLevel extends OptionObject{constructor(e){super(qn,"encryptionLevel",["40bit","128bit"])}}class Enforce extends StringObject{constructor(e){super(qn,"enforce")}}class Equate extends XFAObject{constructor(e){super(qn,"equate");this.force=getInteger({data:e.force,defaultValue:1,validate:e=>0===e});this.from=e.from||"";this.to=e.to||""}}class EquateRange extends XFAObject{constructor(e){super(qn,"equateRange");this.from=e.from||"";this.to=e.to||"";this._unicodeRange=e.unicodeRange||""}get unicodeRange(){const e=[],t=/U\+([0-9a-fA-F]+)/,i=this._unicodeRange;for(let a of i.split(",").map((e=>e.trim())).filter((e=>!!e))){a=a.split("-",2).map((e=>{const i=e.match(t);return i?parseInt(i[1],16):0}));1===a.length&&a.push(a[0]);e.push(a)}return shadow(this,"unicodeRange",e)}}class Exclude extends ContentObject{constructor(e){super(qn,"exclude")}[sr](){this[er]=this[er].trim().split(/\s+/).filter((e=>e&&["calculate","close","enter","exit","initialize","ready","validate"].includes(e)))}}class ExcludeNS extends StringObject{constructor(e){super(qn,"excludeNS")}}class FlipLabel extends OptionObject{constructor(e){super(qn,"flipLabel",["usePrinterSetting","on","off"])}}class config_FontInfo extends XFAObject{constructor(e){super(qn,"fontInfo",!0);this.embed=null;this.map=null;this.subsetBelow=null;this.alwaysEmbed=new XFAObjectArray;this.defaultTypeface=new XFAObjectArray;this.neverEmbed=new XFAObjectArray}}class FormFieldFilling extends Option01{constructor(e){super(qn,"formFieldFilling")}}class GroupParent extends StringObject{constructor(e){super(qn,"groupParent")}}class IfEmpty extends OptionObject{constructor(e){super(qn,"ifEmpty",["dataValue","dataGroup","ignore","remove"])}}class IncludeXDPContent extends StringObject{constructor(e){super(qn,"includeXDPContent")}}class IncrementalLoad extends OptionObject{constructor(e){super(qn,"incrementalLoad",["none","forwardOnly"])}}class IncrementalMerge extends Option01{constructor(e){super(qn,"incrementalMerge")}}class Interactive extends Option01{constructor(e){super(qn,"interactive")}}class Jog extends OptionObject{constructor(e){super(qn,"jog",["usePrinterSetting","none","pageSet"])}}class LabelPrinter extends XFAObject{constructor(e){super(qn,"labelPrinter",!0);this.name=getStringOption(e.name,["zpl","dpl","ipl","tcpl"]);this.batchOutput=null;this.flipLabel=null;this.fontInfo=null;this.xdc=null}}class Layout extends OptionObject{constructor(e){super(qn,"layout",["paginate","panel"])}}class Level extends IntegerObject{constructor(e){super(qn,"level",0,(e=>e>0))}}class Linearized extends Option01{constructor(e){super(qn,"linearized")}}class Locale extends StringObject{constructor(e){super(qn,"locale")}}class LocaleSet extends StringObject{constructor(e){super(qn,"localeSet")}}class Log extends XFAObject{constructor(e){super(qn,"log",!0);this.mode=null;this.threshold=null;this.to=null;this.uri=null}}class MapElement extends XFAObject{constructor(e){super(qn,"map",!0);this.equate=new XFAObjectArray;this.equateRange=new XFAObjectArray}}class MediumInfo extends XFAObject{constructor(e){super(qn,"mediumInfo",!0);this.map=null}}class config_Message extends XFAObject{constructor(e){super(qn,"message",!0);this.msgId=null;this.severity=null}}class Messaging extends XFAObject{constructor(e){super(qn,"messaging",!0);this.message=new XFAObjectArray}}class Mode extends OptionObject{constructor(e){super(qn,"mode",["append","overwrite"])}}class ModifyAnnots extends Option01{constructor(e){super(qn,"modifyAnnots")}}class MsgId extends IntegerObject{constructor(e){super(qn,"msgId",1,(e=>e>=1))}}class NameAttr extends StringObject{constructor(e){super(qn,"nameAttr")}}class NeverEmbed extends ContentObject{constructor(e){super(qn,"neverEmbed")}}class NumberOfCopies extends IntegerObject{constructor(e){super(qn,"numberOfCopies",null,(e=>e>=2&&e<=5))}}class OpenAction extends XFAObject{constructor(e){super(qn,"openAction",!0);this.destination=null}}class Output extends XFAObject{constructor(e){super(qn,"output",!0);this.to=null;this.type=null;this.uri=null}}class OutputBin extends StringObject{constructor(e){super(qn,"outputBin")}}class OutputXSL extends XFAObject{constructor(e){super(qn,"outputXSL",!0);this.uri=null}}class Overprint extends OptionObject{constructor(e){super(qn,"overprint",["none","both","draw","field"])}}class Packets extends StringObject{constructor(e){super(qn,"packets")}[sr](){"*"!==this[er]&&(this[er]=this[er].trim().split(/\s+/).filter((e=>["config","datasets","template","xfdf","xslt"].includes(e))))}}class PageOffset extends XFAObject{constructor(e){super(qn,"pageOffset");this.x=getInteger({data:e.x,defaultValue:"useXDCSetting",validate:e=>!0});this.y=getInteger({data:e.y,defaultValue:"useXDCSetting",validate:e=>!0})}}class PageRange extends StringObject{constructor(e){super(qn,"pageRange")}[sr](){const e=this[er].trim().split(/\s+/).map((e=>parseInt(e,10))),t=[];for(let i=0,a=e.length;i<a;i+=2)t.push(e.slice(i,i+2));this[er]=t}}class Pagination extends OptionObject{constructor(e){super(qn,"pagination",["simplex","duplexShortEdge","duplexLongEdge"])}}class PaginationOverride extends OptionObject{constructor(e){super(qn,"paginationOverride",["none","forceDuplex","forceDuplexLongEdge","forceDuplexShortEdge","forceSimplex"])}}class Part extends IntegerObject{constructor(e){super(qn,"part",1,(e=>!1))}}class Pcl extends XFAObject{constructor(e){super(qn,"pcl",!0);this.name=e.name||"";this.batchOutput=null;this.fontInfo=null;this.jog=null;this.mediumInfo=null;this.outputBin=null;this.pageOffset=null;this.staple=null;this.xdc=null}}class Pdf extends XFAObject{constructor(e){super(qn,"pdf",!0);this.name=e.name||"";this.adobeExtensionLevel=null;this.batchOutput=null;this.compression=null;this.creator=null;this.encryption=null;this.fontInfo=null;this.interactive=null;this.linearized=null;this.openAction=null;this.pdfa=null;this.producer=null;this.renderPolicy=null;this.scriptModel=null;this.silentPrint=null;this.submitFormat=null;this.tagged=null;this.version=null;this.viewerPreferences=null;this.xdc=null}}class Pdfa extends XFAObject{constructor(e){super(qn,"pdfa",!0);this.amd=null;this.conformance=null;this.includeXDPContent=null;this.part=null}}class Permissions extends XFAObject{constructor(e){super(qn,"permissions",!0);this.accessibleContent=null;this.change=null;this.contentCopy=null;this.documentAssembly=null;this.formFieldFilling=null;this.modifyAnnots=null;this.plaintextMetadata=null;this.print=null;this.printHighQuality=null}}class PickTrayByPDFSize extends Option01{constructor(e){super(qn,"pickTrayByPDFSize")}}class config_Picture extends StringObject{constructor(e){super(qn,"picture")}}class PlaintextMetadata extends Option01{constructor(e){super(qn,"plaintextMetadata")}}class Presence extends OptionObject{constructor(e){super(qn,"presence",["preserve","dissolve","dissolveStructure","ignore","remove"])}}class Present extends XFAObject{constructor(e){super(qn,"present",!0);this.behaviorOverride=null;this.cache=null;this.common=null;this.copies=null;this.destination=null;this.incrementalMerge=null;this.layout=null;this.output=null;this.overprint=null;this.pagination=null;this.paginationOverride=null;this.script=null;this.validate=null;this.xdp=null;this.driver=new XFAObjectArray;this.labelPrinter=new XFAObjectArray;this.pcl=new XFAObjectArray;this.pdf=new XFAObjectArray;this.ps=new XFAObjectArray;this.submitUrl=new XFAObjectArray;this.webClient=new XFAObjectArray;this.zpl=new XFAObjectArray}}class Print extends Option01{constructor(e){super(qn,"print")}}class PrintHighQuality extends Option01{constructor(e){super(qn,"printHighQuality")}}class PrintScaling extends OptionObject{constructor(e){super(qn,"printScaling",["appdefault","noScaling"])}}class PrinterName extends StringObject{constructor(e){super(qn,"printerName")}}class Producer extends StringObject{constructor(e){super(qn,"producer")}}class Ps extends XFAObject{constructor(e){super(qn,"ps",!0);this.name=e.name||"";this.batchOutput=null;this.fontInfo=null;this.jog=null;this.mediumInfo=null;this.outputBin=null;this.staple=null;this.xdc=null}}class Range extends ContentObject{constructor(e){super(qn,"range")}[sr](){this[er]=this[er].trim().split(/\s*,\s*/,2).map((e=>e.split("-").map((e=>parseInt(e.trim(),10))))).filter((e=>e.every((e=>!isNaN(e))))).map((e=>{1===e.length&&e.push(e[0]);return e}))}}class Record extends ContentObject{constructor(e){super(qn,"record")}[sr](){this[er]=this[er].trim();const e=parseInt(this[er],10);!isNaN(e)&&e>=0&&(this[er]=e)}}class Relevant extends ContentObject{constructor(e){super(qn,"relevant")}[sr](){this[er]=this[er].trim().split(/\s+/)}}class Rename extends ContentObject{constructor(e){super(qn,"rename")}[sr](){this[er]=this[er].trim();(this[er].toLowerCase().startsWith("xml")||new RegExp("[\\p{L}_][\\p{L}\\d._\\p{M}-]*","u").test(this[er]))&&warn("XFA - Rename: invalid XFA name")}}class RenderPolicy extends OptionObject{constructor(e){super(qn,"renderPolicy",["server","client"])}}class RunScripts extends OptionObject{constructor(e){super(qn,"runScripts",["both","client","none","server"])}}class config_Script extends XFAObject{constructor(e){super(qn,"script",!0);this.currentPage=null;this.exclude=null;this.runScripts=null}}class ScriptModel extends OptionObject{constructor(e){super(qn,"scriptModel",["XFA","none"])}}class Severity extends OptionObject{constructor(e){super(qn,"severity",["ignore","error","information","trace","warning"])}}class SilentPrint extends XFAObject{constructor(e){super(qn,"silentPrint",!0);this.addSilentPrint=null;this.printerName=null}}class Staple extends XFAObject{constructor(e){super(qn,"staple");this.mode=getStringOption(e.mode,["usePrinterSetting","on","off"])}}class StartNode extends StringObject{constructor(e){super(qn,"startNode")}}class StartPage extends IntegerObject{constructor(e){super(qn,"startPage",0,(e=>!0))}}class SubmitFormat extends OptionObject{constructor(e){super(qn,"submitFormat",["html","delegate","fdf","xml","pdf"])}}class SubmitUrl extends StringObject{constructor(e){super(qn,"submitUrl")}}class SubsetBelow extends IntegerObject{constructor(e){super(qn,"subsetBelow",100,(e=>e>=0&&e<=100))}}class SuppressBanner extends Option01{constructor(e){super(qn,"suppressBanner")}}class Tagged extends Option01{constructor(e){super(qn,"tagged")}}class config_Template extends XFAObject{constructor(e){super(qn,"template",!0);this.base=null;this.relevant=null;this.startPage=null;this.uri=null;this.xsl=null}}class Threshold extends OptionObject{constructor(e){super(qn,"threshold",["trace","error","information","warning"])}}class To extends OptionObject{constructor(e){super(qn,"to",["null","memory","stderr","stdout","system","uri"])}}class TemplateCache extends XFAObject{constructor(e){super(qn,"templateCache");this.maxEntries=getInteger({data:e.maxEntries,defaultValue:5,validate:e=>e>=0})}}class Trace extends XFAObject{constructor(e){super(qn,"trace",!0);this.area=new XFAObjectArray}}class Transform extends XFAObject{constructor(e){super(qn,"transform",!0);this.groupParent=null;this.ifEmpty=null;this.nameAttr=null;this.picture=null;this.presence=null;this.rename=null;this.whitespace=null}}class Type extends OptionObject{constructor(e){super(qn,"type",["none","ascii85","asciiHex","ccittfax","flate","lzw","runLength","native","xdp","mergedXDP"])}}class Uri extends StringObject{constructor(e){super(qn,"uri")}}class config_Validate extends OptionObject{constructor(e){super(qn,"validate",["preSubmit","prePrint","preExecute","preSave"])}}class ValidateApprovalSignatures extends ContentObject{constructor(e){super(qn,"validateApprovalSignatures")}[sr](){this[er]=this[er].trim().split(/\s+/).filter((e=>["docReady","postSign"].includes(e)))}}class ValidationMessaging extends OptionObject{constructor(e){super(qn,"validationMessaging",["allMessagesIndividually","allMessagesTogether","firstMessageOnly","noMessages"])}}class Version extends OptionObject{constructor(e){super(qn,"version",["1.7","1.6","1.5","1.4","1.3","1.2"])}}class VersionControl extends XFAObject{constructor(e){super(qn,"VersionControl");this.outputBelow=getStringOption(e.outputBelow,["warn","error","update"]);this.sourceAbove=getStringOption(e.sourceAbove,["warn","error"]);this.sourceBelow=getStringOption(e.sourceBelow,["update","maintain"])}}class ViewerPreferences extends XFAObject{constructor(e){super(qn,"viewerPreferences",!0);this.ADBE_JSConsole=null;this.ADBE_JSDebugger=null;this.addViewerPreferences=null;this.duplexOption=null;this.enforce=null;this.numberOfCopies=null;this.pageRange=null;this.pickTrayByPDFSize=null;this.printScaling=null}}class WebClient extends XFAObject{constructor(e){super(qn,"webClient",!0);this.name=e.name?e.name.trim():"";this.fontInfo=null;this.xdc=null}}class Whitespace extends OptionObject{constructor(e){super(qn,"whitespace",["preserve","ltrim","normalize","rtrim","trim"])}}class Window extends ContentObject{constructor(e){super(qn,"window")}[sr](){const e=this[er].trim().split(/\s*,\s*/,2).map((e=>parseInt(e,10)));if(e.some((e=>isNaN(e))))this[er]=[0,0];else{1===e.length&&e.push(e[0]);this[er]=e}}}class Xdc extends XFAObject{constructor(e){super(qn,"xdc",!0);this.uri=new XFAObjectArray;this.xsl=new XFAObjectArray}}class Xdp extends XFAObject{constructor(e){super(qn,"xdp",!0);this.packets=null}}class Xsl extends XFAObject{constructor(e){super(qn,"xsl",!0);this.debug=null;this.uri=null}}class Zpl extends XFAObject{constructor(e){super(qn,"zpl",!0);this.name=e.name?e.name.trim():"";this.batchOutput=null;this.flipLabel=null;this.fontInfo=null;this.xdc=null}}class ConfigNamespace{static[on](e,t){if(ConfigNamespace.hasOwnProperty(e))return ConfigNamespace[e](t)}static acrobat(e){return new Acrobat(e)}static acrobat7(e){return new Acrobat7(e)}static ADBE_JSConsole(e){return new ADBE_JSConsole(e)}static ADBE_JSDebugger(e){return new ADBE_JSDebugger(e)}static addSilentPrint(e){return new AddSilentPrint(e)}static addViewerPreferences(e){return new AddViewerPreferences(e)}static adjustData(e){return new AdjustData(e)}static adobeExtensionLevel(e){return new AdobeExtensionLevel(e)}static agent(e){return new Agent(e)}static alwaysEmbed(e){return new AlwaysEmbed(e)}static amd(e){return new Amd(e)}static area(e){return new config_Area(e)}static attributes(e){return new Attributes(e)}static autoSave(e){return new AutoSave(e)}static base(e){return new Base(e)}static batchOutput(e){return new BatchOutput(e)}static behaviorOverride(e){return new BehaviorOverride(e)}static cache(e){return new Cache(e)}static change(e){return new Change(e)}static common(e){return new Common(e)}static compress(e){return new Compress(e)}static compressLogicalStructure(e){return new CompressLogicalStructure(e)}static compressObjectStream(e){return new CompressObjectStream(e)}static compression(e){return new Compression(e)}static config(e){return new Config(e)}static conformance(e){return new Conformance(e)}static contentCopy(e){return new ContentCopy(e)}static copies(e){return new Copies(e)}static creator(e){return new Creator(e)}static currentPage(e){return new CurrentPage(e)}static data(e){return new Data(e)}static debug(e){return new Debug(e)}static defaultTypeface(e){return new DefaultTypeface(e)}static destination(e){return new Destination(e)}static documentAssembly(e){return new DocumentAssembly(e)}static driver(e){return new Driver(e)}static duplexOption(e){return new DuplexOption(e)}static dynamicRender(e){return new DynamicRender(e)}static embed(e){return new Embed(e)}static encrypt(e){return new config_Encrypt(e)}static encryption(e){return new config_Encryption(e)}static encryptionLevel(e){return new EncryptionLevel(e)}static enforce(e){return new Enforce(e)}static equate(e){return new Equate(e)}static equateRange(e){return new EquateRange(e)}static exclude(e){return new Exclude(e)}static excludeNS(e){return new ExcludeNS(e)}static flipLabel(e){return new FlipLabel(e)}static fontInfo(e){return new config_FontInfo(e)}static formFieldFilling(e){return new FormFieldFilling(e)}static groupParent(e){return new GroupParent(e)}static ifEmpty(e){return new IfEmpty(e)}static includeXDPContent(e){return new IncludeXDPContent(e)}static incrementalLoad(e){return new IncrementalLoad(e)}static incrementalMerge(e){return new IncrementalMerge(e)}static interactive(e){return new Interactive(e)}static jog(e){return new Jog(e)}static labelPrinter(e){return new LabelPrinter(e)}static layout(e){return new Layout(e)}static level(e){return new Level(e)}static linearized(e){return new Linearized(e)}static locale(e){return new Locale(e)}static localeSet(e){return new LocaleSet(e)}static log(e){return new Log(e)}static map(e){return new MapElement(e)}static mediumInfo(e){return new MediumInfo(e)}static message(e){return new config_Message(e)}static messaging(e){return new Messaging(e)}static mode(e){return new Mode(e)}static modifyAnnots(e){return new ModifyAnnots(e)}static msgId(e){return new MsgId(e)}static nameAttr(e){return new NameAttr(e)}static neverEmbed(e){return new NeverEmbed(e)}static numberOfCopies(e){return new NumberOfCopies(e)}static openAction(e){return new OpenAction(e)}static output(e){return new Output(e)}static outputBin(e){return new OutputBin(e)}static outputXSL(e){return new OutputXSL(e)}static overprint(e){return new Overprint(e)}static packets(e){return new Packets(e)}static pageOffset(e){return new PageOffset(e)}static pageRange(e){return new PageRange(e)}static pagination(e){return new Pagination(e)}static paginationOverride(e){return new PaginationOverride(e)}static part(e){return new Part(e)}static pcl(e){return new Pcl(e)}static pdf(e){return new Pdf(e)}static pdfa(e){return new Pdfa(e)}static permissions(e){return new Permissions(e)}static pickTrayByPDFSize(e){return new PickTrayByPDFSize(e)}static picture(e){return new config_Picture(e)}static plaintextMetadata(e){return new PlaintextMetadata(e)}static presence(e){return new Presence(e)}static present(e){return new Present(e)}static print(e){return new Print(e)}static printHighQuality(e){return new PrintHighQuality(e)}static printScaling(e){return new PrintScaling(e)}static printerName(e){return new PrinterName(e)}static producer(e){return new Producer(e)}static ps(e){return new Ps(e)}static range(e){return new Range(e)}static record(e){return new Record(e)}static relevant(e){return new Relevant(e)}static rename(e){return new Rename(e)}static renderPolicy(e){return new RenderPolicy(e)}static runScripts(e){return new RunScripts(e)}static script(e){return new config_Script(e)}static scriptModel(e){return new ScriptModel(e)}static severity(e){return new Severity(e)}static silentPrint(e){return new SilentPrint(e)}static staple(e){return new Staple(e)}static startNode(e){return new StartNode(e)}static startPage(e){return new StartPage(e)}static submitFormat(e){return new SubmitFormat(e)}static submitUrl(e){return new SubmitUrl(e)}static subsetBelow(e){return new SubsetBelow(e)}static suppressBanner(e){return new SuppressBanner(e)}static tagged(e){return new Tagged(e)}static template(e){return new config_Template(e)}static templateCache(e){return new TemplateCache(e)}static threshold(e){return new Threshold(e)}static to(e){return new To(e)}static trace(e){return new Trace(e)}static transform(e){return new Transform(e)}static type(e){return new Type(e)}static uri(e){return new Uri(e)}static validate(e){return new config_Validate(e)}static validateApprovalSignatures(e){return new ValidateApprovalSignatures(e)}static validationMessaging(e){return new ValidationMessaging(e)}static version(e){return new Version(e)}static versionControl(e){return new VersionControl(e)}static viewerPreferences(e){return new ViewerPreferences(e)}static webClient(e){return new WebClient(e)}static whitespace(e){return new Whitespace(e)}static window(e){return new Window(e)}static xdc(e){return new Xdc(e)}static xdp(e){return new Xdp(e)}static xsl(e){return new Xsl(e)}static zpl(e){return new Zpl(e)}}const On=gn.connectionSet.id;class ConnectionSet extends XFAObject{constructor(e){super(On,"connectionSet",!0);this.wsdlConnection=new XFAObjectArray;this.xmlConnection=new XFAObjectArray;this.xsdConnection=new XFAObjectArray}}class EffectiveInputPolicy extends XFAObject{constructor(e){super(On,"effectiveInputPolicy");this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}}class EffectiveOutputPolicy extends XFAObject{constructor(e){super(On,"effectiveOutputPolicy");this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}}class Operation extends StringObject{constructor(e){super(On,"operation");this.id=e.id||"";this.input=e.input||"";this.name=e.name||"";this.output=e.output||"";this.use=e.use||"";this.usehref=e.usehref||""}}class RootElement extends StringObject{constructor(e){super(On,"rootElement");this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}}class SoapAction extends StringObject{constructor(e){super(On,"soapAction");this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}}class SoapAddress extends StringObject{constructor(e){super(On,"soapAddress");this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}}class connection_set_Uri extends StringObject{constructor(e){super(On,"uri");this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}}class WsdlAddress extends StringObject{constructor(e){super(On,"wsdlAddress");this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}}class WsdlConnection extends XFAObject{constructor(e){super(On,"wsdlConnection",!0);this.dataDescription=e.dataDescription||"";this.name=e.name||"";this.effectiveInputPolicy=null;this.effectiveOutputPolicy=null;this.operation=null;this.soapAction=null;this.soapAddress=null;this.wsdlAddress=null}}class XmlConnection extends XFAObject{constructor(e){super(On,"xmlConnection",!0);this.dataDescription=e.dataDescription||"";this.name=e.name||"";this.uri=null}}class XsdConnection extends XFAObject{constructor(e){super(On,"xsdConnection",!0);this.dataDescription=e.dataDescription||"";this.name=e.name||"";this.rootElement=null;this.uri=null}}class ConnectionSetNamespace{static[on](e,t){if(ConnectionSetNamespace.hasOwnProperty(e))return ConnectionSetNamespace[e](t)}static connectionSet(e){return new ConnectionSet(e)}static effectiveInputPolicy(e){return new EffectiveInputPolicy(e)}static effectiveOutputPolicy(e){return new EffectiveOutputPolicy(e)}static operation(e){return new Operation(e)}static rootElement(e){return new RootElement(e)}static soapAction(e){return new SoapAction(e)}static soapAddress(e){return new SoapAddress(e)}static uri(e){return new connection_set_Uri(e)}static wsdlAddress(e){return new WsdlAddress(e)}static wsdlConnection(e){return new WsdlConnection(e)}static xmlConnection(e){return new XmlConnection(e)}static xsdConnection(e){return new XsdConnection(e)}}const Pn=gn.datasets.id;class datasets_Data extends XmlObject{constructor(e){super(Pn,"data",e)}[Gr](){return!0}}class Datasets extends XFAObject{constructor(e){super(Pn,"datasets",!0);this.data=null;this.Signature=null}[Kr](e){const t=e[Yr];("data"===t&&e[Hr]===Pn||"Signature"===t&&e[Hr]===gn.signature.id)&&(this[t]=e);this[js](e)}}class DatasetsNamespace{static[on](e,t){if(DatasetsNamespace.hasOwnProperty(e))return DatasetsNamespace[e](t)}static datasets(e){return new Datasets(e)}static data(e){return new datasets_Data(e)}}const Wn=gn.localeSet.id;class CalendarSymbols extends XFAObject{constructor(e){super(Wn,"calendarSymbols",!0);this.name="gregorian";this.dayNames=new XFAObjectArray(2);this.eraNames=null;this.meridiemNames=null;this.monthNames=new XFAObjectArray(2)}}class CurrencySymbol extends StringObject{constructor(e){super(Wn,"currencySymbol");this.name=getStringOption(e.name,["symbol","isoname","decimal"])}}class CurrencySymbols extends XFAObject{constructor(e){super(Wn,"currencySymbols",!0);this.currencySymbol=new XFAObjectArray(3)}}class DatePattern extends StringObject{constructor(e){super(Wn,"datePattern");this.name=getStringOption(e.name,["full","long","med","short"])}}class DatePatterns extends XFAObject{constructor(e){super(Wn,"datePatterns",!0);this.datePattern=new XFAObjectArray(4)}}class DateTimeSymbols extends ContentObject{constructor(e){super(Wn,"dateTimeSymbols")}}class Day extends StringObject{constructor(e){super(Wn,"day")}}class DayNames extends XFAObject{constructor(e){super(Wn,"dayNames",!0);this.abbr=getInteger({data:e.abbr,defaultValue:0,validate:e=>1===e});this.day=new XFAObjectArray(7)}}class Era extends StringObject{constructor(e){super(Wn,"era")}}class EraNames extends XFAObject{constructor(e){super(Wn,"eraNames",!0);this.era=new XFAObjectArray(2)}}class locale_set_Locale extends XFAObject{constructor(e){super(Wn,"locale",!0);this.desc=e.desc||"";this.name="isoname";this.calendarSymbols=null;this.currencySymbols=null;this.datePatterns=null;this.dateTimeSymbols=null;this.numberPatterns=null;this.numberSymbols=null;this.timePatterns=null;this.typeFaces=null}}class locale_set_LocaleSet extends XFAObject{constructor(e){super(Wn,"localeSet",!0);this.locale=new XFAObjectArray}}class Meridiem extends StringObject{constructor(e){super(Wn,"meridiem")}}class MeridiemNames extends XFAObject{constructor(e){super(Wn,"meridiemNames",!0);this.meridiem=new XFAObjectArray(2)}}class Month extends StringObject{constructor(e){super(Wn,"month")}}class MonthNames extends XFAObject{constructor(e){super(Wn,"monthNames",!0);this.abbr=getInteger({data:e.abbr,defaultValue:0,validate:e=>1===e});this.month=new XFAObjectArray(12)}}class NumberPattern extends StringObject{constructor(e){super(Wn,"numberPattern");this.name=getStringOption(e.name,["full","long","med","short"])}}class NumberPatterns extends XFAObject{constructor(e){super(Wn,"numberPatterns",!0);this.numberPattern=new XFAObjectArray(4)}}class NumberSymbol extends StringObject{constructor(e){super(Wn,"numberSymbol");this.name=getStringOption(e.name,["decimal","grouping","percent","minus","zero"])}}class NumberSymbols extends XFAObject{constructor(e){super(Wn,"numberSymbols",!0);this.numberSymbol=new XFAObjectArray(5)}}class TimePattern extends StringObject{constructor(e){super(Wn,"timePattern");this.name=getStringOption(e.name,["full","long","med","short"])}}class TimePatterns extends XFAObject{constructor(e){super(Wn,"timePatterns",!0);this.timePattern=new XFAObjectArray(4)}}class TypeFace extends XFAObject{constructor(e){super(Wn,"typeFace",!0);this.name=""|e.name}}class TypeFaces extends XFAObject{constructor(e){super(Wn,"typeFaces",!0);this.typeFace=new XFAObjectArray}}class LocaleSetNamespace{static[on](e,t){if(LocaleSetNamespace.hasOwnProperty(e))return LocaleSetNamespace[e](t)}static calendarSymbols(e){return new CalendarSymbols(e)}static currencySymbol(e){return new CurrencySymbol(e)}static currencySymbols(e){return new CurrencySymbols(e)}static datePattern(e){return new DatePattern(e)}static datePatterns(e){return new DatePatterns(e)}static dateTimeSymbols(e){return new DateTimeSymbols(e)}static day(e){return new Day(e)}static dayNames(e){return new DayNames(e)}static era(e){return new Era(e)}static eraNames(e){return new EraNames(e)}static locale(e){return new locale_set_Locale(e)}static localeSet(e){return new locale_set_LocaleSet(e)}static meridiem(e){return new Meridiem(e)}static meridiemNames(e){return new MeridiemNames(e)}static month(e){return new Month(e)}static monthNames(e){return new MonthNames(e)}static numberPattern(e){return new NumberPattern(e)}static numberPatterns(e){return new NumberPatterns(e)}static numberSymbol(e){return new NumberSymbol(e)}static numberSymbols(e){return new NumberSymbols(e)}static timePattern(e){return new TimePattern(e)}static timePatterns(e){return new TimePatterns(e)}static typeFace(e){return new TypeFace(e)}static typeFaces(e){return new TypeFaces(e)}}const Xn=gn.signature.id;class signature_Signature extends XFAObject{constructor(e){super(Xn,"signature",!0)}}class SignatureNamespace{static[on](e,t){if(SignatureNamespace.hasOwnProperty(e))return SignatureNamespace[e](t)}static signature(e){return new signature_Signature(e)}}const jn=gn.stylesheet.id;class Stylesheet extends XFAObject{constructor(e){super(jn,"stylesheet",!0)}}class StylesheetNamespace{static[on](e,t){if(StylesheetNamespace.hasOwnProperty(e))return StylesheetNamespace[e](t)}static stylesheet(e){return new Stylesheet(e)}}const Zn=gn.xdp.id;class xdp_Xdp extends XFAObject{constructor(e){super(Zn,"xdp",!0);this.uuid=e.uuid||"";this.timeStamp=e.timeStamp||"";this.config=null;this.connectionSet=null;this.datasets=null;this.localeSet=null;this.stylesheet=new XFAObjectArray;this.template=null}[Tr](e){const t=gn[e[Yr]];return t&&e[Hr]===t.id}}class XdpNamespace{static[on](e,t){if(XdpNamespace.hasOwnProperty(e))return XdpNamespace[e](t)}static xdp(e){return new xdp_Xdp(e)}}const Vn=gn.xhtml.id,zn=Symbol(),_n=new Set(["color","font","font-family","font-size","font-stretch","font-style","font-weight","margin","margin-bottom","margin-left","margin-right","margin-top","letter-spacing","line-height","orphans","page-break-after","page-break-before","page-break-inside","tab-interval","tab-stop","text-align","text-decoration","text-indent","vertical-align","widows","kerning-mode","xfa-font-horizontal-scale","xfa-font-vertical-scale","xfa-spacerun","xfa-tab-stops"]),$n=new Map([["page-break-after","breakAfter"],["page-break-before","breakBefore"],["page-break-inside","breakInside"],["kerning-mode",e=>"none"===e?"none":"normal"],["xfa-font-horizontal-scale",e=>`scaleX(${Math.max(0,Math.min(parseInt(e)/100)).toFixed(2)})`],["xfa-font-vertical-scale",e=>`scaleY(${Math.max(0,Math.min(parseInt(e)/100)).toFixed(2)})`],["xfa-spacerun",""],["xfa-tab-stops",""],["font-size",(e,t)=>measureToString(.99*(e=t.fontSize=getMeasurement(e)))],["letter-spacing",e=>measureToString(getMeasurement(e))],["line-height",e=>measureToString(getMeasurement(e))],["margin",e=>measureToString(getMeasurement(e))],["margin-bottom",e=>measureToString(getMeasurement(e))],["margin-left",e=>measureToString(getMeasurement(e))],["margin-right",e=>measureToString(getMeasurement(e))],["margin-top",e=>measureToString(getMeasurement(e))],["text-indent",e=>measureToString(getMeasurement(e))],["font-family",e=>e],["vertical-align",e=>measureToString(getMeasurement(e))]]),Ao=/\s+/g,eo=/[\r\n]+/g,to=/\r\n?/g;function mapStyle(e,t,i){const a=Object.create(null);if(!e)return a;const s=Object.create(null);for(const[t,i]of e.split(";").map((e=>e.split(":",2)))){const e=$n.get(t);if(""===e)continue;let r=i;e&&(r="string"==typeof e?e:e(i,s));t.endsWith("scale")?a.transform=a.transform?`${a[t]} ${r}`:r:a[t.replaceAll(/-([a-zA-Z])/g,((e,t)=>t.toUpperCase()))]=r}a.fontFamily&&setFontFamily({typeface:a.fontFamily,weight:a.fontWeight||"normal",posture:a.fontStyle||"normal",size:s.fontSize||0},t,t[yr].fontFinder,a);if(i&&a.verticalAlign&&"0px"!==a.verticalAlign&&a.fontSize){const e=.583,t=.333,i=getMeasurement(a.fontSize);a.fontSize=measureToString(i*e);a.verticalAlign=measureToString(Math.sign(getMeasurement(a.verticalAlign))*i*t)}i&&a.fontSize&&(a.fontSize=`calc(${a.fontSize} * var(--scale-factor))`);fixTextIndent(a);return a}const io=new Set(["body","html"]);class XhtmlObject extends XmlObject{constructor(e,t){super(Vn,t);this[zn]=!1;this.style=e.style||""}[Vs](e){super[Vs](e);this.style=function checkStyle(e){return e.style?e.style.trim().split(/\s*;\s*/).filter((e=>!!e)).map((e=>e.split(/\s*:\s*/,2))).filter((([t,i])=>{"font-family"===t&&e[yr].usedTypefaces.add(i);return _n.has(t)})).map((e=>e.join(":"))).join(";"):""}(this)}[Ws](){return!io.has(this[Yr])}[qr](e,t=!1){if(t)this[zn]=!0;else{e=e.replaceAll(eo,"");this.style.includes("xfa-spacerun:yes")||(e=e.replaceAll(Ao," "))}e&&(this[er]+=e)}[Or](e,t=!0){const i=Object.create(null),a={top:NaN,bottom:NaN,left:NaN,right:NaN};let s=null;for(const[e,t]of this.style.split(";").map((e=>e.split(":",2))))switch(e){case"font-family":i.typeface=stripQuotes(t);break;case"font-size":i.size=getMeasurement(t);break;case"font-weight":i.weight=t;break;case"font-style":i.posture=t;break;case"letter-spacing":i.letterSpacing=getMeasurement(t);break;case"margin":const e=t.split(/ \t/).map((e=>getMeasurement(e)));switch(e.length){case 1:a.top=a.bottom=a.left=a.right=e[0];break;case 2:a.top=a.bottom=e[0];a.left=a.right=e[1];break;case 3:a.top=e[0];a.bottom=e[2];a.left=a.right=e[1];break;case 4:a.top=e[0];a.left=e[1];a.bottom=e[2];a.right=e[3]}break;case"margin-top":a.top=getMeasurement(t);break;case"margin-bottom":a.bottom=getMeasurement(t);break;case"margin-left":a.left=getMeasurement(t);break;case"margin-right":a.right=getMeasurement(t);break;case"line-height":s=getMeasurement(t)}e.pushData(i,a,s);if(this[er])e.addString(this[er]);else for(const t of this[Er]())"#text"!==t[Yr]?t[Or](e):e.addString(t[er]);t&&e.popFont()}[an](e){const t=[];this[ar]={children:t};this[Zs]({});if(0===t.length&&!this[er])return HTMLResult.EMPTY;let i;i=this[zn]?this[er]?this[er].replaceAll(to,"\n"):void 0:this[er]||void 0;return HTMLResult.success({name:this[Yr],attributes:{href:this.href,style:mapStyle(this.style,this,this[zn])},children:t,value:i})}}class A extends XhtmlObject{constructor(e){super(e,"a");this.href=fixURL(e.href)||""}}class B extends XhtmlObject{constructor(e){super(e,"b")}[Or](e){e.pushFont({weight:"bold"});super[Or](e);e.popFont()}}class Body extends XhtmlObject{constructor(e){super(e,"body")}[an](e){const t=super[an](e),{html:i}=t;if(!i)return HTMLResult.EMPTY;i.name="div";i.attributes.class=["xfaRich"];return t}}class Br extends XhtmlObject{constructor(e){super(e,"br")}[en](){return"\n"}[Or](e){e.addString("\n")}[an](e){return HTMLResult.success({name:"br"})}}class Html extends XhtmlObject{constructor(e){super(e,"html")}[an](e){const t=[];this[ar]={children:t};this[Zs]({});if(0===t.length)return HTMLResult.success({name:"div",attributes:{class:["xfaRich"],style:{}},value:this[er]||""});if(1===t.length){const e=t[0];if(e.attributes?.class.includes("xfaRich"))return HTMLResult.success(e)}return HTMLResult.success({name:"div",attributes:{class:["xfaRich"],style:{}},children:t})}}class I extends XhtmlObject{constructor(e){super(e,"i")}[Or](e){e.pushFont({posture:"italic"});super[Or](e);e.popFont()}}class Li extends XhtmlObject{constructor(e){super(e,"li")}}class Ol extends XhtmlObject{constructor(e){super(e,"ol")}}class P extends XhtmlObject{constructor(e){super(e,"p")}[Or](e){super[Or](e,!1);e.addString("\n");e.addPara();e.popFont()}[en](){return this[pr]()[Er]().at(-1)===this?super[en]():super[en]()+"\n"}}class Span extends XhtmlObject{constructor(e){super(e,"span")}}class Sub extends XhtmlObject{constructor(e){super(e,"sub")}}class Sup extends XhtmlObject{constructor(e){super(e,"sup")}}class Ul extends XhtmlObject{constructor(e){super(e,"ul")}}class XhtmlNamespace{static[on](e,t){if(XhtmlNamespace.hasOwnProperty(e))return XhtmlNamespace[e](t)}static a(e){return new A(e)}static b(e){return new B(e)}static body(e){return new Body(e)}static br(e){return new Br(e)}static html(e){return new Html(e)}static i(e){return new I(e)}static li(e){return new Li(e)}static ol(e){return new Ol(e)}static p(e){return new P(e)}static span(e){return new Span(e)}static sub(e){return new Sub(e)}static sup(e){return new Sup(e)}static ul(e){return new Ul(e)}}const ao={config:ConfigNamespace,connection:ConnectionSetNamespace,datasets:DatasetsNamespace,localeSet:LocaleSetNamespace,signature:SignatureNamespace,stylesheet:StylesheetNamespace,template:TemplateNamespace,xdp:XdpNamespace,xhtml:XhtmlNamespace};class UnknownNamespace{constructor(e){this.namespaceId=e}[on](e,t){return new XmlObject(this.namespaceId,e,t)}}class Root extends XFAObject{constructor(e){super(-1,"root",Object.create(null));this.element=null;this[br]=e}[Kr](e){this.element=e;return!0}[sr](){super[sr]();if(this.element.template instanceof Template){this[br].set(jr,this.element);this.element.template[Zr](this[br]);this.element.template[br]=this[br]}}}class Empty extends XFAObject{constructor(){super(-1,"",Object.create(null))}[Kr](e){return!1}}class Builder{constructor(e=null){this._namespaceStack=[];this._nsAgnosticLevel=0;this._namespacePrefixes=new Map;this._namespaces=new Map;this._nextNsId=Math.max(...Object.values(gn).map((({id:e})=>e)));this._currentNamespace=e||new UnknownNamespace(++this._nextNsId)}buildRoot(e){return new Root(e)}build({nsPrefix:e,name:t,attributes:i,namespace:a,prefixes:s}){const r=null!==a;if(r){this._namespaceStack.push(this._currentNamespace);this._currentNamespace=this._searchNamespace(a)}s&&this._addNamespacePrefix(s);if(i.hasOwnProperty(vr)){const e=ao.datasets,t=i[vr];let a=null;for(const[i,s]of Object.entries(t)){if(this._getNamespaceToUse(i)===e){a={xfa:s};break}}a?i[vr]=a:delete i[vr]}const n=this._getNamespaceToUse(e),o=n?.[on](t,i)||new Empty;o[Gr]()&&this._nsAgnosticLevel++;(r||s||o[Gr]())&&(o[_s]={hasNamespace:r,prefixes:s,nsAgnostic:o[Gr]()});return o}isNsAgnostic(){return this._nsAgnosticLevel>0}_searchNamespace(e){let t=this._namespaces.get(e);if(t)return t;for(const[i,{check:a}]of Object.entries(gn))if(a(e)){t=ao[i];if(t){this._namespaces.set(e,t);return t}break}t=new UnknownNamespace(++this._nextNsId);this._namespaces.set(e,t);return t}_addNamespacePrefix(e){for(const{prefix:t,value:i}of e){const e=this._searchNamespace(i);let a=this._namespacePrefixes.get(t);if(!a){a=[];this._namespacePrefixes.set(t,a)}a.push(e)}}_getNamespaceToUse(e){if(!e)return this._currentNamespace;const t=this._namespacePrefixes.get(e);if(t?.length>0)return t.at(-1);warn(`Unknown namespace prefix: ${e}.`);return null}clean(e){const{hasNamespace:t,prefixes:i,nsAgnostic:a}=e;t&&(this._currentNamespace=this._namespaceStack.pop());i&&i.forEach((({prefix:e})=>{this._namespacePrefixes.get(e).pop()}));a&&this._nsAgnosticLevel--}}class XFAParser extends XMLParserBase{constructor(e=null,t=!1){super();this._builder=new Builder(e);this._stack=[];this._globalData={usedTypefaces:new Set};this._ids=new Map;this._current=this._builder.buildRoot(this._ids);this._errorCode=Rs;this._whiteRegex=/^\s+$/;this._nbsps=/\xa0+/g;this._richText=t}parse(e){this.parseXml(e);if(this._errorCode===Rs){this._current[sr]();return this._current.element}}onText(e){e=e.replace(this._nbsps,(e=>e.slice(1)+" "));this._richText||this._current[Ws]()?this._current[qr](e,this._richText):this._whiteRegex.test(e)||this._current[qr](e.trim())}onCdata(e){this._current[qr](e)}_mkAttributes(e,t){let i=null,a=null;const s=Object.create({});for(const{name:r,value:n}of e)if("xmlns"===r)i?warn(`XFA - multiple namespace definition in <${t}>`):i=n;else if(r.startsWith("xmlns:")){const e=r.substring(6);a||(a=[]);a.push({prefix:e,value:n})}else{const e=r.indexOf(":");if(-1===e)s[r]=n;else{let t=s[vr];t||(t=s[vr]=Object.create(null));const[i,a]=[r.slice(0,e),r.slice(e+1)];(t[i]||=Object.create(null))[a]=n}}return[i,a,s]}_getNameAndPrefix(e,t){const i=e.indexOf(":");return-1===i?[e,null]:[e.substring(i+1),t?"":e.substring(0,i)]}onBeginElement(e,t,i){const[a,s,r]=this._mkAttributes(t,e),[n,o]=this._getNameAndPrefix(e,this._builder.isNsAgnostic()),g=this._builder.build({nsPrefix:o,name:n,attributes:r,namespace:a,prefixes:s});g[yr]=this._globalData;if(i){g[sr]();this._current[Kr](g)&&g[zr](this._ids);g[Vs](this._builder)}else{this._stack.push(this._current);this._current=g}}onEndElement(e){const t=this._current;if(t[Sr]()&&"string"==typeof t[er]){const e=new XFAParser;e._globalData=this._globalData;const i=e.parse(t[er]);t[er]=null;t[Kr](i)}t[sr]();this._current=this._stack.pop();this._current[Kr](t)&&t[zr](this._ids);t[Vs](this._builder)}onError(e){this._errorCode=e}}class XFAFactory{constructor(e){try{this.root=(new XFAParser).parse(XFAFactory._createDocument(e));const t=new Binder(this.root);this.form=t.bind();this.dataHandler=new DataHandler(this.root,t.getData());this.form[yr].template=this.form}catch(e){warn(`XFA - an error occurred during parsing and binding: ${e}`)}}isValid(){return this.root&&this.form}_createPagesHelper(){const e=this.form[tn]();return new Promise(((t,i)=>{const nextIteration=()=>{try{const i=e.next();i.done?t(i.value):setTimeout(nextIteration,0)}catch(e){i(e)}};setTimeout(nextIteration,0)}))}async _createPages(){try{this.pages=await this._createPagesHelper();this.dims=this.pages.children.map((e=>{const{width:t,height:i}=e.attributes.style;return[0,0,parseInt(t),parseInt(i)]}))}catch(e){warn(`XFA - an error occurred during layout: ${e}`)}}getBoundingBox(e){return this.dims[e]}async getNumPages(){this.pages||await this._createPages();return this.dims.length}setImages(e){this.form[yr].images=e}setFonts(e){this.form[yr].fontFinder=new FontFinder(e);const t=[];for(let e of this.form[yr].usedTypefaces){e=stripQuotes(e);this.form[yr].fontFinder.find(e)||t.push(e)}return t.length>0?t:null}appendFonts(e,t){this.form[yr].fontFinder.add(e,t)}async getPages(){this.pages||await this._createPages();const e=this.pages;this.pages=null;return e}serializeData(e){return this.dataHandler.serialize(e)}static _createDocument(e){return e["/xdp:xdp"]?Object.values(e).join(""):e["xdp:xdp"]}static getRichTextAsHtml(e){if(!e||"string"!=typeof e)return null;try{let t=new XFAParser(XhtmlNamespace,!0).parse(e);if(!["body","xhtml"].includes(t[Yr])){const e=XhtmlNamespace.body({});e[js](t);t=e}const i=t[an]();if(!i.success)return null;const{html:a}=i,{attributes:s}=a;if(s){s.class&&(s.class=s.class.filter((e=>!e.startsWith("xfa"))));s.dir="auto"}return{html:a,str:t[en]()}}catch(e){warn(`XFA - an error occurred during parsing of rich text: ${e}`)}return null}}class AnnotationFactory{static createGlobals(e){return Promise.all([e.ensureCatalog("acroForm"),e.ensureDoc("xfaDatasets"),e.ensureCatalog("structTreeRoot"),e.ensureCatalog("baseUrl"),e.ensureCatalog("attachments")]).then((([t,i,a,s,r])=>({pdfManager:e,acroForm:t instanceof Dict?t:Dict.empty,xfaDatasets:i,structTreeRoot:a,baseUrl:s,attachments:r})),(e=>{warn(`createGlobals: "${e}".`);return null}))}static async create(e,t,i,a,s,r){const n=s?await this._getPageIndex(e,t,i.pdfManager):null;return i.pdfManager.ensure(this,"_create",[e,t,i,a,s,n,r])}static _create(e,t,i,a,s=!1,r=null,n=null){const o=e.fetchIfRef(t);if(!(o instanceof Dict))return;const{acroForm:g,pdfManager:c}=i,h=t instanceof Ref?t.toString():`annot_${a.createObjId()}`;let l=o.get("Subtype");l=l instanceof Name?l.name:null;const C={xref:e,ref:t,dict:o,subtype:l,id:h,annotationGlobals:i,collectFields:s,needAppearances:!s&&!0===g.get("NeedAppearances"),pageIndex:r,evaluatorOptions:c.evaluatorOptions,pageRef:n};switch(l){case"Link":return new LinkAnnotation(C);case"Text":return new TextAnnotation(C);case"Widget":let e=getInheritableProperty({dict:o,key:"FT"});e=e instanceof Name?e.name:null;switch(e){case"Tx":return new TextWidgetAnnotation(C);case"Btn":return new ButtonWidgetAnnotation(C);case"Ch":return new ChoiceWidgetAnnotation(C);case"Sig":return new SignatureWidgetAnnotation(C)}warn(`Unimplemented widget field type "${e}", falling back to base field type.`);return new WidgetAnnotation(C);case"Popup":return new PopupAnnotation(C);case"FreeText":return new FreeTextAnnotation(C);case"Line":return new LineAnnotation(C);case"Square":return new SquareAnnotation(C);case"Circle":return new CircleAnnotation(C);case"PolyLine":return new PolylineAnnotation(C);case"Polygon":return new PolygonAnnotation(C);case"Caret":return new CaretAnnotation(C);case"Ink":return new InkAnnotation(C);case"Highlight":return new HighlightAnnotation(C);case"Underline":return new UnderlineAnnotation(C);case"Squiggly":return new SquigglyAnnotation(C);case"StrikeOut":return new StrikeOutAnnotation(C);case"Stamp":return new StampAnnotation(C);case"FileAttachment":return new FileAttachmentAnnotation(C);default:s||warn(l?`Unimplemented annotation type "${l}", falling back to base annotation.`:"Annotation is missing the required /Subtype.");return new Annotation(C)}}static async _getPageIndex(e,t,i){try{const a=await e.fetchIfRefAsync(t);if(!(a instanceof Dict))return-1;const s=a.getRaw("P");if(s instanceof Ref)try{return await i.ensureCatalog("getPageIndex",[s])}catch(e){info(`_getPageIndex -- not a valid page reference: "${e}".`)}if(a.has("Kids"))return-1;const r=await i.ensureDoc("numPages");for(let e=0;e<r;e++){const a=await i.getPage(e),s=await i.ensure(a,"annotations");for(const i of s)if(i instanceof Ref&&isRefsEqual(i,t))return e}}catch(e){warn(`_getPageIndex: "${e}".`)}return-1}static generateImages(e,t,i){if(!i){warn("generateImages: OffscreenCanvas is not supported, cannot save or print some annotations with images.");return null}let a;for(const{bitmapId:i,bitmap:s}of e)if(s){a||=new Map;a.set(i,StampAnnotation.createImage(s,t))}return a}static async saveNewAnnotations(e,t,i,a){const s=e.xref;let r;const n=[],o=[],{isOffscreenCanvasSupported:g}=e.options;for(const c of i)if(!c.deleted)switch(c.annotationType){case u:if(!r){const e=new Dict(s);e.set("BaseFont",Name.get("Helvetica"));e.set("Type",Name.get("Font"));e.set("Subtype",Name.get("Type1"));e.set("Encoding",Name.get("WinAnsiEncoding"));const t=[];r=s.getNewTemporaryRef();await writeObject(r,e,t,s);n.push({ref:r,data:t.join("")})}o.push(FreeTextAnnotation.createNewAnnotation(s,c,n,{evaluator:e,task:t,baseFontRef:r}));break;case d:c.quadPoints?o.push(HighlightAnnotation.createNewAnnotation(s,c,n)):o.push(InkAnnotation.createNewAnnotation(s,c,n));break;case p:o.push(InkAnnotation.createNewAnnotation(s,c,n));break;case f:if(!g)break;const i=await a.get(c.bitmapId);if(i.imageStream){const{imageStream:e,smaskStream:t}=i,a=[];if(t){const i=s.getNewTemporaryRef();await writeObject(i,t,a,s);n.push({ref:i,data:a.join("")});e.dict.set("SMask",i);a.length=0}const r=i.imageRef=s.getNewTemporaryRef();await writeObject(r,e,a,s);n.push({ref:r,data:a.join("")});i.imageStream=i.smaskStream=null}o.push(StampAnnotation.createNewAnnotation(s,c,n,{image:i}))}return{annotations:await Promise.all(o),dependencies:n}}static async printNewAnnotations(e,t,i,a,s){if(!a)return null;const{options:r,xref:n}=t,o=[];for(const g of a)if(!g.deleted)switch(g.annotationType){case u:o.push(FreeTextAnnotation.createNewPrintAnnotation(e,n,g,{evaluator:t,task:i,evaluatorOptions:r}));break;case d:g.quadPoints?o.push(HighlightAnnotation.createNewPrintAnnotation(e,n,g,{evaluatorOptions:r})):o.push(InkAnnotation.createNewPrintAnnotation(e,n,g,{evaluatorOptions:r}));break;case p:o.push(InkAnnotation.createNewPrintAnnotation(e,n,g,{evaluatorOptions:r}));break;case f:if(!r.isOffscreenCanvasSupported)break;const a=await s.get(g.bitmapId);if(a.imageStream){const{imageStream:e,smaskStream:t}=a;t&&e.dict.set("SMask",t);a.imageRef=new JpegStream(e,e.length);a.imageStream=a.smaskStream=null}o.push(StampAnnotation.createNewPrintAnnotation(e,n,g,{image:a,evaluatorOptions:r}))}return Promise.all(o)}}function getRgbColor(e,t=new Uint8ClampedArray(3)){if(!Array.isArray(e))return t;const i=t||new Uint8ClampedArray(3);switch(e.length){case 0:return null;case 1:ColorSpace.singletons.gray.getRgbItem(e,0,i,0);return i;case 3:ColorSpace.singletons.rgb.getRgbItem(e,0,i,0);return i;case 4:ColorSpace.singletons.cmyk.getRgbItem(e,0,i,0);return i;default:return t}}function getPdfColorArray(e){return Array.from(e,(e=>e/255))}function getQuadPoints(e,t){const i=e.getArray("QuadPoints");if(!isNumberArray(i,null)||0===i.length||i.length%8>0)return null;const a=[];for(let e=0,s=i.length/8;e<s;e++){let s=1/0,r=-1/0,n=1/0,o=-1/0;for(let t=8*e,a=8*e+8;t<a;t+=2){const e=i[t],a=i[t+1];s=Math.min(e,s);r=Math.max(e,r);n=Math.min(a,n);o=Math.max(a,o)}if(null!==t&&(s<t[0]||r>t[2]||n<t[1]||o>t[3]))return null;a.push([{x:s,y:o},{x:r,y:o},{x:s,y:n},{x:r,y:n}])}return a}function getTransformMatrix(e,t,i){const[a,s,r,n]=Util.getAxialAlignedBoundingBox(t,i);if(a===r||s===n)return[1,0,0,1,e[0],e[1]];const o=(e[2]-e[0])/(r-a),g=(e[3]-e[1])/(n-s);return[o,0,0,g,e[0]-a*o,e[1]-s*g]}class Annotation{constructor(e){const{dict:t,xref:i,annotationGlobals:a}=e;this.setTitle(t.get("T"));this.setContents(t.get("Contents"));this.setModificationDate(t.get("M"));this.setFlags(t.get("F"));this.setRectangle(t.getArray("Rect"));this.setColor(t.getArray("C"));this.setBorderStyle(t);this.setAppearance(t);this.setOptionalContent(t);const s=t.get("MK");this.setBorderAndBackgroundColors(s);this.setRotation(s,t);this.ref=e.ref instanceof Ref?e.ref:null;this._streams=[];this.appearance&&this._streams.push(this.appearance);const r=!!(this.flags&AA),n=!!(this.flags&eA);if(a.structTreeRoot){let i=t.get("StructParent");i=Number.isInteger(i)&&i>=0?i:-1;a.structTreeRoot.addAnnotationIdToPage(e.pageRef,i)}this.data={annotationFlags:this.flags,borderStyle:this.borderStyle,color:this.color,backgroundColor:this.backgroundColor,borderColor:this.borderColor,rotation:this.rotation,contentsObj:this._contents,hasAppearance:!!this.appearance,id:e.id,modificationDate:this.modificationDate,rect:this.rectangle,subtype:e.subtype,hasOwnCanvas:!1,noRotate:!!(this.flags&_),noHTML:r&&n};if(e.collectFields){const a=t.get("Kids");if(Array.isArray(a)){const e=[];for(const t of a)t instanceof Ref&&e.push(t.toString());0!==e.length&&(this.data.kidIds=e)}this.data.actions=collectActions(i,t,uA);this.data.fieldName=this._constructFieldName(t);this.data.pageIndex=e.pageIndex}this._isOffscreenCanvasSupported=e.evaluatorOptions.isOffscreenCanvasSupported;this._fallbackFontDict=null;this._needAppearances=!1}_hasFlag(e,t){return!!(e&t)}_isViewable(e){return!this._hasFlag(e,Z)&&!this._hasFlag(e,$)}_isPrintable(e){return this._hasFlag(e,z)&&!this._hasFlag(e,V)&&!this._hasFlag(e,Z)}mustBeViewed(e,t){const i=e?.get(this.data.id)?.noView;return void 0!==i?!i:this.viewable&&!this._hasFlag(this.flags,V)}mustBePrinted(e){const t=e?.get(this.data.id)?.noPrint;return void 0!==t?!t:this.printable}get viewable(){return null!==this.data.quadPoints&&(0===this.flags||this._isViewable(this.flags))}get printable(){return null!==this.data.quadPoints&&(0!==this.flags&&this._isPrintable(this.flags))}_parseStringHelper(e){const t="string"==typeof e?stringToPDFString(e):"";return{str:t,dir:t&&"rtl"===bidi(t).dir?"rtl":"ltr"}}setDefaultAppearance(e){const{dict:t,annotationGlobals:i}=e,a=getInheritableProperty({dict:t,key:"DA"})||i.acroForm.get("DA");this._defaultAppearance="string"==typeof a?a:"";this.data.defaultAppearanceData=parseDefaultAppearance(this._defaultAppearance)}setTitle(e){this._title=this._parseStringHelper(e)}setContents(e){this._contents=this._parseStringHelper(e)}setModificationDate(e){this.modificationDate="string"==typeof e?e:null}setFlags(e){this.flags=Number.isInteger(e)&&e>0?e:0;this.flags&Z&&"Annotation"!==this.constructor.name&&(this.flags^=Z)}hasFlag(e){return this._hasFlag(this.flags,e)}setRectangle(e){this.rectangle=lookupNormalRect(e,[0,0,0,0])}setColor(e){this.color=getRgbColor(e)}setLineEndings(e){this.lineEndings=["None","None"];if(Array.isArray(e)&&2===e.length)for(let t=0;t<2;t++){const i=e[t];if(i instanceof Name)switch(i.name){case"None":continue;case"Square":case"Circle":case"Diamond":case"OpenArrow":case"ClosedArrow":case"Butt":case"ROpenArrow":case"RClosedArrow":case"Slash":this.lineEndings[t]=i.name;continue}warn(`Ignoring invalid lineEnding: ${i}`)}}setRotation(e,t){this.rotation=0;let i=e instanceof Dict?e.get("R")||0:t.get("Rotate")||0;if(Number.isInteger(i)&&0!==i){i%=360;i<0&&(i+=360);i%90==0&&(this.rotation=i)}}setBorderAndBackgroundColors(e){if(e instanceof Dict){this.borderColor=getRgbColor(e.getArray("BC"),null);this.backgroundColor=getRgbColor(e.getArray("BG"),null)}else this.borderColor=this.backgroundColor=null}setBorderStyle(e){this.borderStyle=new AnnotationBorderStyle;if(e instanceof Dict)if(e.has("BS")){const t=e.get("BS");if(t instanceof Dict){const e=t.get("Type");if(!e||isName(e,"Border")){this.borderStyle.setWidth(t.get("W"),this.rectangle);this.borderStyle.setStyle(t.get("S"));this.borderStyle.setDashArray(t.getArray("D"))}}}else if(e.has("Border")){const t=e.getArray("Border");if(Array.isArray(t)&&t.length>=3){this.borderStyle.setHorizontalCornerRadius(t[0]);this.borderStyle.setVerticalCornerRadius(t[1]);this.borderStyle.setWidth(t[2],this.rectangle);4===t.length&&this.borderStyle.setDashArray(t[3],!0)}}else this.borderStyle.setWidth(0)}setAppearance(e){this.appearance=null;const t=e.get("AP");if(!(t instanceof Dict))return;const i=t.get("N");if(i instanceof BaseStream){this.appearance=i;return}if(!(i instanceof Dict))return;const a=e.get("AS");if(!(a instanceof Name&&i.has(a.name)))return;const s=i.get(a.name);s instanceof BaseStream&&(this.appearance=s)}setOptionalContent(e){this.oc=null;const t=e.get("OC");t instanceof Name?warn("setOptionalContent: Support for /Name-entry is not implemented."):t instanceof Dict&&(this.oc=t)}loadResources(e,t){return t.dict.getAsync("Resources").then((t=>{if(!t)return;return new ObjectLoader(t,e,t.xref).load().then((function(){return t}))}))}async getOperatorList(e,t,a,s,r){const{hasOwnCanvas:n,id:o,rect:c}=this.data;let h=this.appearance;const l=!!(n&&a&g);if(l&&(c[0]===c[2]||c[1]===c[3])){this.data.hasOwnCanvas=!1;return{opList:new OperatorList,separateForm:!1,separateCanvas:!1}}if(!h){if(!l)return{opList:new OperatorList,separateForm:!1,separateCanvas:!1};h=new StringStream("");h.dict=new Dict}const C=h.dict,Q=await this.loadResources(["ExtGState","ColorSpace","Pattern","Shading","XObject","Font"],h),E=lookupRect(C.getArray("BBox"),[0,0,1,1]),u=lookupMatrix(C.getArray("Matrix"),i),d=getTransformMatrix(c,E,u),f=new OperatorList;let p;this.oc&&(p=await e.parseMarkedContentProps(this.oc,null));void 0!==p&&f.addOp(He,["OC",p]);f.addOp(We,[o,c,d,u,l]);await e.getOperatorList({stream:h,task:t,resources:Q,operatorList:f,fallbackFontDict:this._fallbackFontDict});f.addOp(Xe,[]);void 0!==p&&f.addOp(Ye,[]);this.reset();return{opList:f,separateForm:!1,separateCanvas:l}}async save(e,t,i){return null}get hasTextContent(){return!1}async extractTextContent(e,t,i){if(!this.appearance)return;const a=await this.loadResources(["ExtGState","Font","Properties","XObject"],this.appearance),s=[],r=[];let n=null;const o={desiredSize:Math.Infinity,ready:!0,enqueue(e,t){for(const t of e.items)if(void 0!==t.str){n||=t.transform.slice(-2);r.push(t.str);if(t.hasEOL){s.push(r.join("").trimEnd());r.length=0}}}};await e.getTextContent({stream:this.appearance,task:t,resources:a,includeMarkedContent:!0,keepWhiteSpace:!0,sink:o,viewBox:i});this.reset();r.length&&s.push(r.join("").trimEnd());if(s.length>1||s[0]){const e=this.appearance.dict,t=lookupRect(e.getArray("BBox"),null),i=lookupMatrix(e.getArray("Matrix"),null);this.data.textPosition=this._transformPoint(n,t,i);this.data.textContent=s}}_transformPoint(e,t,i){const{rect:a}=this.data;t||=[0,0,1,1];i||=[1,0,0,1,0,0];const s=getTransformMatrix(a,t,i);s[4]-=a[0];s[5]-=a[1];e=Util.applyTransform(e,s);return Util.applyTransform(e,i)}getFieldObject(){return this.data.kidIds?{id:this.data.id,actions:this.data.actions,name:this.data.fieldName,strokeColor:this.data.borderColor,fillColor:this.data.backgroundColor,type:"",kidIds:this.data.kidIds,page:this.data.pageIndex,rotation:this.rotation}:null}reset(){for(const e of this._streams)e.reset()}_constructFieldName(e){if(!e.has("T")&&!e.has("Parent")){warn("Unknown field name, falling back to empty field name.");return""}if(!e.has("Parent"))return stringToPDFString(e.get("T"));const t=[];e.has("T")&&t.unshift(stringToPDFString(e.get("T")));let i=e;const a=new RefSet;e.objId&&a.put(e.objId);for(;i.has("Parent");){i=i.get("Parent");if(!(i instanceof Dict)||i.objId&&a.has(i.objId))break;i.objId&&a.put(i.objId);i.has("T")&&t.unshift(stringToPDFString(i.get("T")))}return t.join(".")}}class AnnotationBorderStyle{constructor(){this.width=1;this.style=lA;this.dashArray=[3];this.horizontalCornerRadius=0;this.verticalCornerRadius=0}setWidth(e,t=[0,0,0,0]){if(e instanceof Name)this.width=0;else if("number"==typeof e){if(e>0){const i=(t[2]-t[0])/2,a=(t[3]-t[1])/2;if(i>0&&a>0&&(e>i||e>a)){warn(`AnnotationBorderStyle.setWidth - ignoring width: ${e}`);e=1}}this.width=e}}setStyle(e){if(e instanceof Name)switch(e.name){case"S":this.style=lA;break;case"D":this.style=CA;break;case"B":this.style=BA;break;case"I":this.style=QA;break;case"U":this.style=EA}}setDashArray(e,t=!1){if(Array.isArray(e)){let i=!0,a=!0;for(const t of e){if(!(+t>=0)){i=!1;break}t>0&&(a=!1)}if(0===e.length||i&&!a){this.dashArray=e;t&&this.setStyle(Name.get("D"))}else this.width=0}else e&&(this.width=0)}setHorizontalCornerRadius(e){Number.isInteger(e)&&(this.horizontalCornerRadius=e)}setVerticalCornerRadius(e){Number.isInteger(e)&&(this.verticalCornerRadius=e)}}class MarkupAnnotation extends Annotation{constructor(e){super(e);const{dict:t}=e;if(t.has("IRT")){const e=t.getRaw("IRT");this.data.inReplyTo=e instanceof Ref?e.toString():null;const i=t.get("RT");this.data.replyType=i instanceof Name?i.name:j}let i=null;if(this.data.replyType===X){const e=t.get("IRT");this.setTitle(e.get("T"));this.data.titleObj=this._title;this.setContents(e.get("Contents"));this.data.contentsObj=this._contents;if(e.has("CreationDate")){this.setCreationDate(e.get("CreationDate"));this.data.creationDate=this.creationDate}else this.data.creationDate=null;if(e.has("M")){this.setModificationDate(e.get("M"));this.data.modificationDate=this.modificationDate}else this.data.modificationDate=null;i=e.getRaw("Popup");if(e.has("C")){this.setColor(e.getArray("C"));this.data.color=this.color}else this.data.color=null}else{this.data.titleObj=this._title;this.setCreationDate(t.get("CreationDate"));this.data.creationDate=this.creationDate;i=t.getRaw("Popup");t.has("C")||(this.data.color=null)}this.data.popupRef=i instanceof Ref?i.toString():null;t.has("RC")&&(this.data.richText=XFAFactory.getRichTextAsHtml(t.get("RC")))}setCreationDate(e){this.creationDate="string"==typeof e?e:null}_setDefaultAppearance({xref:e,extra:t,strokeColor:i,fillColor:a,blendMode:s,strokeAlpha:r,fillAlpha:n,pointsCallback:o}){let g=Number.MAX_VALUE,c=Number.MAX_VALUE,h=Number.MIN_VALUE,l=Number.MIN_VALUE;const C=["q"];t&&C.push(t);i&&C.push(`${i[0]} ${i[1]} ${i[2]} RG`);a&&C.push(`${a[0]} ${a[1]} ${a[2]} rg`);let Q=this.data.quadPoints;Q||(Q=[[{x:this.rectangle[0],y:this.rectangle[3]},{x:this.rectangle[2],y:this.rectangle[3]},{x:this.rectangle[0],y:this.rectangle[1]},{x:this.rectangle[2],y:this.rectangle[1]}]]);for(const e of Q){const[t,i,a,s]=o(C,e);g=Math.min(g,t);h=Math.max(h,i);c=Math.min(c,a);l=Math.max(l,s)}C.push("Q");const E=new Dict(e),u=new Dict(e);u.set("Subtype",Name.get("Form"));const d=new StringStream(C.join(" "));d.dict=u;E.set("Fm0",d);const f=new Dict(e);s&&f.set("BM",Name.get(s));"number"==typeof r&&f.set("CA",r);"number"==typeof n&&f.set("ca",n);const p=new Dict(e);p.set("GS0",f);const m=new Dict(e);m.set("ExtGState",p);m.set("XObject",E);const y=new Dict(e);y.set("Resources",m);const w=this.data.rect=[g,c,h,l];y.set("BBox",w);this.appearance=new StringStream("/GS0 gs /Fm0 Do");this.appearance.dict=y;this._streams.push(this.appearance,d)}static async createNewAnnotation(e,t,i,a){const s=t.ref||=e.getNewTemporaryRef(),r=await this.createNewAppearanceStream(t,e,a),n=[];let o;if(r){const a=e.getNewTemporaryRef();o=this.createNewDict(t,e,{apRef:a});await writeObject(a,r,n,e);i.push({ref:a,data:n.join("")})}else o=this.createNewDict(t,e,{});Number.isInteger(t.parentTreeId)&&o.set("StructParent",t.parentTreeId);n.length=0;await writeObject(s,o,n,e);return{ref:s,data:n.join("")}}static async createNewPrintAnnotation(e,t,i,a){const s=await this.createNewAppearanceStream(i,t,a),r=this.createNewDict(i,t,{ap:s}),n=new this.prototype.constructor({dict:r,xref:t,annotationGlobals:e,evaluatorOptions:a.evaluatorOptions});i.ref&&(n.ref=n.refToReplace=i.ref);return n}}class WidgetAnnotation extends Annotation{constructor(e){super(e);const{dict:t,xref:i,annotationGlobals:a}=e,s=this.data;this._needAppearances=e.needAppearances;s.annotationType=W;void 0===s.fieldName&&(s.fieldName=this._constructFieldName(t));void 0===s.actions&&(s.actions=collectActions(i,t,uA));let r=getInheritableProperty({dict:t,key:"V",getArray:!0});s.fieldValue=this._decodeFormValue(r);const n=getInheritableProperty({dict:t,key:"DV",getArray:!0});s.defaultFieldValue=this._decodeFormValue(n);if(void 0===r&&a.xfaDatasets){const e=this._title.str;if(e){this._hasValueFromXFA=!0;s.fieldValue=r=a.xfaDatasets.getValue(e)}}void 0===r&&null!==s.defaultFieldValue&&(s.fieldValue=s.defaultFieldValue);s.alternativeText=stringToPDFString(t.get("TU")||"");this.setDefaultAppearance(e);s.hasAppearance||=this._needAppearances&&void 0!==s.fieldValue&&null!==s.fieldValue;const o=getInheritableProperty({dict:t,key:"FT"});s.fieldType=o instanceof Name?o.name:null;const g=getInheritableProperty({dict:t,key:"DR"}),c=a.acroForm.get("DR"),h=this.appearance?.dict.get("Resources");this._fieldResources={localResources:g,acroFormResources:c,appearanceResources:h,mergedResources:Dict.merge({xref:i,dictArray:[g,h,c],mergeSubDicts:!0})};s.fieldFlags=getInheritableProperty({dict:t,key:"Ff"});(!Number.isInteger(s.fieldFlags)||s.fieldFlags<0)&&(s.fieldFlags=0);s.readOnly=this.hasFieldFlag(tA);s.required=this.hasFieldFlag(iA);s.hidden=this._hasFlag(s.annotationFlags,V)||this._hasFlag(s.annotationFlags,$)}_decodeFormValue(e){return Array.isArray(e)?e.filter((e=>"string"==typeof e)).map((e=>stringToPDFString(e))):e instanceof Name?stringToPDFString(e.name):"string"==typeof e?stringToPDFString(e):null}hasFieldFlag(e){return!!(this.data.fieldFlags&e)}_isViewable(e){return!0}mustBeViewed(e,t){return t?this.viewable:super.mustBeViewed(e,t)&&!this._hasFlag(this.flags,$)}getRotationMatrix(e){let t=e?.get(this.data.id)?.rotation;void 0===t&&(t=this.rotation);if(0===t)return i;return getRotationMatrix(t,this.data.rect[2]-this.data.rect[0],this.data.rect[3]-this.data.rect[1])}getBorderAndBackgroundAppearances(e){let t=e?.get(this.data.id)?.rotation;void 0===t&&(t=this.rotation);if(!this.backgroundColor&&!this.borderColor)return"";const i=this.data.rect[2]-this.data.rect[0],a=this.data.rect[3]-this.data.rect[1],s=0===t||180===t?`0 0 ${i} ${a} re`:`0 0 ${a} ${i} re`;let r="";this.backgroundColor&&(r=`${getPdfColor(this.backgroundColor,!0)} ${s} f `);if(this.borderColor){r+=`${this.borderStyle.width||1} w ${getPdfColor(this.borderColor,!1)} ${s} S `}return r}async getOperatorList(e,t,i,a,s){if(a&&!(this instanceof SignatureWidgetAnnotation)&&!this.data.noHTML&&!this.data.hasOwnCanvas)return{opList:new OperatorList,separateForm:!0,separateCanvas:!1};if(!this._hasText)return super.getOperatorList(e,t,i,a,s);const r=await this._getAppearance(e,t,i,s);if(this.appearance&&null===r)return super.getOperatorList(e,t,i,a,s);const n=new OperatorList;if(!this._defaultAppearance||null===r)return{opList:n,separateForm:!1,separateCanvas:!1};const o=!!(this.data.hasOwnCanvas&&i&g),c=[0,0,this.data.rect[2]-this.data.rect[0],this.data.rect[3]-this.data.rect[1]],h=getTransformMatrix(this.data.rect,c,[1,0,0,1,0,0]);let l;this.oc&&(l=await e.parseMarkedContentProps(this.oc,null));void 0!==l&&n.addOp(He,["OC",l]);n.addOp(We,[this.data.id,this.data.rect,h,this.getRotationMatrix(s),o]);const C=new StringStream(r);await e.getOperatorList({stream:C,task:t,resources:this._fieldResources.mergedResources,operatorList:n});n.addOp(Xe,[]);void 0!==l&&n.addOp(Ye,[]);return{opList:n,separateForm:!1,separateCanvas:o}}_getMKDict(e){const t=new Dict(null);e&&t.set("R",e);this.borderColor&&t.set("BC",getPdfColorArray(this.borderColor));this.backgroundColor&&t.set("BG",getPdfColorArray(this.backgroundColor));return t.size>0?t:null}amendSavedDict(e,t){}async save(e,t,a){const s=a?.get(this.data.id);let r=s?.value,n=s?.rotation;if(r===this.data.fieldValue||void 0===r){if(!this._hasValueFromXFA&&void 0===n)return null;r||=this.data.fieldValue}if(void 0===n&&!this._hasValueFromXFA&&Array.isArray(r)&&Array.isArray(this.data.fieldValue)&&r.length===this.data.fieldValue.length&&r.every(((e,t)=>e===this.data.fieldValue[t])))return null;void 0===n&&(n=this.rotation);let o=null;if(!this._needAppearances){o=await this._getAppearance(e,t,h,a);if(null===o)return null}let g=!1;if(o?.needAppearances){g=!0;o=null}const{xref:c}=e,l=c.fetchIfRef(this.ref);if(!(l instanceof Dict))return null;const C=new Dict(c);for(const e of l.getKeys())"AP"!==e&&C.set(e,l.getRaw(e));const Q={path:this.data.fieldName,value:r},encoder=e=>isAscii(e)?e:stringToUTF16String(e,!0);C.set("V",Array.isArray(r)?r.map(encoder):encoder(r));this.amendSavedDict(a,C);const E=this._getMKDict(n);E&&C.set("MK",E);const u=[],d=[{ref:this.ref,data:"",xfa:Q,needAppearances:g}];if(null!==o){const e=c.getNewTemporaryRef(),t=new Dict(c);C.set("AP",t);t.set("N",e);const s=this._getSaveFieldResources(c),r=new StringStream(o),n=r.dict=new Dict(c);n.set("Subtype",Name.get("Form"));n.set("Resources",s);n.set("BBox",[0,0,this.data.rect[2]-this.data.rect[0],this.data.rect[3]-this.data.rect[1]]);const g=this.getRotationMatrix(a);g!==i&&n.set("Matrix",g);await writeObject(e,r,u,c);d.push({ref:e,data:u.join(""),xfa:null,needAppearances:!1});u.length=0}C.set("M",`D:${getModificationDate()}`);await writeObject(this.ref,C,u,c);d[0].data=u.join("");return d}async _getAppearance(e,t,i,a){if(this.hasFieldFlag(sA))return null;const s=a?.get(this.data.id);let r,o;if(s){r=s.formattedValue||s.value;o=s.rotation}if(void 0===o&&void 0===r&&!this._needAppearances&&(!this._hasValueFromXFA||this.appearance))return null;const g=this.getBorderAndBackgroundAppearances(a);if(void 0===r){r=this.data.fieldValue;if(!r)return`/Tx BMC q ${g}Q EMC`}Array.isArray(r)&&1===r.length&&(r=r[0]);assert("string"==typeof r,"Expected `value` to be a string.");r=r.trim();if(this.data.combo){const e=this.data.options.find((({exportValue:e})=>r===e));r=e?.displayValue||r}if(""===r)return`/Tx BMC q ${g}Q EMC`;void 0===o&&(o=this.rotation);let c,l=-1;if(this.data.multiLine){c=r.split(/\r\n?|\n/).map((e=>e.normalize("NFC")));l=c.length}else c=[r.replace(/\r\n?|\n/,"").normalize("NFC")];let C=this.data.rect[3]-this.data.rect[1],Q=this.data.rect[2]-this.data.rect[0];90!==o&&270!==o||([Q,C]=[C,Q]);this._defaultAppearance||(this.data.defaultAppearanceData=parseDefaultAppearance(this._defaultAppearance="/Helvetica 0 Tf 0 g"));let E,u,d,f=await WidgetAnnotation._getFontData(e,t,this.data.defaultAppearanceData,this._fieldResources.mergedResources);const p=[];let m=!1;for(const e of c){const t=f.encodeString(e);t.length>1&&(m=!0);p.push(t.join(""))}if(m&&i&h)return{needAppearances:!0};if(m&&this._isOffscreenCanvasSupported){const i=this.data.comb?"monospace":"sans-serif",a=new FakeUnicodeFont(e.xref,i),s=a.createFontResources(c.join("")),n=s.getRaw("Font");if(this._fieldResources.mergedResources.has("Font")){const e=this._fieldResources.mergedResources.get("Font");for(const t of n.getKeys())e.set(t,n.getRaw(t))}else this._fieldResources.mergedResources.set("Font",n);const o=a.fontName.name;f=await WidgetAnnotation._getFontData(e,t,{fontName:o,fontSize:0},s);for(let e=0,t=p.length;e<t;e++)p[e]=stringToUTF16String(c[e]);const g=Object.assign(Object.create(null),this.data.defaultAppearanceData);this.data.defaultAppearanceData.fontSize=0;this.data.defaultAppearanceData.fontName=o;[E,u,d]=this._computeFontSize(C-2,Q-4,r,f,l);this.data.defaultAppearanceData=g}else{this._isOffscreenCanvasSupported||warn("_getAppearance: OffscreenCanvas is not supported, annotation may not render correctly.");[E,u,d]=this._computeFontSize(C-2,Q-4,r,f,l)}let y=f.descent;y=isNaN(y)?n*d:Math.max(n*d,Math.abs(y)*u);const w=Math.min(Math.floor((C-u)/2),1),b=this.data.textAlignment;if(this.data.multiLine)return this._getMultilineAppearance(E,p,f,u,Q,C,b,2,w,y,d,a);if(this.data.comb)return this._getCombAppearance(E,f,p[0],u,Q,C,2,w,y,d,a);const D=w+y;if(0===b||b>2)return`/Tx BMC q ${g}BT `+E+` 1 0 0 1 ${numberToString(2)} ${numberToString(D)} Tm (${escapeString(p[0])}) Tj ET Q EMC`;return`/Tx BMC q ${g}BT `+E+` 1 0 0 1 0 0 Tm ${this._renderText(p[0],f,u,Q,b,{shift:0},2,D)} ET Q EMC`}static async _getFontData(e,t,i,a){const s=new OperatorList,r={font:null,clone(){return this}},{fontName:n,fontSize:o}=i;await e.handleSetFont(a,[n&&Name.get(n),o],null,s,t,r,null);return r.font}_getTextWidth(e,t){return t.charsToGlyphs(e).reduce(((e,t)=>e+t.width),0)/1e3}_computeFontSize(e,t,i,a,r){let{fontSize:n}=this.data.defaultAppearanceData,o=(n||12)*s,g=Math.round(e/o);if(!n){const roundWithTwoDigits=e=>Math.floor(100*e)/100;if(-1===r){const r=this._getTextWidth(i,a);n=roundWithTwoDigits(Math.min(e/s,r>t?t/r:1/0));g=1}else{const c=i.split(/\r\n?|\n/),h=[];for(const e of c){const t=a.encodeString(e).join(""),i=a.charsToGlyphs(t),s=a.getCharPositions(t);h.push({line:t,glyphs:i,positions:s})}const isTooBig=i=>{let s=0;for(const r of h){s+=this._splitLine(null,a,i,t,r).length*i;if(s>e)return!0}return!1};g=Math.max(g,r);for(;;){o=e/g;n=roundWithTwoDigits(o/s);if(!isTooBig(n))break;g++}}const{fontName:c,fontColor:h}=this.data.defaultAppearanceData;this._defaultAppearance=function createDefaultAppearance({fontSize:e,fontName:t,fontColor:i}){return`/${escapePDFName(t)} ${e} Tf ${getPdfColor(i,!0)}`}({fontSize:n,fontName:c,fontColor:h})}return[this._defaultAppearance,n,e/g]}_renderText(e,t,i,a,s,r,n,o){let g;if(1===s){g=(a-this._getTextWidth(e,t)*i)/2}else if(2===s){g=a-this._getTextWidth(e,t)*i-n}else g=n;const c=numberToString(g-r.shift);r.shift=g;return`${c} ${o=numberToString(o)} Td (${escapeString(e)}) Tj`}_getSaveFieldResources(e){const{localResources:t,appearanceResources:i,acroFormResources:a}=this._fieldResources,s=this.data.defaultAppearanceData?.fontName;if(!s)return t||Dict.empty;for(const e of[t,i])if(e instanceof Dict){const t=e.get("Font");if(t instanceof Dict&&t.has(s))return e}if(a instanceof Dict){const i=a.get("Font");if(i instanceof Dict&&i.has(s)){const a=new Dict(e);a.set(s,i.getRaw(s));const r=new Dict(e);r.set("Font",a);return Dict.merge({xref:e,dictArray:[r,t],mergeSubDicts:!0})}}return t||Dict.empty}getFieldObject(){return null}}class TextWidgetAnnotation extends WidgetAnnotation{constructor(e){super(e);this.data.hasOwnCanvas=this.data.readOnly&&!this.data.noHTML;this._hasText=!0;const t=e.dict;"string"!=typeof this.data.fieldValue&&(this.data.fieldValue="");let i=getInheritableProperty({dict:t,key:"Q"});(!Number.isInteger(i)||i<0||i>2)&&(i=null);this.data.textAlignment=i;let a=getInheritableProperty({dict:t,key:"MaxLen"});(!Number.isInteger(a)||a<0)&&(a=0);this.data.maxLen=a;this.data.multiLine=this.hasFieldFlag(aA);this.data.comb=this.hasFieldFlag(hA)&&!this.hasFieldFlag(aA)&&!this.hasFieldFlag(sA)&&!this.hasFieldFlag(gA)&&0!==this.data.maxLen;this.data.doNotScroll=this.hasFieldFlag(cA)}get hasTextContent(){return!!this.appearance&&!this._needAppearances}_getCombAppearance(e,t,i,a,s,r,n,o,g,c,h){const l=s/this.data.maxLen,C=this.getBorderAndBackgroundAppearances(h),Q=[],E=t.getCharPositions(i);for(const[e,t]of E)Q.push(`(${escapeString(i.substring(e,t))}) Tj`);const u=Q.join(` ${numberToString(l)} 0 Td `);return`/Tx BMC q ${C}BT `+e+` 1 0 0 1 ${numberToString(n)} ${numberToString(o+g)} Tm ${u} ET Q EMC`}_getMultilineAppearance(e,t,i,a,s,r,n,o,g,c,h,l){const C=[],Q=s-2*o,E={shift:0};for(let e=0,r=t.length;e<r;e++){const r=t[e],l=this._splitLine(r,i,a,Q);for(let t=0,r=l.length;t<r;t++){const r=l[t],Q=0===e&&0===t?-g-(h-c):-h;C.push(this._renderText(r,i,a,s,n,E,o,Q))}}const u=this.getBorderAndBackgroundAppearances(l),d=C.join("\n");return`/Tx BMC q ${u}BT `+e+` 1 0 0 1 0 ${numberToString(r)} Tm ${d} ET Q EMC`}_splitLine(e,t,i,a,s={}){e=s.line||e;const r=s.glyphs||t.charsToGlyphs(e);if(r.length<=1)return[e];const n=s.positions||t.getCharPositions(e),o=i/1e3,g=[];let c=-1,h=-1,l=-1,C=0,Q=0;for(let t=0,i=r.length;t<i;t++){const[i,s]=n[t],E=r[t],u=E.width*o;if(" "===E.unicode)if(Q+u>a){g.push(e.substring(C,i));C=i;Q=u;c=-1;l=-1}else{Q+=u;c=i;h=s;l=t}else if(Q+u>a)if(-1!==c){g.push(e.substring(C,h));C=h;t=l+1;c=-1;Q=0}else{g.push(e.substring(C,i));C=i;Q=u}else Q+=u}C<e.length&&g.push(e.substring(C,e.length));return g}getFieldObject(){return{id:this.data.id,value:this.data.fieldValue,defaultValue:this.data.defaultFieldValue||"",multiline:this.data.multiLine,password:this.hasFieldFlag(sA),charLimit:this.data.maxLen,comb:this.data.comb,editable:!this.data.readOnly,hidden:this.data.hidden,name:this.data.fieldName,rect:this.data.rect,actions:this.data.actions,page:this.data.pageIndex,strokeColor:this.data.borderColor,fillColor:this.data.backgroundColor,rotation:this.rotation,type:"text"}}}class ButtonWidgetAnnotation extends WidgetAnnotation{constructor(e){super(e);this.checkedAppearance=null;this.uncheckedAppearance=null;this.data.checkBox=!this.hasFieldFlag(rA)&&!this.hasFieldFlag(nA);this.data.radioButton=this.hasFieldFlag(rA)&&!this.hasFieldFlag(nA);this.data.pushButton=this.hasFieldFlag(nA);this.data.isTooltipOnly=!1;if(this.data.checkBox)this._processCheckBox(e);else if(this.data.radioButton)this._processRadioButton(e);else if(this.data.pushButton){this.data.hasOwnCanvas=!0;this.data.noHTML=!1;this._processPushButton(e)}else warn("Invalid field flags for button widget annotation")}async getOperatorList(e,t,a,s,r){if(this.data.pushButton)return super.getOperatorList(e,t,a,!1,r);let n=null,o=null;if(r){const e=r.get(this.data.id);n=e?e.value:null;o=e?e.rotation:null}if(null===n&&this.appearance)return super.getOperatorList(e,t,a,s,r);null==n&&(n=this.data.checkBox?this.data.fieldValue===this.data.exportValue:this.data.fieldValue===this.data.buttonValue);const g=n?this.checkedAppearance:this.uncheckedAppearance;if(g){const n=this.appearance,c=lookupMatrix(g.dict.getArray("Matrix"),i);o&&g.dict.set("Matrix",this.getRotationMatrix(r));this.appearance=g;const h=super.getOperatorList(e,t,a,s,r);this.appearance=n;g.dict.set("Matrix",c);return h}return{opList:new OperatorList,separateForm:!1,separateCanvas:!1}}async save(e,t,i){return this.data.checkBox?this._saveCheckbox(e,t,i):this.data.radioButton?this._saveRadioButton(e,t,i):null}async _saveCheckbox(e,t,i){if(!i)return null;const a=i.get(this.data.id);let s=a?.rotation,r=a?.value;if(void 0===s){if(void 0===r)return null;if(this.data.fieldValue===this.data.exportValue===r)return null}const n=e.xref.fetchIfRef(this.ref);if(!(n instanceof Dict))return null;void 0===s&&(s=this.rotation);void 0===r&&(r=this.data.fieldValue===this.data.exportValue);const o={path:this.data.fieldName,value:r?this.data.exportValue:""},g=Name.get(r?this.data.exportValue:"Off");n.set("V",g);n.set("AS",g);n.set("M",`D:${getModificationDate()}`);const c=this._getMKDict(s);c&&n.set("MK",c);const h=[];await writeObject(this.ref,n,h,e.xref);return[{ref:this.ref,data:h.join(""),xfa:o}]}async _saveRadioButton(e,t,i){if(!i)return null;const a=i.get(this.data.id);let s=a?.rotation,r=a?.value;if(void 0===s){if(void 0===r)return null;if(this.data.fieldValue===this.data.buttonValue===r)return null}const n=e.xref.fetchIfRef(this.ref);if(!(n instanceof Dict))return null;void 0===r&&(r=this.data.fieldValue===this.data.buttonValue);void 0===s&&(s=this.rotation);const o={path:this.data.fieldName,value:r?this.data.buttonValue:""},g=Name.get(r?this.data.buttonValue:"Off"),c=[];let h=null;if(r)if(this.parent instanceof Ref){const t=e.xref.fetch(this.parent);t.set("V",g);await writeObject(this.parent,t,c,e.xref);h=c.join("");c.length=0}else this.parent instanceof Dict&&this.parent.set("V",g);n.set("AS",g);n.set("M",`D:${getModificationDate()}`);const l=this._getMKDict(s);l&&n.set("MK",l);await writeObject(this.ref,n,c,e.xref);const C=[{ref:this.ref,data:c.join(""),xfa:o}];h&&C.push({ref:this.parent,data:h,xfa:null});return C}_getDefaultCheckedAppearance(e,t){const i=this.data.rect[2]-this.data.rect[0],a=this.data.rect[3]-this.data.rect[1],s=[0,0,i,a],r=.8*Math.min(i,a);let n,o;if("check"===t){n={width:.755*r,height:.705*r};o="3"}else if("disc"===t){n={width:.791*r,height:.705*r};o="l"}else unreachable(`_getDefaultCheckedAppearance - unsupported type: ${t}`);const g=`q BT /PdfJsZaDb ${r} Tf 0 g ${numberToString((i-n.width)/2)} ${numberToString((a-n.height)/2)} Td (${o}) Tj ET Q`,c=new Dict(e.xref);c.set("FormType",1);c.set("Subtype",Name.get("Form"));c.set("Type",Name.get("XObject"));c.set("BBox",s);c.set("Matrix",[1,0,0,1,0,0]);c.set("Length",g.length);const h=new Dict(e.xref),l=new Dict(e.xref);l.set("PdfJsZaDb",this.fallbackFontDict);h.set("Font",l);c.set("Resources",h);this.checkedAppearance=new StringStream(g);this.checkedAppearance.dict=c;this._streams.push(this.checkedAppearance)}_processCheckBox(e){const t=e.dict.get("AP");if(!(t instanceof Dict))return;const i=t.get("N");if(!(i instanceof Dict))return;const a=this._decodeFormValue(e.dict.get("AS"));"string"==typeof a&&(this.data.fieldValue=a);const s=null!==this.data.fieldValue&&"Off"!==this.data.fieldValue?this.data.fieldValue:"Yes",r=i.getKeys();if(0===r.length)r.push("Off",s);else if(1===r.length)"Off"===r[0]?r.push(s):r.unshift("Off");else if(r.includes(s)){r.length=0;r.push("Off",s)}else{const e=r.find((e=>"Off"!==e));r.length=0;r.push("Off",e)}r.includes(this.data.fieldValue)||(this.data.fieldValue="Off");this.data.exportValue=r[1];const n=i.get(this.data.exportValue);this.checkedAppearance=n instanceof BaseStream?n:null;const o=i.get("Off");this.uncheckedAppearance=o instanceof BaseStream?o:null;this.checkedAppearance?this._streams.push(this.checkedAppearance):this._getDefaultCheckedAppearance(e,"check");this.uncheckedAppearance&&this._streams.push(this.uncheckedAppearance);this._fallbackFontDict=this.fallbackFontDict;null===this.data.defaultFieldValue&&(this.data.defaultFieldValue="Off")}_processRadioButton(e){this.data.buttonValue=null;const t=e.dict.get("Parent");if(t instanceof Dict){this.parent=e.dict.getRaw("Parent");const i=t.get("V");i instanceof Name&&(this.data.fieldValue=this._decodeFormValue(i))}const i=e.dict.get("AP");if(!(i instanceof Dict))return;const a=i.get("N");if(!(a instanceof Dict))return;for(const e of a.getKeys())if("Off"!==e){this.data.buttonValue=this._decodeFormValue(e);break}const s=a.get(this.data.buttonValue);this.checkedAppearance=s instanceof BaseStream?s:null;const r=a.get("Off");this.uncheckedAppearance=r instanceof BaseStream?r:null;this.checkedAppearance?this._streams.push(this.checkedAppearance):this._getDefaultCheckedAppearance(e,"disc");this.uncheckedAppearance&&this._streams.push(this.uncheckedAppearance);this._fallbackFontDict=this.fallbackFontDict;null===this.data.defaultFieldValue&&(this.data.defaultFieldValue="Off")}_processPushButton(e){const{dict:t,annotationGlobals:i}=e;if(t.has("A")||t.has("AA")||this.data.alternativeText){this.data.isTooltipOnly=!t.has("A")&&!t.has("AA");Catalog.parseDestDictionary({destDict:t,resultObj:this.data,docBaseUrl:i.baseUrl,docAttachments:i.attachments})}else warn("Push buttons without action dictionaries are not supported")}getFieldObject(){let e,t="button";if(this.data.checkBox){t="checkbox";e=this.data.exportValue}else if(this.data.radioButton){t="radiobutton";e=this.data.buttonValue}return{id:this.data.id,value:this.data.fieldValue||"Off",defaultValue:this.data.defaultFieldValue,exportValues:e,editable:!this.data.readOnly,name:this.data.fieldName,rect:this.data.rect,hidden:this.data.hidden,actions:this.data.actions,page:this.data.pageIndex,strokeColor:this.data.borderColor,fillColor:this.data.backgroundColor,rotation:this.rotation,type:t}}get fallbackFontDict(){const e=new Dict;e.set("BaseFont",Name.get("ZapfDingbats"));e.set("Type",Name.get("FallbackType"));e.set("Subtype",Name.get("FallbackType"));e.set("Encoding",Name.get("ZapfDingbatsEncoding"));return shadow(this,"fallbackFontDict",e)}}class ChoiceWidgetAnnotation extends WidgetAnnotation{constructor(e){super(e);const{dict:t,xref:i}=e;this.indices=t.getArray("I");this.hasIndices=Array.isArray(this.indices)&&this.indices.length>0;this.data.options=[];const a=getInheritableProperty({dict:t,key:"Opt"});if(Array.isArray(a))for(let e=0,t=a.length;e<t;e++){const t=i.fetchIfRef(a[e]),s=Array.isArray(t);this.data.options[e]={exportValue:this._decodeFormValue(s?i.fetchIfRef(t[0]):t),displayValue:this._decodeFormValue(s?i.fetchIfRef(t[1]):t)}}if(this.hasIndices){this.data.fieldValue=[];const e=this.data.options.length;for(const t of this.indices)Number.isInteger(t)&&t>=0&&t<e&&this.data.fieldValue.push(this.data.options[t].exportValue)}else"string"==typeof this.data.fieldValue?this.data.fieldValue=[this.data.fieldValue]:this.data.fieldValue||(this.data.fieldValue=[]);this.data.combo=this.hasFieldFlag(oA);this.data.multiSelect=this.hasFieldFlag(IA);this._hasText=!0}getFieldObject(){const e=this.data.combo?"combobox":"listbox",t=this.data.fieldValue.length>0?this.data.fieldValue[0]:null;return{id:this.data.id,value:t,defaultValue:this.data.defaultFieldValue,editable:!this.data.readOnly,name:this.data.fieldName,rect:this.data.rect,numItems:this.data.fieldValue.length,multipleSelection:this.data.multiSelect,hidden:this.data.hidden,actions:this.data.actions,items:this.data.options,page:this.data.pageIndex,strokeColor:this.data.borderColor,fillColor:this.data.backgroundColor,rotation:this.rotation,type:e}}amendSavedDict(e,t){if(!this.hasIndices)return;let i=e?.get(this.data.id)?.value;Array.isArray(i)||(i=[i]);const a=[],{options:s}=this.data;for(let e=0,t=0,r=s.length;e<r;e++)if(s[e].exportValue===i[t]){a.push(e);t+=1}t.set("I",a)}async _getAppearance(e,t,i,a){if(this.data.combo)return super._getAppearance(e,t,i,a);let r,n;const o=a?.get(this.data.id);if(o){n=o.rotation;r=o.value}if(void 0===n&&void 0===r&&!this._needAppearances)return null;void 0===r?r=this.data.fieldValue:Array.isArray(r)||(r=[r]);let g=this.data.rect[3]-this.data.rect[1],c=this.data.rect[2]-this.data.rect[0];90!==n&&270!==n||([c,g]=[g,c]);const h=this.data.options.length,l=[];for(let e=0;e<h;e++){const{exportValue:t}=this.data.options[e];r.includes(t)&&l.push(e)}this._defaultAppearance||(this.data.defaultAppearanceData=parseDefaultAppearance(this._defaultAppearance="/Helvetica 0 Tf 0 g"));const C=await WidgetAnnotation._getFontData(e,t,this.data.defaultAppearanceData,this._fieldResources.mergedResources);let Q,{fontSize:E}=this.data.defaultAppearanceData;if(E)Q=this._defaultAppearance;else{const e=(g-1)/h;let t,i=-1;for(const{displayValue:e}of this.data.options){const a=this._getTextWidth(e,C);if(a>i){i=a;t=e}}[Q,E]=this._computeFontSize(e,c-4,t,C,-1)}const u=E*s,d=(u-E)/2,f=Math.floor(g/u);let p=0;if(l.length>0){const e=Math.min(...l),t=Math.max(...l);p=Math.max(0,t-f+1);p>e&&(p=e)}const m=Math.min(p+f+1,h),y=["/Tx BMC q",`1 1 ${c} ${g} re W n`];if(l.length){y.push("0.600006 0.756866 0.854904 rg");for(const e of l)p<=e&&e<m&&y.push(`1 ${g-(e-p+1)*u} ${c} ${u} re f`)}y.push("BT",Q,`1 0 0 1 0 ${g} Tm`);const w={shift:0};for(let e=p;e<m;e++){const{displayValue:t}=this.data.options[e],i=e===p?d:0;y.push(this._renderText(t,C,E,c,0,w,2,-u+i))}y.push("ET Q EMC");return y.join("\n")}}class SignatureWidgetAnnotation extends WidgetAnnotation{constructor(e){super(e);this.data.fieldValue=null;this.data.hasOwnCanvas=this.data.noRotate;this.data.noHTML=!this.data.hasOwnCanvas}getFieldObject(){return{id:this.data.id,value:null,page:this.data.pageIndex,type:"signature"}}}class TextAnnotation extends MarkupAnnotation{constructor(e){super(e);this.data.noRotate=!0;this.data.hasOwnCanvas=this.data.noRotate;this.data.noHTML=!1;const{dict:t}=e;this.data.annotationType=S;if(this.data.hasAppearance)this.data.name="NoIcon";else{this.data.rect[1]=this.data.rect[3]-22;this.data.rect[2]=this.data.rect[0]+22;this.data.name=t.has("Name")?t.get("Name").name:"Note"}if(t.has("State")){this.data.state=t.get("State")||null;this.data.stateModel=t.get("StateModel")||null}else{this.data.state=null;this.data.stateModel=null}}}class LinkAnnotation extends Annotation{constructor(e){super(e);const{dict:t,annotationGlobals:i}=e;this.data.annotationType=k;this.data.noHTML=!1;const a=getQuadPoints(t,this.rectangle);a&&(this.data.quadPoints=a);this.data.borderColor||=this.data.color;Catalog.parseDestDictionary({destDict:t,resultObj:this.data,docBaseUrl:i.baseUrl,docAttachments:i.attachments})}}class PopupAnnotation extends Annotation{constructor(e){super(e);const{dict:t}=e;this.data.annotationType=q;this.data.noHTML=!1;this.data.rect[0]!==this.data.rect[2]&&this.data.rect[1]!==this.data.rect[3]||(this.data.rect=null);let i=t.get("Parent");if(!i){warn("Popup annotation has a missing or invalid parent annotation.");return}this.data.parentRect=lookupNormalRect(i.getArray("Rect"),null);isName(i.get("RT"),X)&&(i=i.get("IRT"));if(i.has("M")){this.setModificationDate(i.get("M"));this.data.modificationDate=this.modificationDate}else this.data.modificationDate=null;if(i.has("C")){this.setColor(i.getArray("C"));this.data.color=this.color}else this.data.color=null;if(!this.viewable){const e=i.get("F");this._isViewable(e)&&this.setFlags(e)}this.setTitle(i.get("T"));this.data.titleObj=this._title;this.setContents(i.get("Contents"));this.data.contentsObj=this._contents;i.has("RC")&&(this.data.richText=XFAFactory.getRichTextAsHtml(i.get("RC")));this.data.open=!!t.get("Open")}}class FreeTextAnnotation extends MarkupAnnotation{constructor(e){super(e);this.data.hasOwnCanvas=!this.data.noHTML;this.data.noHTML=!1;const{evaluatorOptions:t,xref:i}=e;this.data.annotationType=R;this.setDefaultAppearance(e);this._hasAppearance=!!this.appearance;if(this._hasAppearance){const{fontColor:e,fontSize:a}=function parseAppearanceStream(e,t,i){return new AppearanceStreamEvaluator(e,t,i).parse()}(this.appearance,t,i);this.data.defaultAppearanceData.fontColor=e;this.data.defaultAppearanceData.fontSize=a||10}else{this.data.defaultAppearanceData.fontSize||=10;const{fontColor:t,fontSize:a}=this.data.defaultAppearanceData;if(this._contents.str){this.data.textContent=this._contents.str.split(/\r\n?|\n/).map((e=>e.trimEnd()));const{coords:e,bbox:t,matrix:i}=FakeUnicodeFont.getFirstPositionInfo(this.rectangle,this.rotation,a);this.data.textPosition=this._transformPoint(e,t,i)}if(this._isOffscreenCanvasSupported){const s=e.dict.get("CA"),r=new FakeUnicodeFont(i,"sans-serif");this.appearance=r.createAppearance(this._contents.str,this.rectangle,this.rotation,a,t,s);this._streams.push(this.appearance)}else warn("FreeTextAnnotation: OffscreenCanvas is not supported, annotation may not render correctly.")}}get hasTextContent(){return this._hasAppearance}static createNewDict(e,t,{apRef:i,ap:a}){const{color:s,fontSize:r,rect:n,rotation:o,user:g,value:c}=e,h=new Dict(t);h.set("Type",Name.get("Annot"));h.set("Subtype",Name.get("FreeText"));h.set("CreationDate",`D:${getModificationDate()}`);h.set("Rect",n);const l=`/Helv ${r} Tf ${getPdfColor(s,!0)}`;h.set("DA",l);h.set("Contents",isAscii(c)?c:stringToUTF16String(c,!0));h.set("F",4);h.set("Border",[0,0,0]);h.set("Rotate",o);g&&h.set("T",isAscii(g)?g:stringToUTF16String(g,!0));if(i||a){const e=new Dict(t);h.set("AP",e);i?e.set("N",i):e.set("N",a)}return h}static async createNewAppearanceStream(e,t,i){const{baseFontRef:a,evaluator:r,task:n}=i,{color:o,fontSize:g,rect:c,rotation:h,value:l}=e,C=new Dict(t),Q=new Dict(t);if(a)Q.set("Helv",a);else{const e=new Dict(t);e.set("BaseFont",Name.get("Helvetica"));e.set("Type",Name.get("Font"));e.set("Subtype",Name.get("Type1"));e.set("Encoding",Name.get("WinAnsiEncoding"));Q.set("Helv",e)}C.set("Font",Q);const E=await WidgetAnnotation._getFontData(r,n,{fontName:"Helv",fontSize:g},C),[u,d,f,p]=c;let m=f-u,y=p-d;h%180!=0&&([m,y]=[y,m]);const w=l.split("\n"),b=g/1e3;let D=-1/0;const F=[];for(let e of w){const t=E.encodeString(e);if(t.length>1)return null;e=t.join("");F.push(e);let i=0;const a=E.charsToGlyphs(e);for(const e of a)i+=e.width*b;D=Math.max(D,i)}let S=1;D>m&&(S=m/D);let k=1;const R=s*g,N=1*g,G=R*w.length;G>y&&(k=y/G);const x=g*Math.min(S,k);let M,U,L;switch(h){case 0:L=[1,0,0,1];U=[c[0],c[1],m,y];M=[c[0],c[3]-N];break;case 90:L=[0,1,-1,0];U=[c[1],-c[2],m,y];M=[c[1],-c[0]-N];break;case 180:L=[-1,0,0,-1];U=[-c[2],-c[3],m,y];M=[-c[2],-c[1]-N];break;case 270:L=[0,-1,1,0];U=[-c[3],c[0],m,y];M=[-c[3],c[2]-N]}const J=["q",`${L.join(" ")} 0 0 cm`,`${U.join(" ")} re W n`,"BT",`${getPdfColor(o,!0)}`,`0 Tc /Helv ${numberToString(x)} Tf`];J.push(`${M.join(" ")} Td (${escapeString(F[0])}) Tj`);const H=numberToString(R);for(let e=1,t=F.length;e<t;e++){const t=F[e];J.push(`0 -${H} Td (${escapeString(t)}) Tj`)}J.push("ET","Q");const Y=J.join("\n"),v=new Dict(t);v.set("FormType",1);v.set("Subtype",Name.get("Form"));v.set("Type",Name.get("XObject"));v.set("BBox",c);v.set("Resources",C);v.set("Matrix",[1,0,0,1,-c[0],-c[1]]);const K=new StringStream(Y);K.dict=v;return K}}class LineAnnotation extends MarkupAnnotation{constructor(e){super(e);const{dict:t,xref:i}=e;this.data.annotationType=N;this.data.hasOwnCanvas=this.data.noRotate;this.data.noHTML=!1;const a=lookupRect(t.getArray("L"),[0,0,0,0]);this.data.lineCoordinates=Util.normalizeRect(a);this.setLineEndings(t.getArray("LE"));this.data.lineEndings=this.lineEndings;if(!this.appearance){const e=this.color?getPdfColorArray(this.color):[0,0,0],s=t.get("CA"),r=getRgbColor(t.getArray("IC"),null),n=r?getPdfColorArray(r):null,o=n?s:null,g=this.borderStyle.width||1,c=2*g,h=[this.data.lineCoordinates[0]-c,this.data.lineCoordinates[1]-c,this.data.lineCoordinates[2]+c,this.data.lineCoordinates[3]+c];Util.intersect(this.rectangle,h)||(this.rectangle=h);this._setDefaultAppearance({xref:i,extra:`${g} w`,strokeColor:e,fillColor:n,strokeAlpha:s,fillAlpha:o,pointsCallback:(e,t)=>{e.push(`${a[0]} ${a[1]} m`,`${a[2]} ${a[3]} l`,"S");return[t[0].x-g,t[1].x+g,t[3].y-g,t[1].y+g]}})}}}class SquareAnnotation extends MarkupAnnotation{constructor(e){super(e);const{dict:t,xref:i}=e;this.data.annotationType=G;this.data.hasOwnCanvas=this.data.noRotate;this.data.noHTML=!1;if(!this.appearance){const e=this.color?getPdfColorArray(this.color):[0,0,0],a=t.get("CA"),s=getRgbColor(t.getArray("IC"),null),r=s?getPdfColorArray(s):null,n=r?a:null;if(0===this.borderStyle.width&&!r)return;this._setDefaultAppearance({xref:i,extra:`${this.borderStyle.width} w`,strokeColor:e,fillColor:r,strokeAlpha:a,fillAlpha:n,pointsCallback:(e,t)=>{const i=t[2].x+this.borderStyle.width/2,a=t[2].y+this.borderStyle.width/2,s=t[3].x-t[2].x-this.borderStyle.width,n=t[1].y-t[3].y-this.borderStyle.width;e.push(`${i} ${a} ${s} ${n} re`);r?e.push("B"):e.push("S");return[t[0].x,t[1].x,t[3].y,t[1].y]}})}}}class CircleAnnotation extends MarkupAnnotation{constructor(e){super(e);const{dict:t,xref:i}=e;this.data.annotationType=x;if(!this.appearance){const e=this.color?getPdfColorArray(this.color):[0,0,0],a=t.get("CA"),s=getRgbColor(t.getArray("IC"),null),r=s?getPdfColorArray(s):null,n=r?a:null;if(0===this.borderStyle.width&&!r)return;const o=4/3*Math.tan(Math.PI/8);this._setDefaultAppearance({xref:i,extra:`${this.borderStyle.width} w`,strokeColor:e,fillColor:r,strokeAlpha:a,fillAlpha:n,pointsCallback:(e,t)=>{const i=t[0].x+this.borderStyle.width/2,a=t[0].y-this.borderStyle.width/2,s=t[3].x-this.borderStyle.width/2,n=t[3].y+this.borderStyle.width/2,g=i+(s-i)/2,c=a+(n-a)/2,h=(s-i)/2*o,l=(n-a)/2*o;e.push(`${g} ${n} m`,`${g+h} ${n} ${s} ${c+l} ${s} ${c} c`,`${s} ${c-l} ${g+h} ${a} ${g} ${a} c`,`${g-h} ${a} ${i} ${c-l} ${i} ${c} c`,`${i} ${c+l} ${g-h} ${n} ${g} ${n} c`,"h");r?e.push("B"):e.push("S");return[t[0].x,t[1].x,t[3].y,t[1].y]}})}}}class PolylineAnnotation extends MarkupAnnotation{constructor(e){super(e);const{dict:t,xref:i}=e;this.data.annotationType=U;this.data.hasOwnCanvas=this.data.noRotate;this.data.noHTML=!1;this.data.vertices=[];if(!(this instanceof PolygonAnnotation)){this.setLineEndings(t.getArray("LE"));this.data.lineEndings=this.lineEndings}const a=t.getArray("Vertices");if(isNumberArray(a,null)){for(let e=0,t=a.length;e<t;e+=2)this.data.vertices.push({x:a[e],y:a[e+1]});if(!this.appearance){const e=this.color?getPdfColorArray(this.color):[0,0,0],a=t.get("CA"),s=this.borderStyle.width||1,r=2*s,n=[1/0,1/0,-1/0,-1/0];for(const e of this.data.vertices){n[0]=Math.min(n[0],e.x-r);n[1]=Math.min(n[1],e.y-r);n[2]=Math.max(n[2],e.x+r);n[3]=Math.max(n[3],e.y+r)}Util.intersect(this.rectangle,n)||(this.rectangle=n);this._setDefaultAppearance({xref:i,extra:`${s} w`,strokeColor:e,strokeAlpha:a,pointsCallback:(e,t)=>{const i=this.data.vertices;for(let t=0,a=i.length;t<a;t++)e.push(`${i[t].x} ${i[t].y} ${0===t?"m":"l"}`);e.push("S");return[t[0].x,t[1].x,t[3].y,t[1].y]}})}}}}class PolygonAnnotation extends PolylineAnnotation{constructor(e){super(e);this.data.annotationType=M}}class CaretAnnotation extends MarkupAnnotation{constructor(e){super(e);this.data.annotationType=K}}class InkAnnotation extends MarkupAnnotation{constructor(e){super(e);this.data.hasOwnCanvas=this.data.noRotate;this.data.noHTML=!1;const{dict:t,xref:i}=e;this.data.annotationType=T;this.data.inkLists=[];const a=t.getArray("InkList");if(Array.isArray(a)){for(let e=0,t=a.length;e<t;++e){this.data.inkLists.push([]);if(Array.isArray(a[e]))for(let t=0,s=a[e].length;t<s;t+=2){const s=i.fetchIfRef(a[e][t]),r=i.fetchIfRef(a[e][t+1]);"number"==typeof s&&"number"==typeof r&&this.data.inkLists[e].push({x:s,y:r})}}if(!this.appearance){const e=this.color?getPdfColorArray(this.color):[0,0,0],a=t.get("CA"),s=this.borderStyle.width||1,r=2*s,n=[1/0,1/0,-1/0,-1/0];for(const e of this.data.inkLists)for(const t of e){n[0]=Math.min(n[0],t.x-r);n[1]=Math.min(n[1],t.y-r);n[2]=Math.max(n[2],t.x+r);n[3]=Math.max(n[3],t.y+r)}Util.intersect(this.rectangle,n)||(this.rectangle=n);this._setDefaultAppearance({xref:i,extra:`${s} w`,strokeColor:e,strokeAlpha:a,pointsCallback:(e,t)=>{for(const t of this.data.inkLists){for(let i=0,a=t.length;i<a;i++)e.push(`${t[i].x} ${t[i].y} ${0===i?"m":"l"}`);e.push("S")}return[t[0].x,t[1].x,t[3].y,t[1].y]}})}}}static createNewDict(e,t,{apRef:i,ap:a}){const{color:s,opacity:r,paths:n,outlines:o,rect:g,rotation:c,thickness:h}=e,l=new Dict(t);l.set("Type",Name.get("Annot"));l.set("Subtype",Name.get("Ink"));l.set("CreationDate",`D:${getModificationDate()}`);l.set("Rect",g);l.set("InkList",o?.points||n.map((e=>e.points)));l.set("F",4);l.set("Rotate",c);o&&l.set("IT",Name.get("InkHighlight"));const C=new Dict(t);l.set("BS",C);C.set("W",h);l.set("C",Array.from(s,(e=>e/255)));l.set("CA",r);const Q=new Dict(t);l.set("AP",Q);i?Q.set("N",i):Q.set("N",a);return l}static async createNewAppearanceStream(e,t,i){if(e.outlines)return this.createNewAppearanceStreamForHighlight(e,t,i);const{color:a,rect:s,paths:r,thickness:n,opacity:o}=e,g=[`${n} w 1 J 1 j`,`${getPdfColor(a,!1)}`];1!==o&&g.push("/R0 gs");const c=[];for(const{bezier:e}of r){c.length=0;c.push(`${numberToString(e[0])} ${numberToString(e[1])} m`);if(2===e.length)c.push(`${numberToString(e[0])} ${numberToString(e[1])} l S`);else{for(let t=2,i=e.length;t<i;t+=6){const i=e.slice(t,t+6).map(numberToString).join(" ");c.push(`${i} c`)}c.push("S")}g.push(c.join("\n"))}const h=g.join("\n"),l=new Dict(t);l.set("FormType",1);l.set("Subtype",Name.get("Form"));l.set("Type",Name.get("XObject"));l.set("BBox",s);l.set("Length",h.length);if(1!==o){const e=new Dict(t),i=new Dict(t),a=new Dict(t);a.set("CA",o);a.set("Type",Name.get("ExtGState"));i.set("R0",a);e.set("ExtGState",i);l.set("Resources",e)}const C=new StringStream(h);C.dict=l;return C}static async createNewAppearanceStreamForHighlight(e,t,i){const{color:a,rect:s,outlines:{outline:r},opacity:n}=e,o=[`${getPdfColor(a,!0)}`,"/R0 gs"];o.push(`${numberToString(r[4])} ${numberToString(r[5])} m`);for(let e=6,t=r.length;e<t;e+=6)if(isNaN(r[e])||null===r[e])o.push(`${numberToString(r[e+4])} ${numberToString(r[e+5])} l`);else{const t=r.slice(e,e+6).map(numberToString).join(" ");o.push(`${t} c`)}o.push("h f");const g=o.join("\n"),c=new Dict(t);c.set("FormType",1);c.set("Subtype",Name.get("Form"));c.set("Type",Name.get("XObject"));c.set("BBox",s);c.set("Length",g.length);const h=new Dict(t),l=new Dict(t);h.set("ExtGState",l);c.set("Resources",h);const C=new Dict(t);l.set("R0",C);C.set("BM",Name.get("Multiply"));if(1!==n){C.set("ca",n);C.set("Type",Name.get("ExtGState"))}const Q=new StringStream(g);Q.dict=c;return Q}}class HighlightAnnotation extends MarkupAnnotation{constructor(e){super(e);const{dict:t,xref:i}=e;this.data.annotationType=L;if(this.data.quadPoints=getQuadPoints(t,null)){const e=this.appearance?.dict.get("Resources");if(!this.appearance||!e?.has("ExtGState")){this.appearance&&warn("HighlightAnnotation - ignoring built-in appearance stream.");const e=this.color?getPdfColorArray(this.color):[1,1,0],a=t.get("CA");this._setDefaultAppearance({xref:i,fillColor:e,blendMode:"Multiply",fillAlpha:a,pointsCallback:(e,t)=>{e.push(`${t[0].x} ${t[0].y} m`,`${t[1].x} ${t[1].y} l`,`${t[3].x} ${t[3].y} l`,`${t[2].x} ${t[2].y} l`,"f");return[t[0].x,t[1].x,t[3].y,t[1].y]}})}}else this.data.popupRef=null}static createNewDict(e,t,{apRef:i,ap:a}){const{color:s,opacity:r,rect:n,rotation:o,user:g,quadPoints:c}=e,h=new Dict(t);h.set("Type",Name.get("Annot"));h.set("Subtype",Name.get("Highlight"));h.set("CreationDate",`D:${getModificationDate()}`);h.set("Rect",n);h.set("F",4);h.set("Border",[0,0,0]);h.set("Rotate",o);h.set("QuadPoints",c);h.set("C",Array.from(s,(e=>e/255)));h.set("CA",r);g&&h.set("T",isAscii(g)?g:stringToUTF16String(g,!0));if(i||a){const e=new Dict(t);h.set("AP",e);e.set("N",i||a)}return h}static async createNewAppearanceStream(e,t,i){const{color:a,rect:s,outlines:r,opacity:n}=e,o=[`${getPdfColor(a,!0)}`,"/R0 gs"],g=[];for(const e of r){g.length=0;g.push(`${numberToString(e[0])} ${numberToString(e[1])} m`);for(let t=2,i=e.length;t<i;t+=2)g.push(`${numberToString(e[t])} ${numberToString(e[t+1])} l`);g.push("h");o.push(g.join("\n"))}o.push("f*");const c=o.join("\n"),h=new Dict(t);h.set("FormType",1);h.set("Subtype",Name.get("Form"));h.set("Type",Name.get("XObject"));h.set("BBox",s);h.set("Length",c.length);const l=new Dict(t),C=new Dict(t);l.set("ExtGState",C);h.set("Resources",l);const Q=new Dict(t);C.set("R0",Q);Q.set("BM",Name.get("Multiply"));if(1!==n){Q.set("ca",n);Q.set("Type",Name.get("ExtGState"))}const E=new StringStream(c);E.dict=h;return E}}class UnderlineAnnotation extends MarkupAnnotation{constructor(e){super(e);const{dict:t,xref:i}=e;this.data.annotationType=J;if(this.data.quadPoints=getQuadPoints(t,null)){if(!this.appearance){const e=this.color?getPdfColorArray(this.color):[0,0,0],a=t.get("CA");this._setDefaultAppearance({xref:i,extra:"[] 0 d 0.571 w",strokeColor:e,strokeAlpha:a,pointsCallback:(e,t)=>{e.push(`${t[2].x} ${t[2].y+1.3} m`,`${t[3].x} ${t[3].y+1.3} l`,"S");return[t[0].x,t[1].x,t[3].y,t[1].y]}})}}else this.data.popupRef=null}}class SquigglyAnnotation extends MarkupAnnotation{constructor(e){super(e);const{dict:t,xref:i}=e;this.data.annotationType=H;if(this.data.quadPoints=getQuadPoints(t,null)){if(!this.appearance){const e=this.color?getPdfColorArray(this.color):[0,0,0],a=t.get("CA");this._setDefaultAppearance({xref:i,extra:"[] 0 d 1 w",strokeColor:e,strokeAlpha:a,pointsCallback:(e,t)=>{const i=(t[0].y-t[2].y)/6;let a=i,s=t[2].x;const r=t[2].y,n=t[3].x;e.push(`${s} ${r+a} m`);do{s+=2;a=0===a?i:0;e.push(`${s} ${r+a} l`)}while(s<n);e.push("S");return[t[2].x,n,r-2*i,r+2*i]}})}}else this.data.popupRef=null}}class StrikeOutAnnotation extends MarkupAnnotation{constructor(e){super(e);const{dict:t,xref:i}=e;this.data.annotationType=Y;if(this.data.quadPoints=getQuadPoints(t,null)){if(!this.appearance){const e=this.color?getPdfColorArray(this.color):[0,0,0],a=t.get("CA");this._setDefaultAppearance({xref:i,extra:"[] 0 d 1 w",strokeColor:e,strokeAlpha:a,pointsCallback:(e,t)=>{e.push((t[0].x+t[2].x)/2+" "+(t[0].y+t[2].y)/2+" m",(t[1].x+t[3].x)/2+" "+(t[1].y+t[3].y)/2+" l","S");return[t[0].x,t[1].x,t[3].y,t[1].y]}})}}else this.data.popupRef=null}}class StampAnnotation extends MarkupAnnotation{constructor(e){super(e);this.data.annotationType=v;this.data.hasOwnCanvas=this.data.noRotate;this.data.noHTML=!1}static async createImage(e,t){const{width:i,height:a}=e,s=new OffscreenCanvas(i,a),r=s.getContext("2d",{alpha:!0});r.drawImage(e,0,0);const n=r.getImageData(0,0,i,a).data,o=new Uint32Array(n.buffer),g=o.some(FeatureTest.isLittleEndian?e=>e>>>24!=255:e=>255!=(255&e));if(g){r.fillStyle="white";r.fillRect(0,0,i,a);r.drawImage(e,0,0)}const c=s.convertToBlob({type:"image/jpeg",quality:1}).then((e=>e.arrayBuffer())),h=Name.get("XObject"),l=Name.get("Image"),C=new Dict(t);C.set("Type",h);C.set("Subtype",l);C.set("BitsPerComponent",8);C.set("ColorSpace",Name.get("DeviceRGB"));C.set("Filter",Name.get("DCTDecode"));C.set("BBox",[0,0,i,a]);C.set("Width",i);C.set("Height",a);let Q=null;if(g){const e=new Uint8Array(o.length);if(FeatureTest.isLittleEndian)for(let t=0,i=o.length;t<i;t++)e[t]=o[t]>>>24;else for(let t=0,i=o.length;t<i;t++)e[t]=255&o[t];const s=new Dict(t);s.set("Type",h);s.set("Subtype",l);s.set("BitsPerComponent",8);s.set("ColorSpace",Name.get("DeviceGray"));s.set("Width",i);s.set("Height",a);Q=new Stream(e,0,0,s)}return{imageStream:new Stream(await c,0,0,C),smaskStream:Q,width:i,height:a}}static createNewDict(e,t,{apRef:i,ap:a}){const{rect:s,rotation:r,user:n}=e,o=new Dict(t);o.set("Type",Name.get("Annot"));o.set("Subtype",Name.get("Stamp"));o.set("CreationDate",`D:${getModificationDate()}`);o.set("Rect",s);o.set("F",4);o.set("Border",[0,0,0]);o.set("Rotate",r);n&&o.set("T",isAscii(n)?n:stringToUTF16String(n,!0));if(i||a){const e=new Dict(t);o.set("AP",e);i?e.set("N",i):e.set("N",a)}return o}static async createNewAppearanceStream(e,t,i){const{rotation:a}=e,{imageRef:s,width:r,height:n}=i.image,o=new Dict(t),g=new Dict(t);o.set("XObject",g);g.set("Im0",s);const c=`q ${r} 0 0 ${n} 0 0 cm /Im0 Do Q`,h=new Dict(t);h.set("FormType",1);h.set("Subtype",Name.get("Form"));h.set("Type",Name.get("XObject"));h.set("BBox",[0,0,r,n]);h.set("Resources",o);if(a){const e=getRotationMatrix(a,r,n);h.set("Matrix",e)}const l=new StringStream(c);l.dict=h;return l}}class FileAttachmentAnnotation extends MarkupAnnotation{constructor(e){super(e);const{dict:t,xref:i}=e,a=new FileSpec(t.get("FS"),i);this.data.annotationType=O;this.data.hasOwnCanvas=this.data.noRotate;this.data.noHTML=!1;this.data.file=a.serializable;const s=t.get("Name");this.data.name=s instanceof Name?stringToPDFString(s.name):"PushPin";const r=t.get("ca");this.data.fillAlpha="number"==typeof r&&r>=0&&r<=1?r:null}}function decodeString(e){try{return stringToUTF8String(e)}catch(t){warn(`UTF-8 decoding failed: "${t}".`);return e}}class DatasetXMLParser extends SimpleXMLParser{constructor(e){super(e);this.node=null}onEndElement(e){const t=super.onEndElement(e);if(t&&"xfa:datasets"===e){this.node=t;throw new Error("Aborting DatasetXMLParser.")}}}class DatasetReader{constructor(e){if(e.datasets)this.node=new SimpleXMLParser({hasAttributes:!0}).parseFromString(e.datasets).documentElement;else{const t=new DatasetXMLParser({hasAttributes:!0});try{t.parseFromString(e["xdp:xdp"])}catch{}this.node=t.node}}getValue(e){if(!this.node||!e)return"";const t=this.node.searchNode(parseXFAPath(e),0);if(!t)return"";const i=t.firstChild;return"value"===i?.nodeName?t.children.map((e=>decodeString(e.textContent))):decodeString(t.textContent)}}class XRef{#K=null;constructor(e,t){this.stream=e;this.pdfManager=t;this.entries=[];this._xrefStms=new Set;this._cacheMap=new Map;this._pendingRefs=new RefSet;this._newPersistentRefNum=null;this._newTemporaryRefNum=null;this._persistentRefsCache=null}getNewPersistentRef(e){null===this._newPersistentRefNum&&(this._newPersistentRefNum=this.entries.length||1);const t=this._newPersistentRefNum++;this._cacheMap.set(t,e);return Ref.get(t,0)}getNewTemporaryRef(){if(null===this._newTemporaryRefNum){this._newTemporaryRefNum=this.entries.length||1;if(this._newPersistentRefNum){this._persistentRefsCache=new Map;for(let e=this._newTemporaryRefNum;e<this._newPersistentRefNum;e++){this._persistentRefsCache.set(e,this._cacheMap.get(e));this._cacheMap.delete(e)}}}return Ref.get(this._newTemporaryRefNum++,0)}resetNewTemporaryRef(){this._newTemporaryRefNum=null;if(this._persistentRefsCache)for(const[e,t]of this._persistentRefsCache)this._cacheMap.set(e,t);this._persistentRefsCache=null}setStartXRef(e){this.startXRefQueue=[e]}parse(e=!1){let t,i,a;if(e){warn("Indexing all PDF objects");t=this.indexObjects()}else t=this.readXRef();t.assignXref(this);this.trailer=t;try{i=t.get("Encrypt")}catch(e){if(e instanceof MissingDataException)throw e;warn(`XRef.parse - Invalid "Encrypt" reference: "${e}".`)}if(i instanceof Dict){const e=t.get("ID"),a=e?.length?e[0]:"";i.suppressEncryption=!0;this.encrypt=new CipherTransformFactory(i,a,this.pdfManager.password)}try{a=t.get("Root")}catch(e){if(e instanceof MissingDataException)throw e;warn(`XRef.parse - Invalid "Root" reference: "${e}".`)}if(a instanceof Dict)try{if(a.get("Pages")instanceof Dict){this.root=a;return}}catch(e){if(e instanceof MissingDataException)throw e;warn(`XRef.parse - Invalid "Pages" reference: "${e}".`)}if(!e)throw new XRefParseException;throw new InvalidPDFException("Invalid Root reference.")}processXRefTable(e){"tableState"in this||(this.tableState={entryNum:0,streamPos:e.lexer.stream.pos,parserBuf1:e.buf1,parserBuf2:e.buf2});if(!isCmd(this.readXRefTable(e),"trailer"))throw new FormatError("Invalid XRef table: could not find trailer dictionary");let t=e.getObj();t instanceof Dict||!t.dict||(t=t.dict);if(!(t instanceof Dict))throw new FormatError("Invalid XRef table: could not parse trailer dictionary");delete this.tableState;return t}readXRefTable(e){const t=e.lexer.stream,i=this.tableState;t.pos=i.streamPos;e.buf1=i.parserBuf1;e.buf2=i.parserBuf2;let a;for(;;){if(!("firstEntryNum"in i)||!("entryCount"in i)){if(isCmd(a=e.getObj(),"trailer"))break;i.firstEntryNum=a;i.entryCount=e.getObj()}let s=i.firstEntryNum;const r=i.entryCount;if(!Number.isInteger(s)||!Number.isInteger(r))throw new FormatError("Invalid XRef table: wrong types in subsection header");for(let a=i.entryNum;a<r;a++){i.streamPos=t.pos;i.entryNum=a;i.parserBuf1=e.buf1;i.parserBuf2=e.buf2;const n={};n.offset=e.getObj();n.gen=e.getObj();const o=e.getObj();if(o instanceof Cmd)switch(o.cmd){case"f":n.free=!0;break;case"n":n.uncompressed=!0}if(!Number.isInteger(n.offset)||!Number.isInteger(n.gen)||!n.free&&!n.uncompressed)throw new FormatError(`Invalid entry in XRef subsection: ${s}, ${r}`);0===a&&n.free&&1===s&&(s=0);this.entries[a+s]||(this.entries[a+s]=n)}i.entryNum=0;i.streamPos=t.pos;i.parserBuf1=e.buf1;i.parserBuf2=e.buf2;delete i.firstEntryNum;delete i.entryCount}if(this.entries[0]&&!this.entries[0].free)throw new FormatError("Invalid XRef table: unexpected first object");return a}processXRefStream(e){if(!("streamState"in this)){const t=e.dict,i=t.get("W");let a=t.get("Index");a||(a=[0,t.get("Size")]);this.streamState={entryRanges:a,byteWidths:i,entryNum:0,streamPos:e.pos}}this.readXRefStream(e);delete this.streamState;return e.dict}readXRefStream(e){const t=this.streamState;e.pos=t.streamPos;const[i,a,s]=t.byteWidths,r=t.entryRanges;for(;r.length>0;){const[n,o]=r;if(!Number.isInteger(n)||!Number.isInteger(o))throw new FormatError(`Invalid XRef range fields: ${n}, ${o}`);if(!Number.isInteger(i)||!Number.isInteger(a)||!Number.isInteger(s))throw new FormatError(`Invalid XRef entry fields length: ${n}, ${o}`);for(let r=t.entryNum;r<o;++r){t.entryNum=r;t.streamPos=e.pos;let o=0,g=0,c=0;for(let t=0;t<i;++t){const t=e.getByte();if(-1===t)throw new FormatError("Invalid XRef byteWidths 'type'.");o=o<<8|t}0===i&&(o=1);for(let t=0;t<a;++t){const t=e.getByte();if(-1===t)throw new FormatError("Invalid XRef byteWidths 'offset'.");g=g<<8|t}for(let t=0;t<s;++t){const t=e.getByte();if(-1===t)throw new FormatError("Invalid XRef byteWidths 'generation'.");c=c<<8|t}const h={};h.offset=g;h.gen=c;switch(o){case 0:h.free=!0;break;case 1:h.uncompressed=!0;break;case 2:break;default:throw new FormatError(`Invalid XRef entry type: ${o}`)}this.entries[n+r]||(this.entries[n+r]=h)}t.entryNum=0;t.streamPos=e.pos;r.splice(0,2)}}indexObjects(){function readToken(e,t){let i="",a=e[t];for(;10!==a&&13!==a&&60!==a&&!(++t>=e.length);){i+=String.fromCharCode(a);a=e[t]}return i}function skipUntil(e,t,i){const a=i.length,s=e.length;let r=0;for(;t<s;){let s=0;for(;s<a&&e[t+s]===i[s];)++s;if(s>=a)break;t++;r++}return r}const e=/\b(endobj|\d+\s+\d+\s+obj|xref|trailer\s*<<)\b/g,t=/\b(startxref|\d+\s+\d+\s+obj)\b/g,i=/^(\d+)\s+(\d+)\s+obj\b/,a=new Uint8Array([116,114,97,105,108,101,114]),s=new Uint8Array([115,116,97,114,116,120,114,101,102]),r=new Uint8Array([47,88,82,101,102]);this.entries.length=0;this._cacheMap.clear();const n=this.stream;n.pos=0;const o=n.getBytes(),g=bytesToString(o),c=o.length;let h=n.start;const l=[],C=[];for(;h<c;){let Q=o[h];if(9===Q||10===Q||13===Q||32===Q){++h;continue}if(37===Q){do{++h;if(h>=c)break;Q=o[h]}while(10!==Q&&13!==Q);continue}const E=readToken(o,h);let u;if(E.startsWith("xref")&&(4===E.length||/\s/.test(E[4]))){h+=skipUntil(o,h,a);l.push(h);h+=skipUntil(o,h,s)}else if(u=i.exec(E)){const t=0|u[1],i=0|u[2],a=h+E.length;let s,l=!1;if(this.entries[t]){if(this.entries[t].gen===i)try{new Parser({lexer:new Lexer(n.makeSubStream(a))}).getObj();l=!0}catch(e){e instanceof ParserEOFException?warn(`indexObjects -- checking object (${E}): "${e}".`):l=!0}}else l=!0;l&&(this.entries[t]={offset:h-n.start,gen:i,uncompressed:!0});e.lastIndex=a;const Q=e.exec(g);if(Q){s=e.lastIndex+1-h;if("endobj"!==Q[1]){warn(`indexObjects: Found "${Q[1]}" inside of another "obj", caused by missing "endobj" -- trying to recover.`);s-=Q[1].length+1}}else s=c-h;const d=o.subarray(h,h+s),f=skipUntil(d,0,r);if(f<s&&d[f+5]<64){C.push(h-n.start);this._xrefStms.add(h-n.start)}h+=s}else if(E.startsWith("trailer")&&(7===E.length||/\s/.test(E[7]))){l.push(h);const e=h+E.length;let i;t.lastIndex=e;const a=t.exec(g);if(a){i=t.lastIndex+1-h;if("startxref"!==a[1]){warn(`indexObjects: Found "${a[1]}" after "trailer", caused by missing "startxref" -- trying to recover.`);i-=a[1].length+1}}else i=c-h;h+=i}else h+=E.length+1}for(const e of C){this.startXRefQueue.push(e);this.readXRef(!0)}const Q=[];let E,u,d=!1;for(const e of l){n.pos=e;const t=new Parser({lexer:new Lexer(n),xref:this,allowStreams:!0,recoveryMode:!0});if(!isCmd(t.getObj(),"trailer"))continue;const i=t.getObj();if(i instanceof Dict){Q.push(i);i.has("Encrypt")&&(d=!0)}}for(const e of[...Q,"genFallback",...Q]){if("genFallback"===e){if(!u)break;this._generationFallback=!0;continue}let t=!1;try{const i=e.get("Root");if(!(i instanceof Dict))continue;const a=i.get("Pages");if(!(a instanceof Dict))continue;const s=a.get("Count");Number.isInteger(s)&&(t=!0)}catch(e){u=e;continue}if(t&&(!d||e.has("Encrypt"))&&e.has("ID"))return e;E=e}if(E)return E;if(this.topDict)return this.topDict;throw new InvalidPDFException("Invalid PDF structure.")}readXRef(e=!1){const t=this.stream,i=new Set;for(;this.startXRefQueue.length;){try{const e=this.startXRefQueue[0];if(i.has(e)){warn("readXRef - skipping XRef table since it was already parsed.");this.startXRefQueue.shift();continue}i.add(e);t.pos=e+t.start;const a=new Parser({lexer:new Lexer(t),xref:this,allowStreams:!0});let s,r=a.getObj();if(isCmd(r,"xref")){s=this.processXRefTable(a);this.topDict||(this.topDict=s);r=s.get("XRefStm");if(Number.isInteger(r)&&!this._xrefStms.has(r)){this._xrefStms.add(r);this.startXRefQueue.push(r);this.#K??=r}}else{if(!Number.isInteger(r))throw new FormatError("Invalid XRef stream header");if(!(Number.isInteger(a.getObj())&&isCmd(a.getObj(),"obj")&&(r=a.getObj())instanceof BaseStream))throw new FormatError("Invalid XRef stream");s=this.processXRefStream(r);this.topDict||(this.topDict=s);if(!s)throw new FormatError("Failed to read XRef stream")}r=s.get("Prev");Number.isInteger(r)?this.startXRefQueue.push(r):r instanceof Ref&&this.startXRefQueue.push(r.num)}catch(e){if(e instanceof MissingDataException)throw e;info("(while reading XRef): "+e)}this.startXRefQueue.shift()}if(this.topDict)return this.topDict;if(!e)throw new XRefParseException}get lastXRefStreamPos(){return this.#K??(this._xrefStms.size>0?Math.max(...this._xrefStms):null)}getEntry(e){const t=this.entries[e];return t&&!t.free&&t.offset?t:null}fetchIfRef(e,t=!1){return e instanceof Ref?this.fetch(e,t):e}fetch(e,t=!1){if(!(e instanceof Ref))throw new Error("ref object is not a reference");const i=e.num,a=this._cacheMap.get(i);if(void 0!==a){a instanceof Dict&&!a.objId&&(a.objId=e.toString());return a}let s=this.getEntry(i);if(null===s){this._cacheMap.set(i,s);return s}if(this._pendingRefs.has(e)){this._pendingRefs.remove(e);warn(`Ignoring circular reference: ${e}.`);return ft}this._pendingRefs.put(e);try{s=s.uncompressed?this.fetchUncompressed(e,s,t):this.fetchCompressed(e,s,t);this._pendingRefs.remove(e)}catch(t){this._pendingRefs.remove(e);throw t}s instanceof Dict?s.objId=e.toString():s instanceof BaseStream&&(s.dict.objId=e.toString());return s}fetchUncompressed(e,t,i=!1){const a=e.gen;let s=e.num;if(t.gen!==a){const r=`Inconsistent generation in XRef: ${e}`;if(this._generationFallback&&t.gen<a){warn(r);return this.fetchUncompressed(Ref.get(s,t.gen),t,i)}throw new XRefEntryException(r)}const r=this.stream.makeSubStream(t.offset+this.stream.start),n=new Parser({lexer:new Lexer(r),xref:this,allowStreams:!0}),o=n.getObj(),g=n.getObj(),c=n.getObj();if(o!==s||g!==a||!(c instanceof Cmd))throw new XRefEntryException(`Bad (uncompressed) XRef entry: ${e}`);if("obj"!==c.cmd){if(c.cmd.startsWith("obj")){s=parseInt(c.cmd.substring(3),10);if(!Number.isNaN(s))return s}throw new XRefEntryException(`Bad (uncompressed) XRef entry: ${e}`)}(t=this.encrypt&&!i?n.getObj(this.encrypt.createCipherTransform(s,a)):n.getObj())instanceof BaseStream||this._cacheMap.set(s,t);return t}fetchCompressed(e,t,i=!1){const a=t.offset,s=this.fetch(Ref.get(a,0));if(!(s instanceof BaseStream))throw new FormatError("bad ObjStm stream");const r=s.dict.get("First"),n=s.dict.get("N");if(!Number.isInteger(r)||!Number.isInteger(n))throw new FormatError("invalid first and n parameters for ObjStm stream");let o=new Parser({lexer:new Lexer(s),xref:this,allowStreams:!0});const g=new Array(n),c=new Array(n);for(let e=0;e<n;++e){const t=o.getObj();if(!Number.isInteger(t))throw new FormatError(`invalid object number in the ObjStm stream: ${t}`);const i=o.getObj();if(!Number.isInteger(i))throw new FormatError(`invalid object offset in the ObjStm stream: ${i}`);g[e]=t;c[e]=i}const h=(s.start||0)+r,l=new Array(n);for(let e=0;e<n;++e){const t=e<n-1?c[e+1]-c[e]:void 0;if(t<0)throw new FormatError("Invalid offset in the ObjStm stream.");o=new Parser({lexer:new Lexer(s.makeSubStream(h+c[e],t,s.dict)),xref:this,allowStreams:!0});const i=o.getObj();l[e]=i;if(i instanceof BaseStream)continue;const r=g[e],C=this.entries[r];C&&C.offset===a&&C.gen===e&&this._cacheMap.set(r,i)}if(void 0===(t=l[t.gen]))throw new XRefEntryException(`Bad (compressed) XRef entry: ${e}`);return t}async fetchIfRefAsync(e,t){return e instanceof Ref?this.fetchAsync(e,t):e}async fetchAsync(e,t){try{return this.fetch(e,t)}catch(i){if(!(i instanceof MissingDataException))throw i;await this.pdfManager.requestRange(i.begin,i.end);return this.fetchAsync(e,t)}}getCatalogObj(){return this.root}}const so=[0,0,612,792];class Page{constructor({pdfManager:e,xref:t,pageIndex:i,pageDict:a,ref:s,globalIdFactory:r,fontCache:n,builtInCMapCache:o,standardFontDataCache:g,globalImageCache:c,systemFontCache:h,nonBlendModesSet:l,xfaFactory:C}){this.pdfManager=e;this.pageIndex=i;this.pageDict=a;this.xref=t;this.ref=s;this.fontCache=n;this.builtInCMapCache=o;this.standardFontDataCache=g;this.globalImageCache=c;this.systemFontCache=h;this.nonBlendModesSet=l;this.evaluatorOptions=e.evaluatorOptions;this.resourcesPromise=null;this.xfaFactory=C;const Q={obj:0};this._localIdFactory=class extends r{static createObjId(){return`p${i}_${++Q.obj}`}static getPageObjId(){return`p${s.toString()}`}}}_getInheritableProperty(e,t=!1){const i=getInheritableProperty({dict:this.pageDict,key:e,getArray:t,stopWhenFound:!1});return Array.isArray(i)?1!==i.length&&i[0]instanceof Dict?Dict.merge({xref:this.xref,dictArray:i}):i[0]:i}get content(){return this.pageDict.getArray("Contents")}get resources(){const e=this._getInheritableProperty("Resources");return shadow(this,"resources",e instanceof Dict?e:Dict.empty)}_getBoundingBox(e){if(this.xfaData)return this.xfaData.bbox;const t=lookupNormalRect(this._getInheritableProperty(e,!0),null);if(t){if(t[2]-t[0]>0&&t[3]-t[1]>0)return t;warn(`Empty, or invalid, /${e} entry.`)}return null}get mediaBox(){return shadow(this,"mediaBox",this._getBoundingBox("MediaBox")||so)}get cropBox(){return shadow(this,"cropBox",this._getBoundingBox("CropBox")||this.mediaBox)}get userUnit(){let e=this.pageDict.get("UserUnit");("number"!=typeof e||e<=0)&&(e=1);return shadow(this,"userUnit",e)}get view(){const{cropBox:e,mediaBox:t}=this;if(e!==t&&!isArrayEqual(e,t)){const i=Util.intersect(e,t);if(i&&i[2]-i[0]>0&&i[3]-i[1]>0)return shadow(this,"view",i);warn("Empty /CropBox and /MediaBox intersection.")}return shadow(this,"view",t)}get rotate(){let e=this._getInheritableProperty("Rotate")||0;e%90!=0?e=0:e>=360?e%=360:e<0&&(e=(e%360+360)%360);return shadow(this,"rotate",e)}_onSubStreamError(e,t){if(!this.evaluatorOptions.ignoreErrors)throw e;warn(`getContentStream - ignoring sub-stream (${t}): "${e}".`)}getContentStream(){return this.pdfManager.ensure(this,"content").then((e=>e instanceof BaseStream?e:Array.isArray(e)?new StreamsSequenceStream(e,this._onSubStreamError.bind(this)):new NullStream))}get xfaData(){return shadow(this,"xfaData",this.xfaFactory?{bbox:this.xfaFactory.getBoundingBox(this.pageIndex)}:null)}#T(e,t,i){for(const a of e)if(a.id){const e=Ref.fromString(a.id);if(!e){warn(`A non-linked annotation cannot be modified: ${a.id}`);continue}if(a.deleted){t.put(e,e);continue}i?.put(e);a.ref=e;delete a.id}}async saveNewAnnotations(e,t,i,a){if(this.xfaFactory)throw new Error("XFA: Cannot save new annotations.");const s=new PartialEvaluator({xref:this.xref,handler:e,pageIndex:this.pageIndex,idFactory:this._localIdFactory,fontCache:this.fontCache,builtInCMapCache:this.builtInCMapCache,standardFontDataCache:this.standardFontDataCache,globalImageCache:this.globalImageCache,systemFontCache:this.systemFontCache,options:this.evaluatorOptions}),r=new RefSetCache,n=new RefSet;this.#T(i,r,n);const o=this.pageDict,g=this.annotations.filter((e=>!(e instanceof Ref&&r.has(e)))),c=await AnnotationFactory.saveNewAnnotations(s,t,i,a);for(const{ref:e}of c.annotations)e instanceof Ref&&!n.has(e)&&g.push(e);const h=o.get("Annots");o.set("Annots",g);const l=[];await writeObject(this.ref,o,l,this.xref);h&&o.set("Annots",h);const C=c.dependencies;C.push({ref:this.ref,data:l.join("")},...c.annotations);for(const e of r)C.push({ref:e,data:null});return C}save(e,t,i){const a=new PartialEvaluator({xref:this.xref,handler:e,pageIndex:this.pageIndex,idFactory:this._localIdFactory,fontCache:this.fontCache,builtInCMapCache:this.builtInCMapCache,standardFontDataCache:this.standardFontDataCache,globalImageCache:this.globalImageCache,systemFontCache:this.systemFontCache,options:this.evaluatorOptions});return this._parsedAnnotations.then((function(e){const s=[];for(const r of e)r.mustBePrinted(i)&&s.push(r.save(a,t,i).catch((function(e){warn(`save - ignoring annotation data during "${t.name}" task: "${e}".`);return null})));return Promise.all(s).then((function(e){return e.filter((e=>!!e))}))}))}loadResources(e){this.resourcesPromise||=this.pdfManager.ensure(this,"resources");return this.resourcesPromise.then((()=>new ObjectLoader(this.resources,e,this.xref).load()))}getOperatorList({handler:e,sink:t,task:i,intent:a,cacheKey:s,annotationStorage:r=null}){const n=this.getContentStream(),h=this.loadResources(["ColorSpace","ExtGState","Font","Pattern","Properties","Shading","XObject"]),Q=new PartialEvaluator({xref:this.xref,handler:e,pageIndex:this.pageIndex,idFactory:this._localIdFactory,fontCache:this.fontCache,builtInCMapCache:this.builtInCMapCache,standardFontDataCache:this.standardFontDataCache,globalImageCache:this.globalImageCache,systemFontCache:this.systemFontCache,options:this.evaluatorOptions}),u=this.xfaFactory?null:getNewAnnotationsMap(r),d=u?.get(this.pageIndex);let f=Promise.resolve(null),p=null;if(d){const e=this.pdfManager.ensureDoc("annotationGlobals");let t;const a=new Set;for(const{bitmapId:e,bitmap:t}of d)!e||t||a.has(e)||a.add(e);const{isOffscreenCanvasSupported:s}=this.evaluatorOptions;if(a.size>0){const e=d.slice();for(const[t,i]of r)t.startsWith(E)&&i.bitmap&&a.has(i.bitmapId)&&e.push(i);t=AnnotationFactory.generateImages(e,this.xref,s)}else t=AnnotationFactory.generateImages(d,this.xref,s);p=new RefSet;this.#T(d,p,null);f=e.then((e=>e?AnnotationFactory.printNewAnnotations(e,Q,i,d,t):null))}const m=Promise.all([n,h]).then((([r])=>{const n=new OperatorList(a,t);e.send("StartRenderPage",{transparency:Q.hasBlendModes(this.resources,this.nonBlendModesSet),pageIndex:this.pageIndex,cacheKey:s});return Q.getOperatorList({stream:r,task:i,resources:this.resources,operatorList:n}).then((function(){return n}))}));return Promise.all([m,this._parsedAnnotations,f]).then((function([e,t,s]){if(s){t=t.filter((e=>!(e.ref&&p.has(e.ref))));for(let e=0,i=s.length;e<i;e++){const a=s[e];if(a.refToReplace){const r=t.findIndex((e=>e.ref&&isRefsEqual(e.ref,a.refToReplace)));if(r>=0){t.splice(r,1,a);s.splice(e--,1);i--}}}t=t.concat(s)}if(0===t.length||a&C){e.flush(!0);return{length:e.totalLength}}const n=!!(a&l),h=!!(a&o),E=!!(a&g),u=!!(a&c),d=[];for(const e of t)(h||E&&e.mustBeViewed(r,n)||u&&e.mustBePrinted(r))&&d.push(e.getOperatorList(Q,i,a,n,r).catch((function(e){warn(`getOperatorList - ignoring annotation data during "${i.name}" task: "${e}".`);return{opList:null,separateForm:!1,separateCanvas:!1}})));return Promise.all(d).then((function(t){let i=!1,a=!1;for(const{opList:s,separateForm:r,separateCanvas:n}of t){e.addOpList(s);i||=r;a||=n}e.flush(!0,{form:i,canvas:a});return{length:e.totalLength}}))}))}async extractTextContent({handler:e,task:t,includeMarkedContent:i,disableNormalization:a,sink:s}){const r=this.getContentStream(),n=this.loadResources(["ExtGState","Font","Properties","XObject"]),o=this.pdfManager.ensureCatalog("lang"),[g,,c]=await Promise.all([r,n,o]);return new PartialEvaluator({xref:this.xref,handler:e,pageIndex:this.pageIndex,idFactory:this._localIdFactory,fontCache:this.fontCache,builtInCMapCache:this.builtInCMapCache,standardFontDataCache:this.standardFontDataCache,globalImageCache:this.globalImageCache,systemFontCache:this.systemFontCache,options:this.evaluatorOptions}).getTextContent({stream:g,task:t,resources:this.resources,includeMarkedContent:i,disableNormalization:a,sink:s,viewBox:this.view,lang:c})}async getStructTree(){const e=await this.pdfManager.ensureCatalog("structTreeRoot");if(!e)return null;await this._parsedAnnotations;return(await this.pdfManager.ensure(this,"_parseStructTree",[e])).serializable}_parseStructTree(e){const t=new StructTreePage(e,this.pageDict);t.parse(this.ref);return t}async getAnnotationsData(e,t,i){const a=await this._parsedAnnotations;if(0===a.length)return a;const s=[],r=[];let n;const h=!!(i&o),l=!!(i&g),C=!!(i&c);for(const i of a){const a=h||l&&i.viewable;(a||C&&i.printable)&&s.push(i.data);if(i.hasTextContent&&a){n||=new PartialEvaluator({xref:this.xref,handler:e,pageIndex:this.pageIndex,idFactory:this._localIdFactory,fontCache:this.fontCache,builtInCMapCache:this.builtInCMapCache,standardFontDataCache:this.standardFontDataCache,globalImageCache:this.globalImageCache,systemFontCache:this.systemFontCache,options:this.evaluatorOptions});r.push(i.extractTextContent(n,t,[-1/0,-1/0,1/0,1/0]).catch((function(e){warn(`getAnnotationsData - ignoring textContent during "${t.name}" task: "${e}".`)})))}}await Promise.all(r);return s}get annotations(){const e=this._getInheritableProperty("Annots");return shadow(this,"annotations",Array.isArray(e)?e:[])}get _parsedAnnotations(){return shadow(this,"_parsedAnnotations",this.pdfManager.ensure(this,"annotations").then((async e=>{if(0===e.length)return e;const t=await this.pdfManager.ensureDoc("annotationGlobals");if(!t)return[];const i=[];for(const a of e)i.push(AnnotationFactory.create(this.xref,a,t,this._localIdFactory,!1,this.ref).catch((function(e){warn(`_parsedAnnotations: "${e}".`);return null})));const a=[];let s,r;for(const e of await Promise.all(i))e&&(e instanceof WidgetAnnotation?(r||=[]).push(e):e instanceof PopupAnnotation?(s||=[]).push(e):a.push(e));r&&a.push(...r);s&&a.push(...s);return a})))}get jsActions(){return shadow(this,"jsActions",collectActions(this.xref,this.pageDict,fA))}}const ro=new Uint8Array([37,80,68,70,45]),no=new Uint8Array([115,116,97,114,116,120,114,101,102]),oo=new Uint8Array([101,110,100,111,98,106]);function find(e,t,i=1024,a=!1){const s=t.length,r=e.peekBytes(i),n=r.length-s;if(n<=0)return!1;if(a){const i=s-1;let a=r.length-1;for(;a>=i;){let n=0;for(;n<s&&r[a-n]===t[i-n];)n++;if(n>=s){e.pos+=a-i;return!0}a--}}else{let i=0;for(;i<=n;){let a=0;for(;a<s&&r[i+a]===t[a];)a++;if(a>=s){e.pos+=i;return!0}i++}}return!1}class PDFDocument{constructor(e,t){if(t.length<=0)throw new InvalidPDFException("The PDF file is empty, i.e. its size is zero bytes.");this.pdfManager=e;this.stream=t;this.xref=new XRef(t,e);this._pagePromises=new Map;this._version=null;const i={font:0};this._globalIdFactory=class{static getDocId(){return`g_${e.docId}`}static createFontId(){return"f"+ ++i.font}static createObjId(){unreachable("Abstract method `createObjId` called.")}static getPageObjId(){unreachable("Abstract method `getPageObjId` called.")}}}parse(e){this.xref.parse(e);this.catalog=new Catalog(this.pdfManager,this.xref)}get linearization(){let e=null;try{e=Linearization.create(this.stream)}catch(e){if(e instanceof MissingDataException)throw e;info(e)}return shadow(this,"linearization",e)}get startXRef(){const e=this.stream;let t=0;if(this.linearization){e.reset();if(find(e,oo)){e.skip(6);let i=e.peekByte();for(;isWhiteSpace(i);){e.pos++;i=e.peekByte()}t=e.pos-e.start}}else{const i=1024,a=no.length;let s=!1,r=e.end;for(;!s&&r>0;){r-=i-a;r<0&&(r=0);e.pos=r;s=find(e,no,i,!0)}if(s){e.skip(9);let i;do{i=e.getByte()}while(isWhiteSpace(i));let a="";for(;i>=32&&i<=57;){a+=String.fromCharCode(i);i=e.getByte()}t=parseInt(a,10);isNaN(t)&&(t=0)}}return shadow(this,"startXRef",t)}checkHeader(){const e=this.stream;e.reset();if(!find(e,ro))return;e.moveStart();e.skip(ro.length);let t,i="";for(;(t=e.getByte())>32&&i.length<7;)i+=String.fromCharCode(t);Dt.test(i)?this._version=i:warn(`Invalid PDF header version: ${i}`)}parseStartXRef(){this.xref.setStartXRef(this.startXRef)}get numPages(){let e=0;e=this.catalog.hasActualNumPages?this.catalog.numPages:this.xfaFactory?this.xfaFactory.getNumPages():this.linearization?this.linearization.numPages:this.catalog.numPages;return shadow(this,"numPages",e)}_hasOnlyDocumentSignatures(e,t=0){return!!Array.isArray(e)&&e.every((e=>{if(!((e=this.xref.fetchIfRef(e))instanceof Dict))return!1;if(e.has("Kids")){if(++t>10){warn("_hasOnlyDocumentSignatures: maximum recursion depth reached");return!1}return this._hasOnlyDocumentSignatures(e.get("Kids"),t)}const i=isName(e.get("FT"),"Sig"),a=e.get("Rect"),s=Array.isArray(a)&&a.every((e=>0===e));return i&&s}))}get _xfaStreams(){const e=this.catalog.acroForm;if(!e)return null;const t=e.get("XFA"),i={"xdp:xdp":"",template:"",datasets:"",config:"",connectionSet:"",localeSet:"",stylesheet:"","/xdp:xdp":""};if(t instanceof BaseStream&&!t.isEmpty){i["xdp:xdp"]=t;return i}if(!Array.isArray(t)||0===t.length)return null;for(let e=0,a=t.length;e<a;e+=2){let s;s=0===e?"xdp:xdp":e===a-2?"/xdp:xdp":t[e];if(!i.hasOwnProperty(s))continue;const r=this.xref.fetchIfRef(t[e+1]);r instanceof BaseStream&&!r.isEmpty&&(i[s]=r)}return i}get xfaDatasets(){const e=this._xfaStreams;if(!e)return shadow(this,"xfaDatasets",null);for(const t of["datasets","xdp:xdp"]){const i=e[t];if(i)try{const e=stringToUTF8String(i.getString());return shadow(this,"xfaDatasets",new DatasetReader({[t]:e}))}catch{warn("XFA - Invalid utf-8 string.");break}}return shadow(this,"xfaDatasets",null)}get xfaData(){const e=this._xfaStreams;if(!e)return null;const t=Object.create(null);for(const[i,a]of Object.entries(e))if(a)try{t[i]=stringToUTF8String(a.getString())}catch{warn("XFA - Invalid utf-8 string.");return null}return t}get xfaFactory(){let e;this.pdfManager.enableXfa&&this.catalog.needsRendering&&this.formInfo.hasXfa&&!this.formInfo.hasAcroForm&&(e=this.xfaData);return shadow(this,"xfaFactory",e?new XFAFactory(e):null)}get isPureXfa(){return!!this.xfaFactory&&this.xfaFactory.isValid()}get htmlForXfa(){return this.xfaFactory?this.xfaFactory.getPages():null}async loadXfaImages(){const e=await this.pdfManager.ensureCatalog("xfaImages");if(!e)return;const t=e.getKeys(),i=new ObjectLoader(e,t,this.xref);await i.load();const a=new Map;for(const i of t){const t=e.get(i);t instanceof BaseStream&&a.set(i,t.getBytes())}this.xfaFactory.setImages(a)}async loadXfaFonts(e,t){const i=await this.pdfManager.ensureCatalog("acroForm");if(!i)return;const a=await i.getAsync("DR");if(!(a instanceof Dict))return;const s=new ObjectLoader(a,["Font"],this.xref);await s.load();const r=a.get("Font");if(!(r instanceof Dict))return;const n=Object.assign(Object.create(null),this.pdfManager.evaluatorOptions);n.useSystemFonts=!1;const o=new PartialEvaluator({xref:this.xref,handler:e,pageIndex:-1,idFactory:this._globalIdFactory,fontCache:this.catalog.fontCache,builtInCMapCache:this.catalog.builtInCMapCache,standardFontDataCache:this.catalog.standardFontDataCache,options:n}),g=new OperatorList,c=[],h={get font(){return c.at(-1)},set font(e){c.push(e)},clone(){return this}},l=new Map;r.forEach(((e,t)=>{l.set(e,t)}));const C=[];for(const[e,i]of l){const s=i.get("FontDescriptor");if(!(s instanceof Dict))continue;let r=s.get("FontFamily");r=r.replaceAll(/[ ]+(\d)/g,"$1");const n={fontFamily:r,fontWeight:s.get("FontWeight"),italicAngle:-s.get("ItalicAngle")};validateCSSFont(n)&&C.push(o.handleSetFont(a,[Name.get(e),1],null,g,t,h,null,n).catch((function(e){warn(`loadXfaFonts: "${e}".`);return null})))}await Promise.all(C);const Q=this.xfaFactory.setFonts(c);if(!Q)return;n.ignoreErrors=!0;C.length=0;c.length=0;const E=new Set;for(const e of Q)getXfaFontName(`${e}-Regular`)||E.add(e);E.size&&Q.push("PdfJS-Fallback");for(const e of Q)if(!E.has(e))for(const i of[{name:"Regular",fontWeight:400,italicAngle:0},{name:"Bold",fontWeight:700,italicAngle:0},{name:"Italic",fontWeight:400,italicAngle:12},{name:"BoldItalic",fontWeight:700,italicAngle:12}]){const s=`${e}-${i.name}`,r=getXfaFontDict(s);C.push(o.handleSetFont(a,[Name.get(s),1],null,g,t,h,r,{fontFamily:e,fontWeight:i.fontWeight,italicAngle:i.italicAngle}).catch((function(e){warn(`loadXfaFonts: "${e}".`);return null})))}await Promise.all(C);this.xfaFactory.appendFonts(c,E)}async serializeXfaData(e){return this.xfaFactory?this.xfaFactory.serializeData(e):null}get version(){return this.catalog.version||this._version}get formInfo(){const e={hasFields:!1,hasAcroForm:!1,hasXfa:!1,hasSignatures:!1},t=this.catalog.acroForm;if(!t)return shadow(this,"formInfo",e);try{const i=t.get("Fields"),a=Array.isArray(i)&&i.length>0;e.hasFields=a;const s=t.get("XFA");e.hasXfa=Array.isArray(s)&&s.length>0||s instanceof BaseStream&&!s.isEmpty;const r=!!(1&t.get("SigFlags")),n=r&&this._hasOnlyDocumentSignatures(i);e.hasAcroForm=a&&!n;e.hasSignatures=r}catch(e){if(e instanceof MissingDataException)throw e;warn(`Cannot fetch form information: "${e}".`)}return shadow(this,"formInfo",e)}get documentInfo(){const e={PDFFormatVersion:this.version,Language:this.catalog.lang,EncryptFilterName:this.xref.encrypt?this.xref.encrypt.filterName:null,IsLinearized:!!this.linearization,IsAcroFormPresent:this.formInfo.hasAcroForm,IsXFAPresent:this.formInfo.hasXfa,IsCollectionPresent:!!this.catalog.collection,IsSignaturesPresent:this.formInfo.hasSignatures};let t;try{t=this.xref.trailer.get("Info")}catch(e){if(e instanceof MissingDataException)throw e;info("The document information dictionary is invalid.")}if(!(t instanceof Dict))return shadow(this,"documentInfo",e);for(const i of t.getKeys()){const a=t.get(i);switch(i){case"Title":case"Author":case"Subject":case"Keywords":case"Creator":case"Producer":case"CreationDate":case"ModDate":if("string"==typeof a){e[i]=stringToPDFString(a);continue}break;case"Trapped":if(a instanceof Name){e[i]=a;continue}break;default:let t;switch(typeof a){case"string":t=stringToPDFString(a);break;case"number":case"boolean":t=a;break;default:a instanceof Name&&(t=a)}if(void 0===t){warn(`Bad value, for custom key "${i}", in Info: ${a}.`);continue}e.Custom||(e.Custom=Object.create(null));e.Custom[i]=t;continue}warn(`Bad value, for key "${i}", in Info: ${a}.`)}return shadow(this,"documentInfo",e)}get fingerprints(){function validate(e){return"string"==typeof e&&e.length>0&&"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"!==e}function hexString(e){const t=[];for(const i of e){const e=i.toString(16);t.push(e.padStart(2,"0"))}return t.join("")}const e=this.xref.trailer.get("ID");let t,i;if(Array.isArray(e)&&validate(e[0])){t=stringToBytes(e[0]);e[1]!==e[0]&&validate(e[1])&&(i=stringToBytes(e[1]))}else t=Js(this.stream.getByteRange(0,1024),0,1024);return shadow(this,"fingerprints",[hexString(t),i?hexString(i):null])}async _getLinearizationPage(e){const{catalog:t,linearization:i,xref:a}=this,s=Ref.get(i.objectNumberFirst,0);try{const e=await a.fetchAsync(s);if(e instanceof Dict){let i=e.getRaw("Type");i instanceof Ref&&(i=await a.fetchAsync(i));if(isName(i,"Page")||!e.has("Type")&&!e.has("Kids")&&e.has("Contents")){t.pageKidsCountCache.has(s)||t.pageKidsCountCache.put(s,1);t.pageIndexCache.has(s)||t.pageIndexCache.put(s,0);return[e,s]}}throw new FormatError("The Linearization dictionary doesn't point to a valid Page dictionary.")}catch(i){warn(`_getLinearizationPage: "${i.message}".`);return t.getPageDict(e)}}getPage(e){const t=this._pagePromises.get(e);if(t)return t;const{catalog:i,linearization:a,xfaFactory:s}=this;let r;r=s?Promise.resolve([Dict.empty,null]):a?.pageFirst===e?this._getLinearizationPage(e):i.getPageDict(e);r=r.then((([t,a])=>new Page({pdfManager:this.pdfManager,xref:this.xref,pageIndex:e,pageDict:t,ref:a,globalIdFactory:this._globalIdFactory,fontCache:i.fontCache,builtInCMapCache:i.builtInCMapCache,standardFontDataCache:i.standardFontDataCache,globalImageCache:i.globalImageCache,systemFontCache:i.systemFontCache,nonBlendModesSet:i.nonBlendModesSet,xfaFactory:s})));this._pagePromises.set(e,r);return r}async checkFirstPage(e=!1){if(!e)try{await this.getPage(0)}catch(e){if(e instanceof XRefEntryException){this._pagePromises.delete(0);await this.cleanup();throw new XRefParseException}}}async checkLastPage(e=!1){const{catalog:t,pdfManager:i}=this;t.setActualNumPages();let a;try{await Promise.all([i.ensureDoc("xfaFactory"),i.ensureDoc("linearization"),i.ensureCatalog("numPages")]);if(this.xfaFactory)return;a=this.linearization?this.linearization.numPages:t.numPages;if(!Number.isInteger(a))throw new FormatError("Page count is not an integer.");if(a<=1)return;await this.getPage(a-1)}catch(s){this._pagePromises.delete(a-1);await this.cleanup();if(s instanceof XRefEntryException&&!e)throw new XRefParseException;warn(`checkLastPage - invalid /Pages tree /Count: ${a}.`);let r;try{r=await t.getAllPageDicts(e)}catch(i){if(i instanceof XRefEntryException&&!e)throw new XRefParseException;t.setActualNumPages(1);return}for(const[e,[a,s]]of r){let r;if(a instanceof Error){r=Promise.reject(a);r.catch((()=>{}))}else r=Promise.resolve(new Page({pdfManager:i,xref:this.xref,pageIndex:e,pageDict:a,ref:s,globalIdFactory:this._globalIdFactory,fontCache:t.fontCache,builtInCMapCache:t.builtInCMapCache,standardFontDataCache:t.standardFontDataCache,globalImageCache:t.globalImageCache,systemFontCache:t.systemFontCache,nonBlendModesSet:t.nonBlendModesSet,xfaFactory:null}));this._pagePromises.set(e,r)}t.setActualNumPages(r.size)}}fontFallback(e,t){return this.catalog.fontFallback(e,t)}async cleanup(e=!1){return this.catalog?this.catalog.cleanup(e):clearGlobalCaches()}async#q(e,t,i,a,s){const{xref:r}=this;if(!(t instanceof Ref)||s.has(t))return;s.put(t);const n=await r.fetchAsync(t);if(!(n instanceof Dict))return;if(n.has("T")){const t=stringToPDFString(await n.getAsync("T"));e=""===e?t:`${e}.${t}`}else{let t=n;for(;;){t=t.getRaw("Parent");if(t instanceof Ref){if(s.has(t))break;t=await r.fetchAsync(t)}if(!(t instanceof Dict))break;if(t.has("T")){const i=stringToPDFString(await t.getAsync("T"));e=""===e?i:`${e}.${i}`;break}}}i.has(e)||i.set(e,[]);i.get(e).push(AnnotationFactory.create(r,t,a,null,!0,null).then((e=>e?.getFieldObject())).catch((function(e){warn(`#collectFieldObjects: "${e}".`);return null})));if(!n.has("Kids"))return;const o=await n.getAsync("Kids");if(Array.isArray(o))for(const t of o)await this.#q(e,t,i,a,s)}get fieldObjects(){if(!this.formInfo.hasFields)return shadow(this,"fieldObjects",Promise.resolve(null));return shadow(this,"fieldObjects",Promise.all([this.pdfManager.ensureDoc("annotationGlobals"),this.pdfManager.ensureCatalog("acroForm")]).then((async([e,t])=>{if(!e)return null;const i=new RefSet,a=Object.create(null),s=new Map;for(const a of await t.getAsync("Fields"))await this.#q("",a,s,e,i);const r=[];for(const[e,t]of s)r.push(Promise.all(t).then((t=>{(t=t.filter((e=>!!e))).length>0&&(a[e]=t)})));await Promise.all(r);return a})))}get hasJSActions(){return shadow(this,"hasJSActions",this.pdfManager.ensureDoc("_parseHasJSActions"))}async _parseHasJSActions(){const[e,t]=await Promise.all([this.pdfManager.ensureCatalog("jsActions"),this.pdfManager.ensureDoc("fieldObjects")]);return!!e||!!t&&Object.values(t).some((e=>e.some((e=>null!==e.actions))))}get calculationOrderIds(){const e=this.catalog.acroForm;if(!e?.has("CO"))return shadow(this,"calculationOrderIds",null);const t=e.get("CO");if(!Array.isArray(t)||0===t.length)return shadow(this,"calculationOrderIds",null);const i=[];for(const e of t)e instanceof Ref&&i.push(e.toString());return 0===i.length?shadow(this,"calculationOrderIds",null):shadow(this,"calculationOrderIds",i)}get annotationGlobals(){return shadow(this,"annotationGlobals",AnnotationFactory.createGlobals(this.pdfManager))}}class BasePdfManager{constructor(e){this.constructor===BasePdfManager&&unreachable("Cannot initialize BasePdfManager.");this._docBaseUrl=function parseDocBaseUrl(e){if(e){const t=createValidAbsoluteUrl(e);if(t)return t.href;warn(`Invalid absolute docBaseUrl: "${e}".`)}return null}(e.docBaseUrl);this._docId=e.docId;this._password=e.password;this.enableXfa=e.enableXfa;e.evaluatorOptions.isOffscreenCanvasSupported&&=FeatureTest.isOffscreenCanvasSupported;this.evaluatorOptions=Object.freeze(e.evaluatorOptions)}get docId(){return this._docId}get password(){return this._password}get docBaseUrl(){return this._docBaseUrl}get catalog(){return this.pdfDocument.catalog}ensureDoc(e,t){return this.ensure(this.pdfDocument,e,t)}ensureXRef(e,t){return this.ensure(this.pdfDocument.xref,e,t)}ensureCatalog(e,t){return this.ensure(this.pdfDocument.catalog,e,t)}getPage(e){return this.pdfDocument.getPage(e)}fontFallback(e,t){return this.pdfDocument.fontFallback(e,t)}loadXfaFonts(e,t){return this.pdfDocument.loadXfaFonts(e,t)}loadXfaImages(){return this.pdfDocument.loadXfaImages()}serializeXfaData(e){return this.pdfDocument.serializeXfaData(e)}cleanup(e=!1){return this.pdfDocument.cleanup(e)}async ensure(e,t,i){unreachable("Abstract method `ensure` called")}requestRange(e,t){unreachable("Abstract method `requestRange` called")}requestLoadedStream(e=!1){unreachable("Abstract method `requestLoadedStream` called")}sendProgressiveData(e){unreachable("Abstract method `sendProgressiveData` called")}updatePassword(e){this._password=e}terminate(e){unreachable("Abstract method `terminate` called")}}class LocalPdfManager extends BasePdfManager{constructor(e){super(e);const t=new Stream(e.source);this.pdfDocument=new PDFDocument(this,t);this._loadedStreamPromise=Promise.resolve(t)}async ensure(e,t,i){const a=e[t];return"function"==typeof a?a.apply(e,i):a}requestRange(e,t){return Promise.resolve()}requestLoadedStream(e=!1){return this._loadedStreamPromise}terminate(e){}}class NetworkPdfManager extends BasePdfManager{constructor(e){super(e);this.streamManager=new ChunkedStreamManager(e.source,{msgHandler:e.handler,length:e.length,disableAutoFetch:e.disableAutoFetch,rangeChunkSize:e.rangeChunkSize});this.pdfDocument=new PDFDocument(this,this.streamManager.getStream())}async ensure(e,t,i){try{const a=e[t];return"function"==typeof a?a.apply(e,i):a}catch(a){if(!(a instanceof MissingDataException))throw a;await this.requestRange(a.begin,a.end);return this.ensure(e,t,i)}}requestRange(e,t){return this.streamManager.requestRange(e,t)}requestLoadedStream(e=!1){return this.streamManager.requestAllChunks(e)}sendProgressiveData(e){this.streamManager.onReceiveData({chunk:e})}terminate(e){this.streamManager.abort(e)}}const go=1,Io=2,co=1,ho=2,lo=3,Co=4,Bo=5,Qo=6,Eo=7,uo=8;function wrapReason(e){e instanceof Error||"object"==typeof e&&null!==e||unreachable('wrapReason: Expected "reason" to be a (possibly cloned) Error.');switch(e.name){case"AbortException":return new AbortException(e.message);case"MissingPDFException":return new MissingPDFException(e.message);case"PasswordException":return new PasswordException(e.message,e.code);case"UnexpectedResponseException":return new UnexpectedResponseException(e.message,e.status);case"UnknownErrorException":return new UnknownErrorException(e.message,e.details);default:return new UnknownErrorException(e.message,e.toString())}}class MessageHandler{constructor(e,t,i){this.sourceName=e;this.targetName=t;this.comObj=i;this.callbackId=1;this.streamId=1;this.streamSinks=Object.create(null);this.streamControllers=Object.create(null);this.callbackCapabilities=Object.create(null);this.actionHandler=Object.create(null);this._onComObjOnMessage=e=>{const t=e.data;if(t.targetName!==this.sourceName)return;if(t.stream){this.#O(t);return}if(t.callback){const e=t.callbackId,i=this.callbackCapabilities[e];if(!i)throw new Error(`Cannot resolve callback ${e}`);delete this.callbackCapabilities[e];if(t.callback===go)i.resolve(t.data);else{if(t.callback!==Io)throw new Error("Unexpected callback case");i.reject(wrapReason(t.reason))}return}const a=this.actionHandler[t.action];if(!a)throw new Error(`Unknown action from worker: ${t.action}`);if(t.callbackId){const e=this.sourceName,s=t.sourceName;new Promise((function(e){e(a(t.data))})).then((function(a){i.postMessage({sourceName:e,targetName:s,callback:go,callbackId:t.callbackId,data:a})}),(function(a){i.postMessage({sourceName:e,targetName:s,callback:Io,callbackId:t.callbackId,reason:wrapReason(a)})}))}else t.streamId?this.#P(t):a(t.data)};i.addEventListener("message",this._onComObjOnMessage)}on(e,t){const i=this.actionHandler;if(i[e])throw new Error(`There is already an actionName called "${e}"`);i[e]=t}send(e,t,i){this.comObj.postMessage({sourceName:this.sourceName,targetName:this.targetName,action:e,data:t},i)}sendWithPromise(e,t,i){const a=this.callbackId++,s=Promise.withResolvers();this.callbackCapabilities[a]=s;try{this.comObj.postMessage({sourceName:this.sourceName,targetName:this.targetName,action:e,callbackId:a,data:t},i)}catch(e){s.reject(e)}return s.promise}sendWithStream(e,t,i,a){const s=this.streamId++,r=this.sourceName,n=this.targetName,o=this.comObj;return new ReadableStream({start:i=>{const g=Promise.withResolvers();this.streamControllers[s]={controller:i,startCall:g,pullCall:null,cancelCall:null,isClosed:!1};o.postMessage({sourceName:r,targetName:n,action:e,streamId:s,data:t,desiredSize:i.desiredSize},a);return g.promise},pull:e=>{const t=Promise.withResolvers();this.streamControllers[s].pullCall=t;o.postMessage({sourceName:r,targetName:n,stream:Qo,streamId:s,desiredSize:e.desiredSize});return t.promise},cancel:e=>{assert(e instanceof Error,"cancel must have a valid reason");const t=Promise.withResolvers();this.streamControllers[s].cancelCall=t;this.streamControllers[s].isClosed=!0;o.postMessage({sourceName:r,targetName:n,stream:co,streamId:s,reason:wrapReason(e)});return t.promise}},i)}#P(e){const t=e.streamId,i=this.sourceName,a=e.sourceName,s=this.comObj,r=this,n=this.actionHandler[e.action],o={enqueue(e,r=1,n){if(this.isCancelled)return;const o=this.desiredSize;this.desiredSize-=r;if(o>0&&this.desiredSize<=0){this.sinkCapability=Promise.withResolvers();this.ready=this.sinkCapability.promise}s.postMessage({sourceName:i,targetName:a,stream:Co,streamId:t,chunk:e},n)},close(){if(!this.isCancelled){this.isCancelled=!0;s.postMessage({sourceName:i,targetName:a,stream:lo,streamId:t});delete r.streamSinks[t]}},error(e){assert(e instanceof Error,"error must have a valid reason");if(!this.isCancelled){this.isCancelled=!0;s.postMessage({sourceName:i,targetName:a,stream:Bo,streamId:t,reason:wrapReason(e)})}},sinkCapability:Promise.withResolvers(),onPull:null,onCancel:null,isCancelled:!1,desiredSize:e.desiredSize,ready:null};o.sinkCapability.resolve();o.ready=o.sinkCapability.promise;this.streamSinks[t]=o;new Promise((function(t){t(n(e.data,o))})).then((function(){s.postMessage({sourceName:i,targetName:a,stream:uo,streamId:t,success:!0})}),(function(e){s.postMessage({sourceName:i,targetName:a,stream:uo,streamId:t,reason:wrapReason(e)})}))}#O(e){const t=e.streamId,i=this.sourceName,a=e.sourceName,s=this.comObj,r=this.streamControllers[t],n=this.streamSinks[t];switch(e.stream){case uo:e.success?r.startCall.resolve():r.startCall.reject(wrapReason(e.reason));break;case Eo:e.success?r.pullCall.resolve():r.pullCall.reject(wrapReason(e.reason));break;case Qo:if(!n){s.postMessage({sourceName:i,targetName:a,stream:Eo,streamId:t,success:!0});break}n.desiredSize<=0&&e.desiredSize>0&&n.sinkCapability.resolve();n.desiredSize=e.desiredSize;new Promise((function(e){e(n.onPull?.())})).then((function(){s.postMessage({sourceName:i,targetName:a,stream:Eo,streamId:t,success:!0})}),(function(e){s.postMessage({sourceName:i,targetName:a,stream:Eo,streamId:t,reason:wrapReason(e)})}));break;case Co:assert(r,"enqueue should have stream controller");if(r.isClosed)break;r.controller.enqueue(e.chunk);break;case lo:assert(r,"close should have stream controller");if(r.isClosed)break;r.isClosed=!0;r.controller.close();this.#W(r,t);break;case Bo:assert(r,"error should have stream controller");r.controller.error(wrapReason(e.reason));this.#W(r,t);break;case ho:e.success?r.cancelCall.resolve():r.cancelCall.reject(wrapReason(e.reason));this.#W(r,t);break;case co:if(!n)break;new Promise((function(t){t(n.onCancel?.(wrapReason(e.reason)))})).then((function(){s.postMessage({sourceName:i,targetName:a,stream:ho,streamId:t,success:!0})}),(function(e){s.postMessage({sourceName:i,targetName:a,stream:ho,streamId:t,reason:wrapReason(e)})}));n.sinkCapability.reject(wrapReason(e.reason));n.isCancelled=!0;delete this.streamSinks[t];break;default:throw new Error("Unexpected stream case")}}async#W(e,t){await Promise.allSettled([e.startCall?.promise,e.pullCall?.promise,e.cancelCall?.promise]);delete this.streamControllers[t]}destroy(){this.comObj.removeEventListener("message",this._onComObjOnMessage)}}class PDFWorkerStream{constructor(e){this._msgHandler=e;this._contentLength=null;this._fullRequestReader=null;this._rangeRequestReaders=[]}getFullReader(){assert(!this._fullRequestReader,"PDFWorkerStream.getFullReader can only be called once.");this._fullRequestReader=new PDFWorkerStreamReader(this._msgHandler);return this._fullRequestReader}getRangeReader(e,t){const i=new PDFWorkerStreamRangeReader(e,t,this._msgHandler);this._rangeRequestReaders.push(i);return i}cancelAllRequests(e){this._fullRequestReader?.cancel(e);for(const t of this._rangeRequestReaders.slice(0))t.cancel(e)}}class PDFWorkerStreamReader{constructor(e){this._msgHandler=e;this.onProgress=null;this._contentLength=null;this._isRangeSupported=!1;this._isStreamingSupported=!1;const t=this._msgHandler.sendWithStream("GetReader");this._reader=t.getReader();this._headersReady=this._msgHandler.sendWithPromise("ReaderHeadersReady").then((e=>{this._isStreamingSupported=e.isStreamingSupported;this._isRangeSupported=e.isRangeSupported;this._contentLength=e.contentLength}))}get headersReady(){return this._headersReady}get contentLength(){return this._contentLength}get isStreamingSupported(){return this._isStreamingSupported}get isRangeSupported(){return this._isRangeSupported}async read(){const{value:e,done:t}=await this._reader.read();return t?{value:void 0,done:!0}:{value:e.buffer,done:!1}}cancel(e){this._reader.cancel(e)}}class PDFWorkerStreamRangeReader{constructor(e,t,i){this._msgHandler=i;this.onProgress=null;const a=this._msgHandler.sendWithStream("GetRangeReader",{begin:e,end:t});this._reader=a.getReader()}get isStreamingSupported(){return!1}async read(){const{value:e,done:t}=await this._reader.read();return t?{value:void 0,done:!0}:{value:e.buffer,done:!1}}cancel(e){this._reader.cancel(e)}}class WorkerTask{constructor(e){this.name=e;this.terminated=!1;this._capability=Promise.withResolvers()}get finished(){return this._capability.promise}finish(){this._capability.resolve()}terminate(){this.terminated=!0}ensureNotTerminated(){if(this.terminated)throw new Error("Worker task was terminated")}}class WorkerMessageHandler{static setup(e,t){let i=!1;e.on("test",(function(t){if(!i){i=!0;e.send("test",t instanceof Uint8Array)}}));e.on("configure",(function(e){!function setVerbosityLevel(e){Number.isInteger(e)&&(st=e)}(e.verbosity)}));e.on("GetDocRequest",(function(e){return WorkerMessageHandler.createDocumentHandler(e,t)}))}static createDocumentHandler(e,t){let i,a=!1,s=null;const r=new Set,n=getVerbosityLevel(),{docId:o,apiVersion:g}=e,c="4.3.136";if(g!==c)throw new Error(`The API version "${g}" does not match the Worker version "${c}".`);const h=[];for(const e in[])h.push(e);if(h.length)throw new Error("The `Array.prototype` contains unexpected enumerable properties: "+h.join(", ")+"; thus breaking e.g. `for...in` iteration of `Array`s.");const l=o+"_worker";let C=new MessageHandler(l,o,t);function ensureNotTerminated(){if(a)throw new Error("Worker was terminated")}function startWorkerTask(e){r.add(e)}function finishWorkerTask(e){e.finish();r.delete(e)}async function loadDocument(e){await i.ensureDoc("checkHeader");await i.ensureDoc("parseStartXRef");await i.ensureDoc("parse",[e]);await i.ensureDoc("checkFirstPage",[e]);await i.ensureDoc("checkLastPage",[e]);const t=await i.ensureDoc("isPureXfa");if(t){const e=new WorkerTask("loadXfaFonts");startWorkerTask(e);await Promise.all([i.loadXfaFonts(C,e).catch((e=>{})).then((()=>finishWorkerTask(e))),i.loadXfaImages()])}const[a,s]=await Promise.all([i.ensureDoc("numPages"),i.ensureDoc("fingerprints")]);return{numPages:a,fingerprints:s,htmlForXfa:t?await i.ensureDoc("htmlForXfa"):null}}function getPdfManager({data:e,password:t,disableAutoFetch:i,rangeChunkSize:a,length:r,docBaseUrl:n,enableXfa:g,evaluatorOptions:c}){const h={source:null,disableAutoFetch:i,docBaseUrl:n,docId:o,enableXfa:g,evaluatorOptions:c,handler:C,length:r,password:t,rangeChunkSize:a},l=Promise.withResolvers();let Q;if(e){try{h.source=e;Q=new LocalPdfManager(h);l.resolve(Q)}catch(e){l.reject(e)}return l.promise}let E,u=[];try{E=new PDFWorkerStream(C)}catch(e){l.reject(e);return l.promise}const d=E.getFullReader();d.headersReady.then((function(){if(d.isRangeSupported){h.source=E;h.length=d.contentLength;h.disableAutoFetch||=d.isStreamingSupported;Q=new NetworkPdfManager(h);for(const e of u)Q.sendProgressiveData(e);u=[];l.resolve(Q);s=null}})).catch((function(e){l.reject(e);s=null}));let f=0;new Promise((function(e,t){const readChunk=function({value:e,done:i}){try{ensureNotTerminated();if(i){Q||function(){const e=arrayBuffersToBytes(u);r&&e.length!==r&&warn("reported HTTP length is different from actual");try{h.source=e;Q=new LocalPdfManager(h);l.resolve(Q)}catch(e){l.reject(e)}u=[]}();s=null;return}f+=e.byteLength;d.isStreamingSupported||C.send("DocProgress",{loaded:f,total:Math.max(f,d.contentLength||0)});Q?Q.sendProgressiveData(e):u.push(e);d.read().then(readChunk,t)}catch(e){t(e)}};d.read().then(readChunk,t)})).catch((function(e){l.reject(e);s=null}));s=function(e){E.cancelAllRequests(e)};return l.promise}C.on("GetPage",(function(e){return i.getPage(e.pageIndex).then((function(e){return Promise.all([i.ensure(e,"rotate"),i.ensure(e,"ref"),i.ensure(e,"userUnit"),i.ensure(e,"view")]).then((function([e,t,i,a]){return{rotate:e,ref:t,refStr:t?.toString()??null,userUnit:i,view:a}}))}))}));C.on("GetPageIndex",(function(e){const t=Ref.get(e.num,e.gen);return i.ensureCatalog("getPageIndex",[t])}));C.on("GetDestinations",(function(e){return i.ensureCatalog("destinations")}));C.on("GetDestination",(function(e){return i.ensureCatalog("getDestination",[e.id])}));C.on("GetPageLabels",(function(e){return i.ensureCatalog("pageLabels")}));C.on("GetPageLayout",(function(e){return i.ensureCatalog("pageLayout")}));C.on("GetPageMode",(function(e){return i.ensureCatalog("pageMode")}));C.on("GetViewerPreferences",(function(e){return i.ensureCatalog("viewerPreferences")}));C.on("GetOpenAction",(function(e){return i.ensureCatalog("openAction")}));C.on("GetAttachments",(function(e){return i.ensureCatalog("attachments")}));C.on("GetDocJSActions",(function(e){return i.ensureCatalog("jsActions")}));C.on("GetPageJSActions",(function({pageIndex:e}){return i.getPage(e).then((function(e){return i.ensure(e,"jsActions")}))}));C.on("GetOutline",(function(e){return i.ensureCatalog("documentOutline")}));C.on("GetOptionalContentConfig",(function(e){return i.ensureCatalog("optionalContentConfig")}));C.on("GetPermissions",(function(e){return i.ensureCatalog("permissions")}));C.on("GetMetadata",(function(e){return Promise.all([i.ensureDoc("documentInfo"),i.ensureCatalog("metadata")])}));C.on("GetMarkInfo",(function(e){return i.ensureCatalog("markInfo")}));C.on("GetData",(function(e){return i.requestLoadedStream().then((function(e){return e.bytes}))}));C.on("GetAnnotations",(function({pageIndex:e,intent:t}){return i.getPage(e).then((function(i){const a=new WorkerTask(`GetAnnotations: page ${e}`);startWorkerTask(a);return i.getAnnotationsData(C,a,t).then((e=>{finishWorkerTask(a);return e}),(e=>{finishWorkerTask(a);throw e}))}))}));C.on("GetFieldObjects",(function(e){return i.ensureDoc("fieldObjects")}));C.on("HasJSActions",(function(e){return i.ensureDoc("hasJSActions")}));C.on("GetCalculationOrderIds",(function(e){return i.ensureDoc("calculationOrderIds")}));C.on("SaveDocument",(async function({isPureXfa:e,numPages:t,annotationStorage:a,filename:s}){const r=[i.requestLoadedStream(),i.ensureCatalog("acroForm"),i.ensureCatalog("acroFormRef"),i.ensureDoc("startXRef"),i.ensureDoc("xref"),i.ensureDoc("linearization"),i.ensureCatalog("structTreeRoot")],n=[],o=e?null:getNewAnnotationsMap(a),[g,c,h,l,Q,E,u]=await Promise.all(r),d=Q.trailer.getRaw("Root")||null;let f;if(o){u?await u.canUpdateStructTree({pdfManager:i,xref:Q,newAnnotationsByPage:o})&&(f=u):await StructTreeRoot.canCreateStructureTree({catalogRef:d,pdfManager:i,newAnnotationsByPage:o})&&(f=null);const e=AnnotationFactory.generateImages(a.values(),Q,i.evaluatorOptions.isOffscreenCanvasSupported),t=void 0===f?n:[];for(const[a,s]of o)t.push(i.getPage(a).then((t=>{const i=new WorkerTask(`Save (editor): page ${a}`);return t.saveNewAnnotations(C,i,s,e).finally((function(){finishWorkerTask(i)}))})));null===f?n.push(Promise.all(t).then((async e=>{await StructTreeRoot.createStructureTree({newAnnotationsByPage:o,xref:Q,catalogRef:d,pdfManager:i,newRefs:e});return e}))):f&&n.push(Promise.all(t).then((async e=>{await f.updateStructureTree({newAnnotationsByPage:o,pdfManager:i,newRefs:e});return e})))}if(e)n.push(i.serializeXfaData(a));else for(let e=0;e<t;e++)n.push(i.getPage(e).then((function(t){const i=new WorkerTask(`Save: page ${e}`);return t.save(C,i,a).finally((function(){finishWorkerTask(i)}))})));const p=await Promise.all(n);let m=[],y=null;if(e){y=p[0];if(!y)return g.bytes}else{m=p.flat(2);if(0===m.length)return g.bytes}const w=h&&c instanceof Dict&&m.some((e=>e.needAppearances)),b=c instanceof Dict&&c.get("XFA")||null;let D=null,F=!1;if(Array.isArray(b)){for(let e=0,t=b.length;e<t;e+=2)if("datasets"===b[e]){D=b[e+1];F=!0}null===D&&(D=Q.getNewTemporaryRef())}else b&&warn("Unsupported XFA type.");let S=Object.create(null);if(Q.trailer){const e=Object.create(null),t=Q.trailer.get("Info")||null;t instanceof Dict&&t.forEach(((t,i)=>{"string"==typeof i&&(e[t]=stringToPDFString(i))}));S={rootRef:d,encryptRef:Q.trailer.getRaw("Encrypt")||null,newRef:Q.getNewTemporaryRef(),infoRef:Q.trailer.getRaw("Info")||null,info:e,fileIds:Q.trailer.get("ID")||null,startXRef:E?l:Q.lastXRefStreamPos??l,filename:s}}return incrementalUpdate({originalData:g.bytes,xrefInfo:S,newRefs:m,xref:Q,hasXfa:!!b,xfaDatasetsRef:D,hasXfaDatasetsEntry:F,needAppearances:w,acroFormRef:h,acroForm:c,xfaData:y,useXrefStream:isDict(Q.topDict,"XRef")}).finally((()=>{Q.resetNewTemporaryRef()}))}));C.on("GetOperatorList",(function(e,t){const a=e.pageIndex;i.getPage(a).then((function(i){const s=new WorkerTask(`GetOperatorList: page ${a}`);startWorkerTask(s);const r=n>=pA.INFOS?Date.now():0;i.getOperatorList({handler:C,sink:t,task:s,intent:e.intent,cacheKey:e.cacheKey,annotationStorage:e.annotationStorage}).then((function(e){finishWorkerTask(s);r&&info(`page=${a+1} - getOperatorList: time=${Date.now()-r}ms, len=${e.length}`);t.close()}),(function(e){finishWorkerTask(s);s.terminated||t.error(e)}))}))}));C.on("GetTextContent",(function(e,t){const{pageIndex:a,includeMarkedContent:s,disableNormalization:r}=e;i.getPage(a).then((function(e){const i=new WorkerTask("GetTextContent: page "+a);startWorkerTask(i);const o=n>=pA.INFOS?Date.now():0;e.extractTextContent({handler:C,task:i,sink:t,includeMarkedContent:s,disableNormalization:r}).then((function(){finishWorkerTask(i);o&&info(`page=${a+1} - getTextContent: time=`+(Date.now()-o)+"ms");t.close()}),(function(e){finishWorkerTask(i);i.terminated||t.error(e)}))}))}));C.on("GetStructTree",(function(e){return i.getPage(e.pageIndex).then((function(e){return i.ensure(e,"getStructTree")}))}));C.on("FontFallback",(function(e){return i.fontFallback(e.id,C)}));C.on("Cleanup",(function(e){return i.cleanup(!0)}));C.on("Terminate",(function(e){a=!0;const t=[];if(i){i.terminate(new AbortException("Worker was terminated."));const e=i.cleanup();t.push(e);i=null}else clearGlobalCaches();s&&s(new AbortException("Worker was terminated."));for(const e of r){t.push(e.finished);e.terminate()}return Promise.all(t).then((function(){C.destroy();C=null}))}));C.on("Ready",(function(t){!function setupDoc(e){function onSuccess(e){ensureNotTerminated();C.send("GetDoc",{pdfInfo:e})}function onFailure(e){ensureNotTerminated();if(e instanceof PasswordException){const t=new WorkerTask(`PasswordException: response ${e.code}`);startWorkerTask(t);C.sendWithPromise("PasswordRequest",e).then((function({password:e}){finishWorkerTask(t);i.updatePassword(e);pdfManagerReady()})).catch((function(){finishWorkerTask(t);C.send("DocException",e)}))}else e instanceof InvalidPDFException||e instanceof MissingPDFException||e instanceof UnexpectedResponseException||e instanceof UnknownErrorException?C.send("DocException",e):C.send("DocException",new UnknownErrorException(e.message,e.toString()))}function pdfManagerReady(){ensureNotTerminated();loadDocument(!1).then(onSuccess,(function(e){ensureNotTerminated();e instanceof XRefParseException?i.requestLoadedStream().then((function(){ensureNotTerminated();loadDocument(!0).then(onSuccess,onFailure)})):onFailure(e)}))}ensureNotTerminated();getPdfManager(e).then((function(e){if(a){e.terminate(new AbortException("Worker was terminated."));throw new Error("Worker was terminated")}i=e;i.requestLoadedStream(!0).then((e=>{C.send("DataLoaded",{length:e.bytes.byteLength})}))})).then(pdfManagerReady,onFailure)}(e);e=null}));return l}static initializeFromPort(e){const t=new MessageHandler("worker","main",e);WorkerMessageHandler.setup(t,e);t.send("ready",null)}}"undefined"==typeof window&&!t&&"undefined"!=typeof self&&function isMessagePort(e){return"function"==typeof e.postMessage&&"onmessage"in e}(self)&&WorkerMessageHandler.initializeFromPort(self);var fo=__webpack_exports__.WorkerMessageHandler;export{fo as WorkerMessageHandler}; \ No newline at end of file
diff --git a/vhosts/blog/public/posts/2/index.html b/vhosts/blog/public/posts/2/index.html
deleted file mode 100644
index 9d03cad2..00000000
--- a/vhosts/blog/public/posts/2/index.html
+++ /dev/null
@@ -1,222 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2021 nsfisis">
- <meta name="description" content="投稿した記事の一覧 (2ページ目)">
- <meta property="og:type" content="article">
- <meta property="og:title" content="投稿一覧 (2ページ目)|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="投稿した記事の一覧 (2ページ目)">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/posts/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>投稿一覧 (2ページ目)|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>投稿一覧 (2ページ目)</h1>
- </header>
- <nav class="pagination">
- <div class="pagination-prev">
- <a href="/posts/">前のページ</a>
- </div>
- <div class="pagination-info">
- 2 / 6
- </div>
- <div class="pagination-next">
- <a href="/posts/3/">次のページ</a>
- </div>
- </nav>
- <article class="post-entry">
- <a href="/posts/2024-12-04/cohackpp-report/">
- <header class="entry-header">
- <h2>紅白ぺぱ合戦に参加&amp;LTしました</h2>
- </header>
- <section class="entry-content">
- <p>
- 2024-11-30 に開催された紅白ぺぱ合戦に参加し、ぺ陣営のメンバとして LT しました。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-12-04">2024-12-04</time> 投稿、<time datetime="2024-12-05">2024-12-05</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2024-09-28/mncore-challenge-1/">
- <header class="entry-header">
- <h2>MN-Core Challenge #1 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2024-08-28 から 2024-09-24 にかけて開催された MN-Core Challenge #1 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-09-28">2024-09-28</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2024-08-19/go-template-access-outer-scope-pipeline-within-with-or-range/">
- <header class="entry-header">
- <h2>【Go】 text/template の with や range の内側から外側の &quot;.&quot; にアクセスする</h2>
- </header>
- <section class="entry-content">
- <p>
- Go言語の text/template における with や range は &quot;.&quot; を上書きする。これらの内側から外側の &quot;.&quot; にアクセスする方法を調べた。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-08-19">2024-08-19</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2024-07-19/reparojson-fix-only-json-formatter/">
- <header class="entry-header">
- <h2>reparojson: 文法エラーを直すだけの JSON フォーマッタを作った</h2>
- </header>
- <section class="entry-content">
- <p>
- 文法エラーだけを直し、空白の削除や挿入といった整形処理を一切おこなわない JSON フォーマッタを作成した。Neovim と連携させる設定例も紹介する。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-07-19">2024-07-19</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2024-06-19/scalamatsuri-2024-report/">
- <header class="entry-header">
- <h2>ScalaMatsuri 2024 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2024-06-08 から 2024-06-09 にかけて開催された、ScalaMatsuri 2024 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-06-19">2024-06-19</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2024-05-11/phpconkagawa-2024-report/">
- <header class="entry-header">
- <h2>PHP カンファレンス香川 2024 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2024-05-11 に開催された、PHP カンファレンス香川 2024 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-05-11">2024-05-11</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2024-04-29/zsh-file-completion-for-composer-custom-commands/">
- <header class="entry-header">
- <h2>【Zsh】 Composer のカスタムコマンドに対する Zsh 補完で引数にファイルを補完させる</h2>
- </header>
- <section class="entry-content">
- <p>
- Zsh の Composer に対する補完はカスタムコマンドやその引数を補完しない。カスタムコマンドの引数としてファイルを補完させる方法を調べた。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-04-29">2024-04-29</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2024-04-21/pipefail-option-in-gitlab-ci-cd/">
- <header class="entry-header">
- <h2>【GitLab】 GitLab CI/CD 上での bash/sh は pipefail が有効になっている</h2>
- </header>
- <section class="entry-content">
- <p>
- GitLab CI/CD で bash/sh スクリプトを動かすと、pipefail オプションが有効になった状態で実行される。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-04-21">2024-04-21</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2024-04-14/phpcon-odawara-2024-report/">
- <header class="entry-header">
- <h2>PHP カンファレンス小田原 2024 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2024-04-13 に開催された、PHP カンファレンス小田原 2024 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-04-14">2024-04-14</time> 投稿、<time datetime="2024-06-01">2024-06-01</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2024-03-20/my-bucket-list/">
- <header class="entry-header">
- <h2>死ぬまでに作る自作○○一覧あるいは人生の TODO リスト</h2>
- </header>
- <section class="entry-content">
- <p>
- 駄文
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-03-20">2024-03-20</time> 投稿、<time datetime="2024-04-07">2024-04-07</time> 更新
- </footer>
- </a>
- </article>
- <nav class="pagination">
- <div class="pagination-prev">
- <a href="/posts/">前のページ</a>
- </div>
- <div class="pagination-info">
- 2 / 6
- </div>
- <div class="pagination-next">
- <a href="/posts/3/">次のページ</a>
- </div>
- </nav>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2021-03-05/my-first-post/index.html b/vhosts/blog/public/posts/2021-03-05/my-first-post/index.html
deleted file mode 100644
index f1a3bc89..00000000
--- a/vhosts/blog/public/posts/2021-03-05/my-first-post/index.html
+++ /dev/null
@@ -1,245 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2021 nsfisis">
- <meta name="description" content="これはテスト投稿です。これはテスト投稿です。これはテスト投稿です。">
- <meta property="og:type" content="article">
- <meta property="og:title" content="My First Post|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="これはテスト投稿です。これはテスト投稿です。これはテスト投稿です。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>My First Post|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">My First Post</h1>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2021-03-05">2021-03-05</time>: 公開
- </li>
- <li class="revision">
- <time datetime="2025-05-12">2025-05-12</time>: ジェネレータやスタイルをテストするためのコンテンツを追加
- </li>
- </ol>
- </section>
- <section id="section--test">
- <h2><a href="#section--test">Test</a></h2>
- <p>
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
- </p>
- </section>
- <section id="section--sec-1">
- <h2><a href="#section--sec-1">Section level 1</a></h2>
- <section id="section--sec-1--sec-2">
- <h3><a href="#section--sec-1--sec-2">Section level 2</a></h3>
- <section id="section--sec-1--sec-2--sec-3">
- <h4><a href="#section--sec-1--sec-2--sec-3">Section level 3</a></h4>
- <section id="section--sec-1--sec-2--sec-3--sec-4">
- <h5><a href="#section--sec-1--sec-2--sec-3--sec-4">Section level 4</a></h5>
- <section id="section--sec-1--sec-2--sec-3--sec-4--sec-5">
- <h6><a href="#section--sec-1--sec-2--sec-3--sec-4--sec-5">Section level 5</a></h6>
- <ul>
- <li>
- list item 1
- </li>
- <li>
- list item 2
- <ul>
- <li>
- list item 2.a
- </li>
- <li>
- list item 2.b
- </li>
- </ul>
- </li>
- <li>
- list item 3
- </li>
- <li>
- list item 3
- </li>
- </ul>
- <ol>
- <li>
- list item 1
- </li>
- <li>
- list item 2
- <ol>
- <li>
- list item 2.a
- </li>
- <li>
- list item 2.b
- </li>
- </ol>
- </li>
- <li>
- list item 3
- </li>
- <li>
- list item 3
- </li>
- </ol>
- <ul type="task">
- <li checked="false">
- list item 1
- </li>
- <li checked="false">
- list item 2
- <ul type="task">
- <li checked="false">
- list item 2.a
- </li>
- <li checked="false">
- list item 2.b
- </li>
- </ul>
- </li>
- <li checked="false">
- list item 3
- </li>
- <li checked="false">
- list item 3
- </li>
- </ul>
- <blockquote>
- <p>
- blockquote
- </p>
- </blockquote>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#005CC5">puts</span><span style="color:#032F62"> "Hello, World!"</span></span></code></pre>
- </div>
- <p>
- <strong>emph</strong> <em>strong</em>
- </p>
- <p>
- <mark>highlighted</mark>
- </p>
- <p>
- <a href="https://example.com" rel="noreferrer" target="_blank">https://example.com</a>
- </p>
- <p>
- <a href="https://example.com" rel="noreferrer" target="_blank">example link</a>
- </p>
- <p>
- H<sub>2</sub>O
- </p>
- <p>
- 2<sup>64</sup>
- </p>
- <p>
- ‘foo’ “bar”
- </p>
- <p>
- <code>code</code>
- </p>
- <p>
- <ins>
- inserted
- </ins>
-
- <del>
- deleted
- </del>
- </p>
- <p>
- footenote. <sup class="footnote"><a class="footnote" href="#footnote--foo" id="footnoteref--foo">[1]</a></sup>
- </p>
- <div class="admonition">
- <div class="admonition-label">
- NOTE
- </div>
- <div class="admonition-content">
- <p>
- hoge piyo
- </p>
- </div>
- </div>
- <table>
- <caption>
- </caption>
- <thead>
- <tr>
- <th>
- name
- </th>
- <th align="right">
- age
- </th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>
- Taro
- </td>
- <td align="right">
- 10
- </td>
- </tr>
- <tr>
- <td>
- Hanako
- </td>
- <td align="right">
- 20
- </td>
- </tr>
- </tbody>
- </table>
- </section>
- </section>
- </section>
- </section>
- </section>
- <section class="footnotes">
- <div class="footnote" id="footnote--foo">
- <a href="#footnoteref--foo">1. </a>
- <p>
- foo bar
- </p>
- </div>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2021-03-30/phperkaigi-2021/index.html b/vhosts/blog/public/posts/2021-03-30/phperkaigi-2021/index.html
deleted file mode 100644
index 6815783c..00000000
--- a/vhosts/blog/public/posts/2021-03-30/phperkaigi-2021/index.html
+++ /dev/null
@@ -1,215 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2021 nsfisis">
- <meta name="description" content="2021-03-26 から 2021-03-28 にかけて開催された、PHPerKaigi 2021 に参加した。">
- <meta name="keywords" content="カンファレンス,PHP,PHPerKaigi">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHPerKaigi 2021|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="2021-03-26 から 2021-03-28 にかけて開催された、PHPerKaigi 2021 に参加した。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHPerKaigi 2021|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">PHPerKaigi 2021</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/conference/">カンファレンス</a>
- </li>
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phperkaigi/">PHPerKaigi</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2021-03-30">2021-03-30</time>: 公開
- </li>
- <li class="revision">
- <time datetime="2025-04-09">2025-04-09</time>: それぞれの発表に関するメモ部分を削除し、感想のみに
- </li>
- </ol>
- </section>
- <section id="section--report">
- <h2><a href="#section--report">PHPerKaigi 2021 参加レポ</a></h2>
- <p>
- 2021-03-26 から 2021-03-28 にかけて開催された、<a href="https://phperkaigi.jp/2021/" rel="noreferrer" target="_blank">PHPerKaigi 2021</a> に一般参加者として参加した。弊社<a href="https://www.dgcircus.com/" rel="noreferrer" target="_blank">デジタルサーカス株式会社</a> (今年1月から勤務) はダイヤモンドスポンサーとなっており、スポンサー枠のチケットを使わせていただいた。
- </p>
- <p>
- このようなカンファレンスには初めて参加するのでかねてより心待ちにしていたのだが、生憎2日目から体調を崩してしまい、この記事も途中までとなっている。まだ見ていないセッションも多いが、ひとまず現時点での参加レポを書いておく。
- </p>
- <p>
- 発表はトラック A、B に分かれていたのだが、今回はすべて A トラックを視聴している (切り替えるのが面倒だっただけ)。
- </p>
- <section id="section--report--day-0">
- <h3><a href="#section--report--day-0">Day 0 前夜祭 (2021/03/27)</a></h3>
- <section id="section--report--day-0--1730-a">
- <h4><a href="#section--report--day-0--1730-a">17:30 [A] LAMPをこじらせてサーバーレスに乗り遅れたPHPerがLambdaに入門してみる</a></h4>
- <p>
- AWS Lambda のような Function as a Service はマイクロサービス化における一つの到達点に思えるのだが、これを使って実際に web サービスを作る具体的なイメージがまだ見えない (注: すべて for me として書いている)。
- </p>
- <p>
- PHP on AWS Lambda があれだけ簡単に動かせるのには驚いた。
- </p>
- <p>
- 勝手に AWS Lambda だとフットプリントの軽さが求められそう (= PHP + Laravel などでは動かなさそう) だという先入観を持っていたのだが、この発表のデモによればそうでもないらしい。
- </p>
- </section>
- <section id="section--report--day-0--1810-a">
- <h4><a href="#section--report--day-0--1810-a">18:10 [A] 大規模サイトにおけるSEO観点でのURL設計</a></h4>
- <p>
- SEO (Search Engine Optimization) は大して知らないので新鮮な話が多かった。その分語れることも少ない……。
- </p>
- </section>
- <section id="section--report--day-0--1850-a">
- <h4><a href="#section--report--day-0--1850-a">18:50 [A] PHPerでもわかる!実践Webアクセシビリティ</a></h4>
- <p>
- つい最近 WAI-ARIA についての記事を読んだばかりだったので個人的にタイムリーな話題だった。(あまりこの言葉を使いたくないのだが) いわゆる「健常者」にとって、こうした問題を普段の生活の中で意識するのは難しい。だからこそ情報へのアンテナは張っておくようにしたい。
- </p>
- </section>
- <section id="section--report--day-0--1930-a">
- <h4><a href="#section--report--day-0--1930-a">19:30 [A] PHP でファイルシステムを作ろう</a></h4>
- <p>
- PHP で FUSE
- </p>
- <p>
- 個人的に楽しみだった発表。
- </p>
- <p>
- 期待通りの興味深い発表だった。FUSE 自体も今回の発表で知ったのだが、これ本体の実装を見るのも面白そうだ。この発表を聞きながらファイルシステムにマウントできそうなものを考えていたのだが、およそ木構造をしているものすべてと言えそうだ (ハンマーしか持っていないと云々)。何かできそうだがなかなか思いつかない。
- </p>
- </section>
- </section>
- <section id="section--report--day-1">
- <h3><a href="#section--report--day-1">Day 1 (2021/03/27)</a></h3>
- <section id="section--report--day-1--1050-a">
- <h4><a href="#section--report--day-1--1050-a">10:50 [A] 実践ATDD 〜TDDから更に歩みを進めたソフトウェア開発へ〜</a></h4>
- <p>
- User Acceptance Test (UAT) くらいの規模になると個人開発・趣味開発では触れない領域なので、大いに勉強になった。スライドに添付されている資料が相当に充実していたので、これを読むのが本番といった様相すら感じる。高レベルテストの自動化は現在のプロジェクトでも感じており、自動化のチャンスは伺っている。とはいえセッションでも指摘されているように自動化することにコストがかかりすぎる領域があるのも事実で、そのバランスが難しい。
- </p>
- </section>
- <section id="section--report--day-1--1150-a">
- <h4><a href="#section--report--day-1--1150-a">11:50 [A] 静的型解析を用いた大規模レガシーコードのリファクタリング計画</a></h4>
- <p>
- 型のある世界で生きてきた身として大いに楽しみにしていた発表。
- </p>
- <p>
- 昨今、動的型付き言語での型宣言・型アノテーション・型ヒントの導入が相次いでいる。長らく静的型付き言語を書いてきた私からすると、ようやく気づいたかといったところだが、ともかく型を導入する言語が増えてきた。今のプロジェクトでも新しく追加するコードには型をつけるよう努めているが、どうしても古いコードには型がついていない。個人的には型のないコードに対してどう型を自動的に付けるかという点に興味があり、その点で Ruby の typeprof には注目している。
- </p>
- </section>
- <section id="section--report--day-1--1310-a">
- <h4><a href="#section--report--day-1--1310-a">13:10 [A] 目的に沿ったDocumentation as Codeをいかにして実現していくか</a></h4>
- <p>
- この発表も以前から非常に楽しみにしていた。
- </p>
- <p>
- ドキュメントの管理は現プロジェクトでも課題と感じている。作られた当初は正しくても、実態と乖離していくのを止めるのは困難を極める。全体的に興味深い発表だったが、特にスタックトレースからのドキュメント生成というアイデアに惹かれるものを感じた。スタックトレースという実態と不可分な (乖離しない) 情報を起点にするのは理にかなっている。問題はトレースをいつ、どう取るかだろうか。それを自動化しなければ、実態との乖離が避けられないだろう。
- </p>
- </section>
- <section id="section--report--day-1--1410-a">
- <h4><a href="#section--report--day-1--1410-a">14:10 [A] PHPで学ぶ、セッションの基本と応用</a></h4>
- <p>
- 全体的に基本的な話だったので特に触れない。Cookie やセッションの話としては非常に分かりやすくまとめられていたので、知らない人が学ぶにはいい教材だろう。
- </p>
- </section>
- <section id="section--report--day-1--1450-a">
- <h4><a href="#section--report--day-1--1450-a">14:50 [A] PHP8になった今の時代に、PHPの「エラー」「例外」そして「Error」をおさらいしておこう</a></h4>
- <p>
- PHP を学んでいる途中の私としては、今まさに聞きたい発表だった (現時点で PHP を書き始めてから 4ヶ月ほどになる)。
- </p>
- <p>
- 個人的に例外やエラーを最もうまく扱っているのは Go、Swift、Rust、Haskell などのエラーを「値として」扱う言語だと思っている。try-catch は通常の処理フローを完全に壊してしまう上、構文としても重すぎる。値としてのエラー通知は C言語時代への回帰ともいえるが、その頃と異なるのはエラーを暗黙のうちに握り潰すことがないということだ。これらの言語は型を持っており、静的に検証ができる (C のそれはまともな型付けではない。念のため)。
- </p>
- <p>
- PHP のように、すでに例外が言語システムに根ざしている言語ではどうすればよいか。この場合も同じく静的検証の力を借りることになるだろう。
- </p>
- </section>
- <section id="section--report--day-1--1530-a">
- <h4><a href="#section--report--day-1--1530-a">15:30 [A] Laravel のメール認証の内部実装を掘り下げる</a></h4>
- <p>
- Laravel の知識がない私にはまったくついていけなかった。また、個人的にタイトルがややミスリーディングに感じた。
- </p>
- </section>
- <section id="section--report--day-1--1610-a">
- <h4><a href="#section--report--day-1--1610-a">16:10 [A] ブラウザから始めるgRPC 〜 gRPC-WebにPHPを添えて</a></h4>
- <p>
- (発表の中でもまさに同じことをおっしゃっていたが) PHP 以外の方が向いているだろう、というのが第一の感想である。gRPC はそれ自体というよりも Protobuf というエコシステムに乗れることのメリットが大きいと感じる。そのエコシステムにうまく乗れない時点で、うーんという感じ。
- </p>
- </section>
- </section>
- <section id="section--report--day-2">
- <h3><a href="#section--report--day-2">Day 2 (2021/03/28)</a></h3>
- <p>
- 冒頭に書いた通り、2日目から体調が悪くまともに聴けていない。途中までは頭痛を我慢しつつ見ていたのだが、まともに入ってこなかった。
- </p>
- <p>
- 残念ではあるが、いずれにせよ見られていない発表は他にもあるので、今週末にでもまとめて見ようと思う。
- </p>
- </section>
- <section id="section--report--comments">
- <h3><a href="#section--report--comments">全体の感想</a></h3>
- <p>
- Day 2 にほとんど参加できなかったのは残念だが、イベント自体は大変楽しく、また興味深いものであった。自分がまったく知らない領域の話を聞けるのはこうしたイベントならではだと感じる。オンライン開催ゆえ現地に行く必要がなく、気軽に参加できたのも (特に初参加者として) 嬉しいポイントだった。
- </p>
- <p>
- 今回、雑談/登壇者への質問等向けに Discord サーバもあったのだが、こちらは参加こそしたものの ROM のままになってしまった。発表に1ウィンドウ、メモを書くのに1ウィンドウ、Discord 表示に 1ウィンドウで私にはもう脳のリソースとディスプレイのスペースが追いつかなかった (さらにいうと Zoom でアンカンファレンスもやっていたようだ。こちらはまったく参加していない)。
- </p>
- <p>
- 1つ個人的な反省点としては、一つ一つのセッションを真剣に聞き過ぎたというものがある。もっと適当に聞いておけばよかった。これだけだと大変語弊があるのだが、言い方を変えると、Discord しかりアンカンファレンスしかり「このイベントのこの瞬間にしかないコンテンツ」に触れずに、後から見返せる発表やスライドに注力してしまった、ということだ。発表の詳細な見直しはあとからできるのだから、今しかできないことを考えるべきだった。まあ初カンファレンスだし、とお茶を濁しておこう。
- </p>
- <p>
- さて、カンファレンスで一つ気になったことがある。それは、Discord という書き込み場所が増えたことでニコ生のコメントの流量が吸い取られてしまったのではないか、という点だ。ニコニコだけ見ていると過疎っているかのように見えた発表も、Discord の方では盛り上がっている、というのを何度か見かけた。ニコニコのコメント方式は盛り上がりを如実に反映するが、逆もまたしかり。Discord があったこと自体はプラスだったと思うが、この点はマイナスだったのではないかと感じる。
- </p>
- <hr>
- <p>
- 最後になりましたが、毎年の PHPerKaigi 開催にご尽力されている皆様、スピーカーの皆様、楽しい3日間でした。ありがとうございました! (ずっと常体で書いてしまったのでいきなり仏頂面から笑顔になったようで気持ち悪い)
- </p>
- <p>
- ではまた来年。
- </p>
- </section>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2021-10-02/cpp-you-can-use-keywords-in-attributes/index.html b/vhosts/blog/public/posts/2021-10-02/cpp-you-can-use-keywords-in-attributes/index.html
deleted file mode 100644
index 53bd4c70..00000000
--- a/vhosts/blog/public/posts/2021-10-02/cpp-you-can-use-keywords-in-attributes/index.html
+++ /dev/null
@@ -1,193 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2021 nsfisis">
- <meta name="description" content="C++ の属性構文の属性名には、キーワードが使える。ネタ記事。">
- <meta name="keywords" content="C++,C++ 17">
- <meta property="og:type" content="article">
- <meta property="og:title" content="【C++】 属性構文の属性名にはキーワードが使える|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="C++ の属性構文の属性名には、キーワードが使える。ネタ記事。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>【C++】 属性構文の属性名にはキーワードが使える|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">【C++】 属性構文の属性名にはキーワードが使える</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/cpp/">C++</a>
- </li>
- <li class="tag">
- <a href="/tags/cpp17/">C++ 17</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2021-10-02">2021-10-02</time>: Qiita から移植
- </li>
- </ol>
- </section>
- <div class="admonition">
- <div class="admonition-label">
- NOTE
- </div>
- <div class="admonition-content">
- <p>
- この記事は Qiita から移植してきたものです。元 URL: <a href="https://qiita.com/nsfisis/items/94090937bcf860cfa93b" rel="noreferrer" target="_blank">https://qiita.com/nsfisis/items/94090937bcf860cfa93b</a>
- </p>
- </div>
- </div>
- <p>
- タイトル落ち。まずはこのコードを見て欲しい。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">#include</span><span style="color:#032F62"> &#x3C;iostream></span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#005CC5">[[</span><span style="color:#6F42C1">alignas</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">alignof</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">and</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">and_eq</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">asm</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">auto</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">bitand</span><span style="color:#005CC5">]]</span></span>
-<span class="line"><span style="color:#005CC5">[[</span><span style="color:#6F42C1">bitor</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">bool</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">break</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">case</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">catch</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">char</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">char16_t</span><span style="color:#005CC5">]]</span></span>
-<span class="line"><span style="color:#005CC5">[[</span><span style="color:#6F42C1">char32_t</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">class</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">compl</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">const</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">const_cast</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">constexpr</span><span style="color:#005CC5">]]</span></span>
-<span class="line"><span style="color:#005CC5">[[</span><span style="color:#6F42C1">continue</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">decltype</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">default</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">delete</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">do</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">double</span><span style="color:#005CC5">]]</span></span>
-<span class="line"><span style="color:#005CC5">[[</span><span style="color:#6F42C1">dynamic_cast</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">else</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">enum</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">explicit</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">export</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">extern</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">false</span><span style="color:#005CC5">]]</span></span>
-<span class="line"><span style="color:#005CC5">[[</span><span style="color:#6F42C1">final</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">float</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">for</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">friend</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">goto</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">if</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">inline</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">int</span><span style="color:#005CC5">]]</span></span>
-<span class="line"><span style="color:#005CC5">[[</span><span style="color:#6F42C1">long</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">mutable</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">namespace</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">new</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">noexcept</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">not</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">not_eq</span><span style="color:#005CC5">]]</span></span>
-<span class="line"><span style="color:#005CC5">[[</span><span style="color:#6F42C1">nullptr</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">operator</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">or</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">or_eq</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">override</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">private</span><span style="color:#005CC5">]]</span></span>
-<span class="line"><span style="color:#005CC5">[[</span><span style="color:#6F42C1">protected</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">public</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">register</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">reinterpret_cast</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">return</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">short</span><span style="color:#005CC5">]]</span></span>
-<span class="line"><span style="color:#005CC5">[[</span><span style="color:#6F42C1">signed</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">sizeof</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">static</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">static_assert</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">static_cast</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">struct</span><span style="color:#005CC5">]]</span></span>
-<span class="line"><span style="color:#005CC5">[[</span><span style="color:#6F42C1">switch</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">template</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">this</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">thread_local</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">throw</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">true</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">try</span><span style="color:#005CC5">]]</span></span>
-<span class="line"><span style="color:#005CC5">[[</span><span style="color:#6F42C1">typedef</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">typeid</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">typename</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">union</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">unsigned</span><span style="color:#005CC5">]]</span></span>
-<span class="line"><span style="color:#005CC5">[[</span><span style="color:#6F42C1">virtual</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">void</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">volatile</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">wchar_t</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">while</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">xor</span><span style="color:#005CC5">]]</span><span style="color:#005CC5"> [[</span><span style="color:#6F42C1">xor_eq</span><span style="color:#005CC5">]]</span></span>
-<span class="line"><span style="color:#6A737D">// [[using]]</span></span>
-<span class="line"><span style="color:#D73A49">int</span><span style="color:#6F42C1"> main</span><span style="color:#24292E">() {</span></span>
-<span class="line"><span style="color:#6F42C1"> std</span><span style="color:#24292E">::cout </span><span style="color:#D73A49">&#x3C;&#x3C;</span><span style="color:#032F62"> "Hello, World!"</span><span style="color:#D73A49"> &#x3C;&#x3C;</span><span style="color:#6F42C1"> std</span><span style="color:#24292E">::endl;</span></span>
-<span class="line"><span style="color:#24292E">}</span></span></code></pre>
- </div>
- <p>
- コンパイラのバージョン
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ clang++ –version Apple clang version 11.0.0</span></span>
-<span class="line"><span>(clang-1100.0.33.8) Target: x86_64-apple-darwin19.6.0 Thread model:</span></span>
-<span class="line"><span>posix InstalledDir:</span></span>
-<span class="line"><span>/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin</span></span></code></pre>
- </div>
- <p>
- コンパイルコマンド (C17指定)
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ clang –std=c++17 hoge.cpp</span></span></code></pre>
- </div>
- <p>
- この記事から得られるものはこれ以上ないので以下は蛇足になる。
- </p>
- <p>
- 別件で <a href="https://en.cppreference.com/w/cpp/language/identifiers" rel="noreferrer" target="_blank">cppreference.com の identifier のページ</a>を読んでいた時、次の文が目に止まった。
- </p>
- <blockquote>
- <ul>
- <li>
- the identifiers that are keywords cannot be used for other purposes;
- <ul>
- <li>
- The only place they can be used as non-keywords is in an attribute-token. (e.g. [[private]] is a valid attribute) (since C++11)
- </li>
- </ul>
- </li>
- </ul>
- </blockquote>
- <p>
- キーワードでも属性として指定する場合は非キーワードとして使えるらしい。実際にやってみる。
- </p>
- <p>
- 同サイトの <a href="https://en.cppreference.com/w/cpp/keyword" rel="noreferrer" target="_blank">keywords のページ</a> から一覧を拝借し、上のコードが出来上がった (C++17 においてキーワードでないものなど、一部省いている)。 大量の警告 (unknown attribute `〇〇’ ignored) がコンパイラから出力されるが、コンパイルできる。
- </p>
- <p>
- 上のコードでは <code>[[using]]</code> をコメントアウトしているが、これは <code>using</code> キーワードのみ属性構文の中で意味を持つからであり、このコメントアウトを外すとコンパイルに失敗する。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6A737D">// using の例</span></span>
-<span class="line"><span style="color:#005CC5">[[</span><span style="color:#D73A49">using</span><span style="color:#6F42C1"> foo</span><span style="color:#005CC5">: </span><span style="color:#6F42C1">attr1</span><span style="color:#005CC5">, </span><span style="color:#6F42C1">attr2</span><span style="color:#005CC5">]]</span><span style="color:#D73A49"> int</span><span style="color:#24292E"> x;</span><span style="color:#6A737D"> // [[foo::attr1, foo::attr2]] の糖衣構文</span></span></code></pre>
- </div>
- <p>
- C++17 の仕様も見てみる (正確には標準化前のドラフト)。
- </p>
- <p>
- 引用元: <a href="https://timsong-cpp.github.io/cppwp/n4659/dcl.attr#grammar-4" rel="noreferrer" target="_blank">https://timsong-cpp.github.io/cppwp/n4659/dcl.attr#grammar-4</a>
- </p>
- <blockquote>
- <p>
- If a keyword or an alternative token that satisfies the syntactic requirements of an identifier is contained in an attribute-token, it is considered an identifier.
- </p>
- </blockquote>
- <p>
- 「<code>identifier</code> の構文上の要件を満たすキーワードまたは代替トークンが <code>attribute-token</code> に含まれている場合、<code>identifier</code> とみなされる」とある。どうやら間違いないようだ。
- </p>
- <p>
- ところで、代替トークン (alternative token) とは <code>and</code> (<code>&amp;</code>) や <code>bitor</code> (<code>|</code>) などのことだが、<code>identifier</code> の構文上の要件を満たさないような代替トークンなどあるのか? 疑問に思って調べたところ、代替トークンという語にはダイグラフも含まれるらしい (参考: <a href="https://timsong-cpp.github.io/cppwp/n4659/lex.digraph" rel="noreferrer" target="_blank">同ドラフト</a> )
- </p>
- <ul>
- <li>
- <code>&lt;%</code> → <code>{</code>
- </li>
- <li>
- <code>%&gt;</code> → <code>}</code>
- </li>
- <li>
- <code>&lt;:</code> → <code>[</code>
- </li>
- <li>
- <code>:&gt;</code> → <code>]</code>
- </li>
- <li>
- <code>%:</code> → <code>#</code>
- </li>
- <li>
- <code>%:%:</code> → <code>##</code>
- </li>
- </ul>
- <p>
- 「<code>identifier</code> の構文上の要件を満たさないような代替トークン」はこれらが当てはまると思われる。
- </p>
- <p>
- 調べた感想: 字句解析器か構文解析器が辛そう
- </p>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2021-10-02/python-unbound-local-error/index.html b/vhosts/blog/public/posts/2021-10-02/python-unbound-local-error/index.html
deleted file mode 100644
index 6b9c4172..00000000
--- a/vhosts/blog/public/posts/2021-10-02/python-unbound-local-error/index.html
+++ /dev/null
@@ -1,132 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2021 nsfisis">
- <meta name="description" content="Python における UnboundLocalError の理由と対処法。">
- <meta name="keywords" content="Python,Python 3">
- <meta property="og:type" content="article">
- <meta property="og:title" content="【Python】 クロージャとUnboundLocalError: local variable &apos;x&apos; referenced before assignment|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="Python における UnboundLocalError の理由と対処法。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>【Python】 クロージャとUnboundLocalError: local variable &apos;x&apos; referenced before assignment|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">【Python】 クロージャとUnboundLocalError: local variable &apos;x&apos; referenced before assignment</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/python/">Python</a>
- </li>
- <li class="tag">
- <a href="/tags/python3/">Python 3</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2021-10-02">2021-10-02</time>: Qiita から移植
- </li>
- </ol>
- </section>
- <div class="admonition">
- <div class="admonition-label">
- NOTE
- </div>
- <div class="admonition-content">
- <p>
- この記事は Qiita から移植してきたものです。元 URL: <a href="https://qiita.com/nsfisis/items/5d733703afcb35bbf399" rel="noreferrer" target="_blank">https://qiita.com/nsfisis/items/5d733703afcb35bbf399</a>
- </p>
- </div>
- </div>
- <p>
- 本記事は Python 3.7.6 の動作結果を元にして書かれている。
- </p>
- <p>
- Python でクロージャを作ろうと、次のようなコードを書いた。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">def</span><span style="color:#6F42C1"> f</span><span style="color:#24292E">():</span></span>
-<span class="line"><span style="color:#24292E"> x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> 0</span></span>
-<span class="line"><span style="color:#D73A49"> def</span><span style="color:#6F42C1"> g</span><span style="color:#24292E">():</span></span>
-<span class="line"><span style="color:#24292E"> x </span><span style="color:#D73A49">+=</span><span style="color:#005CC5"> 1</span></span>
-<span class="line"><span style="color:#24292E"> g()</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E">f()</span></span></code></pre>
- </div>
- <p>
- 関数 <code>g</code> から 関数 <code>f</code> のスコープ内で定義された変数 <code>x</code> を参照し、それに 1 を足そうとしている。 これを実行すると <code>x += 1</code> の箇所でエラーが発生する。
- </p>
- <blockquote>
- <p>
- UnboundLocalError: local variable `x’ referenced before assignment
- </p>
- </blockquote>
- <p>
- local変数 <code>x</code> が代入前に参照された、とある。これは、<code>f</code> の <code>x</code> を参照するのではなく、新しく別の変数を <code>g</code> 内に作ってしまっているため。前述のコードを宣言と代入を便宜上分けて書き直すと次のようになる。<code>var</code> を変数宣言のための構文として擬似的に利用している。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6A737D"># 注: var は正しい Python の文法ではない。上記参照のこと</span></span>
-<span class="line"><span style="color:#D73A49">def</span><span style="color:#6F42C1"> f</span><span style="color:#24292E">():</span></span>
-<span class="line"><span style="color:#24292E"> var x </span><span style="color:#6A737D"># f の local変数 'x' を宣言</span></span>
-<span class="line"><span style="color:#24292E"> x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> 0</span><span style="color:#6A737D"> # x に 0 を代入</span></span>
-<span class="line"><span style="color:#D73A49"> def</span><span style="color:#6F42C1"> g</span><span style="color:#24292E">(): </span><span style="color:#6A737D"># f の内部関数 g を定義</span></span>
-<span class="line"><span style="color:#24292E"> var x </span><span style="color:#6A737D"># g の local変数 'x' を宣言</span></span>
-<span class="line"><span style="color:#6A737D"> # たまたま f にも同じ名前の変数があるが、それとは別の変数</span></span>
-<span class="line"><span style="color:#24292E"> x </span><span style="color:#D73A49">+=</span><span style="color:#005CC5"> 1</span><span style="color:#6A737D"> # x に 1 を加算 (x = x + 1 の糖衣構文)</span></span>
-<span class="line"><span style="color:#6A737D"> # 加算する前の値を参照しようとするが、まだ代入されていないためエラー</span></span>
-<span class="line"><span style="color:#24292E"> g()</span></span></code></pre>
- </div>
- <p>
- 当初の意図を表現するには、次のように書けばよい。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">def</span><span style="color:#6F42C1"> f</span><span style="color:#24292E">():</span></span>
-<span class="line"><span style="color:#24292E"> x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> 0</span></span>
-<span class="line"><span style="color:#D73A49"> def</span><span style="color:#6F42C1"> g</span><span style="color:#24292E">():</span></span>
-<span class="line"><span style="color:#D73A49"> nonlocal</span><span style="color:#24292E"> x </span><span style="color:#6A737D">## (*)</span></span>
-<span class="line"><span style="color:#24292E"> x </span><span style="color:#D73A49">+=</span><span style="color:#005CC5"> 1</span></span>
-<span class="line"><span style="color:#24292E"> g()</span></span></code></pre>
- </div>
- <p>
- <code>(*)</code> のように、<code>nonlocal</code> を追加する。これにより一つ外側のスコープ (<code>g</code> の一つ外側 = <code>f</code>) で定義されている <code>x</code> を探しに行くようになる。
- </p>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2021-10-02/ruby-detect-running-implementation/index.html b/vhosts/blog/public/posts/2021-10-02/ruby-detect-running-implementation/index.html
deleted file mode 100644
index 9af43f11..00000000
--- a/vhosts/blog/public/posts/2021-10-02/ruby-detect-running-implementation/index.html
+++ /dev/null
@@ -1,135 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2021 nsfisis">
- <meta name="description" content="Ruby には複数の実装があるが、自身を実行している処理系の種類をスクリプト上からどのように判定すればよいだろうか。">
- <meta name="keywords" content="Ruby">
- <meta property="og:type" content="article">
- <meta property="og:title" content="【Ruby】 自身を実行している処理系の種類を判定する|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="Ruby には複数の実装があるが、自身を実行している処理系の種類をスクリプト上からどのように判定すればよいだろうか。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>【Ruby】 自身を実行している処理系の種類を判定する|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">【Ruby】 自身を実行している処理系の種類を判定する</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/ruby/">Ruby</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2021-10-02">2021-10-02</time>: Qiita から移植
- </li>
- </ol>
- </section>
- <div class="admonition">
- <div class="admonition-label">
- NOTE
- </div>
- <div class="admonition-content">
- <p>
- この記事は Qiita から移植してきたものです。元 URL: <a href="https://qiita.com/nsfisis/items/74d7ffeeebc51b20d791" rel="noreferrer" target="_blank">https://qiita.com/nsfisis/items/74d7ffeeebc51b20d791</a>
- </p>
- </div>
- </div>
- <p>
- Ruby という言語には複数の実装があるが、それらをスクリプト上からどのようにして programmatically に見分ければよいだろうか。
- </p>
- <p>
- <code>Object</code> クラスに定義されている <code>RUBY_ENGINE</code> という定数がこの用途に使える。
- </p>
- <p>
- 参考: <a href="https://docs.ruby-lang.org/ja/latest/method/Object/c/RUBY_ENGINE.html" rel="noreferrer" target="_blank">Object::RUBY_ENGINE</a>
- </p>
- <p>
- 上記ページの例から引用する:
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ ruby-1.9.1 -ve 'p RUBY_ENGINE'</span></span>
-<span class="line"><span>ruby 1.9.1p0 (2009-03-04 revision 22762) [x86_64-linux]</span></span>
-<span class="line"><span>"ruby"</span></span>
-<span class="line"><span>$ jruby -ve 'p RUBY_ENGINE'</span></span>
-<span class="line"><span>jruby 1.2.0 (ruby 1.8.6 patchlevel 287) (2009-03-16 rev 9419) [i386-java]</span></span>
-<span class="line"><span>"jruby"</span></span></code></pre>
- </div>
- <p>
- それぞれの処理系がどのような値を返すかだが、stack overflow に良い質問と回答があった。
- </p>
- <p>
- <a href="https://stackoverflow.com/a/9894232" rel="noreferrer" target="_blank">What values for RUBY_ENGINE correspond to which Ruby implementations?</a> より引用:
- </p>
- <blockquote>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>| RUBY_ENGINE | Implementation |</span></span>
-<span class="line"><span>|:-----------:|:------------------|</span></span>
-<span class="line"><span>| &#x3C;undefined> | MRI &#x3C; 1.9 |</span></span>
-<span class="line"><span>| 'ruby' | MRI >= 1.9 or REE |</span></span>
-<span class="line"><span>| 'jruby' | JRuby |</span></span>
-<span class="line"><span>| 'macruby' | MacRuby |</span></span>
-<span class="line"><span>| 'rbx' | Rubinius |</span></span>
-<span class="line"><span>| 'maglev' | MagLev |</span></span>
-<span class="line"><span>| 'ironruby' | IronRuby |</span></span>
-<span class="line"><span>| 'cardinal' | Cardinal |</span></span></code></pre>
- </div>
- </blockquote>
- <p>
- なお、この質問・回答は 2014年になされたものであり、値は変わっている可能性がある。MRI (aka CRuby) については執筆時現在 (2020/12/8) も <code>&apos;ruby&apos;</code> が返ってくることを確認済み。
- </p>
- <p>
- この表にない主要な処理系として、 <a href="https://mruby.org" rel="noreferrer" target="_blank">mruby</a> は <code>&apos;mruby&apos;</code> を返す。
- </p>
- <p>
- <a href="https://github.com/mruby/mruby/blob/ed29d74bfd95362eaeb946fcf7e865d80346b62b/include/mruby/version.h#L32-L35" rel="noreferrer" target="_blank">mruby 該当部分のソース</a> より引用:
- </p>
- <div class="codeblock">
- <div class="filename">
- version.h
- </div>
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6A737D">/*</span></span>
-<span class="line"><span style="color:#6A737D"> * Ruby engine.</span></span>
-<span class="line"><span style="color:#6A737D"> */</span></span>
-<span class="line"><span style="color:#D73A49">#define</span><span style="color:#6F42C1"> MRUBY_RUBY_ENGINE</span><span style="color:#032F62"> "mruby"</span></span></code></pre>
- </div>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html b/vhosts/blog/public/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html
deleted file mode 100644
index 5d8600f3..00000000
--- a/vhosts/blog/public/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html
+++ /dev/null
@@ -1,290 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2021 nsfisis">
- <meta name="description" content="Ruby 3.0 で追加される case in 構文と、then キーワードについて。">
- <meta name="keywords" content="Ruby,Ruby 3">
- <meta property="og:type" content="article">
- <meta property="og:title" content="【Ruby】 then キーワードと case in|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="Ruby 3.0 で追加される case in 構文と、then キーワードについて。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>【Ruby】 then キーワードと case in|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">【Ruby】 then キーワードと case in</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/ruby/">Ruby</a>
- </li>
- <li class="tag">
- <a href="/tags/ruby3/">Ruby 3</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2021-10-02">2021-10-02</time>: Qiita から移植
- </li>
- </ol>
- </section>
- <div class="admonition">
- <div class="admonition-label">
- NOTE
- </div>
- <div class="admonition-content">
- <p>
- この記事は Qiita から移植してきたものです。元 URL: <a href="https://qiita.com/nsfisis/items/787a8cf888a304497223" rel="noreferrer" target="_blank">https://qiita.com/nsfisis/items/787a8cf888a304497223</a>
- </p>
- </div>
- </div>
- <section id="section--tl-dr">
- <h2><a href="#section--tl-dr">TL; DR</a></h2>
- <p>
- <code>case</code> - <code>in</code> によるパターンマッチング構文でも、<code>case</code> - <code>when</code> と同じように <code>then</code> が使える (場合によっては使う必要がある)。
- </p>
- </section>
- <section id="section--what-is-then-keyword">
- <h2><a href="#section--what-is-then-keyword"><code>then</code> とは</a></h2>
- <p>
- 使われることは稀だが、Ruby では <code>then</code> がキーワードになっている。次のように使う:
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">if</span><span style="color:#24292E"> cond </span><span style="color:#D73A49">then</span></span>
-<span class="line"><span style="color:#005CC5"> puts</span><span style="color:#032F62"> "Y"</span></span>
-<span class="line"><span style="color:#D73A49">else</span></span>
-<span class="line"><span style="color:#005CC5"> puts</span><span style="color:#032F62"> "N"</span></span>
-<span class="line"><span style="color:#D73A49">end</span></span></code></pre>
- </div>
- <p>
- このキーワードが現れうる場所はいくつかあり、<code>if</code>、<code>unless</code>、<code>rescue</code>、<code>case</code> 構文がそれに当たる。 上記のように、何か条件を書いた後 <code>then</code> を置き、式がそこで終了していることを示すマーカーとして機能する。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6A737D"># Example:</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">if</span><span style="color:#24292E"> x </span><span style="color:#D73A49">then</span></span>
-<span class="line"><span style="color:#24292E"> a</span></span>
-<span class="line"><span style="color:#D73A49">end</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">unless</span><span style="color:#24292E"> x </span><span style="color:#D73A49">then</span></span>
-<span class="line"><span style="color:#24292E"> a</span></span>
-<span class="line"><span style="color:#D73A49">end</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">begin</span></span>
-<span class="line"><span style="color:#24292E"> a</span></span>
-<span class="line"><span style="color:#D73A49">rescue</span><span style="color:#D73A49"> then</span></span>
-<span class="line"><span style="color:#24292E"> b</span></span>
-<span class="line"><span style="color:#D73A49">end</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">case</span><span style="color:#24292E"> x</span></span>
-<span class="line"><span style="color:#D73A49">when</span><span style="color:#005CC5"> p</span><span style="color:#D73A49"> then</span></span>
-<span class="line"><span style="color:#24292E"> a</span></span>
-<span class="line"><span style="color:#D73A49">end</span></span></code></pre>
- </div>
- </section>
- <section id="section--why-then-is-usually-unnecessary">
- <h2><a href="#section--why-then-is-usually-unnecessary">なぜ普段は書かなくてもよいのか</a></h2>
- <p>
- 普通 Ruby のコードで <code>then</code> を書くことはない。なぜか。次のコードを実行してみるとわかる。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">if</span><span style="color:#005CC5"> true</span><span style="color:#005CC5"> puts</span><span style="color:#032F62"> 'Hello, World!'</span><span style="color:#D73A49"> end</span></span></code></pre>
- </div>
- <p>
- 次のような構文エラーが出力される。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>20:1: syntax error, unexpected local variable or method, expecting `then' or ';' or '\n'</span></span>
-<span class="line"><span>if true puts 'Hello, World!' end</span></span>
-<span class="line"><span> ^~~~</span></span>
-<span class="line"><span>20:1: syntax error, unexpected `end', expecting end-of-input</span></span>
-<span class="line"><span>...f true puts 'Hello, World!' end</span></span></code></pre>
- </div>
- <p>
- 二つ目のメッセージは無視して一つ目を読むと、<code>then</code> か <code>;</code> か改行が来るはずのところ変数だかメソッドだかが現れたことによりエラーとなっているようだ。
- </p>
- <p>
- ポイントは改行が <code>then</code> (や <code>;</code>) の代わりとなることである。<code>true</code> の後に改行を入れてみる。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">if</span><span style="color:#005CC5"> true</span></span>
-<span class="line"><span style="color:#005CC5">puts</span><span style="color:#032F62"> 'Hello, World!'</span><span style="color:#D73A49"> end</span></span></code></pre>
- </div>
- <p>
- 無事 Hello, World! と出力されるようになった。
- </p>
- </section>
- <section id="section--why-then-or-linebreak-is-needed">
- <h2><a href="#section--why-then-or-linebreak-is-needed">なぜ <code>then</code> や <code>;</code> や改行が必要か</a></h2>
- <p>
- なぜ <code>then</code> や <code>;</code> や改行 (以下 「<code>then</code> 等」) が必要なのだろうか。次の例を見てほしい:
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">if</span><span style="color:#24292E"> a b </span><span style="color:#D73A49">end</span></span></code></pre>
- </div>
- <p>
- <code>then</code> も <code>;</code> も改行もないのでエラーになるが、これは条件式がどこまで続いているのかわからないためだ。この例は二通りに解釈できる。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6A737D"># a という変数かメソッドの評価結果が truthy なら b という変数かメソッドを評価</span></span>
-<span class="line"><span style="color:#D73A49">if</span><span style="color:#24292E"> a </span><span style="color:#D73A49">then</span></span>
-<span class="line"><span style="color:#24292E">b</span></span>
-<span class="line"><span style="color:#D73A49">end</span></span></code></pre>
- </div>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6A737D"># a というメソッドに b という変数かメソッドの評価結果を渡して呼び出し、</span></span>
-<span class="line"><span style="color:#6A737D"># その結果が truthy なら何もしない</span></span>
-<span class="line"><span style="color:#D73A49">if</span><span style="color:#6F42C1"> a</span><span style="color:#24292E">(b) </span><span style="color:#D73A49">then</span></span>
-<span class="line"><span style="color:#D73A49">end</span></span></code></pre>
- </div>
- <p>
- <code>then</code> 等はこの曖昧性を排除するためにあり、条件式は <code>if</code> から <code>then</code> 等までの間にある、ということを明確にする。 C系の <code>if</code> 後に来る <code>(</code>/<code>)</code> や、Python の <code>:</code>、Rust/Go/Swift などの <code>{</code> も同じ役割を持つ。
- </p>
- <p>
- Ruby の場合、プログラマーが書きやすいよう改行でもって <code>then</code> が代用できるので、ほとんどの場合 <code>then</code> は必要ない。
- </p>
- </section>
- <section id="section--then-in-case-in">
- <h2><a href="#section--then-in-case-in"><code>case</code> - <code>in</code> における <code>then</code></a></h2>
- <p>
- ようやく本題にたどり着いた。来る Ruby 3.0 では <code>case</code> と <code>in</code> キーワードを使ったパターンマッチングの構文が入る予定である。この構文でもパターン部との区切りとして <code>then</code> 等が必要になる。 (現在の) Ruby には formal な形式での文法仕様は存在しないので、yacc の定義ファイルを参照した (yacc の説明は省略)。
- </p>
- <p>
- <a href="https://github.com/ruby/ruby/blob/221ca0f8281d39f0dfdfe13b2448875384bbf735/parse.y#L3961-L3986" rel="noreferrer" target="_blank">https://github.com/ruby/ruby/blob/221ca0f8281d39f0dfdfe13b2448875384bbf735/parse.y#L3961-L3986</a>
- </p>
- <div class="codeblock">
- <div class="filename">
- parse.y
- </div>
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>p_case_body : keyword_in</span></span>
-<span class="line"><span>{</span></span>
-<span class="line"><span> SET_LEX_STATE(EXPR_BEG|EXPR_LABEL);</span></span>
-<span class="line"><span> p->command_start = FALSE;</span></span>
-<span class="line"><span> $&#x3C;ctxt>1 = p->ctxt;</span></span>
-<span class="line"><span> p->ctxt.in_kwarg = 1;</span></span>
-<span class="line"><span> $&#x3C;tbl>$ = push_pvtbl(p);</span></span>
-<span class="line"><span>}</span></span>
-<span class="line"><span>{</span></span>
-<span class="line"><span> $&#x3C;tbl>$ = push_pktbl(p);</span></span>
-<span class="line"><span>}</span></span>
-<span class="line"><span>p_top_expr then</span></span>
-<span class="line"><span>{</span></span>
-<span class="line"><span> pop_pktbl(p, $&#x3C;tbl>3);</span></span>
-<span class="line"><span> pop_pvtbl(p, $&#x3C;tbl>2);</span></span>
-<span class="line"><span> p->ctxt.in_kwarg = $&#x3C;ctxt>1.in_kwarg;</span></span>
-<span class="line"><span>}</span></span>
-<span class="line"><span>compstmt</span></span>
-<span class="line"><span>p_cases</span></span>
-<span class="line"><span>{</span></span>
-<span class="line"><span> /*%%%*/</span></span>
-<span class="line"><span> $$ = NEW_IN($4, $7, $8, &#x26;@$);</span></span>
-<span class="line"><span> /*% %*/</span></span>
-<span class="line"><span> /*% ripper: in!($4, $7, escape_Qundef($8)) %*/</span></span>
-<span class="line"><span>}</span></span>
-<span class="line"><span>;</span></span></code></pre>
- </div>
- <p>
- 簡略版:
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>p_case_body : keyword_in p_top_expr then compstmt p_cases</span></span>
-<span class="line"><span>;</span></span></code></pre>
- </div>
- <p>
- ここで、<code>keyword_in</code> は文字通り <code>in</code>、<code>p_top_expr</code> はいわゆるパターン、<code>then</code> は <code>then</code> キーワードのことではなく、この記事で <code>then</code> 等と呼んでいるもの、つまり <code>then</code> キーワード、<code>;</code>、改行のいずれかである。
- </p>
- <p>
- これにより、<code>case</code> - <code>when</code> による従来の構文と同じように、<code>then</code> 等をパターンの後ろに挿入すればよいことがわかった。つまり次の3通りのいずれかになる:
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">case</span><span style="color:#24292E"> x</span></span>
-<span class="line"><span style="color:#D73A49">in</span><span style="color:#005CC5"> 1</span><span style="color:#D73A49"> then</span><span style="color:#24292E"> a</span></span>
-<span class="line"><span style="color:#D73A49">in</span><span style="color:#005CC5"> 2</span><span style="color:#D73A49"> then</span><span style="color:#24292E"> b</span></span>
-<span class="line"><span style="color:#D73A49">in</span><span style="color:#005CC5"> 3</span><span style="color:#D73A49"> then</span><span style="color:#24292E"> c</span></span>
-<span class="line"><span style="color:#D73A49">end</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">case</span><span style="color:#24292E"> x</span></span>
-<span class="line"><span style="color:#D73A49">in</span><span style="color:#005CC5"> 1</span></span>
-<span class="line"><span style="color:#24292E"> a</span></span>
-<span class="line"><span style="color:#D73A49">in</span><span style="color:#005CC5"> 2</span></span>
-<span class="line"><span style="color:#24292E"> b</span></span>
-<span class="line"><span style="color:#D73A49">in</span><span style="color:#005CC5"> 3</span></span>
-<span class="line"><span style="color:#24292E"> c</span></span>
-<span class="line"><span style="color:#D73A49">end</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">case</span><span style="color:#24292E"> x</span></span>
-<span class="line"><span style="color:#D73A49">in</span><span style="color:#005CC5"> 1</span><span style="color:#24292E">; a</span></span>
-<span class="line"><span style="color:#D73A49">in</span><span style="color:#005CC5"> 2</span><span style="color:#24292E">; b</span></span>
-<span class="line"><span style="color:#D73A49">in</span><span style="color:#005CC5"> 3</span><span style="color:#24292E">; c</span></span>
-<span class="line"><span style="color:#D73A49">end</span></span></code></pre>
- </div>
- <p>
- ところで、<code>p_top_expr</code> には <code>if</code> による guard clause が書けるので、その場合は <code>if</code> - <code>then</code> と似たような見た目になる。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">case</span><span style="color:#24292E"> x</span></span>
-<span class="line"><span style="color:#D73A49">in</span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> then</span><span style="color:#24292E"> a</span></span>
-<span class="line"><span style="color:#D73A49">in</span><span style="color:#24292E"> n </span><span style="color:#D73A49">if</span><span style="color:#24292E"> n </span><span style="color:#D73A49">&#x3C;</span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> then</span><span style="color:#24292E"> b</span></span>
-<span class="line"><span style="color:#D73A49">in</span><span style="color:#24292E"> n </span><span style="color:#D73A49">then</span><span style="color:#24292E"> c</span></span>
-<span class="line"><span style="color:#D73A49">end</span></span></code></pre>
- </div>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">まとめ</a></h2>
- <ul>
- <li>
- <code>if</code> や <code>case</code> の条件の後ろには <code>then</code>、<code>;</code>、改行のいずれかが必要
- <ul>
- <li>
- 通常は改行しておけばよい
- </li>
- </ul>
- </li>
- <li>
- 3.0 で入る予定の <code>case</code> - <code>in</code> でも <code>then</code> 等が必要になる
- </li>
- <li>
- Ruby の構文を正確に知るには (現状) <code>parse.y</code> を直接読めばよい
- </li>
- </ul>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2021-10-02/rust-where-are-primitive-types-from/index.html b/vhosts/blog/public/posts/2021-10-02/rust-where-are-primitive-types-from/index.html
deleted file mode 100644
index 840109c8..00000000
--- a/vhosts/blog/public/posts/2021-10-02/rust-where-are-primitive-types-from/index.html
+++ /dev/null
@@ -1,252 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2021 nsfisis">
- <meta name="description" content="Rust のプリミティブ型は予約語ではなく普通の識別子である。どのようにこれが名前解決されるのかを調べた。">
- <meta name="keywords" content="Rust">
- <meta property="og:type" content="article">
- <meta property="og:title" content="Rust のプリミティブ型はどこからやって来るか|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="Rust のプリミティブ型は予約語ではなく普通の識別子である。どのようにこれが名前解決されるのかを調べた。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>Rust のプリミティブ型はどこからやって来るか|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">Rust のプリミティブ型はどこからやって来るか</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/rust/">Rust</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2021-10-02">2021-10-02</time>: Qiita から移植
- </li>
- </ol>
- </section>
- <div class="admonition">
- <div class="admonition-label">
- NOTE
- </div>
- <div class="admonition-content">
- <p>
- この記事は Qiita から移植してきたものです。元 URL: <a href="https://qiita.com/nsfisis/items/9a429432258bbcd6c565" rel="noreferrer" target="_blank">https://qiita.com/nsfisis/items/9a429432258bbcd6c565</a>
- </p>
- </div>
- </div>
- <section id="section--intro">
- <h2><a href="#section--intro">前置き</a></h2>
- <p>
- Rust において、プリミティブ型の名前は予約語でない。したがって、次のコードは合法である。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">#![allow(non_camel_case_types)]</span></span>
-<span class="line"><span style="color:#24292E">#![allow(dead_code)]</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">struct</span><span style="color:#6F42C1"> bool</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#D73A49">struct</span><span style="color:#6F42C1"> char</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#D73A49">struct</span><span style="color:#6F42C1"> i8</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#D73A49">struct</span><span style="color:#6F42C1"> i16</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#D73A49">struct</span><span style="color:#6F42C1"> i32</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#D73A49">struct</span><span style="color:#6F42C1"> i64</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#D73A49">struct</span><span style="color:#6F42C1"> i128</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#D73A49">struct</span><span style="color:#6F42C1"> isize</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#D73A49">struct</span><span style="color:#6F42C1"> u8</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#D73A49">struct</span><span style="color:#6F42C1"> u16</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#D73A49">struct</span><span style="color:#6F42C1"> u32</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#D73A49">struct</span><span style="color:#6F42C1"> u64</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#D73A49">struct</span><span style="color:#6F42C1"> u128</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#D73A49">struct</span><span style="color:#6F42C1"> usize</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#D73A49">struct</span><span style="color:#6F42C1"> f32</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#D73A49">struct</span><span style="color:#6F42C1"> f64</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#D73A49">struct</span><span style="color:#6F42C1"> str</span><span style="color:#24292E">;</span></span></code></pre>
- </div>
- <p>
- では、普段単に <code>bool</code> と書いたとき、この <code>bool</code> は一体どこから来ているのか。rustc のソースを追ってみた。
- </p>
- <p>
- 前提知識: 一般的なコンパイラの構造、用語。<code>rustc</code> そのものの知識は不要 (というよりも筆者自身がよく知らない)
- </p>
- </section>
- <section id="section--code-reading">
- <h2><a href="#section--code-reading">調査</a></h2>
- <p>
- 調査に使用したソース (調査時点での最新 master)
- </p>
- <p>
- <a href="https://github.com/rust-lang/rust/tree/511ed9f2356af365ad8affe046b3dd33f7ac3c98" rel="noreferrer" target="_blank">https://github.com/rust-lang/rust/tree/511ed9f2356af365ad8affe046b3dd33f7ac3c98</a>
- </p>
- <p>
- どのようにして調べるか。rustc の構造には詳しくないため、すぐに当たりをつけるのは難しい。
- </p>
- <p>
- 大雑把な構造としては、<code>compiler</code> フォルダ以下に <code>rustc_*</code> という名前のクレートが数十個入っている。これがどうやら <code>rustc</code> コマンドの実装部のようだ。
- </p>
- <p>
- <code>rustc</code> はセルフホストされている (= <code>rustc</code> 自身が Rust で書かれている) ので、<code>bool</code> や <code>char</code> などで適当に検索をかけてもノイズが多すぎて話にならない。しかし、お誂え向きなことに <code>i128</code>/<code>u128</code> というコンパイラ自身が使うことがなさそうな型が存在するのでこれを使って <code>git grep</code> してみる。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ git grep "\bi128\b" | wc # i128</span></span>
-<span class="line"><span>165 1069 15790</span></span>
-<span class="line"><span></span></span>
-<span class="line"><span>$ git grep "\bu128\b" | wc # u128</span></span>
-<span class="line"><span>293 2127 26667</span></span>
-<span class="line"><span></span></span>
-<span class="line"><span>$ git grep "\bbool\b" | wc # cf. bool の結果</span></span>
-<span class="line"><span>3563 23577 294659</span></span></code></pre>
- </div>
- <p>
- 165 程度であれば探すことができそうだ。今回は、クレート名を見ておおよその当たりをつけた。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ git grep "\bi128\b"</span></span>
-<span class="line"><span>...</span></span>
-<span class="line"><span>rustc_resolve/src/lib.rs: table.insert(sym::i128, Int(IntTy::I128));</span></span>
-<span class="line"><span>...</span></span></code></pre>
- </div>
- <p>
- <code>rustc_resolve</code> というのはいかにも名前解決を担いそうなクレート名である。該当箇所を見てみる。
- </p>
- <div class="codeblock">
- <div class="filename">
- rustc_resolve/src/lib.rs
- </div>
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6A737D">/// Interns the names of the primitive types.</span></span>
-<span class="line"><span style="color:#6A737D">///</span></span>
-<span class="line"><span style="color:#6A737D">/// All other types are defined somewhere and possibly imported, but the primitive ones need</span></span>
-<span class="line"><span style="color:#6A737D">/// special handling, since they have no place of origin.</span></span>
-<span class="line"><span style="color:#D73A49">struct</span><span style="color:#6F42C1"> PrimitiveTypeTable</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#24292E"> primitive_types</span><span style="color:#D73A49">:</span><span style="color:#6F42C1"> FxHashMap</span><span style="color:#24292E">&#x3C;</span><span style="color:#6F42C1">Symbol</span><span style="color:#24292E">, </span><span style="color:#6F42C1">PrimTy</span><span style="color:#24292E">>,</span></span>
-<span class="line"><span style="color:#24292E">}</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">impl</span><span style="color:#6F42C1"> PrimitiveTypeTable</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#D73A49"> fn</span><span style="color:#6F42C1"> new</span><span style="color:#24292E">() </span><span style="color:#D73A49">-></span><span style="color:#6F42C1"> PrimitiveTypeTable</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#D73A49"> let</span><span style="color:#D73A49"> mut</span><span style="color:#24292E"> table </span><span style="color:#D73A49">=</span><span style="color:#6F42C1"> FxHashMap</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">default</span><span style="color:#24292E">();</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E"> table</span><span style="color:#D73A49">.</span><span style="color:#6F42C1">insert</span><span style="color:#24292E">(</span><span style="color:#6F42C1">sym</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">bool</span><span style="color:#24292E">, </span><span style="color:#6F42C1">Bool</span><span style="color:#24292E">);</span></span>
-<span class="line"><span style="color:#24292E"> table</span><span style="color:#D73A49">.</span><span style="color:#6F42C1">insert</span><span style="color:#24292E">(</span><span style="color:#6F42C1">sym</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">char</span><span style="color:#24292E">, </span><span style="color:#6F42C1">Char</span><span style="color:#24292E">);</span></span>
-<span class="line"><span style="color:#24292E"> table</span><span style="color:#D73A49">.</span><span style="color:#6F42C1">insert</span><span style="color:#24292E">(</span><span style="color:#6F42C1">sym</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">f32</span><span style="color:#24292E">, </span><span style="color:#6F42C1">Float</span><span style="color:#24292E">(</span><span style="color:#6F42C1">FloatTy</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">F32</span><span style="color:#24292E">));</span></span>
-<span class="line"><span style="color:#24292E"> table</span><span style="color:#D73A49">.</span><span style="color:#6F42C1">insert</span><span style="color:#24292E">(</span><span style="color:#6F42C1">sym</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">f64</span><span style="color:#24292E">, </span><span style="color:#6F42C1">Float</span><span style="color:#24292E">(</span><span style="color:#6F42C1">FloatTy</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">F64</span><span style="color:#24292E">));</span></span>
-<span class="line"><span style="color:#24292E"> table</span><span style="color:#D73A49">.</span><span style="color:#6F42C1">insert</span><span style="color:#24292E">(</span><span style="color:#6F42C1">sym</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">isize</span><span style="color:#24292E">, </span><span style="color:#6F42C1">Int</span><span style="color:#24292E">(</span><span style="color:#6F42C1">IntTy</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">Isize</span><span style="color:#24292E">));</span></span>
-<span class="line"><span style="color:#24292E"> table</span><span style="color:#D73A49">.</span><span style="color:#6F42C1">insert</span><span style="color:#24292E">(</span><span style="color:#6F42C1">sym</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">i8</span><span style="color:#24292E">, </span><span style="color:#6F42C1">Int</span><span style="color:#24292E">(</span><span style="color:#6F42C1">IntTy</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">I8</span><span style="color:#24292E">));</span></span>
-<span class="line"><span style="color:#24292E"> table</span><span style="color:#D73A49">.</span><span style="color:#6F42C1">insert</span><span style="color:#24292E">(</span><span style="color:#6F42C1">sym</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">i16</span><span style="color:#24292E">, </span><span style="color:#6F42C1">Int</span><span style="color:#24292E">(</span><span style="color:#6F42C1">IntTy</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">I16</span><span style="color:#24292E">));</span></span>
-<span class="line"><span style="color:#24292E"> table</span><span style="color:#D73A49">.</span><span style="color:#6F42C1">insert</span><span style="color:#24292E">(</span><span style="color:#6F42C1">sym</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">i32</span><span style="color:#24292E">, </span><span style="color:#6F42C1">Int</span><span style="color:#24292E">(</span><span style="color:#6F42C1">IntTy</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">I32</span><span style="color:#24292E">));</span></span>
-<span class="line"><span style="color:#24292E"> table</span><span style="color:#D73A49">.</span><span style="color:#6F42C1">insert</span><span style="color:#24292E">(</span><span style="color:#6F42C1">sym</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">i64</span><span style="color:#24292E">, </span><span style="color:#6F42C1">Int</span><span style="color:#24292E">(</span><span style="color:#6F42C1">IntTy</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">I64</span><span style="color:#24292E">));</span></span>
-<span class="line"><span style="color:#24292E"> table</span><span style="color:#D73A49">.</span><span style="color:#6F42C1">insert</span><span style="color:#24292E">(</span><span style="color:#6F42C1">sym</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">i128</span><span style="color:#24292E">, </span><span style="color:#6F42C1">Int</span><span style="color:#24292E">(</span><span style="color:#6F42C1">IntTy</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">I128</span><span style="color:#24292E">));</span></span>
-<span class="line"><span style="color:#24292E"> table</span><span style="color:#D73A49">.</span><span style="color:#6F42C1">insert</span><span style="color:#24292E">(</span><span style="color:#6F42C1">sym</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">str</span><span style="color:#24292E">, </span><span style="color:#6F42C1">Str</span><span style="color:#24292E">);</span></span>
-<span class="line"><span style="color:#24292E"> table</span><span style="color:#D73A49">.</span><span style="color:#6F42C1">insert</span><span style="color:#24292E">(</span><span style="color:#6F42C1">sym</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">usize</span><span style="color:#24292E">, </span><span style="color:#6F42C1">Uint</span><span style="color:#24292E">(</span><span style="color:#6F42C1">UintTy</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">Usize</span><span style="color:#24292E">));</span></span>
-<span class="line"><span style="color:#24292E"> table</span><span style="color:#D73A49">.</span><span style="color:#6F42C1">insert</span><span style="color:#24292E">(</span><span style="color:#6F42C1">sym</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">u8</span><span style="color:#24292E">, </span><span style="color:#6F42C1">Uint</span><span style="color:#24292E">(</span><span style="color:#6F42C1">UintTy</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">U8</span><span style="color:#24292E">));</span></span>
-<span class="line"><span style="color:#24292E"> table</span><span style="color:#D73A49">.</span><span style="color:#6F42C1">insert</span><span style="color:#24292E">(</span><span style="color:#6F42C1">sym</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">u16</span><span style="color:#24292E">, </span><span style="color:#6F42C1">Uint</span><span style="color:#24292E">(</span><span style="color:#6F42C1">UintTy</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">U16</span><span style="color:#24292E">));</span></span>
-<span class="line"><span style="color:#24292E"> table</span><span style="color:#D73A49">.</span><span style="color:#6F42C1">insert</span><span style="color:#24292E">(</span><span style="color:#6F42C1">sym</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">u32</span><span style="color:#24292E">, </span><span style="color:#6F42C1">Uint</span><span style="color:#24292E">(</span><span style="color:#6F42C1">UintTy</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">U32</span><span style="color:#24292E">));</span></span>
-<span class="line"><span style="color:#24292E"> table</span><span style="color:#D73A49">.</span><span style="color:#6F42C1">insert</span><span style="color:#24292E">(</span><span style="color:#6F42C1">sym</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">u64</span><span style="color:#24292E">, </span><span style="color:#6F42C1">Uint</span><span style="color:#24292E">(</span><span style="color:#6F42C1">UintTy</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">U64</span><span style="color:#24292E">));</span></span>
-<span class="line"><span style="color:#24292E"> table</span><span style="color:#D73A49">.</span><span style="color:#6F42C1">insert</span><span style="color:#24292E">(</span><span style="color:#6F42C1">sym</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">u128</span><span style="color:#24292E">, </span><span style="color:#6F42C1">Uint</span><span style="color:#24292E">(</span><span style="color:#6F42C1">UintTy</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">U128</span><span style="color:#24292E">));</span></span>
-<span class="line"><span style="color:#005CC5"> Self</span><span style="color:#24292E"> { primitive_types</span><span style="color:#D73A49">:</span><span style="color:#24292E"> table }</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#24292E">}</span></span></code></pre>
- </div>
- <p>
- これは初めに列挙したプリミティブ型の一覧と一致している。doc comment にも、
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>All other types are defined somewhere and possibly imported, but the</span></span>
-<span class="line"><span>primitive ones need special handling, since they have no place of</span></span>
-<span class="line"><span>origin.</span></span></code></pre>
- </div>
- <p>
- とある。次はこの struct の使用箇所を追う。追うと言っても使われている箇所は次の一箇所しかない。なお説明に不要な箇所は大きく削っている。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6A737D">/// This resolves the identifier `ident` in the namespace `ns` in the current lexical scope.</span></span>
-<span class="line"><span style="color:#6A737D">/// (略)</span></span>
-<span class="line"><span style="color:#D73A49">fn</span><span style="color:#6F42C1"> resolve_ident_in_lexical_scope</span><span style="color:#24292E">(</span></span>
-<span class="line"><span style="color:#D73A49"> &#x26;mut</span><span style="color:#005CC5"> self</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#D73A49"> mut</span><span style="color:#24292E"> ident</span><span style="color:#D73A49">:</span><span style="color:#6F42C1"> Ident</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#24292E"> ns</span><span style="color:#D73A49">:</span><span style="color:#6F42C1"> Namespace</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#6A737D"> // (略)</span></span>
-<span class="line"><span style="color:#24292E">) </span><span style="color:#D73A49">-></span><span style="color:#6F42C1"> Option</span><span style="color:#24292E">&#x3C;</span><span style="color:#6F42C1">LexicalScopeBinding</span><span style="color:#24292E">&#x3C;'</span><span style="color:#6F42C1">a</span><span style="color:#24292E">>> {</span></span>
-<span class="line"><span style="color:#6A737D"> // (略)</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> ns </span><span style="color:#D73A49">==</span><span style="color:#6F42C1"> TypeNS</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#D73A49"> let</span><span style="color:#6F42C1"> Some</span><span style="color:#24292E">(prim_ty) </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> self</span><span style="color:#D73A49">.</span><span style="color:#24292E">primitive_type_table</span><span style="color:#D73A49">.</span><span style="color:#24292E">primitive_types</span><span style="color:#D73A49">.</span><span style="color:#6F42C1">get</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">ident</span><span style="color:#D73A49">.</span><span style="color:#24292E">name) {</span></span>
-<span class="line"><span style="color:#D73A49"> let</span><span style="color:#24292E"> binding </span><span style="color:#D73A49">=</span></span>
-<span class="line"><span style="color:#24292E"> (</span><span style="color:#6F42C1">Res</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">PrimTy</span><span style="color:#24292E">(</span><span style="color:#D73A49">*</span><span style="color:#24292E">prim_ty), </span><span style="color:#6F42C1">ty</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">Visibility</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">Public</span><span style="color:#24292E">, </span><span style="color:#005CC5">DUMMY_SP</span><span style="color:#24292E">, </span><span style="color:#6F42C1">ExpnId</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">root</span><span style="color:#24292E">())</span></span>
-<span class="line"><span style="color:#D73A49"> .</span><span style="color:#6F42C1">to_name_binding</span><span style="color:#24292E">(</span><span style="color:#005CC5">self</span><span style="color:#D73A49">.</span><span style="color:#24292E">arenas);</span></span>
-<span class="line"><span style="color:#D73A49"> return</span><span style="color:#6F42C1"> Some</span><span style="color:#24292E">(</span><span style="color:#6F42C1">LexicalScopeBinding</span><span style="color:#D73A49">::</span><span style="color:#6F42C1">Item</span><span style="color:#24292E">(binding));</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#6F42C1"> None</span></span>
-<span class="line"><span style="color:#24292E">}</span></span></code></pre>
- </div>
- <p>
- 関数名や doc comment が示している通り、この関数は識別子 (identifier, ident) を現在のレキシカルスコープ内で解決 (resolve) する。<code>if ns == TypeNS</code> のブロック内では、<code>primitive_type_table</code> (上記の <code>PrimitiveTypeTable::new()</code> で作られた変数) に含まれている識別子 (<code>bool</code>、<code>i32</code> など) かどうか判定し、そうであればそれに紐づけられたプリミティブ型を返している。
- </p>
- <p>
- なお、<code>ns</code> は「名前空間」を示す変数である。Rust における名前空間はC言語におけるそれとほとんど同じで、今探している名前が関数名/変数名なのか型なのかマクロなのかを区別している。この <code>if</code> は、プリミティブ型に解決されるのは型を探しているときだけだ、と言っている。
- </p>
- <p>
- 重要なのは、これが <code>resolve_ident_in_lexical_scope()</code> の最後に書かれている点である。つまり、最初に挙げたプリミティブ型の識別子は、「名前解決の最終段階で」、「他に同名の型が見つかっていなければ」プリミティブ型として解決される。
- </p>
- <p>
- 動作がわかったところで、例として次のコードを考える。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">#![allow(non_camel_case_types)]</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">struct</span><span style="color:#6F42C1"> bool</span><span style="color:#24292E">;</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">fn</span><span style="color:#6F42C1"> main</span><span style="color:#24292E">() {</span></span>
-<span class="line"><span style="color:#D73A49"> let</span><span style="color:#24292E"> _</span><span style="color:#D73A49">:</span><span style="color:#6F42C1"> bool</span><span style="color:#D73A49"> =</span><span style="color:#6F42C1"> bool</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">}</span></span></code></pre>
- </div>
- <p>
- ここで <code>main()</code> の <code>bool</code> は <code>struct bool</code> として解決される。なぜなら、プリミティブ型の判定をする前に <code>bool</code> という名前の別の型が見つかるからだ。
- </p>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">まとめ</a></h2>
- <p>
- Rust のプリミティブ型は予約語ではない。名前解決の最終段階で特別扱いされ、他に同名の型が見つかっていなければ対応するプリミティブ型に解決される。
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2021-10-02/vim-difference-between-autocmd-bufwrite-and-bufwritepre/index.html b/vhosts/blog/public/posts/2021-10-02/vim-difference-between-autocmd-bufwrite-and-bufwritepre/index.html
deleted file mode 100644
index b053944a..00000000
--- a/vhosts/blog/public/posts/2021-10-02/vim-difference-between-autocmd-bufwrite-and-bufwritepre/index.html
+++ /dev/null
@@ -1,234 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2021 nsfisis">
- <meta name="description" content="Vim の autocmd events における BufWrite/BufWritePre がどう違うのかを調べた結果、違いはないことがわかった。">
- <meta name="keywords" content="Vim">
- <meta property="og:type" content="article">
- <meta property="og:title" content="【Vim】 autocmd events の BufWrite/BufWritePre の違い|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="Vim の autocmd events における BufWrite/BufWritePre がどう違うのかを調べた結果、違いはないことがわかった。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>【Vim】 autocmd events の BufWrite/BufWritePre の違い|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">【Vim】 autocmd events の BufWrite/BufWritePre の違い</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/vim/">Vim</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2021-10-02">2021-10-02</time>: Qiita から移植
- </li>
- </ol>
- </section>
- <div class="admonition">
- <div class="admonition-label">
- NOTE
- </div>
- <div class="admonition-content">
- <p>
- この記事は Qiita から移植してきたものです。元 URL: <a href="https://qiita.com/nsfisis/items/79ab4db8564032de0b25" rel="noreferrer" target="_blank">https://qiita.com/nsfisis/items/79ab4db8564032de0b25</a>
- </p>
- </div>
- </div>
- <section id="section--tl-dr">
- <h2><a href="#section--tl-dr">TL; DR</a></h2>
- <p>
- 違いはない。ただのエイリアス。
- </p>
- </section>
- <section id="section--code-reading">
- <h2><a href="#section--code-reading">調査記録</a></h2>
- <p>
- Vim の autocmd events には似通った名前のものがいくつかある。大抵は <code>:help</code> に説明があるが、この記事のタイトルにある2つを含めた以下のイベントには、その違いについて説明がない。
- </p>
- <ul>
- <li>
- <code>BufRead</code>/<code>BufReadPost</code>
- </li>
- <li>
- <code>BufWrite</code>/<code>BufWritePre</code>
- </li>
- <li>
- <code>BufAdd</code>/<code>BufCreate</code>
- </li>
- </ul>
- <p>
- このうち、<code>BufAdd</code>/<code>BufCreate</code> に関しては、<code>:help BufCreate</code> に
- </p>
- <blockquote>
- <p>
- The BufCreate event is for historic reasons.
- </p>
- </blockquote>
- <p>
- とあり、おそらくは <code>BufAdd</code> のエイリアスであろうということがわかる。他の2組も同様ではないかと予想されるが、確認のため vim と neovim のソースコードを調査した。
- </p>
- <p>
- ソースコードへのリンク
- </p>
- <ul>
- <li>
- <a href="https://github.com/vim/vim/tree/8e6be34338f13a6a625f19bcef82019c9adc65f2" rel="noreferrer" target="_blank">vim (調査時点での master branch)</a>
- </li>
- <li>
- <a href="https://github.com/neovim/neovim/tree/71d4f5851f068eeb432af34850dddda8cc1c71e3" rel="noreferrer" target="_blank">neovim (上に同じ)</a>
- </li>
- </ul>
- <section id="section--code-reading--vim">
- <h3><a href="#section--code-reading--vim">vim のソースコード</a></h3>
- <p>
- 以下は、autocmd events の名前と内部で使われている整数値とのマッピングを定義している箇所である。見ての通り、上でエイリアスではないかと述べた3組には、それぞれ同じ内部値が使われている。
- </p>
- <p>
- <a href="https://github.com/vim/vim/blob/8e6be34338f13a6a625f19bcef82019c9adc65f2/src/autocmd.c#L85-L86" rel="noreferrer" target="_blank">https://github.com/vim/vim/blob/8e6be34338f13a6a625f19bcef82019c9adc65f2/src/autocmd.c#L85-L86</a>
- </p>
- <div class="codeblock">
- <div class="filename">
- src/autocmd.c
- </div>
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">{</span><span style="color:#032F62">"BufAdd"</span><span style="color:#24292E">, EVENT_BUFADD},</span></span>
-<span class="line"><span style="color:#24292E">{</span><span style="color:#032F62">"BufCreate"</span><span style="color:#24292E">, EVENT_BUFADD},</span></span></code></pre>
- </div>
- <p>
- <a href="https://github.com/vim/vim/blob/8e6be34338f13a6a625f19bcef82019c9adc65f2/src/autocmd.c#L95-L97" rel="noreferrer" target="_blank">https://github.com/vim/vim/blob/8e6be34338f13a6a625f19bcef82019c9adc65f2/src/autocmd.c#L95-L97</a>
- </p>
- <div class="codeblock">
- <div class="filename">
- src/autocmd.c
- </div>
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">{</span><span style="color:#032F62">"BufRead"</span><span style="color:#24292E">, EVENT_BUFREADPOST},</span></span>
-<span class="line"><span style="color:#24292E">{</span><span style="color:#032F62">"BufReadCmd"</span><span style="color:#24292E">, EVENT_BUFREADCMD},</span></span>
-<span class="line"><span style="color:#24292E">{</span><span style="color:#032F62">"BufReadPost"</span><span style="color:#24292E">, EVENT_BUFREADPOST},</span></span></code></pre>
- </div>
- <p>
- <a href="https://github.com/vim/vim/blob/8e6be34338f13a6a625f19bcef82019c9adc65f2/src/autocmd.c#L103-L105" rel="noreferrer" target="_blank">https://github.com/vim/vim/blob/8e6be34338f13a6a625f19bcef82019c9adc65f2/src/autocmd.c#L103-L105</a>
- </p>
- <div class="codeblock">
- <div class="filename">
- src/autocmd.c
- </div>
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">{</span><span style="color:#032F62">"BufWrite"</span><span style="color:#24292E">, EVENT_BUFWRITEPRE},</span></span>
-<span class="line"><span style="color:#24292E">{</span><span style="color:#032F62">"BufWritePost"</span><span style="color:#24292E">, EVENT_BUFWRITEPOST},</span></span>
-<span class="line"><span style="color:#24292E">{</span><span style="color:#032F62">"BufWritePre"</span><span style="color:#24292E">, EVENT_BUFWRITEPRE},</span></span></code></pre>
- </div>
- </section>
- <section id="section--code-reading--neovim">
- <h3><a href="#section--code-reading--neovim">neovim のソースコード</a></h3>
- <p>
- neovim の場合でも同様のマッピングが定義されているが、こちらの場合は Lua で書かれている。以下にある通り、はっきり <code>aliases</code> と書かれている。
- </p>
- <p>
- <a href="https://github.com/neovim/neovim/blob/71d4f5851f068eeb432af34850dddda8cc1c71e3/src/nvim/auevents.lua#L119-L124" rel="noreferrer" target="_blank">https://github.com/neovim/neovim/blob/71d4f5851f068eeb432af34850dddda8cc1c71e3/src/nvim/auevents.lua#L119-L124</a>
- </p>
- <div class="codeblock">
- <div class="filename">
- src/nvim/auevents.lua
- </div>
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">aliases </span><span style="color:#D73A49">=</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#24292E"> BufCreate </span><span style="color:#D73A49">=</span><span style="color:#032F62"> 'BufAdd'</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#24292E"> BufRead </span><span style="color:#D73A49">=</span><span style="color:#032F62"> 'BufReadPost'</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#24292E"> BufWrite </span><span style="color:#D73A49">=</span><span style="color:#032F62"> 'BufWritePre'</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#24292E"> FileEncoding </span><span style="color:#D73A49">=</span><span style="color:#032F62"> 'EncodingChanged'</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#24292E">},</span></span></code></pre>
- </div>
- <p>
- ところで、上では取り上げなかった <code>FileEncoding</code> だが、これは <code>:help FileEncoding</code> にしっかりと書いてある。
- </p>
- <div class="codeblock">
- <div class="filename">
- :help FileEncoding
- </div>
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span> *FileEncoding*</span></span>
-<span class="line"><span>FileEncoding Obsolete. It still works and is equivalent</span></span>
-<span class="line"><span> to |EncodingChanged|.</span></span></code></pre>
- </div>
- </section>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">まとめ</a></h2>
- <p>
- 記事タイトルについて言えば、どちらも変わらないので好きな方を使えばよい。あえて言えば、次のようになるだろう。
- </p>
- <ul>
- <li>
- <code>BufAdd</code>/<code>BufCreate</code>
- <ul>
- <li>
- → <code>BufCreate</code> は歴史的な理由により (“for historic reasons”) 存在しているため、新しい方 (<code>BufAdd</code>) を使う
- </li>
- </ul>
- </li>
- <li>
- <code>BufRead</code>/<code>BufReadPost</code>
- <ul>
- <li>
- → <code>BufReadPre</code> との対称性のため、あるいは <code>BufWritePost</code> との対称性のため <code>BufReadPost</code> を使う
- </li>
- </ul>
- </li>
- <li>
- <code>BufWrite</code>/<code>BufWritePre</code>
- <ul>
- <li>
- → <code>BufWritePost</code> との対称性のため、あるいは <code>BufReadPre</code> との対称性のため <code>BufWritePre</code> を使う
- </li>
- </ul>
- </li>
- <li>
- <code>FileEncoding</code>/<code>EncodingChanged</code>
- <ul>
- <li>
- → <code>FileEncoding</code> は “Obsolete” と明言されているので、<code>EncodingChanged</code> を使う
- </li>
- </ul>
- </li>
- </ul>
- <p>
- ところでこの調査で知ったのだが、<code>BufRead</code> と <code>BufWrite</code> は上にある通り発火するタイミングが「後」と「前」で対称性がない。可能なら <code>Pre</code>/<code>Post</code> 付きのものを使った方が分かりやすいだろう。
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2021-10-02/vim-swap-order-of-selected-lines/index.html b/vhosts/blog/public/posts/2021-10-02/vim-swap-order-of-selected-lines/index.html
deleted file mode 100644
index fcdbec23..00000000
--- a/vhosts/blog/public/posts/2021-10-02/vim-swap-order-of-selected-lines/index.html
+++ /dev/null
@@ -1,244 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2021 nsfisis">
- <meta name="description" content="Vim で選択した行の順番を入れ替える方法。">
- <meta name="keywords" content="Vim">
- <meta property="og:type" content="article">
- <meta property="og:title" content="Vimで選択した行の順番を入れ替える|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="Vim で選択した行の順番を入れ替える方法。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>Vimで選択した行の順番を入れ替える|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">Vimで選択した行の順番を入れ替える</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/vim/">Vim</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2021-10-02">2021-10-02</time>: Qiita から移植
- </li>
- </ol>
- </section>
- <div class="admonition">
- <div class="admonition-label">
- NOTE
- </div>
- <div class="admonition-content">
- <p>
- この記事は Qiita から移植してきたものです。元 URL: <a href="https://qiita.com/nsfisis/items/4fefb361d9a693803520" rel="noreferrer" target="_blank">https://qiita.com/nsfisis/items/4fefb361d9a693803520</a>
- </p>
- </div>
- </div>
- <section id="section--tl-dr">
- <h2><a href="#section--tl-dr">TL; DR</a></h2>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6A737D">" License: Public Domain</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">command!</span><span style="color:#24292E"> -bar -</span><span style="color:#D73A49">range=</span><span style="color:#24292E">%</span></span>
-<span class="line"><span style="color:#D73A49"> \</span><span style="color:#24292E"> Reverse</span></span>
-<span class="line"><span style="color:#D73A49"> \</span><span style="color:#24292E"> keeppatterns &#x3C;line1>,&#x3C;line2>g</span><span style="color:#032F62">/^/</span><span style="color:#24292E">m&#x3C;line1>-</span><span style="color:#005CC5">1</span></span></code></pre>
- </div>
- </section>
- <section id="section--version">
- <h2><a href="#section--version">バージョン情報</a></h2>
- <p>
- <code>:version</code> の一部
- </p>
- <blockquote>
- <p>
- VIM - Vi IMproved 8.2 (2019 Dec 12, compiled Jan 26 2020 11:30:30) macOS version Included patches: 1-148 Huge version without GUI.
- </p>
- </blockquote>
- </section>
- <section id="section--existing-solution">
- <h2><a href="#section--existing-solution">よく紹介されている手法</a></h2>
- <section id="section--existing-solution--external-commands">
- <h3><a href="#section--existing-solution--external-commands"><code>tac</code> / <code>tail</code></a></h3>
- <p>
- <code>tac</code> や <code>tail -r</code> などの外部コマンドを <code>!</code> を使って呼び出し、置き換える。
- </p>
- <blockquote>
- <p>
- :h v_!
- </p>
- </blockquote>
- <p>
- <code>tac</code> コマンドや <code>tail</code> の <code>-r</code> オプションは環境によって利用できないことがあり、複数の環境を行き来する場合に採用しづらい
- </p>
- </section>
- <section id="section--existing-solution--global-command">
- <h3><a href="#section--existing-solution--global-command"><code>:g/^/m0</code></a></h3>
- <p>
- こちらは外部コマンドに頼らず、Vim の機能のみを使う。<code>g</code> は <code>:global</code> コマンドの、<code>m</code> は <code>:move</code> コマンドの略
- </p>
- <p>
- <code>:global</code> コマンドは <code>:[range]global/{pattern}/[command]</code> のように使い、<code>[range]</code> で指定された範囲の行のうち、<code>{pattern}</code> で指定された検索パターンにマッチする行に対して、順番に <code>[command]</code> で指定された Ex コマンドを呼び出す。
- </p>
- <blockquote>
- <p>
- :h :global
- </p>
- </blockquote>
- <p>
- <code>:move</code> コマンドは <code>[range]:move {address}</code> のように使い、<code>[range]</code> で指定された範囲の行を <code>{address}</code> で指定された位置に移動させる。
- </p>
- <blockquote>
- <p>
- :h :move
- </p>
- </blockquote>
- <p>
- <code>:g/^/m0</code> のように組み合わせると、「すべての行を1行ずつ 0行目(1行目の上)に動かす」という動きをする。これは確かに行の入れ替えになっている。
- </p>
- <p>
- なお、<code>:g/^/m0</code> は全ての行を入れ替えるが、<code>:N,Mg/^/mN-1</code> とすることで N行目から M行目を処理範囲とするよう拡張できる。手でこれを入力するわけにはいかないので、次のようなコマンドを用意する。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">command!</span><span style="color:#24292E"> -bar -</span><span style="color:#D73A49">range=</span><span style="color:#24292E">%</span></span>
-<span class="line"><span style="color:#D73A49"> \</span><span style="color:#24292E"> Reverse</span></span>
-<span class="line"><span style="color:#D73A49"> \</span><span style="color:#24292E"> &#x3C;line1>,&#x3C;line2>g</span><span style="color:#032F62">/^/</span><span style="color:#24292E">m&#x3C;line1>-</span><span style="color:#005CC5">1</span></span></code></pre>
- </div>
- <p>
- これは望みの動作をするが、実際に実行してみると全行がハイライトされてしまう。次節で詳細を述べる。
- </p>
- </section>
- </section>
- <section id="section--problem-of-global-command">
- <h2><a href="#section--problem-of-global-command"><code>:g/^/m0</code> の問題点</a></h2>
- <p>
- <code>:global</code> コマンドは各行に対してマッチングを行う際、現在の検索パターンを上書きしてしまう。<code>^</code> は行の先頭にマッチするため、結果として全ての行がハイライトされてしまう。<code>&apos;hlsearch&apos;</code> オプションを無効にしている場合その限りではないが、その場合でも直前の検索パターンが失われてしまうと <code>n</code> コマンドなどの際に不便である。
- </p>
- <blockquote>
- <p>
- :h @/
- </p>
- </blockquote>
- </section>
- <section id="section--solution">
- <h2><a href="#section--solution">解決策</a></h2>
- <div class="admonition" editat="2020-09-28" operation="追記">
- <div class="admonition-label">
- 2020-09-28 追記
- </div>
- <div class="admonition-content">
- <p>
- より簡潔な方法を見つけたので次節に追記した。
- </p>
- </div>
- </div>
- <p>
- 前述した <code>:Reverse</code> コマンドの定義を少し変えて、次のようにする:
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">function!</span><span style="color:#6F42C1"> s:reverse_lines</span><span style="color:#24292E">(from, </span><span style="color:#005CC5">to</span><span style="color:#24292E">) </span><span style="color:#D73A49">abort</span></span>
-<span class="line"><span style="color:#005CC5"> execute</span><span style="color:#6F42C1"> printf</span><span style="color:#24292E">(</span><span style="color:#032F62">"%d,%dg/^/m%d"</span><span style="color:#24292E">, a:from, a:to, a:from</span><span style="color:#D73A49"> - </span><span style="color:#005CC5">1</span><span style="color:#24292E">)</span></span>
-<span class="line"><span style="color:#D73A49">endfunction</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">command!</span><span style="color:#24292E"> -bar -</span><span style="color:#D73A49">range=</span><span style="color:#24292E">%</span></span>
-<span class="line"><span style="color:#D73A49"> \</span><span style="color:#24292E"> Reverse</span></span>
-<span class="line"><span style="color:#D73A49"> \</span><span style="color:#D73A49"> call</span><span style="color:#24292E"> &#x3C;</span><span style="color:#005CC5">SID</span><span style="color:#24292E">></span><span style="color:#6F42C1">reverse_lines</span><span style="color:#24292E">(&#x3C;line1>, &#x3C;line2>)</span></span></code></pre>
- </div>
- <p>
- 実行しているコマンドが変わったわけではないが、関数呼び出しを経由するようにした。これだけで前述の問題が解決する。
- </p>
- <p>
- この理由は、ユーザー定義関数を実行する際は検索パターンが一度保存され、実行が終了したあと復元されるため。結果として検索パターンが <code>^</code> で上書きされることがなくなる。
- </p>
- <p>
- Vim のヘルプから該当箇所を引用する (強調は筆者による)。
- </p>
- <blockquote>
- <p>
- :h autocmd-searchpat
- </p>
- <p>
- <strong>Autocommands do not change the current search patterns.</strong> Vim saves the current search patterns before executing autocommands then restores them after the autocommands finish. This means that autocommands do not affect the strings highlighted with the ‘hlsearch’ option.
- </p>
- </blockquote>
- <p>
- これは autocommand の実行に関しての記述だが、これと同じことがユーザー定義関数の実行時にも適用される。このことは <code>:nohlsearch</code> のヘルプにある。同じく該当箇所を引用する (強調は筆者による)。
- </p>
- <blockquote>
- <p>
- :h :nohlsearch
- </p>
- <p>
- (略) This command doesn’t work in an autocommand, because the highlighting state is saved and restored when executing autocommands |autocmd-searchpat|. <strong>Same thing for when invoking a user function.</strong>
- </p>
- </blockquote>
- <p>
- この仕様により、<code>:g/^/m0</code> の呼び出しをユーザー定義関数に切り出すことで上述の問題を解決できる。
- </p>
- </section>
- <section id="section--solution-revised">
- <h2><a href="#section--solution-revised">解決策 (改訂版)</a></h2>
- <div class="admonition" editat="2020-09-28" operation="追記">
- <div class="admonition-label">
- 2020-09-28 追記
- </div>
- <div class="admonition-content">
- <p>
- より簡潔な方法を見つけたため追記する。
- </p>
- </div>
- </div>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">command!</span><span style="color:#24292E"> -bar -</span><span style="color:#D73A49">range=</span><span style="color:#24292E">%</span></span>
-<span class="line"><span style="color:#D73A49"> \</span><span style="color:#24292E"> Reverse</span></span>
-<span class="line"><span style="color:#D73A49"> \</span><span style="color:#24292E"> keeppatterns &#x3C;line1>,&#x3C;line2>g</span><span style="color:#032F62">/^/</span><span style="color:#24292E">m&#x3C;line1>-</span><span style="color:#005CC5">1</span></span></code></pre>
- </div>
- <p>
- まさにこのための Exコマンド、<code>:keeppatterns</code> が存在する。<code>:keeppatterns {command}</code> のように使い、読んで字の如く、後ろに続く Exコマンドを「現在の検索パターンを保ったまま」実行する。はるかに分かりやすく意図を表現できる。
- </p>
- <blockquote>
- <p>
- :h :keeppatterns
- </p>
- </blockquote>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2022-04-09/phperkaigi-2022-tokens/index.html b/vhosts/blog/public/posts/2022-04-09/phperkaigi-2022-tokens/index.html
deleted file mode 100644
index ee215a60..00000000
--- a/vhosts/blog/public/posts/2022-04-09/phperkaigi-2022-tokens/index.html
+++ /dev/null
@@ -1,572 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2022 nsfisis">
- <meta name="description" content="PHPerKaigi 2022 で私が作成した PHPer チャレンジ問題を解説する。">
- <meta name="keywords" content="カンファレンス,PHP,PHPerKaigi">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHPerKaigi 2022 トークン問題の解説|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="PHPerKaigi 2022 で私が作成した PHPer チャレンジ問題を解説する。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHPerKaigi 2022 トークン問題の解説|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">PHPerKaigi 2022 トークン問題の解説</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/conference/">カンファレンス</a>
- </li>
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phperkaigi/">PHPerKaigi</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2022-04-09">2022-04-09</time>: 公開
- </li>
- <li class="revision">
- <time datetime="2022-04-16">2022-04-16</time>: 2問目、3問目の解説を追加、1問目に加筆
- </li>
- </ol>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- 本日開始された <a href="https://phperkaigi.jp/2022/" rel="noreferrer" target="_blank">PHPerKaigi 2022</a> の PHPer チャレンジにおいて、弊社 <a href="https://www.dgcircus.com/" rel="noreferrer" target="_blank">デジタルサーカス株式会社</a> の問題を 3問作成した。この記事では、これらの問題の解説をおこなう。
- </p>
- <p>
- リポジトリはこちら: <a href="https://github.com/nsfisis/PHPerKaigi2022-tokens" rel="noreferrer" target="_blank">https://github.com/nsfisis/PHPerKaigi2022-tokens</a>
- </p>
- </section>
- <section id="section--q1-brainfuck">
- <h2><a href="#section--q1-brainfuck">第1問 brainf_ck.php</a></h2>
- <p>
- ソースコードはこちら。実行には PHP 8.1 以上が必要なので注意。
- </p>
- <div class="codeblock">
- <div class="filename">
- brainf_ck.php
- </div>
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">declare</span><span style="color:#24292E">(</span><span style="color:#005CC5">strict_types</span><span style="color:#D73A49">=</span><span style="color:#005CC5">0O1</span><span style="color:#24292E">);</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">namespace</span><span style="color:#6F42C1"> Dgcircus\PHPerKaigi\Y2022</span><span style="color:#24292E">;</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#6A737D">/**</span></span>
-<span class="line"><span style="color:#6A737D"> * </span><span style="color:#D73A49">@todo</span></span>
-<span class="line"><span style="color:#6A737D"> * Run this program to acquire a PHPer token.</span></span>
-<span class="line"><span style="color:#6A737D"> */</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#005CC5">https</span><span style="color:#D73A49">:</span><span style="color:#6A737D">//creativecommons.org/publicdomain/zero/1.0/</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#005CC5">\error_reporting</span><span style="color:#24292E">(</span><span style="color:#D73A49">~+!</span><span style="color:#032F62">'We are hiring!'</span><span style="color:#24292E">);</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E">$z </span><span style="color:#D73A49">=</span><span style="color:#D73A49"> fn</span><span style="color:#24292E">($f) => (</span><span style="color:#D73A49">fn</span><span style="color:#24292E">($x) => $f(</span><span style="color:#D73A49">fn</span><span style="color:#24292E">(</span><span style="color:#D73A49">...</span><span style="color:#24292E">$xs) => $x($x)(</span><span style="color:#D73A49">...</span><span style="color:#24292E">$xs)))(</span><span style="color:#D73A49">fn</span><span style="color:#24292E">($x) => $f(</span><span style="color:#D73A49">fn</span><span style="color:#24292E">(</span><span style="color:#D73A49">...</span><span style="color:#24292E">$xs) => $x($x)(</span><span style="color:#D73A49">...</span><span style="color:#24292E">$xs)));</span></span>
-<span class="line"><span style="color:#24292E">$id </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> \</span><span style="color:#6F42C1">spl_object_id</span><span style="color:#24292E">(</span><span style="color:#D73A49">...</span><span style="color:#24292E">);</span></span>
-<span class="line"><span style="color:#24292E">$put </span><span style="color:#D73A49">=</span><span style="color:#D73A49"> fn</span><span style="color:#24292E">($c) => </span><span style="color:#005CC5">\</span><span style="color:#005CC5">printf</span><span style="color:#24292E">(</span><span style="color:#032F62">'%c'</span><span style="color:#24292E">, $c);</span></span>
-<span class="line"><span style="color:#24292E">$mm </span><span style="color:#D73A49">=</span><span style="color:#D73A49"> fn</span><span style="color:#24292E">($p, $n) => </span><span style="color:#D73A49">new</span><span style="color:#005CC5"> \ArrayObject</span><span style="color:#24292E">(</span><span style="color:#005CC5">\array_fill</span><span style="color:#24292E">(</span><span style="color:#D73A49">+!!</span><span style="color:#24292E">[], $n, $p));</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E">$👉 </span><span style="color:#D73A49">=</span><span style="color:#D73A49"> fn</span><span style="color:#24292E">($m, $p, $b, $e, $mp, $pc) => [</span><span style="color:#D73A49">++</span><span style="color:#24292E">$mp, </span><span style="color:#D73A49">++</span><span style="color:#24292E">$pc];</span></span>
-<span class="line"><span style="color:#24292E">$👈 </span><span style="color:#D73A49">=</span><span style="color:#D73A49"> fn</span><span style="color:#24292E">($m, $p, $b, $e, $mp, $pc) => [</span><span style="color:#D73A49">--</span><span style="color:#24292E">$mp, </span><span style="color:#D73A49">++</span><span style="color:#24292E">$pc];</span></span>
-<span class="line"><span style="color:#24292E">$👍 </span><span style="color:#D73A49">=</span><span style="color:#D73A49"> fn</span><span style="color:#24292E">($m, $p, $b, $e, $mp, $pc) => [$mp, </span><span style="color:#D73A49">++</span><span style="color:#24292E">$pc, </span><span style="color:#D73A49">++</span><span style="color:#24292E">$m[$mp]];</span></span>
-<span class="line"><span style="color:#24292E">$👎 </span><span style="color:#D73A49">=</span><span style="color:#D73A49"> fn</span><span style="color:#24292E">($m, $p, $b, $e, $mp, $pc) => [$mp, </span><span style="color:#D73A49">++</span><span style="color:#24292E">$pc, </span><span style="color:#D73A49">--</span><span style="color:#24292E">$m[$mp]];</span></span>
-<span class="line"><span style="color:#24292E">$📝 </span><span style="color:#D73A49">=</span><span style="color:#D73A49"> fn</span><span style="color:#24292E">($m, $p, $b, $e, $mp, $pc) => [$mp, </span><span style="color:#D73A49">++</span><span style="color:#24292E">$pc, $put($m[$mp])];</span></span>
-<span class="line"><span style="color:#24292E">$🤡 </span><span style="color:#D73A49">=</span><span style="color:#D73A49"> fn</span><span style="color:#24292E">($m, $p, $b, $e, $mp, $pc) => </span><span style="color:#D73A49">match</span><span style="color:#24292E"> ($m[$mp]) {</span></span>
-<span class="line"><span style="color:#D73A49"> +!!</span><span style="color:#24292E">[] </span><span style="color:#D73A49">=></span><span style="color:#24292E"> [$mp, $z(</span><span style="color:#D73A49">fn</span><span style="color:#24292E">($loop) => </span><span style="color:#D73A49">fn</span><span style="color:#24292E">($pc, $n) => </span><span style="color:#D73A49">match</span><span style="color:#24292E"> ($id($p[$pc])) {</span></span>
-<span class="line"><span style="color:#24292E"> $b </span><span style="color:#D73A49">=></span><span style="color:#24292E"> $loop(</span><span style="color:#D73A49">++</span><span style="color:#24292E">$pc, </span><span style="color:#D73A49">++</span><span style="color:#24292E">$n),</span></span>
-<span class="line"><span style="color:#24292E"> $e </span><span style="color:#D73A49">=></span><span style="color:#24292E"> $n </span><span style="color:#D73A49">===</span><span style="color:#D73A49"> +!!</span><span style="color:#24292E">[] </span><span style="color:#D73A49">?</span><span style="color:#D73A49"> ++</span><span style="color:#24292E">$pc </span><span style="color:#D73A49">:</span><span style="color:#24292E"> $loop(</span><span style="color:#D73A49">++</span><span style="color:#24292E">$pc, </span><span style="color:#D73A49">--</span><span style="color:#24292E">$n),</span></span>
-<span class="line"><span style="color:#D73A49"> default</span><span style="color:#D73A49"> =></span><span style="color:#24292E"> $loop(</span><span style="color:#D73A49">++</span><span style="color:#24292E">$pc, $n),</span></span>
-<span class="line"><span style="color:#24292E"> })($pc, </span><span style="color:#D73A49">-!</span><span style="color:#24292E">[])],</span></span>
-<span class="line"><span style="color:#D73A49"> default</span><span style="color:#D73A49"> =></span><span style="color:#24292E"> [$mp, </span><span style="color:#D73A49">++</span><span style="color:#24292E">$pc],</span></span>
-<span class="line"><span style="color:#24292E">};</span></span>
-<span class="line"><span style="color:#24292E">$🎪 </span><span style="color:#D73A49">=</span><span style="color:#D73A49"> fn</span><span style="color:#24292E">($m, $p, $b, $e, $mp, $pc) => </span><span style="color:#D73A49">match</span><span style="color:#24292E"> ($m[$mp]) {</span></span>
-<span class="line"><span style="color:#D73A49"> +!!</span><span style="color:#24292E">[] </span><span style="color:#D73A49">=></span><span style="color:#24292E"> [$mp, </span><span style="color:#D73A49">++</span><span style="color:#24292E">$pc],</span></span>
-<span class="line"><span style="color:#D73A49"> default</span><span style="color:#D73A49"> =></span><span style="color:#24292E"> [$mp, $z(</span><span style="color:#D73A49">fn</span><span style="color:#24292E">($loop) => </span><span style="color:#D73A49">fn</span><span style="color:#24292E">($pc, $n) => </span><span style="color:#D73A49">match</span><span style="color:#24292E"> ($id($p[$pc])) {</span></span>
-<span class="line"><span style="color:#24292E"> $e </span><span style="color:#D73A49">=></span><span style="color:#24292E"> $loop(</span><span style="color:#D73A49">--</span><span style="color:#24292E">$pc, </span><span style="color:#D73A49">++</span><span style="color:#24292E">$n),</span></span>
-<span class="line"><span style="color:#24292E"> $b </span><span style="color:#D73A49">=></span><span style="color:#24292E"> $n </span><span style="color:#D73A49">===</span><span style="color:#D73A49"> +!!</span><span style="color:#24292E">[] </span><span style="color:#D73A49">?</span><span style="color:#24292E"> $pc</span><span style="color:#D73A49">+!</span><span style="color:#24292E">[] </span><span style="color:#D73A49">:</span><span style="color:#24292E"> $loop(</span><span style="color:#D73A49">--</span><span style="color:#24292E">$pc, </span><span style="color:#D73A49">--</span><span style="color:#24292E">$n),</span></span>
-<span class="line"><span style="color:#D73A49"> default</span><span style="color:#D73A49"> =></span><span style="color:#24292E"> $loop(</span><span style="color:#D73A49">--</span><span style="color:#24292E">$pc, $n),</span></span>
-<span class="line"><span style="color:#24292E"> })($pc, </span><span style="color:#D73A49">-!</span><span style="color:#24292E">[])],</span></span>
-<span class="line"><span style="color:#24292E">};</span></span>
-<span class="line"><span style="color:#24292E">$🐘 </span><span style="color:#D73A49">=</span><span style="color:#D73A49"> fn</span><span style="color:#24292E">($p) => $z(</span><span style="color:#D73A49">fn</span><span style="color:#24292E">($loop) => </span><span style="color:#D73A49">fn</span><span style="color:#24292E">($m, $p, $b, $e, $mp, $pc) =></span></span>
-<span class="line"><span style="color:#005CC5"> isset</span><span style="color:#24292E">($p[$pc]) </span><span style="color:#D73A49">&#x26;&#x26;</span><span style="color:#24292E"> $loop($m, $p, $b, $e, </span><span style="color:#D73A49">...</span><span style="color:#24292E">($p[$pc]($m, $p, $b, $e, $mp, $pc)))</span></span>
-<span class="line"><span style="color:#24292E">)($mm(</span><span style="color:#D73A49">+!!</span><span style="color:#24292E">[], </span><span style="color:#D73A49">+</span><span style="color:#24292E">(</span><span style="color:#D73A49">!</span><span style="color:#24292E">[]</span><span style="color:#D73A49">.</span><span style="color:#D73A49">!</span><span style="color:#24292E">[])), $p, $id($🤡), $id($🎪), </span><span style="color:#D73A49">+!!</span><span style="color:#24292E">[], </span><span style="color:#D73A49">+!!</span><span style="color:#24292E">[]);</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E">$🐘([</span></span>
-<span class="line"><span style="color:#24292E"> $👍, $👍, $👍, $👍, $👍, $👍, $👍, $👍, $👍, $👍,</span></span>
-<span class="line"><span style="color:#24292E"> $🤡,</span></span>
-<span class="line"><span style="color:#24292E"> $👉, $👍, $👍, $👍,</span></span>
-<span class="line"><span style="color:#24292E"> $👉, $👍, $👍, $👍, $👍, $👍,</span></span>
-<span class="line"><span style="color:#24292E"> $👉, $👍, $👍, $👍, $👍, $👍, $👍, $👍, $👍, $👍, $👍, $👍, $👍,</span></span>
-<span class="line"><span style="color:#24292E"> $👉, $👍, $👍, $👍, $👍, $👍, $👍, $👍, $👍, $👍, $👍,</span></span>
-<span class="line"><span style="color:#24292E"> $👈, $👈, $👈, $👈, $👎,</span></span>
-<span class="line"><span style="color:#24292E"> $🎪,</span></span>
-<span class="line"><span style="color:#24292E"> $👉, $👍, $👍, $👍, $👍, $👍, $📝,</span></span>
-<span class="line"><span style="color:#24292E"> $👎, $👎, $📝,</span></span>
-<span class="line"><span style="color:#24292E"> $👉, $👎, $👎, $👎, $📝,</span></span>
-<span class="line"><span style="color:#24292E"> $👉, $👎, $👎, $👎, $📝,</span></span>
-<span class="line"><span style="color:#24292E"> $👎, $👎, $📝,</span></span>
-<span class="line"><span style="color:#24292E"> $👎, $📝,</span></span>
-<span class="line"><span style="color:#24292E"> $👈, $📝,</span></span>
-<span class="line"><span style="color:#24292E"> $👉, $👉, $👎, $👎, $📝,</span></span>
-<span class="line"><span style="color:#24292E"> $👍, $👍, $👍, $👍, $👍, $👍, $👍, $📝,</span></span>
-<span class="line"><span style="color:#24292E"> $👈, $👎, $👎, $👎, $👎, $📝,</span></span>
-<span class="line"><span style="color:#24292E"> $👈, $📝,</span></span>
-<span class="line"><span style="color:#24292E"> $👉, $👍, $👍, $📝,</span></span>
-<span class="line"><span style="color:#24292E"> $👉, $👎, $📝,</span></span>
-<span class="line"><span style="color:#24292E"> $👈, $📝,</span></span>
-<span class="line"><span style="color:#24292E">]);</span></span></code></pre>
- </div>
- <p>
- この問題は、単に適切なバージョンの PHP で動かせばトークンが得られる。
- </p>
- <section id="section--q1-brainfuck--commentary">
- <h3><a href="#section--q1-brainfuck--commentary">解説</a></h3>
- <section id="section--q1-brainfuck--commentary--emoji">
- <h4><a href="#section--q1-brainfuck--commentary--emoji">絵文字</a></h4>
- <p>
- まず目につくのは大量の絵文字だろう。 PHP は識別子に使用できる文字の範囲が広く、絵文字も使うことができる。
- </p>
- </section>
- <section id="section--q1-brainfuck--commentary--brainfuck">
- <h4><a href="#section--q1-brainfuck--commentary--brainfuck">プログラム全体</a></h4>
- <p>
- Brainf*ck のインタプリタとプログラムになっている。 Brainf*ck とは、難解プログラミング言語のひとつであり、ここで説明するよりも Wikipedia の該当ページを読んだ方がよい。
- </p>
- <p>
- <a href="https://ja.wikipedia.org/wiki/Brainfuck" rel="noreferrer" target="_blank">https://ja.wikipedia.org/wiki/Brainfuck</a>
- </p>
- <p>
- なお、brainf*ck プログラムを普通の書き方で書くと、次のようになる。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>+ + + + + + + + + +</span></span>
-<span class="line"><span>[</span></span>
-<span class="line"><span> > + + +</span></span>
-<span class="line"><span> > + + + + +</span></span>
-<span class="line"><span> > + + + + + + + + + + + +</span></span>
-<span class="line"><span> > + + + + + + + + + +</span></span>
-<span class="line"><span> &#x3C; &#x3C; &#x3C; &#x3C; -</span></span>
-<span class="line"><span>]</span></span>
-<span class="line"><span>> + + + + + .</span></span>
-<span class="line"><span>- - .</span></span>
-<span class="line"><span>> - - - .</span></span>
-<span class="line"><span>> - - - .</span></span>
-<span class="line"><span>- - .</span></span>
-<span class="line"><span>- .</span></span>
-<span class="line"><span>&#x3C; .</span></span>
-<span class="line"><span>> > - - .</span></span>
-<span class="line"><span>+ + + + + + + .</span></span>
-<span class="line"><span>&#x3C; - - - - .</span></span>
-<span class="line"><span>&#x3C; .</span></span>
-<span class="line"><span>> + + .</span></span>
-<span class="line"><span>> - .</span></span>
-<span class="line"><span>&#x3C; .</span></span></code></pre>
- </div>
- <p>
- 実行結果はこちら: <a href="https://ideone.com/22VWmb" rel="noreferrer" target="_blank">https://ideone.com/22VWmb</a>
- </p>
- <p>
- それぞれの絵文字で表された関数が、各命令に対応している。
- </p>
- <ul>
- <li>
- <code>$👉</code>: <code>&gt;</code>
- </li>
- <li>
- <code>$👈</code>: <code>&lt;</code>
- </li>
- <li>
- <code>$👍</code>: <code>+</code>
- </li>
- <li>
- <code>$👎</code>: <code>-</code>
- </li>
- <li>
- <code>$📝</code>: <code>.</code>
- </li>
- <li>
- <code>$🤡</code>: <code>[</code>
- </li>
- <li>
- <code>$🎪</code>: <code>]</code>
- </li>
- </ul>
- <p>
- <code>,</code> (入力) に対応する関数はない (このプログラムでは使わないので用意していない)。
- </p>
- <p>
- なお、<code>$🐘</code> はいわゆる main 関数であり、プログラムの実行部分である。
- </p>
- </section>
- <section id="section--q1-brainfuck--commentary--emoji-selection">
- <h4><a href="#section--q1-brainfuck--commentary--emoji-selection">絵文字の選択</a></h4>
- <p>
- おおよそ意味に合致するよう選んでいるが、<code>$🤡</code> と <code>$🎪</code> は弊社デジタルサーカスにちなんでいる。 また、<code>$🐘</code> は PHP のマスコットの象に由来する。
- </p>
- </section>
- <section id="section--q1-brainfuck--commentary--strict-types">
- <h4><a href="#section--q1-brainfuck--commentary--strict-types">strict_types</a></h4>
- <p>
- <code>declare</code> 文の <code>strict_types</code> に指定できるのは、<code>0</code> か <code>1</code> の数値リテラルだが、 <code>0x0</code> や <code>0b1</code> のような値も受け付ける。 今回は、PHP 8.1 から追加された、<code>0O</code> または <code>0o</code> から始まる八進数リテラルを使った。
- </p>
- </section>
- <section id="section--q1-brainfuck--commentary--url">
- <h4><a href="#section--q1-brainfuck--commentary--url">URL</a></h4>
- <p>
- ソースコードのライセンスを示したこの部分だが、
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6F42C1">https</span><span style="color:#24292E">:</span><span style="color:#6A737D">//creativecommons.org/publicdomain/zero/1.0/</span></span></code></pre>
- </div>
- <p>
- 完全に合法な PHP のコードである。 <code>https:</code> 部分はラベル、<code>//</code> 以降は行コメントになっている。
- </p>
- </section>
- <section id="section--q1-brainfuck--commentary--numbers">
- <h4><a href="#section--q1-brainfuck--commentary--numbers">リテラルなしで数値を生成する</a></h4>
- <p>
- ソースコード中に、ほとんど数値リテラルが書かれていないことにお気づきだろうか。PHP では、型変換を利用することで任意の整数を作り出すことができる。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#005CC5">assert</span><span style="color:#24292E">(</span><span style="color:#005CC5">0</span><span style="color:#D73A49"> ===</span><span style="color:#D73A49"> +!!</span><span style="color:#24292E">[]);</span></span>
-<span class="line"><span style="color:#005CC5">assert</span><span style="color:#24292E">(</span><span style="color:#005CC5">1</span><span style="color:#D73A49"> ===</span><span style="color:#D73A49"> +!</span><span style="color:#24292E">[]);</span></span>
-<span class="line"><span style="color:#005CC5">assert</span><span style="color:#24292E">(</span><span style="color:#005CC5">2</span><span style="color:#D73A49"> ===</span><span style="color:#D73A49"> !</span><span style="color:#24292E">[]</span><span style="color:#D73A49">+!</span><span style="color:#24292E">[]);</span></span>
-<span class="line"><span style="color:#005CC5">assert</span><span style="color:#24292E">(</span><span style="color:#005CC5">3</span><span style="color:#D73A49"> ===</span><span style="color:#D73A49"> !</span><span style="color:#24292E">[]</span><span style="color:#D73A49">+!</span><span style="color:#24292E">[]</span><span style="color:#D73A49">+!</span><span style="color:#24292E">[]);</span></span>
-<span class="line"><span style="color:#005CC5">assert</span><span style="color:#24292E">(</span><span style="color:#005CC5">10</span><span style="color:#D73A49"> ===</span><span style="color:#D73A49"> +</span><span style="color:#24292E">(</span><span style="color:#D73A49">!</span><span style="color:#24292E">[]</span><span style="color:#D73A49">.</span><span style="color:#D73A49">+!!</span><span style="color:#24292E">[]));</span></span></code></pre>
- </div>
- <p>
- <code>[]</code> に <code>!</code> を適用すると <code>true</code> が返ってくる。それに <code>+</code> を適用すると、<code>bool</code> から <code>int</code> ヘの型変換が走り、<code>1</code> が生成される。<code>10</code> はさらにトリッキーだ。まず <code>1</code> と <code>0</code> を作り、<code>.</code> で文字列として結合する (<code>&apos;10&apos;</code>)。これに <code>+</code> を適用すると、<code>string</code> から <code>int</code> への型変換が走り、<code>10</code> が生まれる (コード量に頓着しないなら、<code>1</code> を 10 個足し合わせてももちろん 10 が作れる)。
- </p>
- <p>
- また、<code>error_reporting</code> に指定しているのは <code>-1</code> である。 これは、<code>!</code> によって文字列を <code>false</code> にし、<code>+</code> によって <code>false</code> を <code>0</code> にし、さらにビット反転して <code>-1</code> にしている。
- </p>
- </section>
- <section id="section--q1-brainfuck--commentary--conditionals">
- <h4><a href="#section--q1-brainfuck--commentary--conditionals"><code>if</code> 文なしで条件分岐</a></h4>
- <p>
- 三項演算子ないし <code>match</code> 式を使うことで、<code>if</code> を一切書かずに条件分岐ができる。 また、<code>&amp;&amp;</code> / <code>||</code> も使えることがある。遅延評価が不要なケースでは、<code>[$t, $f][$cond]</code> のような形で分岐することもできる。
- </p>
- </section>
- <section id="section--q1-brainfuck--commentary--loops">
- <h4><a href="#section--q1-brainfuck--commentary--loops"><code>while</code>、<code>for</code> 文なしでループ</a></h4>
- <p>
- 不動点コンビネータを使って無名再帰する (詳しい説明は省略する。これらの単語で検索してほしい)。 ここでは、一般に Z コンビネータとして知られるものを使った (<code>$z</code>)。
- </p>
- <p>
- 実際のところ、<code>$🤡</code> や <code>$🎪</code>、<code>$🐘</code> は、一度 Scheme (Lisp の一種) で書いてから PHP に翻訳する形で記述した。
- </p>
- <p>
- なお、PHP は末尾再帰の最適化をおこなわない (少なくとも今のところは) ので、 あまりに長い brainf*ck プログラムを書くとスタックオーバーフローする。
- </p>
- </section>
- </section>
- </section>
- <section id="section--q2-riddle">
- <h2><a href="#section--q2-riddle">第2問 riddle.php</a></h2>
- <p>
- ソースコードはこちら。実行には PHP 8.0 以上が必要なので注意。
- </p>
- <div class="codeblock">
- <div class="filename">
- riddle.php
- </div>
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#6A737D">/*********************************************************</span></span>
-<span class="line"><span style="color:#6A737D"> * This program displays a PHPer token. *</span></span>
-<span class="line"><span style="color:#6A737D"> * Guess 'N'. *</span></span>
-<span class="line"><span style="color:#6A737D"> * *</span></span>
-<span class="line"><span style="color:#6A737D"> * Hints: *</span></span>
-<span class="line"><span style="color:#6A737D"> * - N itself has no special meaning, e.g., 42, 8128, *</span></span>
-<span class="line"><span style="color:#6A737D"> * it is selected at random. *</span></span>
-<span class="line"><span style="color:#6A737D"> * - Each element of $token represents a single letter. *</span></span>
-<span class="line"><span style="color:#6A737D"> * - One letter consists of 5x5 cells. *</span></span>
-<span class="line"><span style="color:#6A737D"> * - Remember, the output is a complete PHPer token. *</span></span>
-<span class="line"><span style="color:#6A737D"> * *</span></span>
-<span class="line"><span style="color:#6A737D"> * License: *</span></span>
-<span class="line"><span style="color:#6A737D"> * https://creativecommons.org/publicdomain/zero/1.0/ *</span></span>
-<span class="line"><span style="color:#6A737D"> *********************************************************/</span></span>
-<span class="line"><span style="color:#D73A49">const</span><span style="color:#005CC5"> N</span><span style="color:#D73A49"> =</span><span style="color:#005CC5"> 0</span><span style="color:#6A737D"> /* Change it to your answer. */</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#005CC5">assert</span><span style="color:#24292E">(</span><span style="color:#005CC5">0</span><span style="color:#D73A49"> &#x3C;=</span><span style="color:#005CC5"> N</span><span style="color:#D73A49"> &#x26;&#x26;</span><span style="color:#005CC5"> N</span><span style="color:#D73A49"> &#x3C;=</span><span style="color:#005CC5"> 0b11111_11111_11111_11111_11111</span><span style="color:#24292E">);</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E">$token </span><span style="color:#D73A49">=</span><span style="color:#24292E"> [</span></span>
-<span class="line"><span style="color:#005CC5"> 0x14B499C</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#005CC5"> 0x0BE34CC</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x01C9C69</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#005CC5"> 0x0ECA069</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x01C2449</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x0FDB166</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x01C9C69</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#005CC5"> 0x01C1C66</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x0FC1C47</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x01C1C66</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#005CC5"> 0x10C5858</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1E4E3B8</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1A2F2F8</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#24292E">];</span></span>
-<span class="line"><span style="color:#D73A49">foreach</span><span style="color:#24292E"> ($token </span><span style="color:#D73A49">as</span><span style="color:#24292E"> $x) {</span></span>
-<span class="line"><span style="color:#24292E"> $x </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $x </span><span style="color:#D73A49">^</span><span style="color:#005CC5"> N</span><span style="color:#24292E">;</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E"> $x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> sprintf</span><span style="color:#24292E">(</span><span style="color:#032F62">'%025b'</span><span style="color:#24292E">, $x);</span></span>
-<span class="line"><span style="color:#24292E"> $x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> str_replace</span><span style="color:#24292E">(</span><span style="color:#6F42C1">search</span><span style="color:#24292E">: [</span><span style="color:#032F62">'0'</span><span style="color:#24292E">, </span><span style="color:#032F62">'1'</span><span style="color:#24292E">], </span><span style="color:#6F42C1">replace</span><span style="color:#24292E">: [</span><span style="color:#032F62">' '</span><span style="color:#24292E">, </span><span style="color:#032F62">'#'</span><span style="color:#24292E">], </span><span style="color:#6F42C1">subject</span><span style="color:#24292E">: $x);</span></span>
-<span class="line"><span style="color:#24292E"> $x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> implode</span><span style="color:#24292E">(</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">, </span><span style="color:#005CC5">str_split</span><span style="color:#24292E">($x, </span><span style="color:#6F42C1">length</span><span style="color:#24292E">: </span><span style="color:#005CC5">5</span><span style="color:#24292E">));</span></span>
-<span class="line"><span style="color:#005CC5"> echo</span><span style="color:#032F62"> "{</span><span style="color:#24292E">$x</span><span style="color:#032F62">}</span><span style="color:#005CC5">\n\n</span><span style="color:#032F62">"</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">}</span></span></code></pre>
- </div>
- <p>
- さて、この問題はさきほどのように単純に実行しただけでは、謎のブロックが表示されるだけでトークンは得られない。トークンを得るためには、ソースコードを読み、定数 <code>N</code> を特定する必要がある。
- </p>
- <p>
- ここでは、私の想定解を解説する。
- </p>
- <section id="section--q2-riddle--code-reading">
- <h3><a href="#section--q2-riddle--code-reading">読解</a></h3>
- <p>
- まずはソースコードを読んでいく。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">$token </span><span style="color:#D73A49">=</span><span style="color:#24292E"> [</span></span>
-<span class="line"><span style="color:#6A737D"> // 略</span></span>
-<span class="line"><span style="color:#24292E">];</span></span></code></pre>
- </div>
- <p>
- 数値からなる <code>$token</code> があり、各要素をループしている。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">$x </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $x </span><span style="color:#D73A49">^</span><span style="color:#005CC5"> N</span><span style="color:#24292E">;</span></span></code></pre>
- </div>
- <p>
- まずは排他的論理和 (xor) を取り、
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">$x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> sprintf</span><span style="color:#24292E">(</span><span style="color:#032F62">'%025b'</span><span style="color:#24292E">, $x);</span></span></code></pre>
- </div>
- <p>
- 二進数に変換して、
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">$x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> str_replace</span><span style="color:#24292E">(</span><span style="color:#6F42C1">search</span><span style="color:#24292E">: [</span><span style="color:#032F62">'0'</span><span style="color:#24292E">, </span><span style="color:#032F62">'1'</span><span style="color:#24292E">], </span><span style="color:#6F42C1">replace</span><span style="color:#24292E">: [</span><span style="color:#032F62">' '</span><span style="color:#24292E">, </span><span style="color:#032F62">'#'</span><span style="color:#24292E">], </span><span style="color:#6F42C1">subject</span><span style="color:#24292E">: $x);</span></span></code></pre>
- </div>
- <p>
- 0 を空白に、1 を <code>#</code> にし、
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">$x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> implode</span><span style="color:#24292E">(</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">, </span><span style="color:#005CC5">str_split</span><span style="color:#24292E">($x, </span><span style="color:#6F42C1">length</span><span style="color:#24292E">: </span><span style="color:#005CC5">5</span><span style="color:#24292E">));</span></span></code></pre>
- </div>
- <p>
- 5文字ごとに区切ったあと、改行で結合している。
- </p>
- </section>
- <section id="section--q2-riddle--hint">
- <h3><a href="#section--q2-riddle--hint">ヒント</a></h3>
- <p>
- 次に、ソースコードに書いてあるヒントを読んでいく。
- </p>
- <ul>
- <li>
- <code>N</code> それ自体は、42 や 8128 といったような特別な意味を持たず、ランダムに決められている
- </li>
- <li>
- <code>$token</code> の各要素は、1文字を表す
- </li>
- <li>
- 1文字は 5x5 のセルからなる
- </li>
- <li>
- 出力されるのは、完全な PHPer トークンである
- </li>
- </ul>
- <p>
- ここで、PHPer トークンは必ず <code>#</code> 記号から始まることを思いだすと、<code>$token</code> の最初の数字 <code>0x14B499C</code> は、変換の結果 <code>#</code> になるのではないかと予想される (なお、このことは、リポジトリの README ファイルに追加ヒントとして書かれている)。
- </p>
- </section>
- <section id="section--q2-riddle--solve">
- <h3><a href="#section--q2-riddle--solve">解く</a></h3>
- <p>
- ここまでわかれば、あと一歩で解ける。すなわち、<code>0x14B499C</code> が <code>#</code> に変換されるような <code>N</code> を見つければよい。
- </p>
- <p>
- <code>N</code> は高々
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#005CC5">assert</span><span style="color:#24292E">(</span><span style="color:#005CC5">0</span><span style="color:#D73A49"> &#x3C;=</span><span style="color:#005CC5"> N</span><span style="color:#D73A49"> &#x26;&#x26;</span><span style="color:#005CC5"> N</span><span style="color:#D73A49"> &#x3C;=</span><span style="color:#005CC5"> 0b11111_11111_11111_11111_11111</span><span style="color:#24292E">);</span></span></code></pre>
- </div>
- <p>
- なのでブルートフォースしてもよいが、ここではブルートフォースしない方法を紹介する。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E">$x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> 0x14B499C</span><span style="color:#24292E">;</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E">$x </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $x </span><span style="color:#D73A49">^</span><span style="color:#005CC5"> N</span><span style="color:#24292E">;</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E">$x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> sprintf</span><span style="color:#24292E">(</span><span style="color:#032F62">'%025b'</span><span style="color:#24292E">, $x);</span></span>
-<span class="line"><span style="color:#24292E">$x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> str_replace</span><span style="color:#24292E">(</span><span style="color:#6F42C1">search</span><span style="color:#24292E">: [</span><span style="color:#032F62">'0'</span><span style="color:#24292E">, </span><span style="color:#032F62">'1'</span><span style="color:#24292E">], </span><span style="color:#6F42C1">replace</span><span style="color:#24292E">: [</span><span style="color:#032F62">' '</span><span style="color:#24292E">, </span><span style="color:#032F62">'#'</span><span style="color:#24292E">], </span><span style="color:#6F42C1">subject</span><span style="color:#24292E">: $x);</span></span>
-<span class="line"><span style="color:#24292E">$x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> implode</span><span style="color:#24292E">(</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">, </span><span style="color:#005CC5">str_split</span><span style="color:#24292E">($x, </span><span style="color:#6F42C1">length</span><span style="color:#24292E">: </span><span style="color:#005CC5">5</span><span style="color:#24292E">));</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#005CC5">assert</span><span style="color:#24292E">($x </span><span style="color:#D73A49">===</span></span>
-<span class="line"><span style="color:#032F62">" # # </span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#D73A49"> .</span></span>
-<span class="line"><span style="color:#032F62">"#####</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#D73A49"> .</span></span>
-<span class="line"><span style="color:#032F62">" # # </span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#D73A49"> .</span></span>
-<span class="line"><span style="color:#032F62">"#####</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#D73A49"> .</span></span>
-<span class="line"><span style="color:#032F62">" # # "</span><span style="color:#24292E">);</span></span></code></pre>
- </div>
- <p>
- この一連の変換に対する逆変換を考えると、次のようになる。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E">$x </span><span style="color:#D73A49">=</span></span>
-<span class="line"><span style="color:#032F62">" # # </span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#D73A49"> .</span></span>
-<span class="line"><span style="color:#032F62">"#####</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#D73A49"> .</span></span>
-<span class="line"><span style="color:#032F62">" # # </span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#D73A49"> .</span></span>
-<span class="line"><span style="color:#032F62">"#####</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#D73A49"> .</span></span>
-<span class="line"><span style="color:#032F62">" # # "</span><span style="color:#24292E">;</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E">$x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> implode</span><span style="color:#24292E">(</span><span style="color:#032F62">''</span><span style="color:#24292E">, </span><span style="color:#005CC5">explode</span><span style="color:#24292E">(</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">, $x));</span></span>
-<span class="line"><span style="color:#24292E">$x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> str_replace</span><span style="color:#24292E">(</span><span style="color:#6F42C1">search</span><span style="color:#24292E">: [</span><span style="color:#032F62">' '</span><span style="color:#24292E">, </span><span style="color:#032F62">'#'</span><span style="color:#24292E">], </span><span style="color:#6F42C1">replace</span><span style="color:#24292E">: [</span><span style="color:#032F62">'0'</span><span style="color:#24292E">, </span><span style="color:#032F62">'1'</span><span style="color:#24292E">], </span><span style="color:#6F42C1">subject</span><span style="color:#24292E">: $x);</span></span>
-<span class="line"><span style="color:#24292E">$x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> bindec</span><span style="color:#24292E">($x);</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E">$n </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $x </span><span style="color:#D73A49">^</span><span style="color:#005CC5"> 0x14B499C</span><span style="color:#24292E">;</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#005CC5">echo</span><span style="color:#032F62"> "N = </span><span style="color:#24292E">$n</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">;</span></span></code></pre>
- </div>
- <p>
- これを実行すると、<code>N</code> が得られる。
- </p>
- </section>
- </section>
- <section id="section--q3-toquine">
- <h2><a href="#section--q3-toquine">第3問 toquine.php</a></h2>
- <p>
- ソースコードはこちら。
- </p>
- <div class="codeblock">
- <div class="filename">
- toquine.php
- </div>
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#6A737D">// License: https://creativecommons.org/publicdomain/zero/1.0/</span></span>
-<span class="line"><span style="color:#6A737D">// This is a quine-like program to generate a PHPer token.</span></span>
-<span class="line"><span style="color:#6A737D">// Execute it like this: php toquine.php | php | php | php | ...</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E">$s </span><span style="color:#D73A49">=</span><span style="color:#032F62"> &#x3C;&#x3C;&#x3C;'</span><span style="color:#D73A49">Q</span><span style="color:#032F62">'</span></span>
-<span class="line"><span style="color:#032F62">&#x3C;?cuc</span></span>
-<span class="line"><span style="color:#032F62">// Yvprafr: uggcf://perngvirpbzzbaf.bet/choyvpqbznva/mreb/1.0/</span></span>
-<span class="line"><span style="color:#032F62">// Guvf vf n dhvar-yvxr cebtenz gb trarengr n CUCre gbxra.</span></span>
-<span class="line"><span style="color:#032F62">// Rkrphgr vg yvxr guvf: cuc gbdhvar.cuc | cuc | cuc | cuc | ...</span></span>
-<span class="line"><span style="color:#032F62">%f$f = %f;</span></span>
-<span class="line"><span style="color:#032F62">$f = fge_ebg13($f); $kf = [</span></span>
-<span class="line"><span style="color:#032F62">%f,</span></span>
-<span class="line"><span style="color:#032F62">];</span></span>
-<span class="line"><span style="color:#032F62">$g = ahyy.snyfr; sbe ($v = 0; $v &#x3C;= vagqvi(__YVAR__-035,6); ++$v) vs (!vffrg($kf[$v])) oernx; ryfr</span></span>
-<span class="line"><span style="color:#032F62">$g .= vzcybqr("\a", fge_fcyvg(fge_ercynpr(['0','1'], [' ','##'], fcevags(pue(37) . '025o', $kf[$v])), 012)) . "\a\a";</span></span>
-<span class="line"><span style="color:#032F62">$jf = neenl_znc(sa($j) => vzcybqr(', ', $j), neenl_puhax(neenl_znc(sa($k) => fcevags('0k' . pue(37) . '07K', $k), $kf), 10));</span></span>
-<span class="line"><span style="color:#032F62">cevags($f, $g, fge_ebg13("&#x3C;&#x3C;&#x3C;'Q'\a{$f}\aQ"), vzcybqr(",\a", $jf));</span></span>
-<span class="line"><span style="color:#D73A49">Q</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">$s </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> str_rot13</span><span style="color:#24292E">($s); $xs </span><span style="color:#D73A49">=</span><span style="color:#24292E"> [</span></span>
-<span class="line"><span style="color:#005CC5">0x0AFABEA</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1F294A7</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1F2109F</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1F294A7</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x0002800</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1F2109F</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x0117041</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1F294A7</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1FAD6B5</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1F295B7</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#005CC5">0x010FC21</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1FAD6B5</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1151151</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x010FC21</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1F294A7</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1F295B7</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1FAD6B5</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1F294A7</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1F295B7</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1F8C63F</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#005CC5">0x1F8C631</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1FAD6B5</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x17AD6BD</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x17AD6BD</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1F8C63F</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1F295B7</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#24292E">];</span></span>
-<span class="line"><span style="color:#24292E">$t </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> null</span><span style="color:#D73A49">.</span><span style="color:#005CC5">false</span><span style="color:#24292E">; </span><span style="color:#D73A49">for</span><span style="color:#24292E"> ($i </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">; $i </span><span style="color:#D73A49">&#x3C;=</span><span style="color:#6F42C1"> intdiv</span><span style="color:#24292E">(</span><span style="color:#005CC5">__LINE__</span><span style="color:#D73A49">-</span><span style="color:#005CC5">035</span><span style="color:#24292E">,</span><span style="color:#005CC5">6</span><span style="color:#24292E">); </span><span style="color:#D73A49">++</span><span style="color:#24292E">$i) </span><span style="color:#D73A49">if</span><span style="color:#24292E"> (</span><span style="color:#D73A49">!</span><span style="color:#005CC5">isset</span><span style="color:#24292E">($xs[$i])) </span><span style="color:#D73A49">break</span><span style="color:#24292E">; </span><span style="color:#D73A49">else</span></span>
-<span class="line"><span style="color:#24292E">$t </span><span style="color:#D73A49">.=</span><span style="color:#005CC5"> implode</span><span style="color:#24292E">(</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">, </span><span style="color:#005CC5">str_split</span><span style="color:#24292E">(</span><span style="color:#005CC5">str_replace</span><span style="color:#24292E">([</span><span style="color:#032F62">'0'</span><span style="color:#24292E">,</span><span style="color:#032F62">'1'</span><span style="color:#24292E">], [</span><span style="color:#032F62">' '</span><span style="color:#24292E">,</span><span style="color:#032F62">'##'</span><span style="color:#24292E">], </span><span style="color:#005CC5">sprintf</span><span style="color:#24292E">(</span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">37</span><span style="color:#24292E">) </span><span style="color:#D73A49">.</span><span style="color:#032F62"> '025b'</span><span style="color:#24292E">, $xs[$i])), </span><span style="color:#005CC5">012</span><span style="color:#24292E">)) </span><span style="color:#D73A49">.</span><span style="color:#032F62"> "</span><span style="color:#005CC5">\n\n</span><span style="color:#032F62">"</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">$ws </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> array_map</span><span style="color:#24292E">(</span><span style="color:#D73A49">fn</span><span style="color:#24292E">($w) => </span><span style="color:#005CC5">implode</span><span style="color:#24292E">(</span><span style="color:#032F62">', '</span><span style="color:#24292E">, $w), </span><span style="color:#005CC5">array_chunk</span><span style="color:#24292E">(</span><span style="color:#005CC5">array_map</span><span style="color:#24292E">(</span><span style="color:#D73A49">fn</span><span style="color:#24292E">($x) => </span><span style="color:#005CC5">sprintf</span><span style="color:#24292E">(</span><span style="color:#032F62">'0x'</span><span style="color:#D73A49"> .</span><span style="color:#005CC5"> chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">37</span><span style="color:#24292E">) </span><span style="color:#D73A49">.</span><span style="color:#032F62"> '07X'</span><span style="color:#24292E">, $x), $xs), </span><span style="color:#005CC5">10</span><span style="color:#24292E">));</span></span>
-<span class="line"><span style="color:#005CC5">printf</span><span style="color:#24292E">($s, $t, </span><span style="color:#005CC5">str_rot13</span><span style="color:#24292E">(</span><span style="color:#032F62">"&#x3C;&#x3C;&#x3C;'D'</span><span style="color:#005CC5">\n</span><span style="color:#032F62">{</span><span style="color:#24292E">$s</span><span style="color:#032F62">}</span><span style="color:#005CC5">\n</span><span style="color:#032F62">D"</span><span style="color:#24292E">), </span><span style="color:#005CC5">implode</span><span style="color:#24292E">(</span><span style="color:#032F62">",</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">, $ws));</span></span></code></pre>
- </div>
- <p>
- コメントにもあるとおり、次のようにして実行すれば答えがでてくる。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ php toquine.php | php | php | php | ...</span></span></code></pre>
- </div>
- <p>
- 実際にはもう少しパイプで繋げなければならない。
- </p>
- <section id="section--q3-toquine--commentary">
- <h3><a href="#section--q3-toquine--commentary">解説</a></h3>
- <section id="section--q3-toquine--commentary--quine">
- <h4><a href="#section--q3-toquine--commentary--quine">プログラム全体</a></h4>
- <p>
- コメントにもあるとおり、これは quine (風) のプログラムになっている。Quine とは、自分のソースコードをそっくりそのまま出力するようなプログラムのことである。
- </p>
- <p>
- このプログラムは、実行すると自身とほとんど同じプログラムを出力する。異なるのはトークンになっている部分のみである。
- </p>
- </section>
- <section id="section--q3-toquine--commentary--tokens">
- <h4><a href="#section--q3-toquine--commentary--tokens">トークン</a></h4>
- <p>
- <code>$xs</code> がトークンに対応している。変換のロジックは <code>riddle.php</code> とほぼ同じなので省略する。
- </p>
- </section>
- <section id="section--q3-toquine--commentary--states">
- <h4><a href="#section--q3-toquine--commentary--states">状態保持</a></h4>
- <p>
- トークンの何文字目まで出力したかを、ソースコードを変えずに (quine なので) 覚えておく必要がある。このプログラムでは、トークンが出力されるとソースコードがだんだんと長くなっていくのを利用して、<code>__LINE__</code> から情報を取得している。
- </p>
- </section>
- <section id="section--q3-toquine--commentary--rot-13">
- <h4><a href="#section--q3-toquine--commentary--rot-13">ROT 13</a></h4>
- <p>
- Quine は、素朴に書くとプログラムの一部が 2回記述されてしまう。これがあまり美しくないので、<code>toquine.php</code> では、ROT 13 変換を使って難読化した。
- </p>
- <p>
- それにしてもなぜこんなものが標準ライブラリに……。
- </p>
- </section>
- </section>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">おわりに</a></h2>
- <p>
- 解いていただいたみなさん、また、難易度調整につきあっていただいた社内のみなさん、ありがとうございました。
- </p>
- <p>
- 今回は直前に作りはじめたのもあり、3問だけかつ使い古されたネタばかりになってしまいましたが、来年は 5問、より面白い問題を持っていきます。
- </p>
- <p>
- 実はもう作りはじめているので、どうか来年もありますように……。
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2022-04-24/term-banner-write-tool-showing-banner-in-terminal/index.html b/vhosts/blog/public/posts/2022-04-24/term-banner-write-tool-showing-banner-in-terminal/index.html
deleted file mode 100644
index 0b8b6d14..00000000
--- a/vhosts/blog/public/posts/2022-04-24/term-banner-write-tool-showing-banner-in-terminal/index.html
+++ /dev/null
@@ -1,157 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2022 nsfisis">
- <meta name="description" content="ターミナルに任意の文字のバナーを表示するためのツールを Go で書いた。">
- <meta property="og:type" content="article">
- <meta property="og:title" content="term-banner: ターミナルにバナーを表示するツールを書いた|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="ターミナルに任意の文字のバナーを表示するためのツールを Go で書いた。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>term-banner: ターミナルにバナーを表示するツールを書いた|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">term-banner: ターミナルにバナーを表示するツールを書いた</h1>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2022-04-24">2022-04-24</time>: 公開
- </li>
- <li class="revision">
- <time datetime="2022-04-27">2022-04-27</time>: -f オプションについて追記
- </li>
- </ol>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- こんなものを作った。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ term-banner 'Hello, World!' 'こんにちは、' '世界!'</span></span></code></pre>
- </div>
- <p>
- <img alt="term-banner が動作している様子のスクリーンショット" src="/posts/2022-04-24/term-banner-write-tool-showing-banner-in-terminal/screenshot.png">
- </p>
- <p>
- コマンドライン引数として渡した文字列をターミナルに大きく表示する。
- </p>
- <p>
- リポジトリはこちら: <a href="https://github.com/nsfisis/term-banner" rel="noreferrer" target="_blank">https://github.com/nsfisis/term-banner</a>
- </p>
- </section>
- <section id="section--motivation">
- <h2><a href="#section--motivation">Motivation</a></h2>
- <p>
- 以前、<a href="https://github.com/nsfisis/big-clock-mode" rel="noreferrer" target="_blank"><code>big-clock-mode</code></a> という似たようなプログラムを書いた。 これは tmux の <code>:clock-mode</code> コマンドに着想を得たもので、<code>:clock-mode</code> よりも大きく現在時刻を表示する。
- </p>
- <p>
- <code>big-clock-mode</code> を開発したのは、次のようなシチュエーションで使うためである。弊社では現在リモートワークが基本だが、web 会議などで画面共有しているときに、休憩を挟んで特定の時刻から再開する、ということがある。こういったケースで、画面上に現在の時刻を大きめに表示しておくと、モニタから離れても遠くから時刻がわかるので便利である。
- </p>
- <p>
- それこそタイマアプリか何かを使えばいいのだが、ターミナルに棲むいきものとしては、住処から離れたくないわけだ。
- </p>
- <p>
- しばらく便利に使っていたのだが、ひとつ不満点が出てきた。それは、再開する時刻がいつだったかを覚えておかなければならないということだ。どこかにメモしておいてもいいが、せっかくなら現在時刻とともに表示させておきたい。
- </p>
- <p>
- そんなわけで、「任意の文字列をターミナルに表示する」プログラムを書く運びとなった。まあ、作らなくても探せばあると思うが、作りたいものは作りたいので知ったことではない。
- </p>
- </section>
- <section id="section--program">
- <h2><a href="#section--program">プログラム</a></h2>
- <p>
- 全体の流れは次のようになっている。
- </p>
- <ol>
- <li>
- フォントファイルを読み込む
- </li>
- <li>
- コマンドライン引数を Shift-JIS に変換する (フォントが Shift-JIS 基準で並んでいるため)
- </li>
- <li>
- 1文字ずつレンダリングしていく
- </li>
- </ol>
- <p>
- <code>big-clock-mode</code> が Go 製なので、今回も Go で書いた。 PNG が標準ライブラリにあったり、Shift-JIS のエンコーディングが準標準ライブラリにあったりしたのは助かった。
- </p>
- <p>
- フォントファイルは <code>go:embed</code> で実行ファイルに埋め込んでいるので、ビルド後はワンバイナリで動く。仕事ではスクリプト言語ばかり書いているが、やはりコンパイル言語はいい。
- </p>
- </section>
- <section id="section--font">
- <h2><a href="#section--font">フォント</a></h2>
- <p>
- フリーの 8x8 ビットマップフォントである、 <a href="https://littlelimit.net/misaki.htm" rel="noreferrer" target="_blank">美咲フォント 2021-05-05a 版</a> を使わせていただいた。
- </p>
- <p>
- はじめは自分でポチポチ打っていたのだが、「き」くらいまでやって挫折した。同じく 8x8 で作っていたのだが、平仮名でさえも、この小さなキャンバスにはとても収められない。
- </p>
- <p>
- 美咲フォントは、平仮名・片仮名に留まらず、JIS 第一・第二水準の漢字までサポートしている。第二水準ともなると一生お目にかかることのない字の方が多いくらいだが、これをこの大きさで書くというのは、もはや芸術の域である。
- </p>
- <p>
- さらに言うと、実のところ美咲フォントは実サイズ 7x7 で作られており、余白が設けられている。これは、単純にそのまま並べても字間・行間を確保できるようにという配慮である。おかげでコーディングまで楽になった。
- </p>
- <p>
- ゴシック体と明朝体があったが、私の好みで明朝体の方にした。ただ、ゴシック体の方が見やすい気がするので、フォントを選べるように後ほど拡張するかもしれない。
- </p>
- <div class="admonition" editat="2022-04-27" operation="追記">
- <div class="admonition-label">
- 2022-04-27 追記
- </div>
- <div class="admonition-content">
- <p>
- <code>-f</code> オプションで選べるようにした。
- </p>
- </div>
- </div>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">おわりに</a></h2>
- <p>
- あなたもターミナルに住んでみませんか?
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2022-04-24/term-banner-write-tool-showing-banner-in-terminal/screenshot.png b/vhosts/blog/public/posts/2022-04-24/term-banner-write-tool-showing-banner-in-terminal/screenshot.png
deleted file mode 100644
index c527879a..00000000
--- a/vhosts/blog/public/posts/2022-04-24/term-banner-write-tool-showing-banner-in-terminal/screenshot.png
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/posts/2022-05-01/phperkaigi-2022/index.html b/vhosts/blog/public/posts/2022-05-01/phperkaigi-2022/index.html
deleted file mode 100644
index 9e9613d5..00000000
--- a/vhosts/blog/public/posts/2022-05-01/phperkaigi-2022/index.html
+++ /dev/null
@@ -1,248 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2022 nsfisis">
- <meta name="description" content="2022-04-09 から 2022-04-11 にかけて開催された、PHPerKaigi 2022 に参加した。">
- <meta name="keywords" content="カンファレンス,PHP,PHPerKaigi">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHPerKaigi 2022|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="2022-04-09 から 2022-04-11 にかけて開催された、PHPerKaigi 2022 に参加した。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHPerKaigi 2022|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">PHPerKaigi 2022</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/conference/">カンファレンス</a>
- </li>
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phperkaigi/">PHPerKaigi</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2022-05-01">2022-05-01</time>: 公開
- </li>
- </ol>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- 2022-04-09 から 2022-04-11 にかけて開催された、 <a href="https://phperkaigi.jp/2022/" rel="noreferrer" target="_blank">PHPerKaigi 2022</a> に、一般参加者として参加した。弊社 <a href="https://www.dgcircus.com/" rel="noreferrer" target="_blank">デジタルサーカス株式会社</a> はダイヤモンドスポンサーとなっており、スポンサー枠のチケットを使わせていただいた。
- </p>
- <p>
- 昨年のレポートは <a href="/posts/2021-03-30/phperkaigi-2021">こちら</a> 。
- </p>
- </section>
- <section id="section--comments">
- <h2><a href="#section--comments">感想</a></h2>
- <section id="section--comments--great-sessions">
- <h3><a href="#section--comments--great-sessions">厳選おすすめトーク</a></h3>
- <p>
- 多くの素晴らしいトークの中から、特におすすめのものを 5つ選んだ。是非聞いてほしい。引用部分は、リンク先プロポーザルから引用している。
- </p>
- <p>
- <a href="https://fortee.jp/phperkaigi-2022/proposal/ef8cf4ed-63fe-42f8-8145-b3e70054458b" rel="noreferrer" target="_blank">予防に勝る防御なし - 堅牢なコードを導く様々な設計のヒント</a>
- </p>
- <blockquote>
- <p>
- PHP はバージョンを追う毎に型宣言、例外、表明、列挙型などの機能が大幅に強化され、堅牢なコードを書くための機能が充実してきました。それらの機能はどう使うと効果的なのでしょうか。
- </p>
- <p>
- 本講演では PHP 8.1 をベースにして、誤りを想定してチェックするのではなく、そもそも誤りにくい設計とはどのようなものか、つまり「予防」の観点を軸足に、堅牢なコードを導くための様々な設計のヒントをご紹介します。
- </p>
- </blockquote>
- <p>
- <a href="https://fortee.jp/phperkaigi-2022/proposal/db00d49e-0dd6-453f-b54b-f731d112f10e" rel="noreferrer" target="_blank">PHPのエラーを理解して適切なエラーハンドリングを学ぼう</a>
- </p>
- <blockquote>
- <p>
- PHPを使ってるとよく遭遇する Fatal error / Parse error / Warning / Notice 理解していますか?
- </p>
- <p>
- これらのエラー文を理解することで、すぐにエラーの原因に気付き適切に対象できる様になります!
- </p>
- <p>
- またそれらを理解した上でのエラーハンドリングを学びましょう。
- </p>
- </blockquote>
- <p>
- <a href="https://fortee.jp/phperkaigi-2022/proposal/4a7e3ded-9134-4919-955c-ec7bf4491c0d" rel="noreferrer" target="_blank">エラー監視とテスト体制への改善作戦</a>
- </p>
- <blockquote>
- <p>
- 毎日流れてくるエラーに皆さんはどう向き合ってますか?
- </p>
- <p>
- エラーを出さない事が一番ですが、完全に塞ぐ事は難しいと考えます。
- </p>
- <p>
- サービス運用の中で本番環境から発生するエラー(サーバー・クライアントサイド・サードパーティ起因のエラー)への監視体制と、
- </p>
- <p>
- エラー・バグ防御のためチームで行っているテストコード文化づくりの話をします。
- </p>
- </blockquote>
- <p>
- <a href="https://fortee.jp/phperkaigi-2022/proposal/6f47daf8-c78f-4fb1-9b99-e9656e6fe7f7" rel="noreferrer" target="_blank">ISUCON11のPHP実装は、何を考え、どのようにして作られていたのか</a>
- </p>
- <blockquote>
- <p>
- 昨年開催されたISUCON11にて問題(参考実装)のPHPへの移植を担当させていただきました。
- </p>
- <p>
- 最終的なソースコードこそシンプルなWebアプリケーションではありますが、その裏には
- </p>
- <ul>
- <li>
- 「(私の思う)良い設計」を実現するための意思決定
- </li>
- <li>
- 「ISUCONの問題」という位置付けに由来する取捨選択
- </li>
- <li>
- 移植中に遭遇したトラブルとその解決策
- </li>
- </ul>
- <p>
- といった文脈や葛藤が存在しています。
- </p>
- <p>
- 本発表はそれらを共有することで
- </p>
- <ul>
- <li>
- PHPアプリケーションの設計、実装事例として役立ててもらう
- </li>
- <li>
- ISUCONの言語移植に興味を持ってもらう
- </li>
- <li>
- ISUCON問題移植の「実装や設計の練習をする教材」としての可能性を知ってもらう
- </li>
- </ul>
- <p>
- ことを目的とします。
- </p>
- </blockquote>
- <p>
- <a href="https://fortee.jp/phperkaigi-2022/proposal/5a260e4e-542d-4d82-849d-ef3d6cb7c854" rel="noreferrer" target="_blank">チームの仕事はまわっていたけど、メンバーはそれぞれモヤモヤを抱えていた話──40名の大規模開発チームで1on1ログを公開してみた</a>
- </p>
- <blockquote>
- <p>
- サイボウズの大企業向けグループウェアのGaroon(ガルーン)は、PHPで開発されている20年目の製品です。ガルーン開発チームは日本で40名、ベトナムで50名の計90名ほどのチームになっています。また、コロナ禍でフルリモートでの活動がこの2年ほど継続してきました。
- </p>
- <p>
- フルリモートになっても仕事はまわっており、継続的にリリースはしていましたが、一方でお互いの考えていることや感じている問題意識が見えづらくなり、モヤモヤを抱えているメンバーが増えていました。
- </p>
- <p>
- このセッションでは、そういう状況で私がチーム外からジョインし、聴き役に徹しながら見える化することで状況を改善していった取り組みを紹介します。同じように大きなチームやリモートワークで難しさを感じている人に、難しさの原因への気づきや取り組みへのヒントがあれば幸いです。
- </p>
- </blockquote>
- </section>
- <section id="section--comments--token-quizzes">
- <h3><a href="#section--comments--token-quizzes">トークン問題の作成</a></h3>
- <p>
- 今回は、PHPer チャレンジ用に弊社のトークン問題を 3題作成した。こちらについては <a href="/posts/2022-04-09/phperkaigi-2022-tokens">別途記事にしている</a> ので、そちらを参照されたい。
- </p>
- </section>
- <section id="section--comments--phper-challenge">
- <h3><a href="#section--comments--phper-challenge">PHPer チャレンジ</a></h3>
- <p>
- <a href="https://fortee.jp/phperkaigi-2022/challenge" rel="noreferrer" target="_blank">1位</a> になった。また、賞品として <a href="https://www.amazon.co.jp/dp/B08MQNJC9Z" rel="noreferrer" target="_blank">Echo Show 15</a> をいただいた。
- </p>
- </section>
- <section id="section--comments--conference">
- <h3><a href="#section--comments--conference">カンファレンス全体への感想</a></h3>
- <p>
- <a href="/posts/2021-03-30/phperkaigi-2021">去年の参加レポ</a> では、こんなことを書いた。
- </p>
- <blockquote>
- <p>
- 1つ個人的な反省点としては、(中略) Discord しかりアンカンファレンスしかり「このイベントのこの瞬間にしかないコンテンツ」に触れずに、後から見返せる発表やスライドに注力してしまった、ということだ。発表の詳細な見直しはあとからできるのだから、今しかできないことを考えるべきだった。まあ初カンファレンスだし、とお茶を濁しておこう。
- </p>
- </blockquote>
- <p>
- この反省を踏まえ、今年は積極的にほかの場 (公式の Discord サーバや、アンカンファレンス) にも参加した。これにより、参加体験の質がはるかに向上した。特に Discord に関しては、登壇者ご本人による補足や、質問への回答などがおこなわれる (ことが多い) ため、特別な理由のない限り、発言はしないまでも参加はしておいたほうが良いと思われる。
- </p>
- <p>
- なお、アンカンファレンスについては、1日目の終わりに <a href="https://fortee.jp/phperkaigi-2022/unconference/view/d332797a-8921-4706-a7e2-ee72640c9b5e" rel="noreferrer" target="_blank">トークン問題の解説放送</a> もおこなった。
- </p>
- <p>
- また、今年はオフラインとオンラインのハイブリッド開催であったが、去年の全オンラインと比べて、オンライン参加の体験が落ちていなかったのは、特筆すべきであろう。今年は 3回目のワクチン接種が間に合わなかったこともあり現地参加は見送ったのだが、来年は是非オフラインで参加したい。
- </p>
- </section>
- </section>
- <section id="section--next-year">
- <h2><a href="#section--next-year">そして来年へ……?</a></h2>
- <p>
- PHPerKaigi 2023 があるかどうか存じ上げないが、あるとすれば、次の 4つを目標としたい。
- </p>
- <ul>
- <li>
- プロポーザルを出す
- </li>
- <li>
- PHPer チャレンジのトークン問題を 5題作成する
- </li>
- <li>
- 現地に行く
- </li>
- <li>
- PHPer チャレンジで圧勝する
- </li>
- </ul>
- <hr>
- <p>
- 最後になりましたが、PHPerKaigi のスタッフ、スポンサー、スピーカーのみなさん、素敵な時間をありがとうございました。
- </p>
- <p>
- ではまた来年。
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2022-08-27/php-conference-okinawa-code-golf/index.html b/vhosts/blog/public/posts/2022-08-27/php-conference-okinawa-code-golf/index.html
deleted file mode 100644
index 5835615d..00000000
--- a/vhosts/blog/public/posts/2022-08-27/php-conference-okinawa-code-golf/index.html
+++ /dev/null
@@ -1,178 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2022 nsfisis">
- <meta name="description" content="PHP カンファレンス沖縄の懇親会 LT で出題されたコードゴルフの問題を解いてみた。">
- <meta name="keywords" content="カンファレンス,PHP,PHP カンファレンス沖縄">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHP カンファレンス沖縄で出題されたコードゴルフの問題を解いてみた|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="PHP カンファレンス沖縄の懇親会 LT で出題されたコードゴルフの問題を解いてみた。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHP カンファレンス沖縄で出題されたコードゴルフの問題を解いてみた|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">PHP カンファレンス沖縄で出題されたコードゴルフの問題を解いてみた</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/conference/">カンファレンス</a>
- </li>
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phpconokinawa/">PHP カンファレンス沖縄</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2022-08-27">2022-08-27</time>: 公開
- </li>
- </ol>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- 本日 <a href="https://phpcon.okinawa.jp/" rel="noreferrer" target="_blank">PHP カンファレンス沖縄 2022</a> が開催された (らしい)。
- </p>
- <p>
- カンファレンスには参加できなかったものの、懇親会の LT で出題されたコードゴルフの問題が Twitter に流れてきたので、解いてみた。
- </p>
- <ul>
- <li>
- ツイート: <a href="https://twitter.com/m3m0r7/status/1563397620231712772" rel="noreferrer" target="_blank">https://twitter.com/m3m0r7/status/1563397620231712772</a>
- </li>
- <li>
- スライド: <a href="https://speakerdeck.com/memory1994/php-conference-okinawa-2022-extra?slide=3" rel="noreferrer" target="_blank">https://speakerdeck.com/memory1994/php-conference-okinawa-2022-extra?slide=3</a>
- </li>
- </ul>
- </section>
- <section id="section--solution">
- <h2><a href="#section--solution">解</a></h2>
- <p>
- 細かいレギュレーションは不明だったので、勝手に定めた。
- </p>
- <ul>
- <li>
- コマンドライン引数の第1引数で受けとる
- </li>
- <li>
- 結果は標準出力に出す
- </li>
- <li>
- コンマの直後にはスペースを1つ置く
- </li>
- <li>
- 末尾コンマは禁止
- </li>
- <li>
- 数字でないものは入ってこないものとする
- </li>
- <li>
- 負数は入ってこないものとする
- </li>
- </ul>
- <p>
- 書いたものがこちら:
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">[</span><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span><span style="color:#24292E"> $n</span><span style="color:#D73A49">=</span><span style="color:#24292E">$argv[</span><span style="color:#005CC5">1</span><span style="color:#24292E">];</span><span style="color:#D73A49">foreach</span><span style="color:#24292E">([</span><span style="color:#005CC5">1e4</span><span style="color:#24292E">,</span><span style="color:#005CC5">5e3</span><span style="color:#24292E">,</span><span style="color:#005CC5">2e3</span><span style="color:#24292E">,</span><span style="color:#005CC5">1e3</span><span style="color:#24292E">,</span><span style="color:#005CC5">500</span><span style="color:#24292E">,</span><span style="color:#005CC5">100</span><span style="color:#24292E">,</span><span style="color:#005CC5">50</span><span style="color:#24292E">,</span><span style="color:#005CC5">10</span><span style="color:#24292E">,</span><span style="color:#005CC5">5</span><span style="color:#24292E">,</span><span style="color:#005CC5">1</span><span style="color:#24292E">]</span><span style="color:#D73A49">as</span><span style="color:#24292E">$x)</span><span style="color:#D73A49">for</span><span style="color:#24292E">(;$n</span><span style="color:#D73A49">>=</span><span style="color:#24292E">$x;$n</span><span style="color:#D73A49">-=</span><span style="color:#24292E">$x)$r[]</span><span style="color:#D73A49">=</span><span style="color:#24292E">$x;</span><span style="color:#005CC5">echo</span><span style="color:#005CC5"> implode</span><span style="color:#24292E">(</span><span style="color:#032F62">', '</span><span style="color:#24292E">,$r</span><span style="color:#D73A49">??</span><span style="color:#24292E">[]);</span><span style="color:#D73A49">?></span><span style="color:#24292E">]</span></span></code></pre>
- </div>
- <p>
- しめて 123 バイトとなった (末尾改行を含めずにカウント)。
- </p>
- <p>
- こちらは改行とスペースを追加したバージョン:
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">[</span><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E">$n </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $argv[</span><span style="color:#005CC5">1</span><span style="color:#24292E">];</span></span>
-<span class="line"><span style="color:#D73A49">foreach</span><span style="color:#24292E"> ([</span><span style="color:#005CC5">1e4</span><span style="color:#24292E">, </span><span style="color:#005CC5">5e3</span><span style="color:#24292E">, </span><span style="color:#005CC5">2e3</span><span style="color:#24292E">, </span><span style="color:#005CC5">1e3</span><span style="color:#24292E">, </span><span style="color:#005CC5">500</span><span style="color:#24292E">, </span><span style="color:#005CC5">100</span><span style="color:#24292E">, </span><span style="color:#005CC5">50</span><span style="color:#24292E">, </span><span style="color:#005CC5">10</span><span style="color:#24292E">, </span><span style="color:#005CC5">5</span><span style="color:#24292E">, </span><span style="color:#005CC5">1</span><span style="color:#24292E">] </span><span style="color:#D73A49">as</span><span style="color:#24292E"> $x)</span></span>
-<span class="line"><span style="color:#D73A49"> for</span><span style="color:#24292E"> (; $n </span><span style="color:#D73A49">>=</span><span style="color:#24292E"> $x; $n </span><span style="color:#D73A49">-=</span><span style="color:#24292E"> $x)</span></span>
-<span class="line"><span style="color:#24292E"> $r[] </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $x;</span></span>
-<span class="line"><span style="color:#005CC5">echo</span><span style="color:#005CC5"> implode</span><span style="color:#24292E">(</span><span style="color:#032F62">', '</span><span style="color:#24292E">, $r </span><span style="color:#D73A49">??</span><span style="color:#24292E"> []);</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">?></span><span style="color:#24292E">]</span></span></code></pre>
- </div>
- </section>
- <section id="section--techniques">
- <h2><a href="#section--techniques">使用したテクニック</a></h2>
- <section id="section--techniques--exponential-notation">
- <h3><a href="#section--techniques--exponential-notation">指数表記</a></h3>
- <p>
- 割と多くの言語のゴルフで使えるテクニック。<code>e</code> を用いた指数表記で、大きな数を短く表す。このコードでは <code>10000</code>、<code>5000</code>、<code>2000</code>、<code>1000</code> を指数表記している。
- </p>
- </section>
- <section id="section--techniques--shorten-loop">
- <h3><a href="#section--techniques--shorten-loop">foreach や for の中身を1つの文に</a></h3>
- <p>
- <code>foreach</code>、<code>for</code>、<code>if</code> などの後ろには、通常 <code>{</code> を続けて複数の文を連ねるが、中身の文を1つにしてしまえば、<code>{</code> と <code>}</code> を省略できる。C言語などでも使える。
- </p>
- </section>
- <section id="section--techniques--omit-initialization">
- <h3><a href="#section--techniques--omit-initialization">$r に初期値を入れない</a></h3>
- <p>
- PHP では、<code>$r[] = ......</code> のような配列の末尾に追加する式を実行したとき、<code>$r</code> が未定義だった場合は <code>$r</code> を勝手に定義して空の配列で初期化してくれる。これを利用すると、<code>$r = [];</code> のような初期化が不要になる。
- </p>
- <p>
- ただし、プログラムに 0 が渡されるとループを一度も回らないので、<code>$r</code> が未定義になってしまい、<code>implode()</code> に渡すところでエラーになる。それを防ぐために <code>$r ?? []</code> を使っている。
- </p>
- <p>
- もし 0 が渡されたケースを無視するなら、これが不要になるので 4 バイト縮む。
- </p>
- </section>
- <section id="section--techniques--put-text-outside-php-tag">
- <h3><a href="#section--techniques--put-text-outside-php-tag">PHP タグの外に文字列を置く</a></h3>
- <p>
- PHP では、<code>&lt;?php</code> <code>?&gt;</code> で囲われた部分の外側にある文字列は、そのまま出力される。今回のケースでは、先頭と末尾に必ず <code>[</code> と <code>]</code> を出力するので、そのまま書いてやればよい。
- </p>
- </section>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">おわりに</a></h2>
- <p>
- 最後になりましたが、 <a href="https://twitter.com/m3m0r7" rel="noreferrer" target="_blank">めもりー</a> さん、楽しい問題をありがとうございました。
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2022-08-31/support-for-communty-is-employee-benefits/index.html b/vhosts/blog/public/posts/2022-08-31/support-for-communty-is-employee-benefits/index.html
deleted file mode 100644
index 3f5c70e8..00000000
--- a/vhosts/blog/public/posts/2022-08-31/support-for-communty-is-employee-benefits/index.html
+++ /dev/null
@@ -1,108 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2022 nsfisis">
- <meta name="description" content="先日、私の勤めるデジタルサーカス株式会社が、PHP Foundation へ寄付をおこないました。本件を社内でしつこく推進した1人として、推進の理由等を書き残しておきます。">
- <meta property="og:type" content="article">
- <meta property="og:title" content="弊社の PHP Foundation への寄付に寄せて|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="先日、私の勤めるデジタルサーカス株式会社が、PHP Foundation へ寄付をおこないました。本件を社内でしつこく推進した1人として、推進の理由等を書き残しておきます。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>弊社の PHP Foundation への寄付に寄せて|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">弊社の PHP Foundation への寄付に寄せて</h1>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2022-08-31">2022-08-31</time>: 公開
- </li>
- </ol>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- <strong>注: これは私個人の意見であり、所属する組織を代表するものではありません。</strong>
- </p>
- <p>
- 先日、私の勤める <a href="https://www.dgcircus.com/" rel="noreferrer" target="_blank">デジタルサーカス株式会社</a> が <a href="https://opencollective.com/phpfoundation" rel="noreferrer" target="_blank">PHP Foundation</a> へ $2,000 の寄付をおこないました。
- </p>
- <p>
- 記事: <a href="https://www.dgcircus.com/news/581" rel="noreferrer" target="_blank">https://www.dgcircus.com/news/581</a>
- </p>
- <p>
- 本件を社内でしつこく推進した1人として、推進の理由等を書き残しておきます。
- </p>
- </section>
- <section id="section--why">
- <h2><a href="#section--why">なぜ?</a></h2>
- <p>
- 組織としての寄付理由は前掲した記事に譲るとして、ここでは、私が社内でこの件を推進した理由について書くことにします。
- </p>
- <p>
- 当時の考えを端的にまとめた社内チャットの投稿があったので、それを引用します:
- </p>
- <blockquote>
- <p>
- 結局これを通したい (私の中での) 最大の理由が、「自分の勤める会社が、これをやる会社であってほしい」というのがあり、↑にしても、感情ベースの理由しか出せていないというのが説得力に欠けている理由なのだと思いますが、寄付の報告が流れてきたり、OSS のフリーライドの話が流れてきたりするたびに、自尊心が毀損される、というか (これは大袈裟すぎる表現で、実際にはそこまで明確に傷ついているわけではありませんが)。
- </p>
- <p>
- 追記: 「肩身が狭くなる」というのがより適切でした。
- </p>
- </blockquote>
- <p>
- ※文中の「↑にしても」は、ここに載せていない別の投稿を指しています。
- </p>
- <p>
- OSS を金銭的に支援したり、技術カンファレンスへ協賛したり (あるいは <a href="https://twitter.com/tomzoh" rel="noreferrer" target="_blank">CTO</a> がカンファレンスを年2で主催したり: <a href="https://iosdc.jp" rel="noreferrer" target="_blank">iOSDC</a> <a href="https://phperkaigi.jp" rel="noreferrer" target="_blank">PHPerKaigi</a> ) といった行為は、コミュニティへの貢献であると同時に、社員に対する精神的福利厚生でもあると言えるでしょう (知らんけど)。これらは、技術や技術者を大切にする組織である、ということの、対外的にも対内的にも強力なメッセージなのです。
- </p>
- <p>
- 以上が、私が社内で寄付の件を進めた (かなり私的な) 理由です。
- </p>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">おわりに</a></h2>
- <p>
- 最終的に社としての寄付まで漕ぎ着けられたのは、もちろん私の力ではなく役員の方々の決定によるものです。この場を借りて感謝申し上げます。
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2022-09-29/write-fizzbuzz-in-php-2-letters-per-line/index.html b/vhosts/blog/public/posts/2022-09-29/write-fizzbuzz-in-php-2-letters-per-line/index.html
deleted file mode 100644
index ab8c9867..00000000
--- a/vhosts/blog/public/posts/2022-09-29/write-fizzbuzz-in-php-2-letters-per-line/index.html
+++ /dev/null
@@ -1,704 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2022 nsfisis">
- <meta name="description" content="PHP で fizzbuzz を書いた。ただし、1行あたりに使える文字数は2文字まで。">
- <meta name="keywords" content="PHP">
- <meta property="og:type" content="article">
- <meta property="og:title" content="【PHP】 fizzbuzz を書く。1行あたり2文字で。|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="PHP で fizzbuzz を書いた。ただし、1行あたりに使える文字数は2文字まで。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>【PHP】 fizzbuzz を書く。1行あたり2文字で。|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">【PHP】 fizzbuzz を書く。1行あたり2文字で。</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2022-09-28">2022-09-28</time>: 公開
- </li>
- <li class="revision">
- <time datetime="2022-09-29">2022-09-29</time>: 小さな文言の修正・変更
- </li>
- </ol>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">記事の構成について</a></h2>
- <p>
- この記事は、普通の fizzbuzz を徐々に変形して最終形にしていく、という構成で書かれている。最終形を見てどのような仕組みで動いているのか解読してから解説を読みたい、というかたがいれば、<a href="https://gist.github.com/nsfisis/04c227d5a419867472a0b23a83ad2919#file-fizzbuzz-php-2-letters-per-line-and-supports-php-8-x-without-warnings" rel="noreferrer" target="_blank">このページ</a> にソースコードがあるので、そちらを先に見てほしい。
- </p>
- </section>
- <section id="section--regulations">
- <h2><a href="#section--regulations">レギュレーション</a></h2>
- <p>
- PHP で、次のような制約の下に fizzbuzz を書いた。
- </p>
- <ul>
- <li>
- 1行あたりの文字数は2文字までに収めること (ただし <code>&lt;?php</code> タグは除く)
- <ul>
- <li>
- 厳密な定義: <code>&lt;?php</code> タグ以降のソースコードが、2 byte ごとにラインフィード (LF) で区切られること
- </li>
- </ul>
- </li>
- <li>
- スペースやタブを使用しないこと
- </li>
- <li>
- ループのアンロールをしないこと
- <ul>
- <li>
- 100 回ループの代わりに 100 回コードをコピペ、というのは禁止
- </li>
- </ul>
- </li>
- <li>
- PHP 7.4〜8.1 で動作すること
- </li>
- <li>
- 実行時に Notice や Warning が出ないこと
- </li>
- <li>
- 標準的なインストール構成の PHP で実現できること (デフォルトで有効になっていない拡張等を使わないこと)
- </li>
- </ul>
- <p>
- 備考: PHP には <code>short_open_tag</code> というオプションがあり、これを有効にするとファイル冒頭の <code>&lt;?php</code> の代わりに <code>&lt;?</code> を使うことができ、文字どおり1行2文字で書ける。ただ、このオプションはデフォルト off になっている環境が多いようなので、今回は使わないことにした。
- </p>
- </section>
- <section id="section--problems">
- <h2><a href="#section--problems">主な障害</a></h2>
- <p>
- 1行あたりの文字数など、適当に改行を挟めばいいだけではないのか?
- </p>
- <p>
- 特に、C言語でこのような試みをおこなったことがあるかたならそう思うだろう。事実、Cでのこの制約はほとんど無意味に等しい。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">#</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#24292E">i</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#24292E">n</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#24292E">c</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#24292E">l</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#24292E">u</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#24292E">d</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#24292E">e</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#D73A49">&#x3C;</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#24292E">s</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#24292E">t</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#24292E">d</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#24292E">i</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#24292E">o</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#24292E">.</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#24292E">h</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#D73A49">></span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#6A737D">/*</span></span>
-<span class="line"><span style="color:#6A737D">*/</span></span>
-<span class="line"><span style="color:#24292E">i</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#24292E">n</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#24292E">t</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#6A737D">/*</span></span>
-<span class="line"><span style="color:#6A737D">*/</span></span>
-<span class="line"><span style="color:#24292E">m</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#24292E">a</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#24292E">i</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#6F42C1">n</span><span style="color:#24292E">(</span></span>
-<span class="line"><span style="color:#24292E">){</span></span>
-<span class="line"><span style="color:#24292E">f</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#24292E">o</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#6F42C1">r</span><span style="color:#24292E">(</span></span>
-<span class="line"><span style="color:#24292E">i</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#24292E">n</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#24292E">t</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#6A737D">/*</span></span>
-<span class="line"><span style="color:#6A737D">*/</span></span>
-<span class="line"><span style="color:#24292E">i</span><span style="color:#D73A49">=</span></span>
-<span class="line"><span style="color:#005CC5">1</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">i</span><span style="color:#D73A49">&#x3C;</span></span>
-<span class="line"><span style="color:#005CC5">1\</span></span>
-<span class="line"><span style="color:#005CC5">0\</span></span>
-<span class="line"><span style="color:#005CC5">0</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">i</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#D73A49">+</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#D73A49">+</span><span style="color:#24292E">)</span></span>
-<span class="line"><span style="color:#D73A49">if</span></span>
-<span class="line"><span style="color:#24292E">(i</span></span>
-<span class="line"><span style="color:#D73A49">%</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#005CC5">15</span></span>
-<span class="line"><span style="color:#D73A49">==</span></span>
-<span class="line"><span style="color:#005CC5">0</span><span style="color:#24292E">)</span></span>
-<span class="line"><span style="color:#24292E">p</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#24292E">r</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#24292E">i</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#24292E">n</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#24292E">t</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#6F42C1">f</span><span style="color:#24292E">(</span></span>
-<span class="line"><span style="color:#032F62">"</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#032F62">F</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#032F62">i</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#032F62">z</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#032F62">z</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#032F62">B</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#032F62">u</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#032F62">z</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#032F62">z</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#B31D28;font-style:italic">%</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#032F62">c</span><span style="color:#005CC5">\</span></span>
-<span class="line"><span style="color:#032F62">"</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#005CC5">10</span></span>
-<span class="line"><span style="color:#24292E">);</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#6A737D">/* あとは同じように普通のプログラムを変形するだけなので省略 */</span></span></code></pre>
- </div>
- <p>
- バックスラッシュを使った行継続がトークンを区切らない、というのがポイントだ。
- </p>
- <p>
- さて、PHP ではそもそもバックスラッシュを行継続に使うことができない。これにより、「3文字以上からなるトークンが一切使えない」という制約が課される。例えば、<code>echo</code> で出力することや、<code>for</code> でループすること、<code>new</code> でインスタンスを生成することができない。特に、出力は fizzbuzz をどんなアルゴリズムで実装しようとおこなわなければならないので、できないのは致命的である。
- </p>
- <p>
- 当然、名前が3文字以上ある関数も使えない。なお、標準 PHP の範囲内において、名前が 2文字以下の関数は以下のとおりである:
- </p>
- <ul>
- <li>
- <code>_</code>: <code>gettext</code> のエイリアス
- </li>
- <li>
- <code>dl</code>: 拡張モジュールをロードする
- </li>
- <li>
- <code>pi</code>: 円周率を返す
- </li>
- </ul>
- <p>
- (環境によって多少は変わるかも)
- </p>
- <p>
- 2文字の関数を定義しまくった拡張モジュールを用意しておいて <code>dl()</code> で読み込む行為は、レギュレーションで定めた
- </p>
- <blockquote>
- <ul>
- <li>
- 標準的なインストール構成の PHP で実現できること (デフォルトで有効になっていない拡張等を使わないこと)
- </li>
- </ul>
- </blockquote>
- <p>
- に反する (というより、「それだとおもしろくもなんともないので、このルールを足した」というのが正しい)。
- </p>
- <p>
- また、2文字だと文字列がまともに書けないのも辛い。<code>&apos;&apos;</code> だけで2文字使うので、「1文字の文字列リテラル」というものを書くことができない。PHP では文字列リテラル中に生の改行が書けるので
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">$a</span></span>
-<span class="line"><span style="color:#D73A49">=</span><span style="color:#032F62">'</span></span>
-<span class="line"><span style="color:#032F62">a'</span></span>
-<span class="line"><span style="color:#24292E">;;</span></span></code></pre>
- </div>
- <p>
- とすると <code>$a</code> は <code>&quot;\na&quot;</code> になるのだが、余計な改行が入ってしまう。
- </p>
- <p>
- これらの障害をどのように乗り越えるのか、次節から見ていく。
- </p>
- </section>
- <section id="section--commentary">
- <h2><a href="#section--commentary">解説</a></h2>
- <section id="section--commentary--normal-fizzbuzz">
- <h3><a href="#section--commentary--normal-fizzbuzz">普通の (?) fizzbuzz</a></h3>
- <p>
- まずは普通に書くとしよう。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">for</span><span style="color:#24292E"> ($i </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> 1</span><span style="color:#24292E">; $i </span><span style="color:#D73A49">&#x3C;</span><span style="color:#005CC5"> 100</span><span style="color:#24292E">; $i</span><span style="color:#D73A49">++</span><span style="color:#24292E">) {</span></span>
-<span class="line"><span style="color:#005CC5"> echo</span><span style="color:#24292E"> (($i </span><span style="color:#D73A49">%</span><span style="color:#005CC5"> 3</span><span style="color:#D73A49"> ?</span><span style="color:#032F62"> ''</span><span style="color:#D73A49"> :</span><span style="color:#032F62"> 'Fizz'</span><span style="color:#24292E">) </span><span style="color:#D73A49">.</span><span style="color:#24292E"> ($i </span><span style="color:#D73A49">%</span><span style="color:#005CC5"> 5</span><span style="color:#D73A49"> ?</span><span style="color:#032F62"> ''</span><span style="color:#D73A49"> :</span><span style="color:#032F62"> 'Buzz'</span><span style="color:#24292E">) </span><span style="color:#D73A49">?:</span><span style="color:#24292E"> $i) </span><span style="color:#D73A49">.</span><span style="color:#032F62"> "</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">}</span></span></code></pre>
- </div>
- <p>
- 素直に書いた fizzbuzz とは言い難いが、このくらいは普通だということにしておかないと、この先がやっていられないので許してほしい。
- </p>
- </section>
- <section id="section--commentary--remove-keywords">
- <h3><a href="#section--commentary--remove-keywords"><code>for</code> の排除</a></h3>
- <p>
- <code>for</code> は、3文字もある長いキーワードである。こんなものは使えない。<code>array_</code> 系の関数を使って、適当に置き換えるとしよう。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E">$s </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> range</span><span style="color:#24292E">(</span><span style="color:#005CC5">1</span><span style="color:#24292E">, </span><span style="color:#005CC5">100</span><span style="color:#24292E">);</span></span>
-<span class="line"><span style="color:#005CC5">array_walk</span><span style="color:#24292E">(</span></span>
-<span class="line"><span style="color:#24292E">$s,</span></span>
-<span class="line"><span style="color:#D73A49">fn</span><span style="color:#24292E">($i) =></span></span>
-<span class="line"><span style="color:#005CC5">printf</span><span style="color:#24292E">((($i </span><span style="color:#D73A49">%</span><span style="color:#005CC5"> 3</span><span style="color:#D73A49"> ?</span><span style="color:#032F62"> ''</span><span style="color:#D73A49"> :</span><span style="color:#032F62"> 'Fizz'</span><span style="color:#24292E">) </span><span style="color:#D73A49">.</span><span style="color:#24292E"> ($i </span><span style="color:#D73A49">%</span><span style="color:#005CC5"> 5</span><span style="color:#D73A49"> ?</span><span style="color:#032F62"> ''</span><span style="color:#D73A49"> :</span><span style="color:#032F62"> 'Buzz'</span><span style="color:#24292E">) </span><span style="color:#D73A49">?:</span><span style="color:#24292E"> $i) </span><span style="color:#D73A49">.</span><span style="color:#032F62"> "</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">),</span></span>
-<span class="line"><span style="color:#24292E">);</span></span></code></pre>
- </div>
- <p>
- <code>array_walk</code> や <code>range</code>、<code>printf</code> といった <code>for</code> よりも長いトークンが現れてしまったが、これは次節で直すことにする。なお、<code>echo</code> は文 (statement) であり式 (expression) ではないので、式である <code>printf</code> に置き換えた。
- </p>
- </section>
- <section id="section--commentary--shorten-function-invocation">
- <h3><a href="#section--commentary--shorten-function-invocation">関数呼び出しの短縮</a></h3>
- <p>
- <code>range</code>、<code>array_walk</code>、<code>printf</code> は長すぎるのでどうにかせねばならない。ここで、PHP の可変関数を使う。可変関数とは、関数名が文字列として入った変数を経由して、関数を呼び出す機能である。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E">$r </span><span style="color:#D73A49">=</span><span style="color:#032F62"> 'range'</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">$w </span><span style="color:#D73A49">=</span><span style="color:#032F62"> 'array_walk'</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">$p </span><span style="color:#D73A49">=</span><span style="color:#032F62"> 'printf'</span><span style="color:#24292E">;</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E">$s </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $r(</span><span style="color:#005CC5">1</span><span style="color:#24292E">, </span><span style="color:#005CC5">100</span><span style="color:#24292E">);</span></span>
-<span class="line"><span style="color:#24292E">$w(</span></span>
-<span class="line"><span style="color:#24292E">$s,</span></span>
-<span class="line"><span style="color:#D73A49">fn</span><span style="color:#24292E">($i) =></span></span>
-<span class="line"><span style="color:#24292E">$p((($i </span><span style="color:#D73A49">%</span><span style="color:#005CC5"> 3</span><span style="color:#D73A49"> ?</span><span style="color:#032F62"> ''</span><span style="color:#D73A49"> :</span><span style="color:#032F62"> 'Fizz'</span><span style="color:#24292E">) </span><span style="color:#D73A49">.</span><span style="color:#24292E"> ($i </span><span style="color:#D73A49">%</span><span style="color:#005CC5"> 5</span><span style="color:#D73A49"> ?</span><span style="color:#032F62"> ''</span><span style="color:#D73A49"> :</span><span style="color:#032F62"> 'Buzz'</span><span style="color:#24292E">) </span><span style="color:#D73A49">?:</span><span style="color:#24292E"> $i) </span><span style="color:#D73A49">.</span><span style="color:#032F62"> "</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">),</span></span>
-<span class="line"><span style="color:#24292E">);</span></span></code></pre>
- </div>
- <p>
- これで関数を呼び出している所は短くなった。では、<code>$r</code> や <code>$w</code> や <code>$p</code>、また <code>&apos;Fizz&apos;</code> や <code>&apos;Buzz&apos;</code> はどうやって 1 行 2 文字に収めるのか。次のテクニックへ移ろう。
- </p>
- </section>
- <section id="section--commentary--incompatible-solution">
- <h3><a href="#section--commentary--incompatible-solution">余談: PHP 8.x で動作しなくてもいいなら</a></h3>
- <p>
- 今回使ったテクニックを説明する前に、余談として、文字列リテラルの短縮法として今回採用しなかったものを紹介する。
- </p>
- <blockquote>
- <ul>
- <li>
- PHP 7.4〜8.1 で動作すること
- </li>
- </ul>
- </blockquote>
- <p>
- というルールがない場合、「未定義の定数が評価された場合、その定数の名前が値になる」という PHP 7.x までの仕様が利用できる。例えば、 <code>Fizz</code> という文字列が欲しければ、次のようにする。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">$f</span></span>
-<span class="line"><span style="color:#D73A49">=</span><span style="color:#005CC5">F</span></span>
-<span class="line"><span style="color:#D73A49">.</span><span style="color:#005CC5">i</span></span>
-<span class="line"><span style="color:#D73A49">.</span><span style="color:#005CC5">z</span></span>
-<span class="line"><span style="color:#D73A49">.</span><span style="color:#005CC5">z</span></span>
-<span class="line"><span style="color:#24292E">;;</span></span></code></pre>
- </div>
- <p>
- こうして簡単に文字列を作れる。なお、この仕様は 7.x 時点でも警告を受けるので、<code>@</code> 演算子を使って抑制してやるとよい。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">$f</span></span>
-<span class="line"><span style="color:#D73A49">=@</span></span>
-<span class="line"><span style="color:#005CC5">F</span><span style="color:#D73A49">.</span></span>
-<span class="line"><span style="color:#D73A49">@</span><span style="color:#005CC5">i</span></span>
-<span class="line"><span style="color:#D73A49">.</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#D73A49">@</span><span style="color:#005CC5">z</span></span>
-<span class="line"><span style="color:#D73A49">.</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#D73A49">@</span><span style="color:#005CC5">z</span></span>
-<span class="line"><span style="color:#24292E">;;</span></span></code></pre>
- </div>
- <p>
- むしろ、このことがわかっていたからこそ PHP 8.x での動作を要件に課したところがある。
- </p>
- </section>
- <section id="section--commentary--shorten-string-literals">
- <h3><a href="#section--commentary--shorten-string-literals">文字列リテラルの短縮</a></h3>
- <p>
- 実際に使った手法の説明に移る。
- </p>
- <p>
- ずばり、文字列同士のビット演算を使う。PHP では、文字列同士でビット演算 (<code>&amp;</code>、<code>|</code>、<code>^</code>) をした場合、文字列の各バイトごとに指定したビット演算がなされ、それを結合したものが演算結果となる。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">$a </span><span style="color:#D73A49">=</span><span style="color:#032F62"> "12345"</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">$b </span><span style="color:#D73A49">=</span><span style="color:#032F62"> "world"</span><span style="color:#24292E">;</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#6A737D">// $a ^ $b は次のコードと同じ</span></span>
-<span class="line"><span style="color:#24292E">$result </span><span style="color:#D73A49">=</span><span style="color:#032F62"> ''</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#D73A49">for</span><span style="color:#24292E"> ($i </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">; $i </span><span style="color:#D73A49">&#x3C;</span><span style="color:#005CC5"> min</span><span style="color:#24292E">(</span><span style="color:#005CC5">strlen</span><span style="color:#24292E">($a), </span><span style="color:#005CC5">strlen</span><span style="color:#24292E">($b)); $i</span><span style="color:#D73A49">++</span><span style="color:#24292E">) {</span></span>
-<span class="line"><span style="color:#24292E">$result </span><span style="color:#D73A49">.=</span><span style="color:#24292E"> $a[$i] </span><span style="color:#D73A49">^</span><span style="color:#24292E"> $b[$i];</span></span>
-<span class="line"><span style="color:#24292E">}</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#005CC5">echo</span><span style="color:#24292E"> $result;</span></span>
-<span class="line"><span style="color:#6A737D">// => F]AXQ</span></span></code></pre>
- </div>
- <p>
- これを踏まえ、次のコードを見てみよう。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">$x </span><span style="color:#D73A49">=</span><span style="color:#032F62"> "x</span><span style="color:#005CC5">\n</span><span style="color:#032F62">Om</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">$y </span><span style="color:#D73A49">=</span><span style="color:#032F62"> "</span><span style="color:#005CC5">\n</span><span style="color:#032F62">k!</span><span style="color:#005CC5">\n</span><span style="color:#032F62">o"</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">$r </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $x </span><span style="color:#D73A49">^</span><span style="color:#24292E"> $y;</span></span>
-<span class="line"><span style="color:#005CC5">echo</span><span style="color:#032F62"> "</span><span style="color:#24292E">$r</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">;</span></span></code></pre>
- </div>
- <p>
- 実行すると、<code>range</code> が表示される。さて、PHP では文字列リテラル中に生の改行を直接書いてもよいのだった (「主な障害」の節を参照のこと)。書きかえてみよう。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">$x</span></span>
-<span class="line"><span style="color:#D73A49">=</span><span style="color:#032F62">'x</span></span>
-<span class="line"><span style="color:#032F62">Om</span></span>
-<span class="line"><span style="color:#032F62">'</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">$y</span></span>
-<span class="line"><span style="color:#D73A49">=</span><span style="color:#032F62">'</span></span>
-<span class="line"><span style="color:#032F62">k!</span></span>
-<span class="line"><span style="color:#032F62">o'</span></span>
-<span class="line"><span style="color:#24292E">;</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E">$r </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $x </span><span style="color:#D73A49">^</span><span style="color:#24292E"> $y;</span></span>
-<span class="line"><span style="color:#005CC5">echo</span><span style="color:#032F62"> "</span><span style="color:#24292E">$r</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">;</span></span></code></pre>
- </div>
- <p>
- さらに <code>#</code> を使って適当に調整すると、次のようになる。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">$x</span></span>
-<span class="line"><span style="color:#D73A49">=</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#032F62">'x</span></span>
-<span class="line"><span style="color:#032F62">Om</span></span>
-<span class="line"><span style="color:#032F62">'</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">$y</span></span>
-<span class="line"><span style="color:#D73A49">=</span><span style="color:#032F62">'</span></span>
-<span class="line"><span style="color:#032F62">k!</span></span>
-<span class="line"><span style="color:#032F62">o'</span></span>
-<span class="line"><span style="color:#24292E">;</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#24292E">$r</span></span>
-<span class="line"><span style="color:#D73A49">=</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#24292E">$x</span></span>
-<span class="line"><span style="color:#D73A49">^</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#24292E">$y</span></span>
-<span class="line"><span style="color:#24292E">;</span><span style="color:#6A737D">#</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#005CC5">echo</span><span style="color:#032F62"> "</span><span style="color:#24292E">$r</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">;</span></span></code></pre>
- </div>
- <p>
- 1行あたり2文字で、<code>range</code> という文字列を生成することに成功した。他の必要な文字列にも、同様の処理をほどこす。
- </p>
- <p>
- 備考: <code>Buzz</code> 中にある小文字の <code>u</code> は、このロジックだと non-printable な文字になってしまう。ここまでのテクニックを駆使すれば回避するのはそう難しくないので、考えてみてほしい。
- </p>
- </section>
- </section>
- <section id="section--stretched-fizzbuzz">
- <h2><a href="#section--stretched-fizzbuzz">完成系</a></h2>
- <p>
- 完成したものがこちら。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E">$x</span></span>
-<span class="line"><span style="color:#D73A49">=</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#032F62">'i</span></span>
-<span class="line"><span style="color:#032F62">S'</span></span>
-<span class="line"><span style="color:#24292E">;;</span></span>
-<span class="line"><span style="color:#24292E">$y</span></span>
-<span class="line"><span style="color:#D73A49">=</span><span style="color:#032F62">'</span></span>
-<span class="line"><span style="color:#032F62">b!</span></span>
-<span class="line"><span style="color:#032F62">'</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">$c</span></span>
-<span class="line"><span style="color:#D73A49">=</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#24292E">$x</span></span>
-<span class="line"><span style="color:#D73A49">^</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#24292E">$y</span></span>
-<span class="line"><span style="color:#24292E">;</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#24292E">$x</span></span>
-<span class="line"><span style="color:#D73A49">=</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#032F62">'x</span></span>
-<span class="line"><span style="color:#032F62">Om</span></span>
-<span class="line"><span style="color:#032F62">'</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">$y</span></span>
-<span class="line"><span style="color:#D73A49">=</span><span style="color:#032F62">'</span></span>
-<span class="line"><span style="color:#032F62">k!</span></span>
-<span class="line"><span style="color:#032F62">o'</span></span>
-<span class="line"><span style="color:#24292E">;</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#24292E">$r</span></span>
-<span class="line"><span style="color:#D73A49">=</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#24292E">$x</span></span>
-<span class="line"><span style="color:#D73A49">^</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#24292E">$y</span></span>
-<span class="line"><span style="color:#24292E">;</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#24292E">$x</span></span>
-<span class="line"><span style="color:#D73A49">=</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#032F62">'k</span></span>
-<span class="line"><span style="color:#032F62">Sk</span></span>
-<span class="line"><span style="color:#032F62">~}</span></span>
-<span class="line"><span style="color:#032F62">Ma</span></span>
-<span class="line"><span style="color:#032F62">'</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">$y</span></span>
-<span class="line"><span style="color:#D73A49">=</span><span style="color:#032F62">'</span></span>
-<span class="line"><span style="color:#032F62">x!</span></span>
-<span class="line"><span style="color:#032F62">s!</span></span>
-<span class="line"><span style="color:#032F62">k!</span></span>
-<span class="line"><span style="color:#032F62">'</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">$w</span></span>
-<span class="line"><span style="color:#D73A49">=</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#24292E">$x</span></span>
-<span class="line"><span style="color:#D73A49">^</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#24292E">$y</span></span>
-<span class="line"><span style="color:#24292E">;</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#24292E">$x</span></span>
-<span class="line"><span style="color:#D73A49">=</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#032F62">'z</span></span>
-<span class="line"><span style="color:#032F62">Hd</span></span>
-<span class="line"><span style="color:#032F62">G'</span></span>
-<span class="line"><span style="color:#24292E">;</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#24292E">$y</span></span>
-<span class="line"><span style="color:#D73A49">=</span><span style="color:#032F62">'</span></span>
-<span class="line"><span style="color:#032F62">x!</span></span>
-<span class="line"><span style="color:#032F62">~!</span></span>
-<span class="line"><span style="color:#032F62">'</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">$p</span></span>
-<span class="line"><span style="color:#D73A49">=</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#24292E">$x</span></span>
-<span class="line"><span style="color:#D73A49">^</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#24292E">$y</span></span>
-<span class="line"><span style="color:#24292E">;</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#24292E">$x</span></span>
-<span class="line"><span style="color:#D73A49">=</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#032F62">'L</span></span>
-<span class="line"><span style="color:#032F62">[p</span></span>
-<span class="line"><span style="color:#032F62">'</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">$y</span></span>
-<span class="line"><span style="color:#D73A49">=</span><span style="color:#032F62">'</span></span>
-<span class="line"><span style="color:#032F62">c!</span></span>
-<span class="line"><span style="color:#032F62">'</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">$f</span></span>
-<span class="line"><span style="color:#D73A49">=</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#24292E">$x</span></span>
-<span class="line"><span style="color:#D73A49">^</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#24292E">$y</span></span>
-<span class="line"><span style="color:#24292E">;</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#24292E">$x</span></span>
-<span class="line"><span style="color:#D73A49">=</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#032F62">'H</span></span>
-<span class="line"><span style="color:#032F62">[p</span></span>
-<span class="line"><span style="color:#032F62">'</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">$y</span></span>
-<span class="line"><span style="color:#D73A49">=</span><span style="color:#032F62">'</span></span>
-<span class="line"><span style="color:#032F62">_!</span></span>
-<span class="line"><span style="color:#032F62">'</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">$b</span></span>
-<span class="line"><span style="color:#D73A49">=</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#24292E">$x</span></span>
-<span class="line"><span style="color:#D73A49">^</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#24292E">$y</span></span>
-<span class="line"><span style="color:#24292E">;</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#24292E">$b</span></span>
-<span class="line"><span style="color:#24292E">[</span><span style="color:#005CC5">1</span></span>
-<span class="line"><span style="color:#24292E">]</span><span style="color:#D73A49">=</span></span>
-<span class="line"><span style="color:#24292E">$c</span></span>
-<span class="line"><span style="color:#24292E">(</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#005CC5">13</span></span>
-<span class="line"><span style="color:#D73A49">*</span><span style="color:#005CC5">9</span></span>
-<span class="line"><span style="color:#24292E">);</span></span>
-<span class="line"><span style="color:#24292E">$s</span></span>
-<span class="line"><span style="color:#D73A49">=</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#24292E">$r</span></span>
-<span class="line"><span style="color:#24292E">(</span><span style="color:#005CC5">1</span></span>
-<span class="line"><span style="color:#24292E">,(</span></span>
-<span class="line"><span style="color:#005CC5">10</span></span>
-<span class="line"><span style="color:#D73A49">**</span></span>
-<span class="line"><span style="color:#005CC5">2</span><span style="color:#24292E">)</span></span>
-<span class="line"><span style="color:#24292E">);</span></span>
-<span class="line"><span style="color:#24292E">$w</span></span>
-<span class="line"><span style="color:#24292E">(</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#24292E">$s</span></span>
-<span class="line"><span style="color:#24292E">,</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#005CC5">fn</span></span>
-<span class="line"><span style="color:#24292E">(</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#24292E">$i</span></span>
-<span class="line"><span style="color:#24292E">)</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#D73A49">=></span></span>
-<span class="line"><span style="color:#24292E">$p</span></span>
-<span class="line"><span style="color:#24292E">((</span></span>
-<span class="line"><span style="color:#24292E">(</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#24292E">$i</span></span>
-<span class="line"><span style="color:#D73A49">%</span><span style="color:#005CC5">3</span></span>
-<span class="line"><span style="color:#D73A49">?</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#032F62">''</span></span>
-<span class="line"><span style="color:#D73A49">:</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#24292E">$f</span></span>
-<span class="line"><span style="color:#24292E">)</span><span style="color:#D73A49">.</span></span>
-<span class="line"><span style="color:#24292E">(</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#24292E">$i</span></span>
-<span class="line"><span style="color:#D73A49">%</span><span style="color:#005CC5">5</span></span>
-<span class="line"><span style="color:#D73A49">?</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#032F62">''</span></span>
-<span class="line"><span style="color:#D73A49">:</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#24292E">$b</span></span>
-<span class="line"><span style="color:#24292E">)</span><span style="color:#D73A49">?</span></span>
-<span class="line"><span style="color:#D73A49">:</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#24292E">$i</span></span>
-<span class="line"><span style="color:#24292E">)</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#D73A49">.</span><span style="color:#032F62">'</span></span>
-<span class="line"><span style="color:#032F62">'</span><span style="color:#24292E">)</span></span>
-<span class="line"><span style="color:#24292E">);</span></span></code></pre>
- </div>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">感想など</a></h2>
- <p>
- PHP は、スクリプト言語の中だとシンタックスシュガーが少ない (体感)。この挑戦は不可能に思われたが、PHP マニュアルとにらめっこしていたらなんとかなった。
- </p>
- <p>
- みんなもプログラムを細長くしよう。
- </p>
- </section>
- <section id="section--alternative-solution">
- <h2><a href="#section--alternative-solution">余談2: 別解</a></h2>
- <p>
- PHP では、バッククォートを使ってシェルを呼び出せる。これは <code>shell_exec</code> 関数と等価である。さて、PHP ではバックスラッシュによる行継続が使えないと書いたが、シェルでは使える (当然だが、呼び出されるシェルに依存する。Bash なら大丈夫だろう。知らんけど)。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#005CC5">printf</span><span style="color:#24292E">(</span><span style="color:#032F62">`</span></span>
-<span class="line"><span style="color:#032F62">e\</span></span>
-<span class="line"><span style="color:#032F62">c\</span></span>
-<span class="line"><span style="color:#032F62">h\</span></span>
-<span class="line"><span style="color:#032F62">o\</span></span>
-<span class="line"><span style="color:#032F62">\</span></span>
-<span class="line"><span style="color:#032F62">1\</span></span>
-<span class="line"><span style="color:#032F62">2\</span></span>
-<span class="line"><span style="color:#032F62">3\</span></span>
-<span class="line"><span style="color:#032F62">`</span><span style="color:#24292E">);</span></span></code></pre>
- </div>
- <p>
- なお、ここでは簡単のため出力に <code>printf</code> をそのまま使っているが、実際には <code>printf</code> という文字列を合成して可変関数で呼び出す。
- </p>
- <p>
- ただし、これでは
- </p>
- <blockquote>
- <ul>
- <li>
- スペースやタブを使用しないこと
- </li>
- </ul>
- </blockquote>
- <p>
- に違反してしまう。スペースが使えないと引数とコマンドを区切れない。これは困った。
- </p>
- <p>
- もうこれ以上は不可能だと思っていたのだが、この記事の執筆中に解決する方法を思いついたので載せておく。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E">$c </span><span style="color:#D73A49">=</span><span style="color:#032F62"> 'chr'</span><span style="color:#24292E">;</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E">${</span></span>
-<span class="line"><span style="color:#032F62">'_</span></span>
-<span class="line"><span style="color:#032F62">'</span><span style="color:#24292E">}</span></span>
-<span class="line"><span style="color:#D73A49">=</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#24292E">$c</span></span>
-<span class="line"><span style="color:#24292E">(</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#005CC5">32</span></span>
-<span class="line"><span style="color:#24292E">)</span><span style="color:#D73A49">.</span></span>
-<span class="line"><span style="color:#24292E">$c</span></span>
-<span class="line"><span style="color:#24292E">(</span><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#005CC5">92</span></span>
-<span class="line"><span style="color:#24292E">);</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#005CC5">printf</span><span style="color:#24292E">(</span><span style="color:#032F62">`</span></span>
-<span class="line"><span style="color:#032F62">e\</span></span>
-<span class="line"><span style="color:#032F62">c\</span></span>
-<span class="line"><span style="color:#032F62">h\</span></span>
-<span class="line"><span style="color:#032F62">o\</span></span>
-<span class="line"><span style="color:#032F62">${</span></span>
-<span class="line"><span style="color:#032F62">'_</span></span>
-<span class="line"><span style="color:#032F62">'}</span></span>
-<span class="line"><span style="color:#032F62">1\</span></span>
-<span class="line"><span style="color:#032F62">2\</span></span>
-<span class="line"><span style="color:#032F62">3\</span></span>
-<span class="line"><span style="color:#032F62">`</span><span style="color:#24292E">);</span></span></code></pre>
- </div>
- <p>
- 先程と同じく、<code>chr</code> や <code>printf</code> を生成する部分は長くなるので省いた。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>${</span></span>
-<span class="line"><span>'_</span></span>
-<span class="line"><span>'}</span></span></code></pre>
- </div>
- <p>
- は変数で、中にはスペースとエスケープが入っている (<code>chr(32) . chr(92)</code>)。シェルに渡されている文字列は次のようになる。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>e\</span></span>
-<span class="line"><span>c\</span></span>
-<span class="line"><span>h\</span></span>
-<span class="line"><span>o\</span></span>
-<span class="line"><span>\</span></span>
-<span class="line"><span>1\</span></span>
-<span class="line"><span>2\</span></span>
-<span class="line"><span>3\</span></span></code></pre>
- </div>
- <p>
- これは、前掲したコマンドと同じだ。かくして、スペースを陽に書かずにシェルをおおよそ自由に扱えるようになった。Fizzbuzz のワンライナーくらいすぐ書けるだろうから、あとはなんとかなるだろう (試してないけど)。
- </p>
- <p>
- ということでこれは別解ということにしておく。
- </p>
- <p>
- ちなみに、PHP 8.2 からは、この記法で Warning が出るようになるようだ。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>${</span></span>
-<span class="line"><span>'_</span></span>
-<span class="line"><span>'}</span></span></code></pre>
- </div>
- <p>
- 最新版で警告が出るというのも美しくないので、私としては本編の解法を推す。
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2022-10-23/phperkaigi-2023-unused-token-quiz-1/index.html b/vhosts/blog/public/posts/2022-10-23/phperkaigi-2023-unused-token-quiz-1/index.html
deleted file mode 100644
index 364bfb9c..00000000
--- a/vhosts/blog/public/posts/2022-10-23/phperkaigi-2023-unused-token-quiz-1/index.html
+++ /dev/null
@@ -1,207 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2022 nsfisis">
- <meta name="description" content="来年の PHPerKaigi 2023 でデジタルサーカス株式会社から出題予定のトークン問題のうち、ボツになった問題を公開する (その 1)。">
- <meta name="keywords" content="PHP,PHPerKaigi">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHPerKaigi 2023: ボツになったトークン問題 その 1|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="来年の PHPerKaigi 2023 でデジタルサーカス株式会社から出題予定のトークン問題のうち、ボツになった問題を公開する (その 1)。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHPerKaigi 2023: ボツになったトークン問題 その 1|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">PHPerKaigi 2023: ボツになったトークン問題 その 1</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phperkaigi/">PHPerKaigi</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2022-10-23">2022-10-23</time>: 公開
- </li>
- </ol>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- 2023 年 3 月 23 日から 25 日にかけて開催予定 (記事執筆時点) の、<a href="https://phperkaigi.jp/2023/" rel="noreferrer" target="_blank">PHPerKaigi 2023</a> において、昨年と同様に、弊社 <a href="https://www.dgcircus.com/" rel="noreferrer" target="_blank">デジタルサーカス株式会社</a> から、トークン問題を出題予定である。
- </p>
- <p>
- 昨年のトークン問題の記事はこちら: <a href="/posts/2022-04-09/phperkaigi-2022-tokens">PHPerKaigi 2022 トークン問題の解説</a>
- </p>
- <p>
- すでに 2023 年用の問題は作成済みであるが、その制作過程の中でいくつかボツ問ができた。せっかくなので、PHPerKaigi 開催を待つ間に紹介しようと思う。
- </p>
- <p>
- 10 月から 2 月まで、毎月 1 記事ずつ公開していく予定 (忘れていなければ)。
- </p>
- </section>
- <section id="section--quiz">
- <h2><a href="#section--quiz">問題</a></h2>
- <p>
- 注意: これはボツ問なので、得られたトークンを PHPerKaigi で入力してもポイントにはならない。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E">$π </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $argv[</span><span style="color:#005CC5">1</span><span style="color:#24292E">] </span><span style="color:#D73A49">??</span><span style="color:#005CC5"> null</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#D73A49">if</span><span style="color:#24292E"> ($π </span><span style="color:#D73A49">===</span><span style="color:#005CC5"> null</span><span style="color:#24292E">) {</span></span>
-<span class="line"><span style="color:#D73A49"> exit</span><span style="color:#24292E">(</span><span style="color:#032F62">'No input.'</span><span style="color:#24292E">);</span></span>
-<span class="line"><span style="color:#24292E">}</span></span>
-<span class="line"><span style="color:#24292E">$π </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> trim</span><span style="color:#24292E">($π);</span></span>
-<span class="line"><span style="color:#D73A49">if</span><span style="color:#24292E"> (</span><span style="color:#D73A49">!</span><span style="color:#005CC5">is_numeric</span><span style="color:#24292E">($π)) {</span></span>
-<span class="line"><span style="color:#D73A49"> exit</span><span style="color:#24292E">(</span><span style="color:#032F62">'Invalid input.'</span><span style="color:#24292E">);</span></span>
-<span class="line"><span style="color:#24292E">}</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E">$s </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> implode</span><span style="color:#24292E">(</span><span style="color:#005CC5">array_map</span><span style="color:#24292E">(</span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#D73A49">...</span><span style="color:#24292E">), </span><span style="color:#005CC5">str_split</span><span style="color:#24292E">($π, </span><span style="color:#005CC5">2</span><span style="color:#24292E">)));</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#005CC5">preg_match</span><span style="color:#24292E">(</span><span style="color:#032F62">'/(</span><span style="color:#22863A;font-weight:bold">\x</span><span style="color:#032F62">23.</span><span style="color:#D73A49">+</span><span style="color:#032F62">?) /'</span><span style="color:#24292E">, $s, $m);</span></span>
-<span class="line"><span style="color:#24292E">$t </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $m[</span><span style="color:#005CC5">1</span><span style="color:#24292E">] </span><span style="color:#D73A49">??</span><span style="color:#032F62"> ''</span><span style="color:#24292E">;</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">if</span><span style="color:#24292E"> (</span><span style="color:#005CC5">md5</span><span style="color:#24292E">($t) </span><span style="color:#D73A49">===</span><span style="color:#032F62"> '056e831a4146bf123e8ea16613303d2e'</span><span style="color:#24292E">) {</span></span>
-<span class="line"><span style="color:#005CC5"> echo</span><span style="color:#032F62"> "Token: {</span><span style="color:#24292E">$t</span><span style="color:#032F62">}</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">} </span><span style="color:#D73A49">else</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#005CC5"> echo</span><span style="color:#032F62"> "Failed.</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">}</span></span></code></pre>
- </div>
- </section>
- <section id="section--how-to-obtain-token">
- <h2><a href="#section--how-to-obtain-token">トークン入手方法</a></h2>
- <p>
- ソースを見るとわかるとおり、<code>$argv[1]</code> を参照している。それを <code>$π</code> なる変数に代入しているので、円周率を渡してみる。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ php Q.php 3.14</span></span>
-<span class="line"><span>Failed.</span></span></code></pre>
- </div>
- <p>
- 失敗してしまった。精度を上げてみる。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ php Q.php 3.1415</span></span>
-<span class="line"><span>Failed.</span></span></code></pre>
- </div>
- <p>
- だめだった。これを成功するまで繰り返す。
- </p>
- <p>
- 最初にトークンが得られるのは、小数点以下 16 桁目まで入力したときで、こうなる。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ php Q.php 3.1415926535897932</span></span>
-<span class="line"><span>Token: #YO</span></span></code></pre>
- </div>
- <p>
- めでたくトークン「<code>#YO</code>」が手に入った。
- </p>
- </section>
- <section id="section--commentary">
- <h2><a href="#section--commentary">解説</a></h2>
- <p>
- 短いので頭から追っていく。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">$π </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $argv[</span><span style="color:#005CC5">1</span><span style="color:#24292E">] </span><span style="color:#D73A49">??</span><span style="color:#005CC5"> null</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#D73A49">if</span><span style="color:#24292E"> ($π </span><span style="color:#D73A49">===</span><span style="color:#005CC5"> null</span><span style="color:#24292E">) {</span></span>
-<span class="line"><span style="color:#D73A49"> exit</span><span style="color:#24292E">(</span><span style="color:#032F62">'No input.'</span><span style="color:#24292E">);</span></span>
-<span class="line"><span style="color:#24292E">}</span></span>
-<span class="line"><span style="color:#24292E">$π </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> trim</span><span style="color:#24292E">($π);</span></span>
-<span class="line"><span style="color:#D73A49">if</span><span style="color:#24292E"> (</span><span style="color:#D73A49">!</span><span style="color:#005CC5">is_numeric</span><span style="color:#24292E">($π)) {</span></span>
-<span class="line"><span style="color:#D73A49"> exit</span><span style="color:#24292E">(</span><span style="color:#032F62">'Invalid input.'</span><span style="color:#24292E">);</span></span>
-<span class="line"><span style="color:#24292E">}</span></span></code></pre>
- </div>
- <p>
- 入力のバリデーション部分。数値のみ受け付ける。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">$s </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> implode</span><span style="color:#24292E">(</span><span style="color:#005CC5">array_map</span><span style="color:#24292E">(</span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#D73A49">...</span><span style="color:#24292E">), </span><span style="color:#005CC5">str_split</span><span style="color:#24292E">($π, </span><span style="color:#005CC5">2</span><span style="color:#24292E">)));</span></span></code></pre>
- </div>
- <p>
- <code>$π</code> を 2 文字ごとに区切り (<code>str_split</code>)、数値を ASCII コードと見做して文字に変換 (<code>chr</code>) して結合 (<code>implode</code>) している。
- </p>
- <p>
- 例えば、<code>$π</code> が <code>&apos;656667&apos;</code> だったとすると、<code>65</code>、<code>66</code>、<code>67</code> に対応した <code>&apos;A&apos;</code>、<code>&apos;B&apos;</code>、<code>&apos;C&apos;</code> へと変換され、<code>&apos;ABC&apos;</code> になる。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">$π </span><span style="color:#D73A49">=</span><span style="color:#032F62"> '656667'</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">$s </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> implode</span><span style="color:#24292E">(</span><span style="color:#005CC5">array_map</span><span style="color:#24292E">(</span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#D73A49">...</span><span style="color:#24292E">), </span><span style="color:#005CC5">str_split</span><span style="color:#24292E">($π, </span><span style="color:#005CC5">2</span><span style="color:#24292E">)));</span></span>
-<span class="line"><span style="color:#005CC5">echo</span><span style="color:#24292E"> $s;</span></span>
-<span class="line"><span style="color:#6A737D">// => ABC</span></span></code></pre>
- </div>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#005CC5">preg_match</span><span style="color:#24292E">(</span><span style="color:#032F62">'/(</span><span style="color:#22863A;font-weight:bold">\x</span><span style="color:#032F62">23.</span><span style="color:#D73A49">+</span><span style="color:#032F62">?) /'</span><span style="color:#24292E">, $s, $m);</span></span>
-<span class="line"><span style="color:#24292E">$t </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $m[</span><span style="color:#005CC5">1</span><span style="color:#24292E">] </span><span style="color:#D73A49">??</span><span style="color:#032F62"> ''</span><span style="color:#24292E">;</span></span></code></pre>
- </div>
- <p>
- 正規表現でマッチングしている。<code>\x23</code> は <code>#</code> と同じであることに留意すると、この正規表現は「<code>#</code> から始まる 2 以上の長さ (含 <code>#</code>) の文字列で、最初に現れるスペースまで」にマッチする。つまりこれは、PHPerKaigi におけるトークンである。
- </p>
- <p>
- なお、<code>#</code> を直接書いていないのは、<code>/#.+?) /</code> と書くと、<code>#.+?)</code> という意図せぬトークンが登録されてしまうからである。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">if</span><span style="color:#24292E"> (</span><span style="color:#005CC5">md5</span><span style="color:#24292E">($t) </span><span style="color:#D73A49">===</span><span style="color:#032F62"> '056e831a4146bf123e8ea16613303d2e'</span><span style="color:#24292E">) {</span></span>
-<span class="line"><span style="color:#005CC5"> echo</span><span style="color:#032F62"> "Token: {</span><span style="color:#24292E">$t</span><span style="color:#032F62">}</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">} </span><span style="color:#D73A49">else</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#005CC5"> echo</span><span style="color:#032F62"> "Failed.</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">}</span></span></code></pre>
- </div>
- <p>
- 最後にトークンのハッシュ値を見て、想定解かどうかを確認する。
- </p>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">おわりに</a></h2>
- <p>
- 円周率を何桁も計算して ASCII コード経由で文字列化すれば、トークンっぽいものがどこかで出てくるのではないか、と考えて生まれた作品。
- </p>
- <p>
- 最初は真面目に円周率の計算プログラムを組んでいたのだが、いざ動かしてみるとやけに浅いところにあったので驚いた (ちなみに、それでも <code>M_PI</code> や <code>pi()</code> では精度が足りない)。見つけたときは狂喜したものの、冷静になってみると大して面白くなかったのでボツになった。むしろ、100 万桁目くらいに埋まっていてくれたほうがよかったかもしれない。
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2022-10-28/setup-server-for-this-site/index.html b/vhosts/blog/public/posts/2022-10-28/setup-server-for-this-site/index.html
deleted file mode 100644
index 8ca361a6..00000000
--- a/vhosts/blog/public/posts/2022-10-28/setup-server-for-this-site/index.html
+++ /dev/null
@@ -1,316 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2022 nsfisis">
- <meta name="description" content="GitHub Pages でホストしていたこのサイトを VPS へ移行したので、そのときにやったことのメモ。99 % 自分用。">
- <meta name="keywords" content="備忘録">
- <meta property="og:type" content="article">
- <meta property="og:title" content="【備忘録】 このサイト用の VPS をセットアップしたときのメモ|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="GitHub Pages でホストしていたこのサイトを VPS へ移行したので、そのときにやったことのメモ。99 % 自分用。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>【備忘録】 このサイト用の VPS をセットアップしたときのメモ|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">【備忘録】 このサイト用の VPS をセットアップしたときのメモ</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/note-to-self/">備忘録</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2022-10-28">2022-10-28</time>: 公開
- </li>
- <li class="revision">
- <time datetime="2023-08-30">2023-08-30</time>: ssh_config に IdentitiesOnly yes を追加
- </li>
- </ol>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- これまでこの blog は GitHub Pages でホストしていたのだが、先日 VPS に移行した。そのときにおこなったサーバのセットアップ作業を書き残しておく。99 % 自分用の備忘録。別のベンダに移したりしたくなったら見に来る。
- </p>
- <p>
- 未来の自分へ: 特に自動化してないので、せいぜい苦しんでくれ。
- </p>
- </section>
- <section id="section--vps">
- <h2><a href="#section--vps">VPS</a></h2>
- <p>
- <a href="https://vps.sakura.ad.jp/" rel="noreferrer" target="_blank">さくらの VPS</a> の 2 GB プラン。そこまで真面目に選定していないので、困ったら移動するかも。
- </p>
- </section>
- <section id="section--preparation">
- <h2><a href="#section--preparation">事前準備</a></h2>
- <section id="section--preparation--hostname">
- <h3><a href="#section--preparation--hostname">サーバのホスト名を決める</a></h3>
- <p>
- モチベーションが上がるという効能がある。今回は藤原定家から取って <code>teika</code> にした。たいていいつも源氏物語の帖か小倉百人一首の歌人から選んでいる。
- </p>
- </section>
- <section id="section--preparation--ssh-key">
- <h3><a href="#section--preparation--ssh-key">SSH の鍵生成</a></h3>
- <p>
- ローカルマシンで鍵を生成する。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ ssh-keygen -t ed25519 -b 521 -f ~/.ssh/teika.key</span></span>
-<span class="line"><span>$ ssh-keygen -t ed25519 -b 521 -f ~/.ssh/github2teika.key</span></span></code></pre>
- </div>
- <p>
- <code>teika.key</code> はローカルからサーバへの接続用、<code>github2teika.key</code> は、GitHub Actions からサーバへのデプロイ用。
- </p>
- </section>
- <section id="section--preparation--ssh-config">
- <h3><a href="#section--preparation--ssh-config">SSH の設定</a></h3>
- <p>
- <code>.ssh/config</code> に設定しておく。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>Host teika</span></span>
-<span class="line"><span> HostName **********</span></span>
-<span class="line"><span> User **********</span></span>
-<span class="line"><span> Port **********</span></span>
-<span class="line"><span> IdentityFile ~/.ssh/teika.key</span></span>
-<span class="line"><span> IdentitiesOnly yes</span></span></code></pre>
- </div>
- </section>
- </section>
- <section id="section--basic-setup">
- <h2><a href="#section--basic-setup">基本のセットアップ</a></h2>
- <section id="section--basic-setup--login">
- <h3><a href="#section--basic-setup--login">SSH 接続</a></h3>
- <p>
- VPS 契約時に設定した管理者ユーザとパスワードを使ってログインする。
- </p>
- </section>
- <section id="section--basic-setup--user">
- <h3><a href="#section--basic-setup--user">ユーザを作成する</a></h3>
- <p>
- 管理者ユーザで作業すると危ないので、メインで使うユーザを作成する。<code>sudo</code> グループに追加して <code>sudo</code> できるようにし、<code>su</code> で切り替え。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ sudo adduser **********</span></span>
-<span class="line"><span>$ sudo adduser ********** sudo</span></span>
-<span class="line"><span>$ su **********</span></span>
-<span class="line"><span>$ cd</span></span></code></pre>
- </div>
- </section>
- <section id="section--basic-setup--hostname">
- <h3><a href="#section--basic-setup--hostname">ホスト名を変える</a></h3>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ sudo hostname teika</span></span></code></pre>
- </div>
- </section>
- <section id="section--basic-setup--public-key">
- <h3><a href="#section--basic-setup--public-key">公開鍵を置く</a></h3>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ mkdir ~/.ssh</span></span>
-<span class="line"><span>$ chmod 700 ~/.ssh</span></span>
-<span class="line"><span>$ vi ~/.ssh/authorized_keys</span></span></code></pre>
- </div>
- <p>
- <code>authorized_keys</code> には、ローカルで生成した <code>~/.ssh/teika.key.pub</code> と <code>~/.ssh/github2teika.key.pub</code> の内容をコピーする。
- </p>
- </section>
- <section id="section--basic-setup--ssh-config">
- <h3><a href="#section--basic-setup--ssh-config">SSH の設定</a></h3>
- <p>
- SSH の設定を変更し、少しでも安全にしておく。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak</span></span>
-<span class="line"><span>$ sudo vi /etc/ssh/sshd_config</span></span></code></pre>
- </div>
- <ul>
- <li>
- <code>Port</code> を変更
- </li>
- <li>
- <code>PermitRootLogin</code> を <code>no</code> に
- </li>
- <li>
- <code>PasswordAuthentication</code> を <code>no</code> に
- </li>
- </ul>
- <p>
- そして設定を反映。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ sudo systemctl restart sshd</span></span>
-<span class="line"><span>$ sudo systemctl status sshd</span></span></code></pre>
- </div>
- </section>
- <section id="section--basic-setup--ssh-connect">
- <h3><a href="#section--basic-setup--ssh-connect">SSH で接続確認</a></h3>
- <p>
- 今の SSH セッションは閉じずに、ターミナルを別途開いて疎通確認する。セッションを閉じてしまうと、SSH の設定に不備があった場合に締め出しをくらう。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ ssh teika</span></span></code></pre>
- </div>
- </section>
- <section id="section--basic-setup--close-ports">
- <h3><a href="#section--basic-setup--close-ports">ポートの遮断</a></h3>
- <p>
- デフォルトの 22 番を閉じ、設定したポートだけ空ける。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ sudo ufw deny ssh</span></span>
-<span class="line"><span>$ sudo ufw allow *******</span></span>
-<span class="line"><span>$ sudo ufw enable</span></span>
-<span class="line"><span>$ sudo ufw reload</span></span>
-<span class="line"><span>$ sudo ufw status</span></span></code></pre>
- </div>
- <p>
- ここでもう一度 SSH の接続確認を挟む。
- </p>
- </section>
- <section id="section--basic-setup--ssh-key-for-github">
- <h3><a href="#section--basic-setup--ssh-key-for-github">GitHub 用の SSH 鍵</a></h3>
- <p>
- GitHub に置いてある private リポジトリをサーバから clone したいので、SSH 鍵を生成して置いておく。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ ssh-keygen -t ed25519 -b 521 -f ~/.ssh/github.key</span></span>
-<span class="line"><span>$ cat ~/.ssh/github.key.pub</span></span></code></pre>
- </div>
- <p>
- <a href="https://github.com/settings/ssh" rel="noreferrer" target="_blank">GitHub の設定画面</a> から、この公開鍵を追加する。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ vi ~/.ssh/config</span></span></code></pre>
- </div>
- <p>
- 設定はこう。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>Host github.com</span></span>
-<span class="line"><span> HostName github.com</span></span>
-<span class="line"><span> User git</span></span>
-<span class="line"><span> Port 22</span></span>
-<span class="line"><span> IdentityFile ~/.ssh/github.key</span></span>
-<span class="line"><span> IdentitiesOnly yes</span></span></code></pre>
- </div>
- <p>
- 最後に接続できるか確認しておく。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ ssh -T github.com</span></span></code></pre>
- </div>
- </section>
- <section id="section--basic-setup--upgrade-packages">
- <h3><a href="#section--basic-setup--upgrade-packages">パッケージの更新</a></h3>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ sudo apt update</span></span>
-<span class="line"><span>$ sudo apt upgrade</span></span>
-<span class="line"><span>$ sudo apt update</span></span>
-<span class="line"><span>$ sudo apt upgrade</span></span>
-<span class="line"><span>$ sudo apt autoremove</span></span></code></pre>
- </div>
- </section>
- </section>
- <section id="section--site-hosting-setup">
- <h2><a href="#section--site-hosting-setup">サイトホスティング用のセットアップ</a></h2>
- <section id="section--site-hosting-setup--dns">
- <h3><a href="#section--site-hosting-setup--dns">DNS に IP アドレスを登録する</a></h3>
- <p>
- このサーバは固定の IP アドレスがあるので、<code>A</code> レコードに直接入れるだけで済んだ。
- </p>
- </section>
- <section id="section--site-hosting-setup--install-softwares">
- <h3><a href="#section--site-hosting-setup--install-softwares">使うソフトウェアのインストール</a></h3>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ sudo apt install docker docker-compose git make</span></span></code></pre>
- </div>
- </section>
- <section id="section--site-hosting-setup--docker">
- <h3><a href="#section--site-hosting-setup--docker">メインユーザが Docker を使えるように</a></h3>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ sudo adduser ********** docker</span></span></code></pre>
- </div>
- </section>
- <section id="section--site-hosting-setup--open-http-ports">
- <h3><a href="#section--site-hosting-setup--open-http-ports">HTTP/HTTPS を通す</a></h3>
- <p>
- 80 番と 443 番を空ける。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ sudo ufw allow 80/tcp</span></span>
-<span class="line"><span>$ sudo ufw allow 443/tcp</span></span>
-<span class="line"><span>$ sudo ufw reload</span></span>
-<span class="line"><span>$ sudo ufw status</span></span></code></pre>
- </div>
- </section>
- <section id="section--site-hosting-setup--clone-repositories">
- <h3><a href="#section--site-hosting-setup--clone-repositories">リポジトリのクローン</a></h3>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ cd</span></span>
-<span class="line"><span>$ git clone git@github.com:nsfisis/nsfisis.dev.git</span></span>
-<span class="line"><span>$ cd nsfisis.dev</span></span>
-<span class="line"><span>$ git submodule update --init</span></span></code></pre>
- </div>
- </section>
- <section id="section--site-hosting-setup--certbot">
- <h3><a href="#section--site-hosting-setup--certbot">certbot で証明書取得</a></h3>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ docker-compose up -d acme-challenge</span></span>
-<span class="line"><span>$ make setup</span></span></code></pre>
- </div>
- </section>
- <section id="section--site-hosting-setup--run-server">
- <h3><a href="#section--site-hosting-setup--run-server">サーバを稼動させる</a></h3>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ make serve</span></span></code></pre>
- </div>
- </section>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">感想</a></h2>
- <p>
- (業務でなく) 個人だと数年ぶりのサーバセットアップで、これだけでも割と時間を食ってしまった。とはいえ式年遷宮は楽しいので、これからも定期的にやっていきたい。コンテナデプロイにしたい気持ちもあるのだが、色々実験したい関係上、本物のサーバも欲しくはある。次の式年遷宮では、手順の一部だけでも自動化したいところ。
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2022-11-19/phperkaigi-2023-unused-token-quiz-2/index.html b/vhosts/blog/public/posts/2022-11-19/phperkaigi-2023-unused-token-quiz-2/index.html
deleted file mode 100644
index 551a3700..00000000
--- a/vhosts/blog/public/posts/2022-11-19/phperkaigi-2023-unused-token-quiz-2/index.html
+++ /dev/null
@@ -1,215 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2022 nsfisis">
- <meta name="description" content="来年の PHPerKaigi 2023 でデジタルサーカス株式会社から出題予定のトークン問題のうち、ボツになった問題を公開する (その 2)。">
- <meta name="keywords" content="PHP,PHPerKaigi">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHPerKaigi 2023: ボツになったトークン問題 その 2|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="来年の PHPerKaigi 2023 でデジタルサーカス株式会社から出題予定のトークン問題のうち、ボツになった問題を公開する (その 2)。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHPerKaigi 2023: ボツになったトークン問題 その 2|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">PHPerKaigi 2023: ボツになったトークン問題 その 2</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phperkaigi/">PHPerKaigi</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2022-11-19">2022-11-19</time>: 公開
- </li>
- </ol>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- 2023 年 3 月 23 日から 25 日にかけて開催予定 (記事執筆時点) の <a href="https://phperkaigi.jp/2023/" rel="noreferrer" target="_blank">PHPerKaigi 2023</a> において、昨年と同様に、弊社 <a href="https://www.dgcircus.com/" rel="noreferrer" target="_blank">デジタルサーカス株式会社</a> からトークン問題を出題予定である。
- </p>
- <p>
- 昨年のトークン問題の記事はこちら: <a href="/posts/2022-04-09/phperkaigi-2022-tokens/">PHPerKaigi 2022 トークン問題の解説</a>
- </p>
- <p>
- すでに 2023 年用の問題は作成済みであるが、その制作過程の中でいくつかボツ問ができた。せっかくなので、PHPerKaigi 開催を待つ間に紹介しようと思う。
- </p>
- <p>
- 10 月から 2 月まで、毎月 1 記事ずつ公開していく予定 (忘れていなければ)。
- </p>
- <p>
- その 1 はこちら: <a href="/posts/2022-10-23/phperkaigi-2023-unused-token-quiz-1/">PHPerKaigi 2023: ボツになったトークン問題 その 1</a>
- </p>
- </section>
- <section id="section--quiz">
- <h2><a href="#section--quiz">問題</a></h2>
- <p>
- 注意: これはボツ問なので、得られたトークンを PHPerKaigi で入力してもポイントにはならない。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span><span style="color:#005CC5"> printf</span><span style="color:#24292E">((</span><span style="color:#005CC5">isset</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">?fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">trim</span><span style="color:#24292E">($s,</span><span style="color:#032F62">"​"</span><span style="color:#24292E">)</span><span style="color:#D73A49">:fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">strlen</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">/</span><span style="color:#005CC5">3</span><span style="color:#24292E">))($s</span><span style="color:#D73A49">=</span><span style="color:#032F62">'​&#x3C;?php printf((isset($s)?fn($s)=>trim($s,"​"):fn($s)=>chr(strlen($s)/3))($s=%s)."\n","\x27$s\x27");?>'</span><span style="color:#24292E">)</span><span style="color:#D73A49">.</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">,</span><span style="color:#032F62">"</span><span style="color:#005CC5">\x27</span><span style="color:#24292E">$s</span><span style="color:#005CC5">\x27</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span><span style="color:#D73A49">?></span></span>
-<span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span><span style="color:#005CC5"> printf</span><span style="color:#24292E">((</span><span style="color:#005CC5">isset</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">?fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">trim</span><span style="color:#24292E">($s,</span><span style="color:#032F62">"​"</span><span style="color:#24292E">)</span><span style="color:#D73A49">:fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">strlen</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">/</span><span style="color:#005CC5">3</span><span style="color:#24292E">))($s</span><span style="color:#D73A49">=</span><span style="color:#032F62">'​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&#x3C;?php printf((isset($s)?fn($s)=>trim($s,"​"):fn($s)=>chr(strlen($s)/3))($s=%s)."\n","\x27$s\x27");?>'</span><span style="color:#24292E">)</span><span style="color:#D73A49">.</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">,</span><span style="color:#032F62">"</span><span style="color:#005CC5">\x27</span><span style="color:#24292E">$s</span><span style="color:#005CC5">\x27</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span><span style="color:#D73A49">?></span></span>
-<span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span><span style="color:#005CC5"> printf</span><span style="color:#24292E">((</span><span style="color:#005CC5">isset</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">?fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">trim</span><span style="color:#24292E">($s,</span><span style="color:#032F62">"​"</span><span style="color:#24292E">)</span><span style="color:#D73A49">:fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">strlen</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">/</span><span style="color:#005CC5">3</span><span style="color:#24292E">))($s</span><span style="color:#D73A49">=</span><span style="color:#032F62">'​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&#x3C;?php printf((isset($s)?fn($s)=>trim($s,"​"):fn($s)=>chr(strlen($s)/3))($s=%s)."\n","\x27$s\x27");?>'</span><span style="color:#24292E">)</span><span style="color:#D73A49">.</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">,</span><span style="color:#032F62">"</span><span style="color:#005CC5">\x27</span><span style="color:#24292E">$s</span><span style="color:#005CC5">\x27</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span><span style="color:#D73A49">?></span></span>
-<span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span><span style="color:#005CC5"> printf</span><span style="color:#24292E">((</span><span style="color:#005CC5">isset</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">?fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">trim</span><span style="color:#24292E">($s,</span><span style="color:#032F62">"​"</span><span style="color:#24292E">)</span><span style="color:#D73A49">:fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">strlen</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">/</span><span style="color:#005CC5">3</span><span style="color:#24292E">))($s</span><span style="color:#D73A49">=</span><span style="color:#032F62">'​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&#x3C;?php printf((isset($s)?fn($s)=>trim($s,"​"):fn($s)=>chr(strlen($s)/3))($s=%s)."\n","\x27$s\x27");?>'</span><span style="color:#24292E">)</span><span style="color:#D73A49">.</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">,</span><span style="color:#032F62">"</span><span style="color:#005CC5">\x27</span><span style="color:#24292E">$s</span><span style="color:#005CC5">\x27</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span><span style="color:#D73A49">?></span></span>
-<span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span><span style="color:#005CC5"> printf</span><span style="color:#24292E">((</span><span style="color:#005CC5">isset</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">?fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">trim</span><span style="color:#24292E">($s,</span><span style="color:#032F62">"​"</span><span style="color:#24292E">)</span><span style="color:#D73A49">:fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">strlen</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">/</span><span style="color:#005CC5">3</span><span style="color:#24292E">))($s</span><span style="color:#D73A49">=</span><span style="color:#032F62">'​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&#x3C;?php printf((isset($s)?fn($s)=>trim($s,"​"):fn($s)=>chr(strlen($s)/3))($s=%s)."\n","\x27$s\x27");?>'</span><span style="color:#24292E">)</span><span style="color:#D73A49">.</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">,</span><span style="color:#032F62">"</span><span style="color:#005CC5">\x27</span><span style="color:#24292E">$s</span><span style="color:#005CC5">\x27</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span><span style="color:#D73A49">?></span></span>
-<span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span><span style="color:#005CC5"> printf</span><span style="color:#24292E">((</span><span style="color:#005CC5">isset</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">?fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">trim</span><span style="color:#24292E">($s,</span><span style="color:#032F62">"​"</span><span style="color:#24292E">)</span><span style="color:#D73A49">:fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">strlen</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">/</span><span style="color:#005CC5">3</span><span style="color:#24292E">))($s</span><span style="color:#D73A49">=</span><span style="color:#032F62">'​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&#x3C;?php printf((isset($s)?fn($s)=>trim($s,"​"):fn($s)=>chr(strlen($s)/3))($s=%s)."\n","\x27$s\x27");?>'</span><span style="color:#24292E">)</span><span style="color:#D73A49">.</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">,</span><span style="color:#032F62">"</span><span style="color:#005CC5">\x27</span><span style="color:#24292E">$s</span><span style="color:#005CC5">\x27</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span><span style="color:#D73A49">?></span></span>
-<span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span><span style="color:#005CC5"> printf</span><span style="color:#24292E">((</span><span style="color:#005CC5">isset</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">?fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">trim</span><span style="color:#24292E">($s,</span><span style="color:#032F62">"​"</span><span style="color:#24292E">)</span><span style="color:#D73A49">:fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">strlen</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">/</span><span style="color:#005CC5">3</span><span style="color:#24292E">))($s</span><span style="color:#D73A49">=</span><span style="color:#032F62">'​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&#x3C;?php printf((isset($s)?fn($s)=>trim($s,"​"):fn($s)=>chr(strlen($s)/3))($s=%s)."\n","\x27$s\x27");?>'</span><span style="color:#24292E">)</span><span style="color:#D73A49">.</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">,</span><span style="color:#032F62">"</span><span style="color:#005CC5">\x27</span><span style="color:#24292E">$s</span><span style="color:#005CC5">\x27</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span><span style="color:#D73A49">?></span></span>
-<span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span><span style="color:#005CC5"> printf</span><span style="color:#24292E">((</span><span style="color:#005CC5">isset</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">?fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">trim</span><span style="color:#24292E">($s,</span><span style="color:#032F62">"​"</span><span style="color:#24292E">)</span><span style="color:#D73A49">:fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">strlen</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">/</span><span style="color:#005CC5">3</span><span style="color:#24292E">))($s</span><span style="color:#D73A49">=</span><span style="color:#032F62">'​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&#x3C;?php printf((isset($s)?fn($s)=>trim($s,"​"):fn($s)=>chr(strlen($s)/3))($s=%s)."\n","\x27$s\x27");?>'</span><span style="color:#24292E">)</span><span style="color:#D73A49">.</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">,</span><span style="color:#032F62">"</span><span style="color:#005CC5">\x27</span><span style="color:#24292E">$s</span><span style="color:#005CC5">\x27</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span><span style="color:#D73A49">?></span></span>
-<span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span><span style="color:#005CC5"> printf</span><span style="color:#24292E">((</span><span style="color:#005CC5">isset</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">?fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">trim</span><span style="color:#24292E">($s,</span><span style="color:#032F62">"​"</span><span style="color:#24292E">)</span><span style="color:#D73A49">:fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">strlen</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">/</span><span style="color:#005CC5">3</span><span style="color:#24292E">))($s</span><span style="color:#D73A49">=</span><span style="color:#032F62">'​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&#x3C;?php printf((isset($s)?fn($s)=>trim($s,"​"):fn($s)=>chr(strlen($s)/3))($s=%s)."\n","\x27$s\x27");?>'</span><span style="color:#24292E">)</span><span style="color:#D73A49">.</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">,</span><span style="color:#032F62">"</span><span style="color:#005CC5">\x27</span><span style="color:#24292E">$s</span><span style="color:#005CC5">\x27</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span><span style="color:#D73A49">?></span></span>
-<span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span><span style="color:#005CC5"> printf</span><span style="color:#24292E">((</span><span style="color:#005CC5">isset</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">?fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">trim</span><span style="color:#24292E">($s,</span><span style="color:#032F62">"​"</span><span style="color:#24292E">)</span><span style="color:#D73A49">:fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">strlen</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">/</span><span style="color:#005CC5">3</span><span style="color:#24292E">))($s</span><span style="color:#D73A49">=</span><span style="color:#032F62">'​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&#x3C;?php printf((isset($s)?fn($s)=>trim($s,"​"):fn($s)=>chr(strlen($s)/3))($s=%s)."\n","\x27$s\x27");?>'</span><span style="color:#24292E">)</span><span style="color:#D73A49">.</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">,</span><span style="color:#032F62">"</span><span style="color:#005CC5">\x27</span><span style="color:#24292E">$s</span><span style="color:#005CC5">\x27</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span><span style="color:#D73A49">?></span></span></code></pre>
- </div>
- <p>
- “And Then There Were None” (そして誰もいなくなった) と名付けた作品。変則 quine (自分自身と同じソースコードを出力するプログラム) になっている。
- </p>
- </section>
- <section id="section--how-to-obtain-token">
- <h2><a href="#section--how-to-obtain-token">トークン入手方法</a></h2>
- <p>
- 実行してみると、次のような出力が得られる。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span><span style="color:#005CC5"> printf</span><span style="color:#24292E">((</span><span style="color:#005CC5">isset</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">?fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">trim</span><span style="color:#24292E">($s,</span><span style="color:#032F62">"​"</span><span style="color:#24292E">)</span><span style="color:#D73A49">:fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">strlen</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">/</span><span style="color:#005CC5">3</span><span style="color:#24292E">))($s</span><span style="color:#D73A49">=</span><span style="color:#032F62">'​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&#x3C;?php printf((isset($s)?fn($s)=>trim($s,"​"):fn($s)=>chr(strlen($s)/3))($s=%s)."\n","\x27$s\x27");?>'</span><span style="color:#24292E">)</span><span style="color:#D73A49">.</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">,</span><span style="color:#032F62">"</span><span style="color:#005CC5">\x27</span><span style="color:#24292E">$s</span><span style="color:#005CC5">\x27</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span><span style="color:#D73A49">?></span></span>
-<span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span><span style="color:#005CC5"> printf</span><span style="color:#24292E">((</span><span style="color:#005CC5">isset</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">?fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">trim</span><span style="color:#24292E">($s,</span><span style="color:#032F62">"​"</span><span style="color:#24292E">)</span><span style="color:#D73A49">:fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">strlen</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">/</span><span style="color:#005CC5">3</span><span style="color:#24292E">))($s</span><span style="color:#D73A49">=</span><span style="color:#032F62">'​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&#x3C;?php printf((isset($s)?fn($s)=>trim($s,"​"):fn($s)=>chr(strlen($s)/3))($s=%s)."\n","\x27$s\x27");?>'</span><span style="color:#24292E">)</span><span style="color:#D73A49">.</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">,</span><span style="color:#032F62">"</span><span style="color:#005CC5">\x27</span><span style="color:#24292E">$s</span><span style="color:#005CC5">\x27</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span><span style="color:#D73A49">?></span></span>
-<span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span><span style="color:#005CC5"> printf</span><span style="color:#24292E">((</span><span style="color:#005CC5">isset</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">?fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">trim</span><span style="color:#24292E">($s,</span><span style="color:#032F62">"​"</span><span style="color:#24292E">)</span><span style="color:#D73A49">:fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">strlen</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">/</span><span style="color:#005CC5">3</span><span style="color:#24292E">))($s</span><span style="color:#D73A49">=</span><span style="color:#032F62">'​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&#x3C;?php printf((isset($s)?fn($s)=>trim($s,"​"):fn($s)=>chr(strlen($s)/3))($s=%s)."\n","\x27$s\x27");?>'</span><span style="color:#24292E">)</span><span style="color:#D73A49">.</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">,</span><span style="color:#032F62">"</span><span style="color:#005CC5">\x27</span><span style="color:#24292E">$s</span><span style="color:#005CC5">\x27</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span><span style="color:#D73A49">?></span></span>
-<span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span><span style="color:#005CC5"> printf</span><span style="color:#24292E">((</span><span style="color:#005CC5">isset</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">?fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">trim</span><span style="color:#24292E">($s,</span><span style="color:#032F62">"​"</span><span style="color:#24292E">)</span><span style="color:#D73A49">:fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">strlen</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">/</span><span style="color:#005CC5">3</span><span style="color:#24292E">))($s</span><span style="color:#D73A49">=</span><span style="color:#032F62">'​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&#x3C;?php printf((isset($s)?fn($s)=>trim($s,"​"):fn($s)=>chr(strlen($s)/3))($s=%s)."\n","\x27$s\x27");?>'</span><span style="color:#24292E">)</span><span style="color:#D73A49">.</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">,</span><span style="color:#032F62">"</span><span style="color:#005CC5">\x27</span><span style="color:#24292E">$s</span><span style="color:#005CC5">\x27</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span><span style="color:#D73A49">?></span></span>
-<span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span><span style="color:#005CC5"> printf</span><span style="color:#24292E">((</span><span style="color:#005CC5">isset</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">?fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">trim</span><span style="color:#24292E">($s,</span><span style="color:#032F62">"​"</span><span style="color:#24292E">)</span><span style="color:#D73A49">:fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">strlen</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">/</span><span style="color:#005CC5">3</span><span style="color:#24292E">))($s</span><span style="color:#D73A49">=</span><span style="color:#032F62">'​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&#x3C;?php printf((isset($s)?fn($s)=>trim($s,"​"):fn($s)=>chr(strlen($s)/3))($s=%s)."\n","\x27$s\x27");?>'</span><span style="color:#24292E">)</span><span style="color:#D73A49">.</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">,</span><span style="color:#032F62">"</span><span style="color:#005CC5">\x27</span><span style="color:#24292E">$s</span><span style="color:#005CC5">\x27</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span><span style="color:#D73A49">?></span></span>
-<span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span><span style="color:#005CC5"> printf</span><span style="color:#24292E">((</span><span style="color:#005CC5">isset</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">?fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">trim</span><span style="color:#24292E">($s,</span><span style="color:#032F62">"​"</span><span style="color:#24292E">)</span><span style="color:#D73A49">:fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">strlen</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">/</span><span style="color:#005CC5">3</span><span style="color:#24292E">))($s</span><span style="color:#D73A49">=</span><span style="color:#032F62">'​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&#x3C;?php printf((isset($s)?fn($s)=>trim($s,"​"):fn($s)=>chr(strlen($s)/3))($s=%s)."\n","\x27$s\x27");?>'</span><span style="color:#24292E">)</span><span style="color:#D73A49">.</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">,</span><span style="color:#032F62">"</span><span style="color:#005CC5">\x27</span><span style="color:#24292E">$s</span><span style="color:#005CC5">\x27</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span><span style="color:#D73A49">?></span></span>
-<span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span><span style="color:#005CC5"> printf</span><span style="color:#24292E">((</span><span style="color:#005CC5">isset</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">?fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">trim</span><span style="color:#24292E">($s,</span><span style="color:#032F62">"​"</span><span style="color:#24292E">)</span><span style="color:#D73A49">:fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">strlen</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">/</span><span style="color:#005CC5">3</span><span style="color:#24292E">))($s</span><span style="color:#D73A49">=</span><span style="color:#032F62">'​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&#x3C;?php printf((isset($s)?fn($s)=>trim($s,"​"):fn($s)=>chr(strlen($s)/3))($s=%s)."\n","\x27$s\x27");?>'</span><span style="color:#24292E">)</span><span style="color:#D73A49">.</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">,</span><span style="color:#032F62">"</span><span style="color:#005CC5">\x27</span><span style="color:#24292E">$s</span><span style="color:#005CC5">\x27</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span><span style="color:#D73A49">?></span></span>
-<span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span><span style="color:#005CC5"> printf</span><span style="color:#24292E">((</span><span style="color:#005CC5">isset</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">?fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">trim</span><span style="color:#24292E">($s,</span><span style="color:#032F62">"​"</span><span style="color:#24292E">)</span><span style="color:#D73A49">:fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">strlen</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">/</span><span style="color:#005CC5">3</span><span style="color:#24292E">))($s</span><span style="color:#D73A49">=</span><span style="color:#032F62">'​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&#x3C;?php printf((isset($s)?fn($s)=>trim($s,"​"):fn($s)=>chr(strlen($s)/3))($s=%s)."\n","\x27$s\x27");?>'</span><span style="color:#24292E">)</span><span style="color:#D73A49">.</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">,</span><span style="color:#032F62">"</span><span style="color:#005CC5">\x27</span><span style="color:#24292E">$s</span><span style="color:#005CC5">\x27</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span><span style="color:#D73A49">?></span></span>
-<span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span><span style="color:#005CC5"> printf</span><span style="color:#24292E">((</span><span style="color:#005CC5">isset</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">?fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">trim</span><span style="color:#24292E">($s,</span><span style="color:#032F62">"​"</span><span style="color:#24292E">)</span><span style="color:#D73A49">:fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">strlen</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">/</span><span style="color:#005CC5">3</span><span style="color:#24292E">))($s</span><span style="color:#D73A49">=</span><span style="color:#032F62">'​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&#x3C;?php printf((isset($s)?fn($s)=>trim($s,"​"):fn($s)=>chr(strlen($s)/3))($s=%s)."\n","\x27$s\x27");?>'</span><span style="color:#24292E">)</span><span style="color:#D73A49">.</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">,</span><span style="color:#032F62">"</span><span style="color:#005CC5">\x27</span><span style="color:#24292E">$s</span><span style="color:#005CC5">\x27</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span><span style="color:#D73A49">?></span></span></code></pre>
- </div>
- <p>
- 1 行目を除き、先ほどのコードとほぼ同じものが出てきた。もう一度実行してみる。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#005CC5">W</span></span>
-<span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span><span style="color:#005CC5"> printf</span><span style="color:#24292E">((</span><span style="color:#005CC5">isset</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">?fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">trim</span><span style="color:#24292E">($s,</span><span style="color:#032F62">"​"</span><span style="color:#24292E">)</span><span style="color:#D73A49">:fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">strlen</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">/</span><span style="color:#005CC5">3</span><span style="color:#24292E">))($s</span><span style="color:#D73A49">=</span><span style="color:#032F62">'​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&#x3C;?php printf((isset($s)?fn($s)=>trim($s,"​"):fn($s)=>chr(strlen($s)/3))($s=%s)."\n","\x27$s\x27");?>'</span><span style="color:#24292E">)</span><span style="color:#D73A49">.</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">,</span><span style="color:#032F62">"</span><span style="color:#005CC5">\x27</span><span style="color:#24292E">$s</span><span style="color:#005CC5">\x27</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span><span style="color:#D73A49">?></span></span>
-<span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span><span style="color:#005CC5"> printf</span><span style="color:#24292E">((</span><span style="color:#005CC5">isset</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">?fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">trim</span><span style="color:#24292E">($s,</span><span style="color:#032F62">"​"</span><span style="color:#24292E">)</span><span style="color:#D73A49">:fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">strlen</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">/</span><span style="color:#005CC5">3</span><span style="color:#24292E">))($s</span><span style="color:#D73A49">=</span><span style="color:#032F62">'​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&#x3C;?php printf((isset($s)?fn($s)=>trim($s,"​"):fn($s)=>chr(strlen($s)/3))($s=%s)."\n","\x27$s\x27");?>'</span><span style="color:#24292E">)</span><span style="color:#D73A49">.</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">,</span><span style="color:#032F62">"</span><span style="color:#005CC5">\x27</span><span style="color:#24292E">$s</span><span style="color:#005CC5">\x27</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span><span style="color:#D73A49">?></span></span>
-<span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span><span style="color:#005CC5"> printf</span><span style="color:#24292E">((</span><span style="color:#005CC5">isset</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">?fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">trim</span><span style="color:#24292E">($s,</span><span style="color:#032F62">"​"</span><span style="color:#24292E">)</span><span style="color:#D73A49">:fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">strlen</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">/</span><span style="color:#005CC5">3</span><span style="color:#24292E">))($s</span><span style="color:#D73A49">=</span><span style="color:#032F62">'​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&#x3C;?php printf((isset($s)?fn($s)=>trim($s,"​"):fn($s)=>chr(strlen($s)/3))($s=%s)."\n","\x27$s\x27");?>'</span><span style="color:#24292E">)</span><span style="color:#D73A49">.</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">,</span><span style="color:#032F62">"</span><span style="color:#005CC5">\x27</span><span style="color:#24292E">$s</span><span style="color:#005CC5">\x27</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span><span style="color:#D73A49">?></span></span>
-<span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span><span style="color:#005CC5"> printf</span><span style="color:#24292E">((</span><span style="color:#005CC5">isset</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">?fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">trim</span><span style="color:#24292E">($s,</span><span style="color:#032F62">"​"</span><span style="color:#24292E">)</span><span style="color:#D73A49">:fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">strlen</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">/</span><span style="color:#005CC5">3</span><span style="color:#24292E">))($s</span><span style="color:#D73A49">=</span><span style="color:#032F62">'​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&#x3C;?php printf((isset($s)?fn($s)=>trim($s,"​"):fn($s)=>chr(strlen($s)/3))($s=%s)."\n","\x27$s\x27");?>'</span><span style="color:#24292E">)</span><span style="color:#D73A49">.</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">,</span><span style="color:#032F62">"</span><span style="color:#005CC5">\x27</span><span style="color:#24292E">$s</span><span style="color:#005CC5">\x27</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span><span style="color:#D73A49">?></span></span>
-<span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span><span style="color:#005CC5"> printf</span><span style="color:#24292E">((</span><span style="color:#005CC5">isset</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">?fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">trim</span><span style="color:#24292E">($s,</span><span style="color:#032F62">"​"</span><span style="color:#24292E">)</span><span style="color:#D73A49">:fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">strlen</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">/</span><span style="color:#005CC5">3</span><span style="color:#24292E">))($s</span><span style="color:#D73A49">=</span><span style="color:#032F62">'​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&#x3C;?php printf((isset($s)?fn($s)=>trim($s,"​"):fn($s)=>chr(strlen($s)/3))($s=%s)."\n","\x27$s\x27");?>'</span><span style="color:#24292E">)</span><span style="color:#D73A49">.</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">,</span><span style="color:#032F62">"</span><span style="color:#005CC5">\x27</span><span style="color:#24292E">$s</span><span style="color:#005CC5">\x27</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span><span style="color:#D73A49">?></span></span>
-<span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span><span style="color:#005CC5"> printf</span><span style="color:#24292E">((</span><span style="color:#005CC5">isset</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">?fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">trim</span><span style="color:#24292E">($s,</span><span style="color:#032F62">"​"</span><span style="color:#24292E">)</span><span style="color:#D73A49">:fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">strlen</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">/</span><span style="color:#005CC5">3</span><span style="color:#24292E">))($s</span><span style="color:#D73A49">=</span><span style="color:#032F62">'​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&#x3C;?php printf((isset($s)?fn($s)=>trim($s,"​"):fn($s)=>chr(strlen($s)/3))($s=%s)."\n","\x27$s\x27");?>'</span><span style="color:#24292E">)</span><span style="color:#D73A49">.</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">,</span><span style="color:#032F62">"</span><span style="color:#005CC5">\x27</span><span style="color:#24292E">$s</span><span style="color:#005CC5">\x27</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span><span style="color:#D73A49">?></span></span>
-<span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span><span style="color:#005CC5"> printf</span><span style="color:#24292E">((</span><span style="color:#005CC5">isset</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">?fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">trim</span><span style="color:#24292E">($s,</span><span style="color:#032F62">"​"</span><span style="color:#24292E">)</span><span style="color:#D73A49">:fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">strlen</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">/</span><span style="color:#005CC5">3</span><span style="color:#24292E">))($s</span><span style="color:#D73A49">=</span><span style="color:#032F62">'​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&#x3C;?php printf((isset($s)?fn($s)=>trim($s,"​"):fn($s)=>chr(strlen($s)/3))($s=%s)."\n","\x27$s\x27");?>'</span><span style="color:#24292E">)</span><span style="color:#D73A49">.</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">,</span><span style="color:#032F62">"</span><span style="color:#005CC5">\x27</span><span style="color:#24292E">$s</span><span style="color:#005CC5">\x27</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span><span style="color:#D73A49">?></span></span>
-<span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span><span style="color:#005CC5"> printf</span><span style="color:#24292E">((</span><span style="color:#005CC5">isset</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">?fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">trim</span><span style="color:#24292E">($s,</span><span style="color:#032F62">"​"</span><span style="color:#24292E">)</span><span style="color:#D73A49">:fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">strlen</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">/</span><span style="color:#005CC5">3</span><span style="color:#24292E">))($s</span><span style="color:#D73A49">=</span><span style="color:#032F62">'​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&#x3C;?php printf((isset($s)?fn($s)=>trim($s,"​"):fn($s)=>chr(strlen($s)/3))($s=%s)."\n","\x27$s\x27");?>'</span><span style="color:#24292E">)</span><span style="color:#D73A49">.</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">,</span><span style="color:#032F62">"</span><span style="color:#005CC5">\x27</span><span style="color:#24292E">$s</span><span style="color:#005CC5">\x27</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span><span style="color:#D73A49">?></span></span></code></pre>
- </div>
- <p>
- 今度は 2 行目が書き換えられた。すべての行が変化するまで繰り返すと次のようになる。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6A737D">#</span></span>
-<span class="line"><span style="color:#005CC5">W</span></span>
-<span class="line"><span style="color:#005CC5">E</span></span>
-<span class="line"><span style="color:#005CC5">L</span></span>
-<span class="line"><span style="color:#005CC5">O</span></span>
-<span class="line"><span style="color:#005CC5">V</span></span>
-<span class="line"><span style="color:#005CC5">E</span></span>
-<span class="line"><span style="color:#005CC5">P</span></span>
-<span class="line"><span style="color:#005CC5">H</span></span>
-<span class="line"><span style="color:#005CC5">P</span></span></code></pre>
- </div>
- <p>
- トークン「#WELOVEPHP」が手に入った。
- </p>
- </section>
- <section id="section--commentary">
- <h2><a href="#section--commentary">解説</a></h2>
- <p>
- 一見すると同じ行が 10 行並んでいるだけなのにも関わらず、なぜそれぞれの行で出力が変わるのか。ソースコードをコピーして、適当なエディタに貼り付けるとわかりやすい。
- </p>
- <p>
- Vim で開くと次のようになる (1 行目を抜粋)。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span><span style="color:#005CC5"> printf</span><span style="color:#24292E">((</span><span style="color:#005CC5">isset</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">?fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">trim</span><span style="color:#24292E">($s,</span><span style="color:#032F62">"&#x3C;200b>"</span><span style="color:#24292E">)</span><span style="color:#D73A49">:fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">strlen</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">/</span><span style="color:#005CC5">3</span><span style="color:#24292E">))($s</span><span style="color:#D73A49">=</span><span style="color:#032F62">'&#x3C;200b>&#x3C;?php printf((isset($s)?fn($s)=>trim($s,"&#x3C;200b>"):fn($s)=>chr(strlen($s)/3))($s=%s)."\n","\x27$s\x27");?>'</span><span style="color:#24292E">)</span><span style="color:#D73A49">.</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">,</span><span style="color:#032F62">"</span><span style="color:#005CC5">\x27</span><span style="color:#24292E">$s</span><span style="color:#005CC5">\x27</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span><span style="color:#D73A49">?></span></span></code></pre>
- </div>
- <p>
- <code>&lt;200b&gt;</code> と表示されているのは、Unicode の U+200b で、ゼロ幅スペースである。
- </p>
- <div class="admonition">
- <div class="admonition-label">
- NOTE
- </div>
- <div class="admonition-content">
- <p>
- エディタによっては、ゼロ幅スペースが見えないことがある。VSCode ではブラウザと同様に不可視だった。
- </p>
- </div>
- </div>
- <p>
- 文字列リテラルの中にゼロ幅スペースを仕込むことで、見た目を変えずに情報をエンコードすることが可能となる。
- </p>
- <p>
- 続いて、トークンへの変換ロジックを解析する。注目すべきはこの部分だ。以下、ゼロ幅スペースは Vim での表示に合わせて <code>&lt;200b&gt;</code> と記載する。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">fn</span><span style="color:#24292E">($s)=></span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">strlen</span><span style="color:#24292E">($s)</span><span style="color:#D73A49">/</span><span style="color:#005CC5">3</span><span style="color:#24292E">)</span></span></code></pre>
- </div>
- <p>
- PHP の <code>strlen()</code> は文字列のバイト数を返す。1 行目の <code>$s</code> は以下の内容となっており、
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">$s</span><span style="color:#D73A49">=</span><span style="color:#032F62">'&#x3C;200b>&#x3C;?php printf((isset($s)?fn($s)=>trim($s,"&#x3C;200b>"):fn($s)=>chr(strlen($s)/3))($s=%s)."\n","\x27$s\x27");?>'</span></span></code></pre>
- </div>
- <p>
- このソースコードは UTF-8 で書かれているので、105 バイトになる。それを 3 で割ると 35 となり、これは <code>#</code> の ASCII コードと一致する。他の行も、同様にしてゼロ幅スペースを詰めることで文字列長を調整し、トークンをエンコードしている。
- </p>
- <p>
- デコード部以外の部分は、quine のための記述である。
- </p>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">おわりに</a></h2>
- <p>
- <a href="https://blog.rust-lang.org/2021/11/01/cve-2021-42574.html" rel="noreferrer" target="_blank">CVE-2021-42574</a> に着想を得た作品。この脆弱性は、Unicode の制御文字である left-to-right mark と right-to-left mark を利用し、ソースコードの実際の内容を欺く、というもの。簡単のためゼロ幅スペースを用いることとし、ついでに quine にもするとこうなった。
- </p>
- <p>
- ボツになった理由は、ゼロ幅スペースを表示してくるエディタが想像以上に多かったため。「同じ行が並んでいるだけなのに出力が異なる」というアイデアの根幹を崩されてしまうので、この問題は不採用となった。
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2023-01-10/phperkaigi-2023-unused-token-quiz-3/index.html b/vhosts/blog/public/posts/2023-01-10/phperkaigi-2023-unused-token-quiz-3/index.html
deleted file mode 100644
index 4999317a..00000000
--- a/vhosts/blog/public/posts/2023-01-10/phperkaigi-2023-unused-token-quiz-3/index.html
+++ /dev/null
@@ -1,394 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2023 nsfisis">
- <meta name="description" content="来年の PHPerKaigi 2023 でデジタルサーカス株式会社から出題予定のトークン問題のうち、ボツになった問題を公開する (その 3)。">
- <meta name="keywords" content="PHP,PHPerKaigi">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHPerKaigi 2023: ボツになったトークン問題 その 3|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="来年の PHPerKaigi 2023 でデジタルサーカス株式会社から出題予定のトークン問題のうち、ボツになった問題を公開する (その 3)。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHPerKaigi 2023: ボツになったトークン問題 その 3|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">PHPerKaigi 2023: ボツになったトークン問題 その 3</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phperkaigi/">PHPerKaigi</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2023-01-10">2023-01-10</time>: 公開
- </li>
- </ol>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- 2023 年 3 月 23 日から 25 日にかけて開催予定 (記事執筆時点) の <a href="https://phperkaigi.jp/2023/" rel="noreferrer" target="_blank">PHPerKaigi 2023</a> において、昨年と同様に、弊社 <a href="https://www.dgcircus.com/" rel="noreferrer" target="_blank">デジタルサーカス株式会社</a> からトークン問題を出題予定である。
- </p>
- <p>
- 昨年のトークン問題の記事はこちら: <a href="/posts/2022-04-09/phperkaigi-2022-tokens/">PHPerKaigi 2022 トークン問題の解説</a>
- </p>
- <p>
- すでに 2023 年用の問題は作成済みであるが、その制作過程の中でいくつかボツ問ができた。せっかくなので、PHPerKaigi 開催を待つ間に紹介しようと思う。
- </p>
- <p>
- 10 月から 2 月まで、毎月 1 記事ずつ公開していく予定 (忘れていなければ → 忘れていたので 12 月公開予定だった記事を今書いている)。
- </p>
- <ul>
- <li>
- その 1 はこちら: <a href="/posts/2022-10-23/phperkaigi-2023-unused-token-quiz-1/">PHPerKaigi 2023: ボツになったトークン問題 その 1</a>
- </li>
- <li>
- その 2 はこちら: <a href="/posts/2022-11-19/phperkaigi-2023-unused-token-quiz-2/">PHPerKaigi 2023: ボツになったトークン問題 その 2</a>
- </li>
- </ul>
- </section>
- <section id="section--quiz">
- <h2><a href="#section--quiz">問題</a></h2>
- <p>
- 注意: これはボツ問なので、得られたトークンを PHPerKaigi で入力してもポイントにはならない。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span></span>
-<span class="line"><span style="color:#D73A49">try</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#6F42C1"> f</span><span style="color:#24292E">(</span><span style="color:#6F42C1">g</span><span style="color:#24292E">() </span><span style="color:#D73A49">/</span><span style="color:#005CC5"> __LINE__</span><span style="color:#24292E">);</span></span>
-<span class="line"><span style="color:#24292E">} </span><span style="color:#D73A49">catch</span><span style="color:#24292E"> (</span><span style="color:#005CC5">Throwable</span><span style="color:#24292E"> $e) {</span></span>
-<span class="line"><span style="color:#D73A49"> while</span><span style="color:#24292E"> ($e </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $e</span><span style="color:#D73A49">-></span><span style="color:#6F42C1">getPrevious</span><span style="color:#24292E">()) </span><span style="color:#005CC5">printf</span><span style="color:#24292E">(</span><span style="color:#032F62">'%c'</span><span style="color:#24292E">, $e</span><span style="color:#D73A49">-></span><span style="color:#6F42C1">getLine</span><span style="color:#24292E">() </span><span style="color:#D73A49">+</span><span style="color:#005CC5"> 23</span><span style="color:#24292E">);</span></span>
-<span class="line"><span style="color:#005CC5"> echo</span><span style="color:#032F62"> "</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">}</span></span>
-<span class="line"><span style="color:#D73A49">function</span><span style="color:#6F42C1"> f</span><span style="color:#24292E">(</span><span style="color:#D73A49">int</span><span style="color:#24292E"> $i) {</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> ($i </span><span style="color:#D73A49">&#x3C;</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">) </span><span style="color:#6F42C1">f</span><span style="color:#24292E">();</span></span>
-<span class="line"><span style="color:#D73A49"> try</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#D73A49"> match</span><span style="color:#24292E"> ($i) {</span></span>
-<span class="line"><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> /</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">,</span></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"><span style="color:#005CC5"> 15</span><span style="color:#24292E">, </span><span style="color:#005CC5">36</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> /</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#005CC5"> 14</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> /</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#005CC5"> 37</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> /</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">,</span></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"><span style="color:#005CC5"> 6</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> /</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">,</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#005CC5"> 5</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> /</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">,</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#005CC5"> 22</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> /</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">,</span></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"><span style="color:#005CC5"> 34</span><span style="color:#24292E">, </span><span style="color:#005CC5">35</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> /</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">,</span></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"><span style="color:#005CC5"> 25</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> /</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#005CC5"> 17</span><span style="color:#24292E">, </span><span style="color:#005CC5">21</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> /</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">,</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#005CC5"> 24</span><span style="color:#24292E">, </span><span style="color:#005CC5">32</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> /</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">,</span></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"><span style="color:#005CC5"> 33</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> /</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">,</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#005CC5"> 16</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> /</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">,</span></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"><span style="color:#005CC5"> 18</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> /</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">,</span></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"><span style="color:#005CC5"> 7</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> /</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">,</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#005CC5"> 2</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> /</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#005CC5"> 1</span><span style="color:#24292E">, </span><span style="color:#005CC5">20</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> /</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#005CC5"> 10</span><span style="color:#24292E">, </span><span style="color:#005CC5">28</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> /</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#005CC5"> 8</span><span style="color:#24292E">, </span><span style="color:#005CC5">12</span><span style="color:#24292E">, </span><span style="color:#005CC5">26</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> /</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#005CC5"> 4</span><span style="color:#24292E">, </span><span style="color:#005CC5">9</span><span style="color:#24292E">, </span><span style="color:#005CC5">13</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> /</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">,</span></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"><span style="color:#005CC5"> 31</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> /</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">,</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#005CC5"> 29</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> /</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">,</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#005CC5"> 11</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> /</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">,</span></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"><span style="color:#005CC5"> 3</span><span style="color:#24292E">, </span><span style="color:#005CC5">19</span><span style="color:#24292E">, </span><span style="color:#005CC5">23</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> /</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">,</span></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"><span style="color:#005CC5"> 27</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> /</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">,</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#005CC5"> 30</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> /</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#24292E"> };</span></span>
-<span class="line"><span style="color:#24292E"> } </span><span style="color:#D73A49">finally</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#6F42C1"> f</span><span style="color:#24292E">($i </span><span style="color:#D73A49">-</span><span style="color:#005CC5"> 1</span><span style="color:#24292E">);</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#24292E">}</span></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">function</span><span style="color:#6F42C1"> g</span><span style="color:#24292E">() {</span></span>
-<span class="line"><span style="color:#D73A49"> return</span><span style="color:#005CC5"> __LINE__</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">}</span></span></code></pre>
- </div>
- <p>
- “Catchline” と名付けた作品。実行するとトークン <code>#base64_decode(&apos;SGVsbG8sIFdvcmxkIQ==&apos;)</code> が得られる。
- </p>
- <p>
- トークンは PHP の式になっていて、評価すると <code>Hello, World!</code> という文字列になる。PHPer チャレンジのトークンには空白を含められないという制約があるが、こういった形でトークンにすれば回避できる。
- </p>
- </section>
- <section id="section--commentary">
- <h2><a href="#section--commentary">解説</a></h2>
- <section id="section--commentary--summary">
- <h3><a href="#section--commentary--summary">概要</a></h3>
- <p>
- 例外が発生した行数にデータをエンコードし、それを <code>catch</code> で捕まえて表示している。
- </p>
- </section>
- <section id="section--commentary--chain-of-exceptions">
- <h3><a href="#section--commentary--chain-of-exceptions">例外オブジェクトの連鎖</a></h3>
- <p>
- <a href="https://www.php.net/class.Exception" rel="noreferrer" target="_blank"><code>Exception</code></a> や <a href="https://www.php.net/class.Error" rel="noreferrer" target="_blank"><code>Error</code></a> には <code>$previous</code> というプロパティがあり、コンストラクタの第3引数から渡すことができる。主に 2つの用法がある:
- </p>
- <ul>
- <li>
- エラーを処理している途中に起こった別のエラーに、元のエラー情報を含める
- </li>
- <li>
- 内部エラーをラップして作られたエラーに、内部エラーの情報を含める
- </li>
- </ul>
- <p>
- このうち 1つ目のケースは、 <code>finally</code> 節の中でエラーを投げると PHP 処理系が勝手に <code>$previous</code> を設定してくれる。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">try</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#D73A49"> try</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#D73A49"> throw</span><span style="color:#D73A49"> new</span><span style="color:#005CC5"> Exception</span><span style="color:#24292E">(</span><span style="color:#032F62">"Error 1"</span><span style="color:#24292E">);</span></span>
-<span class="line"><span style="color:#24292E"> } </span><span style="color:#D73A49">finally</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#D73A49"> throw</span><span style="color:#D73A49"> new</span><span style="color:#005CC5"> Exception</span><span style="color:#24292E">(</span><span style="color:#032F62">"Error 2"</span><span style="color:#24292E">);</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#24292E">} </span><span style="color:#D73A49">catch</span><span style="color:#24292E"> (</span><span style="color:#005CC5">Exception</span><span style="color:#24292E"> $e) {</span></span>
-<span class="line"><span style="color:#005CC5"> echo</span><span style="color:#24292E"> $e</span><span style="color:#D73A49">-></span><span style="color:#6F42C1">getMessage</span><span style="color:#24292E">() </span><span style="color:#D73A49">.</span><span style="color:#005CC5"> PHP_EOL</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#6A737D"> // => Error 2</span></span>
-<span class="line"><span style="color:#005CC5"> echo</span><span style="color:#24292E"> $e</span><span style="color:#D73A49">-></span><span style="color:#6F42C1">getPrevious</span><span style="color:#24292E">()</span><span style="color:#D73A49">-></span><span style="color:#6F42C1">getMessage</span><span style="color:#24292E">() </span><span style="color:#D73A49">.</span><span style="color:#005CC5"> PHP_EOL</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#6A737D"> // => Error 1</span></span>
-<span class="line"><span style="color:#24292E">}</span></span></code></pre>
- </div>
- <p>
- この知識を元に、トークンの出力部を解析してみる。
- </p>
- </section>
- <section id="section--commentary--output">
- <h3><a href="#section--commentary--output">出力部の解析</a></h3>
- <p>
- 出力部をコメントや改行を追加して再掲する:
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span></span>
-<span class="line"><span style="color:#D73A49">try</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#6F42C1"> f</span><span style="color:#24292E">(</span><span style="color:#6F42C1">g</span><span style="color:#24292E">() </span><span style="color:#D73A49">/</span><span style="color:#005CC5"> __LINE__</span><span style="color:#24292E">);</span></span>
-<span class="line"><span style="color:#24292E">} </span><span style="color:#D73A49">catch</span><span style="color:#24292E"> (</span><span style="color:#005CC5">Throwable</span><span style="color:#24292E"> $e) {</span></span>
-<span class="line"><span style="color:#D73A49"> while</span><span style="color:#24292E"> ($e </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $e</span><span style="color:#D73A49">-></span><span style="color:#6F42C1">getPrevious</span><span style="color:#24292E">()) {</span></span>
-<span class="line"><span style="color:#005CC5"> printf</span><span style="color:#24292E">(</span><span style="color:#032F62">'%c'</span><span style="color:#24292E">, $e</span><span style="color:#D73A49">-></span><span style="color:#6F42C1">getLine</span><span style="color:#24292E">() </span><span style="color:#D73A49">+</span><span style="color:#005CC5"> 23</span><span style="color:#24292E">);</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#005CC5"> echo</span><span style="color:#032F62"> "</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">}</span></span></code></pre>
- </div>
- <p>
- 出力をおこなう <code>catch</code> 節を見てみると、 <code>Throwable::getPrevious()</code> を呼び出してエラーチェインを辿り、 <code>Throwable::getLine()</code> でエラーが発生した行数を取得している。その行数に <code>23</code> なるマジックナンバーを足し、フォーマット指定子 <code>%c</code> で出力している。
- </p>
- <p>
- フォーマット指定子 <code>%c</code> は、整数を ASCII コード<sup class="footnote"><a class="footnote" href="#footnote--ras-syndrome" id="footnoteref--ras-syndrome">[1]</a></sup> と見做して印字する。トークン <code>#base64_decode(&apos;SGVsbG8sIFdvcmxkIQ==&apos;)</code> の <code>b</code> であれば、ASCII コード <code>98</code> なので、75 行目で発生したエラー、
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#005CC5">1</span><span style="color:#24292E">, </span><span style="color:#005CC5">20</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> /</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">,</span></span></code></pre>
- </div>
- <p>
- によって表現されている。エラーを起こす方法はいろいろと考えられるが、今回はゼロ除算を使った。
- </p>
- <p>
- それでは、エラーチェインを作る箇所、関数 <code>f()</code> を見ていく。
- </p>
- </section>
- <section id="section--commentary--data-construction">
- <h3><a href="#section--commentary--data-construction">データ構成部の解析</a></h3>
- <p>
- <code>f()</code> の定義を再掲する (エラーオブジェクトの行数を利用しているので、一部分だけ抜き出すと値が変わることに注意):
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">function</span><span style="color:#6F42C1"> f</span><span style="color:#24292E">(</span><span style="color:#D73A49">int</span><span style="color:#24292E"> $i) {</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> ($i </span><span style="color:#D73A49">&#x3C;</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">) </span><span style="color:#6F42C1">f</span><span style="color:#24292E">();</span></span>
-<span class="line"><span style="color:#D73A49"> try</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#D73A49"> match</span><span style="color:#24292E"> ($i) {</span></span>
-<span class="line"><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> /</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">, </span><span style="color:#6A737D">// 12 行目</span></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"></span>
-<span class="line"><span style="color:#005CC5"> 15</span><span style="color:#24292E">, </span><span style="color:#005CC5">36</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> /</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#005CC5"> 14</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> /</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#005CC5"> 37</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> /</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">,</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#6A737D"> // (略)</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#005CC5"> 30</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> /</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">, </span><span style="color:#6A737D">// 97 行目</span></span>
-<span class="line"><span style="color:#24292E"> };</span></span>
-<span class="line"><span style="color:#24292E"> } </span><span style="color:#D73A49">finally</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#6F42C1"> f</span><span style="color:#24292E">($i </span><span style="color:#D73A49">-</span><span style="color:#005CC5"> 1</span><span style="color:#24292E">);</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#24292E">}</span></span></code></pre>
- </div>
- <p>
- 前述のように、 <code>finally</code> 節でエラーを投げると PHP 処理系が <code>$previous</code> を設定する。ここでは、エラーを繋げるために <code>f()</code> を再帰呼び出ししている。最初に <code>f()</code> を呼び出している箇所を確認すると、
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span></span>
-<span class="line"><span style="color:#D73A49">try</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#6F42C1"> f</span><span style="color:#24292E">(</span><span style="color:#6F42C1">g</span><span style="color:#24292E">() </span><span style="color:#D73A49">/</span><span style="color:#005CC5"> __LINE__</span><span style="color:#24292E">); </span><span style="color:#6A737D">// 3 行目</span></span></code></pre>
- </div>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">function</span><span style="color:#6F42C1"> g</span><span style="color:#24292E">() {</span></span>
-<span class="line"><span style="color:#D73A49"> return</span><span style="color:#005CC5"> __LINE__</span><span style="color:#24292E">; </span><span style="color:#6A737D">// 111 行目</span></span>
-<span class="line"><span style="color:#24292E">}</span></span></code></pre>
- </div>
- <p>
- <code>f()</code> には <code>111 / 3</code> で <code>37</code> が渡されることがわかる。そこから 1 ずつ減らして再帰呼び出ししていき、0 より小さくなったら <code>f()</code> を引数なしで呼び出す。引数の数が足りないと呼び出しに失敗するので、再帰はここで止まる。
- </p>
- <p>
- エラーチェインは、最後に発生したエラーを先頭とした単方向連結リストになっているので、順に
- </p>
- <ol>
- <li>
- <code>f()</code> の引数が足りないことによる呼び出し失敗
- </li>
- <li>
- <code>f(0)</code> の呼び出しで発生したゼロ除算
- </li>
- <li>
- <code>f(1)</code> の呼び出しで発生したゼロ除算
- </li>
- <li>
- …
- </li>
- <li>
- <code>f(37)</code> の呼び出しで発生したゼロ除算
- </li>
- </ol>
- <p>
- となっている。出力の際は <code>catch</code> したエラーの <code>getPrevious()</code> から処理を始めるので、1 番目の <code>f()</code> によるエラーは無視され、 <code>f(0)</code> によるエラー、 <code>f(1)</code> によるエラー、 <code>f(2)</code> によるエラー、と出力が進む。
- </p>
- <p>
- <code>f()</code> に <code>0</code> を渡したときは 12 行目にある <code>match</code> の <code>0</code> でゼロ除算が起こるので、行数が 12 となったエラーが投げられる。出力部ではこれに 23 を足した数を ASCII コードとして表示しているのだった。 <code>12 + 23</code> は <code>35</code>、ASCII コードでは <code>#</code> である。これがトークンの 1文字目にあたる。
- </p>
- </section>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">おわりに</a></h2>
- <p>
- 「行数」というのはトークン文字列をデコードする対象として優れている。
- </p>
- <ul>
- <li>
- トークンの一部や全部が陽に現れない
- </li>
- <li>
- <code>__LINE__</code> で容易に取得できる
- </li>
- </ul>
- <p>
- しかし、こういった「変な」プログラムを何度も読んだり書いたりしていると、 <code>__LINE__</code> を使うのはあまりにありきたりで退屈になる。では、他に行数を取得する手段はないか。こうして <code>Throwable</code> を思いつき、続けてエラーオブジェクトには <code>$previous</code> があることを思い出した。
- </p>
- <p>
- 今回エラーを投げるのにゼロ除算を用いたのは、それがエラーを投げる最も短いコードだと考えたからである。もし 3バイト未満で <code>Throwable</code> なオブジェクトを投げる手段をご存じのかたがいらっしゃれば、ぜひご教示いただきたい。……と締める予定だったのだが、<code>0/0</code> のところを存在しない定数にすれば、簡単に 1バイトを達成できた。ゼロ除算している箇所はちょうど 26 箇所あるので、アルファベットにでもしておけば意味ありげで良かったかもしれない。
- </p>
- </section>
- <section class="footnotes">
- <div class="footnote" id="footnote--ras-syndrome">
- <a href="#footnoteref--ras-syndrome">1. </a>
- <p>
- RAS syndrome
- </p>
- </div>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2023-03-10/rewrite-this-blog-generator/index.html b/vhosts/blog/public/posts/2023-03-10/rewrite-this-blog-generator/index.html
deleted file mode 100644
index d70cf265..00000000
--- a/vhosts/blog/public/posts/2023-03-10/rewrite-this-blog-generator/index.html
+++ /dev/null
@@ -1,148 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2023 nsfisis">
- <meta name="description" content="このブログのジェネレータを書き直したので、やったことを書き記しておく。">
- <meta property="og:type" content="article">
- <meta property="og:title" content="このブログのジェネレータを書き直した|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="このブログのジェネレータを書き直したので、やったことを書き記しておく。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>このブログのジェネレータを書き直した|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">このブログのジェネレータを書き直した</h1>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2023-03-10">2023-03-10</time>: 公開
- </li>
- </ol>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- このブログを構築するシステムを書き直したのは 2度目である。元々立ち上げた当初は、静的サイトジェネレータである <a href="https://gohugo.io/" rel="noreferrer" target="_blank">Hugo</a> を使っていた。それを <a href="https://asciidoctor.org/" rel="noreferrer" target="_blank">Asciidoctor</a> にいくつかのカスタムを加えた自前のジェネレータに移行したのが 2022年の11月ごろだ。そして今回、スクラッチから書いた <a href="https://deno.land/" rel="noreferrer" target="_blank">Deno</a> 製のジェネレータに移行した。
- </p>
- <p>
- この記事では、移行の理由などを (主に将来の私へ向けて) 書き記しておく。
- </p>
- </section>
- <section id="section--from-hugo-to-asciidoctor">
- <h2><a href="#section--from-hugo-to-asciidoctor">Hugo から Asciidoctor へ</a></h2>
- <p>
- 最初に断っておくと、Hugo は大変に優れた静的サイトジェネレータである。移行の理由の大半は、自分でジェネレータを書きたかったからに他ならない。実のところ、この記事を執筆している現在、自作ジェネレータは Hugo よりも機能が劣っている。例えば、Hugo を使っていたころはサポートしていた RSS フィードの生成は、まだ実装できていない。
- </p>
- <p>
- 移行先のフォーマットとして AsciiDoc を選んだのは、Markdown よりも表現力に優れるからである。Markdown は広く使われている軽量マークアップ言語だが、以下のような欠点を持つ。
- </p>
- <ul>
- <li>
- CommonMark では機能が貧弱である (例: 脚注、<code>id</code> 属性の付与)
- </li>
- <li>
- 拡張記法に実装間で互換性がない
- </li>
- <li>
- メタデータ (公開日など) を埋め込む統一された方法がない
- </li>
- </ul>
- <p>
- AsciiDoc は Markdown に比べると普及していないが、上記の欠点は克服している。
- </p>
- <ul>
- <li>
- ブログを書くのに十分な表現力がある
- </li>
- <li>
- フォーマットを拡張するときの記法があらかじめ定められている
- </li>
- <li>
- メタデータを埋め込む統一された方法がある
- </li>
- </ul>
- <p>
- なお、Hugo は AsciiDoc もサポートしているのだが、AsciiDoc を使う場合 Asciidoctor を別途インストールする必要があり、それならば最初から Asciidoctor でよかろうと移行を決めた。
- </p>
- </section>
- <section id="section--from-asciidoctor-to-my-own-generator">
- <h2><a href="#section--from-asciidoctor-to-my-own-generator">Asciidoctor から自前のジェネレータへ</a></h2>
- <p>
- AsciiDoc は良いフォーマットだが、私には 1点不満があった。それは、高い表現力を担保するために記号が使い倒されており、エスケープが難しいという点だ (具体例を挙げたいのだが、何だったか覚えていない)。これは、多種多様な記号類を入力する必要のある技術ブログにとっては辛い問題である。この問題を解決するため、
- </p>
- <ul>
- <li>
- 表現力が高く、
- </li>
- <li>
- 文法が厳密であり、
- </li>
- <li>
- 簡単に実装できる
- </li>
- </ul>
- <p>
- フォーマットが求められた。これに合致したのが、XML をベースとする <a href="https://docbook.org/" rel="noreferrer" target="_blank">DocBook</a> (今回使っているのは、そのサブセットである <a href="https://tdg.docbook.org/tdg/sdocbook/5.1/" rel="noreferrer" target="_blank">Simplified DocBook</a> ) である。
- </p>
- <p>
- 実は、AsciiDoc と DocBook はおおよそ互換性がある。AsciiDoc で書かれた文書は (ほぼ) 情報ロスなしに DocBook へ変換でき、逆もまたしかりである。よって、DocBook には、AsciiDoc と同等の表現力がある。
- </p>
- <p>
- XML の文法の厳密さについては、説明するまでもないだろう。また、単純な文法であることから実装が容易であり、事実上 Asciidoctor へロックインされる AsciiDoc とは異なり、さまざまな言語で多くのライブラリが存在する。
- </p>
- <p>
- 今回は、XML のパース自体も自分で書いている (これは何となく書きたかったからであり、合理的な理由があるわけではない。実装はサボりまくっているので XML のコメントが使えないといった制限がある)。
- </p>
- <p>
- XML という機械処理しやすいフォーマットを選ぶことには、機械的な変換や検査といった処理がおこないやすくなるといった利点もある。欠点は軽量マークアップ言語と比べて冗長であることだが、書く際は補完などを用いるのでそれほど気にならない。結局のところ、技術ブログの執筆を律速するのは調査と文章の記述であり、マークアップの手段は執筆時間に大した影響を与えない。
- </p>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">おわりに</a></h2>
- <p>
- 2度のリライトを経て、記事のフォーマットとサイトジェネレータを上から下まで掌握した。今後も改善のアイデアは多数あるので、じわじわと進めていきたいところだ。
- </p>
- <p>
- 最後にもう一度書くのだが、Hugo は大変に優れた静的サイトジェネレータである。無駄な拘りがなければこれを使うとよい。私は無駄に拘ったので、ブログの記事を書く時間を潰してブログシステムを作ってしまった。
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2023-04-01/implementation-of-minimal-png-image-encoder/index.html b/vhosts/blog/public/posts/2023-04-01/implementation-of-minimal-png-image-encoder/index.html
deleted file mode 100644
index 83d597ed..00000000
--- a/vhosts/blog/public/posts/2023-04-01/implementation-of-minimal-png-image-encoder/index.html
+++ /dev/null
@@ -1,699 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2023 nsfisis">
- <meta name="description" content="PNG 画像として valid な範囲で最大限手抜きしたエンコーダを書く。">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PNG 画像の最小構成エンコーダを実装する|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="PNG 画像として valid な範囲で最大限手抜きしたエンコーダを書く。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PNG 画像の最小構成エンコーダを実装する|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">PNG 画像の最小構成エンコーダを実装する</h1>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2023-04-01">2023-04-01</time>: 公開
- </li>
- </ol>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- この記事では、PNG 画像として valid な範囲で最大限手抜きしたエンコーダを書く。PNG 画像に対応したビューアであれば読み込めるが、圧縮効率については一切考えない。また、実装には Go 言語を使うが、Go の標準ライブラリにあるさまざまなアルゴリズム (PNG 画像に関係する範囲だと、zlib や CRC32、Adler-32 など) は使わない。
- </p>
- </section>
- <section id="section--basic-structure-of-png">
- <h2><a href="#section--basic-structure-of-png">PNG ファイルの基本構造</a></h2>
- <p>
- PNG ファイルの基本構造は次のようになっている。
- </p>
- <ol>
- <li>
- PNG signature
- </li>
- <li>
- IHDR chunk
- </li>
- <li>
- 任意個の chunk
- </li>
- <li>
- IEND chunk
- </li>
- </ol>
- <p>
- Chunk には画像データを入れる IDAT chunk、パレットデータを入れる PLTE chunk、テキストデータを入れる tEXt chunk などがあるが、今回は最小構成ということで IDAT chunk (と IHDR chunk と IEND chunk) のみを用いる。
- </p>
- <p>
- 次節で、それぞれの具体的な構造を確認しつつ実装していく。
- </p>
- </section>
- <section id="section--implement-png-encoder">
- <h2><a href="#section--implement-png-encoder">PNG のエンコーダを実装する</a></h2>
- <p>
- 以下のソースコードをベースにする。今回 PNG のデコーダは扱わないので、読み込みには Go の標準ライブラリ <code>image/png</code> を用いる。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">package</span><span style="color:#6F42C1"> main</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">import</span><span style="color:#24292E"> (</span></span>
-<span class="line"><span style="color:#032F62"> "</span><span style="color:#6F42C1">image</span><span style="color:#032F62">"</span></span>
-<span class="line"><span style="color:#24292E"> _ </span><span style="color:#032F62">"</span><span style="color:#6F42C1">image/png</span><span style="color:#032F62">"</span></span>
-<span class="line"><span style="color:#032F62"> "</span><span style="color:#6F42C1">io</span><span style="color:#032F62">"</span></span>
-<span class="line"><span style="color:#032F62"> "</span><span style="color:#6F42C1">os</span><span style="color:#032F62">"</span></span>
-<span class="line"><span style="color:#24292E">)</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">func</span><span style="color:#6F42C1"> main</span><span style="color:#24292E">() {</span></span>
-<span class="line"><span style="color:#24292E"> inFile, err </span><span style="color:#D73A49">:=</span><span style="color:#24292E"> os.</span><span style="color:#6F42C1">Open</span><span style="color:#24292E">(</span><span style="color:#032F62">"input.png"</span><span style="color:#24292E">)</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> err </span><span style="color:#D73A49">!=</span><span style="color:#005CC5"> nil</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#6F42C1"> panic</span><span style="color:#24292E">(err)</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#D73A49"> defer</span><span style="color:#24292E"> inFile.</span><span style="color:#6F42C1">Close</span><span style="color:#24292E">()</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E"> img, _, err </span><span style="color:#D73A49">:=</span><span style="color:#24292E"> image.</span><span style="color:#6F42C1">Decode</span><span style="color:#24292E">(inFile)</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> err </span><span style="color:#D73A49">!=</span><span style="color:#005CC5"> nil</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#6F42C1"> panic</span><span style="color:#24292E">(err)</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E"> outFile, err </span><span style="color:#D73A49">:=</span><span style="color:#24292E"> os.</span><span style="color:#6F42C1">Create</span><span style="color:#24292E">(</span><span style="color:#032F62">"output.png"</span><span style="color:#24292E">)</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> err </span><span style="color:#D73A49">!=</span><span style="color:#005CC5"> nil</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#6F42C1"> panic</span><span style="color:#24292E">(err)</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#D73A49"> defer</span><span style="color:#24292E"> outFile.</span><span style="color:#6F42C1">Close</span><span style="color:#24292E">()</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#6F42C1"> writePng</span><span style="color:#24292E">(outFile, img)</span></span>
-<span class="line"><span style="color:#24292E">}</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">func</span><span style="color:#6F42C1"> writePng</span><span style="color:#24292E">(</span><span style="color:#E36209">w</span><span style="color:#6F42C1"> io</span><span style="color:#24292E">.</span><span style="color:#6F42C1">Writer</span><span style="color:#24292E">, </span><span style="color:#E36209">img</span><span style="color:#6F42C1"> image</span><span style="color:#24292E">.</span><span style="color:#6F42C1">Image</span><span style="color:#24292E">) {</span></span>
-<span class="line"><span style="color:#24292E"> width </span><span style="color:#D73A49">:=</span><span style="color:#D73A49"> uint32</span><span style="color:#24292E">(img.</span><span style="color:#6F42C1">Bounds</span><span style="color:#24292E">().</span><span style="color:#6F42C1">Dx</span><span style="color:#24292E">())</span></span>
-<span class="line"><span style="color:#24292E"> height </span><span style="color:#D73A49">:=</span><span style="color:#D73A49"> uint32</span><span style="color:#24292E">(img.</span><span style="color:#6F42C1">Bounds</span><span style="color:#24292E">().</span><span style="color:#6F42C1">Dy</span><span style="color:#24292E">())</span></span>
-<span class="line"><span style="color:#6F42C1"> writeSignature</span><span style="color:#24292E">(w)</span></span>
-<span class="line"><span style="color:#6F42C1"> writeChunkIhdr</span><span style="color:#24292E">(w, width, height)</span></span>
-<span class="line"><span style="color:#6F42C1"> writeChunkIdat</span><span style="color:#24292E">(w, width, height, img)</span></span>
-<span class="line"><span style="color:#6F42C1"> writeChunkIend</span><span style="color:#24292E">(w)</span></span>
-<span class="line"><span style="color:#24292E">}</span></span></code></pre>
- </div>
- <p>
- 以降は、<code>writeSignature</code> や <code>writeChunkIhdr</code> などを実装していく。
- </p>
- <section id="section--implement-png-encoder--png-signature">
- <h3><a href="#section--implement-png-encoder--png-signature">PNG signature</a></h3>
- <p>
- PNG signature は、PNG 画像の先頭に固定で付与されるバイト列で、8 バイトからなる。
- </p>
- <ol>
- <li>
- 0x89
- </li>
- <li>
- 0x50 (ASCII コードで「P」)
- </li>
- <li>
- 0x4E (ASCII コードで「N」)
- </li>
- <li>
- 0x47 (ASCII コードで「G」)
- </li>
- <li>
- 0x0D (ASCII コードで CR)
- </li>
- <li>
- 0x0A (ASCII コードで LF)
- </li>
- <li>
- 0x1A (ASCII コードで EOF)
- </li>
- <li>
- 0x0A (ASCII コードで LF)
- </li>
- </ol>
- <p>
- CRLF や LF は、送信中に改行コードの変換が誤っておこなわれていないかどうかを検知するのに使われる。
- </p>
- <p>
- <code>writeSignature</code> の実装はこちら:
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">import</span><span style="color:#032F62"> "</span><span style="color:#6F42C1">encoding/binary</span><span style="color:#032F62">"</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">func</span><span style="color:#6F42C1"> writeSignature</span><span style="color:#24292E">(</span><span style="color:#E36209">w</span><span style="color:#6F42C1"> io</span><span style="color:#24292E">.</span><span style="color:#6F42C1">Writer</span><span style="color:#24292E">) {</span></span>
-<span class="line"><span style="color:#24292E"> sig </span><span style="color:#D73A49">:=</span><span style="color:#24292E"> [</span><span style="color:#005CC5">8</span><span style="color:#24292E">]</span><span style="color:#D73A49">uint8</span><span style="color:#24292E">{</span></span>
-<span class="line"><span style="color:#D73A49"> 0x</span><span style="color:#005CC5">89</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#D73A49"> 0x</span><span style="color:#005CC5">50</span><span style="color:#24292E">, </span><span style="color:#6A737D">// P</span></span>
-<span class="line"><span style="color:#D73A49"> 0x</span><span style="color:#005CC5">4E</span><span style="color:#24292E">, </span><span style="color:#6A737D">// N</span></span>
-<span class="line"><span style="color:#D73A49"> 0x</span><span style="color:#005CC5">47</span><span style="color:#24292E">, </span><span style="color:#6A737D">// G</span></span>
-<span class="line"><span style="color:#D73A49"> 0x</span><span style="color:#005CC5">0D</span><span style="color:#24292E">, </span><span style="color:#6A737D">// CR</span></span>
-<span class="line"><span style="color:#D73A49"> 0x</span><span style="color:#005CC5">0A</span><span style="color:#24292E">, </span><span style="color:#6A737D">// LF</span></span>
-<span class="line"><span style="color:#D73A49"> 0x</span><span style="color:#005CC5">1A</span><span style="color:#24292E">, </span><span style="color:#6A737D">// EOF (^Z)</span></span>
-<span class="line"><span style="color:#D73A49"> 0x</span><span style="color:#005CC5">0A</span><span style="color:#24292E">, </span><span style="color:#6A737D">// LF</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(w, binary.BigEndian, sig)</span></span>
-<span class="line"><span style="color:#24292E">}</span></span></code></pre>
- </div>
- <p>
- <code>encoding/binary</code> パッケージの <code>binary.Write</code> を使い、固定の 8 バイトを書き込む。
- </p>
- </section>
- <section id="section--implement-png-encoder--structure-of-chunk">
- <h3><a href="#section--implement-png-encoder--structure-of-chunk">Chunk の構造</a></h3>
- <p>
- IHDR chunk に進む前に、chunk 一般の構造を確認する。
- </p>
- <ol>
- <li>
- Length: chunk data のバイト長 (符号なし 4 バイト整数)
- </li>
- <li>
- Chunk type: chunk の種類を示す 4 バイトからなる名前
- </li>
- <li>
- Chunk data: 実際のデータ。0 バイトでもよい
- </li>
- <li>
- CRC: chunk type と chunk data の CRC (符号なし 4 バイト整数)
- </li>
- </ol>
- <p>
- CRC (Cyclic Redundancy Check) は誤り検出符号の一種。Go 言語では <code>hash/crc32</code> パッケージにあるが、今回はこれも自前で実装する。PNG の仕様書に C 言語のサンプルコードが載っている ( <a href="https://www.w3.org/TR/png/#D-CRCAppendix" rel="noreferrer" target="_blank">D. Sample CRC implementation</a> ) ので、これを Go に移植する。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">var</span><span style="color:#24292E"> (</span></span>
-<span class="line"><span style="color:#24292E"> crcTable [</span><span style="color:#005CC5">256</span><span style="color:#24292E">]</span><span style="color:#D73A49">uint32</span></span>
-<span class="line"><span style="color:#24292E"> crcTableComputed </span><span style="color:#D73A49">bool</span></span>
-<span class="line"><span style="color:#24292E">)</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">func</span><span style="color:#6F42C1"> makeCrcTable</span><span style="color:#24292E">() {</span></span>
-<span class="line"><span style="color:#D73A49"> for</span><span style="color:#24292E"> n </span><span style="color:#D73A49">:=</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">; n </span><span style="color:#D73A49">&#x3C;</span><span style="color:#005CC5"> 256</span><span style="color:#24292E">; n</span><span style="color:#D73A49">++</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#24292E"> c </span><span style="color:#D73A49">:=</span><span style="color:#D73A49"> uint32</span><span style="color:#24292E">(n)</span></span>
-<span class="line"><span style="color:#D73A49"> for</span><span style="color:#24292E"> k </span><span style="color:#D73A49">:=</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">; k </span><span style="color:#D73A49">&#x3C;</span><span style="color:#005CC5"> 8</span><span style="color:#24292E">; k</span><span style="color:#D73A49">++</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> (c </span><span style="color:#D73A49">&#x26;</span><span style="color:#005CC5"> 1</span><span style="color:#24292E">) </span><span style="color:#D73A49">!=</span><span style="color:#005CC5"> 0</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#24292E"> c </span><span style="color:#D73A49">=</span><span style="color:#D73A49"> 0x</span><span style="color:#005CC5">EDB88320</span><span style="color:#D73A49"> ^</span><span style="color:#24292E"> (c </span><span style="color:#D73A49">>></span><span style="color:#005CC5"> 1</span><span style="color:#24292E">)</span></span>
-<span class="line"><span style="color:#24292E"> } </span><span style="color:#D73A49">else</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#24292E"> c </span><span style="color:#D73A49">=</span><span style="color:#24292E"> c </span><span style="color:#D73A49">>></span><span style="color:#005CC5"> 1</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#24292E"> crcTable[n] </span><span style="color:#D73A49">=</span><span style="color:#24292E"> c</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#24292E"> crcTableComputed </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> true</span></span>
-<span class="line"><span style="color:#24292E">}</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">func</span><span style="color:#6F42C1"> updateCrc</span><span style="color:#24292E">(</span><span style="color:#E36209">crc</span><span style="color:#D73A49"> uint32</span><span style="color:#24292E">, </span><span style="color:#E36209">buf</span><span style="color:#24292E"> []</span><span style="color:#D73A49">byte</span><span style="color:#24292E">) </span><span style="color:#D73A49">uint32</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#D73A49"> !</span><span style="color:#24292E">crcTableComputed {</span></span>
-<span class="line"><span style="color:#6F42C1"> makeCrcTable</span><span style="color:#24292E">()</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E"> c </span><span style="color:#D73A49">:=</span><span style="color:#24292E"> crc</span></span>
-<span class="line"><span style="color:#D73A49"> for</span><span style="color:#24292E"> n </span><span style="color:#D73A49">:=</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">; n </span><span style="color:#D73A49">&#x3C;</span><span style="color:#6F42C1"> len</span><span style="color:#24292E">(buf); n</span><span style="color:#D73A49">++</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#24292E"> c </span><span style="color:#D73A49">=</span><span style="color:#24292E"> crcTable[(c</span><span style="color:#D73A49">^uint32</span><span style="color:#24292E">(buf[n]))</span><span style="color:#D73A49">&#x26;0x</span><span style="color:#005CC5">FF</span><span style="color:#24292E">] </span><span style="color:#D73A49">^</span><span style="color:#24292E"> (c </span><span style="color:#D73A49">>></span><span style="color:#005CC5"> 8</span><span style="color:#24292E">)</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#D73A49"> return</span><span style="color:#24292E"> c</span></span>
-<span class="line"><span style="color:#24292E">}</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">func</span><span style="color:#6F42C1"> crc</span><span style="color:#24292E">(</span><span style="color:#E36209">buf</span><span style="color:#24292E"> []</span><span style="color:#D73A49">byte</span><span style="color:#24292E">) </span><span style="color:#D73A49">uint32</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#D73A49"> return</span><span style="color:#6F42C1"> updateCrc</span><span style="color:#24292E">(</span><span style="color:#D73A49">0x</span><span style="color:#005CC5">FFFFFFFF</span><span style="color:#24292E">, buf) </span><span style="color:#D73A49">^</span><span style="color:#D73A49"> 0x</span><span style="color:#005CC5">FFFFFFFF</span></span>
-<span class="line"><span style="color:#24292E">}</span></span></code></pre>
- </div>
- <p>
- できた <code>crc</code> 関数を使って、chunk 一般を書き込む関数も用意しておこう。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">func</span><span style="color:#6F42C1"> writeChunk</span><span style="color:#24292E">(</span><span style="color:#E36209">w</span><span style="color:#6F42C1"> io</span><span style="color:#24292E">.</span><span style="color:#6F42C1">Writer</span><span style="color:#24292E">, </span><span style="color:#E36209">chunkType</span><span style="color:#D73A49"> string</span><span style="color:#24292E">, </span><span style="color:#E36209">data</span><span style="color:#24292E"> []</span><span style="color:#D73A49">byte</span><span style="color:#24292E">) {</span></span>
-<span class="line"><span style="color:#24292E"> typeAndData </span><span style="color:#D73A49">:=</span><span style="color:#6F42C1"> make</span><span style="color:#24292E">([]</span><span style="color:#D73A49">byte</span><span style="color:#24292E">, </span><span style="color:#005CC5">0</span><span style="color:#24292E">, </span><span style="color:#6F42C1">len</span><span style="color:#24292E">(chunkType)</span><span style="color:#D73A49">+</span><span style="color:#6F42C1">len</span><span style="color:#24292E">(data))</span></span>
-<span class="line"><span style="color:#24292E"> typeAndData </span><span style="color:#D73A49">=</span><span style="color:#6F42C1"> append</span><span style="color:#24292E">(typeAndData, []</span><span style="color:#D73A49">byte</span><span style="color:#24292E">(chunkType)</span><span style="color:#D73A49">...</span><span style="color:#24292E">)</span></span>
-<span class="line"><span style="color:#24292E"> typeAndData </span><span style="color:#D73A49">=</span><span style="color:#6F42C1"> append</span><span style="color:#24292E">(typeAndData, data</span><span style="color:#D73A49">...</span><span style="color:#24292E">)</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(w, binary.BigEndian, </span><span style="color:#D73A49">uint32</span><span style="color:#24292E">(</span><span style="color:#6F42C1">len</span><span style="color:#24292E">(data)))</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(w, binary.BigEndian, typeAndData)</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(w, binary.BigEndian, </span><span style="color:#6F42C1">crc</span><span style="color:#24292E">(typeAndData))</span></span>
-<span class="line"><span style="color:#24292E">}</span></span></code></pre>
- </div>
- <p>
- 仕様どおり、<code>chunkType</code> と <code>data</code> から CRC を計算し、<code>data</code> の長さと合わせて書き込んでいる。PNG では基本的に big endian を使うことに注意する。
- </p>
- <p>
- 準備ができたところで、具体的な chunk をエンコードしていく。
- </p>
- </section>
- <section id="section--implement-png-encoder--ihdr-chunk">
- <h3><a href="#section--implement-png-encoder--ihdr-chunk">IHDR chunk</a></h3>
- <p>
- IHDR chunk は最初に配置される chunk である。次のようなデータからなる。
- </p>
- <ol>
- <li>
- 画像の幅 (符号なし 4 バイト整数)
- </li>
- <li>
- 画像の高さ (符号なし 4 バイト整数)
- </li>
- <li>
- ビット深度 (符号なし 1 バイト整数)
- <ul>
- <li>
- 1 色に使うビット数。1 ピクセルに 24 bit 使う truecolor 画像では 8 になる
- </li>
- </ul>
- </li>
- <li>
- 色タイプ (符号なし 1 バイト整数)
- <ul>
- <li>
- 0: グレースケール
- </li>
- <li>
- 2: Truecolor (今回はこれに決め打ち)
- </li>
- <li>
- 3: パレットのインデックス
- </li>
- <li>
- 4: グレースケール + アルファ
- </li>
- <li>
- 6: Truecolor + アルファ
- </li>
- </ul>
- </li>
- <li>
- 圧縮方式 (符号なし 1 バイト整数)
- <ul>
- <li>
- PNG の仕様書に 0 しか定義されていないので 0 で固定
- </li>
- </ul>
- </li>
- <li>
- フィルタ方式 (符号なし 1 バイト整数)
- <ul>
- <li>
- PNG の仕様書に 0 しか定義されていないので 0 で固定
- </li>
- </ul>
- </li>
- <li>
- インターレース方式 (符号なし 1 バイト整数)
- <ul>
- <li>
- 今回はインターレースしないので 0
- </li>
- </ul>
- </li>
- </ol>
- <p>
- 今回ほとんどのデータは決め打ちするので、データに応じて変わるのは width と height だけになる。コードは次のようになる。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">import</span><span style="color:#032F62"> "</span><span style="color:#6F42C1">bytes</span><span style="color:#032F62">"</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">func</span><span style="color:#6F42C1"> writeChunkIhdr</span><span style="color:#24292E">(</span><span style="color:#E36209">w</span><span style="color:#6F42C1"> io</span><span style="color:#24292E">.</span><span style="color:#6F42C1">Writer</span><span style="color:#24292E">, </span><span style="color:#E36209">width</span><span style="color:#24292E">, </span><span style="color:#E36209">height</span><span style="color:#D73A49"> uint32</span><span style="color:#24292E">) {</span></span>
-<span class="line"><span style="color:#D73A49"> var</span><span style="color:#24292E"> buf </span><span style="color:#6F42C1">bytes</span><span style="color:#24292E">.</span><span style="color:#6F42C1">Buffer</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">buf, binary.BigEndian, width)</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">buf, binary.BigEndian, height)</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">buf, binary.BigEndian, </span><span style="color:#D73A49">uint8</span><span style="color:#24292E">(</span><span style="color:#005CC5">8</span><span style="color:#24292E">))</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">buf, binary.BigEndian, </span><span style="color:#D73A49">uint8</span><span style="color:#24292E">(</span><span style="color:#005CC5">2</span><span style="color:#24292E">))</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">buf, binary.BigEndian, </span><span style="color:#D73A49">uint8</span><span style="color:#24292E">(</span><span style="color:#005CC5">0</span><span style="color:#24292E">))</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">buf, binary.BigEndian, </span><span style="color:#D73A49">uint8</span><span style="color:#24292E">(</span><span style="color:#005CC5">0</span><span style="color:#24292E">))</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">buf, binary.BigEndian, </span><span style="color:#D73A49">uint8</span><span style="color:#24292E">(</span><span style="color:#005CC5">0</span><span style="color:#24292E">))</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#6F42C1"> writeChunk</span><span style="color:#24292E">(w, </span><span style="color:#032F62">"IHDR"</span><span style="color:#24292E">, buf.</span><span style="color:#6F42C1">Bytes</span><span style="color:#24292E">())</span></span>
-<span class="line"><span style="color:#24292E">}</span></span></code></pre>
- </div>
- </section>
- <section id="section--implement-png-encoder--idat-chunk">
- <h3><a href="#section--implement-png-encoder--idat-chunk">IDAT chunk</a></h3>
- <p>
- IDAT chunk は、実際の画像データが格納された chunk である。IDAT chunk は deflate アルゴリズムにより圧縮され、zlib 形式で格納される。
- </p>
- <section id="section--implement-png-encoder--idat-chunk--zlib">
- <h4><a href="#section--implement-png-encoder--idat-chunk--zlib">Zlib</a></h4>
- <p>
- まずは zlib について確認する。おおよそ次のような構造になっている。
- </p>
- <ol>
- <li>
- 固定で 0x78 (符号なし 1 バイト整数)
- </li>
- <li>
- 固定で 0x01 (符号なし 1 バイト整数)
- </li>
- <li>
- データ
- </li>
- <li>
- データの Adler-32
- </li>
- </ol>
- <p>
- 最初の 2 バイトにも意味はあるが、PNG では固定で構わない。
- </p>
- <p>
- Adler-32 も CRC と同じく誤り検出符号である。こちらも zlib の仕様書に C 言語でサンプルコードが記載されている ( <a href="https://www.rfc-editor.org/rfc/rfc1950#section-9" rel="noreferrer" target="_blank">9. Appendix: Sample code</a> ) ので、Go に移植する。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">const</span><span style="color:#005CC5"> adler32Base</span><span style="color:#D73A49"> =</span><span style="color:#005CC5"> 65521</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">func</span><span style="color:#6F42C1"> updateAdler32</span><span style="color:#24292E">(</span><span style="color:#E36209">adler</span><span style="color:#D73A49"> uint32</span><span style="color:#24292E">, </span><span style="color:#E36209">buf</span><span style="color:#24292E"> []</span><span style="color:#D73A49">byte</span><span style="color:#24292E">) </span><span style="color:#D73A49">uint32</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#24292E"> s1 </span><span style="color:#D73A49">:=</span><span style="color:#24292E"> adler </span><span style="color:#D73A49">&#x26;</span><span style="color:#D73A49"> 0x</span><span style="color:#005CC5">FFFF</span></span>
-<span class="line"><span style="color:#24292E"> s2 </span><span style="color:#D73A49">:=</span><span style="color:#24292E"> (adler </span><span style="color:#D73A49">>></span><span style="color:#005CC5"> 16</span><span style="color:#24292E">) </span><span style="color:#D73A49">&#x26;</span><span style="color:#D73A49"> 0x</span><span style="color:#005CC5">FFFF</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49"> for</span><span style="color:#24292E"> n </span><span style="color:#D73A49">:=</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">; n </span><span style="color:#D73A49">&#x3C;</span><span style="color:#6F42C1"> len</span><span style="color:#24292E">(buf); n</span><span style="color:#D73A49">++</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#24292E"> s1 </span><span style="color:#D73A49">=</span><span style="color:#24292E"> (s1 </span><span style="color:#D73A49">+</span><span style="color:#D73A49"> uint32</span><span style="color:#24292E">(buf[n])) </span><span style="color:#D73A49">%</span><span style="color:#24292E"> adler32Base</span></span>
-<span class="line"><span style="color:#24292E"> s2 </span><span style="color:#D73A49">=</span><span style="color:#24292E"> (s2 </span><span style="color:#D73A49">+</span><span style="color:#24292E"> s1) </span><span style="color:#D73A49">%</span><span style="color:#24292E"> adler32Base</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#D73A49"> return</span><span style="color:#24292E"> (s2 </span><span style="color:#D73A49">&#x3C;&#x3C;</span><span style="color:#005CC5"> 16</span><span style="color:#24292E">) </span><span style="color:#D73A49">+</span><span style="color:#24292E"> s1</span></span>
-<span class="line"><span style="color:#24292E">}</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">func</span><span style="color:#6F42C1"> adler32</span><span style="color:#24292E">(</span><span style="color:#E36209">buf</span><span style="color:#24292E"> []</span><span style="color:#D73A49">byte</span><span style="color:#24292E">) </span><span style="color:#D73A49">uint32</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#D73A49"> return</span><span style="color:#6F42C1"> updateAdler32</span><span style="color:#24292E">(</span><span style="color:#005CC5">1</span><span style="color:#24292E">, buf)</span></span>
-<span class="line"><span style="color:#24292E">}</span></span></code></pre>
- </div>
- <p>
- 「データ」の部分には圧縮したデータが入るのだが、真面目に deflate アルゴリズムを実装する必要はない。Zlib には無圧縮のデータブロックを格納することができるので、これを使う。本来は、データの圧縮効率の悪いランダムなデータをそのまま格納するためのものだが、今回は deflate の実装をサボるために使う。
- </p>
- <p>
- 1 つの無圧縮ブロックには 65535 (2<sup>16</sup> - 1) バイトまで格納できる。それぞれのブロックは次のような構成になっている。
- </p>
- <ol>
- <li>
- 最終ブロックなら 1、そうでなければ 0 (符号なし 1 バイト整数)
- </li>
- <li>
- ブロックのバイト長 (符号なし 2 バイト整数)
- </li>
- <li>
- ブロックのバイト長の 1 の補数、あるいはビット反転 (符号なし 2 バイト整数)
- </li>
- <li>
- データ (最大 65535 バイト)
- </li>
- </ol>
- <p>
- 実際にこの手抜き zlib を実装したものがこちら:
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">func</span><span style="color:#6F42C1"> encodeZlib</span><span style="color:#24292E">(</span><span style="color:#E36209">data</span><span style="color:#24292E"> []</span><span style="color:#D73A49">byte</span><span style="color:#24292E">) []</span><span style="color:#D73A49">byte</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#D73A49"> var</span><span style="color:#24292E"> buf </span><span style="color:#6F42C1">bytes</span><span style="color:#24292E">.</span><span style="color:#6F42C1">Buffer</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">buf, binary.BigEndian, </span><span style="color:#D73A49">uint8</span><span style="color:#24292E">(</span><span style="color:#D73A49">0x</span><span style="color:#005CC5">78</span><span style="color:#24292E">))</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">buf, binary.BigEndian, </span><span style="color:#D73A49">uint8</span><span style="color:#24292E">(</span><span style="color:#D73A49">0x</span><span style="color:#005CC5">01</span><span style="color:#24292E">))</span></span>
-<span class="line"><span style="color:#24292E"> blockSize </span><span style="color:#D73A49">:=</span><span style="color:#005CC5"> 65535</span></span>
-<span class="line"><span style="color:#24292E"> isFinalBlock </span><span style="color:#D73A49">:=</span><span style="color:#005CC5"> false</span></span>
-<span class="line"><span style="color:#D73A49"> for</span><span style="color:#24292E"> i </span><span style="color:#D73A49">:=</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">; </span><span style="color:#D73A49">!</span><span style="color:#24292E">isFinalBlock; i</span><span style="color:#D73A49">++</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#D73A49"> var</span><span style="color:#24292E"> block []</span><span style="color:#D73A49">byte</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#6F42C1"> len</span><span style="color:#24292E">(data) </span><span style="color:#D73A49">&#x3C;=</span><span style="color:#24292E"> (i</span><span style="color:#D73A49">+</span><span style="color:#005CC5">1</span><span style="color:#24292E">)</span><span style="color:#D73A49">*</span><span style="color:#24292E">blockSize {</span></span>
-<span class="line"><span style="color:#24292E"> block </span><span style="color:#D73A49">=</span><span style="color:#24292E"> data[i</span><span style="color:#D73A49">*</span><span style="color:#24292E">blockSize:]</span></span>
-<span class="line"><span style="color:#24292E"> isFinalBlock </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> true</span></span>
-<span class="line"><span style="color:#24292E"> } </span><span style="color:#D73A49">else</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#24292E"> block </span><span style="color:#D73A49">=</span><span style="color:#24292E"> data[i</span><span style="color:#D73A49">*</span><span style="color:#24292E">blockSize : (i</span><span style="color:#D73A49">+</span><span style="color:#005CC5">1</span><span style="color:#24292E">)</span><span style="color:#D73A49">*</span><span style="color:#24292E">blockSize]</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">buf, binary.BigEndian, isFinalBlock)</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">buf, binary.LittleEndian, </span><span style="color:#D73A49">uint16</span><span style="color:#24292E">(</span><span style="color:#6F42C1">len</span><span style="color:#24292E">(block)))</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">buf, binary.LittleEndian, </span><span style="color:#D73A49">uint16</span><span style="color:#24292E">(</span><span style="color:#D73A49">^</span><span style="color:#6F42C1">len</span><span style="color:#24292E">(block)))</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">buf, binary.LittleEndian, block)</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">buf, binary.BigEndian, </span><span style="color:#6F42C1">adler32</span><span style="color:#24292E">(data))</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49"> return</span><span style="color:#24292E"> buf.</span><span style="color:#6F42C1">Bytes</span><span style="color:#24292E">()</span></span>
-<span class="line"><span style="color:#24292E">}</span></span></code></pre>
- </div>
- </section>
- <section id="section--implement-png-encoder--idat-chunk--image-data">
- <h4><a href="#section--implement-png-encoder--idat-chunk--image-data">画像データ</a></h4>
- <p>
- では次に、zlib 形式で格納するデータを用意する。PNG 画像は次のような順にスキャンする。画像の左上のピクセルから同じ行を横にスキャンしていき、一番右まで到達したら次の行の左に向かう。右下のピクセルまで行けば終わり。要は Z 字型に進んでいく。
- </p>
- <p>
- また、それぞれの行の先頭には、圧縮のためのフィルタタイプを指定する。ただ、今回はその実装を省略するために、常にフィルタ 0 (何も加工しない) を使う。
- </p>
- <p>
- 先ほどの <code>encodeZlib</code> も使って実際に実装したものがこちら:
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">func</span><span style="color:#6F42C1"> writeChunkIdat</span><span style="color:#24292E">(</span><span style="color:#E36209">w</span><span style="color:#6F42C1"> io</span><span style="color:#24292E">.</span><span style="color:#6F42C1">Writer</span><span style="color:#24292E">, </span><span style="color:#E36209">width</span><span style="color:#24292E">, </span><span style="color:#E36209">height</span><span style="color:#D73A49"> uint32</span><span style="color:#24292E">, </span><span style="color:#E36209">img</span><span style="color:#6F42C1"> image</span><span style="color:#24292E">.</span><span style="color:#6F42C1">Image</span><span style="color:#24292E">) {</span></span>
-<span class="line"><span style="color:#D73A49"> var</span><span style="color:#24292E"> pixels </span><span style="color:#6F42C1">bytes</span><span style="color:#24292E">.</span><span style="color:#6F42C1">Buffer</span></span>
-<span class="line"><span style="color:#D73A49"> for</span><span style="color:#24292E"> y </span><span style="color:#D73A49">:=</span><span style="color:#D73A49"> uint32</span><span style="color:#24292E">(</span><span style="color:#005CC5">0</span><span style="color:#24292E">); y </span><span style="color:#D73A49">&#x3C;</span><span style="color:#24292E"> height; y</span><span style="color:#D73A49">++</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">pixels, binary.BigEndian, </span><span style="color:#D73A49">uint8</span><span style="color:#24292E">(</span><span style="color:#005CC5">0</span><span style="color:#24292E">))</span></span>
-<span class="line"><span style="color:#D73A49"> for</span><span style="color:#24292E"> x </span><span style="color:#D73A49">:=</span><span style="color:#D73A49"> uint32</span><span style="color:#24292E">(</span><span style="color:#005CC5">0</span><span style="color:#24292E">); x </span><span style="color:#D73A49">&#x3C;</span><span style="color:#24292E"> width; x</span><span style="color:#D73A49">++</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#24292E"> r, g, b, _ </span><span style="color:#D73A49">:=</span><span style="color:#24292E"> img.</span><span style="color:#6F42C1">At</span><span style="color:#24292E">(</span><span style="color:#D73A49">int</span><span style="color:#24292E">(x), </span><span style="color:#D73A49">int</span><span style="color:#24292E">(y)).</span><span style="color:#6F42C1">RGBA</span><span style="color:#24292E">()</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">pixels, binary.BigEndian, </span><span style="color:#D73A49">uint8</span><span style="color:#24292E">(r))</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">pixels, binary.BigEndian, </span><span style="color:#D73A49">uint8</span><span style="color:#24292E">(g))</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">pixels, binary.BigEndian, </span><span style="color:#D73A49">uint8</span><span style="color:#24292E">(b))</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#6F42C1"> writeChunk</span><span style="color:#24292E">(w, </span><span style="color:#032F62">"IDAT"</span><span style="color:#24292E">, </span><span style="color:#6F42C1">encodeZlib</span><span style="color:#24292E">(pixels.</span><span style="color:#6F42C1">Bytes</span><span style="color:#24292E">()))</span></span>
-<span class="line"><span style="color:#24292E">}</span></span></code></pre>
- </div>
- </section>
- </section>
- <section id="section--implement-png-encoder--iend-chunk">
- <h3><a href="#section--implement-png-encoder--iend-chunk">IEND chunk</a></h3>
- <p>
- 最後に IEND chunk を書き込む。これは PNG 画像の最後に配置される chunk で、PNG のデコーダはこの chunk に出会うとそこでデコードを停止する。
- </p>
- <p>
- 特に追加のデータはなく、必要なのは chunk type の <code>IEND</code> くらいなので実装は簡単:
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">func</span><span style="color:#6F42C1"> writeChunkIend</span><span style="color:#24292E">(</span><span style="color:#E36209">w</span><span style="color:#6F42C1"> io</span><span style="color:#24292E">.</span><span style="color:#6F42C1">Writer</span><span style="color:#24292E">) {</span></span>
-<span class="line"><span style="color:#6F42C1"> writeChunk</span><span style="color:#24292E">(w, </span><span style="color:#032F62">"IEND"</span><span style="color:#24292E">, </span><span style="color:#005CC5">nil</span><span style="color:#24292E">)</span></span>
-<span class="line"><span style="color:#24292E">}</span></span></code></pre>
- </div>
- </section>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">おわりに</a></h2>
- <p>
- 最後に全ソースコードを再掲しておく。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">package</span><span style="color:#6F42C1"> main</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">import</span><span style="color:#24292E"> (</span></span>
-<span class="line"><span style="color:#032F62"> "</span><span style="color:#6F42C1">bytes</span><span style="color:#032F62">"</span></span>
-<span class="line"><span style="color:#032F62"> "</span><span style="color:#6F42C1">encoding/binary</span><span style="color:#032F62">"</span></span>
-<span class="line"><span style="color:#032F62"> "</span><span style="color:#6F42C1">image</span><span style="color:#032F62">"</span></span>
-<span class="line"><span style="color:#24292E"> _ </span><span style="color:#032F62">"</span><span style="color:#6F42C1">image/png</span><span style="color:#032F62">"</span></span>
-<span class="line"><span style="color:#032F62"> "</span><span style="color:#6F42C1">io</span><span style="color:#032F62">"</span></span>
-<span class="line"><span style="color:#032F62"> "</span><span style="color:#6F42C1">os</span><span style="color:#032F62">"</span></span>
-<span class="line"><span style="color:#24292E">)</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">func</span><span style="color:#6F42C1"> main</span><span style="color:#24292E">() {</span></span>
-<span class="line"><span style="color:#24292E"> inFile, err </span><span style="color:#D73A49">:=</span><span style="color:#24292E"> os.</span><span style="color:#6F42C1">Open</span><span style="color:#24292E">(</span><span style="color:#032F62">"input.png"</span><span style="color:#24292E">)</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> err </span><span style="color:#D73A49">!=</span><span style="color:#005CC5"> nil</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#6F42C1"> panic</span><span style="color:#24292E">(err)</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#D73A49"> defer</span><span style="color:#24292E"> inFile.</span><span style="color:#6F42C1">Close</span><span style="color:#24292E">()</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E"> img, _, err </span><span style="color:#D73A49">:=</span><span style="color:#24292E"> image.</span><span style="color:#6F42C1">Decode</span><span style="color:#24292E">(inFile)</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> err </span><span style="color:#D73A49">!=</span><span style="color:#005CC5"> nil</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#6F42C1"> panic</span><span style="color:#24292E">(err)</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E"> outFile, err </span><span style="color:#D73A49">:=</span><span style="color:#24292E"> os.</span><span style="color:#6F42C1">Create</span><span style="color:#24292E">(</span><span style="color:#032F62">"output.png"</span><span style="color:#24292E">)</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> err </span><span style="color:#D73A49">!=</span><span style="color:#005CC5"> nil</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#6F42C1"> panic</span><span style="color:#24292E">(err)</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#D73A49"> defer</span><span style="color:#24292E"> outFile.</span><span style="color:#6F42C1">Close</span><span style="color:#24292E">()</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#6F42C1"> writePng</span><span style="color:#24292E">(outFile, img)</span></span>
-<span class="line"><span style="color:#24292E">}</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">func</span><span style="color:#6F42C1"> writePng</span><span style="color:#24292E">(</span><span style="color:#E36209">w</span><span style="color:#6F42C1"> io</span><span style="color:#24292E">.</span><span style="color:#6F42C1">Writer</span><span style="color:#24292E">, </span><span style="color:#E36209">img</span><span style="color:#6F42C1"> image</span><span style="color:#24292E">.</span><span style="color:#6F42C1">Image</span><span style="color:#24292E">) {</span></span>
-<span class="line"><span style="color:#24292E"> width </span><span style="color:#D73A49">:=</span><span style="color:#D73A49"> uint32</span><span style="color:#24292E">(img.</span><span style="color:#6F42C1">Bounds</span><span style="color:#24292E">().</span><span style="color:#6F42C1">Dx</span><span style="color:#24292E">())</span></span>
-<span class="line"><span style="color:#24292E"> height </span><span style="color:#D73A49">:=</span><span style="color:#D73A49"> uint32</span><span style="color:#24292E">(img.</span><span style="color:#6F42C1">Bounds</span><span style="color:#24292E">().</span><span style="color:#6F42C1">Dy</span><span style="color:#24292E">())</span></span>
-<span class="line"><span style="color:#6F42C1"> writeSignature</span><span style="color:#24292E">(w)</span></span>
-<span class="line"><span style="color:#6F42C1"> writeChunkIhdr</span><span style="color:#24292E">(w, width, height)</span></span>
-<span class="line"><span style="color:#6F42C1"> writeChunkIdat</span><span style="color:#24292E">(w, width, height, img)</span></span>
-<span class="line"><span style="color:#6F42C1"> writeChunkIend</span><span style="color:#24292E">(w)</span></span>
-<span class="line"><span style="color:#24292E">}</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">func</span><span style="color:#6F42C1"> writeSignature</span><span style="color:#24292E">(</span><span style="color:#E36209">w</span><span style="color:#6F42C1"> io</span><span style="color:#24292E">.</span><span style="color:#6F42C1">Writer</span><span style="color:#24292E">) {</span></span>
-<span class="line"><span style="color:#24292E"> sig </span><span style="color:#D73A49">:=</span><span style="color:#24292E"> [</span><span style="color:#005CC5">8</span><span style="color:#24292E">]</span><span style="color:#D73A49">uint8</span><span style="color:#24292E">{</span></span>
-<span class="line"><span style="color:#D73A49"> 0x</span><span style="color:#005CC5">89</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#D73A49"> 0x</span><span style="color:#005CC5">50</span><span style="color:#24292E">, </span><span style="color:#6A737D">// P</span></span>
-<span class="line"><span style="color:#D73A49"> 0x</span><span style="color:#005CC5">4E</span><span style="color:#24292E">, </span><span style="color:#6A737D">// N</span></span>
-<span class="line"><span style="color:#D73A49"> 0x</span><span style="color:#005CC5">47</span><span style="color:#24292E">, </span><span style="color:#6A737D">// G</span></span>
-<span class="line"><span style="color:#D73A49"> 0x</span><span style="color:#005CC5">0D</span><span style="color:#24292E">, </span><span style="color:#6A737D">// CR</span></span>
-<span class="line"><span style="color:#D73A49"> 0x</span><span style="color:#005CC5">0A</span><span style="color:#24292E">, </span><span style="color:#6A737D">// LF</span></span>
-<span class="line"><span style="color:#D73A49"> 0x</span><span style="color:#005CC5">1A</span><span style="color:#24292E">, </span><span style="color:#6A737D">// EOF (^Z)</span></span>
-<span class="line"><span style="color:#D73A49"> 0x</span><span style="color:#005CC5">0A</span><span style="color:#24292E">, </span><span style="color:#6A737D">// LF</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(w, binary.BigEndian, sig)</span></span>
-<span class="line"><span style="color:#24292E">}</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">func</span><span style="color:#6F42C1"> writeChunkIhdr</span><span style="color:#24292E">(</span><span style="color:#E36209">w</span><span style="color:#6F42C1"> io</span><span style="color:#24292E">.</span><span style="color:#6F42C1">Writer</span><span style="color:#24292E">, </span><span style="color:#E36209">width</span><span style="color:#24292E">, </span><span style="color:#E36209">height</span><span style="color:#D73A49"> uint32</span><span style="color:#24292E">) {</span></span>
-<span class="line"><span style="color:#D73A49"> var</span><span style="color:#24292E"> buf </span><span style="color:#6F42C1">bytes</span><span style="color:#24292E">.</span><span style="color:#6F42C1">Buffer</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">buf, binary.BigEndian, width)</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">buf, binary.BigEndian, height)</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">buf, binary.BigEndian, </span><span style="color:#D73A49">uint8</span><span style="color:#24292E">(</span><span style="color:#005CC5">8</span><span style="color:#24292E">))</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">buf, binary.BigEndian, </span><span style="color:#D73A49">uint8</span><span style="color:#24292E">(</span><span style="color:#005CC5">2</span><span style="color:#24292E">))</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">buf, binary.BigEndian, </span><span style="color:#D73A49">uint8</span><span style="color:#24292E">(</span><span style="color:#005CC5">0</span><span style="color:#24292E">))</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">buf, binary.BigEndian, </span><span style="color:#D73A49">uint8</span><span style="color:#24292E">(</span><span style="color:#005CC5">0</span><span style="color:#24292E">))</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">buf, binary.BigEndian, </span><span style="color:#D73A49">uint8</span><span style="color:#24292E">(</span><span style="color:#005CC5">0</span><span style="color:#24292E">))</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#6F42C1"> writeChunk</span><span style="color:#24292E">(w, </span><span style="color:#032F62">"IHDR"</span><span style="color:#24292E">, buf.</span><span style="color:#6F42C1">Bytes</span><span style="color:#24292E">())</span></span>
-<span class="line"><span style="color:#24292E">}</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">func</span><span style="color:#6F42C1"> writeChunkIdat</span><span style="color:#24292E">(</span><span style="color:#E36209">w</span><span style="color:#6F42C1"> io</span><span style="color:#24292E">.</span><span style="color:#6F42C1">Writer</span><span style="color:#24292E">, </span><span style="color:#E36209">width</span><span style="color:#24292E">, </span><span style="color:#E36209">height</span><span style="color:#D73A49"> uint32</span><span style="color:#24292E">, </span><span style="color:#E36209">img</span><span style="color:#6F42C1"> image</span><span style="color:#24292E">.</span><span style="color:#6F42C1">Image</span><span style="color:#24292E">) {</span></span>
-<span class="line"><span style="color:#D73A49"> var</span><span style="color:#24292E"> pixels </span><span style="color:#6F42C1">bytes</span><span style="color:#24292E">.</span><span style="color:#6F42C1">Buffer</span></span>
-<span class="line"><span style="color:#D73A49"> for</span><span style="color:#24292E"> y </span><span style="color:#D73A49">:=</span><span style="color:#D73A49"> uint32</span><span style="color:#24292E">(</span><span style="color:#005CC5">0</span><span style="color:#24292E">); y </span><span style="color:#D73A49">&#x3C;</span><span style="color:#24292E"> height; y</span><span style="color:#D73A49">++</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">pixels, binary.BigEndian, </span><span style="color:#D73A49">uint8</span><span style="color:#24292E">(</span><span style="color:#005CC5">0</span><span style="color:#24292E">))</span></span>
-<span class="line"><span style="color:#D73A49"> for</span><span style="color:#24292E"> x </span><span style="color:#D73A49">:=</span><span style="color:#D73A49"> uint32</span><span style="color:#24292E">(</span><span style="color:#005CC5">0</span><span style="color:#24292E">); x </span><span style="color:#D73A49">&#x3C;</span><span style="color:#24292E"> width; x</span><span style="color:#D73A49">++</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#24292E"> r, g, b, _ </span><span style="color:#D73A49">:=</span><span style="color:#24292E"> img.</span><span style="color:#6F42C1">At</span><span style="color:#24292E">(</span><span style="color:#D73A49">int</span><span style="color:#24292E">(x), </span><span style="color:#D73A49">int</span><span style="color:#24292E">(y)).</span><span style="color:#6F42C1">RGBA</span><span style="color:#24292E">()</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">pixels, binary.BigEndian, </span><span style="color:#D73A49">uint8</span><span style="color:#24292E">(r))</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">pixels, binary.BigEndian, </span><span style="color:#D73A49">uint8</span><span style="color:#24292E">(g))</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">pixels, binary.BigEndian, </span><span style="color:#D73A49">uint8</span><span style="color:#24292E">(b))</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#6F42C1"> writeChunk</span><span style="color:#24292E">(w, </span><span style="color:#032F62">"IDAT"</span><span style="color:#24292E">, </span><span style="color:#6F42C1">encodeZlib</span><span style="color:#24292E">(pixels.</span><span style="color:#6F42C1">Bytes</span><span style="color:#24292E">()))</span></span>
-<span class="line"><span style="color:#24292E">}</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">func</span><span style="color:#6F42C1"> encodeZlib</span><span style="color:#24292E">(</span><span style="color:#E36209">data</span><span style="color:#24292E"> []</span><span style="color:#D73A49">byte</span><span style="color:#24292E">) []</span><span style="color:#D73A49">byte</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#D73A49"> var</span><span style="color:#24292E"> buf </span><span style="color:#6F42C1">bytes</span><span style="color:#24292E">.</span><span style="color:#6F42C1">Buffer</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">buf, binary.BigEndian, </span><span style="color:#D73A49">uint8</span><span style="color:#24292E">(</span><span style="color:#D73A49">0x</span><span style="color:#005CC5">78</span><span style="color:#24292E">))</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">buf, binary.BigEndian, </span><span style="color:#D73A49">uint8</span><span style="color:#24292E">(</span><span style="color:#D73A49">0x</span><span style="color:#005CC5">01</span><span style="color:#24292E">))</span></span>
-<span class="line"><span style="color:#24292E"> blockSize </span><span style="color:#D73A49">:=</span><span style="color:#005CC5"> 65535</span></span>
-<span class="line"><span style="color:#24292E"> isFinalBlock </span><span style="color:#D73A49">:=</span><span style="color:#005CC5"> false</span></span>
-<span class="line"><span style="color:#D73A49"> for</span><span style="color:#24292E"> i </span><span style="color:#D73A49">:=</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">; </span><span style="color:#D73A49">!</span><span style="color:#24292E">isFinalBlock; i</span><span style="color:#D73A49">++</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#D73A49"> var</span><span style="color:#24292E"> block []</span><span style="color:#D73A49">byte</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#6F42C1"> len</span><span style="color:#24292E">(data) </span><span style="color:#D73A49">&#x3C;=</span><span style="color:#24292E"> (i</span><span style="color:#D73A49">+</span><span style="color:#005CC5">1</span><span style="color:#24292E">)</span><span style="color:#D73A49">*</span><span style="color:#24292E">blockSize {</span></span>
-<span class="line"><span style="color:#24292E"> block </span><span style="color:#D73A49">=</span><span style="color:#24292E"> data[i</span><span style="color:#D73A49">*</span><span style="color:#24292E">blockSize:]</span></span>
-<span class="line"><span style="color:#24292E"> isFinalBlock </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> true</span></span>
-<span class="line"><span style="color:#24292E"> } </span><span style="color:#D73A49">else</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#24292E"> block </span><span style="color:#D73A49">=</span><span style="color:#24292E"> data[i</span><span style="color:#D73A49">*</span><span style="color:#24292E">blockSize : (i</span><span style="color:#D73A49">+</span><span style="color:#005CC5">1</span><span style="color:#24292E">)</span><span style="color:#D73A49">*</span><span style="color:#24292E">blockSize]</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">buf, binary.BigEndian, isFinalBlock)</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">buf, binary.LittleEndian, </span><span style="color:#D73A49">uint16</span><span style="color:#24292E">(</span><span style="color:#6F42C1">len</span><span style="color:#24292E">(block)))</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">buf, binary.LittleEndian, </span><span style="color:#D73A49">uint16</span><span style="color:#24292E">(</span><span style="color:#D73A49">^</span><span style="color:#6F42C1">len</span><span style="color:#24292E">(block)))</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">buf, binary.LittleEndian, block)</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(</span><span style="color:#D73A49">&#x26;</span><span style="color:#24292E">buf, binary.BigEndian, </span><span style="color:#6F42C1">adler32</span><span style="color:#24292E">(data))</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49"> return</span><span style="color:#24292E"> buf.</span><span style="color:#6F42C1">Bytes</span><span style="color:#24292E">()</span></span>
-<span class="line"><span style="color:#24292E">}</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">func</span><span style="color:#6F42C1"> writeChunkIend</span><span style="color:#24292E">(</span><span style="color:#E36209">w</span><span style="color:#6F42C1"> io</span><span style="color:#24292E">.</span><span style="color:#6F42C1">Writer</span><span style="color:#24292E">) {</span></span>
-<span class="line"><span style="color:#6F42C1"> writeChunk</span><span style="color:#24292E">(w, </span><span style="color:#032F62">"IEND"</span><span style="color:#24292E">, </span><span style="color:#005CC5">nil</span><span style="color:#24292E">)</span></span>
-<span class="line"><span style="color:#24292E">}</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">func</span><span style="color:#6F42C1"> writeChunk</span><span style="color:#24292E">(</span><span style="color:#E36209">w</span><span style="color:#6F42C1"> io</span><span style="color:#24292E">.</span><span style="color:#6F42C1">Writer</span><span style="color:#24292E">, </span><span style="color:#E36209">chunkType</span><span style="color:#D73A49"> string</span><span style="color:#24292E">, </span><span style="color:#E36209">data</span><span style="color:#24292E"> []</span><span style="color:#D73A49">byte</span><span style="color:#24292E">) {</span></span>
-<span class="line"><span style="color:#24292E"> typeAndData </span><span style="color:#D73A49">:=</span><span style="color:#6F42C1"> make</span><span style="color:#24292E">([]</span><span style="color:#D73A49">byte</span><span style="color:#24292E">, </span><span style="color:#005CC5">0</span><span style="color:#24292E">, </span><span style="color:#6F42C1">len</span><span style="color:#24292E">(chunkType)</span><span style="color:#D73A49">+</span><span style="color:#6F42C1">len</span><span style="color:#24292E">(data))</span></span>
-<span class="line"><span style="color:#24292E"> typeAndData </span><span style="color:#D73A49">=</span><span style="color:#6F42C1"> append</span><span style="color:#24292E">(typeAndData, []</span><span style="color:#D73A49">byte</span><span style="color:#24292E">(chunkType)</span><span style="color:#D73A49">...</span><span style="color:#24292E">)</span></span>
-<span class="line"><span style="color:#24292E"> typeAndData </span><span style="color:#D73A49">=</span><span style="color:#6F42C1"> append</span><span style="color:#24292E">(typeAndData, data</span><span style="color:#D73A49">...</span><span style="color:#24292E">)</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(w, binary.BigEndian, </span><span style="color:#D73A49">uint32</span><span style="color:#24292E">(</span><span style="color:#6F42C1">len</span><span style="color:#24292E">(data)))</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(w, binary.BigEndian, typeAndData)</span></span>
-<span class="line"><span style="color:#24292E"> binary.</span><span style="color:#6F42C1">Write</span><span style="color:#24292E">(w, binary.BigEndian, </span><span style="color:#6F42C1">crc</span><span style="color:#24292E">(typeAndData))</span></span>
-<span class="line"><span style="color:#24292E">}</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">var</span><span style="color:#24292E"> (</span></span>
-<span class="line"><span style="color:#24292E"> crcTable [</span><span style="color:#005CC5">256</span><span style="color:#24292E">]</span><span style="color:#D73A49">uint32</span></span>
-<span class="line"><span style="color:#24292E"> crcTableComputed </span><span style="color:#D73A49">bool</span></span>
-<span class="line"><span style="color:#24292E">)</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">func</span><span style="color:#6F42C1"> makeCrcTable</span><span style="color:#24292E">() {</span></span>
-<span class="line"><span style="color:#D73A49"> for</span><span style="color:#24292E"> n </span><span style="color:#D73A49">:=</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">; n </span><span style="color:#D73A49">&#x3C;</span><span style="color:#005CC5"> 256</span><span style="color:#24292E">; n</span><span style="color:#D73A49">++</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#24292E"> c </span><span style="color:#D73A49">:=</span><span style="color:#D73A49"> uint32</span><span style="color:#24292E">(n)</span></span>
-<span class="line"><span style="color:#D73A49"> for</span><span style="color:#24292E"> k </span><span style="color:#D73A49">:=</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">; k </span><span style="color:#D73A49">&#x3C;</span><span style="color:#005CC5"> 8</span><span style="color:#24292E">; k</span><span style="color:#D73A49">++</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> (c </span><span style="color:#D73A49">&#x26;</span><span style="color:#005CC5"> 1</span><span style="color:#24292E">) </span><span style="color:#D73A49">!=</span><span style="color:#005CC5"> 0</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#24292E"> c </span><span style="color:#D73A49">=</span><span style="color:#D73A49"> 0x</span><span style="color:#005CC5">EDB88320</span><span style="color:#D73A49"> ^</span><span style="color:#24292E"> (c </span><span style="color:#D73A49">>></span><span style="color:#005CC5"> 1</span><span style="color:#24292E">)</span></span>
-<span class="line"><span style="color:#24292E"> } </span><span style="color:#D73A49">else</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#24292E"> c </span><span style="color:#D73A49">=</span><span style="color:#24292E"> c </span><span style="color:#D73A49">>></span><span style="color:#005CC5"> 1</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#24292E"> crcTable[n] </span><span style="color:#D73A49">=</span><span style="color:#24292E"> c</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#24292E"> crcTableComputed </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> true</span></span>
-<span class="line"><span style="color:#24292E">}</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">func</span><span style="color:#6F42C1"> updateCrc</span><span style="color:#24292E">(</span><span style="color:#E36209">crc</span><span style="color:#D73A49"> uint32</span><span style="color:#24292E">, </span><span style="color:#E36209">buf</span><span style="color:#24292E"> []</span><span style="color:#D73A49">byte</span><span style="color:#24292E">) </span><span style="color:#D73A49">uint32</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#D73A49"> !</span><span style="color:#24292E">crcTableComputed {</span></span>
-<span class="line"><span style="color:#6F42C1"> makeCrcTable</span><span style="color:#24292E">()</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E"> c </span><span style="color:#D73A49">:=</span><span style="color:#24292E"> crc</span></span>
-<span class="line"><span style="color:#D73A49"> for</span><span style="color:#24292E"> n </span><span style="color:#D73A49">:=</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">; n </span><span style="color:#D73A49">&#x3C;</span><span style="color:#6F42C1"> len</span><span style="color:#24292E">(buf); n</span><span style="color:#D73A49">++</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#24292E"> c </span><span style="color:#D73A49">=</span><span style="color:#24292E"> crcTable[(c</span><span style="color:#D73A49">^uint32</span><span style="color:#24292E">(buf[n]))</span><span style="color:#D73A49">&#x26;0x</span><span style="color:#005CC5">FF</span><span style="color:#24292E">] </span><span style="color:#D73A49">^</span><span style="color:#24292E"> (c </span><span style="color:#D73A49">>></span><span style="color:#005CC5"> 8</span><span style="color:#24292E">)</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#D73A49"> return</span><span style="color:#24292E"> c</span></span>
-<span class="line"><span style="color:#24292E">}</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">func</span><span style="color:#6F42C1"> crc</span><span style="color:#24292E">(</span><span style="color:#E36209">buf</span><span style="color:#24292E"> []</span><span style="color:#D73A49">byte</span><span style="color:#24292E">) </span><span style="color:#D73A49">uint32</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#D73A49"> return</span><span style="color:#6F42C1"> updateCrc</span><span style="color:#24292E">(</span><span style="color:#D73A49">0x</span><span style="color:#005CC5">FFFFFFFF</span><span style="color:#24292E">, buf) </span><span style="color:#D73A49">^</span><span style="color:#D73A49"> 0x</span><span style="color:#005CC5">FFFFFFFF</span></span>
-<span class="line"><span style="color:#24292E">}</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">const</span><span style="color:#005CC5"> adler32Base</span><span style="color:#D73A49"> =</span><span style="color:#005CC5"> 65521</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">func</span><span style="color:#6F42C1"> updateAdler32</span><span style="color:#24292E">(</span><span style="color:#E36209">adler</span><span style="color:#D73A49"> uint32</span><span style="color:#24292E">, </span><span style="color:#E36209">buf</span><span style="color:#24292E"> []</span><span style="color:#D73A49">byte</span><span style="color:#24292E">) </span><span style="color:#D73A49">uint32</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#24292E"> s1 </span><span style="color:#D73A49">:=</span><span style="color:#24292E"> adler </span><span style="color:#D73A49">&#x26;</span><span style="color:#D73A49"> 0x</span><span style="color:#005CC5">FFFF</span></span>
-<span class="line"><span style="color:#24292E"> s2 </span><span style="color:#D73A49">:=</span><span style="color:#24292E"> (adler </span><span style="color:#D73A49">>></span><span style="color:#005CC5"> 16</span><span style="color:#24292E">) </span><span style="color:#D73A49">&#x26;</span><span style="color:#D73A49"> 0x</span><span style="color:#005CC5">FFFF</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49"> for</span><span style="color:#24292E"> n </span><span style="color:#D73A49">:=</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">; n </span><span style="color:#D73A49">&#x3C;</span><span style="color:#6F42C1"> len</span><span style="color:#24292E">(buf); n</span><span style="color:#D73A49">++</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#24292E"> s1 </span><span style="color:#D73A49">=</span><span style="color:#24292E"> (s1 </span><span style="color:#D73A49">+</span><span style="color:#D73A49"> uint32</span><span style="color:#24292E">(buf[n])) </span><span style="color:#D73A49">%</span><span style="color:#24292E"> adler32Base</span></span>
-<span class="line"><span style="color:#24292E"> s2 </span><span style="color:#D73A49">=</span><span style="color:#24292E"> (s2 </span><span style="color:#D73A49">+</span><span style="color:#24292E"> s1) </span><span style="color:#D73A49">%</span><span style="color:#24292E"> adler32Base</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#D73A49"> return</span><span style="color:#24292E"> (s2 </span><span style="color:#D73A49">&#x3C;&#x3C;</span><span style="color:#005CC5"> 16</span><span style="color:#24292E">) </span><span style="color:#D73A49">+</span><span style="color:#24292E"> s1</span></span>
-<span class="line"><span style="color:#24292E">}</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">func</span><span style="color:#6F42C1"> adler32</span><span style="color:#24292E">(</span><span style="color:#E36209">buf</span><span style="color:#24292E"> []</span><span style="color:#D73A49">byte</span><span style="color:#24292E">) </span><span style="color:#D73A49">uint32</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#D73A49"> return</span><span style="color:#6F42C1"> updateAdler32</span><span style="color:#24292E">(</span><span style="color:#005CC5">1</span><span style="color:#24292E">, buf)</span></span>
-<span class="line"><span style="color:#24292E">}</span></span></code></pre>
- </div>
- </section>
- <section id="section--references">
- <h2><a href="#section--references">参考</a></h2>
- <ul>
- <li>
- <a href="https://www.w3.org/TR/png" rel="noreferrer" target="_blank">Portable Network Graphics (PNG) Specification (Third Edition)</a>
- </li>
- <li>
- <a href="https://www.rfc-editor.org/rfc/rfc1950" rel="noreferrer" target="_blank">ZLIB Compressed Data Format Specification version 3.3</a>
- </li>
- </ul>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2023-04-04/phperkaigi-2023-report/index.html b/vhosts/blog/public/posts/2023-04-04/phperkaigi-2023-report/index.html
deleted file mode 100644
index 2fb7421b..00000000
--- a/vhosts/blog/public/posts/2023-04-04/phperkaigi-2023-report/index.html
+++ /dev/null
@@ -1,264 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2023 nsfisis">
- <meta name="description" content="2023-03-23 から 2023-03-25 にかけて開催された、PHPerKaigi 2023 に参加した。">
- <meta name="keywords" content="カンファレンス,PHP,PHPerKaigi">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHPerKaigi 2023 参加レポ|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="2023-03-23 から 2023-03-25 にかけて開催された、PHPerKaigi 2023 に参加した。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHPerKaigi 2023 参加レポ|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">PHPerKaigi 2023 参加レポ</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/conference/">カンファレンス</a>
- </li>
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phperkaigi/">PHPerKaigi</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2023-04-04">2023-04-04</time>: 公開
- </li>
- <li class="revision">
- <time datetime="2023-06-28">2023-06-28</time>: トークセッションの記事版の執筆を中止
- </li>
- </ol>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- 2023-03-23 から 2023-03-25 にかけて開催された、 <a href="https://phperkaigi.jp/2023/" rel="noreferrer" target="_blank">PHPerKaigi 2023</a> に参加した。今年は 2つのセッションのスピーカーとして、また、当日スタッフとして参加した。
- </p>
- <p>
- 昨年、一昨年の参加レポはこちら:
- </p>
- <ul>
- <li>
- <a href="/posts/2022-05-01/phperkaigi-2022/">PHPerKaigi 2022</a>
- </li>
- <li>
- <a href="/posts/2021-03-30/phperkaigi-2021/">PHPerKaigi 2021</a>
- </li>
- </ul>
- </section>
- <section id="section--as-speaker">
- <h2><a href="#section--as-speaker">スピーカーとして</a></h2>
- <p>
- これまでとの最大の違いとして、今回はスピーカーとして登壇した。まずはそれについて書く。2つのセッションで登壇した。
- </p>
- <ul>
- <li>
- 詳説「参照」:PHP 処理系の実装から参照を理解する
- <ul>
- <li>
- <a href="https://fortee.jp/phperkaigi-2023/proposal/95e4dd94-5fc7-40fe-9e1a-230e36404cbe" rel="noreferrer" target="_blank">プロポーザル</a>
- </li>
- <li>
- <a href="/slides/2023-03-24/phperkaigi-2023/">スライド</a>
- </li>
- <li>
- 解説記事 (執筆中) → 追記: 記事版の執筆は諦めた
- </li>
- </ul>
- </li>
- <li>
- PHPerチャレンジ解説セッション - デジタルサーカス株式会社
- <ul>
- <li>
- <a href="https://fortee.jp/phperkaigi-2023/proposal/524c9dca-1d70-4b32-a939-9c73ffe5cb48" rel="noreferrer" target="_blank">プロポーザル</a>
- </li>
- <li>
- <a href="/slides/2023-03-25/phperkaigi-2023-tokens/">スライド</a>
- </li>
- <li>
- 解説記事 (執筆中) → 追記: 記事版の執筆は諦めた
- </li>
- </ul>
- </li>
- </ul>
- <p>
- PHPer チャレンジの話については後述する。参照については、PHP を書き始めた頃からずっと疑問に思っていたので、仕組みを理解する良い機会となった。
- </p>
- </section>
- <section id="section--as-staff">
- <h2><a href="#section--as-staff">当日スタッフとして</a></h2>
- <p>
- 今回はスピーカーのみならず当日スタッフとしても参加した。カンファレンスのスタッフとしての参加は初めてだったが、初参加のスタッフでもスムーズに作業ができるような仕組みが整えられていた。
- </p>
- <p>
- PHPerKaigi は一般参加者の目線でもよくできたカンファレンスだなあという印象だったのだが、よりその思いを強くした。なんとスタッフにとってもよくできたカンファレンスなのである。
- </p>
- <p>
- 反省点は私自身の最大 HP がまったく足りていなかったことで、次の機会には最後まで動けるようにしたいところである。
- </p>
- </section>
- <section id="section--as-attendee">
- <h2><a href="#section--as-attendee">参加者として</a></h2>
- <section id="section--as-attendee--recommended-sessions">
- <h3><a href="#section--as-attendee--recommended-sessions">おすすめセッション</a></h3>
- <p>
- 5つのセッションを厳選した。
- </p>
- <p>
- <a href="https://fortee.jp/phperkaigi-2023/proposal/f7f2f18a-e6b0-47e4-ade0-e324f72428ae" rel="noreferrer" target="_blank">ブラウザの向こう側で「200 OK」を返すまでに何が起きているのか調べてみた</a>
- </p>
- <p>
- Web に関わるなら、バックエンドでもフロントエンドでも知っておいてほしい知識。タイトルを見て「こんな話だろうな」と想像がつくレベルなら見なくてもいいかも。
- </p>
- <p>
- <a href="https://fortee.jp/phperkaigi-2023/proposal/280706e0-7158-4237-8202-c9d64330b96f" rel="noreferrer" target="_blank">PHPで学ぶ “Cacheの距離” の話</a>
- </p>
- <p>
- これも上セッションと同様に、基礎を抑えられる良いセッション。
- </p>
- <p>
- <a href="https://fortee.jp/phperkaigi-2023/proposal/ad3ba31c-0214-4557-a0df-3755db8ed8cc" rel="noreferrer" target="_blank">防衛的 PHP: 多様性を生き抜くための PHP 入門</a>
- </p>
- <p>
- 静的解析ツールの話。静的解析は PHP のみならず最近の動的言語の一大潮流なので、逃れられない。
- </p>
- <p>
- <a href="https://fortee.jp/phperkaigi-2023/proposal/e00788a4-ef25-49ee-b254-9d2b53e19633" rel="noreferrer" target="_blank">PHPの最高機能、配列を捨てよう!!</a>
- </p>
- <p>
- 実はこれも上のセッションと同様の話。PHP の静的解析ツールは配列にも (無理矢理) 型が付けられるものが多いが、実行時にも検査できるという点において専用のクラスを作る方が優れている。
- </p>
- <p>
- <a href="https://fortee.jp/phperkaigi-2023/proposal/7e212cb2-be37-43e8-b6ee-5236d259fcbf" rel="noreferrer" target="_blank">時間を気にせず普通にカンニングもしつつ ISUCON12 本選問題を PHP でやってみる</a>
- </p>
- <p>
- 個人的に最も楽しみにしていたセッションであり、今回のモリアガリトーク賞 (盛り上がったセッションに運営側から贈られる賞) でもある。ネタバレになるが、最終的に (Go で実装された) 本戦優勝スコアを超えている。
- </p>
- </section>
- <section id="section--as-attendee--phper-challenge">
- <h3><a href="#section--as-attendee--phper-challenge">PHPer チャレンジ</a></h3>
- <p>
- 昨年に引き続き、弊社デジタルサーカス株式会社からのトークン問題の作題を担当した。また、今年はさらに作成した問題を解説するセッションにも登壇した。今年のトークンは、昨年の PHPerKaigi 2022 が終わった段階から作り始め、約半年かけて制作した。
- </p>
- <p>
- 問題の制作中は大変楽しかったが、まあやりすぎた。いかに超絶技巧を凝らすかに注力してしまい、解く楽しさという観点を失ってしまったきらいがある。
- </p>
- <p>
- (WIP: 解説ブログ記事執筆中。終わったらここにリンク)
- </p>
- </section>
- <section id="section--as-attendee--random-thoughts">
- <h3><a href="#section--as-attendee--random-thoughts">雑多な感想</a></h3>
- <p>
- なんかいろいろ。
- </p>
- <ul>
- <li>
- マカロンおいしかった
- </li>
- <li>
- \ペチパー/
- </li>
- <li>
- 名札便利
- </li>
- <li>
- \ペチパー/
- </li>
- <li>
- 傘袋便利
- </li>
- <li>
- \ペチパー/
- </li>
- <li>
- パーカーのデザイン良き
- </li>
- </ul>
- <p>
- (あとから見返して自分でもわけがわからなくなりそうなので書いておくと、会場に入場する際に名札をタッチすると小桜エツコさんの声で「ペチパー」という音声が流れるギミックがあった)
- </p>
- </section>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">おわりに</a></h2>
- <p>
- <a href="/posts/2022-05-01/phperkaigi-2022/#section--next-year">去年の参加レポ</a> では、来年の目標として次を挙げた。
- </p>
- <blockquote>
- <ul>
- <li>
- プロポーザルを出す
- </li>
- <li>
- PHPer チャレンジのトークン問題を 5題作成する
- </li>
- <li>
- 現地に行く
- </li>
- <li>
- PHPer チャレンジで圧勝する
- </li>
- </ul>
- </blockquote>
- <p>
- プロポーザルに関しては採択されて登壇できたし、PHPer チャレンジは解説もおこなった。また、現地に行くだけでなく、当日スタッフとして参加した。4つ目の PHPer チャレンジに関しては、今年は参加していない。スタッフをやりながらだと入力する時間も探す時間も取れそうになかったのと、スタッフをやっている関係で少しだけ早く入手してしまうトークンがいくつか存在していたため。
- </p>
- <p>
- カンファレンス全体の感想についてだが、大規模なカンファレンスにオフラインで参加するのは今回が初めてだったので、その話をしたい。
- </p>
- <p>
- オンラインとオフラインだと体験が別物になる。そもそもが似て非なるものなのだ。向き不向きはあるだろうが、オンラインしか参加したことのないという方は、一度現地参加してみてはいかがだろうか。
- </p>
- <p>
- さて、参加レポは去年も一昨年もこの言葉で締め括っているので、今年もそれで終わろうと思う。
- </p>
- <p>
- ではまた来年。
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2023-06-25/phpconfuk-2023-report/index.html b/vhosts/blog/public/posts/2023-06-25/phpconfuk-2023-report/index.html
deleted file mode 100644
index 0ee28741..00000000
--- a/vhosts/blog/public/posts/2023-06-25/phpconfuk-2023-report/index.html
+++ /dev/null
@@ -1,155 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2023 nsfisis">
- <meta name="description" content="2023-06-24 に開催された、PHP カンファレンス福岡に参加した。">
- <meta name="keywords" content="カンファレンス,PHP,PHP カンファレンス福岡">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHP カンファレンス福岡 2023 参加レポ|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="2023-06-24 に開催された、PHP カンファレンス福岡に参加した。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHP カンファレンス福岡 2023 参加レポ|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">PHP カンファレンス福岡 2023 参加レポ</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/conference/">カンファレンス</a>
- </li>
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phpconfuk/">PHP カンファレンス福岡</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2023-06-25">2023-06-25</time>: 公開
- </li>
- </ol>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- 2023-06-24 に開催された、 <a href="https://phpcon.fukuoka.jp/2023/" rel="noreferrer" target="_blank">PHP カンファレンス福岡 2023</a> に参加した。また、その前日に催された、 <a href="https://connpass.com/event/282285/" rel="noreferrer" target="_blank">非公式の前夜祭</a> にも参加した。前夜祭では、15分の登壇もおこなった。 <a href="/slides/2023-06-23/phpconfuk-2023-eve/">登壇の方の資料はこちら。</a>
- </p>
- </section>
- <section id="section--sessions-thoughts">
- <h2><a href="#section--sessions-thoughts">セッションの感想</a></h2>
- <section id="section--sessions-thoughts--eve">
- <h3><a href="#section--sessions-thoughts--eve">前夜祭</a></h3>
- <p>
- ※セッションの題名と発表者名は、 <a href="https://connpass.com/event/282285/" rel="noreferrer" target="_blank">前夜祭イベントの connpass ページ</a> から引用。
- </p>
- <ul>
- <li>
- スクラム(の一部)を導入してよくなったこと (asumikam さん)
- <ul>
- <li>
- スクラムの「一部」を導入されたということでしたが、理想的な形で改善が進んでいるように見受けられました。特に、ブランチ運用やデプロイ頻度、フィードバックサイクルに大きく変化が起きているのは驚くべき成果だと感じました。
- </li>
- </ul>
- </li>
- <li>
- 地方の小さな勉強会を一番の活動舞台にする (tomio さん)
- <ul>
- <li>
- すさまじいほどの「熱」を感じました。私自身、最近になってカンファレンスや勉強会への参加・登壇を活発におこなうようになったことで、頷く点が多かったです。
- </li>
- </ul>
- </li>
- </ul>
- </section>
- <section id="section--sessions-thoughts--conference">
- <h3><a href="#section--sessions-thoughts--conference">カンファレンス</a></h3>
- <p>
- ※セッションの題名と発表者名は、 <a href="https://fortee.jp/phpconfukuoka-2023/proposal/accepted" rel="noreferrer" target="_blank">カンファレンスの fortee ページ</a> から引用。
- </p>
- <ul>
- <li>
- <a href="https://fortee.jp/phpconfukuoka-2023/proposal/df5f06e8-900e-4e71-94d7-d0c3cc57a0ac" rel="noreferrer" target="_blank">育成力 - エンジニアの才能を引き出す環境とチューターの立ち回り - (岡嵜 雄平 さん)</a>
- <ul>
- <li>
- ちょうど弊チームに新規メンバがジョインしたばかりで、オンボーディングプロセスについて考えていたところの発表でした。すぐにすべてを取り入れるというわけにはいきませんが、弊社での新人育成プロセスの改善につながるヒントをいくつか得られたと思います。
- </li>
- </ul>
- </li>
- <li>
- オブジェクト指向は本当に必要か? (たなかひさてる さん、こいほげ さん)
- <ul>
- <li>
- ※当日 D ホールでおこなわれたアンカンファレンスセッションのため、正式タイトル・リンクなし
- </li>
- <li>
- 私自身、「オブジェクト指向」については色々と言いたいことがあるのですが、だいたいツイートしたこれとこれです。
- <ul>
- <li>
- 「オブジェクト指向の話は、パラダイムの異なる複数の言語に触れているかどうかで見え方がまったく異なる印象がある。OOPはどうでもいいです (※個人の感想です)」 ( <a href="https://twitter.com/nsfisis/status/1672502935983656960" rel="noreferrer" target="_blank">Twitter のツイートへのリンク</a> )
- </li>
- <li>
- 「OOPは現代の言語で考える意味はほぼない古いパラダイムだよという立場ですが、OOPについてあまり大っぴらに話してると色んなところから刺されそうなんですよね (Twitterは大っぴらじゃないんですか?)」 ( <a href="https://twitter.com/nsfisis/status/1672504892244787201" rel="noreferrer" target="_blank">Twitter のツイートへのリンク</a> )
- </li>
- </ul>
- </li>
- </ul>
- </li>
- <li>
- <a href="https://fortee.jp/phpconfukuoka-2023/proposal/ae71f3a7-4c3c-4c87-8816-8426bcc8d325" rel="noreferrer" target="_blank">その説明、コードコメントに書く?コミットメッセージに書く?プルリクエストに書く? (おかしょい/岡田正平 さん)</a>
- <ul>
- <li>
- Twitter にもツイートしましたが、完全に自分の意見と一致していたので、とても共感できました。今後は社内のコードレビュー時に、こちらの資料を貼りつけることにします。
- </li>
- </ul>
- </li>
- </ul>
- </section>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">おわりに</a></h2>
- <p>
- 居住地域から離れた場所への遠征参加は初めてだったが、大変楽しい (しかも勉強にもなる!) 体験だった。受け取った「熱」が冷める前に、自らの手を動かしていきたい。
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2023-10-02/compile-php-runtime-to-wasm/index.html b/vhosts/blog/public/posts/2023-10-02/compile-php-runtime-to-wasm/index.html
deleted file mode 100644
index 34070bf9..00000000
--- a/vhosts/blog/public/posts/2023-10-02/compile-php-runtime-to-wasm/index.html
+++ /dev/null
@@ -1,401 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2023 nsfisis">
- <meta name="description" content="PHP の処理系 (php/php-src) を Emscripten で WebAssembly にコンパイルし、任意のコードを隔離された環境で評価できるようにした。">
- <meta name="keywords" content="PHP,WebAssembly">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHP の処理系を Emscripten で WebAssembly にコンパイルする|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="PHP の処理系 (php/php-src) を Emscripten で WebAssembly にコンパイルし、任意のコードを隔離された環境で評価できるようにした。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHP の処理系を Emscripten で WebAssembly にコンパイルする|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">PHP の処理系を Emscripten で WebAssembly にコンパイルする</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/wasm/">WebAssembly</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2023-10-02">2023-10-02</time>: 公開
- </li>
- <li class="revision">
- <time datetime="2025-04-23">2025-04-23</time>: fflush() の前に改行の出力が必要だった理由と正しい実装について追記
- </li>
- </ol>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- <a href="https://emscripten.org/" rel="noreferrer" target="_blank">Emscripten</a> を用いて <a href="https://github.com/php/php-src" rel="noreferrer" target="_blank">PHP の処理系</a> を <a href="https://developer.mozilla.org/docs/WebAssembly" rel="noreferrer" target="_blank">WebAssembly</a> にコンパイルした。機能をある程度絞ることで、思ったよりも簡単に実現できたので、備忘録として記しておく。
- </p>
- <p>
- なお、この記事では Emscripten や WebAssembly とは何か知っていることを前提とする。
- </p>
- </section>
- <section id="section--version">
- <h2><a href="#section--version">バージョン情報</a></h2>
- <p>
- この記事中で使用するソフトウェア等のバージョンを記載する。
- </p>
- <ul>
- <li>
- Ubuntu 22.04 on WSL2
- </li>
- <li>
- Docker version 24.0.6
- </li>
- <li>
- Emscripten 3.1.46
- </li>
- <li>
- Node.js 20.7.0
- </li>
- <li>
- PHP 8.2.10
- </li>
- </ul>
- <p>
- なお、Docker から下は Docker 上で導入するので、ホストマシンにはインストールしなくてよい。
- </p>
- </section>
- <section id="section--goal">
- <h2><a href="#section--goal">本記事のゴール</a></h2>
- <p>
- 先にこの記事のゴールを示しておく。これから示す手順のとおりに進めると、次のようなコードが動くようになる。このコードはこのあと使うので、<code>index.mjs</code> の名前で保存しておくこと。
- </p>
- <div class="codeblock">
- <div class="filename">
- index.mjs
- </div>
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">import</span><span style="color:#24292E"> { readFile } </span><span style="color:#D73A49">from</span><span style="color:#032F62"> 'node:fs/promises'</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#D73A49">import</span><span style="color:#24292E"> PHPWasm </span><span style="color:#D73A49">from</span><span style="color:#032F62"> './php-wasm.mjs'</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">const</span><span style="color:#005CC5"> code</span><span style="color:#D73A49"> =</span><span style="color:#D73A49"> await</span><span style="color:#6F42C1"> readFile</span><span style="color:#24292E">(</span><span style="color:#032F62">'/dev/stdin'</span><span style="color:#24292E">, { encoding: </span><span style="color:#032F62">'utf-8'</span><span style="color:#24292E"> });</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">const</span><span style="color:#24292E"> { </span><span style="color:#005CC5">ccall</span><span style="color:#24292E"> } </span><span style="color:#D73A49">=</span><span style="color:#D73A49"> await</span><span style="color:#6F42C1"> PHPWasm</span><span style="color:#24292E">();</span></span>
-<span class="line"><span style="color:#D73A49">const</span><span style="color:#005CC5"> result</span><span style="color:#D73A49"> =</span><span style="color:#6F42C1"> ccall</span><span style="color:#24292E">(</span></span>
-<span class="line"><span style="color:#032F62"> 'php_wasm_run'</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#032F62"> 'number'</span><span style="color:#24292E">, [</span><span style="color:#032F62">'string'</span><span style="color:#24292E">],</span></span>
-<span class="line"><span style="color:#24292E"> [code],</span></span>
-<span class="line"><span style="color:#24292E">);</span></span>
-<span class="line"><span style="color:#24292E">console.</span><span style="color:#6F42C1">log</span><span style="color:#24292E">(</span><span style="color:#032F62">`exit code: ${</span><span style="color:#24292E">result</span><span style="color:#032F62">}`</span><span style="color:#24292E">);</span></span></code></pre>
- </div>
- <p>
- 標準入力から与えたコードを WebAssembly にコンパイルされた PHP 処理系の上で実行している。このような <code>php-wasm.mjs</code> (とそこから呼び出される <code>php-wasm.wasm</code>) を作成する。
- </p>
- </section>
- <section id="section--build">
- <h2><a href="#section--build">ビルド</a></h2>
- <section id="section--build--write-c-entrypoint">
- <h3><a href="#section--build--write-c-entrypoint">C のエントリポイントを書く</a></h3>
- <p>
- 先ほどのコードでも使っていたエントリポイントである <code>php_wasm_run</code> を用意する。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">#include</span><span style="color:#032F62"> &#x3C;stdio.h></span></span>
-<span class="line"><span style="color:#D73A49">#include</span><span style="color:#032F62"> &#x3C;emscripten.h></span></span>
-<span class="line"><span style="color:#D73A49">#include</span><span style="color:#032F62"> &#x3C;Zend/zend_execute.h></span></span>
-<span class="line"><span style="color:#D73A49">#include</span><span style="color:#032F62"> &#x3C;sapi/embed/php_embed.h></span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">int</span><span style="color:#24292E"> EMSCRIPTEN_KEEPALIVE </span><span style="color:#6F42C1">php_wasm_run</span><span style="color:#24292E">(</span><span style="color:#D73A49">const</span><span style="color:#D73A49"> char*</span><span style="color:#E36209"> code</span><span style="color:#24292E">) {</span></span>
-<span class="line"><span style="color:#24292E"> zend_result result;</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49"> int</span><span style="color:#24292E"> argc </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> 1</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#D73A49"> char*</span><span style="color:#24292E"> argv</span><span style="color:#D73A49">[]</span><span style="color:#D73A49"> =</span><span style="color:#24292E"> { </span><span style="color:#032F62">"php.wasm"</span><span style="color:#24292E">, </span><span style="color:#005CC5">NULL</span><span style="color:#24292E"> };</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#6F42C1"> PHP_EMBED_START_BLOCK</span><span style="color:#24292E">(argc, argv);</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E"> result </span><span style="color:#D73A49">=</span><span style="color:#6F42C1"> zend_eval_string_ex</span><span style="color:#24292E">(code, </span><span style="color:#005CC5">NULL</span><span style="color:#24292E">, </span><span style="color:#032F62">"php.wasm code"</span><span style="color:#24292E">, </span><span style="color:#005CC5">1</span><span style="color:#24292E">);</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#6F42C1"> PHP_EMBED_END_BLOCK</span><span style="color:#24292E">();</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#6F42C1"> fprintf</span><span style="color:#24292E">(stdout, </span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span></span>
-<span class="line"><span style="color:#6F42C1"> fflush</span><span style="color:#24292E">(stdout);</span></span>
-<span class="line"><span style="color:#6F42C1"> fprintf</span><span style="color:#24292E">(stderr, </span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span></span>
-<span class="line"><span style="color:#6F42C1"> fflush</span><span style="color:#24292E">(stderr);</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49"> return</span><span style="color:#24292E"> result </span><span style="color:#D73A49">==</span><span style="color:#24292E"> SUCCESS </span><span style="color:#D73A49">?</span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> :</span><span style="color:#005CC5"> 1</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">}</span></span></code></pre>
- </div>
- <p>
- ほとんどはただの PHP の公開 API を使ったコードだが、Emscripten 向けの注意点が 2点ある。
- </p>
- <p>
- まずは <code>EMSCRIPTEN_KEEPALIVE</code> について。これは Emscripten が用意している特殊なマクロである。このマクロが付与されている関数は、どこからも使用されていなくともコンパイル後の WebAssembly バイナリから削除されない。もしこれを付け忘れると、未使用の関数とみなされ削除される。
- </p>
- <p>
- 次に、コードを評価したあとに呼んでいる標準出力と標準エラー出力に対する改行の出力について。出力バッファから出力させるためだけなら改行を出力させなくとも <code>fflush()</code> だけで事足りると考えたのだが、ないと動かなかったので追加した。これにより、PHP コードの出力の後ろに余分な改行が追加されてしまう。改行を出力せずともバッファを消費させる手段をご存知のかたはご教示願いたい。
- </p>
- <div class="admonition" editat="2025-04-23" operation="追記">
- <div class="admonition-label">
- 2025-04-23 追記
- </div>
- <div class="admonition-content">
- <p>
- <code>fflush()</code> の前に改行の出力が必要だった理由が判明したので追記する。これは、<code>index.mjs</code> で標準出力・標準エラー出力へ出力する方法を指定せず、デフォルトの実装に任せているため。Emscripten のデフォルト実装では、改行コードを出力するまで出力内容がバッファリングされ、<code>fflush()</code> が機能しない。
- </p>
- <p>
- デフォルトの出力方法は <code>index.mjs</code> の中で <code>PHPWasm()</code> を呼ぶとき、<code>stdout</code>・<code>stderr</code> というオプションを渡せば変更できる。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">const</span><span style="color:#24292E"> { </span><span style="color:#005CC5">ccall</span><span style="color:#24292E"> } </span><span style="color:#D73A49">=</span><span style="color:#D73A49"> await</span><span style="color:#6F42C1"> PHPWasm</span><span style="color:#24292E">({</span></span>
-<span class="line"><span style="color:#6F42C1"> stdout</span><span style="color:#24292E">: (</span><span style="color:#E36209">c</span><span style="color:#24292E">) </span><span style="color:#D73A49">=></span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> (c </span><span style="color:#D73A49">===</span><span style="color:#005CC5"> null</span><span style="color:#24292E">) {</span></span>
-<span class="line"><span style="color:#6A737D"> // flush the standard output.</span></span>
-<span class="line"><span style="color:#24292E"> } </span><span style="color:#D73A49">else</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#6A737D"> // output c to the standard output.</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#24292E"> },</span></span>
-<span class="line"><span style="color:#24292E">});</span></span></code></pre>
- </div>
- <p>
- <code>c</code> は <code>null</code> か 1バイト符号つき整数を取り、<code>null</code> が flush 要求を意味する。
- </p>
- <p>
- 記事末尾のリポジトリはすでにこの変更を適用済み。<code>stdout</code> や <code>stderr</code> の完全なサンプルはそちらを参照のこと。
- </p>
- </div>
- </div>
- </section>
- <section id="section--build--compile-to-wasm">
- <h3><a href="#section--build--compile-to-wasm">WebAssembly にコンパイルする</a></h3>
- <p>
- それでは WebAssembly にコンパイルしていこう。ここからは <code>Dockerfile</code> 上のコマンドとして操作を示す。
- </p>
- <p>
- まずは <a href="https://hub.docker.com/r/emscripten/emsdk" rel="noreferrer" target="_blank">Emscripten 公式が提供している Docker イメージ</a> を使って、PHP 処理系と先ほど示した C 言語のソースコードを WebAssembly にコンパイルする。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">FROM</span><span style="color:#24292E"> emscripten/emsdk:3.1.46 </span><span style="color:#D73A49">AS</span><span style="color:#24292E"> wasm-builder</span></span></code></pre>
- </div>
- <p>
- 次に、 <a href="https://github.com/php/php-src" rel="noreferrer" target="_blank">php/php-src</a> から PHP 処理系のソースコードを取得し、ビルドに必要な apt パッケージを取ってくる。有効にする拡張を増やしたいなら、ここでインストールするパッケージも増やすことになるだろう。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">RUN</span><span style="color:#24292E"> git clone --depth=1 --branch=php-8.2.10 https://github.com/php/php-src</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">RUN</span><span style="color:#24292E"> apt-get update &#x26;&#x26; \</span></span>
-<span class="line"><span style="color:#24292E"> apt-get install -y --no-install-recommends \</span></span>
-<span class="line"><span style="color:#24292E"> autoconf \</span></span>
-<span class="line"><span style="color:#24292E"> bison \</span></span>
-<span class="line"><span style="color:#24292E"> pkg-config \</span></span>
-<span class="line"><span style="color:#24292E"> re2c \</span></span>
-<span class="line"><span style="color:#24292E"> &#x26;&#x26; \</span></span>
-<span class="line"><span style="color:#24292E"> :</span></span></code></pre>
- </div>
- <p>
- 続けて、Emscripten のツールチェインを用いて PHP 処理系をビルドする。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">RUN</span><span style="color:#24292E"> cd php-src &#x26;&#x26; \</span></span>
-<span class="line"><span style="color:#24292E"> ./buildconf --force &#x26;&#x26; \</span></span>
-<span class="line"><span style="color:#24292E"> emconfigure ./configure \</span></span>
-<span class="line"><span style="color:#24292E"> --disable-all \</span></span>
-<span class="line"><span style="color:#24292E"> --disable-mbregex \</span></span>
-<span class="line"><span style="color:#24292E"> --disable-fiber-asm \</span></span>
-<span class="line"><span style="color:#24292E"> --disable-cli \</span></span>
-<span class="line"><span style="color:#24292E"> --disable-cgi \</span></span>
-<span class="line"><span style="color:#24292E"> --disable-phpdbg \</span></span>
-<span class="line"><span style="color:#24292E"> --enable-embed=static \</span></span>
-<span class="line"><span style="color:#24292E"> --enable-mbstring \</span></span>
-<span class="line"><span style="color:#24292E"> --without-iconv \</span></span>
-<span class="line"><span style="color:#24292E"> --without-libxml \</span></span>
-<span class="line"><span style="color:#24292E"> --without-pcre-jit \</span></span>
-<span class="line"><span style="color:#24292E"> --without-pdo-sqlite \</span></span>
-<span class="line"><span style="color:#24292E"> --without-sqlite3 \</span></span>
-<span class="line"><span style="color:#24292E"> &#x26;&#x26; \</span></span>
-<span class="line"><span style="color:#24292E"> EMCC_CFLAGS=</span><span style="color:#032F62">'-s ERROR_ON_UNDEFINED_SYMBOLS=0'</span><span style="color:#24292E"> emmake make -j$(nproc) &#x26;&#x26; \</span></span>
-<span class="line"><span style="color:#24292E"> mv libs/libphp.a .. &#x26;&#x26; \</span></span>
-<span class="line"><span style="color:#24292E"> make clean &#x26;&#x26; \</span></span>
-<span class="line"><span style="color:#24292E"> git clean -fd &#x26;&#x26; \</span></span>
-<span class="line"><span style="color:#24292E"> :</span></span></code></pre>
- </div>
- <p>
- ここまでと比べると少し複雑なので、それぞれ詳しく見ていこう。
- </p>
- <p>
- まず、<code>buildconf</code> は PHP 処理系をビルドするときに (Emscripten とは関係なく) 使うツールである。このツールの最も重要な仕事は、<code>configure</code> の生成である。
- </p>
- <p>
- 次に <code>configure</code> するわけだが、ここで <code>emconfigure</code> を使う。これを使うことで、Emscripten が上手く諸々のツールチェインを WebAssembly のビルド向けに調整しながら <code>configure</code> してくれる。
- </p>
- <p>
- <code>configure</code> の後ろに指定してあるフラグは、通常の PHP 処理系のビルドで使う <code>configure</code> と同じなので、詳しくはそちらの <code>cofigure --help</code> を参照していただきたい。ほとんどは、機能の無効化のために指定している (依存するライブラリを減らし、ビルドをより簡単にするため)。
- </p>
- <p>
- 通常の C のビルドなら、<code>configure</code> の次は <code>make</code> するところだが、ここでも <code>emmake</code> を使う。役割はほとんど <code>emconfigure</code> と同様である。指定してある <code>EMCC_CFLAGS</code> という環境変数は、Emscripten の C コンパイラへのフラグで、ここでは <code>ERROR_ON_UNDEFINED_SYMBOLS</code> を無効化している。これにより、コンパイル中に出現した解決できなかったシンボルを無視するようになる (代わりに、そのシンボルを呼ぼうとしたタイミングで実行時エラーになる)。すべての依存を完全に解決するのは面倒なので、あまり使わない機能については無視してもよいだろう。
- </p>
- <p>
- ここまでを実行すると <code>libs/libphp.a</code> が生成される。これは後で使うので移動させている。
- </p>
- <p>
- さて、PHP 処理系をライブラリ化できたので、次に先ほど載せた C のソースコードをビルドしていこう。<code>Dockerfile</code> と同じ場所に <code>php-wasm.c</code> という名前で保存し、次のようにする。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">COPY</span><span style="color:#24292E"> php-wasm.c /src/</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">RUN</span><span style="color:#24292E"> cd php-src &#x26;&#x26; \</span></span>
-<span class="line"><span style="color:#24292E"> emcc \</span></span>
-<span class="line"><span style="color:#24292E"> -c \</span></span>
-<span class="line"><span style="color:#24292E"> -o php-wasm.o \</span></span>
-<span class="line"><span style="color:#24292E"> -I . \</span></span>
-<span class="line"><span style="color:#24292E"> -I TSRM \</span></span>
-<span class="line"><span style="color:#24292E"> -I Zend \</span></span>
-<span class="line"><span style="color:#24292E"> -I main \</span></span>
-<span class="line"><span style="color:#24292E"> ../php-wasm.c \</span></span>
-<span class="line"><span style="color:#24292E"> &#x26;&#x26; \</span></span>
-<span class="line"><span style="color:#24292E"> mv php-wasm.o .. &#x26;&#x26; \</span></span>
-<span class="line"><span style="color:#24292E"> make clean &#x26;&#x26; \</span></span>
-<span class="line"><span style="color:#24292E"> git clean -fd &#x26;&#x26; \</span></span>
-<span class="line"><span style="color:#24292E"> :</span></span></code></pre>
- </div>
- <p>
- <code>emcc</code> は <code>cc</code> (C コンパイラ/リンカ) の Emscripten 版で、<code>-c</code> は「コンパイル」の意。<code>-o</code> や <code>-I</code> は普通の C コンパイラと同様、出力ファイルの指定とインクルードパスの指定である。
- </p>
- <p>
- <code>libphp.a</code> と <code>php-wasm.o</code> が手に入ったので、これらをリンクして WebAssembly のバイナリとそのラッパである JavaScript ファイルを生成する。これにも <code>emcc</code> コマンドを使う。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">RUN</span><span style="color:#24292E"> emcc \</span></span>
-<span class="line"><span style="color:#24292E"> -s ENVIRONMENT=node \</span></span>
-<span class="line"><span style="color:#24292E"> -s ERROR_ON_UNDEFINED_SYMBOLS=0 \</span></span>
-<span class="line"><span style="color:#24292E"> -s EXPORTED_RUNTIME_METHODS=</span><span style="color:#032F62">'["ccall"]'</span><span style="color:#24292E"> \</span></span>
-<span class="line"><span style="color:#24292E"> -s EXPORT_ES6=1 \</span></span>
-<span class="line"><span style="color:#24292E"> -s INITIAL_MEMORY=16777216 \</span></span>
-<span class="line"><span style="color:#24292E"> -s INVOKE_RUN=0 \</span></span>
-<span class="line"><span style="color:#24292E"> -s MODULARIZE=1 \</span></span>
-<span class="line"><span style="color:#24292E"> -o php-wasm.js \</span></span>
-<span class="line"><span style="color:#24292E"> php-wasm.o \</span></span>
-<span class="line"><span style="color:#24292E"> libphp.a \</span></span>
-<span class="line"><span style="color:#24292E"> ;</span></span></code></pre>
- </div>
- <p>
- それぞれのフラグについて解説する。
- </p>
- <p>
- <code>-s ENVIRONMENT=node</code> は、生成する WebAssembly/JavaScript の実行環境を指定する。今回は <code>node</code> を指定しているので、Node.js 向けのファイルが生成される。
- </p>
- <p>
- <code>-s ERROR_ON_UNDEFINED_SYMBOLS=0</code> についてはすでに述べたので省略する。
- </p>
- <p>
- <code>-s EXPORTED_RUNTIME_METHODS=&apos;[&quot;ccall&quot;]&apos;</code> は、生成される JavaScript から公開される API である。すでに <code>index.mjs</code> で使用しているが、<code>ccall(&apos;関数名&apos;, &apos;返り値の型&apos;, [&apos;仮引数の型&apos;, ...], [&apos;実引数&apos;, ...])</code> のように使う。
- </p>
- <p>
- <code>-s EXPORT_ES6=1</code> は、JavaScript コードを ECMAScript 6 に準拠した module として生成する。これを指定することで、<code>require()</code> ではなく <code>import</code> できる JavaScript を生成させられる。
- </p>
- <p>
- <code>-s INITIAL_MEMORY=16777216</code> は呼んで字のごとく。用途に合わせて適当に決めてほしい。
- </p>
- <p>
- <code>-s INVOKE_RUN=0</code> は、module をロードしたときに勝手に <code>main()</code> を呼ぶかどうか (だと思う)。今回は <code>php_wasm_run()</code> しか使うつもりがないので切っている。
- </p>
- <p>
- <code>-s MODULARIZE=1</code> は、実質的にほぼ必須のオプションであり、1 を指定することで「WebAssembly module をインスタンス化する関数」をエクスポートするような JavaScript ファイルを生成するようになる。これを指定しないと、生成物の JavaScript ファイルを読み込むと WebAssembly module が即座にインスタンス化されてしまい、起動のタイミングを制御できない。
- </p>
- <p>
- ここまで実行すると、<code>php-wasm.js</code> と <code>php-wasm.wasm</code> が作られる。では、ここからはこれらの実行環境を作っていこう。
- </p>
- <p>
- といっても、Node.js はビルトインで WebAssembly をサポートしているので、ほとんどやることはない。先ほど掲載した JavaScript のコードは、<code>Dockerfile</code> と同じディレクトリに <code>index.mjs</code> で配置すること。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">FROM</span><span style="color:#24292E"> node:20.7</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">WORKDIR</span><span style="color:#24292E"> /app</span></span>
-<span class="line"><span style="color:#D73A49">COPY</span><span style="color:#24292E"> --from=wasm-builder /src/php-wasm.js /app/php-wasm.mjs</span></span>
-<span class="line"><span style="color:#D73A49">COPY</span><span style="color:#24292E"> --from=wasm-builder /src/php-wasm.wasm /app/php-wasm.wasm</span></span>
-<span class="line"><span style="color:#D73A49">COPY</span><span style="color:#24292E"> index.mjs /app/</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">ENTRYPOINT</span><span style="color:#24292E"> [</span><span style="color:#032F62">"node"</span><span style="color:#24292E">, </span><span style="color:#032F62">"index.mjs"</span><span style="color:#24292E">]</span></span></code></pre>
- </div>
- </section>
- </section>
- <section id="section--run">
- <h2><a href="#section--run">実行</a></h2>
- <p>
- <code>Dockerfile</code>、<code>php-wasm.c</code>、<code>index.mjs</code> を用意したら、Docker コンテナをビルドして実行する。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ docker build -t php-wasm .</span></span>
-<span class="line"><span>$ echo 'echo "Hello, World!", PHP_EOL;' | docker run --rm -i php-wasm</span></span>
-<span class="line"><span>Hello, World!</span></span>
-<span class="line"><span></span></span>
-<span class="line"><span></span></span>
-<span class="line"><span>exit code: 0</span></span></code></pre>
- </div>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">まとめ</a></h2>
- <p>
- <a href="https://github.com/nsfisis/tiny-php.wasm" rel="noreferrer" target="_blank">ここまでをまとめた Git リポジトリ</a> を用意した。簡単にコンパイルできるので、興味があれば試してみてほしい。
- </p>
- </section>
- <section id="section--references">
- <h2><a href="#section--references">参考リンク</a></h2>
- <ul>
- <li>
- <a href="https://github.com/php/php-src" rel="noreferrer" target="_blank">php/php-src: ビルドの方法について</a>
- </li>
- <li>
- <a href="https://emscripten.org/docs/getting_started/Tutorial.html" rel="noreferrer" target="_blank">Emscripten: チュートリアル</a>
- </li>
- <li>
- <a href="https://emscripten.org/docs/compiling/Building-Projects.html#building-projects" rel="noreferrer" target="_blank">Emscripten: ビルドの基本</a>
- </li>
- <li>
- <a href="https://emscripten.org/docs/tools_reference/emcc.html#emccdoc" rel="noreferrer" target="_blank">Emscripten: <code>emcc</code> などのリファレンス</a>
- </li>
- <li>
- <a href="https://emscripten.org/docs/api_reference/module.html#module" rel="noreferrer" target="_blank">Emscripten: 生成される JavaScript の API</a>
- </li>
- </ul>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2023-10-13/i-entered-the-open-university-of-japan/index.html b/vhosts/blog/public/posts/2023-10-13/i-entered-the-open-university-of-japan/index.html
deleted file mode 100644
index b7454af0..00000000
--- a/vhosts/blog/public/posts/2023-10-13/i-entered-the-open-university-of-japan/index.html
+++ /dev/null
@@ -1,79 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2023 nsfisis">
- <meta name="description" content="放送大学に入学しました。頑張ります。">
- <meta name="keywords" content="放送大学">
- <meta property="og:type" content="article">
- <meta property="og:title" content="放送大学に入学しました|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="放送大学に入学しました。頑張ります。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>放送大学に入学しました|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">放送大学に入学しました</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/ouj/">放送大学</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2023-10-13">2023-10-13</time>: 公開
- </li>
- </ol>
- </section>
- <section id="section--i-entered-ouj">
- <h2><a href="#section--i-entered-ouj">放送大学に入学しました</a></h2>
- <p>
- とあるきっかけがあり、もう一度大学生をすることにしました。仕事のほうも、これまでどおりフルタイムで続けていきます。
- </p>
- <p>
- 黙っているよりも公表したほうがモチベーションの向上に繋がるだろうと思い、このブログに記事として載せました。
- </p>
- <p>
- 以上、短いですが報告でした。
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2023-12-03/isucon-13/index.html b/vhosts/blog/public/posts/2023-12-03/isucon-13/index.html
deleted file mode 100644
index 0a476a84..00000000
--- a/vhosts/blog/public/posts/2023-12-03/isucon-13/index.html
+++ /dev/null
@@ -1,149 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2023 nsfisis">
- <meta name="description" content="ISUCON 13 に参加した。チーム名「うつしもゆ」、最終スコア 13,580 点">
- <meta name="keywords" content="ISUCON">
- <meta property="og:type" content="article">
- <meta property="og:title" content="ISUCON 13 に参加した|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="ISUCON 13 に参加した。チーム名「うつしもゆ」、最終スコア 13,580 点">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>ISUCON 13 に参加した|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">ISUCON 13 に参加した</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/isucon/">ISUCON</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2023-12-03">2023-12-03</time>: 公開
- </li>
- </ol>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- 先日 11月25日、 <a href="https://isucon.net/archives/57801192.html" rel="noreferrer" target="_blank">ISUCON 13</a> に参加した。ISUCON への参加は今回が初めてとなる。私 nsfisis の1人チーム「うつしもゆ」として参加し、最終スコアは 13,580 点だった。使用言語は Go。
- </p>
- <div class="admonition">
- <div class="admonition-label">
- NOTE
- </div>
- <div class="admonition-content">
- <p>
- 「ISUCON」は、LINEヤフー株式会社の商標または登録商標です。 <a href="https://isucon.net/" rel="noreferrer" target="_blank">ISUCON 公式サイトはこちら。</a>
- </p>
- </div>
- </div>
- </section>
- <section id="section--goals">
- <h2><a href="#section--goals">目標</a></h2>
- <p>
- 今回は初参加ということもあり、目標を以下のように定めた。
- </p>
- <ul>
- <li>
- 正のスコアを取る
- <ul>
- <li>
- ISUCON ではサーバ動作の整合性がチェックされ、失敗するとスコア 0 となる
- </li>
- </ul>
- </li>
- <li>
- 速度改善以外に時間を浪費しない (= ハマらない)
- <ul>
- <li>
- プロビジョニング、デバッグ、ミドルウェアの設定方法の調査など、性能改善に寄与しない時間を最小限にする
- </li>
- </ul>
- </li>
- </ul>
- </section>
- <section id="section--strategy">
- <h2><a href="#section--strategy">戦略</a></h2>
- <p>
- ISUCON で高スコアを出す戦略については、戦闘力の高い方々が良質な記事を書いてくださっている。ここでは、上述したような低い目標を達成するための戦略について書こうと思う。
- </p>
- <section id="section--strategy--do-not-destroy-environment">
- <h3><a href="#section--strategy--do-not-destroy-environment">環境を破壊しない</a></h3>
- <p>
- ミドルウェアの設定やアプリケーションコードなど、変更を加えるあらゆるものは、必ずバックアップを取るか Git で管理する。復旧不能になって環境ごと作り直すことだけは必ず避ける。
- </p>
- </section>
- <section id="section--strategy--revert-changes-immediately">
- <h3><a href="#section--strategy--revert-changes-immediately">すぐに変更を取り消す</a></h3>
- <p>
- それでも壊してしまったときは、即座に変更を取り消す。壊れた理由を調べることに固執しない。
- </p>
- </section>
- <section id="section--strategy--do-small-deployment">
- <h3><a href="#section--strategy--do-small-deployment">小さくデプロイする</a></h3>
- <p>
- 一度に複数の変更を加えず、可能な限り小さな単位でデプロイする。そしてその都度ベンチマークを走らせ、整合性チェックが通るかどうかを (当然速くなっているかどうかも) 確かめる。
- </p>
- </section>
- <section id="section--strategy--use-familiar-tools">
- <h3><a href="#section--strategy--use-familiar-tools">使い慣れた道具を使う</a></h3>
- <p>
- 使用する言語、ミドルウェア、ツール類を、使い慣れたものに限定する。「このツールのオプションはほとんどそらで指定できる」と言えるようなものだけを使う。「自分では使ったことがないが ISUCON 強者がお勧めしていた」といった理由でツールを選定しない (もちろん、本番までに練習して習熟するという選択肢は存在する)。
- </p>
- </section>
- </section>
- <section id="section--performance-optimization">
- <h2><a href="#section--performance-optimization">パフォーマンスの最適化</a></h2>
- <p>
- もっと強い人の記事を参考にしてほしい。
- </p>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">おわりに</a></h2>
- <p>
- 事前の準備も含めて、大変楽しいイベントだった。次回があるなら是非また参加したい。その際は、順位やスコアを目標として立てられるようになりたいものである。
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2023-12-31/2023-reflections/index.html b/vhosts/blog/public/posts/2023-12-31/2023-reflections/index.html
deleted file mode 100644
index 423eade4..00000000
--- a/vhosts/blog/public/posts/2023-12-31/2023-reflections/index.html
+++ /dev/null
@@ -1,183 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2023 nsfisis">
- <meta name="description" content="2023年にやったことを振り返る">
- <meta property="og:type" content="article">
- <meta property="og:title" content="2023年の振り返り|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="2023年にやったことを振り返る">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>2023年の振り返り|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">2023年の振り返り</h1>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2023-12-31">2023-12-31</time>: 公開
- </li>
- </ol>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- 男もすなる年末の振り返りといふものを女もしてみむとてするなり。
- </p>
- </section>
- <section id="section--conferences">
- <h2><a href="#section--conferences">登壇・カンファレンススタッフ</a></h2>
- <p>
- 勉強会やカンファレンスで登壇したりスタッフをしたりし始めたのは今年かららしい。LT 等も含めて計 11 回の登壇をおこなった。
- </p>
- <ul>
- <li>
- PHP 勉強会@東京での登壇 (計 8 回)
- <ul>
- <li>
- <a href="/slides/2023-01-18/phpstudy-tokyo-148/">第 148 回</a>
- </li>
- <li>
- <a href="/slides/2023-02-15/phpstudy-tokyo-149/">第 149 回</a>
- </li>
- <li>
- <a href="/slides/2023-03-15/phpstudy-tokyo-150/">第 150 回</a>
- </li>
- <li>
- <a href="/slides/2023-04-12/phpstudy-tokyo-151/">第 151 回</a>
- </li>
- <li>
- <a href="/slides/2023-06-21/phpstudy-tokyo-153/">第 153 回</a>
- </li>
- <li>
- <a href="/slides/2023-07-26/phpstudy-tokyo-154/">第 154 回</a>
- </li>
- <li>
- <a href="/slides/2023-08-24/phpstudy-tokyo-155/">第 155 回</a>
- </li>
- <li>
- <a href="/slides/2023-10-25/phpstudy-tokyo-157/">第 157 回</a>
- </li>
- </ul>
- </li>
- <li>
- PHPerKaigi 2023 での登壇
- <ul>
- <li>
- <a href="/slides/2023-03-24/phperkaigi-2023/">レギュラートーク</a>
- </li>
- <li>
- <a href="/slides/2023-03-25/phperkaigi-2023-tokens/">トークン解説セッション</a>
- </li>
- </ul>
- </li>
- <li>
- PHPerKaigi 2023 での当日スタッフ業
- </li>
- <li>
- <a href="/slides/2023-06-23/phpconfuk-2023-eve/">非公式でおこなわれた PHP カンファレンス福岡 2023 の 前夜祭イベントでの登壇</a>
- </li>
- <li>
- PHPerKaigi 2024 でのコアスタッフ業
- </li>
- </ul>
- </section>
- <section id="section--articles">
- <h2><a href="#section--articles">書いた記事</a></h2>
- <p>
- 登壇が増えたためか記事を書く機会が減ってしまった。特に社内記事の本数が大きく減少しており、一昨年は約 100 本、昨年は約 60 本の社内記事を書いていたが、今年は 30 本強に留まった。その頃と比べると文章を書く筋肉が衰えているように感じる。
- </p>
- <ul>
- <li>
- 社外記事 (このブログ): 8本
- </li>
- <li>
- 社内記事: 34本
- <ul>
- <li>
- 年間で最も記事を書いた人として社内表彰された
- </li>
- </ul>
- </li>
- </ul>
- </section>
- <section id="section--coding">
- <h2><a href="#section--coding">作ったもの</a></h2>
- <p>
- ガラクタをいくつか作った。役には立たないが、作るのが楽しいという効用がある。
- </p>
- <ul>
- <li>
- <a href="https://github.com/nsfisis/PHPerKaigi2023-tokens" rel="noreferrer" target="_blank">PHPerKaigi2023-tokens</a> : PHPerKaigi 2023 でおこなわれた PHPer チャレンジという企画で用意した問題
- </li>
- <li>
- <a href="https://github.com/nsfisis/twitter2x-quine" rel="noreferrer" target="_blank">twitter2x-quine</a> : Twitter のロゴを 𝕏 にする変則 quine
- </li>
- <li>
- <a href="https://github.com/nsfisis/9-puzzle-quine.php" rel="noreferrer" target="_blank">9-puzzle-quine.php</a> : 9パズルが遊べる変則 quine
- </li>
- </ul>
- </section>
- <section id="section--misc">
- <h2><a href="#section--misc">その他</a></h2>
- <ul>
- <li>
- <a href="/posts/2023-10-13/i-entered-the-open-university-of-japan/">放送大学に入学した</a>
- </li>
- <li>
- <a href="/posts/2023-12-03/isucon-13/">ISUCON に初参加した</a>
- </li>
- <li>
- データベーススペシャリストを取得した
- </li>
- <li>
- 漢検2級を取得した
- </li>
- </ul>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">おわりに</a></h2>
- <p>
- 今年も大変お世話になりました。よいお年を!
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2024-01-10/neovim-insert-namespace-declaration-to-empty-php-file/index.html b/vhosts/blog/public/posts/2024-01-10/neovim-insert-namespace-declaration-to-empty-php-file/index.html
deleted file mode 100644
index a85e5bb5..00000000
--- a/vhosts/blog/public/posts/2024-01-10/neovim-insert-namespace-declaration-to-empty-php-file/index.html
+++ /dev/null
@@ -1,280 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="Neovim で空の PHP ファイルを開いたとき、ディレクトリの構造に基づいて自動的に namespace 宣言を挿入するようにする。">
- <meta name="keywords" content="Neovim,PHP">
- <meta property="og:type" content="article">
- <meta property="og:title" content="【Neovim】 空の PHP ファイルに namespace 宣言を挿入する|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="Neovim で空の PHP ファイルを開いたとき、ディレクトリの構造に基づいて自動的に namespace 宣言を挿入するようにする。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>【Neovim】 空の PHP ファイルに namespace 宣言を挿入する|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">【Neovim】 空の PHP ファイルに namespace 宣言を挿入する</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/neovim/">Neovim</a>
- </li>
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2024-01-10">2024-01-10</time>: 公開
- </li>
- </ol>
- </section>
- <div class="admonition">
- <div class="admonition-label">
- NOTE
- </div>
- <div class="admonition-content">
- <p>
- この記事は <a href="https://vim-jp.org/ekiden/" rel="noreferrer" target="_blank">Vim 駅伝</a> #136 の記事です。
- </p>
- </div>
- </div>
- <section id="section--intro">
- <h2><a href="#section--intro">やりたいこと</a></h2>
- <p>
- Neovim で空の PHP ファイルを開いたとき、そのファイルが置かれているディレクトリの構造に基づいて、自動的に <code>namespace</code> 宣言を挿入したい。具体的には、トップレベルの名前空間が <code>MyNamespace</code> であり、ファイル <code>src/Foo/Bar/Baz.php</code> を開いたときに、そのファイルが空であるなら、次のようなテンプレートが自動的に挿入されてほしい。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">namespace</span><span style="color:#6F42C1"> MyNamespace\Foo\Bar</span><span style="color:#24292E">;</span></span></code></pre>
- </div>
- </section>
- <section id="section--version">
- <h2><a href="#section--version">バージョン情報</a></h2>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ nvim --version</span></span>
-<span class="line"><span>NVIM v0.9.2</span></span>
-<span class="line"><span>Build type: Release</span></span>
-<span class="line"><span>LuaJIT 2.1.1693350652</span></span></code></pre>
- </div>
- <p>
- 今回は Lua で処理を記述したため、Vim では動作しない。以下の説明でも Neovim に絞って述べる。また、パス区切りがスラッシュである前提で記述したため、Windows には対応していない。
- </p>
- </section>
- <section id="section--ftplugin">
- <h2><a href="#section--ftplugin">ftplugin を用意する</a></h2>
- <p>
- Neovim には特定のファイルタイプに対して特別な処理をおこなうための ftplugin と呼ばれる仕組みがある。Neovim の設定を置くディレクトリ (例えば <code>~/.config/nvim</code>) の配下に <code>ftplugin/&lt;FILE_TYPE&gt;.vim</code> または <code>ftplugin/&lt;FILE_TYPE&gt;.lua</code> というファイルを配置すると、その <code>&lt;FILE_TYPE&gt;</code> が読み込まれたときにそのファイルが自動的に実行される。
- </p>
- <p>
- 今回は、Neovim がデフォルトで用意している PHP 用 ftplugin が動作したあとに追加の処理をおこないたいので、<code>after/ftplugin/php.{vim,lua}</code> というファイルを配置する。名前から察せられるとおり、<code>after/ftplugin</code> 以下のファイルは <code>ftplugin</code> 以下のファイルよりもあとに実行される。
- </p>
- <p>
- この記事では Lua で処理を記述するため、拡張子には <code>.lua</code> を用いる。これ以降載せるコードは、すべて <code>after/ftplugin/php.lua</code> の中に記述している。
- </p>
- </section>
- <section id="section--did-ftplugin">
- <h2><a href="#section--did-ftplugin">二重読み込みを防ぐ</a></h2>
- <p>
- ファイルタイプは読み込んだあとに変更されることもあるので、ftplugin は複数回実行されうる。二重読み込みを防ぐために、<code>did_ftplugin_&lt;FILE_TYPE&gt;_after</code> というバッファローカル変数を定義しておくのが慣習となっている。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">if</span><span style="color:#24292E"> vim.</span><span style="color:#6F42C1">b</span><span style="color:#24292E">.</span><span style="color:#6F42C1">did_ftplugin_php_after</span><span style="color:#D73A49"> then</span></span>
-<span class="line"><span style="color:#D73A49"> return</span></span>
-<span class="line"><span style="color:#D73A49">end</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#6A737D">-- ここに実際の処理を書く</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E">vim.</span><span style="color:#6F42C1">b</span><span style="color:#24292E">.</span><span style="color:#6F42C1">did_ftplugin_php_after</span><span style="color:#D73A49"> =</span><span style="color:#005CC5"> true</span></span></code></pre>
- </div>
- </section>
- <section id="section--implement">
- <h2><a href="#section--implement">実装する</a></h2>
- <p>
- では実装していこう。今回私は次のようなロジックとした。以降、「今 Neovim で開いた PHP ファイル」のことを「対象ファイル」と呼ぶことにする。
- </p>
- <ol>
- <li>
- 対象ファイルが空でなければ何もしない
- </li>
- <li>
- 対象ファイルが置かれたディレクトリを上に辿って、<code>composer.json</code> を見つける
- </li>
- <li>
- <code>composer.json</code> の <code>autoload.psr-4</code> を見て、トップレベルの名前空間とディレクトリを特定する
- </li>
- <li>
- 対象ファイルが置かれたディレクトリが、トップレベルのディレクトリを基準としてどのようにネストしているか調べる
- </li>
- <li>
- オートロードの設定と照らし合わせて、対象ファイルが属すべき名前空間を特定する
- </li>
- <li>
- PHP の開始タグとともに <code>namespace</code> 宣言を挿入する
- </li>
- </ol>
- <p>
- 実装を簡単にするため、Composer を用いない場合や PSR 4 以外のオートロード規則を使う場合には対応しない。少々長くなるが、以下にスクリプト全文を載せる。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">if</span><span style="color:#24292E"> vim.</span><span style="color:#6F42C1">b</span><span style="color:#24292E">.</span><span style="color:#6F42C1">did_ftplugin_php_after</span><span style="color:#D73A49"> then</span></span>
-<span class="line"><span style="color:#D73A49"> return</span></span>
-<span class="line"><span style="color:#D73A49">end</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#6A737D">-- base_dir を起点としてディレクトリを上向きに辿っていき、composer.json を探す</span></span>
-<span class="line"><span style="color:#6A737D">-- :help vim.fs.find()</span></span>
-<span class="line"><span style="color:#D73A49">local</span><span style="color:#D73A49"> function</span><span style="color:#6F42C1"> find_composer_json</span><span style="color:#24292E">(base_dir)</span></span>
-<span class="line"><span style="color:#D73A49"> return</span><span style="color:#24292E"> vim.</span><span style="color:#6F42C1">fs</span><span style="color:#24292E">.</span><span style="color:#005CC5">find</span><span style="color:#24292E">(</span><span style="color:#032F62">'composer.json'</span><span style="color:#24292E">, {</span></span>
-<span class="line"><span style="color:#24292E"> path </span><span style="color:#D73A49">=</span><span style="color:#24292E"> base_dir,</span></span>
-<span class="line"><span style="color:#24292E"> upward </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> true</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#6A737D"> -- ホームディレクトリまで到達したら探索を打ち切る</span></span>
-<span class="line"><span style="color:#24292E"> stop </span><span style="color:#D73A49">=</span><span style="color:#24292E"> vim.</span><span style="color:#6F42C1">loop</span><span style="color:#24292E">.</span><span style="color:#005CC5">os_homedir</span><span style="color:#24292E">(),</span></span>
-<span class="line"><span style="color:#24292E"> type </span><span style="color:#D73A49">=</span><span style="color:#032F62"> 'file'</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#24292E"> })[</span><span style="color:#005CC5">1</span><span style="color:#24292E">]</span></span>
-<span class="line"><span style="color:#D73A49">end</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#6A737D">-- JSON ファイルを読み込み、デコードして返す</span></span>
-<span class="line"><span style="color:#6A737D">-- :help readblob()</span></span>
-<span class="line"><span style="color:#6A737D">-- :help vim.json.decode</span></span>
-<span class="line"><span style="color:#6A737D">-- :help luaref-pcall()</span></span>
-<span class="line"><span style="color:#D73A49">local</span><span style="color:#D73A49"> function</span><span style="color:#6F42C1"> load_json</span><span style="color:#24292E">(file_path)</span></span>
-<span class="line"><span style="color:#6A737D"> -- readblob() は Vim script では Blob オブジェクトを返すが、Lua から呼ぶと string に変換される</span></span>
-<span class="line"><span style="color:#D73A49"> local</span><span style="color:#24292E"> ok_read, content </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> pcall</span><span style="color:#24292E">(vim.</span><span style="color:#6F42C1">fn</span><span style="color:#24292E">.</span><span style="color:#6F42C1">readblob</span><span style="color:#24292E">, file_path)</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#D73A49"> not</span><span style="color:#24292E"> ok_read </span><span style="color:#D73A49">then</span></span>
-<span class="line"><span style="color:#D73A49"> return</span><span style="color:#005CC5"> nil</span></span>
-<span class="line"><span style="color:#D73A49"> end</span></span>
-<span class="line"><span style="color:#D73A49"> local</span><span style="color:#24292E"> ok_decode, obj </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> pcall</span><span style="color:#24292E">(vim.</span><span style="color:#6F42C1">json</span><span style="color:#24292E">.</span><span style="color:#6F42C1">decode</span><span style="color:#24292E">, content)</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#D73A49"> not</span><span style="color:#24292E"> ok_decode </span><span style="color:#D73A49">then</span></span>
-<span class="line"><span style="color:#D73A49"> return</span><span style="color:#005CC5"> nil</span></span>
-<span class="line"><span style="color:#D73A49"> end</span></span>
-<span class="line"><span style="color:#D73A49"> return</span><span style="color:#24292E"> obj</span></span>
-<span class="line"><span style="color:#D73A49">end</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#6A737D">-- 対象ファイルの置かれたディレクトリを基に namespace 宣言を生成する</span></span>
-<span class="line"><span style="color:#6A737D">-- :help nvim_buf_get_name()</span></span>
-<span class="line"><span style="color:#6A737D">-- :help vim.fs.dirname()</span></span>
-<span class="line"><span style="color:#D73A49">local</span><span style="color:#D73A49"> function</span><span style="color:#6F42C1"> generate_namespace_declaration</span><span style="color:#24292E">()</span></span>
-<span class="line"><span style="color:#6A737D"> -- composer.json を探し、トップレベルの名前空間とディレクトリを特定する</span></span>
-<span class="line"><span style="color:#D73A49"> local</span><span style="color:#24292E"> current_dir </span><span style="color:#D73A49">=</span><span style="color:#24292E"> vim.</span><span style="color:#6F42C1">fs</span><span style="color:#24292E">.</span><span style="color:#005CC5">dirname</span><span style="color:#24292E">(vim.</span><span style="color:#6F42C1">api</span><span style="color:#24292E">.</span><span style="color:#005CC5">nvim_buf_get_name</span><span style="color:#24292E">(</span><span style="color:#005CC5">0</span><span style="color:#24292E">))</span></span>
-<span class="line"><span style="color:#D73A49"> local</span><span style="color:#24292E"> path_to_composer_json </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> find_composer_json</span><span style="color:#24292E">(current_dir)</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#D73A49"> not</span><span style="color:#24292E"> path_to_composer_json </span><span style="color:#D73A49">then</span></span>
-<span class="line"><span style="color:#D73A49"> return</span><span style="color:#005CC5"> nil</span><span style="color:#6A737D"> -- failed to locate composer.json</span></span>
-<span class="line"><span style="color:#D73A49"> end</span></span>
-<span class="line"><span style="color:#D73A49"> local</span><span style="color:#24292E"> composer_json </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> load_json</span><span style="color:#24292E">(path_to_composer_json)</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#D73A49"> not</span><span style="color:#24292E"> composer_json </span><span style="color:#D73A49">then</span></span>
-<span class="line"><span style="color:#D73A49"> return</span><span style="color:#005CC5"> nil</span><span style="color:#6A737D"> -- failed to load composer.json</span></span>
-<span class="line"><span style="color:#D73A49"> end</span></span>
-<span class="line"><span style="color:#6A737D"> -- autoload.psr-4 を探し、型が期待される型と一致するかどうか調べる</span></span>
-<span class="line"><span style="color:#D73A49"> local</span><span style="color:#24292E"> psr4 </span><span style="color:#D73A49">=</span><span style="color:#24292E"> vim.</span><span style="color:#005CC5">tbl_get</span><span style="color:#24292E">(composer_json, </span><span style="color:#032F62">'autoload'</span><span style="color:#24292E">, </span><span style="color:#032F62">'psr-4'</span><span style="color:#24292E">)</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#D73A49"> not</span><span style="color:#24292E"> psr4 </span><span style="color:#D73A49">then</span></span>
-<span class="line"><span style="color:#D73A49"> return</span><span style="color:#005CC5"> nil</span><span style="color:#6A737D"> -- autoload.psr-4 section is absent</span></span>
-<span class="line"><span style="color:#D73A49"> end</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> vim.</span><span style="color:#005CC5">tbl_count</span><span style="color:#24292E">(psr4) </span><span style="color:#D73A49">~=</span><span style="color:#005CC5"> 1</span><span style="color:#D73A49"> then</span></span>
-<span class="line"><span style="color:#D73A49"> return</span><span style="color:#005CC5"> nil</span><span style="color:#6A737D"> -- psr-4 section is ambiguous</span></span>
-<span class="line"><span style="color:#D73A49"> end</span></span>
-<span class="line"><span style="color:#D73A49"> local</span><span style="color:#24292E"> psr4_namespace, psr4_dir</span></span>
-<span class="line"><span style="color:#D73A49"> for</span><span style="color:#24292E"> k, v </span><span style="color:#D73A49">in</span><span style="color:#005CC5"> pairs</span><span style="color:#24292E">(psr4) </span><span style="color:#D73A49">do</span></span>
-<span class="line"><span style="color:#24292E"> psr4_namespace </span><span style="color:#D73A49">=</span><span style="color:#24292E"> k</span></span>
-<span class="line"><span style="color:#24292E"> psr4_dir </span><span style="color:#D73A49">=</span><span style="color:#24292E"> v</span></span>
-<span class="line"><span style="color:#D73A49"> end</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#005CC5"> type</span><span style="color:#24292E">(psr4_dir) </span><span style="color:#D73A49">==</span><span style="color:#032F62"> 'table' </span><span style="color:#D73A49">then</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#D73A49"> #</span><span style="color:#24292E">psr4_dir </span><span style="color:#D73A49">==</span><span style="color:#005CC5"> 1</span><span style="color:#D73A49"> then</span></span>
-<span class="line"><span style="color:#24292E"> psr4_dir </span><span style="color:#D73A49">=</span><span style="color:#24292E"> psr4_dir[</span><span style="color:#005CC5">1</span><span style="color:#24292E">]</span></span>
-<span class="line"><span style="color:#D73A49"> else</span></span>
-<span class="line"><span style="color:#D73A49"> return</span><span style="color:#005CC5"> nil</span><span style="color:#6A737D"> -- psr-4 section is ambiguous</span></span>
-<span class="line"><span style="color:#D73A49"> end</span></span>
-<span class="line"><span style="color:#D73A49"> end</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#005CC5"> type</span><span style="color:#24292E">(psr4_namespace) </span><span style="color:#D73A49">~=</span><span style="color:#032F62"> 'string' </span><span style="color:#D73A49">or</span><span style="color:#005CC5"> type</span><span style="color:#24292E">(psr4_dir) </span><span style="color:#D73A49">~=</span><span style="color:#032F62"> 'string' </span><span style="color:#D73A49">then</span></span>
-<span class="line"><span style="color:#D73A49"> return</span><span style="color:#005CC5"> nil</span><span style="color:#6A737D"> -- psr-4 section is invalid</span></span>
-<span class="line"><span style="color:#D73A49"> end</span></span>
-<span class="line"><span style="color:#6A737D"> -- 末尾のスラッシュとバックスラッシュを取り除いておく</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#6F42C1"> psr4_namespace</span><span style="color:#24292E">:</span><span style="color:#005CC5">sub</span><span style="color:#24292E">(</span><span style="color:#D73A49">-</span><span style="color:#005CC5">1</span><span style="color:#24292E">, </span><span style="color:#D73A49">-</span><span style="color:#005CC5">1</span><span style="color:#24292E">) </span><span style="color:#D73A49">==</span><span style="color:#032F62"> '</span><span style="color:#005CC5">\\</span><span style="color:#032F62">' </span><span style="color:#D73A49">then</span></span>
-<span class="line"><span style="color:#24292E"> psr4_namespace </span><span style="color:#D73A49">=</span><span style="color:#6F42C1"> psr4_namespace</span><span style="color:#24292E">:</span><span style="color:#005CC5">sub</span><span style="color:#24292E">(</span><span style="color:#005CC5">0</span><span style="color:#24292E">, </span><span style="color:#D73A49">-</span><span style="color:#005CC5">2</span><span style="color:#24292E">)</span></span>
-<span class="line"><span style="color:#D73A49"> end</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#6F42C1"> psr4_dir</span><span style="color:#24292E">:</span><span style="color:#005CC5">sub</span><span style="color:#24292E">(</span><span style="color:#D73A49">-</span><span style="color:#005CC5">1</span><span style="color:#24292E">, </span><span style="color:#D73A49">-</span><span style="color:#005CC5">1</span><span style="color:#24292E">) </span><span style="color:#D73A49">==</span><span style="color:#032F62"> '/' </span><span style="color:#D73A49">then</span></span>
-<span class="line"><span style="color:#24292E"> psr4_dir </span><span style="color:#D73A49">=</span><span style="color:#6F42C1"> psr4_dir</span><span style="color:#24292E">:</span><span style="color:#005CC5">sub</span><span style="color:#24292E">(</span><span style="color:#005CC5">0</span><span style="color:#24292E">, </span><span style="color:#D73A49">-</span><span style="color:#005CC5">2</span><span style="color:#24292E">)</span></span>
-<span class="line"><span style="color:#D73A49"> end</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#6A737D"> -- 対象ファイルが置かれたディレクトリとトップレベルのディレクトリを比較し、その差分を名前空間とする</span></span>
-<span class="line"><span style="color:#D73A49"> local</span><span style="color:#24292E"> namespace_root_dir </span><span style="color:#D73A49">=</span><span style="color:#24292E"> vim.</span><span style="color:#6F42C1">fs</span><span style="color:#24292E">.</span><span style="color:#005CC5">dirname</span><span style="color:#24292E">(path_to_composer_json) </span><span style="color:#D73A49">..</span><span style="color:#032F62"> '/' </span><span style="color:#D73A49">..</span><span style="color:#24292E"> psr4_dir</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#D73A49"> not</span><span style="color:#24292E"> vim.</span><span style="color:#005CC5">startswith</span><span style="color:#24292E">(current_dir, namespace_root_dir) </span><span style="color:#D73A49">then</span></span>
-<span class="line"><span style="color:#D73A49"> return</span><span style="color:#005CC5"> nil</span></span>
-<span class="line"><span style="color:#D73A49"> end</span></span>
-<span class="line"><span style="color:#D73A49"> local</span><span style="color:#24292E"> current_path_suffix </span><span style="color:#D73A49">=</span><span style="color:#6F42C1"> current_dir</span><span style="color:#24292E">:</span><span style="color:#005CC5">sub</span><span style="color:#24292E">(</span><span style="color:#D73A49">#</span><span style="color:#24292E">namespace_root_dir </span><span style="color:#D73A49">+</span><span style="color:#005CC5"> 1</span><span style="color:#24292E">)</span></span>
-<span class="line"><span style="color:#D73A49"> local</span><span style="color:#24292E"> namespace </span><span style="color:#D73A49">=</span><span style="color:#24292E"> psr4_namespace </span><span style="color:#D73A49">..</span><span style="color:#6F42C1"> current_path_suffix</span><span style="color:#24292E">:</span><span style="color:#005CC5">gsub</span><span style="color:#24292E">(</span><span style="color:#032F62">'/'</span><span style="color:#24292E">, </span><span style="color:#032F62">'</span><span style="color:#005CC5">\\</span><span style="color:#032F62">'</span><span style="color:#24292E">)</span></span>
-<span class="line"><span style="color:#D73A49"> return</span><span style="color:#24292E"> (</span><span style="color:#032F62">"namespace %s;"</span><span style="color:#24292E">):</span><span style="color:#005CC5">format</span><span style="color:#24292E">(namespace)</span></span>
-<span class="line"><span style="color:#D73A49">end</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">local</span><span style="color:#D73A49"> function</span><span style="color:#6F42C1"> generate_template</span><span style="color:#24292E">()</span></span>
-<span class="line"><span style="color:#D73A49"> local</span><span style="color:#24292E"> lines </span><span style="color:#D73A49">=</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#032F62"> '&#x3C;?php'</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#032F62"> ''</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#032F62"> 'declare(strict_types=1);'</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#032F62"> ''</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#D73A49"> local</span><span style="color:#24292E"> namespace_decl </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> generate_namespace_declaration</span><span style="color:#24292E">()</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> namespace_decl </span><span style="color:#D73A49">then</span></span>
-<span class="line"><span style="color:#24292E"> lines[</span><span style="color:#D73A49">#</span><span style="color:#24292E">lines </span><span style="color:#D73A49">+</span><span style="color:#005CC5"> 1</span><span style="color:#24292E">] </span><span style="color:#D73A49">=</span><span style="color:#24292E"> namespace_decl</span></span>
-<span class="line"><span style="color:#24292E"> lines[</span><span style="color:#D73A49">#</span><span style="color:#24292E">lines </span><span style="color:#D73A49">+</span><span style="color:#005CC5"> 1</span><span style="color:#24292E">] </span><span style="color:#D73A49">=</span><span style="color:#032F62"> ''</span></span>
-<span class="line"><span style="color:#D73A49"> end</span></span>
-<span class="line"><span style="color:#24292E"> lines[</span><span style="color:#D73A49">#</span><span style="color:#24292E">lines </span><span style="color:#D73A49">+</span><span style="color:#005CC5"> 1</span><span style="color:#24292E">] </span><span style="color:#D73A49">=</span><span style="color:#032F62"> ''</span></span>
-<span class="line"><span style="color:#D73A49"> return</span><span style="color:#24292E"> lines</span></span>
-<span class="line"><span style="color:#D73A49">end</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">if</span><span style="color:#24292E"> vim.</span><span style="color:#6F42C1">fn</span><span style="color:#24292E">.</span><span style="color:#005CC5">line</span><span style="color:#24292E">(</span><span style="color:#032F62">'$'</span><span style="color:#24292E">) </span><span style="color:#D73A49">==</span><span style="color:#005CC5"> 1</span><span style="color:#D73A49"> and</span><span style="color:#24292E"> vim.</span><span style="color:#6F42C1">fn</span><span style="color:#24292E">.</span><span style="color:#005CC5">getline</span><span style="color:#24292E">(</span><span style="color:#005CC5">1</span><span style="color:#24292E">) </span><span style="color:#D73A49">==</span><span style="color:#032F62"> '' </span><span style="color:#D73A49">then</span></span>
-<span class="line"><span style="color:#6A737D"> -- 対象ファイルが空なら、テンプレートを挿入してカーソルを末尾に移動させる</span></span>
-<span class="line"><span style="color:#6A737D"> -- :help setline()</span></span>
-<span class="line"><span style="color:#6A737D"> -- :help cursor()</span></span>
-<span class="line"><span style="color:#24292E"> vim.</span><span style="color:#6F42C1">fn</span><span style="color:#24292E">.</span><span style="color:#005CC5">setline</span><span style="color:#24292E">(</span><span style="color:#005CC5">1</span><span style="color:#24292E">, </span><span style="color:#005CC5">generate_template</span><span style="color:#24292E">())</span></span>
-<span class="line"><span style="color:#24292E"> vim.</span><span style="color:#6F42C1">fn</span><span style="color:#24292E">.</span><span style="color:#005CC5">cursor</span><span style="color:#24292E">(</span><span style="color:#032F62">'$'</span><span style="color:#24292E">, </span><span style="color:#005CC5">0</span><span style="color:#24292E">)</span></span>
-<span class="line"><span style="color:#D73A49">end</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E">vim.</span><span style="color:#6F42C1">b</span><span style="color:#24292E">.</span><span style="color:#6F42C1">did_ftplugin_php_after</span><span style="color:#D73A49"> =</span><span style="color:#005CC5"> true</span></span></code></pre>
- </div>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">おわりに</a></h2>
- <p>
- 簡易的な実装だが、多くのケースではうまく動いているようだ。最大の問題は PSR 4 に準拠しないフレームワークを用いているとまったく役に立たないことで、今まさに職場で困っている。こちらはいずれ改良したい。
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2024-02-03/install-wireguard-on-personal-server/index.html b/vhosts/blog/public/posts/2024-02-03/install-wireguard-on-personal-server/index.html
deleted file mode 100644
index fe9be513..00000000
--- a/vhosts/blog/public/posts/2024-02-03/install-wireguard-on-personal-server/index.html
+++ /dev/null
@@ -1,211 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="個人用サービスのセルフホストに使っているサーバに WireGuard を導入する作業をしたメモ">
- <meta name="keywords" content="備忘録,WireGuard">
- <meta property="og:type" content="article">
- <meta property="og:title" content="【備忘録】 個人用サーバに WireGuard を導入する|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="個人用サービスのセルフホストに使っているサーバに WireGuard を導入する作業をしたメモ">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>【備忘録】 個人用サーバに WireGuard を導入する|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">【備忘録】 個人用サーバに WireGuard を導入する</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/note-to-self/">備忘録</a>
- </li>
- <li class="tag">
- <a href="/tags/wireguard/">WireGuard</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2024-02-03">2024-02-03</time>: 公開
- </li>
- <li class="revision">
- <time datetime="2024-02-17">2024-02-17</time>: 80 番ポートについて追記
- </li>
- </ol>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- 個人用サービスのセルフホストに使っているサーバに <a href="https://www.wireguard.com/" rel="noreferrer" target="_blank">WireGuard</a> を導入する作業をしたのでメモ。
- </p>
- <p>
- 登場するホストは以下のとおり:
- </p>
- <ul>
- <li>
- サーバ (Ubuntu): <code>10.10.1.1</code>
- </li>
- <li>
- クライアント 1 (Windows): <code>10.10.1.2</code>
- </li>
- <li>
- クライアント 2 (Android): <code>10.10.1.3</code>
- </li>
- </ul>
- <p>
- 後ろの IP アドレスは VPN 内で使用するプライベート IP アドレス。
- </p>
- </section>
- <section id="section--install-wireguard-server">
- <h2><a href="#section--install-wireguard-server">WireGuard のインストール: サーバ</a></h2>
- <p>
- まずは個人用サービスをホストしている Ubuntu のサーバに WireGuard をインストールする。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ sudo apt install wireguard</span></span></code></pre>
- </div>
- <p>
- 次に、WireGuard で使用する鍵を生成する。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ wg genkey | sudo tee /etc/wireguard/server.key | wg pubkey | sudo tee /etc/wireguard/server.pub</span></span>
-<span class="line"><span>$ sudo chmod 600 /etc/wireguard/server.{key,pub}</span></span></code></pre>
- </div>
- </section>
- <section id="section--install-wireguard-client">
- <h2><a href="#section--install-wireguard-client">WireGuard のインストール: クライアント</a></h2>
- <p>
- 公式サイトから各 OS 向けのクライアントソフトウェアを入手し、インストールする。次に、設定をおこなう。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6A737D"># クライアント 1 の場合</span></span>
-<span class="line"><span style="color:#6F42C1">[Interface]</span></span>
-<span class="line"><span style="color:#D73A49">Address</span><span style="color:#24292E"> = 10.10.1.2/32</span></span>
-<span class="line"><span style="color:#D73A49">PrivateKey</span><span style="color:#24292E"> = &#x3C;クライアント 1 の秘密鍵></span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#6F42C1">[Peer]</span></span>
-<span class="line"><span style="color:#D73A49">PublicKey</span><span style="color:#24292E"> = &#x3C;サーバの公開鍵></span></span>
-<span class="line"><span style="color:#D73A49">AllowedIPs</span><span style="color:#24292E"> = &#x3C;サーバの外部 IP アドレス>/32</span></span>
-<span class="line"><span style="color:#D73A49">Endpoint</span><span style="color:#24292E"> = &#x3C;サーバの外部 IP アドレス>:51820</span></span></code></pre>
- </div>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6A737D"># クライアント 2 の場合</span></span>
-<span class="line"><span style="color:#6F42C1">[Interface]</span></span>
-<span class="line"><span style="color:#D73A49">Address</span><span style="color:#24292E"> = 10.10.1.3/32</span></span>
-<span class="line"><span style="color:#D73A49">PrivateKey</span><span style="color:#24292E"> = &#x3C;クライアント 2 の秘密鍵></span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#6F42C1">[Peer]</span></span>
-<span class="line"><span style="color:#D73A49">PublicKey</span><span style="color:#24292E"> = &#x3C;サーバの公開鍵></span></span>
-<span class="line"><span style="color:#D73A49">AllowedIPs</span><span style="color:#24292E"> = &#x3C;サーバの外部 IP アドレス>/32</span></span>
-<span class="line"><span style="color:#D73A49">Endpoint</span><span style="color:#24292E"> = &#x3C;サーバの外部 IP アドレス>:51820</span></span></code></pre>
- </div>
- <p>
- <code>PrivateKey</code> や <code>PublicKey</code> は鍵ファイルのパスではなく中身を書くことに注意。
- </p>
- </section>
- <section id="section--configure-wireguard">
- <h2><a href="#section--configure-wireguard">WireGuard の設定</a></h2>
- <p>
- 一度サーバへ戻り、WireGuard の設定ファイルを書く。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ sudo vim /etc/wireguard/wg0.conf</span></span></code></pre>
- </div>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6F42C1">[Interface]</span></span>
-<span class="line"><span style="color:#D73A49">Address</span><span style="color:#24292E"> = 10.10.1.1/32</span></span>
-<span class="line"><span style="color:#D73A49">SaveConfig</span><span style="color:#24292E"> = true</span></span>
-<span class="line"><span style="color:#D73A49">PrivateKey</span><span style="color:#24292E"> = &#x3C;サーバの秘密鍵></span></span>
-<span class="line"><span style="color:#D73A49">ListenPort</span><span style="color:#24292E"> = 51820</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#6F42C1">[Peer]</span></span>
-<span class="line"><span style="color:#D73A49">PublicKey</span><span style="color:#24292E"> = &#x3C;クライアント 1 の公開鍵></span></span>
-<span class="line"><span style="color:#D73A49">AllowedIPs</span><span style="color:#24292E"> = 10.10.1.2/32</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#6F42C1">[Peer]</span></span>
-<span class="line"><span style="color:#D73A49">PublicKey</span><span style="color:#24292E"> = &#x3C;クライアント 2 の公開鍵></span></span>
-<span class="line"><span style="color:#D73A49">AllowedIPs</span><span style="color:#24292E"> = 10.10.1.3/32</span></span></code></pre>
- </div>
- <p>
- 次に、WireGuard のサービスを起動する。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ sudo systemctl enable wg-quick@wg0</span></span>
-<span class="line"><span>$ sudo systemctl start wg-quick@wg0</span></span></code></pre>
- </div>
- </section>
- <section id="section--configure-firewall">
- <h2><a href="#section--configure-firewall">ファイアウォールの設定</a></h2>
- <p>
- 続けてファイアウォールを設定する。まずは WireGuard が使用する UDP のポートを開き、<code>wg0</code> を通る通信を許可する。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ sudo ufw allow 51820/udp</span></span>
-<span class="line"><span>$ sudo ufw allow in on wg0</span></span>
-<span class="line"><span>$ sudo ufw allow out on wg0</span></span></code></pre>
- </div>
- <p>
- 次に、80 や 443 などの必要なポートについて、<code>wg0</code> を経由してのアクセスのみ許可する。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ sudo ufw allow in on wg0 to any port 80 proto tcp</span></span>
-<span class="line"><span>$ sudo ufw allow in on wg0 to any port 443 proto tcp</span></span></code></pre>
- </div>
- <p>
- 最後に、<code>ufw</code> を有効にする。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ sudo ufw status</span></span>
-<span class="line"><span>$ sudo ufw enable</span></span></code></pre>
- </div>
- </section>
- <section id="section--connect-each-other">
- <h2><a href="#section--connect-each-other">接続する</a></h2>
- <p>
- これで、各クライアントで VPN を有効にすると、当該サーバの 80 ポートや 443 ポートにアクセスできるようになったはずだ。念のため VPN を切った状態でアクセスできないことも確認しておくとよいだろう。
- </p>
- </section>
- <section id="section--edit-80-port">
- <h2><a href="#section--edit-80-port">追記: 80 番ポートについて</a></h2>
- <p>
- Let’s Encrypt でサーバの証明書を取得している場合、80 番ポートを空けておく必要がある。気づかないうちに証明書が切れないよう注意。
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2024-02-10/yapcjapan-2024-report/index.html b/vhosts/blog/public/posts/2024-02-10/yapcjapan-2024-report/index.html
deleted file mode 100644
index 65e18ba8..00000000
--- a/vhosts/blog/public/posts/2024-02-10/yapcjapan-2024-report/index.html
+++ /dev/null
@@ -1,123 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="2024-02-10 に開催された、YAPC::Hiroshima 2024 に参加した。">
- <meta name="keywords" content="カンファレンス,Perl,YAPC">
- <meta property="og:type" content="article">
- <meta property="og:title" content="YAPC::Hiroshima 2024 参加レポ|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="2024-02-10 に開催された、YAPC::Hiroshima 2024 に参加した。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>YAPC::Hiroshima 2024 参加レポ|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">YAPC::Hiroshima 2024 参加レポ</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/conference/">カンファレンス</a>
- </li>
- <li class="tag">
- <a href="/tags/perl/">Perl</a>
- </li>
- <li class="tag">
- <a href="/tags/yapc/">YAPC</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2024-02-10">2024-02-10</time>: 公開
- </li>
- </ol>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- 2024-02-10 に開催された、 <a href="https://yapcjapan.org/2024hiroshima/" rel="noreferrer" target="_blank">YAPC::Hiroshima 2024</a> に参加した。
- </p>
- </section>
- <section id="section--sessions-thoughts">
- <h2><a href="#section--sessions-thoughts">セッションの感想</a></h2>
- <p>
- ※セッションの題名と発表者名は、 <a href="https://fortee.jp/yapc-hiroshima-2024" rel="noreferrer" target="_blank">カンファレンスの fortee ページ</a> から引用。
- </p>
- <ul>
- <li>
- <a href="https://fortee.jp/yapc-hiroshima-2024/proposal/c0e77f91-f856-48a0-9741-b9afb662cd30" rel="noreferrer" target="_blank">VISAカードの裏側と “手が掛かる” 決済システムの育て方 (三谷 さん)</a>
- <ul>
- <li>
- ベストスピーカー賞にも選ばれていましたが、大変面白い発表でした。私自身はカード決済の知識がまったくなかったのですが、巧みな説明により、「わかったような気がする」状態になれました。
- </li>
- </ul>
- </li>
- <li>
- <a href="https://fortee.jp/yapc-hiroshima-2024/proposal/0e545260-61e1-465e-951c-91d6afb7782c" rel="noreferrer" target="_blank">awkでつくってわかる、Webアプリケーション (やんまー さん)</a>
- <ul>
- <li>
- ゲームでもプログラミングでも縛りプレイほど楽しいものはないと思います。発表中ではさらっと流されていましたが、データベースとの通信や TLS、GitHub の SSO など、およそ awk で書かれたとは思えぬ機能が多数実装されており、カンファレンスなどの場でしかなかなか味わうことのない狂気に触れることができました。
- </li>
- </ul>
- </li>
- <li>
- キーノート (杜甫々 さん)
- <ul>
- <li>
- ※ 招待講演のため fortee のプロポーザルページなし
- </li>
- <li>
- 私が小学6年生のとき、プログラミングを始めようと最初に開いたのが「 <a href="https://www.tohoho-web.com/java/" rel="noreferrer" target="_blank">とほほの Java 入門</a> 」でした。私の人生の道を決定したその第一歩目のサイトの運営者が今まさに目の前で話しているというのは、感動などという言葉ではとても言い尽くせません。これだけで、広島まで来る価値があったと断言できます。
- </li>
- </ul>
- </li>
- </ul>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">おわりに</a></h2>
- <p>
- 最高だった。特に、杜甫々氏の講演を生で拝聴できたのは、感慨とともに大いに刺激となった。次回の YAPC にも是非参加したい。
- </p>
- <p>
- P.S. Perl を書いたことがなくとも十二分に楽しめるイベントなので、「Perl を書かない」という理由で参加しなかったかたは、次回是非参加を検討してみてほしい。
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2024-02-22/phpkansai-2024-report/index.html b/vhosts/blog/public/posts/2024-02-22/phpkansai-2024-report/index.html
deleted file mode 100644
index f3f42d6a..00000000
--- a/vhosts/blog/public/posts/2024-02-22/phpkansai-2024-report/index.html
+++ /dev/null
@@ -1,120 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="2024-02-11 に開催された、PHPカンファレンス関西 2024 に参加した。">
- <meta name="keywords" content="カンファレンス,PHP,PHP カンファレンス関西">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHPカンファレンス関西 2024 参加レポ|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="2024-02-11 に開催された、PHPカンファレンス関西 2024 に参加した。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHPカンファレンス関西 2024 参加レポ|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">PHPカンファレンス関西 2024 参加レポ</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/conference/">カンファレンス</a>
- </li>
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phpkansai/">PHP カンファレンス関西</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2024-02-21">2024-02-21</time>: 公開
- </li>
- </ol>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- 2024-02-11 に開催された、 <a href="https://2024.kphpug.jp/" rel="noreferrer" target="_blank">PHPカンファレンス関西 2024</a> に参加した。
- </p>
- </section>
- <section id="section--sessions-thoughts">
- <h2><a href="#section--sessions-thoughts">セッションの感想</a></h2>
- <p>
- ※セッションの題名と発表者名は、 <a href="https://fortee.jp/phpcon-kansai2024" rel="noreferrer" target="_blank">カンファレンスの fortee ページ</a> から引用。
- </p>
- <ul>
- <li>
- <a href="https://fortee.jp/phpcon-kansai2024/proposal/4e03491c-2a97-40aa-8ff9-a68593b0e847" rel="noreferrer" target="_blank">RDBアンチパターンと戦う - 削除フラグ 完全攻略ガイド (曽根 壮大 さん)</a>
- <ul>
- <li>
- アンチパターンとして紙の上での知識だけあるものの、実際にどう設計すべきなのか、あるいは今すでに使われている場合にどう直していくべきなのかについては、知識がまったく足りていなかったため、よい機会となりました。データベース分野については、今後も知識のインプットと経験が必要だと感じています。
- </li>
- </ul>
- </li>
- <li>
- <a href="https://fortee.jp/phpcon-kansai2024/proposal/c903c4be-77bb-47b9-85a1-5bfdfd61c1aa" rel="noreferrer" target="_blank">PHPコミュニティ、その魅力と熱狂をあなたにも!!! (ことみん さん)</a>
- <ul>
- <li>
- もしこの記事を読んでいるあなたがまだ一度もカンファレンスや勉強会に参加したことがないなら、この記事はどうでもいいのでスライドを見てください。伝えるべきことは以上です。
- </li>
- </ul>
- </li>
- <li>
- <a href="https://fortee.jp/phpcon-kansai2024/proposal/0e0befdb-2028-42c8-98e2-b19e434f5a82" rel="noreferrer" target="_blank">ほげ言語にあってPHPにない機能 (田中ひさてる さん)</a>
- <ul>
- <li>
- 私はプログラミング言語の比較が大好きなので、非常に楽しかったです。UFCS (Uniform Function Call Syntax) の知名度の低さには驚きましたが、D言語er で会場が埋め尽くされていたらそれはそれで驚きなのでやむなしかもしれません。個人的に「ほげ言語にあってPHPにない機能」の中で一番ほしいのは代数的データ型です。
- </li>
- </ul>
- </li>
- </ul>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">おわりに</a></h2>
- <p>
- <a href="/posts/2024-02-10/yapcjapan-2024-report/">本カンファレンスの前日 2024-02-10 は YAPC::Hiroshima に参加しており</a> 、2日連続のカンファレンスとなった。かなり疲れはしたが、その分充実した週末となったように思う。
- </p>
- <p>
- 翌3月は PHPerKaigi 2024、4月は PHPカンファレンス小田原 2024 があり、いずれもスタッフ兼スピーカーで参加予定である。今度は提供する側として、満足のいくカンファレンスになるようにしたい。
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2024-03-17/phperkaigi-2024-report/index.html b/vhosts/blog/public/posts/2024-03-17/phperkaigi-2024-report/index.html
deleted file mode 100644
index fef781ed..00000000
--- a/vhosts/blog/public/posts/2024-03-17/phperkaigi-2024-report/index.html
+++ /dev/null
@@ -1,176 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="2024-03-07 から 2024-03-09 にかけて開催された、PHPerKaigi 2024 に参加した。">
- <meta name="keywords" content="カンファレンス,PHP,PHPerKaigi">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHPerKaigi 2024 参加レポ|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="2024-03-07 から 2024-03-09 にかけて開催された、PHPerKaigi 2024 に参加した。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHPerKaigi 2024 参加レポ|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">PHPerKaigi 2024 参加レポ</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/conference/">カンファレンス</a>
- </li>
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phperkaigi/">PHPerKaigi</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2024-03-17">2024-03-17</time>: 公開
- </li>
- <li class="revision">
- <time datetime="2024-07-07">2024-07-07</time>: Wasm ランタイムの進捗について追記
- </li>
- </ol>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- 2024-03-07 から 2024-03-09 にかけて開催された、 <a href="https://phperkaigi.jp/2024/" rel="noreferrer" target="_blank">PHPerKaigi 2024</a> に参加した。今年はスピーカーとして、また、コアスタッフとして参加した。
- </p>
- <p>
- 過去の参加レポはこちら:
- </p>
- <ul>
- <li>
- <a href="/posts/2023-04-04/phperkaigi-2023-report/">PHPerKaigi 2023</a>
- </li>
- <li>
- <a href="/posts/2022-05-01/phperkaigi-2022/">PHPerKaigi 2022</a>
- </li>
- <li>
- <a href="/posts/2021-03-30/phperkaigi-2021/">PHPerKaigi 2021</a>
- </li>
- </ul>
- </section>
- <section id="section--as-speaker">
- <h2><a href="#section--as-speaker">スピーカーとして</a></h2>
- <p>
- 昨年に続き、スピーカーとして登壇をおこなった。
- </p>
- <ul>
- <li>
- WebAssembly を理解する 〜VM の作成を通して〜
- <ul>
- <li>
- <a href="https://fortee.jp/phperkaigi-2024/proposal/bc5dc153-17af-4079-8f1b-2660af97e2c8" rel="noreferrer" target="_blank">プロポーザル</a>
- </li>
- <li>
- <a href="/slides/2024-03-08/phperkaigi-2024/">スライド</a>
- </li>
- </ul>
- </li>
- </ul>
- <p>
- WebAssembly の VM を PHP で実装し、実装に至るまでの道程や WebAssembly の特徴、言語処理系を作る楽しさについて語った。タイトルにある「WebAssembly を理解する」という目的が達成できるようなトークだったかと言われると疑問は残るものの、実際に作った人にしかできない話をすることはできたと思う。
- </p>
- </section>
- <section id="section--as-staff">
- <h2><a href="#section--as-staff">コアスタッフとして</a></h2>
- <p>
- 昨年は当日スタッフとして参加したが、今年はコアスタッフとして運営に参加した。今年はコードゴルフ企画を提案し、その準備とシステムの開発、当日の運用をおこなった。そのシステムは現在も下記の URL から閲覧でき、当日出題された問題や参加者の方々の回答が見られる。
- </p>
- <p>
- <a href="https://t.nil.ninja/phperkaigi/2024/golf/" rel="noreferrer" target="_blank">Albatross.PHP</a>
- </p>
- <p>
- システムの開発完了や問題の作成完了はスケジュールギリギリとなったのだが、当日はそこそこ安定して稼動していたのではないかと思う。
- </p>
- </section>
- <section id="section--as-attendee">
- <h2><a href="#section--as-attendee">参加者として</a></h2>
- <section id="section--as-attendee--my-best-session">
- <h3><a href="#section--as-attendee--my-best-session">マイベストセッション</a></h3>
- <p>
- <a href="https://fortee.jp/phperkaigi-2024/proposal/ac59d0dd-795a-47cb-ba59-c0b1772d00cc" rel="noreferrer" target="_blank">RubyVM を PHP で実装する〜Hello World を出力するまで〜</a> (めもりー さん)
- </p>
- <p>
- 今回一番楽しみにしていたセッションであり、期待どおりの面白さだった。私も今回 VM を作るというテーマで登壇したこともあり、高い解像度で受け取ることができたように思う。
- </p>
- <p>
- P.S. Ask the Speaker で話した、Ruby VM (written in PHP) on PHP VM (compiled to Wasm) on Wasm VM (written in PHP) on PHP というアイデアは「マジ」なので、続報をお待ちください (自作 Wasm runtime に不足している機能を鋭意実装中です)。
- </p>
- <div class="admonition" editat="2024-07-07" operation="追記">
- <div class="admonition-label">
- 2024-07-07 追記
- </div>
- <div class="admonition-content">
- <p>
- <a href="https://github.com/nsfisis/php-waddiwasi/commit/a312e95a95d243943535f94653822d6796d4637f" rel="noreferrer" target="_blank">コミット a312e95</a> で、ついに Ruby VM on PHP VM on Wasm VM on PHP を実現した。現時点での動かしかたは README に記載している。
- </p>
- </div>
- </div>
- </section>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">おわりに</a></h2>
- <p>
- 今年はスピーカーとスタッフともに開発を伴うものだったので (Wasm 処理系とコードゴルフシステム)、両者がぶつかった結果として準備段階は去年よりも大変になった。
- </p>
- <p>
- <a href="https://twitter.com/nsfisis/status/1765366490277253502" rel="noreferrer" target="_blank">ゴリゴリに開発しなければいけないセッションのスピーカーとゴリゴリに開発しなければいけない企画のスタッフを同じカンファレンスでやってはいけない</a>
- </p>
- <p>
- ただ、それでもコアスタッフとして半年ほど関わっただけに、終わってみると感慨深い。例年どおり、お祭のような活気・熱気を感じることができた。
- </p>
- <p>
- 来月は、また登壇とスタッフ (こちらは当日スタッフ) をおこなう <a href="https://phpcon-odawara.jp/" rel="noreferrer" target="_blank">PHP カンファレンス小田原</a> があるので、良いトーク・良いカンファレンスを作れるようにしたい。
- </p>
- <p>
- さて、参加レポは例年この言葉で締め括っているので、今年もそれで終わろうと思う。
- </p>
- <p>
- ではまた来年。
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2024-03-20/my-bucket-list/index.html b/vhosts/blog/public/posts/2024-03-20/my-bucket-list/index.html
deleted file mode 100644
index 2a074a11..00000000
--- a/vhosts/blog/public/posts/2024-03-20/my-bucket-list/index.html
+++ /dev/null
@@ -1,129 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="駄文">
- <meta property="og:type" content="article">
- <meta property="og:title" content="死ぬまでに作る自作○○一覧あるいは人生の TODO リスト|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="駄文">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>死ぬまでに作る自作○○一覧あるいは人生の TODO リスト|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">死ぬまでに作る自作○○一覧あるいは人生の TODO リスト</h1>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2024-03-20">2024-03-20</time>: 公開
- </li>
- <li class="revision">
- <time datetime="2024-04-07">2024-04-07</time>: URL slug を todos-in-my-life から my-bucket-list へ変更
- </li>
- </ol>
- </section>
- <p>
- これは眠れない夜にノートへ書き散らした文をなんとか文章の体裁に直したものであり、およそ論理と呼べるものを期待してはならぬ。
- </p>
- <p>
- Knuth 曰くプログラミングは文芸である。断っておくが、労役に伴うプロダクティブでプラクティカルな行為を指してそう言っているのではない (Knuth がどう考えているかは知らないが、少なくとも私にとっては)。いわゆる趣味プログラミング、穢れなき自由意志の下で記述されるプログラムとはすなわち、絵描きにとっての絵、文字書きにとっての文章に等しい。プログラムとは、ソースコードとは、芸術作品の一形態なのである。
- </p>
- <p>
- この人生でプログラミングという行為に魅せられたからには、美しい作品を遺さねばならぬ。すなわち、簡潔で、理解しやすく、凝縮され、機能的で、速く、軽く、よい名前を持ち、うまく動くものをだ。
- </p>
- <p>
- 何を作りたいかは各々異なるであろうが、私にとっては車輪の再発明として知られる自作○○である。
- </p>
- <p>
- 車輪の再発明を恐れてはいけない。これを批判する人間というのは、プロダクティビティやプラクティカリティにフォーカスするエンジニアという人種である。今私が表現者たろうとするなら、自らの手で自らの車輪を作ることに何の恐れを抱く必要があろうか。
- </p>
- <p>
- そう、これが私の死ぬまでに作る自作○○一覧あるいは人生の TODO リストである (現時点ですでに部分的あるいは全面的に達成しているものを含む)。
- </p>
- <ul>
- <li>
- 自作 C コンパイラ
- </li>
- <li>
- 自作アセンブラ
- </li>
- <li>
- 自作リンカ
- </li>
- <li>
- 自作 Scheme 処理系
- </li>
- <li>
- 自作 ML コンパイラ
- </li>
- <li>
- 自作 Lua 処理系
- </li>
- <li>
- 自作 JVM
- </li>
- <li>
- 自作 Wasm 処理系
- </li>
- <li>
- 自作正規表現エンジン
- </li>
- <li>
- 自作 JavaScript 処理系
- </li>
- <li>
- 自作ブラウザ
- </li>
- <li>
- 自作エディタ
- </li>
- <li>
- 自作 ActivityPub 実装
- </li>
- </ul>
- <p>
- 選定理由は作りたいということのほかにない。そこに題材とキャンバスがあり絵筆と絵具があれば、生きとし生けるもの、いづれかコードを書かざりける。
- </p>
- <p>
- おお、願わくは、私にこれらを生み出すだけの時間があらんことを。
- </p>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2024-04-14/phpcon-odawara-2024-report/index.html b/vhosts/blog/public/posts/2024-04-14/phpcon-odawara-2024-report/index.html
deleted file mode 100644
index 1d971870..00000000
--- a/vhosts/blog/public/posts/2024-04-14/phpcon-odawara-2024-report/index.html
+++ /dev/null
@@ -1,172 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="2024-04-13 に開催された、PHP カンファレンス小田原 2024 に参加した。">
- <meta name="keywords" content="カンファレンス,PHP,PHP カンファレンス小田原">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHP カンファレンス小田原 2024 参加レポ|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="2024-04-13 に開催された、PHP カンファレンス小田原 2024 に参加した。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHP カンファレンス小田原 2024 参加レポ|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">PHP カンファレンス小田原 2024 参加レポ</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/conference/">カンファレンス</a>
- </li>
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phpcon-odawara/">PHP カンファレンス小田原</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2024-04-14">2024-04-14</time>: 公開
- </li>
- <li class="revision">
- <time datetime="2024-06-01">2024-06-01</time>: セッションの感想を追加
- </li>
- </ol>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- 2024-04-13 に開催された <a href="https://phpcon-odawara.jp/" rel="noreferrer" target="_blank">PHP カンファレンス小田原</a> に、スピーカーとして、また当日スタッフとして参加した。
- </p>
- </section>
- <section id="section--as-speaker">
- <h2><a href="#section--as-speaker">スピーカーとして</a></h2>
- <p>
- PHP 処理系の JIT コンパイルにおける PHP 8.4 での変更について、登壇をおこなった。
- </p>
- <ul>
- <li>
- 来る新 JIT エンジンについて知った気になる
- <ul>
- <li>
- <a href="https://fortee.jp/phpconodawara-2024/proposal/bc9669f6-6583-489c-aa6a-1b68abf7c291" rel="noreferrer" target="_blank">プロポーザル</a>
- </li>
- <li>
- <a href="/slides/2024-04-13/phpcon-odawara-2024/">スライド</a>
- </li>
- </ul>
- </li>
- </ul>
- <p>
- 今回、どこから話を始めるか大いに迷ったのだが、最終的には PHP 処理系の opcode や VM といった概念は既知のものとし、そこから JIT コンパイルへ繋げるといった構成にした。
- </p>
- <p>
- PHP の処理系がスクリプトを opcode へ変換する過程については、ちょうど同じカンファレンスの <a href="https://fortee.jp/phpconodawara-2024/proposal/21d94a60-404d-4fba-8c60-d1c8889a0138" rel="noreferrer" target="_blank">めもりーさんの発表</a> あたりを参考にしていただくとよいだろう。また、新しい IR についてより詳しく知りたいという方は、スライド末尾の「参考資料」にあるリンクを参照いただくのがよいかと思う。
- </p>
- <p>
- Tracing JIT の発火条件や、IR を使って実現される最適化方法など、調べたものの発表に入らなかった話がごまんとあるので、これもどこかに持っていければと考えている。
- </p>
- </section>
- <section id="section--as-staff">
- <h2><a href="#section--as-staff">スタッフとして</a></h2>
- <p>
- 当日スタッフとして前日の準備と当日の運営をおこなった。今回はモノの移動が比較的 (比較対象: <a href="/posts/2024-03-17/phperkaigi-2024-report/">PHPerKaigi</a> ) 少なく、体力にはかなり余裕があった。
- </p>
- <p>
- 自分の担当範囲内では、一度タイムキーパー係のときに時間を思いきり間違えた以外は、スムーズに進められたかと思う。
- </p>
- <p>
- また、これはコアスタッフの方々のおかげだろうが、初開催としては大きなトラブルなく終わったと言えるのではないだろうか。
- </p>
- </section>
- <section id="section--as-attendee">
- <h2><a href="#section--as-attendee">参加者として</a></h2>
- <p>
- 発表タイトルと発表者名は fortee より引用
- </p>
- <ul>
- <li>
- FigmaとPHPで作る、1ミリたりとも表示崩れしない最強の帳票印刷ソリューション (たつきち さん)
- <ul>
- <li>
- プロポーザルリンク: <a href="https://fortee.jp/phpconodawara-2024/proposal/7c57d5ca-213a-4d7a-aaf0-26ddc44897f0" rel="noreferrer" target="_blank">https://fortee.jp/phpconodawara-2024/proposal/7c57d5ca-213a-4d7a-aaf0-26ddc44897f0</a>
- </li>
- <li>
- 感想: 最初のアイデアから途中の泥臭いワークアラウンドまで非常におもしろかったです。帳票には何度か苦しめられているので、機会があれば試してみたいです。
- </li>
- </ul>
- </li>
- <li>
- PHPの次期バージョンはこの時期どうなっているのか、Internalsの開発体制について (てきめん さん)
- <ul>
- <li>
- プロポーザルリンク: <a href="https://fortee.jp/phpconodawara-2024/proposal/740b034a-81f0-4b7a-90e9-cd3fa01c651f" rel="noreferrer" target="_blank">https://fortee.jp/phpconodawara-2024/proposal/740b034a-81f0-4b7a-90e9-cd3fa01c651f</a>
- </li>
- <li>
- 感想: 前々から出そうとしている RFC があるので、RFC についての日本語情報が増えるのは大変ありがたいです。あとは作業を進めなければ……。
- </li>
- </ul>
- </li>
- <li>
- Architecture Decision Record を一年運用してみた (富所 亮 さん)
- <ul>
- <li>
- プロポーザルリンク: <a href="https://fortee.jp/phpconodawara-2024/proposal/56218b4f-b724-4199-82f1-67497501a9ef" rel="noreferrer" target="_blank">https://fortee.jp/phpconodawara-2024/proposal/56218b4f-b724-4199-82f1-67497501a9ef</a>
- </li>
- <li>
- 感想: 今回最も楽しみにしていた発表の一つです。設計指針の調査・共有等には課題を感じていたので、弊チームでも導入のために動いていこうと思います。
- </li>
- </ul>
- </li>
- </ul>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">おわりに</a></h2>
- <p>
- 怒涛の月刊 PHP カンファレンスも折り返しとなったが、まだまだ新鮮に楽しい。
- </p>
- <p>
- また今度、カンファレンスで会いましょう (震源地がよくわかっていないのだけれど、575 が流行っているらしい)。
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2024-04-21/pipefail-option-in-gitlab-ci-cd/index.html b/vhosts/blog/public/posts/2024-04-21/pipefail-option-in-gitlab-ci-cd/index.html
deleted file mode 100644
index 31fee59b..00000000
--- a/vhosts/blog/public/posts/2024-04-21/pipefail-option-in-gitlab-ci-cd/index.html
+++ /dev/null
@@ -1,221 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="GitLab CI/CD で bash/sh スクリプトを動かすと、pipefail オプションが有効になった状態で実行される。">
- <meta name="keywords" content="CI/CD,GitLab">
- <meta property="og:type" content="article">
- <meta property="og:title" content="【GitLab】 GitLab CI/CD 上での bash/sh は pipefail が有効になっている|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="GitLab CI/CD で bash/sh スクリプトを動かすと、pipefail オプションが有効になった状態で実行される。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>【GitLab】 GitLab CI/CD 上での bash/sh は pipefail が有効になっている|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">【GitLab】 GitLab CI/CD 上での bash/sh は pipefail が有効になっている</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/ci-cd/">CI/CD</a>
- </li>
- <li class="tag">
- <a href="/tags/gitlab/">GitLab</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2022-11-17">2022-11-17</time>: デジタルサーカス株式会社の社内記事として公開
- </li>
- <li class="revision">
- <time datetime="2024-04-21">2024-04-21</time>: ブログ記事として一般公開
- </li>
- </ol>
- </section>
- <div class="admonition">
- <div class="admonition-label">
- NOTE
- </div>
- <div class="admonition-content">
- <p>
- この記事は、2022-11-17 に <a href="https://www.dgcircus.com/" rel="noreferrer" target="_blank">デジタルサーカス株式会社</a> の社内 Qiita Team に公開された記事をベースに、加筆修正して一般公開したものです。
- </p>
- </div>
- </div>
- <p>
- ハマったのでメモ。
- </p>
- <section id="section--background">
- <h2><a href="#section--background">前提</a></h2>
- <section id="section--background--gitlab-ci-cd">
- <h3><a href="#section--background--gitlab-ci-cd">GitLab CI/CD について</a></h3>
- <p>
- GitLab CI/CD では、Docker executor を用いて任意の Docker image 上でスクリプトを走らせることができる。
- </p>
- <p>
- 例:
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#22863A">hello-world</span><span style="color:#24292E">:</span></span>
-<span class="line"><span style="color:#22863A"> stage</span><span style="color:#24292E">: </span><span style="color:#032F62">test</span></span>
-<span class="line"><span style="color:#22863A"> image</span><span style="color:#24292E">: </span><span style="color:#032F62">alpine:latest</span></span>
-<span class="line"><span style="color:#22863A"> script</span><span style="color:#24292E">:</span></span>
-<span class="line"><span style="color:#24292E"> - </span><span style="color:#032F62">'echo "Hello, World!"'</span></span>
-<span class="line"><span style="color:#22863A"> rules</span><span style="color:#24292E">:</span></span>
-<span class="line"><span style="color:#24292E"> - </span><span style="color:#22863A">if</span><span style="color:#24292E">: </span><span style="color:#032F62">'$CI_MERGE_REQUEST_IID'</span></span>
-<span class="line"><span style="color:#22863A"> when</span><span style="color:#24292E">: </span><span style="color:#032F62">always</span></span></code></pre>
- </div>
- <p>
- ここで、<code>script</code> に指定したコマンドが失敗する (exit status が 0 以外になる) と、即座に実行が停止され、ジョブは失敗する。
- </p>
- <p>
- では、次のようなケースだとどうなるか。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#22863A">hello-world</span><span style="color:#24292E">:</span></span>
-<span class="line"><span style="color:#22863A"> stage</span><span style="color:#24292E">: </span><span style="color:#032F62">test</span></span>
-<span class="line"><span style="color:#22863A"> image</span><span style="color:#24292E">: </span><span style="color:#032F62">alpine:latest</span></span>
-<span class="line"><span style="color:#22863A"> script</span><span style="color:#24292E">:</span></span>
-<span class="line"><span style="color:#24292E"> - </span><span style="color:#032F62">'exit 1 | exit 0'</span></span>
-<span class="line"><span style="color:#22863A"> rules</span><span style="color:#24292E">:</span></span>
-<span class="line"><span style="color:#24292E"> - </span><span style="color:#22863A">if</span><span style="color:#24292E">: </span><span style="color:#032F62">'$CI_MERGE_REQUEST_IID'</span></span>
-<span class="line"><span style="color:#22863A"> when</span><span style="color:#24292E">: </span><span style="color:#032F62">always</span></span></code></pre>
- </div>
- <p>
- 失敗するコマンドをパイプに接続した。通常 Bash では、パイプの最後のコマンドの exit code が全体の exit code になる。
- </p>
- </section>
- <section id="section--background--pipefail-option">
- <h3><a href="#section--background--pipefail-option"><code>pipefail</code> オプションについて</a></h3>
- <p>
- 前述したようなケースにおいて、途中で失敗したときに全体を失敗させるには、<code>pipefail</code> オプションを有効にする。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6A737D"># On にする</span></span>
-<span class="line"><span style="color:#005CC5">set</span><span style="color:#005CC5"> -o</span><span style="color:#032F62"> pipefail</span></span>
-<span class="line"><span style="color:#6A737D"># Off にする</span></span>
-<span class="line"><span style="color:#005CC5">set</span><span style="color:#032F62"> +o</span><span style="color:#032F62"> pipefail</span></span></code></pre>
- </div>
- <p>
- こうすると、パイプ全体が失敗するようになる。この設定は、デフォルトだと off になっている。
- </p>
- </section>
- </section>
- <section id="section--problem">
- <h2><a href="#section--problem">発生した問題</a></h2>
- <p>
- 次のような GitLab CI/CD ジョブが失敗してしまった。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#22863A">hoge</span><span style="color:#24292E">:</span></span>
-<span class="line"><span style="color:#22863A"> stage</span><span style="color:#24292E">: </span><span style="color:#032F62">test</span></span>
-<span class="line"><span style="color:#22863A"> image</span><span style="color:#24292E">: </span><span style="color:#032F62">alpine:latest</span></span>
-<span class="line"><span style="color:#22863A"> script</span><span style="color:#24292E">:</span></span>
-<span class="line"><span style="color:#24292E"> - </span><span style="color:#032F62">'cat hoge.txt | grep piyo | sed -e "s/foo/bar/g"'</span></span>
-<span class="line"><span style="color:#22863A"> rules</span><span style="color:#24292E">:</span></span>
-<span class="line"><span style="color:#24292E"> - </span><span style="color:#22863A">if</span><span style="color:#24292E">: </span><span style="color:#032F62">'$CI_MERGE_REQUEST_IID'</span></span>
-<span class="line"><span style="color:#22863A"> when</span><span style="color:#24292E">: </span><span style="color:#032F62">always</span></span></code></pre>
- </div>
- <p>
- <code>grep</code> コマンドは、パターンにマッチする行が一行もなかったとき、exit code 1 を返す。よって、<code>pipefail</code> が on になっていると、このジョブは失敗する。現在の <code>pipefail</code> がどうなっているか確かめるため <code>set +o</code> で全オプションを出力させたところ、<code>pipefail</code> が on になっていた。
- </p>
- <p>
- しかし、先述したように Bash における <code>pipefail</code> のデフォルト値は off のはずだ。実際に、ローカルで <code>alpine:latest</code> を動かしてみたところ、
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ docker run --rm alpine:latest sh -c "set +o"</span></span>
-<span class="line"><span>set +o errexit</span></span>
-<span class="line"><span>set +o noglob</span></span>
-<span class="line"><span>set +o ignoreeof</span></span>
-<span class="line"><span>set +o monitor</span></span>
-<span class="line"><span>set +o noexec</span></span>
-<span class="line"><span>set +o xtrace</span></span>
-<span class="line"><span>set +o verbose</span></span>
-<span class="line"><span>set +o noclobber</span></span>
-<span class="line"><span>set +o allexport</span></span>
-<span class="line"><span>set +o notify</span></span>
-<span class="line"><span>set +o nounset</span></span>
-<span class="line"><span>set +o vi</span></span>
-<span class="line"><span>set +o pipefail</span></span></code></pre>
- </div>
- <p>
- 確かに <code>pipefail</code> は無効になっている。
- </p>
- <p>
- なぜスクリプト内で <code>set -o pipefail</code> しているわけでもないのに <code>pipefail</code> が on になっているのか。
- </p>
- </section>
- <section id="section--where-pipefail-is-enabled">
- <h2><a href="#section--where-pipefail-is-enabled">どこで <code>pipefail</code> が on になるか</a></h2>
- <p>
- <code>.gitlab-ci.yml</code> で明示的には書いていないので、GitLab Runner (GitLab CI/CD のスクリプトを実行するプログラム) が勝手に追加しているに違いない。そう仮説を立てて <a href="https://gitlab.com/gitlab-org/gitlab-runner" rel="noreferrer" target="_blank">GitLab Runner のリポジトリ</a> を調査したところ、 <a href="https://gitlab.com/gitlab-org/gitlab-runner/-/blob/c75da0796a0e3048991dccfdf2784e3d931beda4/shells/bash.go#L276" rel="noreferrer" target="_blank">ソースコード中の以下の箇所</a> で <code>set -o pipefail</code> していることが判明した (コメントは筆者による)。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6A737D">// pipefail オプションが存在しない環境にも対応するため、</span></span>
-<span class="line"><span style="color:#6A737D">// 先に set -o でオプション一覧を表示させたあと、set -o pipefail している</span></span>
-<span class="line"><span style="color:#24292E">buf.</span><span style="color:#6F42C1">WriteString</span><span style="color:#24292E">(</span><span style="color:#032F62">"if set -o | grep pipefail > /dev/null; then set -o pipefail; fi; set -o errexit</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">)</span></span></code></pre>
- </div>
- </section>
- <section id="section--how-to-solve">
- <h2><a href="#section--how-to-solve">どのように解決するか</a></h2>
- <p>
- 通常の Bash スクリプトを書く場合と同様に、<code>pipefail</code> が on になっていては困る場所だけ off にしてやればよい。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#22863A"> hoge</span><span style="color:#24292E">:</span></span>
-<span class="line"><span style="color:#22863A"> stage</span><span style="color:#24292E">: </span><span style="color:#032F62">test</span></span>
-<span class="line"><span style="color:#22863A"> image</span><span style="color:#24292E">: </span><span style="color:#032F62">alpine:latest</span></span>
-<span class="line"><span style="color:#22863A"> script</span><span style="color:#24292E">:</span></span>
-<span class="line"><span style="color:#032F62">+ - 'set +o pipefail'</span></span>
-<span class="line"><span style="color:#24292E"> - </span><span style="color:#032F62">'cat hoge.txt | grep piyo | sed -e "s/foo/bar/g"'</span></span>
-<span class="line"><span style="color:#032F62">+ - 'set -o pipefail'</span><span style="color:#6A737D"> # この例の場合、ここで終わりなので戻さなくてもよい</span></span>
-<span class="line"><span style="color:#22863A"> rules</span><span style="color:#24292E">:</span></span>
-<span class="line"><span style="color:#24292E"> - </span><span style="color:#22863A">if</span><span style="color:#24292E">: </span><span style="color:#032F62">'$CI_MERGE_REQUEST_IID'</span></span>
-<span class="line"><span style="color:#22863A"> when</span><span style="color:#24292E">: </span><span style="color:#032F62">always</span></span></code></pre>
- </div>
- </section>
- <section id="section--remarks">
- <h2><a href="#section--remarks">備考</a></h2>
- <p>
- なお、上述した実装ファイルは <code>shells/bash.go</code> だが、<code>alpine:latest</code> の例でもそうであったように、シェルが <code>sh</code> である場合にも適用される。
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2024-04-29/zsh-file-completion-for-composer-custom-commands/index.html b/vhosts/blog/public/posts/2024-04-29/zsh-file-completion-for-composer-custom-commands/index.html
deleted file mode 100644
index 3262c137..00000000
--- a/vhosts/blog/public/posts/2024-04-29/zsh-file-completion-for-composer-custom-commands/index.html
+++ /dev/null
@@ -1,147 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="Zsh の Composer に対する補完はカスタムコマンドやその引数を補完しない。カスタムコマンドの引数としてファイルを補完させる方法を調べた。">
- <meta name="keywords" content="Composer,PHP,Zsh">
- <meta property="og:type" content="article">
- <meta property="og:title" content="【Zsh】 Composer のカスタムコマンドに対する Zsh 補完で引数にファイルを補完させる|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="Zsh の Composer に対する補完はカスタムコマンドやその引数を補完しない。カスタムコマンドの引数としてファイルを補完させる方法を調べた。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>【Zsh】 Composer のカスタムコマンドに対する Zsh 補完で引数にファイルを補完させる|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">【Zsh】 Composer のカスタムコマンドに対する Zsh 補完で引数にファイルを補完させる</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/composer/">Composer</a>
- </li>
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/zsh/">Zsh</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2024-04-29">2024-04-29</time>: 公開
- </li>
- </ol>
- </section>
- <section id="section--version-info">
- <h2><a href="#section--version-info">バージョン情報</a></h2>
- <ul>
- <li>
- Composer: 2.7.4
- </li>
- <li>
- PHP: 8.3.6
- </li>
- <li>
- Zsh: 5.9
- </li>
- </ul>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- <a href="https://getcomposer.org/" rel="noreferrer" target="_blank">Composer</a> は PHP のデファクトスタンダードなパッケージマネージャである。Zsh では、<code>composer</code> コマンドに対する補完が提供されており、<code>composer</code> と入力してタブキーを押すと、利用可能なコマンドやオプションが補完される。Zsh の補完はシェル関数の形で実装されており、<code>composer</code> コマンドに対応した補完をおこなうのは <code>_composer</code> である。<a href="https://github.com/zsh-users/zsh/blob/a66e92918568881af110a3e2e3018b317c054e4a/Completion/Unix/Command/_composer" rel="noreferrer" target="_blank">記事執筆時点での補完関数の定義は、GitHub のミラーリポジトリから参照できる。</a>
- </p>
- </section>
- <section id="section--problem">
- <h2><a href="#section--problem">発生していた問題</a></h2>
- <p>
- <code>composer</code> コマンドはカスタムコマンド (<code>composer.json</code> の <code>scripts</code> で定義されたコマンド) に対して補完をおこなわない。つまり、途中まで入力されたカスタムコマンドを補完しないし、カスタムコマンドの引数も補完しない。例えば、PHPUnit を呼び出す <code>phpunit</code> というカスタムコマンドを定義し <code>composer phpu</code> まで打ってタブキーを押しても、<code>composer phpunit</code> にはならない。また、<code>composer phpunit -- --</code> まで打ってタブキーを押しても、<code>phpunit</code> コマンドのオプションは補完されない。
- </p>
- <p>
- このことは、先ほどリンクを載せた <code>_composer</code> 関数を定義しているファイルの冒頭にも書かれている。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6A737D"># - @todo We don't complete custom commands (including script aliases). This is</span></span>
-<span class="line"><span style="color:#6A737D"># easy to do in the general case, but it probably requires some clever caching</span></span>
-<span class="line"><span style="color:#6A737D"># to avoid introducing a noticeable lag to every completion operation, due to</span></span>
-<span class="line"><span style="color:#6A737D"># the way command resolution works and the fact that discovering custom</span></span>
-<span class="line"><span style="color:#6A737D"># commands requires making slow calls to Composer</span></span></code></pre>
- </div>
- </section>
- <section id="section--what-i-want-to-achive">
- <h2><a href="#section--what-i-want-to-achive">やりたいこと</a></h2>
- <p>
- 確かに、カスタムコマンドに対して完全な補完を提供するのは不可能か、あるいは実現できても遅くなりすぎるだろう。しかし、不完全なフォールバックを提供するくらいなら可能なはずだ。
- </p>
- <p>
- この記事では、これらのカスタムコマンドについて、Zsh が提供するデフォルトのファイル・ディレクトリ補完を適用する。つまり、<code>composer phpunit -- tests/</code> まで打ってタブキーを押すと、<code>tests</code> ディレクトリの下にあるテストファイルまたはディレクトリが補完される。
- </p>
- </section>
- <section id="section--solution">
- <h2><a href="#section--solution">解決策</a></h2>
- <p>
- まずは、Zsh で補完関数を提供する場合のボイラープレートコードを書く。以下は <code>~/.zshrc</code> にすべて書く前提だが、<code>autoload</code> を設定するなどすれば別ファイルに分離できる (詳細な手順は割愛)。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6F42C1">compdef</span><span style="color:#032F62"> _my_composer</span><span style="color:#032F62"> composer</span><span style="color:#032F62"> composer.phar</span></span></code></pre>
- </div>
- <p>
- <code>compdef</code> は Zsh が用意している関数で、第一引数に補完関数の名前、第二引数以降に補完を適用するコマンド名を並べる。この場合は、<code>composer</code> コマンドや <code>composer.phar</code> コマンドに対して <code>_my_composer</code> を使って補完をおこなうよう定義している。
- </p>
- <p>
- 次に <code>_my_composer</code> を定義する。基本的にはデフォルトの <code>composer</code> コマンドの補完関数 (つまり <code>_composer</code> 関数) を使い、それが何も返さなかった場合に限り、Zsh のファイル・ディレクトリ補完へフォールバックする。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">function</span><span style="color:#6F42C1"> _my_composer</span><span style="color:#24292E">() {</span></span>
-<span class="line"><span style="color:#6F42C1"> _composer</span><span style="color:#032F62"> "</span><span style="color:#005CC5">$@</span><span style="color:#032F62">"</span><span style="color:#D73A49"> ||</span><span style="color:#6F42C1"> _files</span><span style="color:#032F62"> "</span><span style="color:#005CC5">$@</span><span style="color:#032F62">"</span></span>
-<span class="line"><span style="color:#24292E">}</span></span></code></pre>
- </div>
- <p>
- <code>_composer</code> コマンドは何も補完候補がなかったとき非ゼロな exit status で終了するので、そうであったなら <code>_files</code> を呼び出す。<code>_files</code> は、Zsh がデフォルトで用意しているファイル・ディレクトリの補完をおこなう関数である。
- </p>
- </section>
- <section id="section--conclusion">
- <h2><a href="#section--conclusion">まとめ</a></h2>
- <p>
- これらの設定をおこなうことで、部分的ながら Composer のカスタムコマンドに対して補完をおこなうことができる。特に、PHPUnit や PHPStan などの対象ファイル・ディレクトリを引数に取るようなコマンドを使う場合に有用であろう。
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2024-05-11/phpconkagawa-2024-report/index.html b/vhosts/blog/public/posts/2024-05-11/phpconkagawa-2024-report/index.html
deleted file mode 100644
index 58395722..00000000
--- a/vhosts/blog/public/posts/2024-05-11/phpconkagawa-2024-report/index.html
+++ /dev/null
@@ -1,163 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="2024-05-11 に開催された、PHP カンファレンス香川 2024 に参加した。">
- <meta name="keywords" content="カンファレンス,PHP,PHP カンファレンス香川">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHP カンファレンス香川 2024 参加レポ|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="2024-05-11 に開催された、PHP カンファレンス香川 2024 に参加した。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHP カンファレンス香川 2024 参加レポ|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">PHP カンファレンス香川 2024 参加レポ</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/conference/">カンファレンス</a>
- </li>
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phpconkagawa/">PHP カンファレンス香川</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2024-05-11">2024-05-11</time>: 公開
- </li>
- </ol>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- 2024-05-11 に開催された <a href="https://phpcon.kagawa.jp/2024/" rel="noreferrer" target="_blank">PHP カンファレンス香川 2024</a> に参加した。
- </p>
- </section>
- <section id="section--session-thoughts">
- <h2><a href="#section--session-thoughts">セッション感想</a></h2>
- <ul>
- <li>
- 泥まみれの技術革新: あなたの[ PHPバージョンアップ | 新フレームワーク採用 | アーキテクチャ刷新 | … ]を後押しするために by nrslib
- <ul>
- <li>
- fortee URL: <a href="https://fortee.jp/phpconkagawa-2024/proposal/7f4622af-03b6-4b83-a0ef-e1cfc7b7c930" rel="noreferrer" target="_blank">https://fortee.jp/phpconkagawa-2024/proposal/7f4622af-03b6-4b83-a0ef-e1cfc7b7c930</a>
- </li>
- <li>
- 感想: ちょうどとあるマイグレーション作業をしているので、頷きながら拝聴しました。結局は誰しも移行作業は根気と腕力なのだということに勇気をもらえました。
- </li>
- </ul>
- </li>
- <li>
- PHP 9 に備えよ - 動的プロパティ、どうすればいぃ? by 荒瀬 泰輔
- <ul>
- <li>
- fortee URL: <a href="https://fortee.jp/phpconkagawa-2024/proposal/039ebb21-d104-4df2-86bb-be2680979b7b" rel="noreferrer" target="_blank">https://fortee.jp/phpconkagawa-2024/proposal/039ebb21-d104-4df2-86bb-be2680979b7b</a>
- </li>
- <li>
- 感想: これも上と同じく移行作業の話ではあり、結局のところは「頑張って地道にやっていく」しかないところもあります (とはいえこちらは静的解析である程度潰せますが)。PHP 言語のコミュニティ全体で頑張っていきましょう。
- </li>
- </ul>
- </li>
- <li>
- 1人プロ・ペアプロ・モブプロの効果的な使い分け by まきまき
- <ul>
- <li>
- fortee URL: <a href="https://fortee.jp/phpconkagawa-2024/proposal/db3e9634-4a79-46c1-84fd-8ffa4d495a13" rel="noreferrer" target="_blank">https://fortee.jp/phpconkagawa-2024/proposal/db3e9634-4a79-46c1-84fd-8ffa4d495a13</a>
- </li>
- <li>
- 感想: 今会社でペアプロを部分的に取り入れているものの、迷うところが多く、楽しみにしていた発表です。まずは何か一つ変えないことには始まらないので、発表から得たヒントを自分たちのチームに反映すべく、何かやりかたを変えてみる予定です。
- </li>
- </ul>
- </li>
- <li>
- mb_trim関数を作りました - PHPに新しい関数を追加しました - by てきめん
- <ul>
- <li>
- fortee URL: <a href="https://fortee.jp/phpconkagawa-2024/proposal/0ec36f50-c4b7-4aa4-abef-006f8bab3931" rel="noreferrer" target="_blank">https://fortee.jp/phpconkagawa-2024/proposal/0ec36f50-c4b7-4aa4-abef-006f8bab3931</a>
- </li>
- <li>
- 感想: RFC を必要とするような機能追加のプロセスを日本語で解説する資料がどんどんと増えていくのは、ハードルを下げるという意味で非常にありがたいです。私も以前から出そう出そうと考えている書きかけの RFC があるのですが、具体的なプロセスが明示されるとやはりやる気になりますね。
- </li>
- </ul>
- </li>
- <li>
- (「PHPカンファレンス小田原2024」を実行委員長がふりかえる by asumikam)
- <ul>
- <li>
- fortee URL: <a href="https://fortee.jp/phpconkagawa-2024/proposal/c1efd828-72c9-4719-93f7-2ca3f8f20ac1" rel="noreferrer" target="_blank">https://fortee.jp/phpconkagawa-2024/proposal/c1efd828-72c9-4719-93f7-2ca3f8f20ac1</a>
- </li>
- <li>
- 備考: ちょっとしたトラブルにより午前中の発表が見られなかったので、生で拝聴したわけではなく、スライドを拝見して感想を書いています。
- </li>
- <li>
- 感想: Thanks のスライド非常に嬉しかったです。こちらこそ素晴らしいカンファレンスの場をありがとうございました!スタッフ募集あれば来年も是非参加させてください。
- </li>
- </ul>
- </li>
- </ul>
- </section>
- <section id="section--lightning-talk">
- <h2><a href="#section--lightning-talk">懇親会 LT</a></h2>
- <p>
- 今回登壇者ではなかったのだが、プロポーザル募集時に用意していたスライド (LT 用に作っていたのだが、そもそも LT 枠がなかったのでお蔵入りになっていた) があったので懇親会の LT で発表した。
- </p>
- <p>
- 中身は <a href="/slides/2023-03-15/phpstudy-tokyo-150/">第150回PHP勉強会@東京で登壇した内容</a> とほぼ同じで、タイトルを「うどんのように細長い FizzBuzz を書く」にしただけの手抜き・一発ネタ発表である。個別にスライドはアップロードしないので、前述のリンクを参照してほしい。
- </p>
- <p>
- なお、この発表には <a href="/posts/2022-09-29/write-fizzbuzz-in-php-2-letters-per-line/">ブログ記事バージョン</a> もある。
- </p>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">おわりに</a></h2>
- <p>
- 午前中の発表に間に合わなかったことがとにかく心残りなのだが、それ以外は PHP カンファレンス小田原のスタッフの方々をはじめ多くの方と交流でき、非常に楽しいカンファレンスだった。来年もあるそうなので (この分だと来年も月刊 PHP カンファレンスにならないか?)、是非参加したい。
- </p>
- <p>
- あれ、そういえば香川でうどん食べてないな……。
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2024-06-19/scalamatsuri-2024-report/index.html b/vhosts/blog/public/posts/2024-06-19/scalamatsuri-2024-report/index.html
deleted file mode 100644
index d1adbb16..00000000
--- a/vhosts/blog/public/posts/2024-06-19/scalamatsuri-2024-report/index.html
+++ /dev/null
@@ -1,126 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="2024-06-08 から 2024-06-09 にかけて開催された、ScalaMatsuri 2024 に参加した。">
- <meta name="keywords" content="カンファレンス,Scala,ScalaMatsuri">
- <meta property="og:type" content="article">
- <meta property="og:title" content="ScalaMatsuri 2024 参加レポ|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="2024-06-08 から 2024-06-09 にかけて開催された、ScalaMatsuri 2024 に参加した。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>ScalaMatsuri 2024 参加レポ|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">ScalaMatsuri 2024 参加レポ</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/conference/">カンファレンス</a>
- </li>
- <li class="tag">
- <a href="/tags/scala/">Scala</a>
- </li>
- <li class="tag">
- <a href="/tags/scalamatsuri/">ScalaMatsuri</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2024-06-19">2024-06-19</time>: 公開
- </li>
- </ol>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- 2024-06-08 から 2024-06-09 にかけて開催された <a href="https://2024.scalamatsuri.org/ja" rel="noreferrer" target="_blank">ScalaMatsuri 2024</a> に参加した。
- </p>
- <p>
- Day 2 には当日参加できなかったため、day 2 のセッションの感想は YouTube にアップロードされたアーカイブ動画を観て書いている。
- </p>
- </section>
- <section id="section--sessions">
- <h2><a href="#section--sessions">セッション感想</a></h2>
- <p>
- 特に印象に残ったセッションを、day 1 と day 2 で一つずつ選んだ (タイトルと登壇者名は <a href="https://2024.scalamatsuri.org/ja/programs" rel="noreferrer" target="_blank">公式ホームページの「プログラム」</a> から引用)。
- </p>
- <ul>
- <li>
- <a href="https://2024.scalamatsuri.org/ja/programs/SESSION_DAY_1_02" rel="noreferrer" target="_blank">Scala to WebAssembly: 動機と方法</a> (Rikito Taniguchi さん)
- <ul>
- <li>
- <a href="/posts/2024-03-17/phperkaigi-2024-report/#section--as-speaker">最近 WebAssembly の処理系を作った</a> こともあって、気になっていたセッションです。私の処理系は WasmGC proposal を実装していないので動かせないのですが、いつかサポートして動かしてみたいですね。
- </li>
- </ul>
- </li>
- <li>
- <a href="https://2024.scalamatsuri.org/ja/programs/SESSION_DAY_2_04" rel="noreferrer" target="_blank">作って学ぶ Extensible Effects</a> (Kory さん・hsjoihs さん)
- <ul>
- <li>
- 今回一番楽しみにしていたセッションです。Day 2 当日は参加できず、後日アーカイブ動画を視聴したのですが、期待を裏切らない濃厚なセッションでした。後日開かれた <a href="https://nextbeat.connpass.com/event/315988/" rel="noreferrer" target="_blank">NB-Scala レトロスペクティブ (非公式後夜祭)</a> の発表も拝聴したのですが、どちらも非常に面白かったです。
- </li>
- </ul>
- </li>
- </ul>
- </section>
- <section id="section--others">
- <h2><a href="#section--others">その他感想</a></h2>
- <ul>
- <li>
- 良い会場だった。よく取り沙汰されるスライドの文字サイズの問題は、巨大なスクリーンを用意することで解決するという発見があった
- </li>
- <li>
- ランチにお弁当が用意されており、おいしかった ( <a href="https://x.com/nsfisis/status/1799276217583260092" rel="noreferrer" target="_blank">参考画像</a> )
- </li>
- </ul>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">おわりに</a></h2>
- <p>
- 私が Scala を書いたり追ったりしていたのは Scala 2 の頃で、Scala 3 はほとんど浦島太郎状態だったのだが、非常に楽しく面白いイベントだった。イベントに触発されて、長らく塩漬けになっていた Scala 製の趣味プロジェクトを久しぶりに触っているのだが、これもまた楽しい。
- </p>
- <p>
- ScalaMatsuri 運営の皆さま、スピーカーの皆さま、スポンサーの皆さま、最高のイベントをありがとうございました!次回も楽しみにしています。
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2024-07-19/reparojson-fix-only-json-formatter/index.html b/vhosts/blog/public/posts/2024-07-19/reparojson-fix-only-json-formatter/index.html
deleted file mode 100644
index f191ebeb..00000000
--- a/vhosts/blog/public/posts/2024-07-19/reparojson-fix-only-json-formatter/index.html
+++ /dev/null
@@ -1,205 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="文法エラーだけを直し、空白の削除や挿入といった整形処理を一切おこなわない JSON フォーマッタを作成した。Neovim と連携させる設定例も紹介する。">
- <meta name="keywords" content="Neovim,Vim">
- <meta property="og:type" content="article">
- <meta property="og:title" content="reparojson: 文法エラーを直すだけの JSON フォーマッタを作った|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="文法エラーだけを直し、空白の削除や挿入といった整形処理を一切おこなわない JSON フォーマッタを作成した。Neovim と連携させる設定例も紹介する。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>reparojson: 文法エラーを直すだけの JSON フォーマッタを作った|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">reparojson: 文法エラーを直すだけの JSON フォーマッタを作った</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/neovim/">Neovim</a>
- </li>
- <li class="tag">
- <a href="/tags/vim/">Vim</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2024-07-19">2024-07-19</time>: 公開
- </li>
- </ol>
- </section>
- <div class="admonition">
- <div class="admonition-label">
- NOTE
- </div>
- <div class="admonition-content">
- <p>
- この記事は <a href="https://vim-jp.org/ekiden/" rel="noreferrer" target="_blank">Vim 駅伝</a> #218 の記事です。
- </p>
- </div>
- </div>
- <section id="section--intro">
- <h2><a href="#section--intro">欲しかったもの</a></h2>
- <p>
- Vim で JSON を編集しているときに、文法エラー (末尾カンマやカンマの不足) のみを修正して一切の整形をおこなわないプラグインが欲しかった。整形も同時におこなうプラグインは見つかっただけでも多数あったのだが、整形しないものは見つけられなかったので自作することにした。
- </p>
- <p>
- なお、作成したツール自体は単体の CLI として動作し、Vim とは無関係に使うことができる。この記事では Neovim と組み合わせる場合の設定を紹介するが、およそ任意のエディタで使えるだろう。
- </p>
- </section>
- <section id="section--reparojson">
- <h2><a href="#section--reparojson">作ったもの</a></h2>
- <p>
- 作成したものがこちら: <a href="https://github.com/nsfisis/reparojson" rel="noreferrer" target="_blank">ReparoJSON</a>
- </p>
- <p>
- 次のように動作する。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ echo '[ 1 2 ]' | reparojson</span></span>
-<span class="line"><span>[ 1, 2 ]</span></span>
-<span class="line"><span></span></span>
-<span class="line"><span>$ echo '[ 1, 2, ]' | reparojson</span></span>
-<span class="line"><span>[ 1, 2 ]</span></span>
-<span class="line"><span></span></span>
-<span class="line"><span>$ echo '{ "foo": 1 "bar": 2 }' | reparojson</span></span>
-<span class="line"><span>{ "foo": 1, "bar": 2 }</span></span>
-<span class="line"><span></span></span>
-<span class="line"><span>$ echo '{ "foo": 1, "bar": 2, }' | reparojson</span></span>
-<span class="line"><span>{ "foo": 1, "bar": 2 }</span></span></code></pre>
- </div>
- <p>
- バージョン 0.1.1 時点で修正対象の文法エラーは次のとおり:
- </p>
- <ul>
- <li>
- 配列末尾の余計なカンマ (削除する)
- </li>
- <li>
- 配列内のカンマ不足 (挿入する)
- </li>
- <li>
- オブジェクト末尾の余計なカンマ (削除する)
- </li>
- <li>
- オブジェクト内のカンマ不足 (挿入する)
- </li>
- </ul>
- <p>
- 他にも自動で直せそうなエラーはいくつか思いつくが (オブジェクトのキーがクォートされていない等)、私自身があまり困っていないので優先度は低い。
- </p>
- </section>
- <section id="section--itegration-with-neovim">
- <h2><a href="#section--itegration-with-neovim">Neovim との連携</a></h2>
- <p>
- Neovim で JSON ファイルを保存したときに、上記のツールを自動で走らせるように設定する。
- </p>
- <p>
- ここでは、 <a href="https://github.com/neovim/nvim-lspconfig" rel="noreferrer" target="_blank">nvim-lspconfig</a> と <a href="https://github.com/mattn/efm-langserver" rel="noreferrer" target="_blank">efm-langserver</a> を用いた設定例を紹介する。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49"> local</span><span style="color:#24292E"> lspconfig </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> require</span><span style="color:#24292E">(</span><span style="color:#032F62">'lspconfig'</span><span style="color:#24292E">)</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E"> lspconfig.</span><span style="color:#6F42C1">efm</span><span style="color:#24292E">.</span><span style="color:#005CC5">setup</span><span style="color:#24292E">({</span></span>
-<span class="line"><span style="color:#24292E"> init_options </span><span style="color:#D73A49">=</span><span style="color:#24292E"> { documentFormatting </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> true</span><span style="color:#24292E"> },</span></span>
-<span class="line"><span style="color:#24292E"> settings </span><span style="color:#D73A49">=</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#24292E"> rootMarkers </span><span style="color:#D73A49">=</span><span style="color:#24292E"> {</span><span style="color:#032F62">".git/"</span><span style="color:#24292E">},</span></span>
-<span class="line"><span style="color:#24292E"> languages </span><span style="color:#D73A49">=</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#24292E"> json </span><span style="color:#D73A49">=</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#24292E"> formatCommand </span><span style="color:#D73A49">=</span><span style="color:#032F62"> "reparojson -q"</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#24292E"> formatStdin </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> true</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#24292E"> },</span></span>
-<span class="line"><span style="color:#24292E"> },</span></span>
-<span class="line"><span style="color:#24292E"> },</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#24292E"> })</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#24292E"> vim.</span><span style="color:#6F42C1">api</span><span style="color:#24292E">.</span><span style="color:#005CC5">nvim_create_autocmd</span><span style="color:#24292E">(</span><span style="color:#032F62">'LspAttach'</span><span style="color:#24292E">, {</span></span>
-<span class="line"><span style="color:#6F42C1"> callback</span><span style="color:#D73A49"> =</span><span style="color:#D73A49"> function</span><span style="color:#24292E">(e)</span></span>
-<span class="line"><span style="color:#24292E"> vim.</span><span style="color:#6F42C1">api</span><span style="color:#24292E">.</span><span style="color:#005CC5">nvim_create_autocmd</span><span style="color:#24292E">(</span><span style="color:#032F62">'BufWritePre'</span><span style="color:#24292E">, {</span></span>
-<span class="line"><span style="color:#24292E"> buffer </span><span style="color:#D73A49">=</span><span style="color:#24292E"> e.</span><span style="color:#6F42C1">buf</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#6F42C1"> callback</span><span style="color:#D73A49"> =</span><span style="color:#D73A49"> function</span><span style="color:#24292E">()</span></span>
-<span class="line"><span style="color:#24292E"> vim.</span><span style="color:#6F42C1">lsp</span><span style="color:#24292E">.</span><span style="color:#6F42C1">buf</span><span style="color:#24292E">.</span><span style="color:#005CC5">format</span><span style="color:#24292E">({ async </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> false</span><span style="color:#24292E"> })</span></span>
-<span class="line"><span style="color:#D73A49"> end</span></span>
-<span class="line"><span style="color:#24292E"> })</span></span>
-<span class="line"><span style="color:#D73A49"> end</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#24292E"> })</span></span></code></pre>
- </div>
- <p>
- ほとんどは nvim-lspconfig と efm-langserver を使う際のボイラープレートだが、<code>formatCommand</code> で <code>-q</code> フラグを指定していることに注意してほしい。このツールは、デフォルトでは JSON が修正された場合 exit code 1 で終了する。これは、入力が最初から正しかった場合と修正して正しくなった場合を区別するためだが、異常終了してしまうと置き換えが発生しない。そのため、<code>-q</code> フラグを指定して、修正されたときも exit code 0 で終了するようにしている。
- </p>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">おわりに</a></h2>
- <p>
- このツールが威力を発揮するのは、行の入れ換え時である。次のような JSON があり、
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#005CC5"> "a"</span><span style="color:#24292E">: </span><span style="color:#005CC5">true</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#005CC5"> "b"</span><span style="color:#24292E">: </span><span style="color:#005CC5">false</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span></code></pre>
- </div>
- <p>
- 2行目と3行目を入れ換えて以下のように編集した。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#005CC5"> "b"</span><span style="color:#24292E">: </span><span style="color:#005CC5">false</span></span>
-<span class="line"><span style="color:#032F62"> "a"</span><span style="color:#B31D28;font-style:italic">:</span><span style="color:#005CC5"> true</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span></code></pre>
- </div>
- <p>
- これは不正な JSON だが、このツールを通せば次のようになる。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#005CC5"> "b"</span><span style="color:#24292E">: </span><span style="color:#005CC5">false</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#005CC5"> "a"</span><span style="color:#24292E">: </span><span style="color:#005CC5">true</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span></code></pre>
- </div>
- <p>
- もちろん、このような操作を文法を壊さずにおこなう Vim プラグインは存在する。しかし、単なる行の入れ換えであれば <code>ddp</code> の3ストロークでおこなうことができ、専用のキーバインドを覚える必要もない。このツールを用いることで、より Vimmer-friendly な JSON 編集が可能となる。
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2024-08-19/go-template-access-outer-scope-pipeline-within-with-or-range/index.html b/vhosts/blog/public/posts/2024-08-19/go-template-access-outer-scope-pipeline-within-with-or-range/index.html
deleted file mode 100644
index 39450d30..00000000
--- a/vhosts/blog/public/posts/2024-08-19/go-template-access-outer-scope-pipeline-within-with-or-range/index.html
+++ /dev/null
@@ -1,184 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="Go言語の text/template における with や range は &quot;.&quot; を上書きする。これらの内側から外側の &quot;.&quot; にアクセスする方法を調べた。">
- <meta name="keywords" content="Go">
- <meta property="og:type" content="article">
- <meta property="og:title" content="【Go】 text/template の with や range の内側から外側の &quot;.&quot; にアクセスする|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="Go言語の text/template における with や range は &quot;.&quot; を上書きする。これらの内側から外側の &quot;.&quot; にアクセスする方法を調べた。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>【Go】 text/template の with や range の内側から外側の &quot;.&quot; にアクセスする|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">【Go】 text/template の with や range の内側から外側の &quot;.&quot; にアクセスする</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/go/">Go</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2024-08-19">2024-08-19</time>: 公開
- </li>
- </ol>
- </section>
- <section id="section--tldr">
- <h2><a href="#section--tldr">TL;DR</a></h2>
- <p>
- 常にトップレベルを指す特殊変数 <code>$</code> を使えばよい。
- </p>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- Go には、標準ライブラリにテンプレートライブラリ <code>text/template</code> がある。この <code>text/template</code> における制御構造、<code>with</code> と <code>range</code> は次のように使われる。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span># {{ .Title }}</span></span>
-<span class="line"><span></span></span>
-<span class="line"><span># User</span></span>
-<span class="line"><span></span></span>
-<span class="line"><span>{{ with .User }}</span></span>
-<span class="line"><span> {{ .Name }} ({{ .ID }})</span></span>
-<span class="line"><span>{{ end }}</span></span>
-<span class="line"><span></span></span>
-<span class="line"><span># Items</span></span>
-<span class="line"><span></span></span>
-<span class="line"><span>{{ range .Items }}</span></span>
-<span class="line"><span> - {{ . }}</span></span>
-<span class="line"><span>{{ end }}</span></span></code></pre>
- </div>
- <p>
- <code>text/template</code> の <code>.</code> は、現在の操作対象を表す特殊なオブジェクトである。
- </p>
- <p>
- <code>with</code> や <code>range</code> は、<code>.</code> を変更する効果を持つ。<code>with</code> は引数に渡されたオブジェクトを <code>.</code> へセットして、内部のテンプレートを実行する。<code>range</code> は引数に渡されたイテレート可能なオブジェクトに対し、それぞれの要素を <code>.</code> へセットして、要素の個数だけ内部のテンプレートを実行する。
- </p>
- <p>
- つまりこのテンプレートは、次のような構造をレンダリングしている (<code>Execute()</code> の第2引数)。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">tmpl.</span><span style="color:#6F42C1">Execute</span><span style="color:#24292E">(out, </span><span style="color:#6F42C1">Params</span><span style="color:#24292E">{</span></span>
-<span class="line"><span style="color:#24292E"> Title: </span><span style="color:#032F62">"foo"</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#24292E"> User: </span><span style="color:#6F42C1">User</span><span style="color:#24292E">{</span></span>
-<span class="line"><span style="color:#24292E"> ID: </span><span style="color:#005CC5">123</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#24292E"> Name: </span><span style="color:#032F62">"john"</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#24292E"> },</span></span>
-<span class="line"><span style="color:#24292E"> Items: []</span><span style="color:#D73A49">string</span><span style="color:#24292E">{</span></span>
-<span class="line"><span style="color:#032F62"> "hoge"</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#032F62"> "piyo"</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#032F62"> "fuga"</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#24292E"> },</span></span>
-<span class="line"><span style="color:#24292E">})</span></span></code></pre>
- </div>
- </section>
- <section id="section--what-i-want-to-do">
- <h2><a href="#section--what-i-want-to-do">やりたいこと</a></h2>
- <p>
- 今回おこないたいのは、<code>with</code> や <code>range</code> の中で、その外側で使われていたトップレベルのオブジェクトを参照することだ。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>{{ with .User }}</span></span>
-<span class="line"><span> ここから .Title を参照するには?</span></span>
-<span class="line"><span>{{ end }}</span></span>
-<span class="line"><span></span></span>
-<span class="line"><span>{{ range .Items }}</span></span>
-<span class="line"><span> ここから .User を参照するには?</span></span>
-<span class="line"><span>{{ end }}</span></span></code></pre>
- </div>
- <p>
- <code>with</code> や <code>range</code> は、<code>.</code> を自身の対象オブジェクトに変更するので、単に <code>{{ with .User }}</code> の中で <code>.Title</code> と書いても、それは <code>User</code> の <code>Title</code> プロパティを参照しているとみなされる。
- </p>
- <p>
- <code>text/template</code> では変数が使えるので、テンプレートの先頭で
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>{{ $params := . }}</span></span></code></pre>
- </div>
- <p>
- とでもしておけば実現は可能である。
- </p>
- <p>
- しかしながら、頻発するシチュエーションにしてはあまりに不恰好である。よりスマートな方法が用意されているはずだ。
- </p>
- </section>
- <section id="section--solution">
- <h2><a href="#section--solution">解決方法</a></h2>
- <p>
- 常にトップレベルを指す特殊変数 <code>$</code> を使えばよい。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>{{ with .User }}</span></span>
-<span class="line"><span> {{ $.Title }}</span></span>
-<span class="line"><span>{{ end }}</span></span>
-<span class="line"><span></span></span>
-<span class="line"><span>{{ range .Items }}</span></span>
-<span class="line"><span> {{ $.User.Name }}</span></span>
-<span class="line"><span>{{ end }}</span></span></code></pre>
- </div>
- <p>
- <code>$</code> は、テンプレートが実行されるときに渡されたオブジェクトを指す。これを使えば現在の <code>.</code> に関係なくトップレベルを参照できる。
- </p>
- <p>
- このことは、<a href="https://pkg.go.dev/text/template#hdr-Variables" rel="noreferrer" target="_blank"><code>text/template</code> の公式ドキュメント</a>にも以下のように記載されている。
- </p>
- <blockquote>
- <p>
- When execution begins, $ is set to the data argument passed to Execute, that is, to the starting value of dot.
- </p>
- </blockquote>
- </section>
- <section id="section--reference">
- <h2><a href="#section--reference">参考</a></h2>
- <ul>
- <li>
- <a href="https://stackoverflow.com/questions/14800204/in-a-template-how-do-you-access-an-outer-scope-while-inside-of-a-with-or-rang" rel="noreferrer" target="_blank">直接の出典である Stack Overflow の回答: <span>In a template how do you access an outer scope while inside of a “with” or “range” scope?</span></a>
- </li>
- <li>
- <a href="https://pkg.go.dev/text/template#hdr-Variables" rel="noreferrer" target="_blank">大元の出典である <code>text/template</code> の公式ドキュメント</a>
- </li>
- </ul>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2024-09-28/mncore-challenge-1/index.html b/vhosts/blog/public/posts/2024-09-28/mncore-challenge-1/index.html
deleted file mode 100644
index 23d77a20..00000000
--- a/vhosts/blog/public/posts/2024-09-28/mncore-challenge-1/index.html
+++ /dev/null
@@ -1,104 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="2024-08-28 から 2024-09-24 にかけて開催された MN-Core Challenge #1 に参加した。">
- <meta name="keywords" content="MN-Core Challenge">
- <meta property="og:type" content="article">
- <meta property="og:title" content="MN-Core Challenge #1 参加レポ|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="2024-08-28 から 2024-09-24 にかけて開催された MN-Core Challenge #1 に参加した。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>MN-Core Challenge #1 参加レポ|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">MN-Core Challenge #1 参加レポ</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/mncore-challenge/">MN-Core Challenge</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2024-09-28">2024-09-28</time>: 公開
- </li>
- </ol>
- </section>
- <div class="admonition">
- <div class="admonition-label">
- NOTE
- </div>
- <div class="admonition-content">
- <p>
- ただの参加記で解説はない。
- </p>
- </div>
- </div>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- 2024-08-28 から 2024-09-24 の約1ヶ月に渡り開催された <a href="https://mncore-challenge.preferred.jp/" rel="noreferrer" target="_blank">MN-Core Challenge #1</a> に参加した。私 nsfisis (<a href="https://x.com/nsfisis/status/1838276770560364977" rel="noreferrer" target="_blank">あるいは <code>0b0100000111111000</code></a>) はスコア 1181 で、最終順位 29 位だった。
- </p>
- <p>
- この記事で解説はしないが、提出した回答はこちらのリポジトリ (<a href="https://github.com/nsfisis/mncore-challenge" rel="noreferrer" target="_blank">GitHub: nsfisis/mncore-challenge</a>) にアップロードしている。
- </p>
- </section>
- <section id="section--thought">
- <h2><a href="#section--thought">感想</a></h2>
- <p>
- MN-Core には初めて触れたが、それでも問題なく全問 (除 FizzBuzz) 解けるよう線路が敷かれており、前半の問題を解くことで自然と後半を解くだけの知識が身に付くように設計されていた。
- </p>
- <p>
- 開催期間中はほぼ常に MN-Core Challenge のことを考え続けており、期間中 (前掲した回答を貯めるためのリポジトリを除き) 自分の Git リポジトリをほとんど触ることがなかった。途中更新ができずに苦しい時間もあったが、一つ気付くと一つ縮まる楽しいゴルフだった。
- </p>
- <p>
- 悔しいポイントも多数あるのだが、書いているとキリがないので自分で反省するだけにしておく。
- </p>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">おわりに</a></h2>
- <p>
- 最後になりましたが、運営のみなさま、素晴しいコンテストをありがとうございました!非常に楽しい時間でした!第2回を首を長くして待っています!
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2024-12-04/cohackpp-report/index.html b/vhosts/blog/public/posts/2024-12-04/cohackpp-report/index.html
deleted file mode 100644
index 9c05a78a..00000000
--- a/vhosts/blog/public/posts/2024-12-04/cohackpp-report/index.html
+++ /dev/null
@@ -1,266 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="2024-11-30 に開催された紅白ぺぱ合戦に参加し、ぺ陣営のメンバとして LT しました。">
- <meta name="keywords" content="紅白ぺぱ合戦,PHP">
- <meta property="og:type" content="article">
- <meta property="og:title" content="紅白ぺぱ合戦に参加&amp;LTしました|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="2024-11-30 に開催された紅白ぺぱ合戦に参加し、ぺ陣営のメンバとして LT しました。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>紅白ぺぱ合戦に参加&amp;LTしました|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">紅白ぺぱ合戦に参加&amp;LTしました</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/cohackpp/">紅白ぺぱ合戦</a>
- </li>
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2024-12-04">2024-12-04</time>: 公開
- </li>
- <li class="revision">
- <time datetime="2024-12-05">2024-12-05</time>: 「育てた」枠・「育てられた」枠を勘違いして逆に表記していたので修正
- </li>
- </ol>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- 2024-11-30 に開催された <a href="https://connpass.com/event/329428/" rel="noreferrer" target="_blank">紅白ぺぱ合戦</a> なる催しに参加しました。私は「ぺ」陣営のメンバとして LT をおこないました。
- </p>
- <p>
- 紅白ぺぱ合戦のイベントページにある説明を以下に引用します。
- </p>
- <blockquote>
- <p>
- Webエンジニアの <a href="https://x.com/asumikam" rel="noreferrer" target="_blank">asumikam</a> とWebエンジニアの <a href="https://x.com/stefafafan" rel="noreferrer" target="_blank">stefafafan</a> が2024年7月7日に結婚しました。
- </p>
- <p>
- せっかくなので技術トークとかで紅白戦をしませんか?いいですね!やっていきます!
- </p>
- <p>
- 場所はァ!小田原ァ!盛り上がっていきましょゥ!!!
- </p>
- </blockquote>
- <p>
- ざっくりと言えば、テックカンファレンスの形式をとった結婚披露宴です。タイトルの「ぺ」は PHPer、「ぱ」は Perl Monger の略です。
- </p>
- </section>
- <section id="section--thoughts">
- <h2><a href="#section--thoughts">感想</a></h2>
- <p>
- 私は「ぺ」陣営のスピーカーとして LT をしていたのですが、その前にまずは登壇以外の感想を。
- </p>
- <p>
- いや~最高でしたね。どの枠のスピーチの方も良かったのですが、特に (asumikam さん/stefafafan さんに)「育てられた」枠のお二方が印象に残っています。(asumikam さん/stefafafan さんを)「育てた」枠としてお世話になった方に声をかけることはできると思うんですよ。それだけでなく、「自分が育てたのだ」と言える人がいて、そしてそれに 100 点で応える人がいるということ。この素晴しさ。人徳。
- </p>
- <p>
- 改めて、asumikam さん、stefafafan さん、ご結婚おめでとうございます!
- </p>
- </section>
- <section id="section--lt">
- <h2><a href="#section--lt">LT</a></h2>
- <section id="section--lt--prepare">
- <h3><a href="#section--lt--prepare">合戦準備</a></h3>
- <p>
- さて、時を合戦の前に戻しまして、両陣営の登壇者が発表され徐々に謎のイベントの輪郭が見えてきた頃、asumikam さんから次のような連絡を受けました。
- </p>
- <p>
- <img alt="asumikam「いまむらさんおつかれさまです。ぺぱ合戦で、LTタイムあることになり、技術で3人「ぺ」側を選出することになったのですが、いまむらさん、LTやりませんか。「ぺ」陣営で一緒に頂きを目指しませんか。」nsfisis「OKです!」" src="/posts/2024-12-04/cohackpp-report/lt.png">
- </p>
- <p>
- 最初は直近のカンファレンスに出して落選したプロポーザルテーマを LT に編集して話そうとしていたのですが、この機会でなければ話せない・この機会で話すことに意味があるテーマにしようとネタ出しをおこない、最終的に次のテーマでの登壇となりました。
- </p>
- </section>
- <section id="section--lt--battle">
- <h3><a href="#section--lt--battle">いざ尋常に勝負</a></h3>
- <p>
- 当日は、「プログラミングマナー講座」と題して発表をおこないました。結婚式のマナー、特に「忌み言葉」へフォーカスし、これを無理やりプログラミングに適用するというものです。<a href="/slides/2024-11-30/cohackpp/">スライドはこちらにアップロードしています。</a>
- </p>
- <p>
- 最終的にお祝いのメッセージを仕込んだソースコードで締めるという構成は、我ながら綺麗にまとまったと思っています。忌み言葉の案は他にも大量にあったのですが、技術 LT かつ結婚祝いスピーチにするためにどうしても最後のソースコードが必要だったので、時間の関係上それらには犠牲となってもらいました ( <a href="https://x.com/nsfisis/status/1862798137452327206" rel="noreferrer" target="_blank">ボツになった案のひとつ</a> )。
- </p>
- <p>
- そもそも結婚式・披露宴でのスピーチ自体が初めてだったのでそれなりに緊張していたのですが、登壇時やその後の反応を伺う限り概ね好評だったようで良かったです。
- </p>
- </section>
- </section>
- <section id="section--congrats">
- <h2><a href="#section--congrats">ご結婚おめでとうございます</a></h2>
- <p>
- <a href="https://github.com/nsfisis/cohackpp/blob/main/congrats.php" rel="noreferrer" target="_blank">https://github.com/nsfisis/cohackpp/blob/main/congrats.php</a>
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span></span>
-<span class="line"><span style="color:#24292E">$s</span><span style="color:#D73A49">=</span><span style="color:#032F62">&#x3C;&#x3C;&#x3C;'</span><span style="color:#D73A49">Q</span><span style="color:#032F62">'</span></span>
-<span class="line"><span style="color:#032F62">&#x3C;?php</span></span>
-<span class="line"><span style="color:#032F62">%</span></span>
-<span class="line"><span style="color:#032F62">$s=&#x3C;&#x3C;&#x3C;'Q'</span></span>
-<span class="line"><span style="color:#032F62">@$c=[`];</span></span>
-<span class="line"><span style="color:#032F62">$m="";for($k=0;$k&#x3C;min(13,intdiv(__LINE__-119,80)+1);$k++){$C=str_replace("\n","",</span></span>
-<span class="line"><span style="color:#032F62">$c[$k]);$f=!0;foreach(str_split(base64_decode($C))as$l){$L=ord($l);$m.=str_repeat</span></span>
-<span class="line"><span style="color:#032F62">($f?"#":chr(32),$L&#x26;127);$f=!$f;if($L&#x26;128){$m.="\n";$f=!0;continue;}}}print(</span></span>
-<span class="line"><span style="color:#032F62">str_replace([chr(96),chr(37),chr(64)],[implode("\n",array_map(fn($C)=>"'".trim(</span></span>
-<span class="line"><span style="color:#032F62">chunk_split(str_replace("\n","",$C),80,"\n"))."',",$c)),"\n{$m}","{$s}\nQ;\n"],$s));</span></span>
-<span class="line"><span style="color:#D73A49">Q</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">$c</span><span style="color:#D73A49">=</span><span style="color:#24292E">[</span><span style="color:#032F62">'0AFOgQFOgQFOgQFOgQFOgQFEAgiBAUIECIEBQwQHgQE8AQYFBoEBOgQGBAaBAToEBwQFgQE6BQYFBIEB</span></span>
-<span class="line"><span style="color:#032F62">OwQHBASBATwEBgUDgQE8BQYEA4EBPQQGBAOBAT0FBgEFgQERBhsIBAQMgQERKQQFC4EBESkFAQ6BAREp</span></span>
-<span class="line"><span style="color:#032F62">FIEBESkUgQERKRSBAU6BAU6BAU6BAU6BAU6BAU6BAU6BAU6BAU6BAU6BAU6BAU6BAU6BAU6BAU6BAU6B</span></span>
-<span class="line"><span style="color:#032F62">AU6BAU6BAU6BAU6BAU6BAU6BAU6BAU6BAU6BAQ4EPIEBDQY7gQENBjuBAQ0GO4EBDQU8gQENBTyBAQwG</span></span>
-<span class="line"><span style="color:#032F62">PIEBDAY8gQEMBjyBAQwGPIEBDAY8gQEMBjyBAQwHO4EBDAc7gQENBzqBAQ0IOYEBDgg4gQEOCiUCD4EB</span></span>
-<span class="line"><span style="color:#032F62">DwwdBw+BARAQDhEPgQERLg+BARItD4EBFCsPgQEXJRKBARsbGIEBToEBToEBToEBToEBToHQ'</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#032F62">'0AFOgQFOgQFOgQEPASMFFoEBDwMhBRaBAQ4FIAUWgQEOBSAFFoEBDQUhBRaBAQ0FIQUWgQEMBSIFFoEB</span></span>
-<span class="line"><span style="color:#032F62">DAUiBRaBAQsFIwUWgQELBQgBGgUWgQEKBQkDGAUWgQEKBQgGBCoDgQEJBQkFBSoDgQEFAQMECQYFKgOB</span></span>
-<span class="line"><span style="color:#032F62">AQQDAQUJBQYqA4EBBAgJBQcqA4EBAwkJBRkFFoEBBAcJBRoFFoEBBQYIBRsFFoEBBgYHBRsFFoEBBwYF</span></span>
-<span class="line"><span style="color:#032F62">BRwFFoEBCAYDBR0FFoEBCQYCBR0FFoEBCgseBRaBAQsJHwUWgQEMByAFFoEBDAcFAxgFFoEBDQUFBBgF</span></span>
-<span class="line"><span style="color:#032F62">FoEBDQQGBRYGFoEBDAUHBAcmBYEBCwUIBQYmBYEBCwQKBAYmBYEBCgQLBQUmBYEBCQUMBS+BAQgFDAYv</span></span>
-<span class="line"><span style="color:#032F62">gQEDHC+BAQMdLoEBAx0ugQEDHi2BAQMJBAUIBC2BARAFCAQtgQEQBQgELYEBEAUJAS+BARAFESEHgQEQ</span></span>
-<span class="line"><span style="color:#032F62">BREhB4EBBwEIBQYBCiEHgQEHBAUFBAQJIQeBAQcEBQUEBAkEGAUHgQEGBQUFBAUIBBgFB4EBBgUFBQUE</span></span>
-<span class="line"><span style="color:#032F62">CAQYBQeBAQYFBQUFBAgEGAUHgQEGBAYFBQUHBBgFB4EBBgQGBQYEBwQYBQeBAQUFBgUGBQYEGAUHgQEF</span></span>
-<span class="line"><span style="color:#032F62">BQYFBwQGBBgFB4EBBQQHBQcEBgQYBQeBAQUEBwUHBQUEGAUHgQEEBQcFBwUFBBgFB4EBBAUHBQgEBQQY</span></span>
-<span class="line"><span style="color:#032F62">BQeBAQQECAUIBAUEGAUHgQEDBQgFCAEIBBgFB4EBAwUIBREEGAUHgQECBQkFEQQYBQeBAQIFCQURIQeB</span></span>
-<span class="line"><span style="color:#032F62">AQQCCgURIQeBARAFESEHgQEQBREhB4EBEAURIQeBARAFEQQYBQeBARAFEQQYBQeBARAFEQQYBQeBARAF</span></span>
-<span class="line"><span style="color:#032F62">EQQYBQeBAU6BAU6BAU6B0A=='</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#032F62">'0AFOgQFOgQFOgQEOAjEBDIEBDgUqBwqBAQ0FJwwJgQENBSETCIEBDQURAQcXDIEBDQURGxCBAQ0FERcU</span></span>
-<span class="line"><span style="color:#032F62">gQENBBIOBAUUgQEMBRIGDAUUgQEMBRIFDQUUgQEMBRIFDgQUgQEMBRIFDgQUgQEMBBMFDgQUgQELBRMF</span></span>
-<span class="line"><span style="color:#032F62">DgQUgQELBRMFDgUTgQELBRMFDgUTgQEDGQcFDgUTgQEDGwUoA4EBAxsFKAOBAQMbBSgDgQEDGwUoA4EB</span></span>
-<span class="line"><span style="color:#032F62">CgUKBQUFDwUSgQEKBAsEBgUQBBKBAQkFCwQGBRAFEYEBCQULBAYFEAURgQEJBQoFBgUQBRGBAQkFCgUG</span></span>
-<span class="line"><span style="color:#032F62">BREFEIEBCQQLBQYFEQUQgQEIBQsFBgUSBQkBBYEBCAULBQYFEgUJAwOBAQgFCwUGBQoFBAUIBAKBAQgF</span></span>
-<span class="line"><span style="color:#032F62">CwQHBQQLBAYHAwOBAQgECwUHFAUGBQQDgQEHBQsFAxgFBwQEA4EBBwULBQMVCQ4DgQEHBQsFAw8QDQOB</span></span>
-<span class="line"><span style="color:#032F62">AQcEDAUDCRcLBIEBBgULBQUCHwgFgQEGBQsFKAQHgQEGBQsFM4EBBgULBTOBAQYFCgUKIgiBAQUHCQUK</span></span>
-<span class="line"><span style="color:#032F62">IgiBAQUICAUKIgiBAQUKBgUKIgiBAQULBAULBRgFCIEBBA0DBQsFGAUIgQEEBQIHAgULBRgFCIEBBgMD</span></span>
-<span class="line"><span style="color:#032F62">DAwFGAUIgQENCwwFGAUIgQEOCgwFGAUIgQEQBw0FGAUIgQERBwwFGAUIgQERCAsiCIEBEAoKIgiBARAL</span></span>
-<span class="line"><span style="color:#032F62">CSIIgQEPDQgiCIEBDwUCBwcFGAUIgQEOBgMHBgUYBQiBAQ0GBQcFBRgFCIEBDAcGBgUFGAUIgQELBwgE</span></span>
-<span class="line"><span style="color:#032F62">BgUYBQiBAQoHCgMGBRgFCIEBCQcMAQcFGAUIgQEIBxUFGAUIgQEHCBUiCIEBBggWIgiBAQQJFyIIgQEF</span></span>
-<span class="line"><span style="color:#032F62">BxgiCIEBBQUaBRgFCIEBBgMbBRgFCIEBJAUYBQiBAU6BAU6BAU6B0A=='</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#032F62">'0AFOgQFOgQFOgQFOgQFOgQFOgQFOgQEZBi+BARkGL4EBGgUvgQEaBS+BARoFL4EBGgUvgQEaBS+BARoF</span></span>
-<span class="line"><span style="color:#032F62">L4EBGgUvgQEaBRkBFYEBGgUZAxOBARoFDwEIBRKBARoFCwUIBxCBARoFBgoHCg6BARoVCQkNgQEJJgsJ</span></span>
-<span class="line"><span style="color:#032F62">C4EBCSYMCQqBAQohEgkIgQEKGxoIB4EBChUhCQWBARkFIwkEgQEZBSUGBYEBGQUmBAaBARkFKAIGgQEZ</span></span>
-<span class="line"><span style="color:#032F62">BTCBARkFMIEBGQUwgQEZBTCBARkFMIEBGQUwgQEZBTCBARkFCRAXgQEZBQQYFIEBGSMSgQEZJBGBARkS</span></span>
-<span class="line"><span style="color:#032F62">CAwPgQEXDhIJDoEBFQwYCA2BARMMGwcNgQESDB0HDIEBEA4eBgyBAQ8IAwQfBguBAQ4IBAQfBguBAQ0H</span></span>
-<span class="line"><span style="color:#032F62">BgQgBQuBAQwHBwQgBQuBAQsHCAUfBQuBAQoGCgUfBQuBAQoGCgUfBQuBAQkGCwUfBQuBAQkFDAUeBguB</span></span>
-<span class="line"><span style="color:#032F62">AQgGDAUeBguBAQgGDAUdBwuBAQgGDAUdBgyBAQgGDAUcBwyBAQkFDAUbBw2BAQkGCwUZCQ2BAQkHCgUY</span></span>
-<span class="line"><span style="color:#032F62">CQ6BAQoIBwYVCw+BAQsIBQcSDRCBAQwSChURgQENEQoTE4EBDhAKERWBARANDA4XgQESCwwLGoEBFQYO</span></span>
-<span class="line"><span style="color:#032F62">BSCBAU6BAU6BAU6BAU6BAU6BAU6B0A=='</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#032F62">'0AFOgQFOgQFOgQFOgQFOgQFOgQFOgQEuBhqBAS4FG4EBLgUbgQEuBRuBARICGQYbgQEPBRkGG4EBDgYZ</span></span>
-<span class="line"><span style="color:#032F62">BRyBAQ8FGQUcgQEPBhgFHIEBDwYXBhyBARAFFwUdgQEQBRcFHYEBEAYNERqBAREFChcXgQERBQccFYEB</span></span>
-<span class="line"><span style="color:#032F62">EQYEIBOBARIFAg4DExGBARIRBwYEChCBARIOCgUHCQ+BARMKDQUJCA6BARIJDgYKCA2BAREIEAUNBwyB</span></span>
-<span class="line"><span style="color:#032F62">ARAJEAUOBgyBAQ8KDwYPBguBAQ4MDgUQBwqBAQ4MDgURBgqBAQ0GAgYMBRMFCoEBDAYEBQwFEwYJgQEM</span></span>
-<span class="line"><span style="color:#032F62">BgQFCwYTBgmBAQsGBQYKBRUFCYEBCgYHBQkGFQYIgQEKBQgGCAYVBgiBAQkGCQUIBRcFCIEBCQUKBgYG</span></span>
-<span class="line"><span style="color:#032F62">FwUIgQEJBQsFBgUYBQiBAQgFDAYEBhgFCIEBCAUNBQMGGQUIgQEIBQ0GAgYZBQiBAQcFDwwaBQiBAQcF</span></span>
-<span class="line"><span style="color:#032F62">DwwaBQiBAQcFEAobBQiBAQcFEAoaBgiBAQcFEQgbBgiBAQcFEgYcBgiBAQcFEQgbBQmBAQcFEAoZBgmB</span></span>
-<span class="line"><span style="color:#032F62">AQcFEAoZBgmBAQcFDwwXBgqBAQcFDg4VBwqBAQcGDAcCBxQGC4EBCAULBwQEFQcLgQEIBggIBgIVBwyB</span></span>
-<span class="line"><span style="color:#032F62">AQgIBAkHARUHDYEBCRMcCQ2BAQoRHAkOgQELDhwKD4EBDAwbChGBAQ4HGwwSgQEsDxOBASgRFYEBKQ4X</span></span>
-<span class="line"><span style="color:#032F62">gQEpDBmBASoIHIEBKwMggQFOgQFOgQFOgQFOgQFOgQFOgQFOgdA='</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#032F62">'0AFOgQFOgQFOgQFOgQFOgQFOgQFOgQFOgQFOgQFOgQE1DwqBASkbCoEBHiYKgQETMQqBAQc9CoEBBjQU</span></span>
-<span class="line"><span style="color:#032F62">gQEGIQQKGYEBBhcOBxyBAQcOFAcegQEHBhsHH4EBJwYhgQEmBiKBASUGFgEMgQEkBhUDDIEBIwYWBAuB</span></span>
-<span class="line"><span style="color:#032F62">ASMGFwQKgQEiBg8DBgQKgQEhBg8EBwQJgQEhBhAEBwQIgQEgBhEFBgQIgQEgBRMEBwQHgQEfBhQEBgUG</span></span>
-<span class="line"><span style="color:#032F62">gQEfBhQEBwQGgQEfBRYEBgIIgQEeBhYEEIEBHgYXBA+BAR4FGAMQgQEeBSuBAR0GK4EBHQYrgQEdBiuB</span></span>
-<span class="line"><span style="color:#032F62">AR0GK4EBHQYrgQEdBiuBAR0GK4EBHQYrgQEdBiuBAR4FK4EBHgYqgQEeBiqBAR4HKYEBHwYpgQEfByiB</span></span>
-<span class="line"><span style="color:#032F62">ASAHJ4EBIAcngQEhByaBASEJJIEBIgkjgQEjCiGBASQLH4EBJQwdgQEmDxmBASgTE4EBKhMRgQErEhGB</span></span>
-<span class="line"><span style="color:#032F62">AS4PEYEBMAwSgQE0CBKBAU6BAU6BAU6BAU6BAU6BAU6BAU6BAU6BAU6BAU6B0A=='</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#032F62">'0AFOgQFOgQFOgQFOgQFOgQFOgQFOgQFOgQEXATaBARQENoEBEgY2gQESBzWBARMGNYEBEwc0gQEUBjSB</span></span>
-<span class="line"><span style="color:#032F62">ARQGNIEBFQYzgQEVBiABEoEBFgYeAxGBARYGHAYQgQEWBxoHEIEBFwYYCg+BARcHFQsQgQEYBhMLEoEB</span></span>
-<span class="line"><span style="color:#032F62">GAYRCxSBARkGDgsWgQEZBgwLGIEBGgYJCxqBARoHBwocgQEbBgUKHoEBGwcCCiCBARwRIYEBHA8jgQEd</span></span>
-<span class="line"><span style="color:#032F62">DCWBAR0KJ4EBHAoogQEbCSqBARoILIEBGQgtgQEXCC+BARYIMIEBFQgxgQEVBzKBARQHM4EBEwc0gQES</span></span>
-<span class="line"><span style="color:#032F62">BzWBARIGNoEBEQY3gQERBjeBAREFOIEBEAY4gQEQBjiBARAGOIEBEAY4gQEQBjiBARAGOIEBEAY4gQEQ</span></span>
-<span class="line"><span style="color:#032F62">BjiBARAHN4EBEAc3gQERBzaBAREINYEBEgkzgQETCiEDDYEBEw0WCw2BARQtDYEBFisNgQEXKg2BARon</span></span>
-<span class="line"><span style="color:#032F62">DYEBHSARgQEjDxyBAU6BAU6BAU6BAU6BAU6BAU6BAU6B0A=='</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#032F62">'0AFOgQFOgQFOgQFOgQFOgQFOgQFOgQEXBDOBARcLLIEBFxQjgQEXIRaBARchFoEBGh4WgQEiFhaBASsN</span></span>
-<span class="line"><span style="color:#032F62">FoEBNgEXgQFOgQFOgQFOgQFOgQFOgQFOgQFOgQFOgQFOgQEkDR2BAR4WGoEBGR0YgQEVIxaBARApFYEB</span></span>
-<span class="line"><span style="color:#032F62">DRcLCxSBAQ4QFAkTgQEODBoIEoEBDgkeBxKBAQ4GIgcRgQEPAiYGEYEBNwcQgQE4BhCBATgGEIEBOAYQ</span></span>
-<span class="line"><span style="color:#032F62">gQE4BhCBATkFEIEBOQUQgQE5BRCBATgGEIEBOAYQgQE4BhCBATgGEIEBNwcQgQE3BhGBATcGEYEBNgcR</span></span>
-<span class="line"><span style="color:#032F62">gQE1BxKBATUHEoEBNAcTgQEzCBOBATIIFIEBMQgVgQEvCRaBAS4JF4EBLAoYgQEqCxmBAScMG4EBJQ0c</span></span>
-<span class="line"><span style="color:#032F62">gQEhDx6BARwTH4EBGBQigQEZESSBARoNJ4EBGgoqgQEbBS6BAU6BAU6BAU6BAU6BAU6BAU6BAU6B0A=='</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#032F62">'0AFOgQFOgQFOgQFOgQFOgQFDAgmBAUEECYEBQgQIgQE7AQYFB4EBOQQGBAeBATkEBwQGgQE5BQYFBYEB</span></span>
-<span class="line"><span style="color:#032F62">OgQHBAWBATsEBgUEgQE7BQYEBIEBPAQGBASBATwFBgEGgQEQBhsIBAQNgQEQKQQFDIEBECkFAQ+BARAp</span></span>
-<span class="line"><span style="color:#032F62">FYEBECkVgQEQKRWBAU6BAU6BAU6BAU6BAU6BAU6BAU6BAU6BAU6BAU6BAU6BAU6BAU6BAU6BAU6BAU6B</span></span>
-<span class="line"><span style="color:#032F62">AU6BAU6BAU6BAU6BAU6BAU6BAU6BAU6BAU6BAQ0EPYEBDAY8gQEMBjyBAQwGPIEBDAU9gQEMBT2BAQsG</span></span>
-<span class="line"><span style="color:#032F62">PYEBCwY9gQELBj2BAQsGPYEBCwY9gQELBj2BAQsHPIEBCwc8gQEMBzuBAQwIOoEBDQg5gQENCiUCEIEB</span></span>
-<span class="line"><span style="color:#032F62">DgwdBxCBAQ8QDhEQgQEQLhCBAREtEIEBEysQgQEWJROBARobGYEBToEBToEBToEBToEBToHQ'</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#032F62">'0AFOgQFOgQFOgQFOgQFCAwmBAUEECYEBQQUIgQE5AwYFB4EBOAQHBAeBASkCDgQGBQaBASYGDQUGBAaB</span></span>
-<span class="line"><span style="color:#032F62">ASYGDgQHBAWBASYGDgUGBAWBAScFDwQHBASBAScGDwQGAwWBAScGDwUNgQEoBRAEDYEBKAUQAw6BASgG</span></span>
-<span class="line"><span style="color:#032F62">IIEBKQUQAw2BASkFDAcNgQEpBgYMDYEBCgMdFw2BAQsVAh8NgQELNQ6BAQsxEoEBCysYgQELJh2BARkI</span></span>
-<span class="line"><span style="color:#032F62">CwUdgQEsBhyBAS0FHIEBLQUcgQEuBRuBAS4FG4EBLwUagQEvBRqBATAFGYEBMAYYgQExBRiBATEGF4EB</span></span>
-<span class="line"><span style="color:#032F62">MgUXgQEyBhaBATMGFYEBNAUVgQE0BhSBATUGE4EBEAIWCgMHEoEBEAYSFRGBAQ8GExURgQEPBRQUEoEB</span></span>
-<span class="line"><span style="color:#032F62">DgYaDROBAQ4GIwQTgQEOBTuBAQ0GO4EBDQY7gQENBTyBAQ0FPIEBDQU8gQENBTyBAQ0FPIEBDQU8gQEN</span></span>
-<span class="line"><span style="color:#032F62">BjuBAQ0GO4EBDgY6gQEOBzmBAQ4IOIEBDwg3gQEQCh4BFYEBEQwVBxWBARInFYEBEyYVgQEVJBWBARgh</span></span>
-<span class="line"><span style="color:#032F62">FYEBGxoZgQFOgQFOgQFOgQFOgdA='</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#032F62">'0AFOgQFOgQFOgQFOgQFOgQFOgQFOgQFOgQFOgQFOgQFOgQFOgQEJBz6BAQkGP4EBCQY/gQEJBigDFIEB</span></span>
-<span class="line"><span style="color:#032F62">CQYlBhSBAQkGJQcTgQEJBiYHEoEBCQYnBhKBAQkGJwcRgQEJBigGEYEBCQYoBxCBAQkGKQYQgQEJBioG</span></span>
-<span class="line"><span style="color:#032F62">D4EBCQYqBg+BAQkGKgcOgQEJBisGDoEBCgUrBg6BAQoFLAYNgQEKBSwGDYEBCgUtBgyBAQoFLQYMgQEK</span></span>
-<span class="line"><span style="color:#032F62">BS0GDIEBCgUuBguBAQoFLgYLgQEKBS4GC4EBCgYtBguBAQoGLgYKgQEKBi4GCoEBCgYuBgqBAQoGLwYJ</span></span>
-<span class="line"><span style="color:#032F62">gQELBS8GCYEBCwUvBgmBAQsFLwYJgQELBhMBGgYJgQELBhMCGgYIgQELBhMDGQYIgQEMBRMEGAYIgQEM</span></span>
-<span class="line"><span style="color:#032F62">BhEGFwYIgQEMBhEGFwYIgQEMBhAGGQUIgQENBg8GGQUIgQENBg8GGQUIgQENBg4GGgILgQEOBg0GJ4EB</span></span>
-<span class="line"><span style="color:#032F62">DgcLBiiBAQ4HCgcogQEPBwgHKYEBEAcGCCmBARAKAQkqgQEREiuBARIRK4EBEhAsgQETDi2BARULLoEB</span></span>
-<span class="line"><span style="color:#032F62">FwcwgQFOgQFOgQFOgQFOgQFOgQFOgQFOgQFOgQFOgQFOgQFOgdA='</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#032F62">'0AFOgQFOgQFOgQFOgQFOgQFOgQFOgQElBiOBASYFI4EBJgUjgQEmBSOBASYFI4EBJgUjgQEmBSOBASYF</span></span>
-<span class="line"><span style="color:#032F62">I4EBJgUQBQ6BAQ4IEAUGDw6BAQ4yDoEBDjIOgQEOMg6BAQ4rFYEBGhIigQEmBSOBASYFI4EBJgUjgQEm</span></span>
-<span class="line"><span style="color:#032F62">BSOBASYFI4EBJgUjgQEmBSOBASYFI4EBJgUjgQEmBRQCDYEBDQMWBQwKDYEBDQ8JHA2BAQ4zDYEBDjMN</span></span>
-<span class="line"><span style="color:#032F62">gQEOMg6BARAnF4EBJQYjgQEmBSOBASYFI4EBJgUjgQEmBSOBASYFI4EBJgUjgQEmBSOBASYFI4EBJgUj</span></span>
-<span class="line"><span style="color:#032F62">gQEmBSOBAR0EBQUjgQEXFCOBARQZIYEBEh4egQERIRyBARAJDBAZgQEPBxARF4EBDgYSExWBAQ4FEwYD</span></span>
-<span class="line"><span style="color:#032F62">CxSBAQ4FEwYFCxKBAQ0FFAYHChGBAQ0FFAYJCg+BAQ0FFAYKCg6BAQ0GEwYMCQ2BAQ4FEwYNCQyBAQ4G</span></span>
-<span class="line"><span style="color:#032F62">EQYQBg2BAQ4HDwcRBQ2BAQ8IDAgSAw6BAQ8bFAEPgQERGCWBARIWJoEBFBIogQEXDSqBAU6BAU6BAU6B</span></span>
-<span class="line"><span style="color:#032F62">AU6BAU6BAU6B0A=='</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#032F62">'0AFOgQFOgQFOgQFOgQFOgQFOgQEpBh+BASkGH4EBKQYfgQEqBR+BASoFH4EBKgUfgQEqBR+BASoFH4EB</span></span>
-<span class="line"><span style="color:#032F62">KgUfgQEqBR+BARkuB4EBBkEHgQEHQAeBAQdAB4EBB0AHgQEHDBcFH4EBKgUfgQEqBR+BASoFH4EBKgUf</span></span>
-<span class="line"><span style="color:#032F62">gQEqBR+BASoFH4EBKgUfgQEgDx+BAR4RH4EBHBMfgQEbFB+BARoIBAkfgQEZBwkGH4EBGQYLBh6BARgG</span></span>
-<span class="line"><span style="color:#032F62">DQUegQEYBQ4GHYEBFwYPBR2BARcFEAUdgQEXBRAFHYEBFwUQBhyBARcFEAYcgQEXBQ8HHIEBFwUPBxyB</span></span>
-<span class="line"><span style="color:#032F62">ARcGDgccgQEXBg0IHIEBGAYMBx2BARgHCggdgQEZCAYKHYEBGhcdgQEbFh2BARwVHYEBHgsBBh6BASAG</span></span>
-<span class="line"><span style="color:#032F62">BAYegQEpBh+BASkGH4EBKAYggQEnByCBASYHIYEBJQcigQEkCCKBASIJI4EBIAokgQEeCyWBARwLJ4EB</span></span>
-<span class="line"><span style="color:#032F62">GQ0ogQEWDiqBARcMK4EBGAktgQEZBTCBARoCMoEBToEBToEBToEBToEBToEBToHQ'</span><span style="color:#24292E">,];</span></span>
-<span class="line"><span style="color:#24292E">$m</span><span style="color:#D73A49">=</span><span style="color:#032F62">""</span><span style="color:#24292E">;</span><span style="color:#D73A49">for</span><span style="color:#24292E">($k</span><span style="color:#D73A49">=</span><span style="color:#005CC5">0</span><span style="color:#24292E">;$k</span><span style="color:#D73A49">&#x3C;</span><span style="color:#005CC5">min</span><span style="color:#24292E">(</span><span style="color:#005CC5">13</span><span style="color:#24292E">,</span><span style="color:#6F42C1">intdiv</span><span style="color:#24292E">(</span><span style="color:#005CC5">__LINE__</span><span style="color:#D73A49">-</span><span style="color:#005CC5">119</span><span style="color:#24292E">,</span><span style="color:#005CC5">80</span><span style="color:#24292E">)</span><span style="color:#D73A49">+</span><span style="color:#005CC5">1</span><span style="color:#24292E">);$k</span><span style="color:#D73A49">++</span><span style="color:#24292E">){$C</span><span style="color:#D73A49">=</span><span style="color:#005CC5">str_replace</span><span style="color:#24292E">(</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">,</span><span style="color:#032F62">""</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#24292E">$c[$k]);$f</span><span style="color:#D73A49">=!</span><span style="color:#005CC5">0</span><span style="color:#24292E">;</span><span style="color:#D73A49">foreach</span><span style="color:#24292E">(</span><span style="color:#005CC5">str_split</span><span style="color:#24292E">(</span><span style="color:#005CC5">base64_decode</span><span style="color:#24292E">($C))</span><span style="color:#D73A49">as</span><span style="color:#24292E">$l){$L</span><span style="color:#D73A49">=</span><span style="color:#005CC5">ord</span><span style="color:#24292E">($l);$m</span><span style="color:#D73A49">.=</span><span style="color:#005CC5">str_repeat</span></span>
-<span class="line"><span style="color:#24292E">($f</span><span style="color:#D73A49">?</span><span style="color:#032F62">"#"</span><span style="color:#D73A49">:</span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">32</span><span style="color:#24292E">),$L</span><span style="color:#D73A49">&#x26;</span><span style="color:#005CC5">127</span><span style="color:#24292E">);$f</span><span style="color:#D73A49">=!</span><span style="color:#24292E">$f;</span><span style="color:#D73A49">if</span><span style="color:#24292E">($L</span><span style="color:#D73A49">&#x26;</span><span style="color:#005CC5">128</span><span style="color:#24292E">){$m</span><span style="color:#D73A49">.=</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">;$f</span><span style="color:#D73A49">=!</span><span style="color:#005CC5">0</span><span style="color:#24292E">;</span><span style="color:#D73A49">continue</span><span style="color:#24292E">;}}}</span><span style="color:#005CC5">print</span><span style="color:#24292E">(</span></span>
-<span class="line"><span style="color:#005CC5">str_replace</span><span style="color:#24292E">([</span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">96</span><span style="color:#24292E">),</span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">37</span><span style="color:#24292E">),</span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">64</span><span style="color:#24292E">)],[</span><span style="color:#005CC5">implode</span><span style="color:#24292E">(</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">,</span><span style="color:#005CC5">array_map</span><span style="color:#24292E">(</span><span style="color:#D73A49">fn</span><span style="color:#24292E">($C)=></span><span style="color:#032F62">"'"</span><span style="color:#D73A49">.</span><span style="color:#005CC5">trim</span><span style="color:#24292E">(</span></span>
-<span class="line"><span style="color:#005CC5">chunk_split</span><span style="color:#24292E">(</span><span style="color:#005CC5">str_replace</span><span style="color:#24292E">(</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">,</span><span style="color:#032F62">""</span><span style="color:#24292E">,$C),</span><span style="color:#005CC5">80</span><span style="color:#24292E">,</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">))</span><span style="color:#D73A49">.</span><span style="color:#032F62">"',"</span><span style="color:#24292E">,$c)),</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">{</span><span style="color:#24292E">$m</span><span style="color:#032F62">}"</span><span style="color:#24292E">,</span><span style="color:#032F62">"{</span><span style="color:#24292E">$s</span><span style="color:#032F62">}</span><span style="color:#005CC5">\n</span><span style="color:#032F62">Q;</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">],$s));</span></span></code></pre>
- </div>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2024-12-04/cohackpp-report/lt.png b/vhosts/blog/public/posts/2024-12-04/cohackpp-report/lt.png
deleted file mode 100644
index 1075d95f..00000000
--- a/vhosts/blog/public/posts/2024-12-04/cohackpp-report/lt.png
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/posts/2024-12-33/2024-reflections/index.html b/vhosts/blog/public/posts/2024-12-33/2024-reflections/index.html
deleted file mode 100644
index d1f71cea..00000000
--- a/vhosts/blog/public/posts/2024-12-33/2024-reflections/index.html
+++ /dev/null
@@ -1,198 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2025 nsfisis">
- <meta name="description" content="2024年にやったことを振り返る">
- <meta property="og:type" content="article">
- <meta property="og:title" content="2024年の振り返り|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="2024年にやったことを振り返る">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>2024年の振り返り|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">2024年の振り返り</h1>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2025-01-02">2025-01-02</time>: 公開
- </li>
- </ol>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- ご存じのとおり、4 と 11 と 23 で割り切れる年は閏年というやつで 12 月が 33 日まである。1年の振り返りを書く猶予が平年よりも長くなるので大変に都合がよい。
- </p>
- <p>
- 去年のやつ: <a href="/posts/2023-12-31/2023-reflections/">/posts/2023-12-31/2023-reflections/</a>
- </p>
- </section>
- <section id="section--conference">
- <h2><a href="#section--conference">登壇・カンファレンス参加</a></h2>
- <p>
- 参加または登壇した勉強会やカンファレンス。LT 等も含めて計 8 回の登壇をおこなった。また、4つのカンファレンスでコアスタッフまたは当日スタッフとして参加した。
- </p>
- <ul>
- <li>
- PHP カンファレンス北海道 2024 オンラインで参加
- </li>
- <li>
- <a href="/slides/2024-01-24/phpstudy-tokyo-160/">PHP 勉強会@東京 第 160 回 登壇</a>
- </li>
- <li>
- <a href="/posts/2024-02-10/yapcjapan-2024-report/">YAPC::Hiroshima 2024 参加</a>
- </li>
- <li>
- <a href="/posts/2024-02-22/phpkansai-2024-report/">PHPカンファレンス関西 2024 参加</a>
- </li>
- <li>
- PHPerKaigi 2024
- <ul>
- <li>
- <a href="/slides/2024-03-08/phperkaigi-2024/">登壇</a>
- </li>
- <li>
- コアスタッフとして参加
- </li>
- </ul>
- </li>
- <li>
- <a href="/slides/2024-03-15/ya8-2024/">Ya8 2024 登壇</a>
- </li>
- <li>
- PHP カンファレンス小田原 2024
- <ul>
- <li>
- <a href="/slides/2024-04-13/phpcon-odawara-2024/">登壇</a>
- </li>
- <li>
- 当日スタッフとして参加
- </li>
- </ul>
- </li>
- <li>
- <a href="/slides/2024-04-25/phpstudy-tokyo-163/">PHP 勉強会@東京 第 163 回 LT で登壇</a>
- </li>
- <li>
- <a href="/posts/2024-05-11/phpconkagawa-2024-report/">PHP カンファレンス香川 2024 参加</a>
- </li>
- <li>
- <a href="/posts/2024-06-19/scalamatsuri-2024-report/">ScalaMatsuri 2024 参加</a>
- </li>
- <li>
- <a href="/slides/2024-07-18/phpstudy-tokyo-166/">PHP 勉強会@東京 第 166 回 登壇</a>
- </li>
- <li>
- iOSDC Japan 2024 コアスタッフとして参加
- </li>
- <li>
- Nix meetup #1 参加
- </li>
- <li>
- <a href="/slides/2024-10-30/phpstudy-tokyo-169/">PHP 勉強会@東京 第 169 回 登壇</a>
- </li>
- <li>
- <a href="/slides/2024-11-30/cohackpp/">紅白ぺぱ合戦 LT で登壇</a>
- </li>
- <li>
- PHP カンファレンス 2024 当日スタッフとして参加
- </li>
- </ul>
- </section>
- <section id="section--articles">
- <h2><a href="#section--articles">書いた記事</a></h2>
- <p>
- 今年はこのブログに月1記事以上の記事を書くという目標を立てていた。本数としては 12 本以上あるが、10月と11月はゼロになってしまった。社内記事を社外向けにリライトする作業を中々進められていないので、2025年は定期的に消化していきたい。
- </p>
- <ul>
- <li>
- 社外記事 (このブログ): 15本
- </li>
- <li>
- 社内記事: 22本
- <ul>
- <li>
- 年間で最も記事を書いた人として社内表彰された
- </li>
- </ul>
- </li>
- </ul>
- </section>
- <section id="section--coding">
- <h2><a href="#section--coding">作ったもの</a></h2>
- <p>
- 今年は主に WebAssembly ランタイムと、カンファレンスの企画で使うシステムを作っていた。後者のシステムでもサンドボックス化のための技術として WebAssembly を用いているので、今年は WebAssembly と戯れた一年だったと言える。
- </p>
- <ul>
- <li>
- <a href="https://github.com/nsfisis/php-waddiwasi" rel="noreferrer" target="_blank">Waddiwasi: pure PHP で書かれた WebAssembly ランタイム</a>
- </li>
- <li>
- <a href="https://github.com/nsfisis/phperkaigi-2024-albatross" rel="noreferrer" target="_blank">Albatross.PHP: PHPerKaigi 2024 のコードゴルフ企画で使われたシステム</a>
- </li>
- <li>
- <a href="https://github.com/nsfisis/iosdc-japan-2024-albatross" rel="noreferrer" target="_blank">Albatross.swift: iOSDC Japan 2024 のコードバトル企画で使われたシステム</a>
- </li>
- <li>
- <a href="/posts/2024-07-19/reparojson-fix-only-json-formatter/">ReparoJSON: 文法エラーを直すだけの JSON フォーマッタ</a>
- </li>
- </ul>
- </section>
- <section id="section--misc">
- <h2><a href="#section--misc">その他</a></h2>
- <ul>
- <li>
- <a href="/posts/2024-09-28/mncore-challenge-1/">MN-Core Challenge #1 に参加</a>
- </li>
- <li>
- ISUCON 14 に参加
- </li>
- </ul>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">おわりに</a></h2>
- <p>
- 今年も大変お世話になりました。よいお年を!
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2025-01-08/phperkaigi-2023-tokens-q1/Q1.png b/vhosts/blog/public/posts/2025-01-08/phperkaigi-2023-tokens-q1/Q1.png
deleted file mode 100644
index 7f099d74..00000000
--- a/vhosts/blog/public/posts/2025-01-08/phperkaigi-2023-tokens-q1/Q1.png
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/posts/2025-01-08/phperkaigi-2023-tokens-q1/index.html b/vhosts/blog/public/posts/2025-01-08/phperkaigi-2023-tokens-q1/index.html
deleted file mode 100644
index a49c1087..00000000
--- a/vhosts/blog/public/posts/2025-01-08/phperkaigi-2023-tokens-q1/index.html
+++ /dev/null
@@ -1,471 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2025 nsfisis">
- <meta name="description" content="PHPerKaigi 2023 でデジタルサーカス株式会社から出題した問題を解説する。全5問中の第1問。">
- <meta name="keywords" content="カンファレンス,PHP,PHPerKaigi,Piet">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHPerKaigi 2023 トークン問題解説 (1/5)|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="PHPerKaigi 2023 でデジタルサーカス株式会社から出題した問題を解説する。全5問中の第1問。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHPerKaigi 2023 トークン問題解説 (1/5)|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">PHPerKaigi 2023 トークン問題解説 (1/5)</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/conference/">カンファレンス</a>
- </li>
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phperkaigi/">PHPerKaigi</a>
- </li>
- <li class="tag">
- <a href="/tags/piet/">Piet</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2025-01-08">2025-01-08</time>: 公開
- </li>
- <li class="revision">
- <time datetime="2025-01-11">2025-01-11</time>: 読みやすさのため一部の文言を調整
- </li>
- </ol>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <div class="admonition">
- <div class="admonition-label">
- NOTE
- </div>
- <div class="admonition-content">
- <p>
- これは PHPerKaigi 2023 の記事です。今は 2025 年ですが、PHPerKaigi 2023 の記事です。
- </p>
- </div>
- </div>
- <p>
- 2023-03-23 から 2023-03-25 にかけて開催された <a href="https://phperkaigi.jp/2023/" rel="noreferrer" target="_blank">PHPerKaigi 2023</a> では、PHPer チャレンジという企画がおこなわれた。PHPer チャレンジとは、スポンサーのパンフレットやカンファレンス会場などから「#」記号で始まる文字列を集め、景品などを得るという企画である。この文字列は「PHPer トークン」と呼ばれている。弊社 <a href="https://www.dgcircus.com/" rel="noreferrer" target="_blank">デジタルサーカス株式会社</a> からは、トークン問題という形で、PHP に関する問題を解くと PHPer トークンが得られるようになっている問題を出題した。
- </p>
- <p>
- <a href="/posts/2023-04-04/phperkaigi-2023-report/">PHPerKaigi 2023 の参加レポ</a> でも書いたとおり、この年のトークン問題は「昨年の PHPerKaigi 2022 が終わった段階から作り始め、約半年かけて制作」された。PHPerKaigi 当日も <a href="/slides/2023-03-25/phperkaigi-2023-tokens/">PHPer チャレンジ解説セッション</a> という形で解説の機会を頂いたのだが、せっかく時間をかけて作題したので記事の形でも残しておこうと思う。
- </p>
- <p>
- この記事では、全5問ある中の第1問について解説する。他の問題については以下のリンクを参照のこと。
- </p>
- <ol>
- <li>
- <a href="/posts/2025-01-08/phperkaigi-2023-tokens-q1/">第1問 (この記事)</a>
- </li>
- <li>
- 第2問 (TODO: 執筆中)
- </li>
- <li>
- 第3問 (TODO: 執筆中)
- </li>
- <li>
- 第4問 (TODO: 執筆中)
- </li>
- <li>
- 第5問 (TODO: 執筆中)
- </li>
- </ol>
- <p>
- それぞれの問題はこちらの GitHub リポジトリ ( <a href="https://github.com/nsfisis/PHPerKaigi2023-tokens" rel="noreferrer" target="_blank">nsfisis/PHPerKaigi2023-tokens</a> ) からも閲覧できる。
- </p>
- </section>
- <section id="section--quiz">
- <h2><a href="#section--quiz">Q1: An Art of Computer Programming</a></h2>
- <p>
- 第1問『An Art of Computer Programming』はこちら。
- </p>
- <p>
- <img alt="全体がQRコードになっており、中央には小さな文字で「Password is one of the PHPer tokens.」と書かれている" src="/posts/2025-01-08/phperkaigi-2023-tokens-q1/Q1.png">
- </p>
- </section>
- <section id="section--how-to-solve">
- <h2><a href="#section--how-to-solve">解き方</a></h2>
- <p>
- まずはトークンを得る方法を解説抜きで説明する。次のように実行する。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ echo "#iwillblog" | php Q1.png >/dev/null</span></span></code></pre>
- </div>
- <p>
- 無事に実行できていれば「#ModernPHPisStaticallyTypedLanguage」というトークンが得られる。
- </p>
- </section>
- <section id="section--commentary">
- <h2><a href="#section--commentary">解説</a></h2>
- <section id="section--commentary--read-as-image">
- <h3><a href="#section--commentary--read-as-image">画像として解釈する</a></h3>
- <p>
- まずは素直に画像として見てみよう。全体は QR コードになっている。適当な QR コードリーダで読み込むと、次のようなテキストが表示されるはずだ。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>Guess password. $ echo "password" | php Q1.png >/dev/null</span></span></code></pre>
- </div>
- <p>
- メッセージは、この画像の実行方法とこの問題でやるべきこと (パスワードの推測) を示している。
- </p>
- <p>
- 次に QR コードの中央部に目を向けると、小さな文字で「Password is one of the PHPer tokens.」と書かれているのがわかる。他の PHPer トークンの中から適切な1つを見つけだし、「パスワード」として渡すことで答えとなる PHPer トークンが得られるというわけだ。
- </p>
- </section>
- <section id="section--commentary--password">
- <h3><a href="#section--commentary--password">パスワード</a></h3>
- <p>
- 不正なパスワードを使って実行してみると、次のようなエラーメッセージが表示される。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ echo "foo" | php Q1.png >/dev/null</span></span>
-<span class="line"><span>401 Unauthorized</span></span></code></pre>
- </div>
- <p>
- すでに <a href="#section--how-to-solve">「解き方」の節</a> で示したように、パスワードである PHPer トークンは「#iwillblog」である。これを与えて実行すると正解のトークンが得られる。
- </p>
- <p>
- このパスワードの選択にはとある事情がある。今回の問題の作問は前回の開催 (PHPerKaigi 2022) 直後からスタートしており、この時点では PHPerKaigi 2023 で登録される PHPer トークンにどのようなものがあるかはまったくわからない状態であった。作問作業を早期に終わらせるには、次回開催でも確実に使われるであろう定番のトークンを予測して選ぶ必要があったのだ。かくして、私が知る限り毎回登場しているトークンである「#iwillblog」に白羽の矢が立てられた。
- </p>
- <p>
- なお、解いてくださった方の中には、先頭の「#」を入力せずに何度も試してしまい答えが得られずじまいになった方もいらっしゃるようだった。問題を置いていたリポジトリにヒントとしてパスワードのトークンが「i」で始まると書いていたのだが、これが意図せずミスリードになってしまった。これは私のミスである。
- </p>
- </section>
- <section id="section--commentary--png-steganography">
- <h3><a href="#section--commentary--png-steganography">PNG ステガノグラフィ</a></h3>
- <p>
- QR コードも言っているように、このファイルは PNG 画像であるにもかかわらず PHP で実行することができる。なぜこのようなことが可能なのか。
- </p>
- <p>
- PNG 画像のフォーマットは、次のようになっている。
- </p>
- <ol>
- <li>
- マジックナンバーなど
- </li>
- <li>
- PNG ヘッダ (<code>IHDR</code> チャンク)
- </li>
- <li>
- 実際の画像データ (<code>IDAT</code> チャンク)
- </li>
- <li>
- PNG フッタ (<code>IEND</code> チャンク)
- </li>
- </ol>
- <p>
- PNG フッタの後ろにあるデータは、画像ビューアには解釈されず、画像の表示には影響を与えない。したがって、PNG フッタの後ろには任意のデータを埋め込むことができる。
- </p>
- <p>
- さて、PHP には、PHP プログラムの始まりを示すための PHP タグ (<code>&lt;?php</code> または <code>&lt;?</code>) がある。CLI で実行する場合、PHP タグよりも前にあるデータは標準出力へそのまま出力される。
- </p>
- <p>
- この画像ファイルは次のような構造になっていた。
- </p>
- <ol>
- <li>
- マジックナンバーなど
- </li>
- <li>
- PNG ヘッダ (<code>IHDR</code> チャンク)
- </li>
- <li>
- 実際の画像データ (<code>IDAT</code> チャンク)
- </li>
- <li>
- PNG フッタ (<code>IEND</code> チャンク)
- </li>
- <li>
- <strong>PHP タグ (<code>&lt;?php</code>)</strong>
- </li>
- <li>
- <strong>通常の PHP ソースコード</strong>
- </li>
- </ol>
- <p>
- PNG ファイルとして読むときは PNG フッタ以降は無視され、PHP スクリプトとして読むときは PHP タグ以前が無視されるという仕掛けである。
- </p>
- <p>
- <code>strings</code> コマンドを使うと、隠されたデータを簡単に閲覧できる。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>IHDR</span></span>
-<span class="line"><span>-HHc</span></span>
-<span class="line"><span>&#x3C;PLTE</span></span>
-<span class="line"><span>IDATx</span></span>
-<span class="line"><span>IEND</span></span>
-<span class="line"><span>&#x3C;?php</span></span>
-<span class="line"><span>error_reporting(-1);</span></span>
-<span class="line"><span>$b = unpack('C*', file_get_contents(__FILE__));</span></span>
-<span class="line"><span>$w = $b[20]+2;</span></span>
-<span class="line"><span>$h = $b[24]+2;</span></span>
-<span class="line"><span>// (以下略)</span></span></code></pre>
- </div>
- <p>
- <code>IHDR</code> や <code>IEND</code> が PNG 画像の一部で、<code>&lt;?php</code> からが実際のプログラムになっている。もちろんこれを PHP プログラムとして動かすと、PHP タグより前にある PNG 画像としてのデータはそのまま標準出力へと出力されてしまう。それを防ぐため、QR コードを読み込んだときの実行方法
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>Guess password. $ echo "password" | php Q1.png >/dev/null</span></span></code></pre>
- </div>
- <p>
- には標準出力を捨てるよう <code>&gt;/dev/null</code> と指定されている。
- </p>
- <p>
- なお、このように PNG 画像などに本来のデータとは異なる別のデータを隠すことを「ステガノグラフィ」( <a href="https://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%86%E3%82%AC%E3%83%8E%E3%82%B0%E3%83%A9%E3%83%95%E3%82%A3%E3%83%BC" rel="noreferrer" target="_blank">Wikipedia「ステガノグラフィー」</a> ) と呼ぶ。
- </p>
- </section>
- <section id="section--commentary--php-program">
- <h3><a href="#section--commentary--php-program">実行される PHP プログラム</a></h3>
- <p>
- 画像の正体がわかったところで、画像に隠されていた PHP プログラムについて見ていこう。先ほどは一部しか記載しなかったので、全体を載せる。なお、ある程度ゴルフしながら書いたので、空白こそ残しているものの可読性は非常に低いことと思う。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span></span>
-<span class="line"><span style="color:#005CC5">error_reporting</span><span style="color:#24292E">(</span><span style="color:#D73A49">-</span><span style="color:#005CC5">1</span><span style="color:#24292E">);</span></span>
-<span class="line"><span style="color:#24292E">$b </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> unpack</span><span style="color:#24292E">(</span><span style="color:#032F62">'C*'</span><span style="color:#24292E">, </span><span style="color:#005CC5">file_get_contents</span><span style="color:#24292E">(</span><span style="color:#005CC5">__FILE__</span><span style="color:#24292E">));</span></span>
-<span class="line"><span style="color:#24292E">$w </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $b[</span><span style="color:#005CC5">20</span><span style="color:#24292E">]</span><span style="color:#D73A49">+</span><span style="color:#005CC5">2</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">$h </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $b[</span><span style="color:#005CC5">24</span><span style="color:#24292E">]</span><span style="color:#D73A49">+</span><span style="color:#005CC5">2</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">$cs </span><span style="color:#D73A49">=</span><span style="color:#24292E"> [];</span></span>
-<span class="line"><span style="color:#D73A49">for</span><span style="color:#24292E"> ($y </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">; $y </span><span style="color:#D73A49">&#x3C;</span><span style="color:#24292E"> $h; $y</span><span style="color:#D73A49">++</span><span style="color:#24292E">)</span></span>
-<span class="line"><span style="color:#D73A49"> for</span><span style="color:#24292E"> ($x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">; $x </span><span style="color:#D73A49">&#x3C;</span><span style="color:#24292E"> $w; $x</span><span style="color:#D73A49">++</span><span style="color:#24292E">)</span></span>
-<span class="line"><span style="color:#24292E"> $cs[$y</span><span style="color:#D73A49">*</span><span style="color:#24292E">$w </span><span style="color:#D73A49">+</span><span style="color:#24292E"> $x] </span><span style="color:#D73A49">=</span><span style="color:#24292E"> ($x</span><span style="color:#D73A49">*</span><span style="color:#24292E">$y </span><span style="color:#D73A49">===</span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> ||</span><span style="color:#24292E"> $x </span><span style="color:#D73A49">===</span><span style="color:#24292E"> $w</span><span style="color:#D73A49">-</span><span style="color:#005CC5">1</span><span style="color:#D73A49"> ||</span><span style="color:#24292E"> $y </span><span style="color:#D73A49">===</span><span style="color:#24292E"> $h</span><span style="color:#D73A49">-</span><span style="color:#005CC5">1</span><span style="color:#24292E">)</span></span>
-<span class="line"><span style="color:#D73A49"> ?</span><span style="color:#005CC5"> 0</span></span>
-<span class="line"><span style="color:#D73A49"> :</span><span style="color:#24292E"> $b[</span><span style="color:#005CC5">122</span><span style="color:#D73A49">+</span><span style="color:#24292E">($y</span><span style="color:#D73A49">-</span><span style="color:#005CC5">1</span><span style="color:#24292E">)</span><span style="color:#D73A49">*</span><span style="color:#24292E">($w</span><span style="color:#D73A49">-</span><span style="color:#005CC5">1</span><span style="color:#24292E">)</span><span style="color:#D73A49">+</span><span style="color:#24292E">$x</span><span style="color:#D73A49">-</span><span style="color:#005CC5">1</span><span style="color:#24292E">];</span></span>
-<span class="line"><span style="color:#24292E">$i </span><span style="color:#D73A49">=</span><span style="color:#6F42C1"> stream_isatty</span><span style="color:#24292E">(</span><span style="color:#005CC5">STDIN</span><span style="color:#24292E">)</span></span>
-<span class="line"><span style="color:#D73A49"> ?</span><span style="color:#24292E"> []</span></span>
-<span class="line"><span style="color:#D73A49"> :</span><span style="color:#005CC5"> array_map</span><span style="color:#24292E">(</span><span style="color:#005CC5">ord</span><span style="color:#24292E">(</span><span style="color:#D73A49">...</span><span style="color:#24292E">), </span><span style="color:#005CC5">str_split</span><span style="color:#24292E">(</span><span style="color:#005CC5">trim</span><span style="color:#24292E">((</span><span style="color:#D73A49">string</span><span style="color:#24292E">) </span><span style="color:#005CC5">fgets</span><span style="color:#24292E">(</span><span style="color:#005CC5">STDIN</span><span style="color:#24292E">))));</span></span>
-<span class="line"><span style="color:#24292E">$m </span><span style="color:#D73A49">=</span><span style="color:#24292E"> [];</span></span>
-<span class="line"><span style="color:#24292E">$pc </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> 1</span><span style="color:#D73A49">*</span><span style="color:#24292E">$w</span><span style="color:#D73A49">+</span><span style="color:#005CC5">1</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">$dp </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">$cc </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> 1</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">$c0 </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> 1</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">$b </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">$ns </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">$o </span><span style="color:#D73A49">=</span><span style="color:#032F62"> ''</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#D73A49">while</span><span style="color:#24292E"> (</span><span style="color:#005CC5">true</span><span style="color:#24292E">) {</span></span>
-<span class="line"><span style="color:#24292E"> $ns</span><span style="color:#D73A49">++</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> ($ns </span><span style="color:#D73A49">></span><span style="color:#005CC5"> 1e5</span><span style="color:#24292E">) {</span></span>
-<span class="line"><span style="color:#005CC5"> echo</span><span style="color:#032F62"> "infinite loop detected</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#D73A49"> break</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E"> $c1 </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $cs[$pc];</span></span>
-<span class="line"><span style="color:#24292E"> $y </span><span style="color:#D73A49">=</span><span style="color:#24292E"> (</span><span style="color:#005CC5">6</span><span style="color:#D73A49"> +</span><span style="color:#6F42C1"> intdiv</span><span style="color:#24292E">($c1</span><span style="color:#D73A49">-</span><span style="color:#005CC5">2</span><span style="color:#24292E">, </span><span style="color:#005CC5">3</span><span style="color:#24292E">) </span><span style="color:#D73A49">-</span><span style="color:#6F42C1"> intdiv</span><span style="color:#24292E">($c0</span><span style="color:#D73A49">-</span><span style="color:#005CC5">2</span><span style="color:#24292E">, </span><span style="color:#005CC5">3</span><span style="color:#24292E">)) </span><span style="color:#D73A49">%</span><span style="color:#005CC5"> 6</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E"> $x </span><span style="color:#D73A49">=</span><span style="color:#24292E"> (</span><span style="color:#005CC5">3</span><span style="color:#D73A49"> +</span><span style="color:#24292E"> $c1</span><span style="color:#D73A49">%</span><span style="color:#005CC5">3</span><span style="color:#D73A49"> -</span><span style="color:#24292E"> $c0</span><span style="color:#D73A49">%</span><span style="color:#005CC5">3</span><span style="color:#24292E">) </span><span style="color:#D73A49">%</span><span style="color:#005CC5"> 3</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#D73A49"> match</span><span style="color:#24292E"> (($c0 </span><span style="color:#D73A49">!==</span><span style="color:#005CC5"> 1</span><span style="color:#24292E">) </span><span style="color:#D73A49">*</span><span style="color:#24292E"> ($c1 </span><span style="color:#D73A49">!==</span><span style="color:#005CC5"> 1</span><span style="color:#24292E">) </span><span style="color:#D73A49">*</span><span style="color:#24292E"> ($y</span><span style="color:#D73A49">*</span><span style="color:#005CC5">3</span><span style="color:#D73A49"> +</span><span style="color:#24292E"> $x)) {</span></span>
-<span class="line"><span style="color:#005CC5"> 1</span><span style="color:#D73A49"> =></span><span style="color:#24292E"> $m[] </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $b,</span></span>
-<span class="line"><span style="color:#005CC5"> 2</span><span style="color:#D73A49"> =></span><span style="color:#005CC5"> array_pop</span><span style="color:#24292E">($m),</span></span>
-<span class="line"><span style="color:#005CC5"> 3</span><span style="color:#D73A49"> =></span><span style="color:#24292E"> $m[] </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> array_pop</span><span style="color:#24292E">($m) </span><span style="color:#D73A49">+</span><span style="color:#005CC5"> array_pop</span><span style="color:#24292E">($m),</span></span>
-<span class="line"><span style="color:#005CC5"> 4</span><span style="color:#D73A49"> =></span><span style="color:#24292E"> $m[] </span><span style="color:#D73A49">=</span><span style="color:#24292E"> (</span><span style="color:#D73A49">fn</span><span style="color:#24292E">($x, $y) => $y </span><span style="color:#D73A49">-</span><span style="color:#24292E"> $x)(</span><span style="color:#005CC5">array_pop</span><span style="color:#24292E">($m), </span><span style="color:#005CC5">array_pop</span><span style="color:#24292E">($m)),</span></span>
-<span class="line"><span style="color:#005CC5"> 5</span><span style="color:#D73A49"> =></span><span style="color:#24292E"> $m[] </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> array_pop</span><span style="color:#24292E">($m) </span><span style="color:#D73A49">*</span><span style="color:#005CC5"> array_pop</span><span style="color:#24292E">($m),</span></span>
-<span class="line"><span style="color:#005CC5"> 8</span><span style="color:#D73A49"> =></span><span style="color:#24292E"> $m[] </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> array_pop</span><span style="color:#24292E">($m) </span><span style="color:#D73A49">===</span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> ?</span><span style="color:#005CC5"> 1</span><span style="color:#D73A49"> :</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#005CC5"> 11</span><span style="color:#D73A49"> =></span><span style="color:#24292E"> $cc </span><span style="color:#D73A49">*=</span><span style="color:#005CC5"> pow</span><span style="color:#24292E">(</span><span style="color:#D73A49">-</span><span style="color:#005CC5">1</span><span style="color:#24292E">, </span><span style="color:#005CC5">array_pop</span><span style="color:#24292E">($m)),</span></span>
-<span class="line"><span style="color:#005CC5"> 12</span><span style="color:#D73A49"> =></span><span style="color:#24292E"> $m[] </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $m[</span><span style="color:#005CC5">count</span><span style="color:#24292E">($m)</span><span style="color:#D73A49">-</span><span style="color:#005CC5">1</span><span style="color:#24292E">],</span></span>
-<span class="line"><span style="color:#005CC5"> 13</span><span style="color:#D73A49"> =></span><span style="color:#24292E"> $m </span><span style="color:#D73A49">=</span><span style="color:#24292E"> (</span><span style="color:#D73A49">fn</span><span style="color:#24292E">($n, $d, $m, $l) => [</span></span>
-<span class="line"><span style="color:#D73A49"> ...</span><span style="color:#005CC5">array_slice</span><span style="color:#24292E">($m, </span><span style="color:#005CC5">0</span><span style="color:#24292E">, $l</span><span style="color:#D73A49">-</span><span style="color:#24292E">$d),</span></span>
-<span class="line"><span style="color:#D73A49"> ...</span><span style="color:#005CC5">array_reverse</span><span style="color:#24292E">([</span></span>
-<span class="line"><span style="color:#D73A49"> ...</span><span style="color:#005CC5">array_reverse</span><span style="color:#24292E">(</span><span style="color:#005CC5">array_slice</span><span style="color:#24292E">($m, $l</span><span style="color:#D73A49">-</span><span style="color:#24292E">$d, $d</span><span style="color:#D73A49">-</span><span style="color:#24292E">$n)),</span></span>
-<span class="line"><span style="color:#D73A49"> ...</span><span style="color:#005CC5">array_reverse</span><span style="color:#24292E">(</span><span style="color:#005CC5">array_slice</span><span style="color:#24292E">($m, $l</span><span style="color:#D73A49">-</span><span style="color:#24292E">$n)),</span></span>
-<span class="line"><span style="color:#24292E"> ]),</span></span>
-<span class="line"><span style="color:#24292E"> ])(</span><span style="color:#005CC5">array_pop</span><span style="color:#24292E">($m), </span><span style="color:#005CC5">array_pop</span><span style="color:#24292E">($m), $m, </span><span style="color:#005CC5">count</span><span style="color:#24292E">($m)),</span></span>
-<span class="line"><span style="color:#005CC5"> 15</span><span style="color:#D73A49"> =></span><span style="color:#D73A49"> !</span><span style="color:#005CC5">empty</span><span style="color:#24292E">($i) </span><span style="color:#D73A49">and</span><span style="color:#24292E"> $m[] </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> array_shift</span><span style="color:#24292E">($i),</span></span>
-<span class="line"><span style="color:#005CC5"> 16</span><span style="color:#D73A49"> =></span><span style="color:#24292E"> $o </span><span style="color:#D73A49">.=</span><span style="color:#005CC5"> sprintf</span><span style="color:#24292E">(</span><span style="color:#032F62">'%d'</span><span style="color:#24292E">, </span><span style="color:#005CC5">array_pop</span><span style="color:#24292E">($m)),</span></span>
-<span class="line"><span style="color:#005CC5"> 17</span><span style="color:#D73A49"> =></span><span style="color:#24292E"> $o </span><span style="color:#D73A49">.=</span><span style="color:#005CC5"> sprintf</span><span style="color:#24292E">(</span><span style="color:#032F62">'%c'</span><span style="color:#24292E">, </span><span style="color:#005CC5">array_pop</span><span style="color:#24292E">($m)),</span></span>
-<span class="line"><span style="color:#D73A49"> default</span><span style="color:#D73A49"> =></span><span style="color:#032F62"> 'nop'</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#24292E"> };</span></span>
-<span class="line"><span style="color:#24292E"> $c0 </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $c1;</span></span>
-<span class="line"><span style="color:#D73A49"> for</span><span style="color:#24292E"> ($j </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">; $j </span><span style="color:#D73A49">&#x3C;</span><span style="color:#005CC5"> 8</span><span style="color:#24292E">; $j</span><span style="color:#D73A49">++</span><span style="color:#24292E">) {</span></span>
-<span class="line"><span style="color:#24292E"> $v </span><span style="color:#D73A49">=</span><span style="color:#24292E"> [];</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> ($c1 </span><span style="color:#D73A49">===</span><span style="color:#005CC5"> 1</span><span style="color:#24292E">) {</span></span>
-<span class="line"><span style="color:#24292E"> $x </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $pc </span><span style="color:#D73A49">%</span><span style="color:#24292E"> $w;</span></span>
-<span class="line"><span style="color:#24292E"> $y </span><span style="color:#D73A49">=</span><span style="color:#6F42C1"> intdiv</span><span style="color:#24292E">($pc, $w);</span></span>
-<span class="line"><span style="color:#24292E"> $e </span><span style="color:#D73A49">=</span><span style="color:#24292E"> [($y</span><span style="color:#D73A49">+</span><span style="color:#005CC5">1</span><span style="color:#24292E">)</span><span style="color:#D73A49">*</span><span style="color:#24292E">$w</span><span style="color:#D73A49">-</span><span style="color:#005CC5">1</span><span style="color:#24292E">, ($h</span><span style="color:#D73A49">-</span><span style="color:#005CC5">1</span><span style="color:#24292E">)</span><span style="color:#D73A49">*</span><span style="color:#24292E">$w</span><span style="color:#D73A49">+</span><span style="color:#24292E">$x, $y</span><span style="color:#D73A49">*</span><span style="color:#24292E">$w, $x][$dp];</span></span>
-<span class="line"><span style="color:#24292E"> $z </span><span style="color:#D73A49">=</span><span style="color:#24292E"> [</span><span style="color:#005CC5">1</span><span style="color:#24292E">, $w, </span><span style="color:#D73A49">-</span><span style="color:#005CC5">1</span><span style="color:#24292E">, </span><span style="color:#D73A49">-</span><span style="color:#24292E">$w][$dp];</span></span>
-<span class="line"><span style="color:#D73A49"> for</span><span style="color:#24292E"> ($ep </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $pc; $ep </span><span style="color:#D73A49">!==</span><span style="color:#24292E"> $e; $ep </span><span style="color:#D73A49">+=</span><span style="color:#24292E"> $z)</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> ($cs[$ep] </span><span style="color:#D73A49">!==</span><span style="color:#005CC5"> 1</span><span style="color:#24292E">) </span><span style="color:#D73A49">break</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E"> $ep </span><span style="color:#D73A49">-=</span><span style="color:#24292E"> $z;</span></span>
-<span class="line"><span style="color:#24292E"> $pc </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $ep;</span></span>
-<span class="line"><span style="color:#24292E"> } </span><span style="color:#D73A49">else</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#24292E"> $q </span><span style="color:#D73A49">=</span><span style="color:#24292E"> [$pc];</span></span>
-<span class="line"><span style="color:#24292E"> $ep </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $pc;</span></span>
-<span class="line"><span style="color:#D73A49"> while</span><span style="color:#24292E"> (</span><span style="color:#D73A49">!</span><span style="color:#005CC5">empty</span><span style="color:#24292E">($q)) {</span></span>
-<span class="line"><span style="color:#24292E"> $qq </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> array_pop</span><span style="color:#24292E">($q);</span></span>
-<span class="line"><span style="color:#24292E"> $v[$qq] </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> true</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#D73A49"> foreach</span><span style="color:#24292E"> ([$qq</span><span style="color:#D73A49">+</span><span style="color:#005CC5">1</span><span style="color:#24292E">, $qq</span><span style="color:#D73A49">+</span><span style="color:#24292E">$w, $qq</span><span style="color:#D73A49">-</span><span style="color:#005CC5">1</span><span style="color:#24292E">, $qq</span><span style="color:#D73A49">-</span><span style="color:#24292E">$w] </span><span style="color:#D73A49">as</span><span style="color:#24292E"> $qp) {</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> ($cs[$qp] </span><span style="color:#D73A49">!==</span><span style="color:#24292E"> $c1) </span><span style="color:#D73A49">continue</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> (</span><span style="color:#005CC5">isset</span><span style="color:#24292E">($v[$qp])) </span><span style="color:#D73A49">continue</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E"> $q[] </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $qp;</span></span>
-<span class="line"><span style="color:#24292E"> $qx </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $qp </span><span style="color:#D73A49">%</span><span style="color:#24292E"> $w;</span></span>
-<span class="line"><span style="color:#24292E"> $qy </span><span style="color:#D73A49">=</span><span style="color:#6F42C1"> intdiv</span><span style="color:#24292E">($qp, $w);</span></span>
-<span class="line"><span style="color:#24292E"> $x </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $ep </span><span style="color:#D73A49">%</span><span style="color:#24292E"> $w;</span></span>
-<span class="line"><span style="color:#24292E"> $y </span><span style="color:#D73A49">=</span><span style="color:#6F42C1"> intdiv</span><span style="color:#24292E">($ep, $w);</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> (</span></span>
-<span class="line"><span style="color:#24292E"> ($dp </span><span style="color:#D73A49">===</span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> &#x26;&#x26;</span><span style="color:#24292E"> ($x </span><span style="color:#D73A49">&#x3C;</span><span style="color:#24292E"> $qx </span><span style="color:#D73A49">||</span><span style="color:#24292E"> ($x </span><span style="color:#D73A49">===</span><span style="color:#24292E"> $qx </span><span style="color:#D73A49">&#x26;&#x26;</span><span style="color:#24292E"> ($y</span><span style="color:#D73A49">&#x3C;=></span><span style="color:#24292E">$qy) </span><span style="color:#D73A49">===</span><span style="color:#24292E"> $cc)))</span></span>
-<span class="line"><span style="color:#D73A49"> ||</span><span style="color:#24292E"> ($dp </span><span style="color:#D73A49">===</span><span style="color:#005CC5"> 1</span><span style="color:#D73A49"> &#x26;&#x26;</span><span style="color:#24292E"> ($y </span><span style="color:#D73A49">&#x3C;</span><span style="color:#24292E"> $qy </span><span style="color:#D73A49">||</span><span style="color:#24292E"> ($y </span><span style="color:#D73A49">===</span><span style="color:#24292E"> $qy </span><span style="color:#D73A49">&#x26;&#x26;</span><span style="color:#24292E"> ($qx</span><span style="color:#D73A49">&#x3C;=></span><span style="color:#24292E">$x) </span><span style="color:#D73A49">===</span><span style="color:#24292E"> $cc)))</span></span>
-<span class="line"><span style="color:#D73A49"> ||</span><span style="color:#24292E"> ($dp </span><span style="color:#D73A49">===</span><span style="color:#005CC5"> 2</span><span style="color:#D73A49"> &#x26;&#x26;</span><span style="color:#24292E"> ($qx </span><span style="color:#D73A49">&#x3C;</span><span style="color:#24292E"> $x </span><span style="color:#D73A49">||</span><span style="color:#24292E"> ($qx </span><span style="color:#D73A49">===</span><span style="color:#24292E"> $x </span><span style="color:#D73A49">&#x26;&#x26;</span><span style="color:#24292E"> ($qy</span><span style="color:#D73A49">&#x3C;=></span><span style="color:#24292E">$y) </span><span style="color:#D73A49">===</span><span style="color:#24292E"> $cc)))</span></span>
-<span class="line"><span style="color:#D73A49"> ||</span><span style="color:#24292E"> ($dp </span><span style="color:#D73A49">===</span><span style="color:#005CC5"> 3</span><span style="color:#D73A49"> &#x26;&#x26;</span><span style="color:#24292E"> ($qy </span><span style="color:#D73A49">&#x3C;</span><span style="color:#24292E"> $y </span><span style="color:#D73A49">||</span><span style="color:#24292E"> ($qy </span><span style="color:#D73A49">===</span><span style="color:#24292E"> $y </span><span style="color:#D73A49">&#x26;&#x26;</span><span style="color:#24292E"> ($x</span><span style="color:#D73A49">&#x3C;=></span><span style="color:#24292E">$qx) </span><span style="color:#D73A49">===</span><span style="color:#24292E"> $cc)))</span></span>
-<span class="line"><span style="color:#24292E"> )</span></span>
-<span class="line"><span style="color:#24292E"> $ep </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $qp;</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#24292E"> $np </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $ep </span><span style="color:#D73A49">+</span><span style="color:#24292E"> [</span><span style="color:#005CC5">1</span><span style="color:#24292E">, $w, </span><span style="color:#D73A49">-</span><span style="color:#005CC5">1</span><span style="color:#24292E">, </span><span style="color:#D73A49">-</span><span style="color:#24292E">$w][$dp];</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> ($cs[$np] </span><span style="color:#D73A49">!==</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">) {</span></span>
-<span class="line"><span style="color:#24292E"> $b </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> count</span><span style="color:#24292E">(</span><span style="color:#005CC5">array_keys</span><span style="color:#24292E">($v));</span></span>
-<span class="line"><span style="color:#24292E"> $pc </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $np;</span></span>
-<span class="line"><span style="color:#D73A49"> break</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> ($j </span><span style="color:#D73A49">===</span><span style="color:#005CC5"> 7</span><span style="color:#24292E">) </span><span style="color:#D73A49">break</span><span style="color:#005CC5"> 2</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> ($j </span><span style="color:#D73A49">%</span><span style="color:#005CC5"> 2</span><span style="color:#D73A49"> ===</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">) $cc </span><span style="color:#D73A49">=</span><span style="color:#D73A49"> -</span><span style="color:#24292E">$cc;</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> ($j </span><span style="color:#D73A49">%</span><span style="color:#005CC5"> 2</span><span style="color:#D73A49"> ===</span><span style="color:#005CC5"> 1</span><span style="color:#24292E">) $dp </span><span style="color:#D73A49">=</span><span style="color:#24292E"> ($dp</span><span style="color:#D73A49">+</span><span style="color:#005CC5">1</span><span style="color:#24292E">) </span><span style="color:#D73A49">%</span><span style="color:#005CC5"> 4</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#6A737D">// The original Piet image is wrong: it outputs 403 error for invalid passwords.</span></span>
-<span class="line"><span style="color:#6A737D">// Failure of authentication should be notified by 401, not 403.</span></span>
-<span class="line"><span style="color:#6A737D">// I noticed that one month before PHPerKaigi, but I could not read or write (paint)</span></span>
-<span class="line"><span style="color:#6A737D">// Piet any longer at that time.</span></span>
-<span class="line"><span style="color:#005CC5">fwrite</span><span style="color:#24292E">(</span><span style="color:#005CC5">STDERR</span><span style="color:#24292E">, </span><span style="color:#005CC5">str_replace</span><span style="color:#24292E">(</span><span style="color:#032F62">'403 Forbidden'</span><span style="color:#24292E">, </span><span style="color:#032F62">'401 Unauthorized'</span><span style="color:#24292E">, $o));</span></span></code></pre>
- </div>
- <p>
- これは一体なんなのか。ずばり、難解プログラミング言語の一つ Piet のインタプリタである。Piet はピエト・モンドリアン (『赤・青・黄のコンポジション』などで知られる抽象画家) の作品にインスピレーションを受けて作られた、画像をソースコードとするプログラミング言語である。インタプリタは画像の各ピクセルの上を進みながら、色等に応じて特定の処理をおこなっていく。ここでは詳しい言語仕様については解説しないので、気になる方は <a href="https://ja.wikipedia.org/wiki/Piet" rel="noreferrer" target="_blank">Wikipedia の記事「Piet」</a> などを参照してほしい。
- </p>
- <p>
- プログラムの冒頭にあるこの箇所
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">$b </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> unpack</span><span style="color:#24292E">(</span><span style="color:#032F62">'C*'</span><span style="color:#24292E">, </span><span style="color:#005CC5">file_get_contents</span><span style="color:#24292E">(</span><span style="color:#005CC5">__FILE__</span><span style="color:#24292E">));</span></span></code></pre>
- </div>
- <p>
- で <code>__FILE__</code> つまりこの画像ファイルを読み込んでいる。先ほど Piet は画像をソースコードにしていると説明した。そう、今回の問題の画像ファイル <code>Q1.png</code> は、PHP 製 Piet インタプリタであると同時に、Piet のソースコード画像でもあるのだ。QR コード中央のカラフルな部分が Piet の命令になっている。
- </p>
- </section>
- <section id="section--commentary--piet-source-code">
- <h3><a href="#section--commentary--piet-source-code">Piet のソースコード</a></h3>
- <p>
- さて、Piet でどのようなコードが書かれて (いや、描かれて) いるのかを解説したいところだが、今の私にはできそうにない。というのも、すでに述べたように Piet は「難解プログラミング言語」である。およそ人が描いたり読んだりするようには作られていない。性質としては、パズルに近い代物である。
- </p>
- <p>
- というわけで、ここではあらましを説明するだけでご容赦いただきたい。それぞれの部分はおおよそ次のようなことをやっている (再検証・再読解はしていないので大嘘かもしれない)。
- </p>
- <ul>
- <li>
- 左上: 入力受け付け
- <ul>
- <li>
- 標準入力から1文字ずつ読み込み、入力がなくなるまでスタックに積む。多分。
- </li>
- </ul>
- </li>
- <li>
- 上辺、右辺: パスワードの検証
- <ul>
- <li>
- 入力がパスワードと一致するか (= <code>#iwillblog</code> かどうか) を調べる。多分。
- </li>
- </ul>
- </li>
- <li>
- 下辺、左辺、上辺の3列目、右辺の3列目、下辺の2列目: トークンの出力
- <ul>
- <li>
- パスワードと一致していればここに飛んでくる。正解のトークンを出力する。多分。
- </li>
- </ul>
- </li>
- <li>
- 右辺の2列目、上辺の2列目: 不正解のメッセージ出力
- <ul>
- <li>
- パスワードと一致していなければここに飛んでくる。不正解のときのメッセージを出力する。多分。
- </li>
- </ul>
- </li>
- </ul>
- <p>
- ところで、先ほど掲載した Piet のインタプリタのソースコード末尾には次のような箇所がある。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6A737D">// The original Piet image is wrong: it outputs 403 error for invalid passwords.</span></span>
-<span class="line"><span style="color:#6A737D">// Failure of authentication should be notified by 401, not 403.</span></span>
-<span class="line"><span style="color:#6A737D">// I noticed that one month before PHPerKaigi, but I could not read or write (paint)</span></span>
-<span class="line"><span style="color:#6A737D">// Piet any longer at that time.</span></span>
-<span class="line"><span style="color:#005CC5">fwrite</span><span style="color:#24292E">(</span><span style="color:#005CC5">STDERR</span><span style="color:#24292E">, </span><span style="color:#005CC5">str_replace</span><span style="color:#24292E">(</span><span style="color:#032F62">'403 Forbidden'</span><span style="color:#24292E">, </span><span style="color:#032F62">'401 Unauthorized'</span><span style="color:#24292E">, $o));</span></span></code></pre>
- </div>
- <p>
- コメントにも書かれているが、この Piet のソースコード画像には誤りがあった。本来 HTTP のステータスコードを真似るのなら、認証の失敗には 401 を返さなければならない。しかし、Piet のソースは 403 を返すように書いてしまっていた。そのことに私が気付いたのは PHPerKaigi 2023 が開催されるひと月前で、その時点で私はこの Piet のソースコードを (ちょうどこの記事でそうなっているのと同じように) 読解できなくなっていた。さらに悪いことに、正しいメッセージ「401 Unauthorized」は元の「403 Forbidden」よりも3文字長い。3文字出力が長くなるということは、それだけ Piet で塗るべきピクセルが増えることを意味する。もはや3文字追加で出力するだけの余白はこの画像に残されていなかった (と思う。腕ききの Piet プログラマならできるかもしれないので挑戦してみてほしい)。
- </p>
- <p>
- これを解決するために私が選んだのは、インタプリタを改造し、本来のメッセージとは異なるメッセージを無理やり出力させて帳尻を合わせることだった。そういうわけでこの Piet インタプリタは完全な Piet インタプリタではなく、「403 Forbidden」というテキストを絶対に出力できない。
- </p>
- </section>
- <section id="section--commentary--misc">
- <h3><a href="#section--commentary--misc">その他小ネタ</a></h3>
- <p>
- ここまでで問題の核心部分は説明し終えたので、ここからは残った小ネタを紹介しておく。
- </p>
- <p>
- この問題のタイトル『An Art of Computer Programming』は、ドナルド・クヌースの『The Art of Computer Programming』をパロディしたものである。
- </p>
- <p>
- この問題で得られるトークン「#ModernPHPisStaticallyTypedLanguage」は特に元ネタがあるわけではない。当然のような顔で嘘を主張したかったのでこうなった。
- </p>
- </section>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">おわりに</a></h2>
- <p>
- この問題の自己評価はこちら。問題の出題順はおおよそ作成した順になっているのだが、そのせいで難易度高めの問題が1問目に配置されてしまった。これは反省点の一つである。
- </p>
- <ul>
- <li>
- 難しさ: ★★★★
- </li>
- <li>
- お気に入り度: ★★
- </li>
- <li>
- 鮮やかさ: ★★★★★★★
- </li>
- </ul>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2025-01-26/yaml-breaking-changes-between-v1-1-and-v1-2/index.html b/vhosts/blog/public/posts/2025-01-26/yaml-breaking-changes-between-v1-1-and-v1-2/index.html
deleted file mode 100644
index 1e0d983a..00000000
--- a/vhosts/blog/public/posts/2025-01-26/yaml-breaking-changes-between-v1-1-and-v1-2/index.html
+++ /dev/null
@@ -1,135 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2025 nsfisis">
- <meta name="description" content="データ記述言語 YAML におけるバージョン 1.1 と 1.2 の主な破壊的変更をまとめた。">
- <meta name="keywords" content="YAML">
- <meta property="og:type" content="article">
- <meta property="og:title" content="【YAML】YAML 1.1 と YAML 1.2 の主な破壊的変更|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="データ記述言語 YAML におけるバージョン 1.1 と 1.2 の主な破壊的変更をまとめた。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>【YAML】YAML 1.1 と YAML 1.2 の主な破壊的変更|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">【YAML】YAML 1.1 と YAML 1.2 の主な破壊的変更</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/yaml/">YAML</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2021-06-30">2021-06-30</time>: デジタルサーカス株式会社の社内記事として公開
- </li>
- <li class="revision">
- <time datetime="2025-01-26">2025-01-26</time>: ブログ記事として一般公開
- </li>
- </ol>
- </section>
- <div class="admonition">
- <div class="admonition-label">
- NOTE
- </div>
- <div class="admonition-content">
- <p>
- この記事は、2021-06-30 に <a href="https://www.dgcircus.com/" rel="noreferrer" target="_blank">デジタルサーカス株式会社</a> の社内 Qiita Team に公開された記事をベースに、加筆修正して一般公開したものです。
- </p>
- </div>
- </div>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- データ記述言語の一つ YAML には 1.0、1.1、1.2 のバージョンがある。これらのうち、1.1 と 1.2 の間には無視できない非互換の変更が多く、1.2 に対応していないライブラリもある (Ruby 同梱の <code>yaml</code> など)。この記事では、YAML 1.1 と YAML 1.2 の主な破壊的変更を紹介する (影響範囲が広いものを抜粋しており、すべての非互換を網羅してはいない)。
- </p>
- <p>
- 参照した仕様書はこちら: <a href="https://yaml.org/spec/1.2.2/ext/changes/" rel="noreferrer" target="_blank">https://yaml.org/spec/1.2.2/ext/changes/</a>
- </p>
- </section>
- <section id="section--breaking-changes">
- <h2><a href="#section--breaking-changes">主な破壊的変更</a></h2>
- <section id="section--breaking-changes--boolean-literals">
- <h3><a href="#section--breaking-changes--boolean-literals">Boolean としてパースされるトークンが <code>true</code> / <code>false</code> とその亜種のみに</a></h3>
- <p>
- この変更の影響が最も大きいと思われる。YAML 1.1 では、boolean 値のリテラルとして <code>true</code>、<code>false</code> のほか <code>yes</code>、<code>no</code>、<code>y</code>、<code>n</code>、<code>on</code>、<code>off</code>、それらの大文字バージョンなどが認められていた。YAML 1.2 では、<code>true</code> と <code>false</code>、それらの大文字バージョン (<code>True</code>、<code>TRUE</code>、<code>False</code>、<code>FALSE</code>) のみが boolean としてパースされるようになった。
- </p>
- </section>
- <section id="section--breaking-changes--octal-literals">
- <h3><a href="#section--breaking-changes--octal-literals">八進数リテラルには <code>0o</code> が必須に</a></h3>
- <p>
- C 言語などでは、<code>0</code> から始まる数字の列を八進数としてパースする。YAML 1.1 もこれに準じていたが、1.2 からは <code>0o</code> のプレフィクスが必須となった (“o” は “octal” の “o”)。プログラミング言語では、Python や Haskell、Swift、Rust などがこの記法を採用している。
- </p>
- </section>
- <section id="section--breaking-changes--merging">
- <h3><a href="#section--breaking-changes--merging"><code>&lt;&lt;</code> によるマージが不可能に</a></h3>
- <p>
- YAML 1.1 では、<code>&lt;&lt;</code> という文字列をキーに指定することで、マップをマージすることができた。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#22863A">x</span><span style="color:#24292E">: </span><span style="color:#D73A49">&#x26;</span><span style="color:#6F42C1">base</span></span>
-<span class="line"><span style="color:#22863A"> a</span><span style="color:#24292E">: </span><span style="color:#005CC5">123</span></span>
-<span class="line"><span style="color:#6A737D"># => { "x": { "a": 123 } }</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#005CC5">y</span><span style="color:#24292E">:</span></span>
-<span class="line"><span style="color:#005CC5"> &#x3C;&#x3C;</span><span style="color:#24292E">: </span><span style="color:#D73A49">*</span><span style="color:#24292E">base</span></span>
-<span class="line"><span style="color:#22863A"> b</span><span style="color:#24292E">: </span><span style="color:#005CC5">456</span></span>
-<span class="line"><span style="color:#6A737D"># => { "y": { "a": 123, "b": 456 } }</span></span></code></pre>
- </div>
- <p>
- 1.2 からはこれができなくなる。
- </p>
- </section>
- <section id="section--breaking-changes--number-separator">
- <h3><a href="#section--breaking-changes--number-separator">数字を <code>_</code> で区切るのが禁止に</a></h3>
- <p>
- <code>1234567</code> を <code>1_234_567</code> と書けなくなった。
- </p>
- </section>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">おわりに</a></h2>
- <p>
- 全体的に、<em>There’s more than one way to do it.</em> から <em>There should be one - and preferably only one - obvious way to do it.</em> へ移行しているように思われる。データ記述言語としては望ましい方向性ではないかと感じる。
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2025-02-24/phpcon-nagoya-2025-report/index.html b/vhosts/blog/public/posts/2025-02-24/phpcon-nagoya-2025-report/index.html
deleted file mode 100644
index 82b9d835..00000000
--- a/vhosts/blog/public/posts/2025-02-24/phpcon-nagoya-2025-report/index.html
+++ /dev/null
@@ -1,121 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2025 nsfisis">
- <meta name="description" content="2025-02-22 に開催された、PHP カンファレンス名古屋 2025 に参加した。">
- <meta name="keywords" content="カンファレンス,PHP,PHP カンファレンス名古屋">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHP カンファレンス名古屋 2025 参加レポ|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="2025-02-22 に開催された、PHP カンファレンス名古屋 2025 に参加した。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHP カンファレンス名古屋 2025 参加レポ|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">PHP カンファレンス名古屋 2025 参加レポ</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/conference/">カンファレンス</a>
- </li>
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phpcon-nagoya/">PHP カンファレンス名古屋</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2025-02-24">2025-02-24</time>: 公開
- </li>
- </ol>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- 2025-02-22 に開催された <a href="https://phpcon.nagoya/2025/" rel="noreferrer" target="_blank">PHP カンファレンス名古屋</a> に参加した。
- </p>
- </section>
- <section id="section--sessions">
- <h2><a href="#section--sessions">セッション感想</a></h2>
- <p>
- 特に印象に残ったセッションを二つピックアップした (タイトルと発表者名は fortee のプロポーザルページによる)。
- </p>
- <ul>
- <li>
- <a href="https://fortee.jp/phpcon-nagoya-2025/proposal/26795bcc-78dd-431e-9538-7450779fa2cf" rel="noreferrer" target="_blank">PHPで印刷所に入稿できる名札データを作る by 長谷川智希 さん</a>
- <ul>
- <li>
- PHPerKaigi や iOSDC の名札は品質が高いので、他の勉強会やカンファレンスでもついつい使ってしまうのですが、その裏側を覗くことができ面白かったです。カンファレンスの1セッションという形でなければ触れることのないような話が聴けるのはカンファレンスに参加する醍醐味の一つだと思います。
- </li>
- </ul>
- </li>
- <li>
- <a href="https://fortee.jp/phpcon-nagoya-2025/proposal/d3ecbb68-318d-4b03-abfe-9ecccc6beb81" rel="noreferrer" target="_blank">PHP 製 OSS のメモリ問題を辻斬りしていく by sji さん</a>
- <ul>
- <li>
- 今回一番楽しみにしていた発表です。 <a href="https://github.com/reliforp/reli-prof" rel="noreferrer" target="_blank">Reli</a> は以前 <a href="/slides/2024-03-15/ya8-2024/">自作の WebAssembly 処理系を高速化するのに使ったのもあり</a> その強力さについてはある程度知っていたつもりでしたが、実際に広く使われているライブラリでの調査過程を見ると唸るばかりです。これをすべて (FFI こそ使っているものの) pure PHP で実装しているとは俄に信じられません。
- </li>
- </ul>
- </li>
- </ul>
- </section>
- <section id="section--my-session">
- <h2><a href="#section--my-session">登壇したセッション</a></h2>
- <p>
- <a href="https://fortee.jp/phpcon-nagoya-2025/proposal/24a2ec04-ca57-46f1-905c-52143a449eea" rel="noreferrer" target="_blank">「PHP 処理系の garbage collection を理解する 〜メモリはいつ解放されるのか〜」</a> というタイトルで登壇もおこなった。タイトルどおり、PHP の garbage collection (GC) について扱った発表である。
- </p>
- <p>
- 技術的な内容としては <a href="https://www.php.net/manual/ja/features.gc.php" rel="noreferrer" target="_blank">PHP のマニュアルの GC に関する記述</a> を出ていないものの、PHP 処理系の内部的な用語を使わないようにしたり、本質的でない処理を省いたりして、理解のための前提条件を減らせたのではないかと思う。
- </p>
- <p>
- ところで今回スライドのフォントサイズを大きくするために各スライドの見出し部分を消してみたのだが、結局ほとんどのスライドで見出しらしき文言が必要になったので、あまり効果はなかったかもしれない。
- </p>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">おわりに</a></h2>
- <p>
- 今回もカンファレンスくらいでしか聴けないようなセッションがいくつも聴けてよかった。また、ちょうど連休だったのもあり名古屋も楽しむことができた。運営のみなさま、お疲れさまでした&amp;ありがとうございました。次は PHPerKaigi 2025 で会いましょう。
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2025-03-27/zip-function-like-command-paste-command/index.html b/vhosts/blog/public/posts/2025-03-27/zip-function-like-command-paste-command/index.html
deleted file mode 100644
index 11401ae6..00000000
--- a/vhosts/blog/public/posts/2025-03-27/zip-function-like-command-paste-command/index.html
+++ /dev/null
@@ -1,153 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2025 nsfisis">
- <meta name="description" content="zip 関数のような動きをする paste コマンドについてのメモ。">
- <meta name="keywords" content="備忘録">
- <meta property="og:type" content="article">
- <meta property="og:title" content="zip 関数のようなコマンド paste|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="zip 関数のような動きをする paste コマンドについてのメモ。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>zip 関数のようなコマンド paste|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">zip 関数のようなコマンド paste</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/note-to-self/">備忘録</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2021-03-22">2021-03-22</time>: デジタルサーカス株式会社の社内記事として公開
- </li>
- <li class="revision">
- <time datetime="2025-03-27">2025-03-27</time>: ブログ記事として一般公開
- </li>
- </ol>
- </section>
- <div class="admonition">
- <div class="admonition-label">
- NOTE
- </div>
- <div class="admonition-content">
- <p>
- この記事は、2021-03-22 に <a href="https://www.dgcircus.com/" rel="noreferrer" target="_blank">デジタルサーカス株式会社</a> の社内 Qiita Team に公開された記事をベースに、加筆修正して一般公開したものです。
- </p>
- </div>
- </div>
- <section id="section--intro">
- <h2><a href="#section--intro">実現したい内容</a></h2>
- <p>
- 次の2ファイル <code>a.txt</code> / <code>b.txt</code> から出力 <code>ab.txt</code> を得たい。
- </p>
- <p>
- <code>a.txt</code>
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>a1</span></span>
-<span class="line"><span>a2</span></span>
-<span class="line"><span>a3</span></span></code></pre>
- </div>
- <p>
- <code>b.txt</code>
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>b1</span></span>
-<span class="line"><span>b2</span></span>
-<span class="line"><span>b3</span></span></code></pre>
- </div>
- <p>
- <code>ab.txt</code>
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>a1</span></span>
-<span class="line"><span>b1</span></span>
-<span class="line"><span>a2</span></span>
-<span class="line"><span>b2</span></span>
-<span class="line"><span>a3</span></span>
-<span class="line"><span>b3</span></span></code></pre>
- </div>
- <p>
- ちょうど Python や Haskell などにある <code>zip</code> 関数のような動きをさせたい。
- </p>
- </section>
- <section id="section--paste-command">
- <h2><a href="#section--paste-command">実現方法</a></h2>
- <p>
- 記事タイトルに書いたように、<code>paste</code> コマンドを使うと実現できる。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ paste -d '\</span></span>
-<span class="line"><span>' a.txt b.txt > ab.txt</span></span></code></pre>
- </div>
- <p>
- <code>paste</code> コマンドは複数のファイルを引数に取り、それらを1行ずつ消費しながら <code>-d</code> で指定した文字で区切って出力する。<code>-d</code> は区切り文字の指定で、デフォルトだとタブ区切りになる。
- </p>
- <p>
- ファイル名には <code>-</code> を指定でき、その場合は標準入力から読み込んで出力する。このとき <code>paste - -</code> のように複数回 <code>-</code> を指定すると、指定した回数の行ごとに連結することができる。例えば <code>ab.txt</code> だとこうなる。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ paste - - &#x3C; ab.txt</span></span>
-<span class="line"><span>a1 b1</span></span>
-<span class="line"><span>a2 b2</span></span>
-<span class="line"><span>a3 b3</span></span></code></pre>
- </div>
- <p>
- これは標準入力を使うとき特有の挙動で、単に同じファイル名を指定してもこうはならない。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ paste ab.txt ab.txt</span></span>
-<span class="line"><span>a1 a1</span></span>
-<span class="line"><span>b1 b1</span></span>
-<span class="line"><span>a2 a2</span></span>
-<span class="line"><span>b2 b2</span></span>
-<span class="line"><span>a3 a3</span></span>
-<span class="line"><span>b3 b3</span></span></code></pre>
- </div>
- <p>
- ときどき便利。
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2025-03-28/http-1-1-send-multiple-same-headers/index.html b/vhosts/blog/public/posts/2025-03-28/http-1-1-send-multiple-same-headers/index.html
deleted file mode 100644
index f0e17c27..00000000
--- a/vhosts/blog/public/posts/2025-03-28/http-1-1-send-multiple-same-headers/index.html
+++ /dev/null
@@ -1,171 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2025 nsfisis">
- <meta name="description" content="HTTP/1.1 で同じヘッダを2回送ったときの挙動について仕様を読んでまとめた。">
- <meta name="keywords" content="HTTP">
- <meta property="og:type" content="article">
- <meta property="og:title" content="【HTTP】HTTP/1.1 で同じヘッダを2回送るとどうなるか|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="HTTP/1.1 で同じヘッダを2回送ったときの挙動について仕様を読んでまとめた。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>【HTTP】HTTP/1.1 で同じヘッダを2回送るとどうなるか|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">【HTTP】HTTP/1.1 で同じヘッダを2回送るとどうなるか</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/http/">HTTP</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2022-08-18">2022-08-18</time>: デジタルサーカス株式会社の社内記事として公開
- </li>
- <li class="revision">
- <time datetime="2025-03-28">2025-03-28</time>: ブログ記事として一般公開
- </li>
- </ol>
- </section>
- <div class="admonition">
- <div class="admonition-label">
- NOTE
- </div>
- <div class="admonition-content">
- <p>
- この記事は、2022-08-18 に <a href="https://www.dgcircus.com/" rel="noreferrer" target="_blank">デジタルサーカス株式会社</a> の社内 Qiita Team に公開された記事をベースに、加筆修正して一般公開したものです。
- </p>
- </div>
- </div>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- HTTP version 1.1 で同じ名前のヘッダを2回送ると、どのように解釈されるのか。仕様を確認した。
- </p>
- <p>
- 今回読んだ仕様は RFC 7230 で、こちらのリンクから閲覧できる: <a href="https://datatracker.ietf.org/doc/html/rfc7230" rel="noreferrer" target="_blank">https://datatracker.ietf.org/doc/html/rfc7230</a>
- </p>
- <p>
- その中でも、<a href="https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.2" rel="noreferrer" target="_blank">https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.2</a> を主に引用する。
- </p>
- <p>
- ところで、HTTP 周りの仕様を探すときはここから飛ぶと便利: <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Resources_and_specifications" rel="noreferrer" target="_blank">https://developer.mozilla.org/en-US/docs/Web/HTTP/Resources_and_specifications</a>
- </p>
- </section>
- <section id="section--specification">
- <h2><a href="#section--specification">仕様</a></h2>
- <section id="section--specification--sender">
- <h3><a href="#section--specification--sender">送信側</a></h3>
- <blockquote>
- <p>
- A sender MUST NOT generate multiple header fields with the same field name in a message unless either the entire field value for that header field is defined as a comma-separated list [i.e., #(values)] or the header field is a well-known exception (as noted below).
- </p>
- </blockquote>
- <p>
- 【日本語訳 (私が訳したもので、公式なものではない)】 送信者は、同じ field name の header field を複数生成してはならない (MUST NOT)。ただし、header field の値がコンマ区切りのリストとして定義されているか、header field がよく知られた例外 (後述) である場合はその限りでない。
- </p>
- </section>
- <section id="section--specification--recipient">
- <h3><a href="#section--specification--recipient">受信側</a></h3>
- <blockquote>
- <p>
- A recipient MAY combine multiple header fields with the same field name into one “field-name: field-value” pair, without changing the semantics of the message, by appending each subsequent field value to the combined field value in order, separated by a comma. The order in which header fields with the same field name are received is therefore significant to the interpretation of the combined field value; a proxy MUST NOT change the order of these field values when forwarding a message.
- </p>
- </blockquote>
- <p>
- 【日本語訳 (私が訳したもので、公式なものではない)】 受信者は、同じ field name を持つ複数の header field を、メッセージの意味を変えないようにしつつ同じ順序で追加して、単一のコンマで区切られた <code>&quot;field-name: field-value&quot;</code> のペアに結合してよい (MAY)。したがって、同じ field name を持つ header field がどのような順序で受信されたかは、結合された値の解釈に影響する。よって、プロキシは、メッセージを転送する際、header field の順序を変えてはならない (MUST NOT)。
- </p>
- </section>
- <section id="section--specification--exception">
- <h3><a href="#section--specification--exception">例外ケース: Set-Cookie</a></h3>
- <blockquote>
- <p>
- Note: In practice, the “Set-Cookie” header field ([<a href="https://datatracker.ietf.org/doc/html/rfc6265" rel="noreferrer" target="_blank">RFC6265</a>]) often appears multiple times in a response message and does not use the list syntax, violating the above requirements on multiple header fields with the same name. Since it cannot be combined into a single field-value, recipients ought to handle “Set-Cookie” as a special case while processing header fields. (See Appendix A.2.3 of [Kri2001] for details.)
- </p>
- </blockquote>
- <p>
- 【日本語訳 (私が訳したもので、公式なものではない)】 注意: 実際には、<code>Set-Cookie</code> header field (<a href="https://datatracker.ietf.org/doc/html/rfc6265" rel="noreferrer" target="_blank">RFC6265</a>) は、しばしばレスポンスメッセージ中に複数回現れる。これはリストの構文を使っておらず、上述した同じ field name を持つ header field についての要件に違反している。この値は単一の値へ結合できないため、受信者は、header field を処理する際、<code>Set-Cookie</code> を特別扱いした方がよい。
- </p>
- <p>
- おそらく、「送信側」のところで書かれている「よく知られた例外」の一つがこれだと思われる。
- </p>
- </section>
- <section id="section--specification--comma-separated-list">
- <h3><a href="#section--specification--comma-separated-list">どの header field がコンマ区切りのリストなのか</a></h3>
- <p>
- 上記のように、同じ field name を持つ header field を複数回送れるかどうかは、その header field がコンマ区切りのリストとして定義されているかどうかで決まる。では、特定の header field がその条件を満たしているかどうか知りたいときは、何を見ればよいのか。
- </p>
- <p>
- HTTP の仕様として定義されているような header field であれば、下記のリンクからそれぞれの定義を参照できる。
- </p>
- <ul>
- <li>
- <a href="https://datatracker.ietf.org/doc/html/rfc7231#section-5" rel="noreferrer" target="_blank">https://datatracker.ietf.org/doc/html/rfc7231#section-5</a>
- </li>
- <li>
- <a href="https://datatracker.ietf.org/doc/html/rfc7231#section-7" rel="noreferrer" target="_blank">https://datatracker.ietf.org/doc/html/rfc7231#section-7</a>
- </li>
- </ul>
- <p>
- そうでない場合 (たとえば <code>X-</code> から始まるもの等) は、MDN や各ベンダのドキュメントを探すことになるだろう。
- </p>
- </section>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">まとめ</a></h2>
- <ul>
- <li>
- 送信側: 基本的には複数回送れない。コンマ区切りのヘッダは例外
- </li>
- <li>
- 受信側: 基本的には未規定。コンマ区切りのヘッダは複数回来たらその順に結合する
- </li>
- <li>
- プロキシ: 順序を変えてはならない
- </li>
- <li>
- <code>Set-Cookie</code> は例外ケース
- </li>
- </ul>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/index.html b/vhosts/blog/public/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/index.html
deleted file mode 100644
index 1c36083a..00000000
--- a/vhosts/blog/public/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/index.html
+++ /dev/null
@@ -1,285 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2025 nsfisis">
- <meta name="description" content="RubyKaigi 2025 で開催された TRICK において、『最もRuby on Ruby賞』として審査員賞をいただいた。">
- <meta name="keywords" content="カンファレンス,Ruby,RubyKaigi,TRICK">
- <meta property="og:type" content="article">
- <meta property="og:title" content="RubyKaigi 2025 の TRICK で入賞した|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="RubyKaigi 2025 で開催された TRICK において、『最もRuby on Ruby賞』として審査員賞をいただいた。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>RubyKaigi 2025 の TRICK で入賞した|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">RubyKaigi 2025 の TRICK で入賞した</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/conference/">カンファレンス</a>
- </li>
- <li class="tag">
- <a href="/tags/ruby/">Ruby</a>
- </li>
- <li class="tag">
- <a href="/tags/rubykaigi/">RubyKaigi</a>
- </li>
- <li class="tag">
- <a href="/tags/trick/">TRICK</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2025-04-20">2025-04-20</time>: 公開
- </li>
- </ol>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- 2025-04-16 から 2025-04-18 にかけて開催された <a href="https://rubykaigi.org/2025/" rel="noreferrer" target="_blank">RubyKaigi 2025</a> に参加した (私が参加できたのは 1日目の 2025-04-16 のみ)。
- </p>
- <p>
- 地元松山での大規模なカンファレンスということでスケジュールに無理を言わせて 1日目だけでもと参加したのだが、そこで開催された <a href="https://github.com/tric/trick2025" rel="noreferrer" target="_blank">TRICK 2025</a> で審査員賞をいただいた。
- </p>
- <p>
- この記事では、提出した作品の紹介と解説をおこなおうと思う。
- </p>
- </section>
- <section id="section--trick">
- <h2><a href="#section--trick">TRICK とは</a></h2>
- <p>
- TRICK とは RubyKaigi で不定期に開催されているコンテストで、Ruby で書かれた「変わった」コードを表彰する。早い話が <a href="https://www.ioccc.org/" rel="noreferrer" target="_blank">IOCCC</a> の Ruby 版である。
- </p>
- <p>
- 存在を知ってから次こそは出したいと思っていたところ、ちょうど RubyKaigi の地元開催と被ったのでこれ幸いとエントリーした。
- </p>
- </section>
- <section id="section--my-work">
- <h2><a href="#section--my-work">作品紹介</a></h2>
- <p>
- 今回頂いたのは審査員賞の一つ eto award (公式の賞の名前に合わせて敬称略) で、“Most Ruby-on-Ruby” Award (『最もRuby on Ruby賞』) として受賞した (IOCCC と同じく、それぞれの賞に個別の名前が付く)。
- </p>
- <p>
- ソースコード等はこちら: <a href="https://github.com/tric/trick2025/tree/main/10-nsfisis" rel="noreferrer" target="_blank">https://github.com/tric/trick2025/tree/main/10-nsfisis</a>
- </p>
- <p>
- 今回の TRICK では <code>ruby.wasm</code> の使用が認められている。
- </p>
- <blockquote>
- <ul>
- <li>
- <strong>(NEW)</strong> You can use <a href="https://github.com/ruby/ruby.wasm" rel="noreferrer" target="_blank">ruby.wasm</a>.
- </li>
- </ul>
- </blockquote>
- <p>
- 適当に HTTP サーバを立てて <a href="https://github.com/tric/trick2025/blob/main/10-nsfisis/index.html" rel="noreferrer" target="_blank"><code>index.html</code></a> を開くと、次のように <a href="https://github.com/tric/trick2025/blob/main/10-nsfisis/entry.rb" rel="noreferrer" target="_blank"><code>entry.rb</code></a> の内容が表示される。
- </p>
- <p>
- <img alt="ブラウザで表示された index.html のレンダリング結果。entry.rb の内容がシンタックスハイライトされて表示されており、英単語や記号に振り仮名が振られている" src="/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/screenshot.png">
- </p>
- <p>
- 自身のソースコードを出力するプログラム、いわゆる quine の亜種になっている。
- </p>
- <p>
- しかし、このプログラムは単にソースコードをそのまま出力するのではなく、
- </p>
- <ul>
- <li>
- シンタックスハイライトして、
- </li>
- <li>
- 英単語や記号に振り仮名を振って、
- </li>
- <li>
- HTML で、
- </li>
- </ul>
- <p>
- 表示している。つまり、Ruby プログラムにルビを振った作品である。例えば、先頭の2行目の <code>require</code> は次のような HTML で構成されている。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">&#x3C;</span><span style="color:#22863A">ruby</span><span style="color:#6F42C1"> class</span><span style="color:#24292E">=</span><span style="color:#032F62">"IDENTIFIER"</span><span style="color:#24292E">>require&#x3C;</span><span style="color:#22863A">rp</span><span style="color:#6F42C1"> class</span><span style="color:#24292E">=</span><span style="color:#032F62">""</span><span style="color:#24292E">>(&#x3C;/</span><span style="color:#22863A">rp</span><span style="color:#24292E">>&#x3C;</span><span style="color:#22863A">rt</span><span style="color:#6F42C1"> class</span><span style="color:#24292E">=</span><span style="color:#032F62">""</span><span style="color:#24292E">>リクワイア&#x3C;/</span><span style="color:#22863A">rt</span><span style="color:#24292E">>&#x3C;</span><span style="color:#22863A">rp</span><span style="color:#6F42C1"> class</span><span style="color:#24292E">=</span><span style="color:#032F62">""</span><span style="color:#24292E">>)&#x3C;/</span><span style="color:#22863A">rp</span><span style="color:#24292E">>&#x3C;/</span><span style="color:#22863A">ruby</span><span style="color:#24292E">></span></span></code></pre>
- </div>
- <p>
- 順に使ったテクニックを解説していく。
- </p>
- <section id="section--my-work--quine">
- <h3><a href="#section--my-work--quine">Quine</a></h3>
- <p>
- 改めて quine について説明する。Quine とは、自身のソースコードを出力するようなプログラムである。Ruby では様々な方法で quine を書くことができるが、この作品で使っている基本形は以下のようなものである。
- </p>
- <div class="codeblock numbered">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#005CC5">eval</span><span style="color:#24292E"> $s</span><span style="color:#032F62">=&#x3C;&#x3C;'EOS'</span></span>
-<span class="line"><span style="color:#032F62">print "eval $s=&#x3C;&#x3C;'EOS'</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span></span>
-<span class="line"><span style="color:#032F62">print $s</span></span>
-<span class="line"><span style="color:#032F62">print "EOS</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span></span>
-<span class="line"><span style="color:#032F62">EOS</span></span></code></pre>
- </div>
- <p>
- 変数 <code>$s</code> に 2 行目、3 行目、4 行目が入っており、それに加えて 1 行目と 5 行目を出力すれば元のソースコードが得られる。実際には <code>$s</code> を加工してシンタックスハイライトや振り仮名を振ることになる。
- </p>
- </section>
- <section id="section--my-work--syntax-highlight">
- <h3><a href="#section--my-work--syntax-highlight">シンタックスハイライト</a></h3>
- <p>
- シンタックスハイライトは、トークナイズとトークン種別に応じた色付けの2段階からなる。
- </p>
- <p>
- トークナイズには Ruby 3.4 からデフォルトのパーサになった <a href="https://github.com/ruby/prism" rel="noreferrer" target="_blank">Prism</a> を利用している。<code>Prism.lex()</code> を使うとトークナイズができるので、トークンに付いているソースコード位置の情報を使いつつ元のソースコードを復元する。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#E36209">y</span><span style="color:#D73A49"> =</span><span style="color:#005CC5"> 1</span><span style="color:#6A737D"> # 現在の行</span></span>
-<span class="line"><span style="color:#E36209">x</span><span style="color:#D73A49"> =</span><span style="color:#005CC5"> 0</span><span style="color:#6A737D"> # 現在の列</span></span>
-<span class="line"><span style="color:#005CC5">Prism</span><span style="color:#24292E">.</span><span style="color:#6F42C1">lex</span><span style="color:#24292E">($s).</span><span style="color:#6F42C1">value</span><span style="color:#24292E">[..</span><span style="color:#D73A49">-</span><span style="color:#005CC5">2</span><span style="color:#24292E">].</span><span style="color:#6F42C1">each</span><span style="color:#24292E"> {|t, *|</span></span>
-<span class="line"><span style="color:#E36209"> l</span><span style="color:#D73A49"> =</span><span style="color:#24292E"> t.</span><span style="color:#6F42C1">location</span></span>
-<span class="line"><span style="color:#E36209"> r</span><span style="color:#D73A49"> =</span><span style="color:#24292E"> l.</span><span style="color:#6F42C1">start_line</span><span style="color:#6A737D"> # トークンの開始行</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> y </span><span style="color:#D73A49">&#x3C;</span><span style="color:#24292E"> r </span><span style="color:#6A737D"># 改行が必要なら</span></span>
-<span class="line"><span style="color:#005CC5"> p</span><span style="color:#032F62"> "</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#D73A49"> *</span><span style="color:#24292E"> (r </span><span style="color:#D73A49">-</span><span style="color:#24292E"> y) </span><span style="color:#6A737D"># 改行を挿入して</span></span>
-<span class="line"><span style="color:#E36209"> x</span><span style="color:#D73A49"> =</span><span style="color:#005CC5"> 0</span><span style="color:#6A737D"> # 列の先頭へ戻る</span></span>
-<span class="line"><span style="color:#D73A49"> end</span></span>
-<span class="line"><span style="color:#E36209"> c</span><span style="color:#D73A49"> =</span><span style="color:#24292E"> l.</span><span style="color:#6F42C1">start_column</span><span style="color:#6A737D"> # トークンの開始列</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> x </span><span style="color:#D73A49">&#x3C;</span><span style="color:#24292E"> c </span><span style="color:#6A737D"># 空白が必要なら</span></span>
-<span class="line"><span style="color:#005CC5"> p</span><span style="color:#032F62"> " "</span><span style="color:#D73A49"> *</span><span style="color:#24292E"> (c </span><span style="color:#D73A49">-</span><span style="color:#24292E"> x) </span><span style="color:#6A737D"># 空白を挿入</span></span>
-<span class="line"><span style="color:#D73A49"> end</span></span>
-<span class="line"><span style="color:#005CC5"> p</span><span style="color:#6F42C1"> ruby</span><span style="color:#24292E">(t) </span><span style="color:#6A737D"># トークン本体を出力</span></span>
-<span class="line"><span style="color:#E36209"> y</span><span style="color:#D73A49"> =</span><span style="color:#24292E"> l.</span><span style="color:#6F42C1">end_line</span><span style="color:#6A737D"> # 現在行を更新</span></span>
-<span class="line"><span style="color:#E36209"> x</span><span style="color:#D73A49"> =</span><span style="color:#24292E"> l.</span><span style="color:#6F42C1">end_column</span><span style="color:#6A737D"> # 現在列を更新</span></span>
-<span class="line"><span style="color:#24292E">}</span></span></code></pre>
- </div>
- <p>
- 補足: 変数名がやたら短いのは、このあとの振り仮名データの量を削減するため。
- </p>
- <p>
- トークン種別に応じた色付けは CSS でおこなっている。出力する HTML のクラス名に <code>Prism::Token#type</code> を指定しておいて、<code>index.html</code> でそれぞれのクラスにスタイルを当てた。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E"> &#x3C;</span><span style="color:#22863A">style</span><span style="color:#24292E">></span></span>
-<span class="line"><span style="color:#6A737D"> /* ... */</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#6F42C1"> .COMMENT</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#005CC5"> color</span><span style="color:#24292E">: </span><span style="color:#005CC5">#777</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#005CC5"> font-style</span><span style="color:#24292E">: </span><span style="color:#005CC5">italic</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#6F42C1"> .CONSTANT</span><span style="color:#24292E">, </span><span style="color:#6F42C1">.GLOBAL_VARIABLE</span><span style="color:#24292E">, </span><span style="color:#6F42C1">.INSTANCE_VARIABLE</span><span style="color:#24292E">, </span><span style="color:#6F42C1">.IDENTIFIER</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#005CC5"> color</span><span style="color:#24292E">: </span><span style="color:#005CC5">#088</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#6A737D"> /* ... */</span></span>
-<span class="line"><span style="color:#24292E"> &#x3C;/</span><span style="color:#22863A">style</span><span style="color:#24292E">></span></span></code></pre>
- </div>
- <p>
- トークン種別の列挙にはそれなりに文字数を使ってしまうのだが、今回の TRICK のレギュレーションでは <code>index.html</code> にサイズ制限がなかったので好きに色を付けることができた。
- </p>
- </section>
- <section id="section--my-work--ruby-text">
- <h3><a href="#section--my-work--ruby-text">振り仮名</a></h3>
- <p>
- それぞれの英単語や記号に対応した振り仮名のデータは、プログラム中に埋め込まれている。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">def</span><span style="color:#6F42C1"> rt</span><span style="color:#24292E">(t)</span></span>
-<span class="line"><span style="color:#E36209"> r</span><span style="color:#D73A49"> =</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#005CC5"> :"&#x26;&#x26;"</span><span style="color:#24292E"> => </span><span style="color:#032F62">"1136"</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#005CC5"> :"="</span><span style="color:#24292E"> => </span><span style="color:#032F62">"04199275"</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#005CC5"> :"||"</span><span style="color:#24292E"> => </span><span style="color:#032F62">"623147"</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#005CC5"> :$s</span><span style="color:#24292E"> => </span><span style="color:#032F62">"41750825"</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#005CC5"> :*</span><span style="color:#24292E"> => </span><span style="color:#032F62">"111775"</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#6A737D"> # ...</span></span>
-<span class="line"><span style="color:#005CC5"> type:</span><span style="color:#032F62"> "310455"</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#005CC5"> utf_8:</span><span style="color:#032F62"> "70923803920853080440"</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#005CC5"> value:</span><span style="color:#032F62"> "48746992"</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#005CC5"> x:</span><span style="color:#032F62"> "08351525"</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#005CC5"> y:</span><span style="color:#032F62"> "7904"</span><span style="color:#24292E">,</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#6F42C1"> kana</span><span style="color:#24292E">(</span></span>
-<span class="line"><span style="color:#24292E"> r[</span><span style="color:#005CC5">:"#{t.</span><span style="color:#6F42C1">type</span><span style="color:#005CC5">}"</span><span style="color:#24292E">] </span><span style="color:#D73A49">||</span></span>
-<span class="line"><span style="color:#24292E"> r[s </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> :"#{t.</span><span style="color:#6F42C1">value</span><span style="color:#005CC5">.</span><span style="color:#6F42C1">downcase</span><span style="color:#005CC5">}"</span><span style="color:#24292E">] </span><span style="color:#D73A49">||</span></span>
-<span class="line"><span style="color:#24292E"> s.</span><span style="color:#6F42C1">end_with?</span><span style="color:#24292E">(</span><span style="color:#032F62">":"</span><span style="color:#24292E">) </span><span style="color:#D73A49">&#x26;&#x26;</span><span style="color:#24292E"> r[</span><span style="color:#005CC5">:"#{s[..</span><span style="color:#D73A49">-</span><span style="color:#005CC5">2]}"</span><span style="color:#24292E">] </span><span style="color:#D73A49">||</span></span>
-<span class="line"><span style="color:#005CC5"> nil</span></span>
-<span class="line"><span style="color:#24292E"> )</span></span>
-<span class="line"><span style="color:#D73A49">end</span></span></code></pre>
- </div>
- <p>
- トークンの種類 (<code>t.type</code>) またはトークンの文字列表現そのもの (<code>t.value.downcase</code>) を使ってテーブルを引いて振り仮名へ変換している。このテーブルのキー部分そのものにも振り仮名を振るために、トークンが <code>:</code> で終わっていれば <code>:</code> を取り除いて振り仮名を得ている (例: <code>&quot;value:&quot;</code> → <code>&quot;value&quot;</code> → <code>&quot;48746992&quot;</code>)。
- </p>
- <p>
- このテーブルはサイズ制限を突破するために圧縮されており、<code>kana()</code> 関数で展開される。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">def</span><span style="color:#6F42C1"> kana</span><span style="color:#24292E">(s)</span></span>
-<span class="line"><span style="color:#24292E"> s</span></span>
-<span class="line"><span style="color:#D73A49"> &#x26;.</span><span style="color:#6F42C1">scan</span><span style="color:#24292E">(</span><span style="color:#032F62">/.{2}/</span><span style="color:#24292E">)</span></span>
-<span class="line"><span style="color:#D73A49"> &#x26;.</span><span style="color:#6F42C1">map</span><span style="color:#24292E">{|c| (</span><span style="color:#005CC5">0x30A0</span><span style="color:#D73A49"> +</span><span style="color:#24292E"> c.</span><span style="color:#6F42C1">to_i</span><span style="color:#24292E">).</span><span style="color:#6F42C1">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">Encoding</span><span style="color:#24292E">::</span><span style="color:#005CC5">UTF_8</span><span style="color:#24292E">)}</span></span>
-<span class="line"><span style="color:#D73A49"> &#x26;.*</span><span style="color:#24292E">(</span><span style="color:#032F62">""</span><span style="color:#24292E">)</span></span>
-<span class="line"><span style="color:#D73A49">end</span></span></code></pre>
- </div>
- <p>
- 例えば <code>value</code> に対応する振り仮名データ <code>&quot;48746992&quot;</code> であれば、次のような変換を経て振り仮名へと展開される。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E"> s</span></span>
-<span class="line"><span style="color:#6A737D"> # => "48746992"</span></span>
-<span class="line"><span style="color:#D73A49"> &#x26;.</span><span style="color:#6F42C1">scan</span><span style="color:#24292E">(</span><span style="color:#032F62">/.{2}/</span><span style="color:#24292E">)</span></span>
-<span class="line"><span style="color:#6A737D"> # => ["48", "74", "69", "92"]</span></span>
-<span class="line"><span style="color:#D73A49"> &#x26;.</span><span style="color:#6F42C1">map</span><span style="color:#24292E">{|c| (</span><span style="color:#005CC5">0x30A0</span><span style="color:#D73A49"> +</span><span style="color:#24292E"> c.</span><span style="color:#6F42C1">to_i</span><span style="color:#24292E">).</span><span style="color:#6F42C1">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">Encoding</span><span style="color:#24292E">::</span><span style="color:#005CC5">UTF_8</span><span style="color:#24292E">)}</span></span>
-<span class="line"><span style="color:#6A737D"> # => ["バ", "リ", "ュ", "ー"]</span></span>
-<span class="line"><span style="color:#D73A49"> &#x26;.*</span><span style="color:#24292E">(</span><span style="color:#032F62">""</span><span style="color:#24292E">)</span></span>
-<span class="line"><span style="color:#6A737D"> # => "バリュー"</span></span></code></pre>
- </div>
- <p>
- これは後で気付いたのだが、Ruby は多倍長整数が扱えるので <code>&quot;48746992&quot;</code> のようなデータは単に <code>48746992</code> と書けばよかった。<code>kana()</code> 関数が多少長くはなるが、振り仮名データの数 x 2 バイト分サイズが減るのでこちらの方が短くなる。サイズ制限の都合で振り仮名を振るのを諦めた記号もあったのでもったいない。
- </p>
- </section>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">おわりに</a></h2>
- <p>
- 本っ当に取りたかったので心から嬉しいです。全部で 3作提出したのですが、他の 2つも選外佳作として選出していただけた上、そのうちの “Least Truthful” については最後に Matz 氏から言及があり、審査員賞と合わせて望外の栄誉となりました。
- </p>
- <p>
- ありがとうございました!
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/screenshot.png b/vhosts/blog/public/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/screenshot.png
deleted file mode 100644
index 0bfe3be9..00000000
--- a/vhosts/blog/public/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/screenshot.png
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/posts/2025-04-24/composer-patches-v2-does-not-require-gnu-patch-even-on-macos/index.html b/vhosts/blog/public/posts/2025-04-24/composer-patches-v2-does-not-require-gnu-patch-even-on-macos/index.html
deleted file mode 100644
index c482abb1..00000000
--- a/vhosts/blog/public/posts/2025-04-24/composer-patches-v2-does-not-require-gnu-patch-even-on-macos/index.html
+++ /dev/null
@@ -1,153 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2025 nsfisis">
- <meta name="description" content="composer-patches は BSD patch に対応しておらず、一部のパッチの適用に失敗する。現在ベータ版である v2 では patch コマンドに依存しなくなり、macOS で使うときのストレスが解消される見込み。">
- <meta name="keywords" content="Composer,macOS,PHP">
- <meta property="og:type" content="article">
- <meta property="og:title" content="【Composer】 composer-patches v2 では macOS でも GNU patch のインストールが不要になる (予定)|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="composer-patches は BSD patch に対応しておらず、一部のパッチの適用に失敗する。現在ベータ版である v2 では patch コマンドに依存しなくなり、macOS で使うときのストレスが解消される見込み。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>【Composer】 composer-patches v2 では macOS でも GNU patch のインストールが不要になる (予定)|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">【Composer】 composer-patches v2 では macOS でも GNU patch のインストールが不要になる (予定)</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/composer/">Composer</a>
- </li>
- <li class="tag">
- <a href="/tags/macos/">macOS</a>
- </li>
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2025-04-10">2025-04-10</time>: デジタルサーカス株式会社の社内記事として公開
- </li>
- <li class="revision">
- <time datetime="2025-04-24">2025-04-24</time>: 公開
- </li>
- </ol>
- </section>
- <div class="admonition">
- <div class="admonition-label">
- NOTE
- </div>
- <div class="admonition-content">
- <p>
- この記事は、2025-04-10 に <a href="https://www.dgcircus.com/" rel="noreferrer" target="_blank">デジタルサーカス株式会社</a> の社内 Qiita Team に公開された記事をベースに、加筆修正して一般公開したものです。
- </p>
- </div>
- </div>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- <a href="https://getcomposer.org/" rel="noreferrer" target="_blank">Composer</a> は PHP におけるデファクトスタンダードなパッケージ管理システムである。
- </p>
- <p>
- Composer を拡張するプラグインの一つに、<a href="https://github.com/cweagans/composer-patches" rel="noreferrer" target="_blank">composer-patches</a> という Composer パッケージがある。これは、Composer でパッケージをインストールするときにそのパッケージへ任意のパッチを当てるプラグインである。
- </p>
- <p>
- 社内で発見しすぐに適用しなければならないバグ修正や、Pull Request こそあるもののなかなかマージされない機能等をすぐさま適用してリリースすることができる。
- </p>
- <p>
- 弊社でも多くのプロジェクトで活用されており、のべ数では数百ものパッチが当てられている。
- </p>
- </section>
- <section id="section--on-macos">
- <h2><a href="#section--on-macos">macOS での問題点</a></h2>
- <p>
- <code>composer-patches</code> は、macOS で一部のパッチの適用に失敗することが知られている。関連 issues:
- </p>
- <ul>
- <li>
- <a href="https://github.com/cweagans/composer-patches/issues/522" rel="noreferrer" target="_blank">https://github.com/cweagans/composer-patches/issues/522</a>
- </li>
- <li>
- <a href="https://github.com/cweagans/composer-patches/issues/326" rel="noreferrer" target="_blank">https://github.com/cweagans/composer-patches/issues/326</a>
- </li>
- </ul>
- <p>
- これは、<code>composer-patches</code> の想定する <code>patch</code> コマンドが GNU 実装の patch であることに由来する。macOS にプリインストールされている <code>patch</code> はいわゆる BSD patch であり、GNU patch とは完全な互換性がない。
- </p>
- <p>
- ワークアラウンドとして、macOS にも GNU patch をインストールしてしまうという方法がある。例:
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ brew install gpatch</span></span>
-<span class="line"><span>$ echo 'PATH="/opt/homebrew/opt/gpatch/libexec/gnubin:$PATH"' >> ~/.zshrc</span></span></code></pre>
- </div>
- <p>
- GNU patch を Homebrew などの手段でインストールし、BSD patch よりも優先されるパスに配置すれば問題が解消する。
- </p>
- </section>
- <section id="section--in-version-2">
- <h2><a href="#section--in-version-2">v2 では</a></h2>
- <p>
- 現在ベータ版である <code>composer-patches</code> v2 では、このワークアラウンドが不要になる (見込み)。
- </p>
- <p>
- 最新の実装では、<code>git apply</code> コマンドが最優先で使われる。また、Git リポジトリがない場合 (<code>config.preferred-install</code> を <code>dist</code> に設定している場合など。デフォルトではそうなる) には <code>git init</code> を使って一時的にリポジトリを作成し、その上で <code>git apply</code> を実行するようになった。
- </p>
- <p>
- この変更により、環境ごとに差異のある <code>patch</code> コマンドへの依存がなくなるので、macOS で <code>composer-patches</code> を使うときの厄介事は解消されるものと思われる。
- </p>
- <p>
- <a href="https://github.com/cweagans/composer-patches/releases/tag/2.0.0-beta1" rel="noreferrer" target="_blank">2.0.0-beta1</a> のリリースノートより:
- </p>
- <blockquote>
- <ul>
- <li>
- Only have git patchers and freeform patcher? by <a href="https://github.com/cweagans" rel="noreferrer" target="_blank"><strong>@cweagans</strong></a> in <a href="https://github.com/cweagans/composer-patches/pull/476" rel="noreferrer" target="_blank">#472</a>
- </li>
- </ul>
- </blockquote>
- <p>
- この変更で <code>patch</code> コマンドへの依存が排除された。
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2025-05-05/make-tiny-self-hosted-c-compiler/index.html b/vhosts/blog/public/posts/2025-05-05/make-tiny-self-hosted-c-compiler/index.html
deleted file mode 100644
index da17228a..00000000
--- a/vhosts/blog/public/posts/2025-05-05/make-tiny-self-hosted-c-compiler/index.html
+++ /dev/null
@@ -1,541 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2025 nsfisis">
- <meta name="description" content="ゴールデンウィークを使って、セルフホストできる C コンパイラを開発した">
- <meta name="keywords" content="C">
- <meta property="og:type" content="article">
- <meta property="og:title" content="セルフホスト可能な C コンパイラを作った|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="ゴールデンウィークを使って、セルフホストできる C コンパイラを開発した">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>セルフホスト可能な C コンパイラを作った|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">セルフホスト可能な C コンパイラを作った</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/c/">C</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2025-05-05">2025-05-05</time>: 公開
- </li>
- </ol>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">はじめに</a></h2>
- <p>
- C コンパイラと言えば、世界三大自作したいソフトウェアの一角である。というわけで <a href="https://www.sigbus.info/compilerbook" rel="noreferrer" target="_blank">『低レイヤを知りたい人のためのCコンパイラ作成入門』</a> (以下 compilerbook) 片手に作ることにした。
- </p>
- <p>
- 実装する機能を適切に絞ってやればゴールデンウィークの間 (2025-05-03 から 2025-05-06) にセルフホストまで持っていけるのではないか?という仮説を立て、ISO 8601 の表記で 4日間を表す “P4D” を冠して P4Dcc と名付けた。
- </p>
- <p>
- <a href="https://github.com/nsfisis/P4Dcc" rel="noreferrer" target="_blank">P4Dcc のリポジトリはこちら</a>
- </p>
- </section>
- <section id="section--regulation">
- <h2><a href="#section--regulation">レギュレーション</a></h2>
- <ul>
- <li>
- 実装するのは C 言語からアセンブリ言語への変換部分のみ。アセンブラやリンカは GCC をそのまま用いる
- </li>
- <li>
- compilerbook を読みながら実装してよい
- </li>
- <li>
- compilerbook に記載されたソースコードを除き、コンパイラのソースコードを読まない
- </li>
- <li>
- GCC の出力は見てもよい。それ以外のコンパイラの出力 (特に 9cc などの compilerbook 準拠のコンパイラ) は見ない
- </li>
- <li>
- ソースコードの生成やデバッグに AI を使わない。ツールの使用方法を調べる目的 (GCC に渡すフラグなど) には使ってよい
- </li>
- </ul>
- </section>
- <section id="section--design">
- <h2><a href="#section--design">設計</a></h2>
- <p>
- ゴールデンウィークの4日間で終わらせたいので、実装する言語機能は最低限に絞ることが必要になる。今回は次のような設計とした (compilerbook の設計を踏襲しているものは除く)。
- </p>
- <ul>
- <li>
- 宣言の文法を単純にパースできるものに絞る
- <ul>
- <li>
- <code>typedef</code> をサポートしない
- <ul>
- <li>
- 構造体には必ず <code>struct</code> キーワードを書く
- </li>
- </ul>
- </li>
- <li>
- 配列型をサポートしない
- <ul>
- <li>
- 常にヒープに確保してポインタ経由で扱う
- </li>
- </ul>
- </li>
- <li>
- 以上の制限により、型に関する情報が必ず変数名の前に来る
- </li>
- </ul>
- </li>
- <li>
- 無くてもなんとかなる構文糖を実装しない。ソースを書くときに頑張る
- <ul>
- <li>
- インクリメント・デクリメント演算子 (1足したり引いたりする)
- </li>
- <li>
- 複合代入演算子 (左辺と右辺で 2回書く)
- <ul>
- <li>
- なお、<code>+=</code> と <code>-=</code> はセルフホスト達成後に実装された
- </li>
- </ul>
- </li>
- <li>
- <code>while</code> (<code>for</code> で置き換える)
- <ul>
- <li>
- なお、<code>while</code> はセルフホスト達成後に実装された
- </li>
- </ul>
- </li>
- <li>
- <code>switch</code> (<code>if</code> で置き換える)
- </li>
- <li>
- ほか多数
- </li>
- </ul>
- </li>
- <li>
- プリプロセッサのほとんどを実装しない
- <ul>
- <li>
- 数値または識別子へ置換する単純な <code>#define</code> のみサポートする
- </li>
- <li>
- 特に、<code>#include</code> をサポートしないのは重要な設計判断。すべて 1ファイルでおこなう
- </li>
- </ul>
- </li>
- <li>
- グローバル変数を用いない
- <ul>
- <li>
- <code>stdin</code>、<code>stdout</code>、<code>stderr</code> を含む
- </li>
- <li>
- これは compilerbook とは大きく設計が変わった部分
- </li>
- <li>
- これにより、トップレベルに来るのは関数か構造体の定義/宣言のみとなった
- </li>
- </ul>
- </li>
- <li>
- 変数のシャドウイングを実装しない
- <ul>
- <li>
- 変数は常に関数スコープ
- </li>
- <li>
- グローバル変数もないので、スコープチェーンの実装が不要になる
- </li>
- </ul>
- </li>
- </ul>
- <section id="section--design--language-features">
- <h3><a href="#section--design--language-features">言語機能</a></h3>
- <p>
- 最終的にサポートされた機能は以下のとおり。
- </p>
- <ul>
- <li>
- 文
- <ul>
- <li>
- <code>if</code> / <code>else</code>
- </li>
- <li>
- <code>for</code>
- </li>
- <li>
- <code>break</code>
- </li>
- <li>
- <code>continue</code>
- </li>
- <li>
- <code>return</code>
- </li>
- <li>
- <code>while</code> (実装はセルフホスト達成後)
- </li>
- </ul>
- </li>
- <li>
- 式
- <ul>
- <li>
- 二項演算
- <ul>
- <li>
- <code>+</code> / <code>-</code> / <code>*</code> / <code>/</code> / <code>%</code>
- </li>
- <li>
- <code>==</code> / <code>!=</code>
- </li>
- <li>
- <code>&lt;</code> / <code>&lt;=</code> / <code>&gt;</code> / <code>&gt;=</code>
- </li>
- <li>
- <code>&amp;&amp;</code> / <code>||</code>
- </li>
- </ul>
- </li>
- <li>
- 代入
- <ul>
- <li>
- <code>=</code>
- </li>
- <li>
- <code>+=</code> / <code>-=</code> (実装はセルフホスト達成後)
- </li>
- </ul>
- </li>
- <li>
- 単項演算: <code>-</code> / <code>!</code> / <code>*</code> / <code>&amp;</code> / <code>sizeof</code>
- </li>
- <li>
- 関数呼び出し: <code>f(a, b)</code>
- </li>
- <li>
- 配列アクセス: <code>a[b]</code>
- </li>
- <li>
- メンバ呼び出し: <code>a.b</code> / <code>a-&gt;b</code>
- </li>
- <li>
- 整数リテラル
- </li>
- <li>
- 文字列リテラル
- </li>
- </ul>
- </li>
- <li>
- 型
- <ul>
- <li>
- <code>char</code>
- </li>
- <li>
- <code>int</code>
- </li>
- <li>
- <code>long</code>
- </li>
- <li>
- <code>void</code>
- </li>
- <li>
- <code>struct</code>
- </li>
- <li>
- それらのポインタ
- </li>
- </ul>
- </li>
- <li>
- 宣言・定義
- <ul>
- <li>
- 関数
- </li>
- <li>
- 構造体
- </li>
- </ul>
- </li>
- <li>
- プリプロセッサ
- <ul>
- <li>
- 引数なし <code>#define</code>
- </li>
- </ul>
- </li>
- </ul>
- </section>
- </section>
- <section id="section--development">
- <h2><a href="#section--development">開発</a></h2>
- <p>
- 時系列順に開発の様子を辿っていく。
- </p>
- <section id="section--development--day1">
- <h3><a href="#section--development--day1">1日目 (2025-05-03)</a></h3>
- <p>
- compilerbook では整数一つのパース・コード生成から始めるが、今回は以下のようなソースをパースしてコード生成するところからスタートすることにした。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">int</span><span style="color:#6F42C1"> main</span><span style="color:#24292E">() {</span></span>
-<span class="line"><span style="color:#D73A49"> return</span><span style="color:#005CC5"> 42</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">}</span></span></code></pre>
- </div>
- <p>
- この時点で、<code>struct Token</code>、<code>struct Parser</code>、<code>struct AstNode</code>、<code>struct CodeGen</code> といった主要なデータ構造が定義され、この後もほぼ同じソース設計のまま進めている。
- </p>
- <p>
- compilerbook のようなインクリメンタルな進め方を取らずに、最初から普通の言語処理系のような構成にしたのには理由がある。
- </p>
- <p>
- それは、どのくらいの言語機能があればコンパイラを作るのに十分かをこの時点で見積もるためである。開発を開始する前にも必要な言語機能にはあたりを付けていたが、実際にプロトタイプを作ってみて、これだけの機能セットがあれば足りるだろうという正確な TODO リストを作りたかった。実際、このとき作ったチェックリストはこのあともほとんど変わっていない (大きな変化点は、配列型をサポートしないと決めたことくらいか)。
- </p>
- <p>
- このあとは、おおむね compilerbook に従って以下のように機能追加を続けた。
- </p>
- <ol>
- <li>
- 四則演算
- </li>
- <li>
- 単項マイナス
- </li>
- <li>
- 比較
- </li>
- <li>
- ローカル変数
- </li>
- <li>
- <code>if</code> 文
- </li>
- <li>
- <code>for</code> 文
- </li>
- <li>
- 引数なしの関数呼び出し
- </li>
- <li>
- 引数ありの関数呼び出し
- </li>
- <li>
- 文字列リテラル
- </li>
- </ol>
- <p>
- 一日の終わりには、次のようなプログラムのテストが通るようになった。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">int</span><span style="color:#6F42C1"> printf</span><span style="color:#24292E">();</span></span>
-<span class="line"></span>
-<span class="line"><span style="color:#D73A49">int</span><span style="color:#6F42C1"> main</span><span style="color:#24292E">() {</span></span>
-<span class="line"><span style="color:#D73A49"> int</span><span style="color:#24292E"> i;</span></span>
-<span class="line"><span style="color:#D73A49"> for</span><span style="color:#24292E"> (i </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> 1</span><span style="color:#24292E">; i </span><span style="color:#D73A49">&#x3C;=</span><span style="color:#005CC5"> 100</span><span style="color:#24292E">; i </span><span style="color:#D73A49">=</span><span style="color:#24292E"> i </span><span style="color:#D73A49">+</span><span style="color:#005CC5"> 1</span><span style="color:#24292E">) {</span></span>
-<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> (i </span><span style="color:#D73A49">%</span><span style="color:#005CC5"> 15</span><span style="color:#D73A49"> ==</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">) {</span></span>
-<span class="line"><span style="color:#6F42C1"> printf</span><span style="color:#24292E">(</span><span style="color:#032F62">"FizzBuzz</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span></span>
-<span class="line"><span style="color:#24292E"> } </span><span style="color:#D73A49">else</span><span style="color:#D73A49"> if</span><span style="color:#24292E"> (i </span><span style="color:#D73A49">%</span><span style="color:#005CC5"> 3</span><span style="color:#D73A49"> ==</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">) {</span></span>
-<span class="line"><span style="color:#6F42C1"> printf</span><span style="color:#24292E">(</span><span style="color:#032F62">"Fizz</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span></span>
-<span class="line"><span style="color:#24292E"> } </span><span style="color:#D73A49">else</span><span style="color:#D73A49"> if</span><span style="color:#24292E"> (i </span><span style="color:#D73A49">%</span><span style="color:#005CC5"> 5</span><span style="color:#D73A49"> ==</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">) {</span></span>
-<span class="line"><span style="color:#6F42C1"> printf</span><span style="color:#24292E">(</span><span style="color:#032F62">"Buzz</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">);</span></span>
-<span class="line"><span style="color:#24292E"> } </span><span style="color:#D73A49">else</span><span style="color:#24292E"> {</span></span>
-<span class="line"><span style="color:#6F42C1"> printf</span><span style="color:#24292E">(</span><span style="color:#032F62">"</span><span style="color:#005CC5">%d\n</span><span style="color:#032F62">"</span><span style="color:#24292E">, i);</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#D73A49"> return</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">;</span></span>
-<span class="line"><span style="color:#24292E">}</span></span></code></pre>
- </div>
- </section>
- <section id="section--development--day2">
- <h3><a href="#section--development--day2">2日目 (2025-05-03)</a></h3>
- <p>
- この時点で、不足している機能はおおよそ2つ。ポインタと構造体である。
- </p>
- <p>
- このあたりからは compilerbook の解説も減っていき (構造体については完全に記載がない)、実装も離れていっている。
- </p>
- <p>
- 以下のように実装を進めていった。
- </p>
- <ol>
- <li>
- <code>char</code>、<code>long</code>、<code>void</code>
- </li>
- <li>
- ポインタ
- </li>
- <li>
- アドレス演算子: <code>&amp;</code>
- </li>
- <li>
- 間接参照演算子: <code>*</code>
- </li>
- <li>
- <code>sizeof</code>
- </li>
- <li>
- ポインタの演算
- </li>
- <li>
- <code>#define</code>
- </li>
- <li>
- 構造体の定義・宣言
- </li>
- <li>
- 構造体の <code>sizeof</code>
- </li>
- <li>
- メンバーアクセス
- </li>
- <li>
- 論理演算子: <code>&amp;&amp;</code>、<code>||</code>
- </li>
- <li>
- 初期化式つきの変数定義
- </li>
- <li>
- 文字リテラル
- </li>
- <li>
- 配列アクセス
- </li>
- <li>
- 論理演算子: <code>!</code>
- </li>
- <li>
- 返り値なしの <code>return</code>
- </li>
- </ol>
- <p>
- <code>&amp;</code>、<code>*</code>、<code>sizeof</code> あたりの実装が終わるとかなり C 言語らしくなっていき楽しい。
- </p>
- <p>
- このあたりから、セルフホストに向けて逆方向からのアプローチも並行しておこなっている。セルフホストするためには処理系のソースコードで使っている言語機能をすべて実装する必要があるわけだが、これまでは処理系が扱える機能を拡充していくという方向だった。この逆、つまり処理系のソースコードで使っている機能を減らすことでもセルフホストに近付いていく。
- </p>
- <p>
- 例えば、このコンパイラは <code>typedef</code> をサポートしていないが、開発中ずっと <code>typedef</code> を使わないというのは面倒だ。そこで、セルフホストがある程度現実的になるまでは構造体を <code>typedef</code> しておいて、途中のどこかで <code>typedef</code> を手で脱糖する。
- </p>
- <p>
- これらの作業をおこなうことで、処理系自身のソースコード <code>main.c</code> をパースしてバイナリを出力することができるようになった。いわゆる第2世代のコンパイラである。この現時点ではまだ第2世代コンパイラは何もできない (何を与えてもクラッシュする)。
- </p>
- </section>
- <section id="section--development--day3">
- <h3><a href="#section--development--day3">3日目 (2025-05-03)</a></h3>
- <p>
- さて、第2世代コンパイラが手に入ったので、ここからは地獄のデバッグ作業が始まる。多段になっているために問題が起きている箇所の特定が難しい。
- </p>
- <p>
- ……と考えていたのだが、実際のところデバッグは1時間ほどで終わってしまった。修正したのは1点のみ。なんのことはない、2日目終了時点でほとんど完成していたわけだ。
- </p>
- <p>
- 記念すべき (?) 最後のバグはこちら。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E"> gen_expr(g, ast->expr1, GEN_RVAL);</span></span>
-<span class="line"><span style="color:#24292E"> } else {</span></span>
-<span class="line"><span style="color:#24292E"> gen_expr(g, ast->expr1, GEN_RVAL);</span></span>
-<span class="line"><span style="color:#B31D28">- gen_lval2rval(ast->expr1->ty);</span></span>
-<span class="line"><span style="color:#22863A">+ gen_lval2rval(ast->expr1->ty->to);</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span>
-<span class="line"><span style="color:#24292E"> }</span></span></code></pre>
- </div>
- <p>
- メモリアドレスから参照先の値を得る際、その型によってロードする命令の種類を変える必要があるのだが、その切替をポインタ型でおこなっていた。正しくは、そのポインタ型が指す型を元にして切り替えなければならない。
- </p>
- <p>
- これを修正すると、第2世代コンパイラが第3世代コンパイラを出力できるようになり、その後も第N世代が第N+1世代を生成できるようになった。
- </p>
- <p>
- あとは、第2世代のコンパイラがそれ以降のコンパイラとバイナリレベルで一致するかどうかを確かめればよい。実際に調べてみると、ほとんどの場所が一致したもののどの世代も 6バイトだけ異なることがわかった。
- </p>
- <p>
- 一体どこが異なるのか。<code>hexdump</code> の差分がこちら。
- </p>
- <div class="codeblock">
- <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ diff -u &#x3C;(hexdump -C p4dcc2) &#x3C;(hexdump -C p4dcc3)</span></span>
-<span class="line"><span>@@ -5090,7 +5090,7 @@</span></span>
-<span class="line"><span> 00015db0 72 72 61 79 5f 65 6e 74 72 79 00 66 72 61 6d 65 |rray_entry.frame|</span></span>
-<span class="line"><span> 00015dc0 5f 64 75 6d 6d 79 00 5f 5f 66 72 61 6d 65 5f 64 |_dummy.__frame_d|</span></span>
-<span class="line"><span> 00015dd0 75 6d 6d 79 5f 69 6e 69 74 5f 61 72 72 61 79 5f |ummy_init_array_|</span></span>
-<span class="line"><span>-00015de0 65 6e 74 72 79 00 63 63 6d 69 42 49 59 6b 2e 6f |entry.ccmiBIYk.o|</span></span>
-<span class="line"><span>+00015de0 65 6e 74 72 79 00 63 63 53 71 64 47 76 57 2e 6f |entry.ccSqdGvW.o|</span></span>
-<span class="line"><span> 00015df0 00 66 61 74 61 6c 5f 65 72 72 6f 72 00 72 65 61 |.fatal_error.rea|</span></span>
-<span class="line"><span> 00015e00 64 5f 61 6c 6c 00 74 6f 6b 65 6e 69 7a 65 00 74 |d_all.tokenize.t|</span></span>
-<span class="line"><span> 00015e10 79 70 65 5f 6e 65 77 00 74 79 70 65 5f 6e 65 77 |ype_new.type_new|</span></span></code></pre>
- </div>
- <p>
- <code>fatal_error</code>、<code>read_all</code>、<code>tokenize</code> <code>type_new</code> はいずれも <code>main.c</code> で定義された関数の名前である。このことから考えると、これは GCC が埋め込んだシンボルテーブルである可能性が高い。わずかに異なっている 6バイトは、ランダム生成された何かのように見える。
- </p>
- <p>
- そこで <code>gcc</code> に <code>-s</code> (シンボルテーブルを削除するフラグ) を渡してみると、めでたく2世代目以降のコンパイラのバイナリが完全に一致するようになった。
- </p>
- <p>
- これにてセルフホスト達成である。
- </p>
- </section>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">おわりに</a></h2>
- <p>
- 最終的な実装は1900行ほど、所要時間は20時間弱となった。
- </p>
- <p>
- 正直なところ、思ったより早く終わって拍子抜けしている。これは compilerbook がうまく実装順を整理しているのと、アセンブリの細かい落とし穴を事前に解説して潰していることが大きいと思われる。
- </p>
- <p>
- 当初の仮説どおり、サポートする機能を慎重に選ぶことにより短期間でセルフホストまで持っていくことができた。案外簡単に作れてしまうので、まとまった休みに是非いかがだろうか。
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_ADVENTURERS.jpeg b/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_ADVENTURERS.jpeg
deleted file mode 100644
index 8ba97a06..00000000
--- a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_ADVENTURERS.jpeg
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_BABA_IS_YOU.jpeg b/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_BABA_IS_YOU.jpeg
deleted file mode 100644
index 69c8bb5e..00000000
--- a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_BABA_IS_YOU.jpeg
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_BOOBY_TRAP.jpeg b/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_BOOBY_TRAP.jpeg
deleted file mode 100644
index f993ac34..00000000
--- a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_BOOBY_TRAP.jpeg
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_BOTTLENECK.jpeg b/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_BOTTLENECK.jpeg
deleted file mode 100644
index 9080626e..00000000
--- a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_BOTTLENECK.jpeg
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_CONCRETE_GOALS.jpeg b/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_CONCRETE_GOALS.jpeg
deleted file mode 100644
index a11be095..00000000
--- a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_CONCRETE_GOALS.jpeg
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_CRUSHERS.jpeg b/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_CRUSHERS.jpeg
deleted file mode 100644
index 5a29e603..00000000
--- a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_CRUSHERS.jpeg
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_DUNGEON.jpeg b/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_DUNGEON.jpeg
deleted file mode 100644
index 9ed96771..00000000
--- a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_DUNGEON.jpeg
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_FRAGILE_EXISTENCE.jpeg b/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_FRAGILE_EXISTENCE.jpeg
deleted file mode 100644
index 693958dd..00000000
--- a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_FRAGILE_EXISTENCE.jpeg
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_FURTHER_FIELDS.jpeg b/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_FURTHER_FIELDS.jpeg
deleted file mode 100644
index 866485b9..00000000
--- a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_FURTHER_FIELDS.jpeg
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_GETTING_TOGETHER.jpeg b/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_GETTING_TOGETHER.jpeg
deleted file mode 100644
index 6d9879d2..00000000
--- a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_GETTING_TOGETHER.jpeg
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_HEAVY_CLOUD.jpeg b/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_HEAVY_CLOUD.jpeg
deleted file mode 100644
index 78479628..00000000
--- a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_HEAVY_CLOUD.jpeg
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_INSULATION.jpeg b/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_INSULATION.jpeg
deleted file mode 100644
index 16c8d091..00000000
--- a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_INSULATION.jpeg
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_LOCK_THE_DOOR.jpeg b/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_LOCK_THE_DOOR.jpeg
deleted file mode 100644
index 4f7acf79..00000000
--- a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_LOCK_THE_DOOR.jpeg
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_METEOR_STRIKE.jpeg b/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_METEOR_STRIKE.jpeg
deleted file mode 100644
index 26209ea8..00000000
--- a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_METEOR_STRIKE.jpeg
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_OUT_AT_SEA.jpeg b/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_OUT_AT_SEA.jpeg
deleted file mode 100644
index 0a6fb4df..00000000
--- a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_OUT_AT_SEA.jpeg
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_PARADE.jpeg b/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_PARADE.jpeg
deleted file mode 100644
index 5bd1fe77..00000000
--- a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_PARADE.jpeg
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_PRISON.jpeg b/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_PRISON.jpeg
deleted file mode 100644
index 21701abb..00000000
--- a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_PRISON.jpeg
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_SCENIC_POND.jpeg b/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_SCENIC_POND.jpeg
deleted file mode 100644
index 76b80b7c..00000000
--- a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_SCENIC_POND.jpeg
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_SEEKING_ACCEPTANCE.jpeg b/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_SEEKING_ACCEPTANCE.jpeg
deleted file mode 100644
index e4c33fe8..00000000
--- a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_SEEKING_ACCEPTANCE.jpeg
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_STARDROP.jpeg b/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_STARDROP.jpeg
deleted file mode 100644
index f154f3b8..00000000
--- a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_STARDROP.jpeg
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_SUBMERGED_RUINS.jpeg b/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_SUBMERGED_RUINS.jpeg
deleted file mode 100644
index 3581bc45..00000000
--- a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_SUBMERGED_RUINS.jpeg
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_SUNKEN_TEMPLE.jpeg b/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_SUNKEN_TEMPLE.jpeg
deleted file mode 100644
index 7f7659bb..00000000
--- a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_SUNKEN_TEMPLE.jpeg
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_THE_BOX.jpeg b/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_THE_BOX.jpeg
deleted file mode 100644
index 4c04ae9c..00000000
--- a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_THE_BOX.jpeg
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_THE_RETURN_OF_SCENIC_POND.jpeg b/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_THE_RETURN_OF_SCENIC_POND.jpeg
deleted file mode 100644
index 86edb294..00000000
--- a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_THE_RETURN_OF_SCENIC_POND.jpeg
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_ULTIMATE_MAZE.jpeg b/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_ULTIMATE_MAZE.jpeg
deleted file mode 100644
index 97d3fe7e..00000000
--- a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_ULTIMATE_MAZE.jpeg
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_VIP_AREA.jpeg b/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_VIP_AREA.jpeg
deleted file mode 100644
index 6e352375..00000000
--- a/vhosts/blog/public/posts/2025-06-14/baba-is-you/LEVEL_VIP_AREA.jpeg
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/posts/2025-06-14/baba-is-you/index.html b/vhosts/blog/public/posts/2025-06-14/baba-is-you/index.html
deleted file mode 100644
index cb82965f..00000000
--- a/vhosts/blog/public/posts/2025-06-14/baba-is-you/index.html
+++ /dev/null
@@ -1,577 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2025 nsfisis">
- <meta name="description" content="Baba Is You という最高のパズルゲームをクリアした。是非プレイしてほしい。">
- <meta name="keywords" content="ゲーム">
- <meta property="og:type" content="article">
- <meta property="og:title" content="最高のパズルゲーム Baba Is You をやれ|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="Baba Is You という最高のパズルゲームをクリアした。是非プレイしてほしい。">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>最高のパズルゲーム Baba Is You をやれ|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">最高のパズルゲーム Baba Is You をやれ</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/game/">ゲーム</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2025-06-14">2025-06-14</time>: 公開
- </li>
- <li class="revision">
- <time datetime="2025-06-15">2025-06-15</time>: 後半 (ネタバレあり) のとある面について追記
- </li>
- </ol>
- </section>
- <section id="section--intro">
- <h2><a href="#section--intro">Baba Is You とは</a></h2>
- <p>
- <a href="https://www.hempuli.com/baba/" rel="noreferrer" target="_blank">Baba Is You</a> という倉庫番系パズルゲームがある。私がこれまでプレイしたことのあるパズルゲームの中で、間違いなく最高のパズルゲームだと断言できる。これより面白いパズルゲームを知っている人は、絶対に買うので教えてほしい。
- </p>
- <p>
- すでに押しも押されもせぬ傑作としての名をほしいままにする本作だが、名作の感想はいくつあってもいいので書く。
- </p>
- <p>
- 前半はネタバレなし、後半はネタバレありで書くので、プレイしていない人は前半まで読んだら閉じてほしい。
- </p>
- </section>
- <section id="section--no-spoiler">
- <h2><a href="#section--no-spoiler">前半 (ネタバレなし)</a></h2>
- <section id="section--no-spoiler--what-is-baba-is-you">
- <h3><a href="#section--no-spoiler--what-is-baba-is-you">どういうゲームか?</a></h3>
- <p>
- Baba Is You はいわゆる倉庫番パズルの一種である。2D のグリッドで操作キャラを動かし、アイテムを押して動かすことでパズルを解く。
- </p>
- <p>
- Baba Is You の特異な点は、倉庫番のルールが盤面上で動かせるオブジェクトとして配置してある点にある。これは Baba Is You の一番最初の面である。
- </p>
- <p>
- <img alt="最初の面「BABA IS YOU」のスクリーンショット" src="/posts/2025-06-14/baba-is-you/LEVEL_BABA_IS_YOU.jpeg">
- </p>
- <p>
- ここには次のようなルールがある。
- </p>
- <ul>
- <li>
- <code>BABA</code> <code>IS</code> <code>YOU</code>
- <ul>
- <li>
- Baba はあなた (操作キャラ)
- </li>
- </ul>
- </li>
- <li>
- <code>ROCK</code> <code>IS</code> <code>PUSH</code>
- <ul>
- <li>
- 岩は押せる
- </li>
- </ul>
- </li>
- <li>
- <code>WALL</code> <code>IS</code> <code>STOP</code>
- <ul>
- <li>
- 壁は止まる (押せない)
- </li>
- </ul>
- </li>
- <li>
- <code>FLAG</code> <code>IS</code> <code>WIN</code>
- <ul>
- <li>
- 旗は勝ち
- </li>
- </ul>
- </li>
- </ul>
- <p>
- 最初の状態では、<code>YOU</code> である baba (うさぎや猫のような白い生き物) が <code>WIN</code> である旗に触れることで勝利条件を満たしクリアとなる。
- </p>
- <p>
- これらのルールを構成しているテキストを押して動かすことで、ルールをさまざまに変化させることができる。この面なら一例として次のようなルールが作れるだろう。
- </p>
- <ul>
- <li>
- <code>FLAG</code> <code>IS</code> <code>YOU</code>
- <ul>
- <li>
- 旗が操作キャラになり、キー入力で動かせる
- </li>
- </ul>
- </li>
- <li>
- <code>ROCK</code> <code>IS</code> <code>STOP</code>
- <ul>
- <li>
- 岩が押せなくなる
- </li>
- </ul>
- </li>
- <li>
- <code>BABA</code> <code>IS</code> <code>WALL</code>
- <ul>
- <li>
- Baba が壁へと変化し、操作不能になる
- <ul>
- <li>
- <code>WALL</code> <code>IS</code> <code>YOU</code> を同時に作っていればその限りでない!
- </li>
- </ul>
- </li>
- </ul>
- </li>
- </ul>
- <p>
- この「ルール自体を変えられる」という性質により、パズルの難易度・複雑さが大きく上がっている。プレイヤーは、どのオブジェクトを <code>YOU</code> にするのか、<code>WIN</code> にすべきは何か、どれに <code>PUSH</code> を付けるべきか、いつどの順番でルールを変えるのか、今の手札で作れるルールは何か等と悩みながら、次第に難しくなるパズルと格闘しなければならない。
- </p>
- </section>
- <section id="section--no-spoiler--play-time-and-difficulty">
- <h3><a href="#section--no-spoiler--play-time-and-difficulty">ゲームのボリューム・難易度</a></h3>
- <p>
- 遊べる面の数は「200 以上」ある (Steam ストアページの表記より引用。正確な個数はここでは控える)。ただしこれは追加 DLC の分を含んでいないので、実際には更に大量にある。
- </p>
- <p>
- パズルゲームなのでプレイ時間には大きくブレがあるだろうが、私の場合はノーヒントで 75 時間弱だった。ゲーム画面を閉じて紙とペンで考えていた時間を含めれば、+10~+20時間といったところだろうか。
- </p>
- <p>
- パズルの難易度はべらぼうに高い。ひとつ解くのに数時間かかったり、数日間ひとつも解けなかったりするのはよくある (あくまで全クリを目指す場合)。
- </p>
- <p>
- 完全クリア以外にもいくつかマイルストーンはあるので、それを目指すのもありだろう。
- </p>
- </section>
- <section id="section--no-spoiler--appeal">
- <h3><a href="#section--no-spoiler--appeal">魅力</a></h3>
- <p>
- 何がこのゲームを傑作たらしめているのか。
- </p>
- <section id="section--no-spoiler--appeal--very-difficult">
- <h4><a href="#section--no-spoiler--appeal--very-difficult">高い難易度</a></h4>
- <p>
- すでに書いたが、このゲームは非常に難しい。ゲームのルールを変えられると聞くと、何でもありの大味なプレイ体験かのように思えるかもしれない。しかし、適当にルールを弄り回して解けるような面は最序盤くらいにしかなく、ゲームが進んでいくと総当たりすら困難になっていく。解けない、やれることは全部試したはずだ、ゴールから逆算してもこれ以外ありえないのに実現できない、とにかく解けない。何度もそう思うことになるだろう。
- </p>
- <p>
- それにもかかわらず、理不尽だと感じることは驚くほど少ない。隠された法則・秘密のルールがないというわけではない。最初の面を再び例に出そう。<code>ROCK</code> <code>IS</code> <code>PUSH</code> と <code>ROCK</code> <code>IS</code> <code>STOP</code> を同時に成立させたら、岩は押せるのか押せないのか。<code>PUSH</code> と <code>STOP</code> の優先順は言葉で説明されるわけではないし、自分で試して規則を発見することが求められる。しかし、実際にゲーム上で試しさえすれば、その規則は明らかな結果となってプレイヤーへと提示されるのである。これを繰り返すことで、プレイヤーは単語ごとの挙動を、そして Baba Is You を理解していく。
- </p>
- <p>
- この特徴により、その難易度に比して理不尽さが大きく低減されていると感じる。
- </p>
- </section>
- <section id="section--no-spoiler--appeal--very-flexible">
- <h4><a href="#section--no-spoiler--appeal--very-flexible">新しい単語との出会い</a></h4>
- <p>
- このゲームには <code>PUSH</code>、<code>STOP</code>、<code>WIN</code>、<code>YOU</code> 以外にもさまざまな単語がある。新しい単語が導入されるときは大抵チュートリアル用の簡単な面が用意されており、プレイヤーはそこで新単語を使っていろいろと実験をすることになる。
- </p>
- <p>
- それらの単語の中には、一目で「危険」だとわかる奴らがいる。<code>YOU</code> や <code>WIN</code> は最初からいる連中だが、普通のパズルゲームなら操作キャラや勝利条件を変えられるだけでもとんでもないルールブレイカーだろう。
- </p>
- <p>
- 危険な匂いのする単語と出会ったときの「こんな単語を許したらとんでもないことになるぞ」という感覚は実際にプレイしなければ味わえない。
- </p>
- </section>
- <section id="section--no-spoiler--appeal--very-beautiful">
- <h4><a href="#section--no-spoiler--appeal--very-beautiful">美しいパズル</a></h4>
- <p>
- 私が大好きなとある面の話をしよう。この面は最終盤に出現する。これは序中盤で出てきたとある面のリメイクであり、ほんの少しだけ手が加えられている。オリジナルとリメイク版の差分は1マスの窪みがあるかないか。この一つの差分だけで、難易度が劇的に上昇している。片や特筆することのない印象の薄い面、片やゲーム内屈指の高難易度面である。最終盤にあるがゆえになんとか解けるものの、もし配置順が入れ替わりでもしようものなら (難易度の差を考えれば絶対にありえないことだが)、ほとんどのプレイヤーがここで諦めるだろう。
- </p>
- <p>
- これを解いたときは、たった1マスの差でこれだけ難しくできるものなのかと感動した。他にも似たような例はいくつもある。素晴しい出来の美しいパズルに何度も何度も出会うことができる。
- </p>
- </section>
- </section>
- <section id="section--no-spoiler--play-now">
- <h3><a href="#section--no-spoiler--play-now">Baba Is You をやれ</a></h3>
- <p>
- Baba Is You は最高のパズルゲームである。
- </p>
- <p>
- お世辞にも簡単だとは言えないが、苦しむ価値のあるゲームである。
- </p>
- <p>
- この次のセクションからはネタバレありの感想を書くが、プレイしていない人はもちろん、プレイ中で完全クリアしていない人も読まないことを勧める。その価値があるゲームだと保証する。
- </p>
- </section>
- </section>
- <section id="section--spoiler">
- <h2><a href="#section--spoiler">後半 (ネタバレあり)</a></h2>
- <p>
- ではここからは完全クリアしたプレイヤーに向けて話そう。
- </p>
- <p>
- ここでいう「完全クリア」はレベルパックの「Baba Is You」(いわゆる本編) に用意されているパズルをすべて解いた状態を指すことにする。Steam の場合、全実績解除と読み替えてもよい。すなわち、「Museum」や「New Adventures」を含まない。
- </p>
- <section id="section--spoiler--notation">
- <h3><a href="#section--spoiler--notation">表記</a></h3>
- <p>
- ゲーム上のオブジェクトについて次のように表記することにする。
- </p>
- <ul>
- <li>
- <code>BABA</code>: テキストとしての <code>BABA</code>
- </li>
- <li>
- Baba: オブジェクトとしての baba
- </li>
- <li>
- <code>A</code>、<code>B</code> など: 任意のテキスト
- <ul>
- <li>
- そういうテキストが出てくる面もあるがその面の話はしない
- </li>
- </ul>
- </li>
- <li>
- A、B など: 任意のオブジェクト
- </li>
- <li>
- <code>A/B</code>: <code>A</code> と <code>B</code> のテキストが重なった状態
- </li>
- </ul>
- <p>
- また、個々のパズルのことはここまでと同様に「面」と呼ぶことにする。「<code>LEVEL</code> というテキストが指すゲーム上のオブジェクト」は「level」と書く。
- </p>
- </section>
- <section id="section--spoiler--impressive-levels">
- <h3><a href="#section--spoiler--impressive-levels">印象的な面</a></h3>
- <p>
- ここからは印象的な面を語っていく。
- </p>
- <section id="section--spoiler--impressive-levels--map">
- <h4><a href="#section--spoiler--impressive-levels--map">MAP</a></h4>
- <section id="section--spoiler--impressive-levels--map--submerged-ruins-and-sunken-temple">
- <h5><a href="#section--spoiler--impressive-levels--map--submerged-ruins-and-sunken-temple">SUBMERGED RUINS、SUNKEN TEMPLE</a></h5>
- <p>
- <img alt="「SUBMERGED RUINS」のスクリーンショット" src="/posts/2025-06-14/baba-is-you/LEVEL_SUBMERGED_RUINS.jpeg">
- </p>
- <p>
- <img alt="「SUNKEN TEMPLE」のスクリーンショット" src="/posts/2025-06-14/baba-is-you/LEVEL_SUNKEN_TEMPLE.jpeg">
- </p>
- <p>
- ここまでスルスル解けていて初めてしばらく止まった面。また、苦戦して解いた次の面がその面の派生で絶望するという経験をした最初の面。この瞬間が苦しくもあり楽しくもある。
- </p>
- </section>
- <section id="section--spoiler--impressive-levels--map--prison-and-dungeon">
- <h5><a href="#section--spoiler--impressive-levels--map--prison-and-dungeon">PRISON、DUNGEON</a></h5>
- <p>
- <img alt="「PRISON」のスクリーンショット" src="/posts/2025-06-14/baba-is-you/LEVEL_PRISON.jpeg">
- </p>
- <p>
- <img alt="「DUNGEON」のスクリーンショット" src="/posts/2025-06-14/baba-is-you/LEVEL_DUNGEON.jpeg">
- </p>
- <p>
- 高難易度面で当然のように要求されるテクニックの初出。可能な行動が大きく制限されているのでマシだが、それでも初見時には困惑した。
- </p>
- </section>
- <section id="section--spoiler--impressive-levels--map--further-fields">
- <h5><a href="#section--spoiler--impressive-levels--map--further-fields">FURTHER FIELDS</a></h5>
- <p>
- <img alt="「FURTHER FIELDS」のスクリーンショット" src="/posts/2025-06-14/baba-is-you/LEVEL_FURTHER_FIELDS.jpeg">
- </p>
- <p>
- お気に入りの面。<code>MOVE</code> を活用するのも <code>YOU</code> を一時的に消すのも好きなので、両方出てくるこの面は大好き。
- </p>
- </section>
- <section id="section--spoiler--impressive-levels--map--scenic-pond">
- <h5><a href="#section--spoiler--impressive-levels--map--scenic-pond">SCENIC POND</a></h5>
- <p>
- <img alt="「SCENIC POND」のスクリーンショット" src="/posts/2025-06-14/baba-is-you/LEVEL_SCENIC_POND.jpeg">
- </p>
- <p>
- はい。まあこいつは後で触れることにしよう。
- </p>
- </section>
- <section id="section--spoiler--impressive-levels--map--concrete-goals">
- <h5><a href="#section--spoiler--impressive-levels--map--concrete-goals">CONCRETE GOALS</a></h5>
- <p>
- <img alt="「CONCRETE GOALS」のスクリーンショット" src="/posts/2025-06-14/baba-is-you/LEVEL_CONCRETE_GOALS.jpeg">
- </p>
- <p>
- これも初見時に苦戦した面。PRISON などと同様に一度理解すれば何ということのない面だが、最初に解けたときは偶然だった。<code>FLAG</code> <code>IS</code> <code>WIN</code> がギリギリ取り出せそうに「見える」のが嫌らしい。
- </p>
- </section>
- <section id="section--spoiler--impressive-levels--map--lock-the-door">
- <h5><a href="#section--spoiler--impressive-levels--map--lock-the-door">LOCK THE DOOR</a></h5>
- <p>
- <img alt="「LOCK THE DOOR」のスクリーンショット" src="/posts/2025-06-14/baba-is-you/LEVEL_LOCK_THE_DOOR.jpeg">
- </p>
- <p>
- <code>SHIFT</code> 重ねの初出面。このテクニックを再び使うのは終盤になってからであり、私はそのときにはもう <code>SHIFT</code> 重ねを忘れていたので大苦戦した。戯れにスロット2を使って2周目をやっていてこの面まで到達し、そこでようやく <code>SHIFT</code> 重ねが <code>MOVE</code> もどきになることを思い出した。その意味でも印象深い面。
- </p>
- </section>
- <section id="section--spoiler--impressive-levels--map--insulation">
- <h5><a href="#section--spoiler--impressive-levels--map--insulation">INSULATION</a></h5>
- <p>
- <img alt="「INSULATION」のスクリーンショット" src="/posts/2025-06-14/baba-is-you/LEVEL_INSULATION.jpeg">
- </p>
- <p>
- MAP の前半 (~DEEP FOREST) では最も苦戦した面。<code>SWAP</code> の理解が固まっておらず、「こういう状況が作れたら解けそうだ」という勘が働かなかった。正直なところ <code>SWAP</code> は今も苦手意識がある (終盤で強制的に学ばされる <code>SHIFT</code> と違って、それほど高難度面での出番がないのも大きいと思う)。
- </p>
- </section>
- <section id="section--spoiler--impressive-levels--map--bottleneck">
- <h5><a href="#section--spoiler--impressive-levels--map--bottleneck">BOTTLENECK</a></h5>
- <p>
- <img alt="「BOTTLENECK」のスクリーンショット" src="/posts/2025-06-14/baba-is-you/LEVEL_BOTTLENECK.jpeg">
- </p>
- <p>
- MAP の中で一番苦しんだ面。実は一度ここで投げて諦めたのだが、<code>EMPTY</code> を理解した今となっては脳内でも瞬殺できるくらい簡単になってしまった。最初に面を見てから解き終わるまでの時間は間違いなく最長で、半年以上かかっている (他は長くとも数日間)。
- </p>
- </section>
- <section id="section--spoiler--impressive-levels--map--heavy-cloud">
- <h5><a href="#section--spoiler--impressive-levels--map--heavy-cloud">HEAVY CLOUD</a></h5>
- <p>
- <img alt="「HEAVY CLOUD」のスクリーンショット" src="/posts/2025-06-14/baba-is-you/LEVEL_HEAVY_CLOUD.jpeg">
- </p>
- <p>
- 難しい面ではあるのだが、それ以上に解法の美しさに感動した面。解き終わった後に思わず「美しい……」と呟いてしまったのはこの面だけだった。Baba Is You の好きな面はと聞かれれば真っ先にこれを挙げる。
- </p>
- </section>
- <section id="section--spoiler--impressive-levels--map--adventurers">
- <h5><a href="#section--spoiler--impressive-levels--map--adventurers">ADVENTURERS</a></h5>
- <p>
- <img alt="「ADVENTURERS」のスクリーンショット" src="/posts/2025-06-14/baba-is-you/LEVEL_ADVENTURERS.jpeg">
- </p>
- <p>
- 難所の多い FLOWER GARDEN の癒し。Hand が <code>MOVE</code> と <code>SHIFT</code> でガチャガチャ動くのを見るのが楽しい。
- </p>
- </section>
- <section id="section--spoiler--impressive-levels--map--out-at-sea">
- <h5><a href="#section--spoiler--impressive-levels--map--out-at-sea">OUT AT SEA</a></h5>
- <p>
- <img alt="「OUT AT SEA」のスクリーンショット" src="/posts/2025-06-14/baba-is-you/LEVEL_OUT_AT_SEA.jpeg">
- </p>
- <p>
- MAP の問題児。正攻法がテキスト重ねである最初の面。この面、<code>ICE/LAVA</code> <code>IS</code> <code>PUSH</code> を作ったあと重なった ice と lava を (<code>ICE</code> <code>IS</code> <code>PUSH</code> だけ作るなどして) 分離しないといけないのだが、意気揚々と ice on lava の状態で door に向かって push して push できなかったときの感情はよく覚えている。テキスト同士を重ねて <code>A</code> <code>IS</code> <code>PUSH</code> と <code>B</code> <code>IS</code> <code>PUSH</code> を両立させるというぶっ飛んだアイデアを実現してもなお解けないのか、この方針がまさか間違っているなどということがあるのか、いやそんなはずはない……。実際のところそこからのリカバリーはすぐできたが、そのときの絶望はこれまででも最大であった。
- </p>
- </section>
- <section id="section--spoiler--impressive-levels--map--seeking-acceptance">
- <h5><a href="#section--spoiler--impressive-levels--map--seeking-acceptance">SEEKING ACCEPTANCE</a></h5>
- <p>
- <img alt="「SEEKING ACCEPTANCE」のスクリーンショット" src="/posts/2025-06-14/baba-is-you/LEVEL_SEEKING_ACCEPTANCE.jpeg">
- </p>
- <p>
- ここも好きな面。FURTHER FIELDS の精神的後継のようなものなので当然かもしれない。せっせと働く bird がかわいい。
- </p>
- </section>
- <section id="section--spoiler--impressive-levels--map--fragile-existence">
- <h5><a href="#section--spoiler--impressive-levels--map--fragile-existence">FRAGILE EXISTENCE</a></h5>
- <p>
- <img alt="「FRAGILE EXISTENCE」のスクリーンショット" src="/posts/2025-06-14/baba-is-you/LEVEL_FRAGILE_EXISTENCE.jpeg">
- </p>
- <p>
- MAP の印象的な面と言えば、これを取り上げないわけにはいかない。<code>LEVEL</code> <code>IS</code> <code>A</code> による level の変換がおこなえる初の面である。ここまで Baba Is You を進めたプレイヤーであれば、初出のテキストが現れたらまずはその場の色々なテキストと組み合わせてみて相互作用を確認する。それを見事に利用されたというか、気付かずにはいられないように仕向けられているというか、本当によくできたゲームである。
- </p>
- </section>
- <section id="section--spoiler--impressive-levels--map--map">
- <h5><a href="#section--spoiler--impressive-levels--map--map">MAP</a></h5>
- <p>
- MAP 自身。FRAGILE EXISTENCE でそれに気付いたなら当然 HOSTILE ENVIRONMENT でも気付くし、MAP で baba が操作できることに気付いたならもちろん右下のルールに目を向ける。次に考えるのは無論こうだ。ここで flag を取ったらどうなるんだ? このゲームはその疑問に答えてくれる。期待をはるかに上回る形で。
- </p>
- <p>
- ??? でまたしても待ち構える <code>BABA</code> <code>IS</code> <code>YOU</code> と不穏な <code>LEVEL</code> のテキスト、そして GLITCH の <code>W</code> <code>E</code> <code>L</code> <code>C</code> <code>O</code> <code>M</code> <code>E</code>。間違いなく最高のパズルゲームだと確信した。
- </p>
- </section>
- </section>
- <section id="section--spoiler--impressive-levels--triple-question">
- <h4><a href="#section--spoiler--impressive-levels--triple-question">???</a></h4>
- <section id="section--spoiler--impressive-levels--triple-question--vip-area">
- <h5><a href="#section--spoiler--impressive-levels--triple-question--vip-area">VIP AREA</a></h5>
- <p>
- <img alt="「VIP AREA」のスクリーンショット" src="/posts/2025-06-14/baba-is-you/LEVEL_VIP_AREA.jpeg">
- </p>
- <p>
- ??? で大いに苦戦した面のひとつ。PRISON と DUNGEON で既出のテクニックが肝だが、ちと離れすぎじゃないのか。この面のリメイクもあるが、ここで苦しんだからかそちらはあまり苦戦しなかった。
- </p>
- </section>
- <section id="section--spoiler--impressive-levels--triple-question--ultimate-maze">
- <h5><a href="#section--spoiler--impressive-levels--triple-question--ultimate-maze">ULTIMATE MAZE</a></h5>
- <p>
- <img alt="「ULTIMATE MAZE」のスクリーンショット" src="/posts/2025-06-14/baba-is-you/LEVEL_ULTIMATE_MAZE.jpeg">
- </p>
- <p>
- 普通に解くだけなら大したことのない面だが、問題はこれの <code>LEVEL</code> <code>IS</code> <code>TEXT</code> 解である。出現順に書いているのでここに置いたが、解いたのはもっと後、META の後半に差しかかった頃になる。??? コンプリートの実績が取れていないことに気付き、残っているとすればここの <code>LEVEL</code> <code>IS</code> <code>TEXT</code> しかないと考えたまではよかったが、そこからが大変だった。個人的にこのゲームで一番苦しかったのがここの <code>TEXT</code> 変換解である。単純な難しさに加え、実績が取れていない原因がこの面だという確信も持てなかったので、解けるかどうかわからない状態で挑み続けることとなり疲弊した。
- </p>
- <div class="admonition" editat="2025-06-15" operation="追記">
- <div class="admonition-label">
- 2025-06-15 追記
- </div>
- <div class="admonition-content">
- <p>
- ??? の DO IT YOURSELF 以降を開くにはこの面の <code>LEVEL</code> <code>IS</code> <code>TEXT</code> が必須だと思っていたのだが、どうもそうではないらしい。いずれにせよそれを思いつけなかったので同じことか。
- </p>
- </div>
- </div>
- </section>
- <section id="section--spoiler--impressive-levels--triple-question--stardrop-and-meteor-strike">
- <h5><a href="#section--spoiler--impressive-levels--triple-question--stardrop-and-meteor-strike">STARDROP、METEOR STRIKE</a></h5>
- <p>
- <img alt="「STARDROP」のスクリーンショット" src="/posts/2025-06-14/baba-is-you/LEVEL_STARDROP.jpeg">
- </p>
- <p>
- <img alt="「METEOR STRIKE」のスクリーンショット" src="/posts/2025-06-14/baba-is-you/LEVEL_METEOR_STRIKE.jpeg">
- </p>
- <p>
- 両方とも難しい面ではあったが、単文字のテキストが綺麗に活用された美しい面として印象に残っている。<code>G</code> <code>R</code> <code>A</code> <code>S</code> <code>S</code> <code>IS</code> <code>H</code> <code>O</code> <code>T</code> をこれほど無駄なく使えるとは!
- </p>
- </section>
- <section id="section--spoiler--impressive-levels--triple-question--getting-together">
- <h5><a href="#section--spoiler--impressive-levels--triple-question--getting-together">GETTING TOGETHER</a></h5>
- <p>
- <img alt="「GETTING TOGETHER」のスクリーンショット" src="/posts/2025-06-14/baba-is-you/LEVEL_GETTING_TOGETHER.jpeg">
- </p>
- <p>
- 初見のインパクト大にして難易度も相応に高い良作。この頃はまだ <code>SHIFT</code> を<em>理解</em>していなかったので大変だったが、ここを越えたことでむしろこの後の難所が楽になったと言える。
- </p>
- </section>
- </section>
- <section id="section--spoiler--impressive-levels--depths">
- <h4><a href="#section--spoiler--impressive-levels--depths">DEPTHS</a></h4>
- <p>
- ??? といういかにもクリア後のオマケっぽい名前のマップを攻略したらまだまだ深淵が待ち構えていた。
- </p>
- <section id="section--spoiler--impressive-levels--depths--crushers">
- <h5><a href="#section--spoiler--impressive-levels--depths--crushers">CRUSHERS</a></h5>
- <p>
- <img alt="「CRUSHERS」のスクリーンショット" src="/posts/2025-06-14/baba-is-you/LEVEL_CRUSHERS.jpeg">
- </p>
- <p>
- DEPTHS の序盤で道を塞いでいる必須面であるにもかかわらず圧倒的難易度で立ちはだかる凶悪な面。大苦戦した挙句 <code>LEVEL</code> <code>IS</code> <code>BELT</code> を作ってアレ?となったのは私だけではないはず。
- </p>
- </section>
- <section id="section--spoiler--impressive-levels--depths--parade">
- <h5><a href="#section--spoiler--impressive-levels--depths--parade">PARADE</a></h5>
- <p>
- <img alt="「PARADE」のスクリーンショット" src="/posts/2025-06-14/baba-is-you/LEVEL_PARADE.jpeg">
- </p>
- <p>
- 取れる行動が多いこと、もう少しで解けそうなルートが多いこと、そのどれもが一筋縄ではいかないこと。それらがすべて揃った高難度面。昔のバージョンでは ??? に置いてあったらしい。そんなバカな。
- </p>
- </section>
- </section>
- <section id="section--spoiler--impressive-levels--meta">
- <h4><a href="#section--spoiler--impressive-levels--meta">META</a></h4>
- <p>
- ここではもう覚悟していたので続きがあることには驚かなかったが、明らかに不穏な <code>CURSOR</code> に震えつつ先へ進むことになる。
- </p>
- <section id="section--spoiler--impressive-levels--meta--booby-trap">
- <h5><a href="#section--spoiler--impressive-levels--meta--booby-trap">BOOBY TRAP</a></h5>
- <p>
- <img alt="「BOOBY TRAP」のスクリーンショット" src="/posts/2025-06-14/baba-is-you/LEVEL_BOOBY_TRAP.jpeg">
- </p>
- <p>
- 難しいとか難しくないとかじゃなくここは触れざるをえない。<code>FLAG/TEXT</code> 解以外はそれほど苦戦しなかったが、とにもかくにもクリアの要求回数が多すぎる。もちろん最短で進められるなら別だが、META での試行錯誤のためにはこいつの形を毎回変えなければならない。しかもどの変換もそれなりにステップ数を要するのが厄介である。印象に残った面であるのは確か。
- </p>
- </section>
- <section id="section--spoiler--impressive-levels--meta--the-box">
- <h5><a href="#section--spoiler--impressive-levels--meta--the-box">THE BOX</a></h5>
- <p>
- <img alt="「THE BOX」のスクリーンショット" src="/posts/2025-06-14/baba-is-you/LEVEL_THE_BOX.jpeg">
- </p>
- <p>
- よくぞこの面を作ってくれた。外の level を参照させるギミックは、<code>LEVEL</code> <code>IS</code> <code>A</code> の変換をやりだした頃からいつかあるはずと思っていたので、そのとおりのパズルが出てきてくれて嬉しい。これぞ Baba Is You。
- </p>
- </section>
- <section id="section--spoiler--impressive-levels--meta--the-return-of-scenic-pond">
- <h5><a href="#section--spoiler--impressive-levels--meta--the-return-of-scenic-pond">THE RETURN OF SCENIC POND</a></h5>
- <p>
- <img alt="「THE RETURN OF SCENIC POND」のスクリーンショット" src="/posts/2025-06-14/baba-is-you/LEVEL_THE_RETURN_OF_SCENIC_POND.jpeg">
- </p>
- <p>
- 前半のネタバレなし感想にも書いたが、これは SCENIC POND のリメイクであり、ほとんど差異がない。たった1マス窪みが無くなっただけである。それだけでここまで難しくできるのか。
- </p>
- <p>
- 最終盤に配置されていたことで難易度の割には苦戦しなかったが、難易度以上にリメイクの美しさに感動した面。
- </p>
- </section>
- </section>
- </section>
- <section id="section--spoiler--difficult-levels">
- <h3><a href="#section--spoiler--difficult-levels">初見時難易度ランキング</a></h3>
- <p>
- 最後に、初見時の難易度を 10 位までランキングにしてみた。あくまで初見のときの難易度なので、面自体の難易度ではない。解くのにかかった時間とも少し違う。あえて言うなら苦しんだ順。
- </p>
- <ol>
- <li>
- ULTIMATE MAZE (<code>TEXT</code> 解)
- </li>
- <li>
- CRUSHERS (<code>TEXT</code> 解)
- </li>
- <li>
- PARADE
- </li>
- <li>
- BOTTLENECK
- </li>
- <li>
- BOOBY TRAP (<code>FLAG/TEXT</code> 解)
- </li>
- <li>
- THE RETURN OF SCENIC POND
- </li>
- <li>
- OUT AT SEA
- </li>
- <li>
- GETTING TOGETHER
- </li>
- <li>
- VIP AREA
- </li>
- <li>
- STARDROP
- </li>
- </ol>
- </section>
- </section>
- <section id="section--outro">
- <h2><a href="#section--outro">おわりに</a></h2>
- <p>
- 神ゲー。プレイ済みの人は会ったとき一番好きな面の話でもしましょう。
- </p>
- </section>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/3/index.html b/vhosts/blog/public/posts/3/index.html
deleted file mode 100644
index d1084aa1..00000000
--- a/vhosts/blog/public/posts/3/index.html
+++ /dev/null
@@ -1,222 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2021 nsfisis">
- <meta name="description" content="投稿した記事の一覧 (3ページ目)">
- <meta property="og:type" content="article">
- <meta property="og:title" content="投稿一覧 (3ページ目)|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="投稿した記事の一覧 (3ページ目)">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/posts/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>投稿一覧 (3ページ目)|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>投稿一覧 (3ページ目)</h1>
- </header>
- <nav class="pagination">
- <div class="pagination-prev">
- <a href="/posts/2/">前のページ</a>
- </div>
- <div class="pagination-info">
- 3 / 6
- </div>
- <div class="pagination-next">
- <a href="/posts/4/">次のページ</a>
- </div>
- </nav>
- <article class="post-entry">
- <a href="/posts/2024-03-17/phperkaigi-2024-report/">
- <header class="entry-header">
- <h2>PHPerKaigi 2024 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2024-03-07 から 2024-03-09 にかけて開催された、PHPerKaigi 2024 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-03-17">2024-03-17</time> 投稿、<time datetime="2024-07-07">2024-07-07</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2024-02-22/phpkansai-2024-report/">
- <header class="entry-header">
- <h2>PHPカンファレンス関西 2024 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2024-02-11 に開催された、PHPカンファレンス関西 2024 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-02-21">2024-02-21</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2024-02-10/yapcjapan-2024-report/">
- <header class="entry-header">
- <h2>YAPC::Hiroshima 2024 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2024-02-10 に開催された、YAPC::Hiroshima 2024 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-02-10">2024-02-10</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2024-02-03/install-wireguard-on-personal-server/">
- <header class="entry-header">
- <h2>【備忘録】 個人用サーバに WireGuard を導入する</h2>
- </header>
- <section class="entry-content">
- <p>
- 個人用サービスのセルフホストに使っているサーバに WireGuard を導入する作業をしたメモ
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-02-03">2024-02-03</time> 投稿、<time datetime="2024-02-17">2024-02-17</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2024-01-10/neovim-insert-namespace-declaration-to-empty-php-file/">
- <header class="entry-header">
- <h2>【Neovim】 空の PHP ファイルに namespace 宣言を挿入する</h2>
- </header>
- <section class="entry-content">
- <p>
- Neovim で空の PHP ファイルを開いたとき、ディレクトリの構造に基づいて自動的に namespace 宣言を挿入するようにする。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-01-10">2024-01-10</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2023-12-31/2023-reflections/">
- <header class="entry-header">
- <h2>2023年の振り返り</h2>
- </header>
- <section class="entry-content">
- <p>
- 2023年にやったことを振り返る
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-12-31">2023-12-31</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2023-12-03/isucon-13/">
- <header class="entry-header">
- <h2>ISUCON 13 に参加した</h2>
- </header>
- <section class="entry-content">
- <p>
- ISUCON 13 に参加した。チーム名「うつしもゆ」、最終スコア 13,580 点
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-12-03">2023-12-03</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2023-10-13/i-entered-the-open-university-of-japan/">
- <header class="entry-header">
- <h2>放送大学に入学しました</h2>
- </header>
- <section class="entry-content">
- <p>
- 放送大学に入学しました。頑張ります。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-10-13">2023-10-13</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2023-10-02/compile-php-runtime-to-wasm/">
- <header class="entry-header">
- <h2>PHP の処理系を Emscripten で WebAssembly にコンパイルする</h2>
- </header>
- <section class="entry-content">
- <p>
- PHP の処理系 (php/php-src) を Emscripten で WebAssembly にコンパイルし、任意のコードを隔離された環境で評価できるようにした。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-10-02">2023-10-02</time> 投稿、<time datetime="2025-04-23">2025-04-23</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2023-06-25/phpconfuk-2023-report/">
- <header class="entry-header">
- <h2>PHP カンファレンス福岡 2023 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2023-06-24 に開催された、PHP カンファレンス福岡に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-06-25">2023-06-25</time> 投稿
- </footer>
- </a>
- </article>
- <nav class="pagination">
- <div class="pagination-prev">
- <a href="/posts/2/">前のページ</a>
- </div>
- <div class="pagination-info">
- 3 / 6
- </div>
- <div class="pagination-next">
- <a href="/posts/4/">次のページ</a>
- </div>
- </nav>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/4/index.html b/vhosts/blog/public/posts/4/index.html
deleted file mode 100644
index f5c6bc29..00000000
--- a/vhosts/blog/public/posts/4/index.html
+++ /dev/null
@@ -1,222 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2021 nsfisis">
- <meta name="description" content="投稿した記事の一覧 (4ページ目)">
- <meta property="og:type" content="article">
- <meta property="og:title" content="投稿一覧 (4ページ目)|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="投稿した記事の一覧 (4ページ目)">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/posts/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>投稿一覧 (4ページ目)|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>投稿一覧 (4ページ目)</h1>
- </header>
- <nav class="pagination">
- <div class="pagination-prev">
- <a href="/posts/3/">前のページ</a>
- </div>
- <div class="pagination-info">
- 4 / 6
- </div>
- <div class="pagination-next">
- <a href="/posts/5/">次のページ</a>
- </div>
- </nav>
- <article class="post-entry">
- <a href="/posts/2023-04-04/phperkaigi-2023-report/">
- <header class="entry-header">
- <h2>PHPerKaigi 2023 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2023-03-23 から 2023-03-25 にかけて開催された、PHPerKaigi 2023 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-04-04">2023-04-04</time> 投稿、<time datetime="2023-06-28">2023-06-28</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2023-04-01/implementation-of-minimal-png-image-encoder/">
- <header class="entry-header">
- <h2>PNG 画像の最小構成エンコーダを実装する</h2>
- </header>
- <section class="entry-content">
- <p>
- PNG 画像として valid な範囲で最大限手抜きしたエンコーダを書く。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-04-01">2023-04-01</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2023-03-10/rewrite-this-blog-generator/">
- <header class="entry-header">
- <h2>このブログのジェネレータを書き直した</h2>
- </header>
- <section class="entry-content">
- <p>
- このブログのジェネレータを書き直したので、やったことを書き記しておく。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-03-10">2023-03-10</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2023-01-10/phperkaigi-2023-unused-token-quiz-3/">
- <header class="entry-header">
- <h2>PHPerKaigi 2023: ボツになったトークン問題 その 3</h2>
- </header>
- <section class="entry-content">
- <p>
- 来年の PHPerKaigi 2023 でデジタルサーカス株式会社から出題予定のトークン問題のうち、ボツになった問題を公開する (その 3)。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-01-10">2023-01-10</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2022-11-19/phperkaigi-2023-unused-token-quiz-2/">
- <header class="entry-header">
- <h2>PHPerKaigi 2023: ボツになったトークン問題 その 2</h2>
- </header>
- <section class="entry-content">
- <p>
- 来年の PHPerKaigi 2023 でデジタルサーカス株式会社から出題予定のトークン問題のうち、ボツになった問題を公開する (その 2)。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2022-11-19">2022-11-19</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2022-10-28/setup-server-for-this-site/">
- <header class="entry-header">
- <h2>【備忘録】 このサイト用の VPS をセットアップしたときのメモ</h2>
- </header>
- <section class="entry-content">
- <p>
- GitHub Pages でホストしていたこのサイトを VPS へ移行したので、そのときにやったことのメモ。99 % 自分用。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2022-10-28">2022-10-28</time> 投稿、<time datetime="2023-08-30">2023-08-30</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2022-10-23/phperkaigi-2023-unused-token-quiz-1/">
- <header class="entry-header">
- <h2>PHPerKaigi 2023: ボツになったトークン問題 その 1</h2>
- </header>
- <section class="entry-content">
- <p>
- 来年の PHPerKaigi 2023 でデジタルサーカス株式会社から出題予定のトークン問題のうち、ボツになった問題を公開する (その 1)。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2022-10-23">2022-10-23</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2022-09-29/write-fizzbuzz-in-php-2-letters-per-line/">
- <header class="entry-header">
- <h2>【PHP】 fizzbuzz を書く。1行あたり2文字で。</h2>
- </header>
- <section class="entry-content">
- <p>
- PHP で fizzbuzz を書いた。ただし、1行あたりに使える文字数は2文字まで。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2022-09-28">2022-09-28</time> 投稿、<time datetime="2022-09-29">2022-09-29</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2022-08-31/support-for-communty-is-employee-benefits/">
- <header class="entry-header">
- <h2>弊社の PHP Foundation への寄付に寄せて</h2>
- </header>
- <section class="entry-content">
- <p>
- 先日、私の勤めるデジタルサーカス株式会社が、PHP Foundation へ寄付をおこないました。本件を社内でしつこく推進した1人として、推進の理由等を書き残しておきます。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2022-08-31">2022-08-31</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2022-08-27/php-conference-okinawa-code-golf/">
- <header class="entry-header">
- <h2>PHP カンファレンス沖縄で出題されたコードゴルフの問題を解いてみた</h2>
- </header>
- <section class="entry-content">
- <p>
- PHP カンファレンス沖縄の懇親会 LT で出題されたコードゴルフの問題を解いてみた。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2022-08-27">2022-08-27</time> 投稿
- </footer>
- </a>
- </article>
- <nav class="pagination">
- <div class="pagination-prev">
- <a href="/posts/3/">前のページ</a>
- </div>
- <div class="pagination-info">
- 4 / 6
- </div>
- <div class="pagination-next">
- <a href="/posts/5/">次のページ</a>
- </div>
- </nav>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/5/index.html b/vhosts/blog/public/posts/5/index.html
deleted file mode 100644
index 6ae07782..00000000
--- a/vhosts/blog/public/posts/5/index.html
+++ /dev/null
@@ -1,222 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2021 nsfisis">
- <meta name="description" content="投稿した記事の一覧 (5ページ目)">
- <meta property="og:type" content="article">
- <meta property="og:title" content="投稿一覧 (5ページ目)|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="投稿した記事の一覧 (5ページ目)">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/posts/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>投稿一覧 (5ページ目)|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>投稿一覧 (5ページ目)</h1>
- </header>
- <nav class="pagination">
- <div class="pagination-prev">
- <a href="/posts/4/">前のページ</a>
- </div>
- <div class="pagination-info">
- 5 / 6
- </div>
- <div class="pagination-next">
- <a href="/posts/6/">次のページ</a>
- </div>
- </nav>
- <article class="post-entry">
- <a href="/posts/2022-05-01/phperkaigi-2022/">
- <header class="entry-header">
- <h2>PHPerKaigi 2022</h2>
- </header>
- <section class="entry-content">
- <p>
- 2022-04-09 から 2022-04-11 にかけて開催された、PHPerKaigi 2022 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2022-05-01">2022-05-01</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2022-04-24/term-banner-write-tool-showing-banner-in-terminal/">
- <header class="entry-header">
- <h2>term-banner: ターミナルにバナーを表示するツールを書いた</h2>
- </header>
- <section class="entry-content">
- <p>
- ターミナルに任意の文字のバナーを表示するためのツールを Go で書いた。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2022-04-24">2022-04-24</time> 投稿、<time datetime="2022-04-27">2022-04-27</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2022-04-09/phperkaigi-2022-tokens/">
- <header class="entry-header">
- <h2>PHPerKaigi 2022 トークン問題の解説</h2>
- </header>
- <section class="entry-content">
- <p>
- PHPerKaigi 2022 で私が作成した PHPer チャレンジ問題を解説する。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2022-04-09">2022-04-09</time> 投稿、<time datetime="2022-04-16">2022-04-16</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2021-10-02/cpp-you-can-use-keywords-in-attributes/">
- <header class="entry-header">
- <h2>【C++】 属性構文の属性名にはキーワードが使える</h2>
- </header>
- <section class="entry-content">
- <p>
- C++ の属性構文の属性名には、キーワードが使える。ネタ記事。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2021-10-02">2021-10-02</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2021-10-02/python-unbound-local-error/">
- <header class="entry-header">
- <h2>【Python】 クロージャとUnboundLocalError: local variable &apos;x&apos; referenced before assignment</h2>
- </header>
- <section class="entry-content">
- <p>
- Python における UnboundLocalError の理由と対処法。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2021-10-02">2021-10-02</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2021-10-02/ruby-detect-running-implementation/">
- <header class="entry-header">
- <h2>【Ruby】 自身を実行している処理系の種類を判定する</h2>
- </header>
- <section class="entry-content">
- <p>
- Ruby には複数の実装があるが、自身を実行している処理系の種類をスクリプト上からどのように判定すればよいだろうか。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2021-10-02">2021-10-02</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2021-10-02/ruby-then-keyword-and-case-in/">
- <header class="entry-header">
- <h2>【Ruby】 then キーワードと case in</h2>
- </header>
- <section class="entry-content">
- <p>
- Ruby 3.0 で追加される case in 構文と、then キーワードについて。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2021-10-02">2021-10-02</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2021-10-02/rust-where-are-primitive-types-from/">
- <header class="entry-header">
- <h2>Rust のプリミティブ型はどこからやって来るか</h2>
- </header>
- <section class="entry-content">
- <p>
- Rust のプリミティブ型は予約語ではなく普通の識別子である。どのようにこれが名前解決されるのかを調べた。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2021-10-02">2021-10-02</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2021-10-02/vim-difference-between-autocmd-bufwrite-and-bufwritepre/">
- <header class="entry-header">
- <h2>【Vim】 autocmd events の BufWrite/BufWritePre の違い</h2>
- </header>
- <section class="entry-content">
- <p>
- Vim の autocmd events における BufWrite/BufWritePre がどう違うのかを調べた結果、違いはないことがわかった。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2021-10-02">2021-10-02</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2021-10-02/vim-swap-order-of-selected-lines/">
- <header class="entry-header">
- <h2>Vimで選択した行の順番を入れ替える</h2>
- </header>
- <section class="entry-content">
- <p>
- Vim で選択した行の順番を入れ替える方法。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2021-10-02">2021-10-02</time> 投稿
- </footer>
- </a>
- </article>
- <nav class="pagination">
- <div class="pagination-prev">
- <a href="/posts/4/">前のページ</a>
- </div>
- <div class="pagination-info">
- 5 / 6
- </div>
- <div class="pagination-next">
- <a href="/posts/6/">次のページ</a>
- </div>
- </nav>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/6/index.html b/vhosts/blog/public/posts/6/index.html
deleted file mode 100644
index 9fee169f..00000000
--- a/vhosts/blog/public/posts/6/index.html
+++ /dev/null
@@ -1,100 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2021 nsfisis">
- <meta name="description" content="投稿した記事の一覧 (6ページ目)">
- <meta property="og:type" content="article">
- <meta property="og:title" content="投稿一覧 (6ページ目)|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="投稿した記事の一覧 (6ページ目)">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/posts/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>投稿一覧 (6ページ目)|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>投稿一覧 (6ページ目)</h1>
- </header>
- <nav class="pagination">
- <div class="pagination-prev">
- <a href="/posts/5/">前のページ</a>
- </div>
- <div class="pagination-info">
- 6 / 6
- </div>
- <div class="pagination-next">
- </div>
- </nav>
- <article class="post-entry">
- <a href="/posts/2021-03-30/phperkaigi-2021/">
- <header class="entry-header">
- <h2>PHPerKaigi 2021</h2>
- </header>
- <section class="entry-content">
- <p>
- 2021-03-26 から 2021-03-28 にかけて開催された、PHPerKaigi 2021 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2021-03-30">2021-03-30</time> 投稿、<time datetime="2025-04-09">2025-04-09</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2021-03-05/my-first-post/">
- <header class="entry-header">
- <h2>My First Post</h2>
- </header>
- <section class="entry-content">
- <p>
- これはテスト投稿です。これはテスト投稿です。これはテスト投稿です。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2021-03-05">2021-03-05</time> 投稿、<time datetime="2025-05-12">2025-05-12</time> 更新
- </footer>
- </a>
- </article>
- <nav class="pagination">
- <div class="pagination-prev">
- <a href="/posts/5/">前のページ</a>
- </div>
- <div class="pagination-info">
- 6 / 6
- </div>
- <div class="pagination-next">
- </div>
- </nav>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/posts/atom.xml b/vhosts/blog/public/posts/atom.xml
deleted file mode 100644
index 8ffa9d26..00000000
--- a/vhosts/blog/public/posts/atom.xml
+++ /dev/null
@@ -1,427 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:posts</id>
- <title>投稿一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/posts/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2025-06-15T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:127019eb-e83f-4c9e-ab54-2021124f1bbb</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-06-14/baba-is-you/"></link>
- <title>最高のパズルゲーム Baba Is You をやれ</title>
- <summary>Baba Is You という最高のパズルゲームをクリアした。是非プレイしてほしい。</summary>
- <published>2025-06-14T00:00:00+09:00</published>
- <updated>2025-06-15T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:64f5e1a6-2f5c-4d5d-b1c8-8346a66c1d40</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-05-05/make-tiny-self-hosted-c-compiler/"></link>
- <title>セルフホスト可能な C コンパイラを作った</title>
- <summary>ゴールデンウィークを使って、セルフホストできる C コンパイラを開発した</summary>
- <published>2025-05-05T00:00:00+09:00</published>
- <updated>2025-05-05T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:087e98f2-743c-48d8-9f67-e9b57e354845</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-04-24/composer-patches-v2-does-not-require-gnu-patch-even-on-macos/"></link>
- <title>【Composer】 composer-patches v2 では macOS でも GNU patch のインストールが不要になる (予定)</title>
- <summary>composer-patches は BSD patch に対応しておらず、一部のパッチの適用に失敗する。現在ベータ版である v2 では patch コマンドに依存しなくなり、macOS で使うときのストレスが解消される見込み。</summary>
- <published>2025-04-24T00:00:00+09:00</published>
- <updated>2025-04-24T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:039b3dff-3b75-46b7-a731-9a3a0ff8e21f</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/"></link>
- <title>RubyKaigi 2025 の TRICK で入賞した</title>
- <summary>RubyKaigi 2025 で開催された TRICK において、『最もRuby on Ruby賞』として審査員賞をいただいた。</summary>
- <published>2025-04-20T00:00:00+09:00</published>
- <updated>2025-04-20T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:046e4412-bee8-4ffe-9876-6cbeaa0caf6b</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-03-28/http-1-1-send-multiple-same-headers/"></link>
- <title>【HTTP】HTTP/1.1 で同じヘッダを2回送るとどうなるか</title>
- <summary>HTTP/1.1 で同じヘッダを2回送ったときの挙動について仕様を読んでまとめた。</summary>
- <published>2025-03-28T00:00:00+09:00</published>
- <updated>2025-03-28T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:99111377-27e7-427b-9dc5-a23f621fa826</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-03-27/zip-function-like-command-paste-command/"></link>
- <title>zip 関数のようなコマンド paste</title>
- <summary>zip 関数のような動きをする paste コマンドについてのメモ。</summary>
- <published>2025-03-27T00:00:00+09:00</published>
- <updated>2025-03-27T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:13174dc7-c1a3-465f-9ba6-14f0bc6f5961</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-02-24/phpcon-nagoya-2025-report/"></link>
- <title>PHP カンファレンス名古屋 2025 参加レポ</title>
- <summary>2025-02-22 に開催された、PHP カンファレンス名古屋 2025 に参加した。</summary>
- <published>2025-02-24T00:00:00+09:00</published>
- <updated>2025-02-24T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:da2a0cec-74b3-4c5e-b2a2-47fe79ef49f9</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-01-26/yaml-breaking-changes-between-v1-1-and-v1-2/"></link>
- <title>【YAML】YAML 1.1 と YAML 1.2 の主な破壊的変更</title>
- <summary>データ記述言語 YAML におけるバージョン 1.1 と 1.2 の主な破壊的変更をまとめた。</summary>
- <published>2025-01-26T00:00:00+09:00</published>
- <updated>2025-01-26T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:ce8f20e8-c79f-48f8-982d-53edd4d20483</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-01-08/phperkaigi-2023-tokens-q1/"></link>
- <title>PHPerKaigi 2023 トークン問題解説 (1/5)</title>
- <summary>PHPerKaigi 2023 でデジタルサーカス株式会社から出題した問題を解説する。全5問中の第1問。</summary>
- <published>2025-01-08T00:00:00+09:00</published>
- <updated>2025-01-11T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:d7f98354-83fc-4cf1-8769-2784f0ebb6c8</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-12-33/2024-reflections/"></link>
- <title>2024年の振り返り</title>
- <summary>2024年にやったことを振り返る</summary>
- <published>2025-01-02T00:00:00+09:00</published>
- <updated>2025-01-02T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:ea0593d3-691c-4e08-8db4-98b8925717ec</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-12-04/cohackpp-report/"></link>
- <title>紅白ぺぱ合戦に参加&amp;LTしました</title>
- <summary>2024-11-30 に開催された紅白ぺぱ合戦に参加し、ぺ陣営のメンバとして LT しました。</summary>
- <published>2024-12-04T00:00:00+09:00</published>
- <updated>2024-12-05T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:ee7289ee-ff2e-439d-b343-7f87504192fd</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-09-28/mncore-challenge-1/"></link>
- <title>MN-Core Challenge #1 参加レポ</title>
- <summary>2024-08-28 から 2024-09-24 にかけて開催された MN-Core Challenge #1 に参加した。</summary>
- <published>2024-09-28T00:00:00+09:00</published>
- <updated>2024-09-28T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:eed112e4-3227-4b3f-9991-7e11c288ee2b</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-08-19/go-template-access-outer-scope-pipeline-within-with-or-range/"></link>
- <title>【Go】 text/template の with や range の内側から外側の &quot;.&quot; にアクセスする</title>
- <summary>Go言語の text/template における with や range は &quot;.&quot; を上書きする。これらの内側から外側の &quot;.&quot; にアクセスする方法を調べた。</summary>
- <published>2024-08-19T00:00:00+09:00</published>
- <updated>2024-08-19T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:222488dd-cf07-4961-83aa-a014b05369ff</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-07-19/reparojson-fix-only-json-formatter/"></link>
- <title>reparojson: 文法エラーを直すだけの JSON フォーマッタを作った</title>
- <summary>文法エラーだけを直し、空白の削除や挿入といった整形処理を一切おこなわない JSON フォーマッタを作成した。Neovim と連携させる設定例も紹介する。</summary>
- <published>2024-07-19T00:00:00+09:00</published>
- <updated>2024-07-19T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:8d6f3690-3da3-4235-a81b-b9707cee22ad</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-06-19/scalamatsuri-2024-report/"></link>
- <title>ScalaMatsuri 2024 参加レポ</title>
- <summary>2024-06-08 から 2024-06-09 にかけて開催された、ScalaMatsuri 2024 に参加した。</summary>
- <published>2024-06-19T00:00:00+09:00</published>
- <updated>2024-06-19T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:f13aa9d6-4533-4a15-872a-c298ab2090db</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-05-11/phpconkagawa-2024-report/"></link>
- <title>PHP カンファレンス香川 2024 参加レポ</title>
- <summary>2024-05-11 に開催された、PHP カンファレンス香川 2024 に参加した。</summary>
- <published>2024-05-11T00:00:00+09:00</published>
- <updated>2024-05-11T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:9b26c1ed-45c3-4cad-9476-cbf2cf2e4de7</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-04-29/zsh-file-completion-for-composer-custom-commands/"></link>
- <title>【Zsh】 Composer のカスタムコマンドに対する Zsh 補完で引数にファイルを補完させる</title>
- <summary>Zsh の Composer に対する補完はカスタムコマンドやその引数を補完しない。カスタムコマンドの引数としてファイルを補完させる方法を調べた。</summary>
- <published>2024-04-29T00:00:00+09:00</published>
- <updated>2024-04-29T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:a4c326a6-5ffe-450c-abf2-45833c5efb6a</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-04-21/pipefail-option-in-gitlab-ci-cd/"></link>
- <title>【GitLab】 GitLab CI/CD 上での bash/sh は pipefail が有効になっている</title>
- <summary>GitLab CI/CD で bash/sh スクリプトを動かすと、pipefail オプションが有効になった状態で実行される。</summary>
- <published>2024-04-21T00:00:00+09:00</published>
- <updated>2024-04-21T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:be9c896d-7efa-42dd-a50a-dda5fd3a7f5c</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-04-14/phpcon-odawara-2024-report/"></link>
- <title>PHP カンファレンス小田原 2024 参加レポ</title>
- <summary>2024-04-13 に開催された、PHP カンファレンス小田原 2024 に参加した。</summary>
- <published>2024-04-14T00:00:00+09:00</published>
- <updated>2024-06-01T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:6b749793-c760-4597-8a4c-b32d027b7585</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-03-20/my-bucket-list/"></link>
- <title>死ぬまでに作る自作○○一覧あるいは人生の TODO リスト</title>
- <summary>駄文</summary>
- <published>2024-03-20T00:00:00+09:00</published>
- <updated>2024-04-07T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:750be5c8-ca52-4cbd-86fe-5645b06bde95</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-03-17/phperkaigi-2024-report/"></link>
- <title>PHPerKaigi 2024 参加レポ</title>
- <summary>2024-03-07 から 2024-03-09 にかけて開催された、PHPerKaigi 2024 に参加した。</summary>
- <published>2024-03-17T00:00:00+09:00</published>
- <updated>2024-07-07T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:fd8fcb03-8e4d-4ca7-8499-0674accc51a9</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-02-22/phpkansai-2024-report/"></link>
- <title>PHPカンファレンス関西 2024 参加レポ</title>
- <summary>2024-02-11 に開催された、PHPカンファレンス関西 2024 に参加した。</summary>
- <published>2024-02-21T00:00:00+09:00</published>
- <updated>2024-02-21T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:230a0048-93c0-4aac-91ef-bb3108f3e587</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-02-10/yapcjapan-2024-report/"></link>
- <title>YAPC::Hiroshima 2024 参加レポ</title>
- <summary>2024-02-10 に開催された、YAPC::Hiroshima 2024 に参加した。</summary>
- <published>2024-02-10T00:00:00+09:00</published>
- <updated>2024-02-10T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:210673d0-c19e-4195-a280-968a0729dd41</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-02-03/install-wireguard-on-personal-server/"></link>
- <title>【備忘録】 個人用サーバに WireGuard を導入する</title>
- <summary>個人用サービスのセルフホストに使っているサーバに WireGuard を導入する作業をしたメモ</summary>
- <published>2024-02-03T00:00:00+09:00</published>
- <updated>2024-02-17T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:05cb16e1-05bc-4359-bc06-88ac20510740</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-01-10/neovim-insert-namespace-declaration-to-empty-php-file/"></link>
- <title>【Neovim】 空の PHP ファイルに namespace 宣言を挿入する</title>
- <summary>Neovim で空の PHP ファイルを開いたとき、ディレクトリの構造に基づいて自動的に namespace 宣言を挿入するようにする。</summary>
- <published>2024-01-10T00:00:00+09:00</published>
- <updated>2024-01-10T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:bfdeed72-dd32-4d55-887f-ba004701ff4c</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2023-12-31/2023-reflections/"></link>
- <title>2023年の振り返り</title>
- <summary>2023年にやったことを振り返る</summary>
- <published>2023-12-31T00:00:00+09:00</published>
- <updated>2023-12-31T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:d0c404bb-4700-4a6f-9911-621e9872d8c6</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2023-12-03/isucon-13/"></link>
- <title>ISUCON 13 に参加した</title>
- <summary>ISUCON 13 に参加した。チーム名「うつしもゆ」、最終スコア 13,580 点</summary>
- <published>2023-12-03T00:00:00+09:00</published>
- <updated>2023-12-03T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:78419bf2-a1e6-421f-875b-3d93e777b04f</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2023-10-13/i-entered-the-open-university-of-japan/"></link>
- <title>放送大学に入学しました</title>
- <summary>放送大学に入学しました。頑張ります。</summary>
- <published>2023-10-13T00:00:00+09:00</published>
- <updated>2023-10-13T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:0ed1ccc8-d437-481c-8cca-2131ce800cc0</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2023-10-02/compile-php-runtime-to-wasm/"></link>
- <title>PHP の処理系を Emscripten で WebAssembly にコンパイルする</title>
- <summary>PHP の処理系 (php/php-src) を Emscripten で WebAssembly にコンパイルし、任意のコードを隔離された環境で評価できるようにした。</summary>
- <published>2023-10-02T00:00:00+09:00</published>
- <updated>2025-04-23T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:e1568c4c-9bdd-47b9-8b39-939ade4f3ba0</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2023-06-25/phpconfuk-2023-report/"></link>
- <title>PHP カンファレンス福岡 2023 参加レポ</title>
- <summary>2023-06-24 に開催された、PHP カンファレンス福岡に参加した。</summary>
- <published>2023-06-25T00:00:00+09:00</published>
- <updated>2023-06-25T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:21ce39f0-d613-45f2-a760-89c368892d77</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2023-04-04/phperkaigi-2023-report/"></link>
- <title>PHPerKaigi 2023 参加レポ</title>
- <summary>2023-03-23 から 2023-03-25 にかけて開催された、PHPerKaigi 2023 に参加した。</summary>
- <published>2023-04-04T00:00:00+09:00</published>
- <updated>2023-06-28T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:ed36e185-5bfa-42e1-8358-0b1da9b0a063</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2023-04-01/implementation-of-minimal-png-image-encoder/"></link>
- <title>PNG 画像の最小構成エンコーダを実装する</title>
- <summary>PNG 画像として valid な範囲で最大限手抜きしたエンコーダを書く。</summary>
- <published>2023-04-01T00:00:00+09:00</published>
- <updated>2023-04-01T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:12512894-05d8-42c6-950e-8f5d60f984d8</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2023-03-10/rewrite-this-blog-generator/"></link>
- <title>このブログのジェネレータを書き直した</title>
- <summary>このブログのジェネレータを書き直したので、やったことを書き記しておく。</summary>
- <published>2023-03-10T00:00:00+09:00</published>
- <updated>2023-03-10T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:89722cfb-7f4b-4e96-80bc-e0096e5eeef6</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2023-01-10/phperkaigi-2023-unused-token-quiz-3/"></link>
- <title>PHPerKaigi 2023: ボツになったトークン問題 その 3</title>
- <summary>来年の PHPerKaigi 2023 でデジタルサーカス株式会社から出題予定のトークン問題のうち、ボツになった問題を公開する (その 3)。</summary>
- <published>2023-01-10T00:00:00+09:00</published>
- <updated>2023-01-10T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:10fe9c47-7029-4874-82bd-b4dc50e07809</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-11-19/phperkaigi-2023-unused-token-quiz-2/"></link>
- <title>PHPerKaigi 2023: ボツになったトークン問題 その 2</title>
- <summary>来年の PHPerKaigi 2023 でデジタルサーカス株式会社から出題予定のトークン問題のうち、ボツになった問題を公開する (その 2)。</summary>
- <published>2022-11-19T00:00:00+09:00</published>
- <updated>2022-11-19T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:673cb872-af2d-41a3-9fb0-60f1afcedb0d</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-10-28/setup-server-for-this-site/"></link>
- <title>【備忘録】 このサイト用の VPS をセットアップしたときのメモ</title>
- <summary>GitHub Pages でホストしていたこのサイトを VPS へ移行したので、そのときにやったことのメモ。99 % 自分用。</summary>
- <published>2022-10-28T00:00:00+09:00</published>
- <updated>2023-08-30T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:46e0d5db-b17e-464c-a723-8c3e01af7d1d</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-10-23/phperkaigi-2023-unused-token-quiz-1/"></link>
- <title>PHPerKaigi 2023: ボツになったトークン問題 その 1</title>
- <summary>来年の PHPerKaigi 2023 でデジタルサーカス株式会社から出題予定のトークン問題のうち、ボツになった問題を公開する (その 1)。</summary>
- <published>2022-10-23T00:00:00+09:00</published>
- <updated>2022-10-23T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:42f0b29b-1e44-4dbe-9864-69abe3bb1e6e</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-09-29/write-fizzbuzz-in-php-2-letters-per-line/"></link>
- <title>【PHP】 fizzbuzz を書く。1行あたり2文字で。</title>
- <summary>PHP で fizzbuzz を書いた。ただし、1行あたりに使える文字数は2文字まで。</summary>
- <published>2022-09-28T00:00:00+09:00</published>
- <updated>2022-09-29T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:cd16debe-8077-4edf-aec0-b1d45955a0e2</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-08-31/support-for-communty-is-employee-benefits/"></link>
- <title>弊社の PHP Foundation への寄付に寄せて</title>
- <summary>先日、私の勤めるデジタルサーカス株式会社が、PHP Foundation へ寄付をおこないました。本件を社内でしつこく推進した1人として、推進の理由等を書き残しておきます。</summary>
- <published>2022-08-31T00:00:00+09:00</published>
- <updated>2022-08-31T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:bb71bb5d-361b-44cb-9753-81d14583d860</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-08-27/php-conference-okinawa-code-golf/"></link>
- <title>PHP カンファレンス沖縄で出題されたコードゴルフの問題を解いてみた</title>
- <summary>PHP カンファレンス沖縄の懇親会 LT で出題されたコードゴルフの問題を解いてみた。</summary>
- <published>2022-08-27T00:00:00+09:00</published>
- <updated>2022-08-27T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:9211e1fe-bca3-43c4-ba4e-c67d62f3fed0</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-05-01/phperkaigi-2022/"></link>
- <title>PHPerKaigi 2022</title>
- <summary>2022-04-09 から 2022-04-11 にかけて開催された、PHPerKaigi 2022 に参加した。</summary>
- <published>2022-05-01T00:00:00+09:00</published>
- <updated>2022-05-01T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:42cf2829-b897-4748-bc22-80dd734a3c09</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-04-24/term-banner-write-tool-showing-banner-in-terminal/"></link>
- <title>term-banner: ターミナルにバナーを表示するツールを書いた</title>
- <summary>ターミナルに任意の文字のバナーを表示するためのツールを Go で書いた。</summary>
- <published>2022-04-24T00:00:00+09:00</published>
- <updated>2022-04-27T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:f4985d54-0907-4449-8101-0fcd382f9e02</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-04-09/phperkaigi-2022-tokens/"></link>
- <title>PHPerKaigi 2022 トークン問題の解説</title>
- <summary>PHPerKaigi 2022 で私が作成した PHPer チャレンジ問題を解説する。</summary>
- <published>2022-04-09T00:00:00+09:00</published>
- <updated>2022-04-16T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:69863d75-ef21-42db-b743-5958f7c86827</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2021-10-02/cpp-you-can-use-keywords-in-attributes/"></link>
- <title>【C++】 属性構文の属性名にはキーワードが使える</title>
- <summary>C++ の属性構文の属性名には、キーワードが使える。ネタ記事。</summary>
- <published>2021-10-02T00:00:00+09:00</published>
- <updated>2021-10-02T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:e1aff84c-d6d4-4dea-bc45-9c41e6445006</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2021-10-02/python-unbound-local-error/"></link>
- <title>【Python】 クロージャとUnboundLocalError: local variable &apos;x&apos; referenced before assignment</title>
- <summary>Python における UnboundLocalError の理由と対処法。</summary>
- <published>2021-10-02T00:00:00+09:00</published>
- <updated>2021-10-02T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:e1456a50-4fc6-42ef-89f3-8be78e01da13</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2021-10-02/ruby-detect-running-implementation/"></link>
- <title>【Ruby】 自身を実行している処理系の種類を判定する</title>
- <summary>Ruby には複数の実装があるが、自身を実行している処理系の種類をスクリプト上からどのように判定すればよいだろうか。</summary>
- <published>2021-10-02T00:00:00+09:00</published>
- <updated>2021-10-02T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:87455008-fe5b-49bf-af5a-b875264f8326</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2021-10-02/ruby-then-keyword-and-case-in/"></link>
- <title>【Ruby】 then キーワードと case in</title>
- <summary>Ruby 3.0 で追加される case in 構文と、then キーワードについて。</summary>
- <published>2021-10-02T00:00:00+09:00</published>
- <updated>2021-10-02T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:91c61980-c262-4e8d-89b0-4304e7f6d644</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2021-10-02/rust-where-are-primitive-types-from/"></link>
- <title>Rust のプリミティブ型はどこからやって来るか</title>
- <summary>Rust のプリミティブ型は予約語ではなく普通の識別子である。どのようにこれが名前解決されるのかを調べた。</summary>
- <published>2021-10-02T00:00:00+09:00</published>
- <updated>2021-10-02T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:44171f75-c312-4c92-9927-3d260e162175</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2021-10-02/vim-difference-between-autocmd-bufwrite-and-bufwritepre/"></link>
- <title>【Vim】 autocmd events の BufWrite/BufWritePre の違い</title>
- <summary>Vim の autocmd events における BufWrite/BufWritePre がどう違うのかを調べた結果、違いはないことがわかった。</summary>
- <published>2021-10-02T00:00:00+09:00</published>
- <updated>2021-10-02T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:665de47e-0ed6-405e-ad30-81c3c4592d45</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2021-10-02/vim-swap-order-of-selected-lines/"></link>
- <title>Vimで選択した行の順番を入れ替える</title>
- <summary>Vim で選択した行の順番を入れ替える方法。</summary>
- <published>2021-10-02T00:00:00+09:00</published>
- <updated>2021-10-02T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:3fbe0b8c-216e-48f6-b905-c0d361b94542</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2021-03-30/phperkaigi-2021/"></link>
- <title>PHPerKaigi 2021</title>
- <summary>2021-03-26 から 2021-03-28 にかけて開催された、PHPerKaigi 2021 に参加した。</summary>
- <published>2021-03-30T00:00:00+09:00</published>
- <updated>2025-04-09T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:6e9c71fd-bc8d-43ce-99c5-13d9f5b87ed2</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2021-03-05/my-first-post/"></link>
- <title>My First Post</title>
- <summary>これはテスト投稿です。これはテスト投稿です。これはテスト投稿です。</summary>
- <published>2021-03-05T00:00:00+09:00</published>
- <updated>2025-05-12T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/posts/index.html b/vhosts/blog/public/posts/index.html
deleted file mode 100644
index 7b6ff6c7..00000000
--- a/vhosts/blog/public/posts/index.html
+++ /dev/null
@@ -1,220 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2021 nsfisis">
- <meta name="description" content="投稿した記事の一覧 (1ページ目)">
- <meta property="og:type" content="article">
- <meta property="og:title" content="投稿一覧 (1ページ目)|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="投稿した記事の一覧 (1ページ目)">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/posts/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>投稿一覧 (1ページ目)|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>投稿一覧 (1ページ目)</h1>
- </header>
- <nav class="pagination">
- <div class="pagination-prev">
- </div>
- <div class="pagination-info">
- 1 / 6
- </div>
- <div class="pagination-next">
- <a href="/posts/2/">次のページ</a>
- </div>
- </nav>
- <article class="post-entry">
- <a href="/posts/2025-06-14/baba-is-you/">
- <header class="entry-header">
- <h2>最高のパズルゲーム Baba Is You をやれ</h2>
- </header>
- <section class="entry-content">
- <p>
- Baba Is You という最高のパズルゲームをクリアした。是非プレイしてほしい。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-06-14">2025-06-14</time> 投稿、<time datetime="2025-06-15">2025-06-15</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2025-05-05/make-tiny-self-hosted-c-compiler/">
- <header class="entry-header">
- <h2>セルフホスト可能な C コンパイラを作った</h2>
- </header>
- <section class="entry-content">
- <p>
- ゴールデンウィークを使って、セルフホストできる C コンパイラを開発した
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-05-05">2025-05-05</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2025-04-24/composer-patches-v2-does-not-require-gnu-patch-even-on-macos/">
- <header class="entry-header">
- <h2>【Composer】 composer-patches v2 では macOS でも GNU patch のインストールが不要になる (予定)</h2>
- </header>
- <section class="entry-content">
- <p>
- composer-patches は BSD patch に対応しておらず、一部のパッチの適用に失敗する。現在ベータ版である v2 では patch コマンドに依存しなくなり、macOS で使うときのストレスが解消される見込み。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-04-24">2025-04-24</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/">
- <header class="entry-header">
- <h2>RubyKaigi 2025 の TRICK で入賞した</h2>
- </header>
- <section class="entry-content">
- <p>
- RubyKaigi 2025 で開催された TRICK において、『最もRuby on Ruby賞』として審査員賞をいただいた。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-04-20">2025-04-20</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2025-03-28/http-1-1-send-multiple-same-headers/">
- <header class="entry-header">
- <h2>【HTTP】HTTP/1.1 で同じヘッダを2回送るとどうなるか</h2>
- </header>
- <section class="entry-content">
- <p>
- HTTP/1.1 で同じヘッダを2回送ったときの挙動について仕様を読んでまとめた。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-03-28">2025-03-28</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2025-03-27/zip-function-like-command-paste-command/">
- <header class="entry-header">
- <h2>zip 関数のようなコマンド paste</h2>
- </header>
- <section class="entry-content">
- <p>
- zip 関数のような動きをする paste コマンドについてのメモ。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-03-27">2025-03-27</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2025-02-24/phpcon-nagoya-2025-report/">
- <header class="entry-header">
- <h2>PHP カンファレンス名古屋 2025 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2025-02-22 に開催された、PHP カンファレンス名古屋 2025 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-02-24">2025-02-24</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2025-01-26/yaml-breaking-changes-between-v1-1-and-v1-2/">
- <header class="entry-header">
- <h2>【YAML】YAML 1.1 と YAML 1.2 の主な破壊的変更</h2>
- </header>
- <section class="entry-content">
- <p>
- データ記述言語 YAML におけるバージョン 1.1 と 1.2 の主な破壊的変更をまとめた。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-01-26">2025-01-26</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2025-01-08/phperkaigi-2023-tokens-q1/">
- <header class="entry-header">
- <h2>PHPerKaigi 2023 トークン問題解説 (1/5)</h2>
- </header>
- <section class="entry-content">
- <p>
- PHPerKaigi 2023 でデジタルサーカス株式会社から出題した問題を解説する。全5問中の第1問。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-01-08">2025-01-08</time> 投稿、<time datetime="2025-01-11">2025-01-11</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2024-12-33/2024-reflections/">
- <header class="entry-header">
- <h2>2024年の振り返り</h2>
- </header>
- <section class="entry-content">
- <p>
- 2024年にやったことを振り返る
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-01-02">2025-01-02</time> 投稿
- </footer>
- </a>
- </article>
- <nav class="pagination">
- <div class="pagination-prev">
- </div>
- <div class="pagination-info">
- 1 / 6
- </div>
- <div class="pagination-next">
- <a href="/posts/2/">次のページ</a>
- </div>
- </nav>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/slide.js b/vhosts/blog/public/slide.js
deleted file mode 100644
index 4c7a0de8..00000000
--- a/vhosts/blog/public/slide.js
+++ /dev/null
@@ -1,60 +0,0 @@
-import { GlobalWorkerOptions, getDocument } from "/pdf.min.mjs";
-
-document.addEventListener("DOMContentLoaded", async () => {
- GlobalWorkerOptions.workerSrc = "/pdf.worker.min.mjs";
-
- const canvas = document.getElementById("slide");
- const ctx = canvas.getContext("2d");
- const url = canvas.dataset.slideLink;
-
- let pageNum = 1;
- let pageNumPending = null;
- let pageRendering = false;
- let doc = null;
-
- const renderPage = async (num) => {
- pageRendering = true;
- const page = await doc.getPage(num);
-
- const viewport = page.getViewport({ scale: 1.0 });
- canvas.height = viewport.height;
- canvas.width = viewport.width;
-
- // TODO: error handling
- await page.render({
- canvasContext: ctx,
- viewport: viewport,
- });
-
- pageRendering = false;
- if (pageNumPending !== null) {
- renderPage(pageNumPending);
- pageNumPending = null;
- }
- };
-
- const queueRenderPage = (num) => {
- if (pageRendering) {
- pageNumPending = num;
- } else {
- renderPage(num);
- }
- };
-
- const prev = document.getElementById("prev");
- prev.addEventListener("click", () => {
- if (pageNum <= 1) return;
- pageNum--;
- queueRenderPage(pageNum);
- });
- const next = document.getElementById("next");
- next.addEventListener("click", () => {
- if (pageNum >= doc.numPages) return;
- pageNum++;
- queueRenderPage(pageNum);
- });
-
- // TODO: error handling
- doc = await getDocument(url).promise;
- queueRenderPage(pageNum);
-});
diff --git a/vhosts/blog/public/slides/2023-01-18/phpstudy-tokyo-148/index.html b/vhosts/blog/public/slides/2023-01-18/phpstudy-tokyo-148/index.html
deleted file mode 100644
index f78eb216..00000000
--- a/vhosts/blog/public/slides/2023-01-18/phpstudy-tokyo-148/index.html
+++ /dev/null
@@ -1,82 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2023 nsfisis">
- <meta name="description" content="明日のあなたの役に立たない PHP コーディング技法~polyglot~">
- <meta name="keywords" content="PHP,PHP 勉強会@東京">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHP 勉強会@東京 第148 回 (LT)|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="明日のあなたの役に立たない PHP コーディング技法~polyglot~">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHP 勉強会@東京 第148 回 (LT)|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">明日のあなたの役に立たない PHP コーディング技法~polyglot~</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phpstudy-tokyo/">PHP 勉強会@東京</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2023-01-18">2023-01-18</time>: 登壇
- </li>
- </ol>
- </section>
- <canvas data-slide-link="/slides/2023-01-18/phpstudy-tokyo-148/slide.pdf" id="slide">
- </canvas>
- <div>
- <button id="prev" type="button">
- Prev
- </button>
- <button id="next" type="button">
- Next
- </button>
- </div>
- <script src="/slide.js?h=9e13ae7b86004d858e6bc1f38129cc88" type="module">
- </script>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/slides/2023-01-18/phpstudy-tokyo-148/slide.pdf b/vhosts/blog/public/slides/2023-01-18/phpstudy-tokyo-148/slide.pdf
deleted file mode 100644
index e50d08ef..00000000
--- a/vhosts/blog/public/slides/2023-01-18/phpstudy-tokyo-148/slide.pdf
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/slides/2023-02-15/phpstudy-tokyo-149/index.html b/vhosts/blog/public/slides/2023-02-15/phpstudy-tokyo-149/index.html
deleted file mode 100644
index 8c4d3c70..00000000
--- a/vhosts/blog/public/slides/2023-02-15/phpstudy-tokyo-149/index.html
+++ /dev/null
@@ -1,82 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2023 nsfisis">
- <meta name="description" content="PHPerKaigi 2023 のトークン問題でボツにした問題を供養する">
- <meta name="keywords" content="PHP,PHP 勉強会@東京">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHP 勉強会@東京 第149 回 (LT)|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="PHPerKaigi 2023 のトークン問題でボツにした問題を供養する">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHP 勉強会@東京 第149 回 (LT)|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">PHPerKaigi 2023 のトークン問題でボツにした問題を供養する</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phpstudy-tokyo/">PHP 勉強会@東京</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2023-02-15">2023-02-15</time>: 登壇
- </li>
- </ol>
- </section>
- <canvas data-slide-link="/slides/2023-02-15/phpstudy-tokyo-149/slide.pdf" id="slide">
- </canvas>
- <div>
- <button id="prev" type="button">
- Prev
- </button>
- <button id="next" type="button">
- Next
- </button>
- </div>
- <script src="/slide.js?h=9e13ae7b86004d858e6bc1f38129cc88" type="module">
- </script>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/slides/2023-02-15/phpstudy-tokyo-149/slide.pdf b/vhosts/blog/public/slides/2023-02-15/phpstudy-tokyo-149/slide.pdf
deleted file mode 100644
index f51f6f81..00000000
--- a/vhosts/blog/public/slides/2023-02-15/phpstudy-tokyo-149/slide.pdf
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/slides/2023-03-15/phpstudy-tokyo-150/index.html b/vhosts/blog/public/slides/2023-03-15/phpstudy-tokyo-150/index.html
deleted file mode 100644
index 827677f6..00000000
--- a/vhosts/blog/public/slides/2023-03-15/phpstudy-tokyo-150/index.html
+++ /dev/null
@@ -1,85 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2023 nsfisis">
- <meta name="description" content="明日のあなたの役に立たない PHP コーディング技法~細長い FizzBuzz を書く~">
- <meta name="keywords" content="PHP,PHP 勉強会@東京">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHP 勉強会@東京 第150 回 (LT)|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="明日のあなたの役に立たない PHP コーディング技法~細長い FizzBuzz を書く~">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHP 勉強会@東京 第150 回 (LT)|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">明日のあなたの役に立たない PHP コーディング技法~細長い FizzBuzz を書く~</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phpstudy-tokyo/">PHP 勉強会@東京</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2023-03-15">2023-03-15</time>: 登壇
- </li>
- <li class="revision">
- <time datetime="2023-03-18">2023-03-18</time>: 2文字以下の関数が他にもあったので修正
- </li>
- </ol>
- </section>
- <canvas data-slide-link="/slides/2023-03-15/phpstudy-tokyo-150/slide.pdf" id="slide">
- </canvas>
- <div>
- <button id="prev" type="button">
- Prev
- </button>
- <button id="next" type="button">
- Next
- </button>
- </div>
- <script src="/slide.js?h=9e13ae7b86004d858e6bc1f38129cc88" type="module">
- </script>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/slides/2023-03-15/phpstudy-tokyo-150/slide.pdf b/vhosts/blog/public/slides/2023-03-15/phpstudy-tokyo-150/slide.pdf
deleted file mode 100644
index fdc070c3..00000000
--- a/vhosts/blog/public/slides/2023-03-15/phpstudy-tokyo-150/slide.pdf
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/slides/2023-03-24/phperkaigi-2023/index.html b/vhosts/blog/public/slides/2023-03-24/phperkaigi-2023/index.html
deleted file mode 100644
index 1959fd38..00000000
--- a/vhosts/blog/public/slides/2023-03-24/phperkaigi-2023/index.html
+++ /dev/null
@@ -1,85 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2023 nsfisis">
- <meta name="description" content="詳説「参照」PHP の参照を完全に理解する">
- <meta name="keywords" content="カンファレンス,PHP,PHPerKaigi">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHPerKaigi 2023 (レギュラートーク)|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="詳説「参照」PHP の参照を完全に理解する">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHPerKaigi 2023 (レギュラートーク)|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">詳説「参照」PHP の参照を完全に理解する</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/conference/">カンファレンス</a>
- </li>
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phperkaigi/">PHPerKaigi</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2023-03-24">2023-03-24</time>: 登壇
- </li>
- </ol>
- </section>
- <canvas data-slide-link="/slides/2023-03-24/phperkaigi-2023/slide.pdf" id="slide">
- </canvas>
- <div>
- <button id="prev" type="button">
- Prev
- </button>
- <button id="next" type="button">
- Next
- </button>
- </div>
- <script src="/slide.js?h=9e13ae7b86004d858e6bc1f38129cc88" type="module">
- </script>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/slides/2023-03-24/phperkaigi-2023/slide.pdf b/vhosts/blog/public/slides/2023-03-24/phperkaigi-2023/slide.pdf
deleted file mode 100644
index 6d3d9c39..00000000
--- a/vhosts/blog/public/slides/2023-03-24/phperkaigi-2023/slide.pdf
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/slides/2023-03-25/phperkaigi-2023-tokens/index.html b/vhosts/blog/public/slides/2023-03-25/phperkaigi-2023-tokens/index.html
deleted file mode 100644
index cfa7890f..00000000
--- a/vhosts/blog/public/slides/2023-03-25/phperkaigi-2023-tokens/index.html
+++ /dev/null
@@ -1,85 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2023 nsfisis">
- <meta name="description" content="PHPer チャレンジ解説 (デジタルサーカス株式会社)">
- <meta name="keywords" content="カンファレンス,PHP,PHPerKaigi">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHPerKaigi 2023 (トークン解説セッション)|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="PHPer チャレンジ解説 (デジタルサーカス株式会社)">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHPerKaigi 2023 (トークン解説セッション)|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">PHPer チャレンジ解説 (デジタルサーカス株式会社)</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/conference/">カンファレンス</a>
- </li>
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phperkaigi/">PHPerKaigi</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2023-03-25">2023-03-25</time>: 登壇
- </li>
- </ol>
- </section>
- <canvas data-slide-link="/slides/2023-03-25/phperkaigi-2023-tokens/slide.pdf" id="slide">
- </canvas>
- <div>
- <button id="prev" type="button">
- Prev
- </button>
- <button id="next" type="button">
- Next
- </button>
- </div>
- <script src="/slide.js?h=9e13ae7b86004d858e6bc1f38129cc88" type="module">
- </script>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/slides/2023-03-25/phperkaigi-2023-tokens/slide.pdf b/vhosts/blog/public/slides/2023-03-25/phperkaigi-2023-tokens/slide.pdf
deleted file mode 100644
index 1104b62b..00000000
--- a/vhosts/blog/public/slides/2023-03-25/phperkaigi-2023-tokens/slide.pdf
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/slides/2023-04-12/phpstudy-tokyo-151/index.html b/vhosts/blog/public/slides/2023-04-12/phpstudy-tokyo-151/index.html
deleted file mode 100644
index 38641d42..00000000
--- a/vhosts/blog/public/slides/2023-04-12/phpstudy-tokyo-151/index.html
+++ /dev/null
@@ -1,82 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2023 nsfisis">
- <meta name="description" content="list でない array の末尾を探す">
- <meta name="keywords" content="PHP,PHP 勉強会@東京">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHP 勉強会@東京 第151 回 (LT)|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="list でない array の末尾を探す">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHP 勉強会@東京 第151 回 (LT)|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">list でない array の末尾を探す</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phpstudy-tokyo/">PHP 勉強会@東京</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2023-04-12">2023-04-12</time>: 登壇
- </li>
- </ol>
- </section>
- <canvas data-slide-link="/slides/2023-04-12/phpstudy-tokyo-151/slide.pdf" id="slide">
- </canvas>
- <div>
- <button id="prev" type="button">
- Prev
- </button>
- <button id="next" type="button">
- Next
- </button>
- </div>
- <script src="/slide.js?h=9e13ae7b86004d858e6bc1f38129cc88" type="module">
- </script>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/slides/2023-04-12/phpstudy-tokyo-151/slide.pdf b/vhosts/blog/public/slides/2023-04-12/phpstudy-tokyo-151/slide.pdf
deleted file mode 100644
index 422d9b8f..00000000
--- a/vhosts/blog/public/slides/2023-04-12/phpstudy-tokyo-151/slide.pdf
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/slides/2023-06-21/phpstudy-tokyo-153/index.html b/vhosts/blog/public/slides/2023-06-21/phpstudy-tokyo-153/index.html
deleted file mode 100644
index ee24c8df..00000000
--- a/vhosts/blog/public/slides/2023-06-21/phpstudy-tokyo-153/index.html
+++ /dev/null
@@ -1,82 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2023 nsfisis">
- <meta name="description" content="テキストファイルの末尾には改行コードを入れよう">
- <meta name="keywords" content="PHP,PHP 勉強会@東京">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHP 勉強会@東京 第153 回 (LT)|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="テキストファイルの末尾には改行コードを入れよう">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHP 勉強会@東京 第153 回 (LT)|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">テキストファイルの末尾には改行コードを入れよう</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phpstudy-tokyo/">PHP 勉強会@東京</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2023-06-21">2023-06-21</time>: 登壇
- </li>
- </ol>
- </section>
- <canvas data-slide-link="/slides/2023-06-21/phpstudy-tokyo-153/slide.pdf" id="slide">
- </canvas>
- <div>
- <button id="prev" type="button">
- Prev
- </button>
- <button id="next" type="button">
- Next
- </button>
- </div>
- <script src="/slide.js?h=9e13ae7b86004d858e6bc1f38129cc88" type="module">
- </script>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/slides/2023-06-21/phpstudy-tokyo-153/slide.pdf b/vhosts/blog/public/slides/2023-06-21/phpstudy-tokyo-153/slide.pdf
deleted file mode 100644
index 53d14bac..00000000
--- a/vhosts/blog/public/slides/2023-06-21/phpstudy-tokyo-153/slide.pdf
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/slides/2023-06-23/phpconfuk-2023-eve/index.html b/vhosts/blog/public/slides/2023-06-23/phpconfuk-2023-eve/index.html
deleted file mode 100644
index 1545b4c1..00000000
--- a/vhosts/blog/public/slides/2023-06-23/phpconfuk-2023-eve/index.html
+++ /dev/null
@@ -1,82 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2023 nsfisis">
- <meta name="description" content="巨大なコードベースへ突撃するために">
- <meta name="keywords" content="PHP,PHP カンファレンス福岡">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHP カンファレンス福岡 2023 前夜祭 (非公式) (レギュラートーク)|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="巨大なコードベースへ突撃するために">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHP カンファレンス福岡 2023 前夜祭 (非公式) (レギュラートーク)|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">巨大なコードベースへ突撃するために</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phpconfuk/">PHP カンファレンス福岡</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2023-06-23">2023-06-23</time>: 登壇
- </li>
- </ol>
- </section>
- <canvas data-slide-link="/slides/2023-06-23/phpconfuk-2023-eve/slide.pdf" id="slide">
- </canvas>
- <div>
- <button id="prev" type="button">
- Prev
- </button>
- <button id="next" type="button">
- Next
- </button>
- </div>
- <script src="/slide.js?h=9e13ae7b86004d858e6bc1f38129cc88" type="module">
- </script>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/slides/2023-06-23/phpconfuk-2023-eve/slide.pdf b/vhosts/blog/public/slides/2023-06-23/phpconfuk-2023-eve/slide.pdf
deleted file mode 100644
index 648680e9..00000000
--- a/vhosts/blog/public/slides/2023-06-23/phpconfuk-2023-eve/slide.pdf
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/slides/2023-07-26/phpstudy-tokyo-154/index.html b/vhosts/blog/public/slides/2023-07-26/phpstudy-tokyo-154/index.html
deleted file mode 100644
index 39ef69a0..00000000
--- a/vhosts/blog/public/slides/2023-07-26/phpstudy-tokyo-154/index.html
+++ /dev/null
@@ -1,82 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2023 nsfisis">
- <meta name="description" content="言語間で比較するエラーの通知と処理">
- <meta name="keywords" content="PHP,PHP 勉強会@東京">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHP 勉強会@東京 第154 回 (レギュラートーク)|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="言語間で比較するエラーの通知と処理">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHP 勉強会@東京 第154 回 (レギュラートーク)|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">言語間で比較するエラーの通知と処理</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phpstudy-tokyo/">PHP 勉強会@東京</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2023-07-26">2023-07-26</time>: 登壇
- </li>
- </ol>
- </section>
- <canvas data-slide-link="/slides/2023-07-26/phpstudy-tokyo-154/slide.pdf" id="slide">
- </canvas>
- <div>
- <button id="prev" type="button">
- Prev
- </button>
- <button id="next" type="button">
- Next
- </button>
- </div>
- <script src="/slide.js?h=9e13ae7b86004d858e6bc1f38129cc88" type="module">
- </script>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/slides/2023-07-26/phpstudy-tokyo-154/slide.pdf b/vhosts/blog/public/slides/2023-07-26/phpstudy-tokyo-154/slide.pdf
deleted file mode 100644
index e26c8d10..00000000
--- a/vhosts/blog/public/slides/2023-07-26/phpstudy-tokyo-154/slide.pdf
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/slides/2023-08-24/phpstudy-tokyo-155/index.html b/vhosts/blog/public/slides/2023-08-24/phpstudy-tokyo-155/index.html
deleted file mode 100644
index 913438aa..00000000
--- a/vhosts/blog/public/slides/2023-08-24/phpstudy-tokyo-155/index.html
+++ /dev/null
@@ -1,82 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2023 nsfisis">
- <meta name="description" content="PHP 3.0 の処理系のソースを読んでみる">
- <meta name="keywords" content="PHP,PHP 勉強会@東京">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHP 勉強会@東京 第155 回 (LT)|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="PHP 3.0 の処理系のソースを読んでみる">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHP 勉強会@東京 第155 回 (LT)|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">PHP 3.0 の処理系のソースを読んでみる</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phpstudy-tokyo/">PHP 勉強会@東京</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2023-08-24">2023-08-24</time>: 登壇
- </li>
- </ol>
- </section>
- <canvas data-slide-link="/slides/2023-08-24/phpstudy-tokyo-155/slide.pdf" id="slide">
- </canvas>
- <div>
- <button id="prev" type="button">
- Prev
- </button>
- <button id="next" type="button">
- Next
- </button>
- </div>
- <script src="/slide.js?h=9e13ae7b86004d858e6bc1f38129cc88" type="module">
- </script>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/slides/2023-08-24/phpstudy-tokyo-155/slide.pdf b/vhosts/blog/public/slides/2023-08-24/phpstudy-tokyo-155/slide.pdf
deleted file mode 100644
index ead5c00d..00000000
--- a/vhosts/blog/public/slides/2023-08-24/phpstudy-tokyo-155/slide.pdf
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/slides/2023-10-25/phpstudy-tokyo-157/index.html b/vhosts/blog/public/slides/2023-10-25/phpstudy-tokyo-157/index.html
deleted file mode 100644
index f8bec343..00000000
--- a/vhosts/blog/public/slides/2023-10-25/phpstudy-tokyo-157/index.html
+++ /dev/null
@@ -1,82 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2023 nsfisis">
- <meta name="description" content="PHP コードを隔離された環境で安全に動かす (on WebAssembly)">
- <meta name="keywords" content="PHP,PHP 勉強会@東京">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHP 勉強会@東京 第157 回 (LT)|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="PHP コードを隔離された環境で安全に動かす (on WebAssembly)">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHP 勉強会@東京 第157 回 (LT)|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">PHP コードを隔離された環境で安全に動かす (on WebAssembly)</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phpstudy-tokyo/">PHP 勉強会@東京</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2023-10-25">2023-10-25</time>: 登壇
- </li>
- </ol>
- </section>
- <canvas data-slide-link="/slides/2023-10-25/phpstudy-tokyo-157/slide.pdf" id="slide">
- </canvas>
- <div>
- <button id="prev" type="button">
- Prev
- </button>
- <button id="next" type="button">
- Next
- </button>
- </div>
- <script src="/slide.js?h=9e13ae7b86004d858e6bc1f38129cc88" type="module">
- </script>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/slides/2023-10-25/phpstudy-tokyo-157/slide.pdf b/vhosts/blog/public/slides/2023-10-25/phpstudy-tokyo-157/slide.pdf
deleted file mode 100644
index dde12ea6..00000000
--- a/vhosts/blog/public/slides/2023-10-25/phpstudy-tokyo-157/slide.pdf
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/slides/2024-01-24/phpstudy-tokyo-160/index.html b/vhosts/blog/public/slides/2024-01-24/phpstudy-tokyo-160/index.html
deleted file mode 100644
index 71abc6b0..00000000
--- a/vhosts/blog/public/slides/2024-01-24/phpstudy-tokyo-160/index.html
+++ /dev/null
@@ -1,82 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="PHPStan の力で Algebraic Data Types を実現する">
- <meta name="keywords" content="PHP,PHP 勉強会@東京">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHP 勉強会@東京 第160 回 (レギュラートーク)|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="PHPStan の力で Algebraic Data Types を実現する">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHP 勉強会@東京 第160 回 (レギュラートーク)|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">PHPStan の力で Algebraic Data Types を実現する</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phpstudy-tokyo/">PHP 勉強会@東京</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2024-01-24">2024-01-24</time>: 登壇
- </li>
- </ol>
- </section>
- <canvas data-slide-link="/slides/2024-01-24/phpstudy-tokyo-160/slide.pdf" id="slide">
- </canvas>
- <div>
- <button id="prev" type="button">
- Prev
- </button>
- <button id="next" type="button">
- Next
- </button>
- </div>
- <script src="/slide.js?h=9e13ae7b86004d858e6bc1f38129cc88" type="module">
- </script>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/slides/2024-01-24/phpstudy-tokyo-160/slide.pdf b/vhosts/blog/public/slides/2024-01-24/phpstudy-tokyo-160/slide.pdf
deleted file mode 100644
index 172dd1a7..00000000
--- a/vhosts/blog/public/slides/2024-01-24/phpstudy-tokyo-160/slide.pdf
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/slides/2024-03-08/phperkaigi-2024/index.html b/vhosts/blog/public/slides/2024-03-08/phperkaigi-2024/index.html
deleted file mode 100644
index 2e1b436d..00000000
--- a/vhosts/blog/public/slides/2024-03-08/phperkaigi-2024/index.html
+++ /dev/null
@@ -1,88 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="WebAssembly を理解する 〜VM の作成を通して〜">
- <meta name="keywords" content="カンファレンス,PHP,PHPerKaigi,WebAssembly">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHPerKaigi 2024 (レギュラートーク (40分))|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="WebAssembly を理解する 〜VM の作成を通して〜">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHPerKaigi 2024 (レギュラートーク (40分))|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">WebAssembly を理解する 〜VM の作成を通して〜</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/conference/">カンファレンス</a>
- </li>
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phperkaigi/">PHPerKaigi</a>
- </li>
- <li class="tag">
- <a href="/tags/wasm/">WebAssembly</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2024-03-08">2024-03-08</time>: 登壇
- </li>
- </ol>
- </section>
- <canvas data-slide-link="/slides/2024-03-08/phperkaigi-2024/slide.pdf" id="slide">
- </canvas>
- <div>
- <button id="prev" type="button">
- Prev
- </button>
- <button id="next" type="button">
- Next
- </button>
- </div>
- <script src="/slide.js?h=9e13ae7b86004d858e6bc1f38129cc88" type="module">
- </script>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/slides/2024-03-08/phperkaigi-2024/slide.pdf b/vhosts/blog/public/slides/2024-03-08/phperkaigi-2024/slide.pdf
deleted file mode 100644
index f9677ede..00000000
--- a/vhosts/blog/public/slides/2024-03-08/phperkaigi-2024/slide.pdf
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/slides/2024-03-15/ya8-2024/index.html b/vhosts/blog/public/slides/2024-03-15/ya8-2024/index.html
deleted file mode 100644
index 51b003f0..00000000
--- a/vhosts/blog/public/slides/2024-03-15/ya8-2024/index.html
+++ /dev/null
@@ -1,85 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="CLI の PHP プログラムを限界まで高速化してみる">
- <meta name="keywords" content="カンファレンス,WebAssembly,Ya8">
- <meta property="og:type" content="article">
- <meta property="og:title" content="Ya8 2024 (レギュラートーク (60分))|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="CLI の PHP プログラムを限界まで高速化してみる">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>Ya8 2024 (レギュラートーク (60分))|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">CLI の PHP プログラムを限界まで高速化してみる</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/conference/">カンファレンス</a>
- </li>
- <li class="tag">
- <a href="/tags/wasm/">WebAssembly</a>
- </li>
- <li class="tag">
- <a href="/tags/ya8/">Ya8</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2024-03-15">2024-03-15</time>: 登壇
- </li>
- </ol>
- </section>
- <canvas data-slide-link="/slides/2024-03-15/ya8-2024/slide.pdf" id="slide">
- </canvas>
- <div>
- <button id="prev" type="button">
- Prev
- </button>
- <button id="next" type="button">
- Next
- </button>
- </div>
- <script src="/slide.js?h=9e13ae7b86004d858e6bc1f38129cc88" type="module">
- </script>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/slides/2024-03-15/ya8-2024/slide.pdf b/vhosts/blog/public/slides/2024-03-15/ya8-2024/slide.pdf
deleted file mode 100644
index bb94047d..00000000
--- a/vhosts/blog/public/slides/2024-03-15/ya8-2024/slide.pdf
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/slides/2024-04-13/phpcon-odawara-2024/index.html b/vhosts/blog/public/slides/2024-04-13/phpcon-odawara-2024/index.html
deleted file mode 100644
index 94106604..00000000
--- a/vhosts/blog/public/slides/2024-04-13/phpcon-odawara-2024/index.html
+++ /dev/null
@@ -1,85 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="来る新 JIT エンジンについて知った気になる">
- <meta name="keywords" content="カンファレンス,PHP,PHP カンファレンス小田原">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHP カンファレンス小田原 2024 (レギュラートーク (15分))|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="来る新 JIT エンジンについて知った気になる">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHP カンファレンス小田原 2024 (レギュラートーク (15分))|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">来る新 JIT エンジンについて知った気になる</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/conference/">カンファレンス</a>
- </li>
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phpcon-odawara/">PHP カンファレンス小田原</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2024-04-13">2024-04-13</time>: 登壇
- </li>
- </ol>
- </section>
- <canvas data-slide-link="/slides/2024-04-13/phpcon-odawara-2024/slide.pdf" id="slide">
- </canvas>
- <div>
- <button id="prev" type="button">
- Prev
- </button>
- <button id="next" type="button">
- Next
- </button>
- </div>
- <script src="/slide.js?h=9e13ae7b86004d858e6bc1f38129cc88" type="module">
- </script>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/slides/2024-04-13/phpcon-odawara-2024/slide.pdf b/vhosts/blog/public/slides/2024-04-13/phpcon-odawara-2024/slide.pdf
deleted file mode 100644
index 75e60367..00000000
--- a/vhosts/blog/public/slides/2024-04-13/phpcon-odawara-2024/slide.pdf
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/slides/2024-04-25/phpstudy-tokyo-163/index.html b/vhosts/blog/public/slides/2024-04-25/phpstudy-tokyo-163/index.html
deleted file mode 100644
index 81d28131..00000000
--- a/vhosts/blog/public/slides/2024-04-25/phpstudy-tokyo-163/index.html
+++ /dev/null
@@ -1,82 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="Tracing JIT の発動条件">
- <meta name="keywords" content="PHP,PHP 勉強会@東京">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHP 勉強会@東京 第163回 (LT)|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="Tracing JIT の発動条件">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHP 勉強会@東京 第163回 (LT)|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">Tracing JIT の発動条件</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phpstudy-tokyo/">PHP 勉強会@東京</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2024-04-25">2024-04-25</time>: 登壇
- </li>
- </ol>
- </section>
- <canvas data-slide-link="/slides/2024-04-25/phpstudy-tokyo-163/slide.pdf" id="slide">
- </canvas>
- <div>
- <button id="prev" type="button">
- Prev
- </button>
- <button id="next" type="button">
- Next
- </button>
- </div>
- <script src="/slide.js?h=9e13ae7b86004d858e6bc1f38129cc88" type="module">
- </script>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/slides/2024-04-25/phpstudy-tokyo-163/slide.pdf b/vhosts/blog/public/slides/2024-04-25/phpstudy-tokyo-163/slide.pdf
deleted file mode 100644
index ad0bf085..00000000
--- a/vhosts/blog/public/slides/2024-04-25/phpstudy-tokyo-163/slide.pdf
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/slides/2024-07-18/phpstudy-tokyo-166/index.html b/vhosts/blog/public/slides/2024-07-18/phpstudy-tokyo-166/index.html
deleted file mode 100644
index 0c58b63b..00000000
--- a/vhosts/blog/public/slides/2024-07-18/phpstudy-tokyo-166/index.html
+++ /dev/null
@@ -1,82 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="PHPerKaigi 2024 で発表した WebAssembly ランタイムのその後">
- <meta name="keywords" content="PHP,PHP 勉強会@東京">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHP 勉強会@東京 第166回 (レギュラートーク (20分))|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="PHPerKaigi 2024 で発表した WebAssembly ランタイムのその後">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHP 勉強会@東京 第166回 (レギュラートーク (20分))|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">PHPerKaigi 2024 で発表した WebAssembly ランタイムのその後</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phpstudy-tokyo/">PHP 勉強会@東京</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2024-07-18">2024-07-18</time>: 登壇
- </li>
- </ol>
- </section>
- <canvas data-slide-link="/slides/2024-07-18/phpstudy-tokyo-166/slide.pdf" id="slide">
- </canvas>
- <div>
- <button id="prev" type="button">
- Prev
- </button>
- <button id="next" type="button">
- Next
- </button>
- </div>
- <script src="/slide.js?h=9e13ae7b86004d858e6bc1f38129cc88" type="module">
- </script>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/slides/2024-07-18/phpstudy-tokyo-166/slide.pdf b/vhosts/blog/public/slides/2024-07-18/phpstudy-tokyo-166/slide.pdf
deleted file mode 100644
index a0957334..00000000
--- a/vhosts/blog/public/slides/2024-07-18/phpstudy-tokyo-166/slide.pdf
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/slides/2024-10-30/phpstudy-tokyo-169/index.html b/vhosts/blog/public/slides/2024-10-30/phpstudy-tokyo-169/index.html
deleted file mode 100644
index 50b1cf33..00000000
--- a/vhosts/blog/public/slides/2024-10-30/phpstudy-tokyo-169/index.html
+++ /dev/null
@@ -1,82 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="PHP で PHP を作る (縮小版)">
- <meta name="keywords" content="PHP,PHP 勉強会@東京">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHP 勉強会@東京 第169回 (レギュラートーク (20分))|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="PHP で PHP を作る (縮小版)">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHP 勉強会@東京 第169回 (レギュラートーク (20分))|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">PHP で PHP を作る (縮小版)</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phpstudy-tokyo/">PHP 勉強会@東京</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2024-10-30">2024-10-30</time>: 登壇
- </li>
- </ol>
- </section>
- <canvas data-slide-link="/slides/2024-10-30/phpstudy-tokyo-169/slide.pdf" id="slide">
- </canvas>
- <div>
- <button id="prev" type="button">
- Prev
- </button>
- <button id="next" type="button">
- Next
- </button>
- </div>
- <script src="/slide.js?h=9e13ae7b86004d858e6bc1f38129cc88" type="module">
- </script>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/slides/2024-10-30/phpstudy-tokyo-169/slide.pdf b/vhosts/blog/public/slides/2024-10-30/phpstudy-tokyo-169/slide.pdf
deleted file mode 100644
index acdd51b1..00000000
--- a/vhosts/blog/public/slides/2024-10-30/phpstudy-tokyo-169/slide.pdf
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/slides/2024-11-30/cohackpp/index.html b/vhosts/blog/public/slides/2024-11-30/cohackpp/index.html
deleted file mode 100644
index 4d5b587a..00000000
--- a/vhosts/blog/public/slides/2024-11-30/cohackpp/index.html
+++ /dev/null
@@ -1,82 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="プログラミングマナー講座">
- <meta name="keywords" content="紅白ぺぱ合戦,PHP">
- <meta property="og:type" content="article">
- <meta property="og:title" content="紅白ぺぱ合戦 (LT)|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="プログラミングマナー講座">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>紅白ぺぱ合戦 (LT)|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">プログラミングマナー講座</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/cohackpp/">紅白ぺぱ合戦</a>
- </li>
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2024-11-30">2024-11-30</time>: 登壇
- </li>
- </ol>
- </section>
- <canvas data-slide-link="/slides/2024-11-30/cohackpp/slides.pdf" id="slide">
- </canvas>
- <div>
- <button id="prev" type="button">
- Prev
- </button>
- <button id="next" type="button">
- Next
- </button>
- </div>
- <script src="/slide.js?h=9e13ae7b86004d858e6bc1f38129cc88" type="module">
- </script>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/slides/2024-11-30/cohackpp/slides.pdf b/vhosts/blog/public/slides/2024-11-30/cohackpp/slides.pdf
deleted file mode 100644
index 7cc82ca9..00000000
--- a/vhosts/blog/public/slides/2024-11-30/cohackpp/slides.pdf
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/slides/2025-02-22/phpcon-nagoya-2025/index.html b/vhosts/blog/public/slides/2025-02-22/phpcon-nagoya-2025/index.html
deleted file mode 100644
index da309ea9..00000000
--- a/vhosts/blog/public/slides/2025-02-22/phpcon-nagoya-2025/index.html
+++ /dev/null
@@ -1,85 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2025 nsfisis">
- <meta name="description" content="PHP 処理系の garbage collection を理解する~メモリはいつ解放されるのか~">
- <meta name="keywords" content="カンファレンス,PHP,PHP カンファレンス名古屋">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHP カンファレンス名古屋 2025 (レギュラートーク (30分))|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="PHP 処理系の garbage collection を理解する~メモリはいつ解放されるのか~">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHP カンファレンス名古屋 2025 (レギュラートーク (30分))|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">PHP 処理系の garbage collection を理解する~メモリはいつ解放されるのか~</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/conference/">カンファレンス</a>
- </li>
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phpcon-nagoya/">PHP カンファレンス名古屋</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2025-02-22">2025-02-22</time>: 登壇
- </li>
- </ol>
- </section>
- <canvas data-slide-link="/slides/2025-02-22/phpcon-nagoya-2025/slides.pdf" id="slide">
- </canvas>
- <div>
- <button id="prev" type="button">
- Prev
- </button>
- <button id="next" type="button">
- Next
- </button>
- </div>
- <script src="/slide.js?h=9e13ae7b86004d858e6bc1f38129cc88" type="module">
- </script>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/slides/2025-02-22/phpcon-nagoya-2025/slides.pdf b/vhosts/blog/public/slides/2025-02-22/phpcon-nagoya-2025/slides.pdf
deleted file mode 100644
index be1cd969..00000000
--- a/vhosts/blog/public/slides/2025-02-22/phpcon-nagoya-2025/slides.pdf
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/slides/2025-03-23/phperkaigi-2025/index.html b/vhosts/blog/public/slides/2025-03-23/phperkaigi-2025/index.html
deleted file mode 100644
index f0460e1c..00000000
--- a/vhosts/blog/public/slides/2025-03-23/phperkaigi-2025/index.html
+++ /dev/null
@@ -1,85 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2025 nsfisis">
- <meta name="description" content="PHPで作るPHP~セルフホストできる言語処理系を作ろう~">
- <meta name="keywords" content="カンファレンス,PHP,PHPerKaigi">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHPerKaigi 2025 (レギュラートーク (40分))|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="PHPで作るPHP~セルフホストできる言語処理系を作ろう~">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHPerKaigi 2025 (レギュラートーク (40分))|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">PHPで作るPHP~セルフホストできる言語処理系を作ろう~</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/conference/">カンファレンス</a>
- </li>
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phperkaigi/">PHPerKaigi</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2025-03-23">2025-03-23</time>: 登壇
- </li>
- </ol>
- </section>
- <canvas data-slide-link="/slides/2025-03-23/phperkaigi-2025/slides.pdf" id="slide">
- </canvas>
- <div>
- <button id="prev" type="button">
- Prev
- </button>
- <button id="next" type="button">
- Next
- </button>
- </div>
- <script src="/slide.js?h=9e13ae7b86004d858e6bc1f38129cc88" type="module">
- </script>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/slides/2025-03-23/phperkaigi-2025/slides.pdf b/vhosts/blog/public/slides/2025-03-23/phperkaigi-2025/slides.pdf
deleted file mode 100644
index 6c87d655..00000000
--- a/vhosts/blog/public/slides/2025-03-23/phperkaigi-2025/slides.pdf
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/slides/2025-04-12/phpcon-odawara-2025/index.html b/vhosts/blog/public/slides/2025-04-12/phpcon-odawara-2025/index.html
deleted file mode 100644
index be74f6f6..00000000
--- a/vhosts/blog/public/slides/2025-04-12/phpcon-odawara-2025/index.html
+++ /dev/null
@@ -1,85 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2025 nsfisis">
- <meta name="description" content="PHP 8.x 時代のクラス設計(property promotion から property hooks まで)">
- <meta name="keywords" content="カンファレンス,PHP,PHP カンファレンス小田原">
- <meta property="og:type" content="article">
- <meta property="og:title" content="PHP カンファレンス小田原 2025 (レギュラートーク (20分))|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="PHP 8.x 時代のクラス設計(property promotion から property hooks まで)">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>PHP カンファレンス小田原 2025 (レギュラートーク (20分))|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="single">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <article class="post-single">
- <header class="post-header">
- <h1 class="post-title">PHP 8.x 時代のクラス設計(property promotion から property hooks まで)</h1>
- <ul class="post-tags">
- <li class="tag">
- <a href="/tags/conference/">カンファレンス</a>
- </li>
- <li class="tag">
- <a href="/tags/php/">PHP</a>
- </li>
- <li class="tag">
- <a href="/tags/phpcon-odawara/">PHP カンファレンス小田原</a>
- </li>
- </ul>
- </header>
- <div class="post-content">
- <section id="changelog">
- <h2><a href="#changelog">更新履歴</a></h2>
- <ol>
- <li class="revision">
- <time datetime="2025-04-12">2025-04-12</time>: 登壇
- </li>
- </ol>
- </section>
- <canvas data-slide-link="/slides/2025-04-12/phpcon-odawara-2025/slides.pdf" id="slide">
- </canvas>
- <div>
- <button id="prev" type="button">
- Prev
- </button>
- <button id="next" type="button">
- Next
- </button>
- </div>
- <script src="/slide.js?h=9e13ae7b86004d858e6bc1f38129cc88" type="module">
- </script>
- </div>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/slides/2025-04-12/phpcon-odawara-2025/slides.pdf b/vhosts/blog/public/slides/2025-04-12/phpcon-odawara-2025/slides.pdf
deleted file mode 100644
index 7eeed8d3..00000000
--- a/vhosts/blog/public/slides/2025-04-12/phpcon-odawara-2025/slides.pdf
+++ /dev/null
Binary files differ
diff --git a/vhosts/blog/public/slides/atom.xml b/vhosts/blog/public/slides/atom.xml
deleted file mode 100644
index ef5abb6d..00000000
--- a/vhosts/blog/public/slides/atom.xml
+++ /dev/null
@@ -1,187 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:slides</id>
- <title>スライド一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/slides/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2025-04-12T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:c6c7c241-46c1-44b5-95b2-c30c3a500df3</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2025-04-12/phpcon-odawara-2025/"></link>
- <title>PHP 8.x 時代のクラス設計(property promotion から property hooks まで)</title>
- <summary>登壇: PHP カンファレンス小田原 2025 (レギュラートーク (20分))</summary>
- <published>2025-04-12T00:00:00+09:00</published>
- <updated>2025-04-12T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:ec7f4462-ae56-4bbf-aac7-cbd32bbbeb29</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2025-03-23/phperkaigi-2025/"></link>
- <title>PHPで作るPHP~セルフホストできる言語処理系を作ろう~</title>
- <summary>登壇: PHPerKaigi 2025 (レギュラートーク (40分))</summary>
- <published>2025-03-23T00:00:00+09:00</published>
- <updated>2025-03-23T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:9172fbef-c812-4ade-86f5-eaa12c966708</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2025-02-22/phpcon-nagoya-2025/"></link>
- <title>PHP 処理系の garbage collection を理解する~メモリはいつ解放されるのか~</title>
- <summary>登壇: PHP カンファレンス名古屋 2025 (レギュラートーク (30分))</summary>
- <published>2025-02-22T00:00:00+09:00</published>
- <updated>2025-02-22T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:e1ca4664-f6f1-4de2-b4a5-ea2b64006708</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-11-30/cohackpp/"></link>
- <title>プログラミングマナー講座</title>
- <summary>登壇: 紅白ぺぱ合戦 (LT)</summary>
- <published>2024-11-30T00:00:00+09:00</published>
- <updated>2024-11-30T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:a84100cf-8c92-4856-addf-81a7c5547074</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-10-30/phpstudy-tokyo-169/"></link>
- <title>PHP で PHP を作る (縮小版)</title>
- <summary>登壇: PHP 勉強会@東京 第169回 (レギュラートーク (20分))</summary>
- <published>2024-10-30T00:00:00+09:00</published>
- <updated>2024-10-30T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:eec495b5-45e2-4c6f-a725-e62b1e0a7ad5</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-07-18/phpstudy-tokyo-166/"></link>
- <title>PHPerKaigi 2024 で発表した WebAssembly ランタイムのその後</title>
- <summary>登壇: PHP 勉強会@東京 第166回 (レギュラートーク (20分))</summary>
- <published>2024-07-18T00:00:00+09:00</published>
- <updated>2024-07-18T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:6cf84106-cc69-4d87-b957-9d58d7e585bb</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-04-25/phpstudy-tokyo-163/"></link>
- <title>Tracing JIT の発動条件</title>
- <summary>登壇: PHP 勉強会@東京 第163回 (LT)</summary>
- <published>2024-04-25T00:00:00+09:00</published>
- <updated>2024-04-25T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:69e1694b-5ddb-41a5-a7f4-138ce82a78b2</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-04-13/phpcon-odawara-2024/"></link>
- <title>来る新 JIT エンジンについて知った気になる</title>
- <summary>登壇: PHP カンファレンス小田原 2024 (レギュラートーク (15分))</summary>
- <published>2024-04-13T00:00:00+09:00</published>
- <updated>2024-04-13T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:da7b1d5a-70df-4c4a-936c-1b49ca1a7c37</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-03-15/ya8-2024/"></link>
- <title>CLI の PHP プログラムを限界まで高速化してみる</title>
- <summary>登壇: Ya8 2024 (レギュラートーク (60分))</summary>
- <published>2024-03-15T00:00:00+09:00</published>
- <updated>2024-03-15T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:cee40048-f3c5-4043-9ef8-a4ee2ae7cf0e</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-03-08/phperkaigi-2024/"></link>
- <title>WebAssembly を理解する 〜VM の作成を通して〜</title>
- <summary>登壇: PHPerKaigi 2024 (レギュラートーク (40分))</summary>
- <published>2024-03-08T00:00:00+09:00</published>
- <updated>2024-03-08T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:82db7893-983a-4631-8bee-d0725d078252</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-01-24/phpstudy-tokyo-160/"></link>
- <title>PHPStan の力で Algebraic Data Types を実現する</title>
- <summary>登壇: PHP 勉強会@東京 第160 回 (レギュラートーク)</summary>
- <published>2024-01-24T00:00:00+09:00</published>
- <updated>2024-01-24T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:6c377f3f-6f52-4074-b690-c79d02050562</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-10-25/phpstudy-tokyo-157/"></link>
- <title>PHP コードを隔離された環境で安全に動かす (on WebAssembly)</title>
- <summary>登壇: PHP 勉強会@東京 第157 回 (LT)</summary>
- <published>2023-10-25T00:00:00+09:00</published>
- <updated>2023-10-25T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:d6118e00-5fb1-4230-9d94-854260beae04</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-08-24/phpstudy-tokyo-155/"></link>
- <title>PHP 3.0 の処理系のソースを読んでみる</title>
- <summary>登壇: PHP 勉強会@東京 第155 回 (LT)</summary>
- <published>2023-08-24T00:00:00+09:00</published>
- <updated>2023-08-24T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:669de08d-9e02-44c5-ac3f-35972112e706</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-07-26/phpstudy-tokyo-154/"></link>
- <title>言語間で比較するエラーの通知と処理</title>
- <summary>登壇: PHP 勉強会@東京 第154 回 (レギュラートーク)</summary>
- <published>2023-07-26T00:00:00+09:00</published>
- <updated>2023-07-26T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:72244d87-4cf0-41c4-a074-bcc37acaa678</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-06-23/phpconfuk-2023-eve/"></link>
- <title>巨大なコードベースへ突撃するために</title>
- <summary>登壇: PHP カンファレンス福岡 2023 前夜祭 (非公式) (レギュラートーク)</summary>
- <published>2023-06-23T00:00:00+09:00</published>
- <updated>2023-06-23T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:6016d501-b9c9-474a-a304-1ec1295e049a</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-06-21/phpstudy-tokyo-153/"></link>
- <title>テキストファイルの末尾には改行コードを入れよう</title>
- <summary>登壇: PHP 勉強会@東京 第153 回 (LT)</summary>
- <published>2023-06-21T00:00:00+09:00</published>
- <updated>2023-06-21T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:fe75bb63-1cd9-457e-8244-c444307cd40a</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-04-12/phpstudy-tokyo-151/"></link>
- <title>list でない array の末尾を探す</title>
- <summary>登壇: PHP 勉強会@東京 第151 回 (LT)</summary>
- <published>2023-04-12T00:00:00+09:00</published>
- <updated>2023-04-12T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:3cce70d8-cee9-4e0e-8b38-6ef1e0a8a278</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-03-25/phperkaigi-2023-tokens/"></link>
- <title>PHPer チャレンジ解説 (デジタルサーカス株式会社)</title>
- <summary>登壇: PHPerKaigi 2023 (トークン解説セッション)</summary>
- <published>2023-03-25T00:00:00+09:00</published>
- <updated>2023-03-25T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:2dce7e27-1eaf-4ca4-8037-e9a3ead18b48</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-03-24/phperkaigi-2023/"></link>
- <title>詳説「参照」PHP の参照を完全に理解する</title>
- <summary>登壇: PHPerKaigi 2023 (レギュラートーク)</summary>
- <published>2023-03-24T00:00:00+09:00</published>
- <updated>2023-03-24T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:9376560b-250a-4697-ac10-0903ad16acee</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-03-15/phpstudy-tokyo-150/"></link>
- <title>明日のあなたの役に立たない PHP コーディング技法~細長い FizzBuzz を書く~</title>
- <summary>登壇: PHP 勉強会@東京 第150 回 (LT)</summary>
- <published>2023-03-15T00:00:00+09:00</published>
- <updated>2023-03-18T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:f23ea81c-5996-4b7e-aab0-4e9f23b172c2</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-02-15/phpstudy-tokyo-149/"></link>
- <title>PHPerKaigi 2023 のトークン問題でボツにした問題を供養する</title>
- <summary>登壇: PHP 勉強会@東京 第149 回 (LT)</summary>
- <published>2023-02-15T00:00:00+09:00</published>
- <updated>2023-02-15T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:693a4c2e-6f21-4840-b793-4e3644a8ec22</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-01-18/phpstudy-tokyo-148/"></link>
- <title>明日のあなたの役に立たない PHP コーディング技法~polyglot~</title>
- <summary>登壇: PHP 勉強会@東京 第148 回 (LT)</summary>
- <published>2023-01-18T00:00:00+09:00</published>
- <updated>2023-01-18T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/slides/index.html b/vhosts/blog/public/slides/index.html
deleted file mode 100644
index f3b498ba..00000000
--- a/vhosts/blog/public/slides/index.html
+++ /dev/null
@@ -1,380 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2021 nsfisis">
- <meta name="description" content="登壇したイベントで使用したスライドの一覧">
- <meta property="og:type" content="article">
- <meta property="og:title" content="スライド一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="登壇したイベントで使用したスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/slides/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>スライド一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>スライド一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/slides/2025-04-12/phpcon-odawara-2025/">
- <header class="entry-header">
- <h2>登壇: PHP カンファレンス小田原 2025 (レギュラートーク (20分))</h2>
- </header>
- <section class="entry-content">
- <p>
- PHP 8.x 時代のクラス設計(property promotion から property hooks まで)
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-04-12">2025-04-12</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2025-03-23/phperkaigi-2025/">
- <header class="entry-header">
- <h2>登壇: PHPerKaigi 2025 (レギュラートーク (40分))</h2>
- </header>
- <section class="entry-content">
- <p>
- PHPで作るPHP~セルフホストできる言語処理系を作ろう~
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-03-23">2025-03-23</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2025-02-22/phpcon-nagoya-2025/">
- <header class="entry-header">
- <h2>登壇: PHP カンファレンス名古屋 2025 (レギュラートーク (30分))</h2>
- </header>
- <section class="entry-content">
- <p>
- PHP 処理系の garbage collection を理解する~メモリはいつ解放されるのか~
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-02-22">2025-02-22</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2024-11-30/cohackpp/">
- <header class="entry-header">
- <h2>登壇: 紅白ぺぱ合戦 (LT)</h2>
- </header>
- <section class="entry-content">
- <p>
- プログラミングマナー講座
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-11-30">2024-11-30</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2024-10-30/phpstudy-tokyo-169/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第169回 (レギュラートーク (20分))</h2>
- </header>
- <section class="entry-content">
- <p>
- PHP で PHP を作る (縮小版)
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-10-30">2024-10-30</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2024-07-18/phpstudy-tokyo-166/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第166回 (レギュラートーク (20分))</h2>
- </header>
- <section class="entry-content">
- <p>
- PHPerKaigi 2024 で発表した WebAssembly ランタイムのその後
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-07-18">2024-07-18</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2024-04-25/phpstudy-tokyo-163/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第163回 (LT)</h2>
- </header>
- <section class="entry-content">
- <p>
- Tracing JIT の発動条件
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-04-25">2024-04-25</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2024-04-13/phpcon-odawara-2024/">
- <header class="entry-header">
- <h2>登壇: PHP カンファレンス小田原 2024 (レギュラートーク (15分))</h2>
- </header>
- <section class="entry-content">
- <p>
- 来る新 JIT エンジンについて知った気になる
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-04-13">2024-04-13</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2024-03-15/ya8-2024/">
- <header class="entry-header">
- <h2>登壇: Ya8 2024 (レギュラートーク (60分))</h2>
- </header>
- <section class="entry-content">
- <p>
- CLI の PHP プログラムを限界まで高速化してみる
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-03-15">2024-03-15</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2024-03-08/phperkaigi-2024/">
- <header class="entry-header">
- <h2>登壇: PHPerKaigi 2024 (レギュラートーク (40分))</h2>
- </header>
- <section class="entry-content">
- <p>
- WebAssembly を理解する 〜VM の作成を通して〜
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-03-08">2024-03-08</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2024-01-24/phpstudy-tokyo-160/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第160 回 (レギュラートーク)</h2>
- </header>
- <section class="entry-content">
- <p>
- PHPStan の力で Algebraic Data Types を実現する
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-01-24">2024-01-24</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-10-25/phpstudy-tokyo-157/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第157 回 (LT)</h2>
- </header>
- <section class="entry-content">
- <p>
- PHP コードを隔離された環境で安全に動かす (on WebAssembly)
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-10-25">2023-10-25</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-08-24/phpstudy-tokyo-155/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第155 回 (LT)</h2>
- </header>
- <section class="entry-content">
- <p>
- PHP 3.0 の処理系のソースを読んでみる
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-08-24">2023-08-24</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-07-26/phpstudy-tokyo-154/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第154 回 (レギュラートーク)</h2>
- </header>
- <section class="entry-content">
- <p>
- 言語間で比較するエラーの通知と処理
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-07-26">2023-07-26</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-06-23/phpconfuk-2023-eve/">
- <header class="entry-header">
- <h2>登壇: PHP カンファレンス福岡 2023 前夜祭 (非公式) (レギュラートーク)</h2>
- </header>
- <section class="entry-content">
- <p>
- 巨大なコードベースへ突撃するために
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-06-23">2023-06-23</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-06-21/phpstudy-tokyo-153/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第153 回 (LT)</h2>
- </header>
- <section class="entry-content">
- <p>
- テキストファイルの末尾には改行コードを入れよう
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-06-21">2023-06-21</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-04-12/phpstudy-tokyo-151/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第151 回 (LT)</h2>
- </header>
- <section class="entry-content">
- <p>
- list でない array の末尾を探す
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-04-12">2023-04-12</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-03-25/phperkaigi-2023-tokens/">
- <header class="entry-header">
- <h2>登壇: PHPerKaigi 2023 (トークン解説セッション)</h2>
- </header>
- <section class="entry-content">
- <p>
- PHPer チャレンジ解説 (デジタルサーカス株式会社)
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-03-25">2023-03-25</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-03-24/phperkaigi-2023/">
- <header class="entry-header">
- <h2>登壇: PHPerKaigi 2023 (レギュラートーク)</h2>
- </header>
- <section class="entry-content">
- <p>
- 詳説「参照」PHP の参照を完全に理解する
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-03-24">2023-03-24</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-03-15/phpstudy-tokyo-150/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第150 回 (LT)</h2>
- </header>
- <section class="entry-content">
- <p>
- 明日のあなたの役に立たない PHP コーディング技法~細長い FizzBuzz を書く~
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-03-15">2023-03-15</time> 登壇、<time datetime="2023-03-18">2023-03-18</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-02-15/phpstudy-tokyo-149/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第149 回 (LT)</h2>
- </header>
- <section class="entry-content">
- <p>
- PHPerKaigi 2023 のトークン問題でボツにした問題を供養する
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-02-15">2023-02-15</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-01-18/phpstudy-tokyo-148/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第148 回 (LT)</h2>
- </header>
- <section class="entry-content">
- <p>
- 明日のあなたの役に立たない PHP コーディング技法~polyglot~
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-01-18">2023-01-18</time> 登壇
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/style.css b/vhosts/blog/public/style.css
deleted file mode 100644
index fda139d7..00000000
--- a/vhosts/blog/public/style.css
+++ /dev/null
@@ -1,365 +0,0 @@
-html {
- box-sizing: border-box;
-}
-
-*, *:before, *:after {
- box-sizing: inherit;
-}
-
-body {
- font-family: 'Yu Gothic', 'Meiryo', 'Noto Sans JP', sans-serif;
- color: #000;
- background-color: #fff;
- line-height: 1.8;
- height: 100vh;
- margin: 0;
- padding: 0;
- display: flex;
- flex-direction: column;
- justify-content: space-between;
-}
-
-header.header {
- display: flex;
- flex-direction: column;
- align-items: center;
- padding: 1rem 15%;
- background-color: #000;
-}
-
-main {
- max-width: 800px;
- margin: 2rem auto;
- flex-grow: 1;
-}
-
-body > footer {
- padding: 1rem 20%;
- text-align: center;
- background-color: #000;
- color: #fff;
-}
-
-.site-logo {
- font-size: 1.5rem;
- font-weight: bold;
-}
-
-.site-logo a {
- border: none;
- color: #fff;
-}
-
-nav {
- padding: 0;
- margin: 0.5rem 0 0;
- width: 100%;
-}
-
-nav ul {
- list-style-type: none;
- padding: 0;
- margin: 0;
- display: flex;
- flex-direction: row;
- justify-content: center;
-}
-
-nav ul li {
- text-transform: uppercase;
- font-size: 1.1rem;
- margin: 0 1rem;
- display: flex;
- align-items: center;
-}
-
-nav ul li a {
- border: none;
- color: #fff;
-}
-
-h1, h2, h3, h4, h5, h6 {
- font-weight: bold;
-}
-
-p {
- font-size: 1rem;
- line-height: 1.8;
- margin-bottom: 1.2rem;
-}
-
-a {
- text-decoration: none;
- color: #000;
- border-bottom: 1px solid #000;
- word-break: break-all;
-}
-
-a:hover {
- color: #666;
-}
-
-.codeblock {
- background-color: #f5f5f5;
- position: relative;
- margin: 1rem 0;
- border-radius: 3px;
- overflow: hidden;
- tab-size: 4;
-}
-
-.codeblock .filename {
- background-color: #e0e0e0;
- color: #333;
- font-family: Monaco, Consolas, 'Courier New', Courier, monospace;
- font-size: 0.9rem;
- padding: 0.5rem 1rem;
- border-bottom: 1px solid #ccc;
-}
-
-pre {
- background-color: #f5f5f5;
- padding: 1rem;
- margin: 0;
- overflow-x: auto;
- font-family: Monaco, Consolas, 'Courier New', Courier, monospace;
- font-size: 0.9rem;
-}
-
-blockquote {
- background-color: #f5f5f5;
- border-left: 5px solid #555;
- padding: 1rem;
- margin: 1rem 0;
-}
-
-.tag {
- display: inline-block;
- padding: 3px 8px;
- font-size: 0.9rem;
- margin-right: 5px;
- margin-bottom: 5px;
- border: 1px solid #000;
-}
-
-.tag a {
- border: none;
-}
-
-code {
- background-color: #f5f5f5;
- padding: 2px 5px;
- font-family: Monaco, Consolas, 'Courier New', Courier, monospace;
- font-size: 0.9rem;
-}
-
-.shiki code {
- background-color: unset;
- padding: 0;
-}
-
-/* https://github.com/shikijs/shiki/issues/3 */
-.shiki code {
- counter-reset: codeblock-line-number;
- counter-increment: codeblock-line-number 0;
-}
-
-.numbered .shiki code .line::before {
- content: counter(codeblock-line-number);
- counter-increment: codeblock-line-number;
- width: 2rem;
- margin-right: 1.5rem;
- display: inline-block;
- text-align: right;
- color: #777;
-}
-
-li.revision {
- list-style: inside;
-}
-
-h1 {
- font-size: 2.2rem;
-}
-
-.post-content h2,
-.post-content h3,
-.post-content h4,
-.post-content h5,
-.post-content h6 {
- border-bottom: 1px solid #555;
- margin-bottom: 1.2rem;
-}
-
-.post-content h2 a,
-.post-content h3 a,
-.post-content h4 a,
-.post-content h5 a,
-.post-content h6 a {
- border: none;
-}
-
-.post-content h2:before {
- content: "#";
- padding-right: 0.3rem;
- color: #555;
- font-weight: bold;
-}
-
-.post-content h3:before {
- content: "##";
- padding-right: 0.3rem;
- color: #555;
- font-weight: bold;
-}
-
-.post-content h4:before {
- content: "###";
- padding-right: 0.3rem;
- color: #555;
- font-weight: bold;
-}
-
-.post-content h5:before {
- content: "####";
- padding-right: 0.3rem;
- color: #555;
- font-weight: bold;
-}
-
-.post-content h6:before {
- content: "#####";
- padding-right: 0.3rem;
- color: #555;
- font-weight: bold;
-}
-
-.post-entry {
- min-width: calc(min(800px, 100vw - 4rem));
- padding: 1.5rem;
- margin: 2rem 0;
- border: 2px solid #000;
-}
-
-.post-entry header {
- border: none;
-}
-
-.post-entry header h2 {
- margin: 0;
-}
-
-.post-entry section {
- color: #666;
-}
-
-.post-entry footer {
- padding: 0;
- text-align: left;
- color: #666;
-}
-
-.admonition {
- background-color: #f5f5f5;
- border: 1px solid #d1d1d1;
- padding: 1rem 1.5rem;
- margin: 1rem 0;
-}
-
-.admonition-label {
- font-weight: bold;
- color: #333;
- margin-right: 1rem;
-}
-
-.admonition-content {
- font-size: 1rem;
-}
-
-img {
- max-width: 100%;
- height: auto;
-}
-
-.not-found {
- font-size: 8rem;
- font-weight: bold;
-}
-
-@media screen and (max-width: 768px) {
- main {
- padding: 0 1rem;
- margin: 2rem 1rem;
- }
-}
-
-@media screen and (max-width: 768px) {
- header.header {
- padding: 1rem 0;
- }
-
- nav ul {
- display: none;
- }
-}
-
-.my-icon {
- display: flex;
- justify-content: center;
- align-items: center;
-}
-
-.footnotes {
- border-top: 1px solid #000;
-}
-
-.pagination {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin: 2rem 0;
- padding: 1rem 0;
- border-top: 1px solid #d1d1d1;
- border-bottom: 1px solid #d1d1d1;
-}
-
-.pagination-prev,
-.pagination-next {
- flex: 1;
-}
-
-.pagination-prev {
- text-align: left;
-}
-
-.pagination-next {
- text-align: right;
-}
-
-.pagination-info {
- flex: 0 0 auto;
- text-align: center;
- color: #000;
- font-size: 0.9rem;
-}
-
-.pagination a {
- text-decoration: none;
- color: #000;
- padding: 0.5rem 1rem;
- border: none;
-}
-
-.pagination a:hover {
- color: #666;
-}
-
-@media screen and (max-width: 768px) {
- .pagination {
- font-size: 0.9rem;
- }
-
- .pagination a {
- padding: 0.5rem;
- }
-}
diff --git a/vhosts/blog/public/tags/c/atom.xml b/vhosts/blog/public/tags/c/atom.xml
deleted file mode 100644
index 3a4fc63e..00000000
--- a/vhosts/blog/public/tags/c/atom.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-c</id>
- <title>タグ「C」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/c/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/c/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2025-05-05T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:64f5e1a6-2f5c-4d5d-b1c8-8346a66c1d40</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-05-05/make-tiny-self-hosted-c-compiler/"></link>
- <title>セルフホスト可能な C コンパイラを作った</title>
- <summary>ゴールデンウィークを使って、セルフホストできる C コンパイラを開発した</summary>
- <published>2025-05-05T00:00:00+09:00</published>
- <updated>2025-05-05T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/c/index.html b/vhosts/blog/public/tags/c/index.html
deleted file mode 100644
index 0a738be4..00000000
--- a/vhosts/blog/public/tags/c/index.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2025 nsfisis">
- <meta name="description" content="タグ「C」のついた記事またはスライドの一覧">
- <meta name="keywords" content="C">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「C」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「C」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/c/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「C」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「C」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2025-05-05/make-tiny-self-hosted-c-compiler/">
- <header class="entry-header">
- <h2>セルフホスト可能な C コンパイラを作った</h2>
- </header>
- <section class="entry-content">
- <p>
- ゴールデンウィークを使って、セルフホストできる C コンパイラを開発した
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-05-05">2025-05-05</time> 投稿
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/ci-cd/atom.xml b/vhosts/blog/public/tags/ci-cd/atom.xml
deleted file mode 100644
index 393bec10..00000000
--- a/vhosts/blog/public/tags/ci-cd/atom.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-ci-cd</id>
- <title>タグ「CI/CD」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/ci-cd/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/ci-cd/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2024-04-21T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:a4c326a6-5ffe-450c-abf2-45833c5efb6a</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-04-21/pipefail-option-in-gitlab-ci-cd/"></link>
- <title>【GitLab】 GitLab CI/CD 上での bash/sh は pipefail が有効になっている</title>
- <summary>GitLab CI/CD で bash/sh スクリプトを動かすと、pipefail オプションが有効になった状態で実行される。</summary>
- <published>2024-04-21T00:00:00+09:00</published>
- <updated>2024-04-21T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/ci-cd/index.html b/vhosts/blog/public/tags/ci-cd/index.html
deleted file mode 100644
index 7c3e4992..00000000
--- a/vhosts/blog/public/tags/ci-cd/index.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="タグ「CI/CD」のついた記事またはスライドの一覧">
- <meta name="keywords" content="CI/CD">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「CI/CD」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「CI/CD」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/ci-cd/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「CI/CD」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「CI/CD」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2024-04-21/pipefail-option-in-gitlab-ci-cd/">
- <header class="entry-header">
- <h2>【GitLab】 GitLab CI/CD 上での bash/sh は pipefail が有効になっている</h2>
- </header>
- <section class="entry-content">
- <p>
- GitLab CI/CD で bash/sh スクリプトを動かすと、pipefail オプションが有効になった状態で実行される。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-04-21">2024-04-21</time> 投稿
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/cohackpp/atom.xml b/vhosts/blog/public/tags/cohackpp/atom.xml
deleted file mode 100644
index 389b44f8..00000000
--- a/vhosts/blog/public/tags/cohackpp/atom.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-cohackpp</id>
- <title>タグ「紅白ぺぱ合戦」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/cohackpp/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/cohackpp/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2024-12-05T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:ea0593d3-691c-4e08-8db4-98b8925717ec</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-12-04/cohackpp-report/"></link>
- <title>紅白ぺぱ合戦に参加&amp;LTしました</title>
- <summary>2024-11-30 に開催された紅白ぺぱ合戦に参加し、ぺ陣営のメンバとして LT しました。</summary>
- <published>2024-12-04T00:00:00+09:00</published>
- <updated>2024-12-05T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:e1ca4664-f6f1-4de2-b4a5-ea2b64006708</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-11-30/cohackpp/"></link>
- <title>プログラミングマナー講座</title>
- <summary>登壇: 紅白ぺぱ合戦 (LT)</summary>
- <published>2024-11-30T00:00:00+09:00</published>
- <updated>2024-11-30T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/cohackpp/index.html b/vhosts/blog/public/tags/cohackpp/index.html
deleted file mode 100644
index 55f31447..00000000
--- a/vhosts/blog/public/tags/cohackpp/index.html
+++ /dev/null
@@ -1,81 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="タグ「紅白ぺぱ合戦」のついた記事またはスライドの一覧">
- <meta name="keywords" content="紅白ぺぱ合戦">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「紅白ぺぱ合戦」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「紅白ぺぱ合戦」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/cohackpp/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「紅白ぺぱ合戦」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「紅白ぺぱ合戦」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2024-12-04/cohackpp-report/">
- <header class="entry-header">
- <h2>紅白ぺぱ合戦に参加&amp;LTしました</h2>
- </header>
- <section class="entry-content">
- <p>
- 2024-11-30 に開催された紅白ぺぱ合戦に参加し、ぺ陣営のメンバとして LT しました。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-12-04">2024-12-04</time> 投稿、<time datetime="2024-12-05">2024-12-05</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2024-11-30/cohackpp/">
- <header class="entry-header">
- <h2>登壇: 紅白ぺぱ合戦 (LT)</h2>
- </header>
- <section class="entry-content">
- <p>
- プログラミングマナー講座
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-11-30">2024-11-30</time> 登壇
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/composer/atom.xml b/vhosts/blog/public/tags/composer/atom.xml
deleted file mode 100644
index 9dfa371e..00000000
--- a/vhosts/blog/public/tags/composer/atom.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-composer</id>
- <title>タグ「Composer」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/composer/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/composer/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2025-04-24T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:087e98f2-743c-48d8-9f67-e9b57e354845</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-04-24/composer-patches-v2-does-not-require-gnu-patch-even-on-macos/"></link>
- <title>【Composer】 composer-patches v2 では macOS でも GNU patch のインストールが不要になる (予定)</title>
- <summary>composer-patches は BSD patch に対応しておらず、一部のパッチの適用に失敗する。現在ベータ版である v2 では patch コマンドに依存しなくなり、macOS で使うときのストレスが解消される見込み。</summary>
- <published>2025-04-24T00:00:00+09:00</published>
- <updated>2025-04-24T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:9b26c1ed-45c3-4cad-9476-cbf2cf2e4de7</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-04-29/zsh-file-completion-for-composer-custom-commands/"></link>
- <title>【Zsh】 Composer のカスタムコマンドに対する Zsh 補完で引数にファイルを補完させる</title>
- <summary>Zsh の Composer に対する補完はカスタムコマンドやその引数を補完しない。カスタムコマンドの引数としてファイルを補完させる方法を調べた。</summary>
- <published>2024-04-29T00:00:00+09:00</published>
- <updated>2024-04-29T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/composer/index.html b/vhosts/blog/public/tags/composer/index.html
deleted file mode 100644
index 9ba883b2..00000000
--- a/vhosts/blog/public/tags/composer/index.html
+++ /dev/null
@@ -1,81 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="タグ「Composer」のついた記事またはスライドの一覧">
- <meta name="keywords" content="Composer">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「Composer」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「Composer」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/composer/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「Composer」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「Composer」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2025-04-24/composer-patches-v2-does-not-require-gnu-patch-even-on-macos/">
- <header class="entry-header">
- <h2>【Composer】 composer-patches v2 では macOS でも GNU patch のインストールが不要になる (予定)</h2>
- </header>
- <section class="entry-content">
- <p>
- composer-patches は BSD patch に対応しておらず、一部のパッチの適用に失敗する。現在ベータ版である v2 では patch コマンドに依存しなくなり、macOS で使うときのストレスが解消される見込み。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-04-24">2025-04-24</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2024-04-29/zsh-file-completion-for-composer-custom-commands/">
- <header class="entry-header">
- <h2>【Zsh】 Composer のカスタムコマンドに対する Zsh 補完で引数にファイルを補完させる</h2>
- </header>
- <section class="entry-content">
- <p>
- Zsh の Composer に対する補完はカスタムコマンドやその引数を補完しない。カスタムコマンドの引数としてファイルを補完させる方法を調べた。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-04-29">2024-04-29</time> 投稿
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/conference/atom.xml b/vhosts/blog/public/tags/conference/atom.xml
deleted file mode 100644
index f230c7d5..00000000
--- a/vhosts/blog/public/tags/conference/atom.xml
+++ /dev/null
@@ -1,195 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-conference</id>
- <title>タグ「カンファレンス」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/conference/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/conference/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2025-04-20T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:039b3dff-3b75-46b7-a731-9a3a0ff8e21f</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/"></link>
- <title>RubyKaigi 2025 の TRICK で入賞した</title>
- <summary>RubyKaigi 2025 で開催された TRICK において、『最もRuby on Ruby賞』として審査員賞をいただいた。</summary>
- <published>2025-04-20T00:00:00+09:00</published>
- <updated>2025-04-20T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:c6c7c241-46c1-44b5-95b2-c30c3a500df3</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2025-04-12/phpcon-odawara-2025/"></link>
- <title>PHP 8.x 時代のクラス設計(property promotion から property hooks まで)</title>
- <summary>登壇: PHP カンファレンス小田原 2025 (レギュラートーク (20分))</summary>
- <published>2025-04-12T00:00:00+09:00</published>
- <updated>2025-04-12T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:ec7f4462-ae56-4bbf-aac7-cbd32bbbeb29</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2025-03-23/phperkaigi-2025/"></link>
- <title>PHPで作るPHP~セルフホストできる言語処理系を作ろう~</title>
- <summary>登壇: PHPerKaigi 2025 (レギュラートーク (40分))</summary>
- <published>2025-03-23T00:00:00+09:00</published>
- <updated>2025-03-23T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:13174dc7-c1a3-465f-9ba6-14f0bc6f5961</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-02-24/phpcon-nagoya-2025-report/"></link>
- <title>PHP カンファレンス名古屋 2025 参加レポ</title>
- <summary>2025-02-22 に開催された、PHP カンファレンス名古屋 2025 に参加した。</summary>
- <published>2025-02-24T00:00:00+09:00</published>
- <updated>2025-02-24T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:9172fbef-c812-4ade-86f5-eaa12c966708</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2025-02-22/phpcon-nagoya-2025/"></link>
- <title>PHP 処理系の garbage collection を理解する~メモリはいつ解放されるのか~</title>
- <summary>登壇: PHP カンファレンス名古屋 2025 (レギュラートーク (30分))</summary>
- <published>2025-02-22T00:00:00+09:00</published>
- <updated>2025-02-22T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:ce8f20e8-c79f-48f8-982d-53edd4d20483</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-01-08/phperkaigi-2023-tokens-q1/"></link>
- <title>PHPerKaigi 2023 トークン問題解説 (1/5)</title>
- <summary>PHPerKaigi 2023 でデジタルサーカス株式会社から出題した問題を解説する。全5問中の第1問。</summary>
- <published>2025-01-08T00:00:00+09:00</published>
- <updated>2025-01-11T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:8d6f3690-3da3-4235-a81b-b9707cee22ad</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-06-19/scalamatsuri-2024-report/"></link>
- <title>ScalaMatsuri 2024 参加レポ</title>
- <summary>2024-06-08 から 2024-06-09 にかけて開催された、ScalaMatsuri 2024 に参加した。</summary>
- <published>2024-06-19T00:00:00+09:00</published>
- <updated>2024-06-19T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:f13aa9d6-4533-4a15-872a-c298ab2090db</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-05-11/phpconkagawa-2024-report/"></link>
- <title>PHP カンファレンス香川 2024 参加レポ</title>
- <summary>2024-05-11 に開催された、PHP カンファレンス香川 2024 に参加した。</summary>
- <published>2024-05-11T00:00:00+09:00</published>
- <updated>2024-05-11T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:be9c896d-7efa-42dd-a50a-dda5fd3a7f5c</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-04-14/phpcon-odawara-2024-report/"></link>
- <title>PHP カンファレンス小田原 2024 参加レポ</title>
- <summary>2024-04-13 に開催された、PHP カンファレンス小田原 2024 に参加した。</summary>
- <published>2024-04-14T00:00:00+09:00</published>
- <updated>2024-06-01T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:69e1694b-5ddb-41a5-a7f4-138ce82a78b2</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-04-13/phpcon-odawara-2024/"></link>
- <title>来る新 JIT エンジンについて知った気になる</title>
- <summary>登壇: PHP カンファレンス小田原 2024 (レギュラートーク (15分))</summary>
- <published>2024-04-13T00:00:00+09:00</published>
- <updated>2024-04-13T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:750be5c8-ca52-4cbd-86fe-5645b06bde95</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-03-17/phperkaigi-2024-report/"></link>
- <title>PHPerKaigi 2024 参加レポ</title>
- <summary>2024-03-07 から 2024-03-09 にかけて開催された、PHPerKaigi 2024 に参加した。</summary>
- <published>2024-03-17T00:00:00+09:00</published>
- <updated>2024-07-07T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:da7b1d5a-70df-4c4a-936c-1b49ca1a7c37</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-03-15/ya8-2024/"></link>
- <title>CLI の PHP プログラムを限界まで高速化してみる</title>
- <summary>登壇: Ya8 2024 (レギュラートーク (60分))</summary>
- <published>2024-03-15T00:00:00+09:00</published>
- <updated>2024-03-15T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:cee40048-f3c5-4043-9ef8-a4ee2ae7cf0e</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-03-08/phperkaigi-2024/"></link>
- <title>WebAssembly を理解する 〜VM の作成を通して〜</title>
- <summary>登壇: PHPerKaigi 2024 (レギュラートーク (40分))</summary>
- <published>2024-03-08T00:00:00+09:00</published>
- <updated>2024-03-08T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:fd8fcb03-8e4d-4ca7-8499-0674accc51a9</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-02-22/phpkansai-2024-report/"></link>
- <title>PHPカンファレンス関西 2024 参加レポ</title>
- <summary>2024-02-11 に開催された、PHPカンファレンス関西 2024 に参加した。</summary>
- <published>2024-02-21T00:00:00+09:00</published>
- <updated>2024-02-21T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:230a0048-93c0-4aac-91ef-bb3108f3e587</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-02-10/yapcjapan-2024-report/"></link>
- <title>YAPC::Hiroshima 2024 参加レポ</title>
- <summary>2024-02-10 に開催された、YAPC::Hiroshima 2024 に参加した。</summary>
- <published>2024-02-10T00:00:00+09:00</published>
- <updated>2024-02-10T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:e1568c4c-9bdd-47b9-8b39-939ade4f3ba0</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2023-06-25/phpconfuk-2023-report/"></link>
- <title>PHP カンファレンス福岡 2023 参加レポ</title>
- <summary>2023-06-24 に開催された、PHP カンファレンス福岡に参加した。</summary>
- <published>2023-06-25T00:00:00+09:00</published>
- <updated>2023-06-25T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:21ce39f0-d613-45f2-a760-89c368892d77</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2023-04-04/phperkaigi-2023-report/"></link>
- <title>PHPerKaigi 2023 参加レポ</title>
- <summary>2023-03-23 から 2023-03-25 にかけて開催された、PHPerKaigi 2023 に参加した。</summary>
- <published>2023-04-04T00:00:00+09:00</published>
- <updated>2023-06-28T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:3cce70d8-cee9-4e0e-8b38-6ef1e0a8a278</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-03-25/phperkaigi-2023-tokens/"></link>
- <title>PHPer チャレンジ解説 (デジタルサーカス株式会社)</title>
- <summary>登壇: PHPerKaigi 2023 (トークン解説セッション)</summary>
- <published>2023-03-25T00:00:00+09:00</published>
- <updated>2023-03-25T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:2dce7e27-1eaf-4ca4-8037-e9a3ead18b48</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-03-24/phperkaigi-2023/"></link>
- <title>詳説「参照」PHP の参照を完全に理解する</title>
- <summary>登壇: PHPerKaigi 2023 (レギュラートーク)</summary>
- <published>2023-03-24T00:00:00+09:00</published>
- <updated>2023-03-24T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:bb71bb5d-361b-44cb-9753-81d14583d860</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-08-27/php-conference-okinawa-code-golf/"></link>
- <title>PHP カンファレンス沖縄で出題されたコードゴルフの問題を解いてみた</title>
- <summary>PHP カンファレンス沖縄の懇親会 LT で出題されたコードゴルフの問題を解いてみた。</summary>
- <published>2022-08-27T00:00:00+09:00</published>
- <updated>2022-08-27T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:9211e1fe-bca3-43c4-ba4e-c67d62f3fed0</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-05-01/phperkaigi-2022/"></link>
- <title>PHPerKaigi 2022</title>
- <summary>2022-04-09 から 2022-04-11 にかけて開催された、PHPerKaigi 2022 に参加した。</summary>
- <published>2022-05-01T00:00:00+09:00</published>
- <updated>2022-05-01T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:f4985d54-0907-4449-8101-0fcd382f9e02</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-04-09/phperkaigi-2022-tokens/"></link>
- <title>PHPerKaigi 2022 トークン問題の解説</title>
- <summary>PHPerKaigi 2022 で私が作成した PHPer チャレンジ問題を解説する。</summary>
- <published>2022-04-09T00:00:00+09:00</published>
- <updated>2022-04-16T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:3fbe0b8c-216e-48f6-b905-c0d361b94542</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2021-03-30/phperkaigi-2021/"></link>
- <title>PHPerKaigi 2021</title>
- <summary>2021-03-26 から 2021-03-28 にかけて開催された、PHPerKaigi 2021 に参加した。</summary>
- <published>2021-03-30T00:00:00+09:00</published>
- <updated>2025-04-09T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/conference/index.html b/vhosts/blog/public/tags/conference/index.html
deleted file mode 100644
index 961178c7..00000000
--- a/vhosts/blog/public/tags/conference/index.html
+++ /dev/null
@@ -1,396 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2021 nsfisis">
- <meta name="description" content="タグ「カンファレンス」のついた記事またはスライドの一覧">
- <meta name="keywords" content="カンファレンス">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「カンファレンス」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「カンファレンス」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/conference/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「カンファレンス」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「カンファレンス」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/">
- <header class="entry-header">
- <h2>RubyKaigi 2025 の TRICK で入賞した</h2>
- </header>
- <section class="entry-content">
- <p>
- RubyKaigi 2025 で開催された TRICK において、『最もRuby on Ruby賞』として審査員賞をいただいた。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-04-20">2025-04-20</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2025-04-12/phpcon-odawara-2025/">
- <header class="entry-header">
- <h2>登壇: PHP カンファレンス小田原 2025 (レギュラートーク (20分))</h2>
- </header>
- <section class="entry-content">
- <p>
- PHP 8.x 時代のクラス設計(property promotion から property hooks まで)
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-04-12">2025-04-12</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2025-03-23/phperkaigi-2025/">
- <header class="entry-header">
- <h2>登壇: PHPerKaigi 2025 (レギュラートーク (40分))</h2>
- </header>
- <section class="entry-content">
- <p>
- PHPで作るPHP~セルフホストできる言語処理系を作ろう~
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-03-23">2025-03-23</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2025-02-24/phpcon-nagoya-2025-report/">
- <header class="entry-header">
- <h2>PHP カンファレンス名古屋 2025 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2025-02-22 に開催された、PHP カンファレンス名古屋 2025 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-02-24">2025-02-24</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2025-02-22/phpcon-nagoya-2025/">
- <header class="entry-header">
- <h2>登壇: PHP カンファレンス名古屋 2025 (レギュラートーク (30分))</h2>
- </header>
- <section class="entry-content">
- <p>
- PHP 処理系の garbage collection を理解する~メモリはいつ解放されるのか~
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-02-22">2025-02-22</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2025-01-08/phperkaigi-2023-tokens-q1/">
- <header class="entry-header">
- <h2>PHPerKaigi 2023 トークン問題解説 (1/5)</h2>
- </header>
- <section class="entry-content">
- <p>
- PHPerKaigi 2023 でデジタルサーカス株式会社から出題した問題を解説する。全5問中の第1問。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-01-08">2025-01-08</time> 投稿、<time datetime="2025-01-11">2025-01-11</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2024-06-19/scalamatsuri-2024-report/">
- <header class="entry-header">
- <h2>ScalaMatsuri 2024 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2024-06-08 から 2024-06-09 にかけて開催された、ScalaMatsuri 2024 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-06-19">2024-06-19</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2024-05-11/phpconkagawa-2024-report/">
- <header class="entry-header">
- <h2>PHP カンファレンス香川 2024 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2024-05-11 に開催された、PHP カンファレンス香川 2024 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-05-11">2024-05-11</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2024-04-14/phpcon-odawara-2024-report/">
- <header class="entry-header">
- <h2>PHP カンファレンス小田原 2024 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2024-04-13 に開催された、PHP カンファレンス小田原 2024 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-04-14">2024-04-14</time> 投稿、<time datetime="2024-06-01">2024-06-01</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2024-04-13/phpcon-odawara-2024/">
- <header class="entry-header">
- <h2>登壇: PHP カンファレンス小田原 2024 (レギュラートーク (15分))</h2>
- </header>
- <section class="entry-content">
- <p>
- 来る新 JIT エンジンについて知った気になる
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-04-13">2024-04-13</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2024-03-17/phperkaigi-2024-report/">
- <header class="entry-header">
- <h2>PHPerKaigi 2024 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2024-03-07 から 2024-03-09 にかけて開催された、PHPerKaigi 2024 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-03-17">2024-03-17</time> 投稿、<time datetime="2024-07-07">2024-07-07</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2024-03-15/ya8-2024/">
- <header class="entry-header">
- <h2>登壇: Ya8 2024 (レギュラートーク (60分))</h2>
- </header>
- <section class="entry-content">
- <p>
- CLI の PHP プログラムを限界まで高速化してみる
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-03-15">2024-03-15</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2024-03-08/phperkaigi-2024/">
- <header class="entry-header">
- <h2>登壇: PHPerKaigi 2024 (レギュラートーク (40分))</h2>
- </header>
- <section class="entry-content">
- <p>
- WebAssembly を理解する 〜VM の作成を通して〜
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-03-08">2024-03-08</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2024-02-22/phpkansai-2024-report/">
- <header class="entry-header">
- <h2>PHPカンファレンス関西 2024 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2024-02-11 に開催された、PHPカンファレンス関西 2024 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-02-21">2024-02-21</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2024-02-10/yapcjapan-2024-report/">
- <header class="entry-header">
- <h2>YAPC::Hiroshima 2024 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2024-02-10 に開催された、YAPC::Hiroshima 2024 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-02-10">2024-02-10</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2023-06-25/phpconfuk-2023-report/">
- <header class="entry-header">
- <h2>PHP カンファレンス福岡 2023 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2023-06-24 に開催された、PHP カンファレンス福岡に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-06-25">2023-06-25</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2023-04-04/phperkaigi-2023-report/">
- <header class="entry-header">
- <h2>PHPerKaigi 2023 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2023-03-23 から 2023-03-25 にかけて開催された、PHPerKaigi 2023 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-04-04">2023-04-04</time> 投稿、<time datetime="2023-06-28">2023-06-28</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-03-25/phperkaigi-2023-tokens/">
- <header class="entry-header">
- <h2>登壇: PHPerKaigi 2023 (トークン解説セッション)</h2>
- </header>
- <section class="entry-content">
- <p>
- PHPer チャレンジ解説 (デジタルサーカス株式会社)
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-03-25">2023-03-25</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-03-24/phperkaigi-2023/">
- <header class="entry-header">
- <h2>登壇: PHPerKaigi 2023 (レギュラートーク)</h2>
- </header>
- <section class="entry-content">
- <p>
- 詳説「参照」PHP の参照を完全に理解する
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-03-24">2023-03-24</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2022-08-27/php-conference-okinawa-code-golf/">
- <header class="entry-header">
- <h2>PHP カンファレンス沖縄で出題されたコードゴルフの問題を解いてみた</h2>
- </header>
- <section class="entry-content">
- <p>
- PHP カンファレンス沖縄の懇親会 LT で出題されたコードゴルフの問題を解いてみた。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2022-08-27">2022-08-27</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2022-05-01/phperkaigi-2022/">
- <header class="entry-header">
- <h2>PHPerKaigi 2022</h2>
- </header>
- <section class="entry-content">
- <p>
- 2022-04-09 から 2022-04-11 にかけて開催された、PHPerKaigi 2022 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2022-05-01">2022-05-01</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2022-04-09/phperkaigi-2022-tokens/">
- <header class="entry-header">
- <h2>PHPerKaigi 2022 トークン問題の解説</h2>
- </header>
- <section class="entry-content">
- <p>
- PHPerKaigi 2022 で私が作成した PHPer チャレンジ問題を解説する。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2022-04-09">2022-04-09</time> 投稿、<time datetime="2022-04-16">2022-04-16</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2021-03-30/phperkaigi-2021/">
- <header class="entry-header">
- <h2>PHPerKaigi 2021</h2>
- </header>
- <section class="entry-content">
- <p>
- 2021-03-26 から 2021-03-28 にかけて開催された、PHPerKaigi 2021 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2021-03-30">2021-03-30</time> 投稿、<time datetime="2025-04-09">2025-04-09</time> 更新
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/cpp/atom.xml b/vhosts/blog/public/tags/cpp/atom.xml
deleted file mode 100644
index 2bc67f5f..00000000
--- a/vhosts/blog/public/tags/cpp/atom.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-cpp</id>
- <title>タグ「C++」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/cpp/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/cpp/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2021-10-02T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:69863d75-ef21-42db-b743-5958f7c86827</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2021-10-02/cpp-you-can-use-keywords-in-attributes/"></link>
- <title>【C++】 属性構文の属性名にはキーワードが使える</title>
- <summary>C++ の属性構文の属性名には、キーワードが使える。ネタ記事。</summary>
- <published>2021-10-02T00:00:00+09:00</published>
- <updated>2021-10-02T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/cpp/index.html b/vhosts/blog/public/tags/cpp/index.html
deleted file mode 100644
index cb23cbb6..00000000
--- a/vhosts/blog/public/tags/cpp/index.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2021 nsfisis">
- <meta name="description" content="タグ「C++」のついた記事またはスライドの一覧">
- <meta name="keywords" content="C++">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「C++」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「C++」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/cpp/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「C++」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「C++」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2021-10-02/cpp-you-can-use-keywords-in-attributes/">
- <header class="entry-header">
- <h2>【C++】 属性構文の属性名にはキーワードが使える</h2>
- </header>
- <section class="entry-content">
- <p>
- C++ の属性構文の属性名には、キーワードが使える。ネタ記事。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2021-10-02">2021-10-02</time> 投稿
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/cpp17/atom.xml b/vhosts/blog/public/tags/cpp17/atom.xml
deleted file mode 100644
index 3e312979..00000000
--- a/vhosts/blog/public/tags/cpp17/atom.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-cpp17</id>
- <title>タグ「C++ 17」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/cpp17/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/cpp17/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2021-10-02T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:69863d75-ef21-42db-b743-5958f7c86827</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2021-10-02/cpp-you-can-use-keywords-in-attributes/"></link>
- <title>【C++】 属性構文の属性名にはキーワードが使える</title>
- <summary>C++ の属性構文の属性名には、キーワードが使える。ネタ記事。</summary>
- <published>2021-10-02T00:00:00+09:00</published>
- <updated>2021-10-02T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/cpp17/index.html b/vhosts/blog/public/tags/cpp17/index.html
deleted file mode 100644
index cc6beb35..00000000
--- a/vhosts/blog/public/tags/cpp17/index.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2021 nsfisis">
- <meta name="description" content="タグ「C++ 17」のついた記事またはスライドの一覧">
- <meta name="keywords" content="C++ 17">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「C++ 17」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「C++ 17」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/cpp17/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「C++ 17」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「C++ 17」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2021-10-02/cpp-you-can-use-keywords-in-attributes/">
- <header class="entry-header">
- <h2>【C++】 属性構文の属性名にはキーワードが使える</h2>
- </header>
- <section class="entry-content">
- <p>
- C++ の属性構文の属性名には、キーワードが使える。ネタ記事。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2021-10-02">2021-10-02</time> 投稿
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/game/atom.xml b/vhosts/blog/public/tags/game/atom.xml
deleted file mode 100644
index eb4dcdd0..00000000
--- a/vhosts/blog/public/tags/game/atom.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-game</id>
- <title>タグ「ゲーム」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/game/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/game/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2025-06-15T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:127019eb-e83f-4c9e-ab54-2021124f1bbb</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-06-14/baba-is-you/"></link>
- <title>最高のパズルゲーム Baba Is You をやれ</title>
- <summary>Baba Is You という最高のパズルゲームをクリアした。是非プレイしてほしい。</summary>
- <published>2025-06-14T00:00:00+09:00</published>
- <updated>2025-06-15T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/game/index.html b/vhosts/blog/public/tags/game/index.html
deleted file mode 100644
index aea82f63..00000000
--- a/vhosts/blog/public/tags/game/index.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2025 nsfisis">
- <meta name="description" content="タグ「ゲーム」のついた記事またはスライドの一覧">
- <meta name="keywords" content="ゲーム">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「ゲーム」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「ゲーム」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/game/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「ゲーム」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「ゲーム」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2025-06-14/baba-is-you/">
- <header class="entry-header">
- <h2>最高のパズルゲーム Baba Is You をやれ</h2>
- </header>
- <section class="entry-content">
- <p>
- Baba Is You という最高のパズルゲームをクリアした。是非プレイしてほしい。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-06-14">2025-06-14</time> 投稿、<time datetime="2025-06-15">2025-06-15</time> 更新
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/gitlab/atom.xml b/vhosts/blog/public/tags/gitlab/atom.xml
deleted file mode 100644
index 20e92403..00000000
--- a/vhosts/blog/public/tags/gitlab/atom.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-gitlab</id>
- <title>タグ「GitLab」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/gitlab/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/gitlab/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2024-04-21T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:a4c326a6-5ffe-450c-abf2-45833c5efb6a</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-04-21/pipefail-option-in-gitlab-ci-cd/"></link>
- <title>【GitLab】 GitLab CI/CD 上での bash/sh は pipefail が有効になっている</title>
- <summary>GitLab CI/CD で bash/sh スクリプトを動かすと、pipefail オプションが有効になった状態で実行される。</summary>
- <published>2024-04-21T00:00:00+09:00</published>
- <updated>2024-04-21T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/gitlab/index.html b/vhosts/blog/public/tags/gitlab/index.html
deleted file mode 100644
index 54654079..00000000
--- a/vhosts/blog/public/tags/gitlab/index.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="タグ「GitLab」のついた記事またはスライドの一覧">
- <meta name="keywords" content="GitLab">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「GitLab」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「GitLab」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/gitlab/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「GitLab」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「GitLab」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2024-04-21/pipefail-option-in-gitlab-ci-cd/">
- <header class="entry-header">
- <h2>【GitLab】 GitLab CI/CD 上での bash/sh は pipefail が有効になっている</h2>
- </header>
- <section class="entry-content">
- <p>
- GitLab CI/CD で bash/sh スクリプトを動かすと、pipefail オプションが有効になった状態で実行される。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-04-21">2024-04-21</time> 投稿
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/go/atom.xml b/vhosts/blog/public/tags/go/atom.xml
deleted file mode 100644
index 286f0583..00000000
--- a/vhosts/blog/public/tags/go/atom.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-go</id>
- <title>タグ「Go」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/go/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/go/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2024-08-19T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:eed112e4-3227-4b3f-9991-7e11c288ee2b</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-08-19/go-template-access-outer-scope-pipeline-within-with-or-range/"></link>
- <title>【Go】 text/template の with や range の内側から外側の &quot;.&quot; にアクセスする</title>
- <summary>Go言語の text/template における with や range は &quot;.&quot; を上書きする。これらの内側から外側の &quot;.&quot; にアクセスする方法を調べた。</summary>
- <published>2024-08-19T00:00:00+09:00</published>
- <updated>2024-08-19T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/go/index.html b/vhosts/blog/public/tags/go/index.html
deleted file mode 100644
index 7add2732..00000000
--- a/vhosts/blog/public/tags/go/index.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="タグ「Go」のついた記事またはスライドの一覧">
- <meta name="keywords" content="Go">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「Go」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「Go」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/go/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「Go」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「Go」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2024-08-19/go-template-access-outer-scope-pipeline-within-with-or-range/">
- <header class="entry-header">
- <h2>【Go】 text/template の with や range の内側から外側の &quot;.&quot; にアクセスする</h2>
- </header>
- <section class="entry-content">
- <p>
- Go言語の text/template における with や range は &quot;.&quot; を上書きする。これらの内側から外側の &quot;.&quot; にアクセスする方法を調べた。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-08-19">2024-08-19</time> 投稿
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/http/atom.xml b/vhosts/blog/public/tags/http/atom.xml
deleted file mode 100644
index 9b7571f1..00000000
--- a/vhosts/blog/public/tags/http/atom.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-http</id>
- <title>タグ「HTTP」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/http/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/http/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2025-03-28T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:046e4412-bee8-4ffe-9876-6cbeaa0caf6b</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-03-28/http-1-1-send-multiple-same-headers/"></link>
- <title>【HTTP】HTTP/1.1 で同じヘッダを2回送るとどうなるか</title>
- <summary>HTTP/1.1 で同じヘッダを2回送ったときの挙動について仕様を読んでまとめた。</summary>
- <published>2025-03-28T00:00:00+09:00</published>
- <updated>2025-03-28T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/http/index.html b/vhosts/blog/public/tags/http/index.html
deleted file mode 100644
index 67776cdf..00000000
--- a/vhosts/blog/public/tags/http/index.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2025 nsfisis">
- <meta name="description" content="タグ「HTTP」のついた記事またはスライドの一覧">
- <meta name="keywords" content="HTTP">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「HTTP」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「HTTP」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/http/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「HTTP」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「HTTP」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2025-03-28/http-1-1-send-multiple-same-headers/">
- <header class="entry-header">
- <h2>【HTTP】HTTP/1.1 で同じヘッダを2回送るとどうなるか</h2>
- </header>
- <section class="entry-content">
- <p>
- HTTP/1.1 で同じヘッダを2回送ったときの挙動について仕様を読んでまとめた。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-03-28">2025-03-28</time> 投稿
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/index.html b/vhosts/blog/public/tags/index.html
deleted file mode 100644
index 73260867..00000000
--- a/vhosts/blog/public/tags/index.html
+++ /dev/null
@@ -1,489 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2021 nsfisis">
- <meta name="description" content="タグの一覧">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/tags/c/">
- <header class="entry-header">
- <h2>C</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/ci-cd/">
- <header class="entry-header">
- <h2>CI/CD</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/cohackpp/">
- <header class="entry-header">
- <h2>紅白ぺぱ合戦</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事、1件のスライド
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/composer/">
- <header class="entry-header">
- <h2>Composer</h2>
- </header>
- <footer class="entry-footer">
- 2件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/conference/">
- <header class="entry-header">
- <h2>カンファレンス</h2>
- </header>
- <footer class="entry-footer">
- 15件の記事、8件のスライド
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/cpp/">
- <header class="entry-header">
- <h2>C++</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/cpp17/">
- <header class="entry-header">
- <h2>C++ 17</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/game/">
- <header class="entry-header">
- <h2>ゲーム</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/gitlab/">
- <header class="entry-header">
- <h2>GitLab</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/go/">
- <header class="entry-header">
- <h2>Go</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/http/">
- <header class="entry-header">
- <h2>HTTP</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/isucon/">
- <header class="entry-header">
- <h2>ISUCON</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/macos/">
- <header class="entry-header">
- <h2>macOS</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/mncore-challenge/">
- <header class="entry-header">
- <h2>MN-Core Challenge</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/neovim/">
- <header class="entry-header">
- <h2>Neovim</h2>
- </header>
- <footer class="entry-footer">
- 2件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/note-to-self/">
- <header class="entry-header">
- <h2>備忘録</h2>
- </header>
- <footer class="entry-footer">
- 3件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/ouj/">
- <header class="entry-header">
- <h2>放送大学</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/perl/">
- <header class="entry-header">
- <h2>Perl</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/php/">
- <header class="entry-header">
- <h2>PHP</h2>
- </header>
- <footer class="entry-footer">
- 21件の記事、21件のスライド
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/phpcon-nagoya/">
- <header class="entry-header">
- <h2>PHP カンファレンス名古屋</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事、1件のスライド
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/phpcon-odawara/">
- <header class="entry-header">
- <h2>PHP カンファレンス小田原</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事、2件のスライド
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/phpconfuk/">
- <header class="entry-header">
- <h2>PHP カンファレンス福岡</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事、1件のスライド
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/phpconkagawa/">
- <header class="entry-header">
- <h2>PHP カンファレンス香川</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/phpconokinawa/">
- <header class="entry-header">
- <h2>PHP カンファレンス沖縄</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/phperkaigi/">
- <header class="entry-header">
- <h2>PHPerKaigi</h2>
- </header>
- <footer class="entry-footer">
- 9件の記事、4件のスライド
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/phpkansai/">
- <header class="entry-header">
- <h2>PHP カンファレンス関西</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/phpstudy-tokyo/">
- <header class="entry-header">
- <h2>PHP 勉強会@東京</h2>
- </header>
- <footer class="entry-footer">
- 12件のスライド
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/piet/">
- <header class="entry-header">
- <h2>Piet</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/python/">
- <header class="entry-header">
- <h2>Python</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/python3/">
- <header class="entry-header">
- <h2>Python 3</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/ruby/">
- <header class="entry-header">
- <h2>Ruby</h2>
- </header>
- <footer class="entry-footer">
- 3件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/ruby3/">
- <header class="entry-header">
- <h2>Ruby 3</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/rubykaigi/">
- <header class="entry-header">
- <h2>RubyKaigi</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/rust/">
- <header class="entry-header">
- <h2>Rust</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/scala/">
- <header class="entry-header">
- <h2>Scala</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/scalamatsuri/">
- <header class="entry-header">
- <h2>ScalaMatsuri</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/trick/">
- <header class="entry-header">
- <h2>TRICK</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/vim/">
- <header class="entry-header">
- <h2>Vim</h2>
- </header>
- <footer class="entry-footer">
- 3件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/wasm/">
- <header class="entry-header">
- <h2>WebAssembly</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事、2件のスライド
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/wireguard/">
- <header class="entry-header">
- <h2>WireGuard</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/ya8/">
- <header class="entry-header">
- <h2>Ya8</h2>
- </header>
- <footer class="entry-footer">
- 1件のスライド
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/yaml/">
- <header class="entry-header">
- <h2>YAML</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/yapc/">
- <header class="entry-header">
- <h2>YAPC</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/tags/zsh/">
- <header class="entry-header">
- <h2>Zsh</h2>
- </header>
- <footer class="entry-footer">
- 1件の記事
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/isucon/atom.xml b/vhosts/blog/public/tags/isucon/atom.xml
deleted file mode 100644
index f66776a4..00000000
--- a/vhosts/blog/public/tags/isucon/atom.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-isucon</id>
- <title>タグ「ISUCON」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/isucon/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/isucon/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2023-12-03T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:d0c404bb-4700-4a6f-9911-621e9872d8c6</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2023-12-03/isucon-13/"></link>
- <title>ISUCON 13 に参加した</title>
- <summary>ISUCON 13 に参加した。チーム名「うつしもゆ」、最終スコア 13,580 点</summary>
- <published>2023-12-03T00:00:00+09:00</published>
- <updated>2023-12-03T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/isucon/index.html b/vhosts/blog/public/tags/isucon/index.html
deleted file mode 100644
index 5d5bdd5e..00000000
--- a/vhosts/blog/public/tags/isucon/index.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2023 nsfisis">
- <meta name="description" content="タグ「ISUCON」のついた記事またはスライドの一覧">
- <meta name="keywords" content="ISUCON">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「ISUCON」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「ISUCON」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/isucon/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「ISUCON」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「ISUCON」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2023-12-03/isucon-13/">
- <header class="entry-header">
- <h2>ISUCON 13 に参加した</h2>
- </header>
- <section class="entry-content">
- <p>
- ISUCON 13 に参加した。チーム名「うつしもゆ」、最終スコア 13,580 点
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-12-03">2023-12-03</time> 投稿
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/macos/atom.xml b/vhosts/blog/public/tags/macos/atom.xml
deleted file mode 100644
index b9c56bba..00000000
--- a/vhosts/blog/public/tags/macos/atom.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-macos</id>
- <title>タグ「macOS」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/macos/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/macos/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2025-04-24T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:087e98f2-743c-48d8-9f67-e9b57e354845</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-04-24/composer-patches-v2-does-not-require-gnu-patch-even-on-macos/"></link>
- <title>【Composer】 composer-patches v2 では macOS でも GNU patch のインストールが不要になる (予定)</title>
- <summary>composer-patches は BSD patch に対応しておらず、一部のパッチの適用に失敗する。現在ベータ版である v2 では patch コマンドに依存しなくなり、macOS で使うときのストレスが解消される見込み。</summary>
- <published>2025-04-24T00:00:00+09:00</published>
- <updated>2025-04-24T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/macos/index.html b/vhosts/blog/public/tags/macos/index.html
deleted file mode 100644
index 93cb9132..00000000
--- a/vhosts/blog/public/tags/macos/index.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2025 nsfisis">
- <meta name="description" content="タグ「macOS」のついた記事またはスライドの一覧">
- <meta name="keywords" content="macOS">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「macOS」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「macOS」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/macos/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「macOS」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「macOS」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2025-04-24/composer-patches-v2-does-not-require-gnu-patch-even-on-macos/">
- <header class="entry-header">
- <h2>【Composer】 composer-patches v2 では macOS でも GNU patch のインストールが不要になる (予定)</h2>
- </header>
- <section class="entry-content">
- <p>
- composer-patches は BSD patch に対応しておらず、一部のパッチの適用に失敗する。現在ベータ版である v2 では patch コマンドに依存しなくなり、macOS で使うときのストレスが解消される見込み。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-04-24">2025-04-24</time> 投稿
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/mncore-challenge/atom.xml b/vhosts/blog/public/tags/mncore-challenge/atom.xml
deleted file mode 100644
index 71a65719..00000000
--- a/vhosts/blog/public/tags/mncore-challenge/atom.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-mncore-challenge</id>
- <title>タグ「MN-Core Challenge」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/mncore-challenge/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/mncore-challenge/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2024-09-28T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:ee7289ee-ff2e-439d-b343-7f87504192fd</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-09-28/mncore-challenge-1/"></link>
- <title>MN-Core Challenge #1 参加レポ</title>
- <summary>2024-08-28 から 2024-09-24 にかけて開催された MN-Core Challenge #1 に参加した。</summary>
- <published>2024-09-28T00:00:00+09:00</published>
- <updated>2024-09-28T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/mncore-challenge/index.html b/vhosts/blog/public/tags/mncore-challenge/index.html
deleted file mode 100644
index 7676d112..00000000
--- a/vhosts/blog/public/tags/mncore-challenge/index.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="タグ「MN-Core Challenge」のついた記事またはスライドの一覧">
- <meta name="keywords" content="MN-Core Challenge">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「MN-Core Challenge」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「MN-Core Challenge」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/mncore-challenge/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「MN-Core Challenge」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「MN-Core Challenge」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2024-09-28/mncore-challenge-1/">
- <header class="entry-header">
- <h2>MN-Core Challenge #1 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2024-08-28 から 2024-09-24 にかけて開催された MN-Core Challenge #1 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-09-28">2024-09-28</time> 投稿
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/neovim/atom.xml b/vhosts/blog/public/tags/neovim/atom.xml
deleted file mode 100644
index b3539419..00000000
--- a/vhosts/blog/public/tags/neovim/atom.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-neovim</id>
- <title>タグ「Neovim」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/neovim/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/neovim/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2024-07-19T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:222488dd-cf07-4961-83aa-a014b05369ff</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-07-19/reparojson-fix-only-json-formatter/"></link>
- <title>reparojson: 文法エラーを直すだけの JSON フォーマッタを作った</title>
- <summary>文法エラーだけを直し、空白の削除や挿入といった整形処理を一切おこなわない JSON フォーマッタを作成した。Neovim と連携させる設定例も紹介する。</summary>
- <published>2024-07-19T00:00:00+09:00</published>
- <updated>2024-07-19T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:05cb16e1-05bc-4359-bc06-88ac20510740</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-01-10/neovim-insert-namespace-declaration-to-empty-php-file/"></link>
- <title>【Neovim】 空の PHP ファイルに namespace 宣言を挿入する</title>
- <summary>Neovim で空の PHP ファイルを開いたとき、ディレクトリの構造に基づいて自動的に namespace 宣言を挿入するようにする。</summary>
- <published>2024-01-10T00:00:00+09:00</published>
- <updated>2024-01-10T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/neovim/index.html b/vhosts/blog/public/tags/neovim/index.html
deleted file mode 100644
index ea1cebdc..00000000
--- a/vhosts/blog/public/tags/neovim/index.html
+++ /dev/null
@@ -1,81 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="タグ「Neovim」のついた記事またはスライドの一覧">
- <meta name="keywords" content="Neovim">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「Neovim」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「Neovim」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/neovim/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「Neovim」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「Neovim」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2024-07-19/reparojson-fix-only-json-formatter/">
- <header class="entry-header">
- <h2>reparojson: 文法エラーを直すだけの JSON フォーマッタを作った</h2>
- </header>
- <section class="entry-content">
- <p>
- 文法エラーだけを直し、空白の削除や挿入といった整形処理を一切おこなわない JSON フォーマッタを作成した。Neovim と連携させる設定例も紹介する。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-07-19">2024-07-19</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2024-01-10/neovim-insert-namespace-declaration-to-empty-php-file/">
- <header class="entry-header">
- <h2>【Neovim】 空の PHP ファイルに namespace 宣言を挿入する</h2>
- </header>
- <section class="entry-content">
- <p>
- Neovim で空の PHP ファイルを開いたとき、ディレクトリの構造に基づいて自動的に namespace 宣言を挿入するようにする。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-01-10">2024-01-10</time> 投稿
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/note-to-self/atom.xml b/vhosts/blog/public/tags/note-to-self/atom.xml
deleted file mode 100644
index 7c1fe6d4..00000000
--- a/vhosts/blog/public/tags/note-to-self/atom.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-note-to-self</id>
- <title>タグ「備忘録」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/note-to-self/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/note-to-self/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2025-03-27T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:99111377-27e7-427b-9dc5-a23f621fa826</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-03-27/zip-function-like-command-paste-command/"></link>
- <title>zip 関数のようなコマンド paste</title>
- <summary>zip 関数のような動きをする paste コマンドについてのメモ。</summary>
- <published>2025-03-27T00:00:00+09:00</published>
- <updated>2025-03-27T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:210673d0-c19e-4195-a280-968a0729dd41</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-02-03/install-wireguard-on-personal-server/"></link>
- <title>【備忘録】 個人用サーバに WireGuard を導入する</title>
- <summary>個人用サービスのセルフホストに使っているサーバに WireGuard を導入する作業をしたメモ</summary>
- <published>2024-02-03T00:00:00+09:00</published>
- <updated>2024-02-17T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:673cb872-af2d-41a3-9fb0-60f1afcedb0d</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-10-28/setup-server-for-this-site/"></link>
- <title>【備忘録】 このサイト用の VPS をセットアップしたときのメモ</title>
- <summary>GitHub Pages でホストしていたこのサイトを VPS へ移行したので、そのときにやったことのメモ。99 % 自分用。</summary>
- <published>2022-10-28T00:00:00+09:00</published>
- <updated>2023-08-30T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/note-to-self/index.html b/vhosts/blog/public/tags/note-to-self/index.html
deleted file mode 100644
index 7c4ca73d..00000000
--- a/vhosts/blog/public/tags/note-to-self/index.html
+++ /dev/null
@@ -1,96 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2022 nsfisis">
- <meta name="description" content="タグ「備忘録」のついた記事またはスライドの一覧">
- <meta name="keywords" content="備忘録">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「備忘録」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「備忘録」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/note-to-self/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「備忘録」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「備忘録」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2025-03-27/zip-function-like-command-paste-command/">
- <header class="entry-header">
- <h2>zip 関数のようなコマンド paste</h2>
- </header>
- <section class="entry-content">
- <p>
- zip 関数のような動きをする paste コマンドについてのメモ。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-03-27">2025-03-27</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2024-02-03/install-wireguard-on-personal-server/">
- <header class="entry-header">
- <h2>【備忘録】 個人用サーバに WireGuard を導入する</h2>
- </header>
- <section class="entry-content">
- <p>
- 個人用サービスのセルフホストに使っているサーバに WireGuard を導入する作業をしたメモ
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-02-03">2024-02-03</time> 投稿、<time datetime="2024-02-17">2024-02-17</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2022-10-28/setup-server-for-this-site/">
- <header class="entry-header">
- <h2>【備忘録】 このサイト用の VPS をセットアップしたときのメモ</h2>
- </header>
- <section class="entry-content">
- <p>
- GitHub Pages でホストしていたこのサイトを VPS へ移行したので、そのときにやったことのメモ。99 % 自分用。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2022-10-28">2022-10-28</time> 投稿、<time datetime="2023-08-30">2023-08-30</time> 更新
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/ouj/atom.xml b/vhosts/blog/public/tags/ouj/atom.xml
deleted file mode 100644
index 8a8a3306..00000000
--- a/vhosts/blog/public/tags/ouj/atom.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-ouj</id>
- <title>タグ「放送大学」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/ouj/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/ouj/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2023-10-13T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:78419bf2-a1e6-421f-875b-3d93e777b04f</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2023-10-13/i-entered-the-open-university-of-japan/"></link>
- <title>放送大学に入学しました</title>
- <summary>放送大学に入学しました。頑張ります。</summary>
- <published>2023-10-13T00:00:00+09:00</published>
- <updated>2023-10-13T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/ouj/index.html b/vhosts/blog/public/tags/ouj/index.html
deleted file mode 100644
index 3e76b482..00000000
--- a/vhosts/blog/public/tags/ouj/index.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2023 nsfisis">
- <meta name="description" content="タグ「放送大学」のついた記事またはスライドの一覧">
- <meta name="keywords" content="放送大学">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「放送大学」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「放送大学」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/ouj/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「放送大学」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「放送大学」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2023-10-13/i-entered-the-open-university-of-japan/">
- <header class="entry-header">
- <h2>放送大学に入学しました</h2>
- </header>
- <section class="entry-content">
- <p>
- 放送大学に入学しました。頑張ります。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-10-13">2023-10-13</time> 投稿
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/perl/atom.xml b/vhosts/blog/public/tags/perl/atom.xml
deleted file mode 100644
index b0f8e0df..00000000
--- a/vhosts/blog/public/tags/perl/atom.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-perl</id>
- <title>タグ「Perl」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/perl/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/perl/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2024-02-10T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:230a0048-93c0-4aac-91ef-bb3108f3e587</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-02-10/yapcjapan-2024-report/"></link>
- <title>YAPC::Hiroshima 2024 参加レポ</title>
- <summary>2024-02-10 に開催された、YAPC::Hiroshima 2024 に参加した。</summary>
- <published>2024-02-10T00:00:00+09:00</published>
- <updated>2024-02-10T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/perl/index.html b/vhosts/blog/public/tags/perl/index.html
deleted file mode 100644
index 8865fee9..00000000
--- a/vhosts/blog/public/tags/perl/index.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="タグ「Perl」のついた記事またはスライドの一覧">
- <meta name="keywords" content="Perl">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「Perl」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「Perl」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/perl/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「Perl」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「Perl」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2024-02-10/yapcjapan-2024-report/">
- <header class="entry-header">
- <h2>YAPC::Hiroshima 2024 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2024-02-10 に開催された、YAPC::Hiroshima 2024 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-02-10">2024-02-10</time> 投稿
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/php/atom.xml b/vhosts/blog/public/tags/php/atom.xml
deleted file mode 100644
index efcb52db..00000000
--- a/vhosts/blog/public/tags/php/atom.xml
+++ /dev/null
@@ -1,347 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-php</id>
- <title>タグ「PHP」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/php/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/php/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2025-04-24T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:087e98f2-743c-48d8-9f67-e9b57e354845</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-04-24/composer-patches-v2-does-not-require-gnu-patch-even-on-macos/"></link>
- <title>【Composer】 composer-patches v2 では macOS でも GNU patch のインストールが不要になる (予定)</title>
- <summary>composer-patches は BSD patch に対応しておらず、一部のパッチの適用に失敗する。現在ベータ版である v2 では patch コマンドに依存しなくなり、macOS で使うときのストレスが解消される見込み。</summary>
- <published>2025-04-24T00:00:00+09:00</published>
- <updated>2025-04-24T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:c6c7c241-46c1-44b5-95b2-c30c3a500df3</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2025-04-12/phpcon-odawara-2025/"></link>
- <title>PHP 8.x 時代のクラス設計(property promotion から property hooks まで)</title>
- <summary>登壇: PHP カンファレンス小田原 2025 (レギュラートーク (20分))</summary>
- <published>2025-04-12T00:00:00+09:00</published>
- <updated>2025-04-12T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:ec7f4462-ae56-4bbf-aac7-cbd32bbbeb29</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2025-03-23/phperkaigi-2025/"></link>
- <title>PHPで作るPHP~セルフホストできる言語処理系を作ろう~</title>
- <summary>登壇: PHPerKaigi 2025 (レギュラートーク (40分))</summary>
- <published>2025-03-23T00:00:00+09:00</published>
- <updated>2025-03-23T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:13174dc7-c1a3-465f-9ba6-14f0bc6f5961</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-02-24/phpcon-nagoya-2025-report/"></link>
- <title>PHP カンファレンス名古屋 2025 参加レポ</title>
- <summary>2025-02-22 に開催された、PHP カンファレンス名古屋 2025 に参加した。</summary>
- <published>2025-02-24T00:00:00+09:00</published>
- <updated>2025-02-24T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:9172fbef-c812-4ade-86f5-eaa12c966708</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2025-02-22/phpcon-nagoya-2025/"></link>
- <title>PHP 処理系の garbage collection を理解する~メモリはいつ解放されるのか~</title>
- <summary>登壇: PHP カンファレンス名古屋 2025 (レギュラートーク (30分))</summary>
- <published>2025-02-22T00:00:00+09:00</published>
- <updated>2025-02-22T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:ce8f20e8-c79f-48f8-982d-53edd4d20483</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-01-08/phperkaigi-2023-tokens-q1/"></link>
- <title>PHPerKaigi 2023 トークン問題解説 (1/5)</title>
- <summary>PHPerKaigi 2023 でデジタルサーカス株式会社から出題した問題を解説する。全5問中の第1問。</summary>
- <published>2025-01-08T00:00:00+09:00</published>
- <updated>2025-01-11T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:ea0593d3-691c-4e08-8db4-98b8925717ec</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-12-04/cohackpp-report/"></link>
- <title>紅白ぺぱ合戦に参加&amp;LTしました</title>
- <summary>2024-11-30 に開催された紅白ぺぱ合戦に参加し、ぺ陣営のメンバとして LT しました。</summary>
- <published>2024-12-04T00:00:00+09:00</published>
- <updated>2024-12-05T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:e1ca4664-f6f1-4de2-b4a5-ea2b64006708</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-11-30/cohackpp/"></link>
- <title>プログラミングマナー講座</title>
- <summary>登壇: 紅白ぺぱ合戦 (LT)</summary>
- <published>2024-11-30T00:00:00+09:00</published>
- <updated>2024-11-30T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:a84100cf-8c92-4856-addf-81a7c5547074</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-10-30/phpstudy-tokyo-169/"></link>
- <title>PHP で PHP を作る (縮小版)</title>
- <summary>登壇: PHP 勉強会@東京 第169回 (レギュラートーク (20分))</summary>
- <published>2024-10-30T00:00:00+09:00</published>
- <updated>2024-10-30T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:eec495b5-45e2-4c6f-a725-e62b1e0a7ad5</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-07-18/phpstudy-tokyo-166/"></link>
- <title>PHPerKaigi 2024 で発表した WebAssembly ランタイムのその後</title>
- <summary>登壇: PHP 勉強会@東京 第166回 (レギュラートーク (20分))</summary>
- <published>2024-07-18T00:00:00+09:00</published>
- <updated>2024-07-18T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:f13aa9d6-4533-4a15-872a-c298ab2090db</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-05-11/phpconkagawa-2024-report/"></link>
- <title>PHP カンファレンス香川 2024 参加レポ</title>
- <summary>2024-05-11 に開催された、PHP カンファレンス香川 2024 に参加した。</summary>
- <published>2024-05-11T00:00:00+09:00</published>
- <updated>2024-05-11T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:9b26c1ed-45c3-4cad-9476-cbf2cf2e4de7</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-04-29/zsh-file-completion-for-composer-custom-commands/"></link>
- <title>【Zsh】 Composer のカスタムコマンドに対する Zsh 補完で引数にファイルを補完させる</title>
- <summary>Zsh の Composer に対する補完はカスタムコマンドやその引数を補完しない。カスタムコマンドの引数としてファイルを補完させる方法を調べた。</summary>
- <published>2024-04-29T00:00:00+09:00</published>
- <updated>2024-04-29T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:6cf84106-cc69-4d87-b957-9d58d7e585bb</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-04-25/phpstudy-tokyo-163/"></link>
- <title>Tracing JIT の発動条件</title>
- <summary>登壇: PHP 勉強会@東京 第163回 (LT)</summary>
- <published>2024-04-25T00:00:00+09:00</published>
- <updated>2024-04-25T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:be9c896d-7efa-42dd-a50a-dda5fd3a7f5c</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-04-14/phpcon-odawara-2024-report/"></link>
- <title>PHP カンファレンス小田原 2024 参加レポ</title>
- <summary>2024-04-13 に開催された、PHP カンファレンス小田原 2024 に参加した。</summary>
- <published>2024-04-14T00:00:00+09:00</published>
- <updated>2024-06-01T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:69e1694b-5ddb-41a5-a7f4-138ce82a78b2</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-04-13/phpcon-odawara-2024/"></link>
- <title>来る新 JIT エンジンについて知った気になる</title>
- <summary>登壇: PHP カンファレンス小田原 2024 (レギュラートーク (15分))</summary>
- <published>2024-04-13T00:00:00+09:00</published>
- <updated>2024-04-13T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:750be5c8-ca52-4cbd-86fe-5645b06bde95</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-03-17/phperkaigi-2024-report/"></link>
- <title>PHPerKaigi 2024 参加レポ</title>
- <summary>2024-03-07 から 2024-03-09 にかけて開催された、PHPerKaigi 2024 に参加した。</summary>
- <published>2024-03-17T00:00:00+09:00</published>
- <updated>2024-07-07T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:cee40048-f3c5-4043-9ef8-a4ee2ae7cf0e</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-03-08/phperkaigi-2024/"></link>
- <title>WebAssembly を理解する 〜VM の作成を通して〜</title>
- <summary>登壇: PHPerKaigi 2024 (レギュラートーク (40分))</summary>
- <published>2024-03-08T00:00:00+09:00</published>
- <updated>2024-03-08T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:fd8fcb03-8e4d-4ca7-8499-0674accc51a9</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-02-22/phpkansai-2024-report/"></link>
- <title>PHPカンファレンス関西 2024 参加レポ</title>
- <summary>2024-02-11 に開催された、PHPカンファレンス関西 2024 に参加した。</summary>
- <published>2024-02-21T00:00:00+09:00</published>
- <updated>2024-02-21T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:82db7893-983a-4631-8bee-d0725d078252</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-01-24/phpstudy-tokyo-160/"></link>
- <title>PHPStan の力で Algebraic Data Types を実現する</title>
- <summary>登壇: PHP 勉強会@東京 第160 回 (レギュラートーク)</summary>
- <published>2024-01-24T00:00:00+09:00</published>
- <updated>2024-01-24T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:05cb16e1-05bc-4359-bc06-88ac20510740</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-01-10/neovim-insert-namespace-declaration-to-empty-php-file/"></link>
- <title>【Neovim】 空の PHP ファイルに namespace 宣言を挿入する</title>
- <summary>Neovim で空の PHP ファイルを開いたとき、ディレクトリの構造に基づいて自動的に namespace 宣言を挿入するようにする。</summary>
- <published>2024-01-10T00:00:00+09:00</published>
- <updated>2024-01-10T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:6c377f3f-6f52-4074-b690-c79d02050562</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-10-25/phpstudy-tokyo-157/"></link>
- <title>PHP コードを隔離された環境で安全に動かす (on WebAssembly)</title>
- <summary>登壇: PHP 勉強会@東京 第157 回 (LT)</summary>
- <published>2023-10-25T00:00:00+09:00</published>
- <updated>2023-10-25T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:0ed1ccc8-d437-481c-8cca-2131ce800cc0</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2023-10-02/compile-php-runtime-to-wasm/"></link>
- <title>PHP の処理系を Emscripten で WebAssembly にコンパイルする</title>
- <summary>PHP の処理系 (php/php-src) を Emscripten で WebAssembly にコンパイルし、任意のコードを隔離された環境で評価できるようにした。</summary>
- <published>2023-10-02T00:00:00+09:00</published>
- <updated>2025-04-23T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:d6118e00-5fb1-4230-9d94-854260beae04</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-08-24/phpstudy-tokyo-155/"></link>
- <title>PHP 3.0 の処理系のソースを読んでみる</title>
- <summary>登壇: PHP 勉強会@東京 第155 回 (LT)</summary>
- <published>2023-08-24T00:00:00+09:00</published>
- <updated>2023-08-24T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:669de08d-9e02-44c5-ac3f-35972112e706</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-07-26/phpstudy-tokyo-154/"></link>
- <title>言語間で比較するエラーの通知と処理</title>
- <summary>登壇: PHP 勉強会@東京 第154 回 (レギュラートーク)</summary>
- <published>2023-07-26T00:00:00+09:00</published>
- <updated>2023-07-26T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:e1568c4c-9bdd-47b9-8b39-939ade4f3ba0</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2023-06-25/phpconfuk-2023-report/"></link>
- <title>PHP カンファレンス福岡 2023 参加レポ</title>
- <summary>2023-06-24 に開催された、PHP カンファレンス福岡に参加した。</summary>
- <published>2023-06-25T00:00:00+09:00</published>
- <updated>2023-06-25T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:72244d87-4cf0-41c4-a074-bcc37acaa678</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-06-23/phpconfuk-2023-eve/"></link>
- <title>巨大なコードベースへ突撃するために</title>
- <summary>登壇: PHP カンファレンス福岡 2023 前夜祭 (非公式) (レギュラートーク)</summary>
- <published>2023-06-23T00:00:00+09:00</published>
- <updated>2023-06-23T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:6016d501-b9c9-474a-a304-1ec1295e049a</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-06-21/phpstudy-tokyo-153/"></link>
- <title>テキストファイルの末尾には改行コードを入れよう</title>
- <summary>登壇: PHP 勉強会@東京 第153 回 (LT)</summary>
- <published>2023-06-21T00:00:00+09:00</published>
- <updated>2023-06-21T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:fe75bb63-1cd9-457e-8244-c444307cd40a</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-04-12/phpstudy-tokyo-151/"></link>
- <title>list でない array の末尾を探す</title>
- <summary>登壇: PHP 勉強会@東京 第151 回 (LT)</summary>
- <published>2023-04-12T00:00:00+09:00</published>
- <updated>2023-04-12T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:21ce39f0-d613-45f2-a760-89c368892d77</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2023-04-04/phperkaigi-2023-report/"></link>
- <title>PHPerKaigi 2023 参加レポ</title>
- <summary>2023-03-23 から 2023-03-25 にかけて開催された、PHPerKaigi 2023 に参加した。</summary>
- <published>2023-04-04T00:00:00+09:00</published>
- <updated>2023-06-28T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:3cce70d8-cee9-4e0e-8b38-6ef1e0a8a278</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-03-25/phperkaigi-2023-tokens/"></link>
- <title>PHPer チャレンジ解説 (デジタルサーカス株式会社)</title>
- <summary>登壇: PHPerKaigi 2023 (トークン解説セッション)</summary>
- <published>2023-03-25T00:00:00+09:00</published>
- <updated>2023-03-25T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:2dce7e27-1eaf-4ca4-8037-e9a3ead18b48</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-03-24/phperkaigi-2023/"></link>
- <title>詳説「参照」PHP の参照を完全に理解する</title>
- <summary>登壇: PHPerKaigi 2023 (レギュラートーク)</summary>
- <published>2023-03-24T00:00:00+09:00</published>
- <updated>2023-03-24T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:9376560b-250a-4697-ac10-0903ad16acee</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-03-15/phpstudy-tokyo-150/"></link>
- <title>明日のあなたの役に立たない PHP コーディング技法~細長い FizzBuzz を書く~</title>
- <summary>登壇: PHP 勉強会@東京 第150 回 (LT)</summary>
- <published>2023-03-15T00:00:00+09:00</published>
- <updated>2023-03-18T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:f23ea81c-5996-4b7e-aab0-4e9f23b172c2</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-02-15/phpstudy-tokyo-149/"></link>
- <title>PHPerKaigi 2023 のトークン問題でボツにした問題を供養する</title>
- <summary>登壇: PHP 勉強会@東京 第149 回 (LT)</summary>
- <published>2023-02-15T00:00:00+09:00</published>
- <updated>2023-02-15T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:693a4c2e-6f21-4840-b793-4e3644a8ec22</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-01-18/phpstudy-tokyo-148/"></link>
- <title>明日のあなたの役に立たない PHP コーディング技法~polyglot~</title>
- <summary>登壇: PHP 勉強会@東京 第148 回 (LT)</summary>
- <published>2023-01-18T00:00:00+09:00</published>
- <updated>2023-01-18T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:89722cfb-7f4b-4e96-80bc-e0096e5eeef6</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2023-01-10/phperkaigi-2023-unused-token-quiz-3/"></link>
- <title>PHPerKaigi 2023: ボツになったトークン問題 その 3</title>
- <summary>来年の PHPerKaigi 2023 でデジタルサーカス株式会社から出題予定のトークン問題のうち、ボツになった問題を公開する (その 3)。</summary>
- <published>2023-01-10T00:00:00+09:00</published>
- <updated>2023-01-10T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:10fe9c47-7029-4874-82bd-b4dc50e07809</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-11-19/phperkaigi-2023-unused-token-quiz-2/"></link>
- <title>PHPerKaigi 2023: ボツになったトークン問題 その 2</title>
- <summary>来年の PHPerKaigi 2023 でデジタルサーカス株式会社から出題予定のトークン問題のうち、ボツになった問題を公開する (その 2)。</summary>
- <published>2022-11-19T00:00:00+09:00</published>
- <updated>2022-11-19T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:46e0d5db-b17e-464c-a723-8c3e01af7d1d</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-10-23/phperkaigi-2023-unused-token-quiz-1/"></link>
- <title>PHPerKaigi 2023: ボツになったトークン問題 その 1</title>
- <summary>来年の PHPerKaigi 2023 でデジタルサーカス株式会社から出題予定のトークン問題のうち、ボツになった問題を公開する (その 1)。</summary>
- <published>2022-10-23T00:00:00+09:00</published>
- <updated>2022-10-23T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:42f0b29b-1e44-4dbe-9864-69abe3bb1e6e</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-09-29/write-fizzbuzz-in-php-2-letters-per-line/"></link>
- <title>【PHP】 fizzbuzz を書く。1行あたり2文字で。</title>
- <summary>PHP で fizzbuzz を書いた。ただし、1行あたりに使える文字数は2文字まで。</summary>
- <published>2022-09-28T00:00:00+09:00</published>
- <updated>2022-09-29T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:bb71bb5d-361b-44cb-9753-81d14583d860</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-08-27/php-conference-okinawa-code-golf/"></link>
- <title>PHP カンファレンス沖縄で出題されたコードゴルフの問題を解いてみた</title>
- <summary>PHP カンファレンス沖縄の懇親会 LT で出題されたコードゴルフの問題を解いてみた。</summary>
- <published>2022-08-27T00:00:00+09:00</published>
- <updated>2022-08-27T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:9211e1fe-bca3-43c4-ba4e-c67d62f3fed0</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-05-01/phperkaigi-2022/"></link>
- <title>PHPerKaigi 2022</title>
- <summary>2022-04-09 から 2022-04-11 にかけて開催された、PHPerKaigi 2022 に参加した。</summary>
- <published>2022-05-01T00:00:00+09:00</published>
- <updated>2022-05-01T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:f4985d54-0907-4449-8101-0fcd382f9e02</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-04-09/phperkaigi-2022-tokens/"></link>
- <title>PHPerKaigi 2022 トークン問題の解説</title>
- <summary>PHPerKaigi 2022 で私が作成した PHPer チャレンジ問題を解説する。</summary>
- <published>2022-04-09T00:00:00+09:00</published>
- <updated>2022-04-16T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:3fbe0b8c-216e-48f6-b905-c0d361b94542</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2021-03-30/phperkaigi-2021/"></link>
- <title>PHPerKaigi 2021</title>
- <summary>2021-03-26 から 2021-03-28 にかけて開催された、PHPerKaigi 2021 に参加した。</summary>
- <published>2021-03-30T00:00:00+09:00</published>
- <updated>2025-04-09T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/php/index.html b/vhosts/blog/public/tags/php/index.html
deleted file mode 100644
index cfb41078..00000000
--- a/vhosts/blog/public/tags/php/index.html
+++ /dev/null
@@ -1,681 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2021 nsfisis">
- <meta name="description" content="タグ「PHP」のついた記事またはスライドの一覧">
- <meta name="keywords" content="PHP">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「PHP」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「PHP」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/php/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「PHP」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「PHP」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2025-04-24/composer-patches-v2-does-not-require-gnu-patch-even-on-macos/">
- <header class="entry-header">
- <h2>【Composer】 composer-patches v2 では macOS でも GNU patch のインストールが不要になる (予定)</h2>
- </header>
- <section class="entry-content">
- <p>
- composer-patches は BSD patch に対応しておらず、一部のパッチの適用に失敗する。現在ベータ版である v2 では patch コマンドに依存しなくなり、macOS で使うときのストレスが解消される見込み。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-04-24">2025-04-24</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2025-04-12/phpcon-odawara-2025/">
- <header class="entry-header">
- <h2>登壇: PHP カンファレンス小田原 2025 (レギュラートーク (20分))</h2>
- </header>
- <section class="entry-content">
- <p>
- PHP 8.x 時代のクラス設計(property promotion から property hooks まで)
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-04-12">2025-04-12</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2025-03-23/phperkaigi-2025/">
- <header class="entry-header">
- <h2>登壇: PHPerKaigi 2025 (レギュラートーク (40分))</h2>
- </header>
- <section class="entry-content">
- <p>
- PHPで作るPHP~セルフホストできる言語処理系を作ろう~
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-03-23">2025-03-23</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2025-02-24/phpcon-nagoya-2025-report/">
- <header class="entry-header">
- <h2>PHP カンファレンス名古屋 2025 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2025-02-22 に開催された、PHP カンファレンス名古屋 2025 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-02-24">2025-02-24</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2025-02-22/phpcon-nagoya-2025/">
- <header class="entry-header">
- <h2>登壇: PHP カンファレンス名古屋 2025 (レギュラートーク (30分))</h2>
- </header>
- <section class="entry-content">
- <p>
- PHP 処理系の garbage collection を理解する~メモリはいつ解放されるのか~
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-02-22">2025-02-22</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2025-01-08/phperkaigi-2023-tokens-q1/">
- <header class="entry-header">
- <h2>PHPerKaigi 2023 トークン問題解説 (1/5)</h2>
- </header>
- <section class="entry-content">
- <p>
- PHPerKaigi 2023 でデジタルサーカス株式会社から出題した問題を解説する。全5問中の第1問。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-01-08">2025-01-08</time> 投稿、<time datetime="2025-01-11">2025-01-11</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2024-12-04/cohackpp-report/">
- <header class="entry-header">
- <h2>紅白ぺぱ合戦に参加&amp;LTしました</h2>
- </header>
- <section class="entry-content">
- <p>
- 2024-11-30 に開催された紅白ぺぱ合戦に参加し、ぺ陣営のメンバとして LT しました。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-12-04">2024-12-04</time> 投稿、<time datetime="2024-12-05">2024-12-05</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2024-11-30/cohackpp/">
- <header class="entry-header">
- <h2>登壇: 紅白ぺぱ合戦 (LT)</h2>
- </header>
- <section class="entry-content">
- <p>
- プログラミングマナー講座
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-11-30">2024-11-30</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2024-10-30/phpstudy-tokyo-169/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第169回 (レギュラートーク (20分))</h2>
- </header>
- <section class="entry-content">
- <p>
- PHP で PHP を作る (縮小版)
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-10-30">2024-10-30</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2024-07-18/phpstudy-tokyo-166/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第166回 (レギュラートーク (20分))</h2>
- </header>
- <section class="entry-content">
- <p>
- PHPerKaigi 2024 で発表した WebAssembly ランタイムのその後
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-07-18">2024-07-18</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2024-05-11/phpconkagawa-2024-report/">
- <header class="entry-header">
- <h2>PHP カンファレンス香川 2024 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2024-05-11 に開催された、PHP カンファレンス香川 2024 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-05-11">2024-05-11</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2024-04-29/zsh-file-completion-for-composer-custom-commands/">
- <header class="entry-header">
- <h2>【Zsh】 Composer のカスタムコマンドに対する Zsh 補完で引数にファイルを補完させる</h2>
- </header>
- <section class="entry-content">
- <p>
- Zsh の Composer に対する補完はカスタムコマンドやその引数を補完しない。カスタムコマンドの引数としてファイルを補完させる方法を調べた。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-04-29">2024-04-29</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2024-04-25/phpstudy-tokyo-163/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第163回 (LT)</h2>
- </header>
- <section class="entry-content">
- <p>
- Tracing JIT の発動条件
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-04-25">2024-04-25</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2024-04-14/phpcon-odawara-2024-report/">
- <header class="entry-header">
- <h2>PHP カンファレンス小田原 2024 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2024-04-13 に開催された、PHP カンファレンス小田原 2024 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-04-14">2024-04-14</time> 投稿、<time datetime="2024-06-01">2024-06-01</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2024-04-13/phpcon-odawara-2024/">
- <header class="entry-header">
- <h2>登壇: PHP カンファレンス小田原 2024 (レギュラートーク (15分))</h2>
- </header>
- <section class="entry-content">
- <p>
- 来る新 JIT エンジンについて知った気になる
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-04-13">2024-04-13</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2024-03-17/phperkaigi-2024-report/">
- <header class="entry-header">
- <h2>PHPerKaigi 2024 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2024-03-07 から 2024-03-09 にかけて開催された、PHPerKaigi 2024 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-03-17">2024-03-17</time> 投稿、<time datetime="2024-07-07">2024-07-07</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2024-03-08/phperkaigi-2024/">
- <header class="entry-header">
- <h2>登壇: PHPerKaigi 2024 (レギュラートーク (40分))</h2>
- </header>
- <section class="entry-content">
- <p>
- WebAssembly を理解する 〜VM の作成を通して〜
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-03-08">2024-03-08</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2024-02-22/phpkansai-2024-report/">
- <header class="entry-header">
- <h2>PHPカンファレンス関西 2024 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2024-02-11 に開催された、PHPカンファレンス関西 2024 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-02-21">2024-02-21</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2024-01-24/phpstudy-tokyo-160/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第160 回 (レギュラートーク)</h2>
- </header>
- <section class="entry-content">
- <p>
- PHPStan の力で Algebraic Data Types を実現する
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-01-24">2024-01-24</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2024-01-10/neovim-insert-namespace-declaration-to-empty-php-file/">
- <header class="entry-header">
- <h2>【Neovim】 空の PHP ファイルに namespace 宣言を挿入する</h2>
- </header>
- <section class="entry-content">
- <p>
- Neovim で空の PHP ファイルを開いたとき、ディレクトリの構造に基づいて自動的に namespace 宣言を挿入するようにする。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-01-10">2024-01-10</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-10-25/phpstudy-tokyo-157/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第157 回 (LT)</h2>
- </header>
- <section class="entry-content">
- <p>
- PHP コードを隔離された環境で安全に動かす (on WebAssembly)
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-10-25">2023-10-25</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2023-10-02/compile-php-runtime-to-wasm/">
- <header class="entry-header">
- <h2>PHP の処理系を Emscripten で WebAssembly にコンパイルする</h2>
- </header>
- <section class="entry-content">
- <p>
- PHP の処理系 (php/php-src) を Emscripten で WebAssembly にコンパイルし、任意のコードを隔離された環境で評価できるようにした。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-10-02">2023-10-02</time> 投稿、<time datetime="2025-04-23">2025-04-23</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-08-24/phpstudy-tokyo-155/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第155 回 (LT)</h2>
- </header>
- <section class="entry-content">
- <p>
- PHP 3.0 の処理系のソースを読んでみる
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-08-24">2023-08-24</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-07-26/phpstudy-tokyo-154/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第154 回 (レギュラートーク)</h2>
- </header>
- <section class="entry-content">
- <p>
- 言語間で比較するエラーの通知と処理
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-07-26">2023-07-26</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2023-06-25/phpconfuk-2023-report/">
- <header class="entry-header">
- <h2>PHP カンファレンス福岡 2023 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2023-06-24 に開催された、PHP カンファレンス福岡に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-06-25">2023-06-25</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-06-23/phpconfuk-2023-eve/">
- <header class="entry-header">
- <h2>登壇: PHP カンファレンス福岡 2023 前夜祭 (非公式) (レギュラートーク)</h2>
- </header>
- <section class="entry-content">
- <p>
- 巨大なコードベースへ突撃するために
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-06-23">2023-06-23</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-06-21/phpstudy-tokyo-153/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第153 回 (LT)</h2>
- </header>
- <section class="entry-content">
- <p>
- テキストファイルの末尾には改行コードを入れよう
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-06-21">2023-06-21</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-04-12/phpstudy-tokyo-151/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第151 回 (LT)</h2>
- </header>
- <section class="entry-content">
- <p>
- list でない array の末尾を探す
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-04-12">2023-04-12</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2023-04-04/phperkaigi-2023-report/">
- <header class="entry-header">
- <h2>PHPerKaigi 2023 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2023-03-23 から 2023-03-25 にかけて開催された、PHPerKaigi 2023 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-04-04">2023-04-04</time> 投稿、<time datetime="2023-06-28">2023-06-28</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-03-25/phperkaigi-2023-tokens/">
- <header class="entry-header">
- <h2>登壇: PHPerKaigi 2023 (トークン解説セッション)</h2>
- </header>
- <section class="entry-content">
- <p>
- PHPer チャレンジ解説 (デジタルサーカス株式会社)
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-03-25">2023-03-25</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-03-24/phperkaigi-2023/">
- <header class="entry-header">
- <h2>登壇: PHPerKaigi 2023 (レギュラートーク)</h2>
- </header>
- <section class="entry-content">
- <p>
- 詳説「参照」PHP の参照を完全に理解する
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-03-24">2023-03-24</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-03-15/phpstudy-tokyo-150/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第150 回 (LT)</h2>
- </header>
- <section class="entry-content">
- <p>
- 明日のあなたの役に立たない PHP コーディング技法~細長い FizzBuzz を書く~
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-03-15">2023-03-15</time> 登壇、<time datetime="2023-03-18">2023-03-18</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-02-15/phpstudy-tokyo-149/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第149 回 (LT)</h2>
- </header>
- <section class="entry-content">
- <p>
- PHPerKaigi 2023 のトークン問題でボツにした問題を供養する
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-02-15">2023-02-15</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-01-18/phpstudy-tokyo-148/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第148 回 (LT)</h2>
- </header>
- <section class="entry-content">
- <p>
- 明日のあなたの役に立たない PHP コーディング技法~polyglot~
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-01-18">2023-01-18</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2023-01-10/phperkaigi-2023-unused-token-quiz-3/">
- <header class="entry-header">
- <h2>PHPerKaigi 2023: ボツになったトークン問題 その 3</h2>
- </header>
- <section class="entry-content">
- <p>
- 来年の PHPerKaigi 2023 でデジタルサーカス株式会社から出題予定のトークン問題のうち、ボツになった問題を公開する (その 3)。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-01-10">2023-01-10</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2022-11-19/phperkaigi-2023-unused-token-quiz-2/">
- <header class="entry-header">
- <h2>PHPerKaigi 2023: ボツになったトークン問題 その 2</h2>
- </header>
- <section class="entry-content">
- <p>
- 来年の PHPerKaigi 2023 でデジタルサーカス株式会社から出題予定のトークン問題のうち、ボツになった問題を公開する (その 2)。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2022-11-19">2022-11-19</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2022-10-23/phperkaigi-2023-unused-token-quiz-1/">
- <header class="entry-header">
- <h2>PHPerKaigi 2023: ボツになったトークン問題 その 1</h2>
- </header>
- <section class="entry-content">
- <p>
- 来年の PHPerKaigi 2023 でデジタルサーカス株式会社から出題予定のトークン問題のうち、ボツになった問題を公開する (その 1)。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2022-10-23">2022-10-23</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2022-09-29/write-fizzbuzz-in-php-2-letters-per-line/">
- <header class="entry-header">
- <h2>【PHP】 fizzbuzz を書く。1行あたり2文字で。</h2>
- </header>
- <section class="entry-content">
- <p>
- PHP で fizzbuzz を書いた。ただし、1行あたりに使える文字数は2文字まで。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2022-09-28">2022-09-28</time> 投稿、<time datetime="2022-09-29">2022-09-29</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2022-08-27/php-conference-okinawa-code-golf/">
- <header class="entry-header">
- <h2>PHP カンファレンス沖縄で出題されたコードゴルフの問題を解いてみた</h2>
- </header>
- <section class="entry-content">
- <p>
- PHP カンファレンス沖縄の懇親会 LT で出題されたコードゴルフの問題を解いてみた。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2022-08-27">2022-08-27</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2022-05-01/phperkaigi-2022/">
- <header class="entry-header">
- <h2>PHPerKaigi 2022</h2>
- </header>
- <section class="entry-content">
- <p>
- 2022-04-09 から 2022-04-11 にかけて開催された、PHPerKaigi 2022 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2022-05-01">2022-05-01</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2022-04-09/phperkaigi-2022-tokens/">
- <header class="entry-header">
- <h2>PHPerKaigi 2022 トークン問題の解説</h2>
- </header>
- <section class="entry-content">
- <p>
- PHPerKaigi 2022 で私が作成した PHPer チャレンジ問題を解説する。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2022-04-09">2022-04-09</time> 投稿、<time datetime="2022-04-16">2022-04-16</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2021-03-30/phperkaigi-2021/">
- <header class="entry-header">
- <h2>PHPerKaigi 2021</h2>
- </header>
- <section class="entry-content">
- <p>
- 2021-03-26 から 2021-03-28 にかけて開催された、PHPerKaigi 2021 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2021-03-30">2021-03-30</time> 投稿、<time datetime="2025-04-09">2025-04-09</time> 更新
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/phpcon-nagoya/atom.xml b/vhosts/blog/public/tags/phpcon-nagoya/atom.xml
deleted file mode 100644
index cfc31796..00000000
--- a/vhosts/blog/public/tags/phpcon-nagoya/atom.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-phpcon-nagoya</id>
- <title>タグ「PHP カンファレンス名古屋」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/phpcon-nagoya/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/phpcon-nagoya/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2025-02-24T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:13174dc7-c1a3-465f-9ba6-14f0bc6f5961</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-02-24/phpcon-nagoya-2025-report/"></link>
- <title>PHP カンファレンス名古屋 2025 参加レポ</title>
- <summary>2025-02-22 に開催された、PHP カンファレンス名古屋 2025 に参加した。</summary>
- <published>2025-02-24T00:00:00+09:00</published>
- <updated>2025-02-24T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:9172fbef-c812-4ade-86f5-eaa12c966708</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2025-02-22/phpcon-nagoya-2025/"></link>
- <title>PHP 処理系の garbage collection を理解する~メモリはいつ解放されるのか~</title>
- <summary>登壇: PHP カンファレンス名古屋 2025 (レギュラートーク (30分))</summary>
- <published>2025-02-22T00:00:00+09:00</published>
- <updated>2025-02-22T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/phpcon-nagoya/index.html b/vhosts/blog/public/tags/phpcon-nagoya/index.html
deleted file mode 100644
index 2b1dc9bf..00000000
--- a/vhosts/blog/public/tags/phpcon-nagoya/index.html
+++ /dev/null
@@ -1,81 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2025 nsfisis">
- <meta name="description" content="タグ「PHP カンファレンス名古屋」のついた記事またはスライドの一覧">
- <meta name="keywords" content="PHP カンファレンス名古屋">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「PHP カンファレンス名古屋」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「PHP カンファレンス名古屋」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/phpcon-nagoya/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「PHP カンファレンス名古屋」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「PHP カンファレンス名古屋」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2025-02-24/phpcon-nagoya-2025-report/">
- <header class="entry-header">
- <h2>PHP カンファレンス名古屋 2025 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2025-02-22 に開催された、PHP カンファレンス名古屋 2025 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-02-24">2025-02-24</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2025-02-22/phpcon-nagoya-2025/">
- <header class="entry-header">
- <h2>登壇: PHP カンファレンス名古屋 2025 (レギュラートーク (30分))</h2>
- </header>
- <section class="entry-content">
- <p>
- PHP 処理系の garbage collection を理解する~メモリはいつ解放されるのか~
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-02-22">2025-02-22</time> 登壇
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/phpcon-odawara/atom.xml b/vhosts/blog/public/tags/phpcon-odawara/atom.xml
deleted file mode 100644
index d4567b24..00000000
--- a/vhosts/blog/public/tags/phpcon-odawara/atom.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-phpcon-odawara</id>
- <title>タグ「PHP カンファレンス小田原」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/phpcon-odawara/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/phpcon-odawara/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2025-04-12T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:c6c7c241-46c1-44b5-95b2-c30c3a500df3</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2025-04-12/phpcon-odawara-2025/"></link>
- <title>PHP 8.x 時代のクラス設計(property promotion から property hooks まで)</title>
- <summary>登壇: PHP カンファレンス小田原 2025 (レギュラートーク (20分))</summary>
- <published>2025-04-12T00:00:00+09:00</published>
- <updated>2025-04-12T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:be9c896d-7efa-42dd-a50a-dda5fd3a7f5c</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-04-14/phpcon-odawara-2024-report/"></link>
- <title>PHP カンファレンス小田原 2024 参加レポ</title>
- <summary>2024-04-13 に開催された、PHP カンファレンス小田原 2024 に参加した。</summary>
- <published>2024-04-14T00:00:00+09:00</published>
- <updated>2024-06-01T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:69e1694b-5ddb-41a5-a7f4-138ce82a78b2</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-04-13/phpcon-odawara-2024/"></link>
- <title>来る新 JIT エンジンについて知った気になる</title>
- <summary>登壇: PHP カンファレンス小田原 2024 (レギュラートーク (15分))</summary>
- <published>2024-04-13T00:00:00+09:00</published>
- <updated>2024-04-13T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/phpcon-odawara/index.html b/vhosts/blog/public/tags/phpcon-odawara/index.html
deleted file mode 100644
index 52fec2b6..00000000
--- a/vhosts/blog/public/tags/phpcon-odawara/index.html
+++ /dev/null
@@ -1,96 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="タグ「PHP カンファレンス小田原」のついた記事またはスライドの一覧">
- <meta name="keywords" content="PHP カンファレンス小田原">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「PHP カンファレンス小田原」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「PHP カンファレンス小田原」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/phpcon-odawara/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「PHP カンファレンス小田原」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「PHP カンファレンス小田原」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/slides/2025-04-12/phpcon-odawara-2025/">
- <header class="entry-header">
- <h2>登壇: PHP カンファレンス小田原 2025 (レギュラートーク (20分))</h2>
- </header>
- <section class="entry-content">
- <p>
- PHP 8.x 時代のクラス設計(property promotion から property hooks まで)
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-04-12">2025-04-12</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2024-04-14/phpcon-odawara-2024-report/">
- <header class="entry-header">
- <h2>PHP カンファレンス小田原 2024 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2024-04-13 に開催された、PHP カンファレンス小田原 2024 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-04-14">2024-04-14</time> 投稿、<time datetime="2024-06-01">2024-06-01</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2024-04-13/phpcon-odawara-2024/">
- <header class="entry-header">
- <h2>登壇: PHP カンファレンス小田原 2024 (レギュラートーク (15分))</h2>
- </header>
- <section class="entry-content">
- <p>
- 来る新 JIT エンジンについて知った気になる
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-04-13">2024-04-13</time> 登壇
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/phpconfuk/atom.xml b/vhosts/blog/public/tags/phpconfuk/atom.xml
deleted file mode 100644
index 4b9d3f4c..00000000
--- a/vhosts/blog/public/tags/phpconfuk/atom.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-phpconfuk</id>
- <title>タグ「PHP カンファレンス福岡」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/phpconfuk/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/phpconfuk/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2023-06-25T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:e1568c4c-9bdd-47b9-8b39-939ade4f3ba0</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2023-06-25/phpconfuk-2023-report/"></link>
- <title>PHP カンファレンス福岡 2023 参加レポ</title>
- <summary>2023-06-24 に開催された、PHP カンファレンス福岡に参加した。</summary>
- <published>2023-06-25T00:00:00+09:00</published>
- <updated>2023-06-25T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:72244d87-4cf0-41c4-a074-bcc37acaa678</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-06-23/phpconfuk-2023-eve/"></link>
- <title>巨大なコードベースへ突撃するために</title>
- <summary>登壇: PHP カンファレンス福岡 2023 前夜祭 (非公式) (レギュラートーク)</summary>
- <published>2023-06-23T00:00:00+09:00</published>
- <updated>2023-06-23T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/phpconfuk/index.html b/vhosts/blog/public/tags/phpconfuk/index.html
deleted file mode 100644
index 80bfc60c..00000000
--- a/vhosts/blog/public/tags/phpconfuk/index.html
+++ /dev/null
@@ -1,81 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2023 nsfisis">
- <meta name="description" content="タグ「PHP カンファレンス福岡」のついた記事またはスライドの一覧">
- <meta name="keywords" content="PHP カンファレンス福岡">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「PHP カンファレンス福岡」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「PHP カンファレンス福岡」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/phpconfuk/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「PHP カンファレンス福岡」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「PHP カンファレンス福岡」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2023-06-25/phpconfuk-2023-report/">
- <header class="entry-header">
- <h2>PHP カンファレンス福岡 2023 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2023-06-24 に開催された、PHP カンファレンス福岡に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-06-25">2023-06-25</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-06-23/phpconfuk-2023-eve/">
- <header class="entry-header">
- <h2>登壇: PHP カンファレンス福岡 2023 前夜祭 (非公式) (レギュラートーク)</h2>
- </header>
- <section class="entry-content">
- <p>
- 巨大なコードベースへ突撃するために
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-06-23">2023-06-23</time> 登壇
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/phpconkagawa/atom.xml b/vhosts/blog/public/tags/phpconkagawa/atom.xml
deleted file mode 100644
index 29697e77..00000000
--- a/vhosts/blog/public/tags/phpconkagawa/atom.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-phpconkagawa</id>
- <title>タグ「PHP カンファレンス香川」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/phpconkagawa/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/phpconkagawa/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2024-05-11T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:f13aa9d6-4533-4a15-872a-c298ab2090db</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-05-11/phpconkagawa-2024-report/"></link>
- <title>PHP カンファレンス香川 2024 参加レポ</title>
- <summary>2024-05-11 に開催された、PHP カンファレンス香川 2024 に参加した。</summary>
- <published>2024-05-11T00:00:00+09:00</published>
- <updated>2024-05-11T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/phpconkagawa/index.html b/vhosts/blog/public/tags/phpconkagawa/index.html
deleted file mode 100644
index 6e1284d0..00000000
--- a/vhosts/blog/public/tags/phpconkagawa/index.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="タグ「PHP カンファレンス香川」のついた記事またはスライドの一覧">
- <meta name="keywords" content="PHP カンファレンス香川">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「PHP カンファレンス香川」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「PHP カンファレンス香川」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/phpconkagawa/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「PHP カンファレンス香川」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「PHP カンファレンス香川」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2024-05-11/phpconkagawa-2024-report/">
- <header class="entry-header">
- <h2>PHP カンファレンス香川 2024 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2024-05-11 に開催された、PHP カンファレンス香川 2024 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-05-11">2024-05-11</time> 投稿
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/phpconokinawa/atom.xml b/vhosts/blog/public/tags/phpconokinawa/atom.xml
deleted file mode 100644
index 30b92418..00000000
--- a/vhosts/blog/public/tags/phpconokinawa/atom.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-phpconokinawa</id>
- <title>タグ「PHP カンファレンス沖縄」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/phpconokinawa/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/phpconokinawa/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2022-08-27T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:bb71bb5d-361b-44cb-9753-81d14583d860</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-08-27/php-conference-okinawa-code-golf/"></link>
- <title>PHP カンファレンス沖縄で出題されたコードゴルフの問題を解いてみた</title>
- <summary>PHP カンファレンス沖縄の懇親会 LT で出題されたコードゴルフの問題を解いてみた。</summary>
- <published>2022-08-27T00:00:00+09:00</published>
- <updated>2022-08-27T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/phpconokinawa/index.html b/vhosts/blog/public/tags/phpconokinawa/index.html
deleted file mode 100644
index 285cb629..00000000
--- a/vhosts/blog/public/tags/phpconokinawa/index.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2022 nsfisis">
- <meta name="description" content="タグ「PHP カンファレンス沖縄」のついた記事またはスライドの一覧">
- <meta name="keywords" content="PHP カンファレンス沖縄">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「PHP カンファレンス沖縄」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「PHP カンファレンス沖縄」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/phpconokinawa/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「PHP カンファレンス沖縄」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「PHP カンファレンス沖縄」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2022-08-27/php-conference-okinawa-code-golf/">
- <header class="entry-header">
- <h2>PHP カンファレンス沖縄で出題されたコードゴルフの問題を解いてみた</h2>
- </header>
- <section class="entry-content">
- <p>
- PHP カンファレンス沖縄の懇親会 LT で出題されたコードゴルフの問題を解いてみた。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2022-08-27">2022-08-27</time> 投稿
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/phperkaigi/atom.xml b/vhosts/blog/public/tags/phperkaigi/atom.xml
deleted file mode 100644
index 25d432da..00000000
--- a/vhosts/blog/public/tags/phperkaigi/atom.xml
+++ /dev/null
@@ -1,115 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-phperkaigi</id>
- <title>タグ「PHPerKaigi」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/phperkaigi/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/phperkaigi/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2025-04-09T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:ec7f4462-ae56-4bbf-aac7-cbd32bbbeb29</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2025-03-23/phperkaigi-2025/"></link>
- <title>PHPで作るPHP~セルフホストできる言語処理系を作ろう~</title>
- <summary>登壇: PHPerKaigi 2025 (レギュラートーク (40分))</summary>
- <published>2025-03-23T00:00:00+09:00</published>
- <updated>2025-03-23T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:ce8f20e8-c79f-48f8-982d-53edd4d20483</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-01-08/phperkaigi-2023-tokens-q1/"></link>
- <title>PHPerKaigi 2023 トークン問題解説 (1/5)</title>
- <summary>PHPerKaigi 2023 でデジタルサーカス株式会社から出題した問題を解説する。全5問中の第1問。</summary>
- <published>2025-01-08T00:00:00+09:00</published>
- <updated>2025-01-11T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:750be5c8-ca52-4cbd-86fe-5645b06bde95</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-03-17/phperkaigi-2024-report/"></link>
- <title>PHPerKaigi 2024 参加レポ</title>
- <summary>2024-03-07 から 2024-03-09 にかけて開催された、PHPerKaigi 2024 に参加した。</summary>
- <published>2024-03-17T00:00:00+09:00</published>
- <updated>2024-07-07T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:cee40048-f3c5-4043-9ef8-a4ee2ae7cf0e</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-03-08/phperkaigi-2024/"></link>
- <title>WebAssembly を理解する 〜VM の作成を通して〜</title>
- <summary>登壇: PHPerKaigi 2024 (レギュラートーク (40分))</summary>
- <published>2024-03-08T00:00:00+09:00</published>
- <updated>2024-03-08T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:21ce39f0-d613-45f2-a760-89c368892d77</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2023-04-04/phperkaigi-2023-report/"></link>
- <title>PHPerKaigi 2023 参加レポ</title>
- <summary>2023-03-23 から 2023-03-25 にかけて開催された、PHPerKaigi 2023 に参加した。</summary>
- <published>2023-04-04T00:00:00+09:00</published>
- <updated>2023-06-28T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:3cce70d8-cee9-4e0e-8b38-6ef1e0a8a278</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-03-25/phperkaigi-2023-tokens/"></link>
- <title>PHPer チャレンジ解説 (デジタルサーカス株式会社)</title>
- <summary>登壇: PHPerKaigi 2023 (トークン解説セッション)</summary>
- <published>2023-03-25T00:00:00+09:00</published>
- <updated>2023-03-25T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:2dce7e27-1eaf-4ca4-8037-e9a3ead18b48</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-03-24/phperkaigi-2023/"></link>
- <title>詳説「参照」PHP の参照を完全に理解する</title>
- <summary>登壇: PHPerKaigi 2023 (レギュラートーク)</summary>
- <published>2023-03-24T00:00:00+09:00</published>
- <updated>2023-03-24T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:89722cfb-7f4b-4e96-80bc-e0096e5eeef6</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2023-01-10/phperkaigi-2023-unused-token-quiz-3/"></link>
- <title>PHPerKaigi 2023: ボツになったトークン問題 その 3</title>
- <summary>来年の PHPerKaigi 2023 でデジタルサーカス株式会社から出題予定のトークン問題のうち、ボツになった問題を公開する (その 3)。</summary>
- <published>2023-01-10T00:00:00+09:00</published>
- <updated>2023-01-10T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:10fe9c47-7029-4874-82bd-b4dc50e07809</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-11-19/phperkaigi-2023-unused-token-quiz-2/"></link>
- <title>PHPerKaigi 2023: ボツになったトークン問題 その 2</title>
- <summary>来年の PHPerKaigi 2023 でデジタルサーカス株式会社から出題予定のトークン問題のうち、ボツになった問題を公開する (その 2)。</summary>
- <published>2022-11-19T00:00:00+09:00</published>
- <updated>2022-11-19T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:46e0d5db-b17e-464c-a723-8c3e01af7d1d</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-10-23/phperkaigi-2023-unused-token-quiz-1/"></link>
- <title>PHPerKaigi 2023: ボツになったトークン問題 その 1</title>
- <summary>来年の PHPerKaigi 2023 でデジタルサーカス株式会社から出題予定のトークン問題のうち、ボツになった問題を公開する (その 1)。</summary>
- <published>2022-10-23T00:00:00+09:00</published>
- <updated>2022-10-23T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:9211e1fe-bca3-43c4-ba4e-c67d62f3fed0</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-05-01/phperkaigi-2022/"></link>
- <title>PHPerKaigi 2022</title>
- <summary>2022-04-09 から 2022-04-11 にかけて開催された、PHPerKaigi 2022 に参加した。</summary>
- <published>2022-05-01T00:00:00+09:00</published>
- <updated>2022-05-01T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:f4985d54-0907-4449-8101-0fcd382f9e02</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2022-04-09/phperkaigi-2022-tokens/"></link>
- <title>PHPerKaigi 2022 トークン問題の解説</title>
- <summary>PHPerKaigi 2022 で私が作成した PHPer チャレンジ問題を解説する。</summary>
- <published>2022-04-09T00:00:00+09:00</published>
- <updated>2022-04-16T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:3fbe0b8c-216e-48f6-b905-c0d361b94542</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2021-03-30/phperkaigi-2021/"></link>
- <title>PHPerKaigi 2021</title>
- <summary>2021-03-26 から 2021-03-28 にかけて開催された、PHPerKaigi 2021 に参加した。</summary>
- <published>2021-03-30T00:00:00+09:00</published>
- <updated>2025-04-09T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/phperkaigi/index.html b/vhosts/blog/public/tags/phperkaigi/index.html
deleted file mode 100644
index bcd8be37..00000000
--- a/vhosts/blog/public/tags/phperkaigi/index.html
+++ /dev/null
@@ -1,246 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2021 nsfisis">
- <meta name="description" content="タグ「PHPerKaigi」のついた記事またはスライドの一覧">
- <meta name="keywords" content="PHPerKaigi">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「PHPerKaigi」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「PHPerKaigi」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/phperkaigi/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「PHPerKaigi」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「PHPerKaigi」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/slides/2025-03-23/phperkaigi-2025/">
- <header class="entry-header">
- <h2>登壇: PHPerKaigi 2025 (レギュラートーク (40分))</h2>
- </header>
- <section class="entry-content">
- <p>
- PHPで作るPHP~セルフホストできる言語処理系を作ろう~
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-03-23">2025-03-23</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2025-01-08/phperkaigi-2023-tokens-q1/">
- <header class="entry-header">
- <h2>PHPerKaigi 2023 トークン問題解説 (1/5)</h2>
- </header>
- <section class="entry-content">
- <p>
- PHPerKaigi 2023 でデジタルサーカス株式会社から出題した問題を解説する。全5問中の第1問。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-01-08">2025-01-08</time> 投稿、<time datetime="2025-01-11">2025-01-11</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2024-03-17/phperkaigi-2024-report/">
- <header class="entry-header">
- <h2>PHPerKaigi 2024 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2024-03-07 から 2024-03-09 にかけて開催された、PHPerKaigi 2024 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-03-17">2024-03-17</time> 投稿、<time datetime="2024-07-07">2024-07-07</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2024-03-08/phperkaigi-2024/">
- <header class="entry-header">
- <h2>登壇: PHPerKaigi 2024 (レギュラートーク (40分))</h2>
- </header>
- <section class="entry-content">
- <p>
- WebAssembly を理解する 〜VM の作成を通して〜
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-03-08">2024-03-08</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2023-04-04/phperkaigi-2023-report/">
- <header class="entry-header">
- <h2>PHPerKaigi 2023 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2023-03-23 から 2023-03-25 にかけて開催された、PHPerKaigi 2023 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-04-04">2023-04-04</time> 投稿、<time datetime="2023-06-28">2023-06-28</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-03-25/phperkaigi-2023-tokens/">
- <header class="entry-header">
- <h2>登壇: PHPerKaigi 2023 (トークン解説セッション)</h2>
- </header>
- <section class="entry-content">
- <p>
- PHPer チャレンジ解説 (デジタルサーカス株式会社)
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-03-25">2023-03-25</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-03-24/phperkaigi-2023/">
- <header class="entry-header">
- <h2>登壇: PHPerKaigi 2023 (レギュラートーク)</h2>
- </header>
- <section class="entry-content">
- <p>
- 詳説「参照」PHP の参照を完全に理解する
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-03-24">2023-03-24</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2023-01-10/phperkaigi-2023-unused-token-quiz-3/">
- <header class="entry-header">
- <h2>PHPerKaigi 2023: ボツになったトークン問題 その 3</h2>
- </header>
- <section class="entry-content">
- <p>
- 来年の PHPerKaigi 2023 でデジタルサーカス株式会社から出題予定のトークン問題のうち、ボツになった問題を公開する (その 3)。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-01-10">2023-01-10</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2022-11-19/phperkaigi-2023-unused-token-quiz-2/">
- <header class="entry-header">
- <h2>PHPerKaigi 2023: ボツになったトークン問題 その 2</h2>
- </header>
- <section class="entry-content">
- <p>
- 来年の PHPerKaigi 2023 でデジタルサーカス株式会社から出題予定のトークン問題のうち、ボツになった問題を公開する (その 2)。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2022-11-19">2022-11-19</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2022-10-23/phperkaigi-2023-unused-token-quiz-1/">
- <header class="entry-header">
- <h2>PHPerKaigi 2023: ボツになったトークン問題 その 1</h2>
- </header>
- <section class="entry-content">
- <p>
- 来年の PHPerKaigi 2023 でデジタルサーカス株式会社から出題予定のトークン問題のうち、ボツになった問題を公開する (その 1)。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2022-10-23">2022-10-23</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2022-05-01/phperkaigi-2022/">
- <header class="entry-header">
- <h2>PHPerKaigi 2022</h2>
- </header>
- <section class="entry-content">
- <p>
- 2022-04-09 から 2022-04-11 にかけて開催された、PHPerKaigi 2022 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2022-05-01">2022-05-01</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2022-04-09/phperkaigi-2022-tokens/">
- <header class="entry-header">
- <h2>PHPerKaigi 2022 トークン問題の解説</h2>
- </header>
- <section class="entry-content">
- <p>
- PHPerKaigi 2022 で私が作成した PHPer チャレンジ問題を解説する。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2022-04-09">2022-04-09</time> 投稿、<time datetime="2022-04-16">2022-04-16</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2021-03-30/phperkaigi-2021/">
- <header class="entry-header">
- <h2>PHPerKaigi 2021</h2>
- </header>
- <section class="entry-content">
- <p>
- 2021-03-26 から 2021-03-28 にかけて開催された、PHPerKaigi 2021 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2021-03-30">2021-03-30</time> 投稿、<time datetime="2025-04-09">2025-04-09</time> 更新
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/phpkansai/atom.xml b/vhosts/blog/public/tags/phpkansai/atom.xml
deleted file mode 100644
index 5eecf3c6..00000000
--- a/vhosts/blog/public/tags/phpkansai/atom.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-phpkansai</id>
- <title>タグ「PHP カンファレンス関西」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/phpkansai/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/phpkansai/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2024-02-21T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:fd8fcb03-8e4d-4ca7-8499-0674accc51a9</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-02-22/phpkansai-2024-report/"></link>
- <title>PHPカンファレンス関西 2024 参加レポ</title>
- <summary>2024-02-11 に開催された、PHPカンファレンス関西 2024 に参加した。</summary>
- <published>2024-02-21T00:00:00+09:00</published>
- <updated>2024-02-21T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/phpkansai/index.html b/vhosts/blog/public/tags/phpkansai/index.html
deleted file mode 100644
index de4d5e63..00000000
--- a/vhosts/blog/public/tags/phpkansai/index.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="タグ「PHP カンファレンス関西」のついた記事またはスライドの一覧">
- <meta name="keywords" content="PHP カンファレンス関西">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「PHP カンファレンス関西」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「PHP カンファレンス関西」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/phpkansai/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「PHP カンファレンス関西」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「PHP カンファレンス関西」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2024-02-22/phpkansai-2024-report/">
- <header class="entry-header">
- <h2>PHPカンファレンス関西 2024 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2024-02-11 に開催された、PHPカンファレンス関西 2024 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-02-21">2024-02-21</time> 投稿
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/phpstudy-tokyo/atom.xml b/vhosts/blog/public/tags/phpstudy-tokyo/atom.xml
deleted file mode 100644
index 88970f63..00000000
--- a/vhosts/blog/public/tags/phpstudy-tokyo/atom.xml
+++ /dev/null
@@ -1,107 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-phpstudy-tokyo</id>
- <title>タグ「PHP 勉強会@東京」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/phpstudy-tokyo/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/phpstudy-tokyo/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2024-10-30T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:a84100cf-8c92-4856-addf-81a7c5547074</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-10-30/phpstudy-tokyo-169/"></link>
- <title>PHP で PHP を作る (縮小版)</title>
- <summary>登壇: PHP 勉強会@東京 第169回 (レギュラートーク (20分))</summary>
- <published>2024-10-30T00:00:00+09:00</published>
- <updated>2024-10-30T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:eec495b5-45e2-4c6f-a725-e62b1e0a7ad5</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-07-18/phpstudy-tokyo-166/"></link>
- <title>PHPerKaigi 2024 で発表した WebAssembly ランタイムのその後</title>
- <summary>登壇: PHP 勉強会@東京 第166回 (レギュラートーク (20分))</summary>
- <published>2024-07-18T00:00:00+09:00</published>
- <updated>2024-07-18T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:6cf84106-cc69-4d87-b957-9d58d7e585bb</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-04-25/phpstudy-tokyo-163/"></link>
- <title>Tracing JIT の発動条件</title>
- <summary>登壇: PHP 勉強会@東京 第163回 (LT)</summary>
- <published>2024-04-25T00:00:00+09:00</published>
- <updated>2024-04-25T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:82db7893-983a-4631-8bee-d0725d078252</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-01-24/phpstudy-tokyo-160/"></link>
- <title>PHPStan の力で Algebraic Data Types を実現する</title>
- <summary>登壇: PHP 勉強会@東京 第160 回 (レギュラートーク)</summary>
- <published>2024-01-24T00:00:00+09:00</published>
- <updated>2024-01-24T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:6c377f3f-6f52-4074-b690-c79d02050562</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-10-25/phpstudy-tokyo-157/"></link>
- <title>PHP コードを隔離された環境で安全に動かす (on WebAssembly)</title>
- <summary>登壇: PHP 勉強会@東京 第157 回 (LT)</summary>
- <published>2023-10-25T00:00:00+09:00</published>
- <updated>2023-10-25T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:d6118e00-5fb1-4230-9d94-854260beae04</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-08-24/phpstudy-tokyo-155/"></link>
- <title>PHP 3.0 の処理系のソースを読んでみる</title>
- <summary>登壇: PHP 勉強会@東京 第155 回 (LT)</summary>
- <published>2023-08-24T00:00:00+09:00</published>
- <updated>2023-08-24T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:669de08d-9e02-44c5-ac3f-35972112e706</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-07-26/phpstudy-tokyo-154/"></link>
- <title>言語間で比較するエラーの通知と処理</title>
- <summary>登壇: PHP 勉強会@東京 第154 回 (レギュラートーク)</summary>
- <published>2023-07-26T00:00:00+09:00</published>
- <updated>2023-07-26T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:6016d501-b9c9-474a-a304-1ec1295e049a</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-06-21/phpstudy-tokyo-153/"></link>
- <title>テキストファイルの末尾には改行コードを入れよう</title>
- <summary>登壇: PHP 勉強会@東京 第153 回 (LT)</summary>
- <published>2023-06-21T00:00:00+09:00</published>
- <updated>2023-06-21T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:fe75bb63-1cd9-457e-8244-c444307cd40a</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-04-12/phpstudy-tokyo-151/"></link>
- <title>list でない array の末尾を探す</title>
- <summary>登壇: PHP 勉強会@東京 第151 回 (LT)</summary>
- <published>2023-04-12T00:00:00+09:00</published>
- <updated>2023-04-12T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:9376560b-250a-4697-ac10-0903ad16acee</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-03-15/phpstudy-tokyo-150/"></link>
- <title>明日のあなたの役に立たない PHP コーディング技法~細長い FizzBuzz を書く~</title>
- <summary>登壇: PHP 勉強会@東京 第150 回 (LT)</summary>
- <published>2023-03-15T00:00:00+09:00</published>
- <updated>2023-03-18T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:f23ea81c-5996-4b7e-aab0-4e9f23b172c2</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-02-15/phpstudy-tokyo-149/"></link>
- <title>PHPerKaigi 2023 のトークン問題でボツにした問題を供養する</title>
- <summary>登壇: PHP 勉強会@東京 第149 回 (LT)</summary>
- <published>2023-02-15T00:00:00+09:00</published>
- <updated>2023-02-15T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:693a4c2e-6f21-4840-b793-4e3644a8ec22</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2023-01-18/phpstudy-tokyo-148/"></link>
- <title>明日のあなたの役に立たない PHP コーディング技法~polyglot~</title>
- <summary>登壇: PHP 勉強会@東京 第148 回 (LT)</summary>
- <published>2023-01-18T00:00:00+09:00</published>
- <updated>2023-01-18T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/phpstudy-tokyo/index.html b/vhosts/blog/public/tags/phpstudy-tokyo/index.html
deleted file mode 100644
index 373da9df..00000000
--- a/vhosts/blog/public/tags/phpstudy-tokyo/index.html
+++ /dev/null
@@ -1,231 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2023 nsfisis">
- <meta name="description" content="タグ「PHP 勉強会@東京」のついた記事またはスライドの一覧">
- <meta name="keywords" content="PHP 勉強会@東京">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「PHP 勉強会@東京」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「PHP 勉強会@東京」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/phpstudy-tokyo/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「PHP 勉強会@東京」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「PHP 勉強会@東京」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/slides/2024-10-30/phpstudy-tokyo-169/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第169回 (レギュラートーク (20分))</h2>
- </header>
- <section class="entry-content">
- <p>
- PHP で PHP を作る (縮小版)
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-10-30">2024-10-30</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2024-07-18/phpstudy-tokyo-166/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第166回 (レギュラートーク (20分))</h2>
- </header>
- <section class="entry-content">
- <p>
- PHPerKaigi 2024 で発表した WebAssembly ランタイムのその後
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-07-18">2024-07-18</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2024-04-25/phpstudy-tokyo-163/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第163回 (LT)</h2>
- </header>
- <section class="entry-content">
- <p>
- Tracing JIT の発動条件
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-04-25">2024-04-25</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2024-01-24/phpstudy-tokyo-160/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第160 回 (レギュラートーク)</h2>
- </header>
- <section class="entry-content">
- <p>
- PHPStan の力で Algebraic Data Types を実現する
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-01-24">2024-01-24</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-10-25/phpstudy-tokyo-157/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第157 回 (LT)</h2>
- </header>
- <section class="entry-content">
- <p>
- PHP コードを隔離された環境で安全に動かす (on WebAssembly)
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-10-25">2023-10-25</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-08-24/phpstudy-tokyo-155/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第155 回 (LT)</h2>
- </header>
- <section class="entry-content">
- <p>
- PHP 3.0 の処理系のソースを読んでみる
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-08-24">2023-08-24</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-07-26/phpstudy-tokyo-154/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第154 回 (レギュラートーク)</h2>
- </header>
- <section class="entry-content">
- <p>
- 言語間で比較するエラーの通知と処理
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-07-26">2023-07-26</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-06-21/phpstudy-tokyo-153/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第153 回 (LT)</h2>
- </header>
- <section class="entry-content">
- <p>
- テキストファイルの末尾には改行コードを入れよう
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-06-21">2023-06-21</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-04-12/phpstudy-tokyo-151/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第151 回 (LT)</h2>
- </header>
- <section class="entry-content">
- <p>
- list でない array の末尾を探す
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-04-12">2023-04-12</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-03-15/phpstudy-tokyo-150/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第150 回 (LT)</h2>
- </header>
- <section class="entry-content">
- <p>
- 明日のあなたの役に立たない PHP コーディング技法~細長い FizzBuzz を書く~
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-03-15">2023-03-15</time> 登壇、<time datetime="2023-03-18">2023-03-18</time> 更新
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-02-15/phpstudy-tokyo-149/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第149 回 (LT)</h2>
- </header>
- <section class="entry-content">
- <p>
- PHPerKaigi 2023 のトークン問題でボツにした問題を供養する
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-02-15">2023-02-15</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2023-01-18/phpstudy-tokyo-148/">
- <header class="entry-header">
- <h2>登壇: PHP 勉強会@東京 第148 回 (LT)</h2>
- </header>
- <section class="entry-content">
- <p>
- 明日のあなたの役に立たない PHP コーディング技法~polyglot~
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-01-18">2023-01-18</time> 登壇
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/piet/atom.xml b/vhosts/blog/public/tags/piet/atom.xml
deleted file mode 100644
index c3b39cd5..00000000
--- a/vhosts/blog/public/tags/piet/atom.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-piet</id>
- <title>タグ「Piet」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/piet/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/piet/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2025-01-11T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:ce8f20e8-c79f-48f8-982d-53edd4d20483</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-01-08/phperkaigi-2023-tokens-q1/"></link>
- <title>PHPerKaigi 2023 トークン問題解説 (1/5)</title>
- <summary>PHPerKaigi 2023 でデジタルサーカス株式会社から出題した問題を解説する。全5問中の第1問。</summary>
- <published>2025-01-08T00:00:00+09:00</published>
- <updated>2025-01-11T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/piet/index.html b/vhosts/blog/public/tags/piet/index.html
deleted file mode 100644
index 6578679e..00000000
--- a/vhosts/blog/public/tags/piet/index.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2025 nsfisis">
- <meta name="description" content="タグ「Piet」のついた記事またはスライドの一覧">
- <meta name="keywords" content="Piet">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「Piet」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「Piet」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/piet/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「Piet」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「Piet」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2025-01-08/phperkaigi-2023-tokens-q1/">
- <header class="entry-header">
- <h2>PHPerKaigi 2023 トークン問題解説 (1/5)</h2>
- </header>
- <section class="entry-content">
- <p>
- PHPerKaigi 2023 でデジタルサーカス株式会社から出題した問題を解説する。全5問中の第1問。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-01-08">2025-01-08</time> 投稿、<time datetime="2025-01-11">2025-01-11</time> 更新
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/python/atom.xml b/vhosts/blog/public/tags/python/atom.xml
deleted file mode 100644
index 286c356d..00000000
--- a/vhosts/blog/public/tags/python/atom.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-python</id>
- <title>タグ「Python」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/python/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/python/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2021-10-02T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:e1aff84c-d6d4-4dea-bc45-9c41e6445006</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2021-10-02/python-unbound-local-error/"></link>
- <title>【Python】 クロージャとUnboundLocalError: local variable &apos;x&apos; referenced before assignment</title>
- <summary>Python における UnboundLocalError の理由と対処法。</summary>
- <published>2021-10-02T00:00:00+09:00</published>
- <updated>2021-10-02T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/python/index.html b/vhosts/blog/public/tags/python/index.html
deleted file mode 100644
index 31f55003..00000000
--- a/vhosts/blog/public/tags/python/index.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2021 nsfisis">
- <meta name="description" content="タグ「Python」のついた記事またはスライドの一覧">
- <meta name="keywords" content="Python">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「Python」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「Python」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/python/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「Python」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「Python」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2021-10-02/python-unbound-local-error/">
- <header class="entry-header">
- <h2>【Python】 クロージャとUnboundLocalError: local variable &apos;x&apos; referenced before assignment</h2>
- </header>
- <section class="entry-content">
- <p>
- Python における UnboundLocalError の理由と対処法。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2021-10-02">2021-10-02</time> 投稿
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/python3/atom.xml b/vhosts/blog/public/tags/python3/atom.xml
deleted file mode 100644
index f549164f..00000000
--- a/vhosts/blog/public/tags/python3/atom.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-python3</id>
- <title>タグ「Python 3」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/python3/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/python3/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2021-10-02T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:e1aff84c-d6d4-4dea-bc45-9c41e6445006</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2021-10-02/python-unbound-local-error/"></link>
- <title>【Python】 クロージャとUnboundLocalError: local variable &apos;x&apos; referenced before assignment</title>
- <summary>Python における UnboundLocalError の理由と対処法。</summary>
- <published>2021-10-02T00:00:00+09:00</published>
- <updated>2021-10-02T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/python3/index.html b/vhosts/blog/public/tags/python3/index.html
deleted file mode 100644
index ea9600eb..00000000
--- a/vhosts/blog/public/tags/python3/index.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2021 nsfisis">
- <meta name="description" content="タグ「Python 3」のついた記事またはスライドの一覧">
- <meta name="keywords" content="Python 3">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「Python 3」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「Python 3」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/python3/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「Python 3」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「Python 3」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2021-10-02/python-unbound-local-error/">
- <header class="entry-header">
- <h2>【Python】 クロージャとUnboundLocalError: local variable &apos;x&apos; referenced before assignment</h2>
- </header>
- <section class="entry-content">
- <p>
- Python における UnboundLocalError の理由と対処法。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2021-10-02">2021-10-02</time> 投稿
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/ruby/atom.xml b/vhosts/blog/public/tags/ruby/atom.xml
deleted file mode 100644
index 04d572e9..00000000
--- a/vhosts/blog/public/tags/ruby/atom.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-ruby</id>
- <title>タグ「Ruby」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/ruby/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/ruby/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2025-04-20T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:039b3dff-3b75-46b7-a731-9a3a0ff8e21f</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/"></link>
- <title>RubyKaigi 2025 の TRICK で入賞した</title>
- <summary>RubyKaigi 2025 で開催された TRICK において、『最もRuby on Ruby賞』として審査員賞をいただいた。</summary>
- <published>2025-04-20T00:00:00+09:00</published>
- <updated>2025-04-20T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:e1456a50-4fc6-42ef-89f3-8be78e01da13</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2021-10-02/ruby-detect-running-implementation/"></link>
- <title>【Ruby】 自身を実行している処理系の種類を判定する</title>
- <summary>Ruby には複数の実装があるが、自身を実行している処理系の種類をスクリプト上からどのように判定すればよいだろうか。</summary>
- <published>2021-10-02T00:00:00+09:00</published>
- <updated>2021-10-02T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:87455008-fe5b-49bf-af5a-b875264f8326</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2021-10-02/ruby-then-keyword-and-case-in/"></link>
- <title>【Ruby】 then キーワードと case in</title>
- <summary>Ruby 3.0 で追加される case in 構文と、then キーワードについて。</summary>
- <published>2021-10-02T00:00:00+09:00</published>
- <updated>2021-10-02T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/ruby/index.html b/vhosts/blog/public/tags/ruby/index.html
deleted file mode 100644
index 1f3e7c74..00000000
--- a/vhosts/blog/public/tags/ruby/index.html
+++ /dev/null
@@ -1,96 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2021 nsfisis">
- <meta name="description" content="タグ「Ruby」のついた記事またはスライドの一覧">
- <meta name="keywords" content="Ruby">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「Ruby」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「Ruby」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/ruby/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「Ruby」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「Ruby」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/">
- <header class="entry-header">
- <h2>RubyKaigi 2025 の TRICK で入賞した</h2>
- </header>
- <section class="entry-content">
- <p>
- RubyKaigi 2025 で開催された TRICK において、『最もRuby on Ruby賞』として審査員賞をいただいた。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-04-20">2025-04-20</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2021-10-02/ruby-detect-running-implementation/">
- <header class="entry-header">
- <h2>【Ruby】 自身を実行している処理系の種類を判定する</h2>
- </header>
- <section class="entry-content">
- <p>
- Ruby には複数の実装があるが、自身を実行している処理系の種類をスクリプト上からどのように判定すればよいだろうか。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2021-10-02">2021-10-02</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2021-10-02/ruby-then-keyword-and-case-in/">
- <header class="entry-header">
- <h2>【Ruby】 then キーワードと case in</h2>
- </header>
- <section class="entry-content">
- <p>
- Ruby 3.0 で追加される case in 構文と、then キーワードについて。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2021-10-02">2021-10-02</time> 投稿
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/ruby3/atom.xml b/vhosts/blog/public/tags/ruby3/atom.xml
deleted file mode 100644
index a738459b..00000000
--- a/vhosts/blog/public/tags/ruby3/atom.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-ruby3</id>
- <title>タグ「Ruby 3」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/ruby3/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/ruby3/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2021-10-02T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:87455008-fe5b-49bf-af5a-b875264f8326</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2021-10-02/ruby-then-keyword-and-case-in/"></link>
- <title>【Ruby】 then キーワードと case in</title>
- <summary>Ruby 3.0 で追加される case in 構文と、then キーワードについて。</summary>
- <published>2021-10-02T00:00:00+09:00</published>
- <updated>2021-10-02T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/ruby3/index.html b/vhosts/blog/public/tags/ruby3/index.html
deleted file mode 100644
index b51d5c1d..00000000
--- a/vhosts/blog/public/tags/ruby3/index.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2021 nsfisis">
- <meta name="description" content="タグ「Ruby 3」のついた記事またはスライドの一覧">
- <meta name="keywords" content="Ruby 3">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「Ruby 3」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「Ruby 3」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/ruby3/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「Ruby 3」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「Ruby 3」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2021-10-02/ruby-then-keyword-and-case-in/">
- <header class="entry-header">
- <h2>【Ruby】 then キーワードと case in</h2>
- </header>
- <section class="entry-content">
- <p>
- Ruby 3.0 で追加される case in 構文と、then キーワードについて。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2021-10-02">2021-10-02</time> 投稿
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/rubykaigi/atom.xml b/vhosts/blog/public/tags/rubykaigi/atom.xml
deleted file mode 100644
index 8fad7b19..00000000
--- a/vhosts/blog/public/tags/rubykaigi/atom.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-rubykaigi</id>
- <title>タグ「RubyKaigi」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/rubykaigi/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/rubykaigi/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2025-04-20T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:039b3dff-3b75-46b7-a731-9a3a0ff8e21f</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/"></link>
- <title>RubyKaigi 2025 の TRICK で入賞した</title>
- <summary>RubyKaigi 2025 で開催された TRICK において、『最もRuby on Ruby賞』として審査員賞をいただいた。</summary>
- <published>2025-04-20T00:00:00+09:00</published>
- <updated>2025-04-20T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/rubykaigi/index.html b/vhosts/blog/public/tags/rubykaigi/index.html
deleted file mode 100644
index 651045a6..00000000
--- a/vhosts/blog/public/tags/rubykaigi/index.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2025 nsfisis">
- <meta name="description" content="タグ「RubyKaigi」のついた記事またはスライドの一覧">
- <meta name="keywords" content="RubyKaigi">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「RubyKaigi」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「RubyKaigi」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/rubykaigi/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「RubyKaigi」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「RubyKaigi」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/">
- <header class="entry-header">
- <h2>RubyKaigi 2025 の TRICK で入賞した</h2>
- </header>
- <section class="entry-content">
- <p>
- RubyKaigi 2025 で開催された TRICK において、『最もRuby on Ruby賞』として審査員賞をいただいた。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-04-20">2025-04-20</time> 投稿
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/rust/atom.xml b/vhosts/blog/public/tags/rust/atom.xml
deleted file mode 100644
index 19707665..00000000
--- a/vhosts/blog/public/tags/rust/atom.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-rust</id>
- <title>タグ「Rust」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/rust/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/rust/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2021-10-02T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:91c61980-c262-4e8d-89b0-4304e7f6d644</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2021-10-02/rust-where-are-primitive-types-from/"></link>
- <title>Rust のプリミティブ型はどこからやって来るか</title>
- <summary>Rust のプリミティブ型は予約語ではなく普通の識別子である。どのようにこれが名前解決されるのかを調べた。</summary>
- <published>2021-10-02T00:00:00+09:00</published>
- <updated>2021-10-02T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/rust/index.html b/vhosts/blog/public/tags/rust/index.html
deleted file mode 100644
index 89b7c5a6..00000000
--- a/vhosts/blog/public/tags/rust/index.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2021 nsfisis">
- <meta name="description" content="タグ「Rust」のついた記事またはスライドの一覧">
- <meta name="keywords" content="Rust">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「Rust」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「Rust」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/rust/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「Rust」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「Rust」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2021-10-02/rust-where-are-primitive-types-from/">
- <header class="entry-header">
- <h2>Rust のプリミティブ型はどこからやって来るか</h2>
- </header>
- <section class="entry-content">
- <p>
- Rust のプリミティブ型は予約語ではなく普通の識別子である。どのようにこれが名前解決されるのかを調べた。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2021-10-02">2021-10-02</time> 投稿
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/scala/atom.xml b/vhosts/blog/public/tags/scala/atom.xml
deleted file mode 100644
index 0755322a..00000000
--- a/vhosts/blog/public/tags/scala/atom.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-scala</id>
- <title>タグ「Scala」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/scala/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/scala/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2024-06-19T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:8d6f3690-3da3-4235-a81b-b9707cee22ad</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-06-19/scalamatsuri-2024-report/"></link>
- <title>ScalaMatsuri 2024 参加レポ</title>
- <summary>2024-06-08 から 2024-06-09 にかけて開催された、ScalaMatsuri 2024 に参加した。</summary>
- <published>2024-06-19T00:00:00+09:00</published>
- <updated>2024-06-19T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/scala/index.html b/vhosts/blog/public/tags/scala/index.html
deleted file mode 100644
index 57c2635c..00000000
--- a/vhosts/blog/public/tags/scala/index.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="タグ「Scala」のついた記事またはスライドの一覧">
- <meta name="keywords" content="Scala">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「Scala」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「Scala」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/scala/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「Scala」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「Scala」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2024-06-19/scalamatsuri-2024-report/">
- <header class="entry-header">
- <h2>ScalaMatsuri 2024 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2024-06-08 から 2024-06-09 にかけて開催された、ScalaMatsuri 2024 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-06-19">2024-06-19</time> 投稿
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/scalamatsuri/atom.xml b/vhosts/blog/public/tags/scalamatsuri/atom.xml
deleted file mode 100644
index 5c4c39ab..00000000
--- a/vhosts/blog/public/tags/scalamatsuri/atom.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-scalamatsuri</id>
- <title>タグ「ScalaMatsuri」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/scalamatsuri/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/scalamatsuri/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2024-06-19T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:8d6f3690-3da3-4235-a81b-b9707cee22ad</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-06-19/scalamatsuri-2024-report/"></link>
- <title>ScalaMatsuri 2024 参加レポ</title>
- <summary>2024-06-08 から 2024-06-09 にかけて開催された、ScalaMatsuri 2024 に参加した。</summary>
- <published>2024-06-19T00:00:00+09:00</published>
- <updated>2024-06-19T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/scalamatsuri/index.html b/vhosts/blog/public/tags/scalamatsuri/index.html
deleted file mode 100644
index d8f4a04e..00000000
--- a/vhosts/blog/public/tags/scalamatsuri/index.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="タグ「ScalaMatsuri」のついた記事またはスライドの一覧">
- <meta name="keywords" content="ScalaMatsuri">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「ScalaMatsuri」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「ScalaMatsuri」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/scalamatsuri/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「ScalaMatsuri」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「ScalaMatsuri」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2024-06-19/scalamatsuri-2024-report/">
- <header class="entry-header">
- <h2>ScalaMatsuri 2024 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2024-06-08 から 2024-06-09 にかけて開催された、ScalaMatsuri 2024 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-06-19">2024-06-19</time> 投稿
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/trick/atom.xml b/vhosts/blog/public/tags/trick/atom.xml
deleted file mode 100644
index 98341b8a..00000000
--- a/vhosts/blog/public/tags/trick/atom.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-trick</id>
- <title>タグ「TRICK」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/trick/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/trick/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2025-04-20T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:039b3dff-3b75-46b7-a731-9a3a0ff8e21f</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/"></link>
- <title>RubyKaigi 2025 の TRICK で入賞した</title>
- <summary>RubyKaigi 2025 で開催された TRICK において、『最もRuby on Ruby賞』として審査員賞をいただいた。</summary>
- <published>2025-04-20T00:00:00+09:00</published>
- <updated>2025-04-20T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/trick/index.html b/vhosts/blog/public/tags/trick/index.html
deleted file mode 100644
index 5cb0388e..00000000
--- a/vhosts/blog/public/tags/trick/index.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2025 nsfisis">
- <meta name="description" content="タグ「TRICK」のついた記事またはスライドの一覧">
- <meta name="keywords" content="TRICK">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「TRICK」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「TRICK」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/trick/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「TRICK」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「TRICK」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/">
- <header class="entry-header">
- <h2>RubyKaigi 2025 の TRICK で入賞した</h2>
- </header>
- <section class="entry-content">
- <p>
- RubyKaigi 2025 で開催された TRICK において、『最もRuby on Ruby賞』として審査員賞をいただいた。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-04-20">2025-04-20</time> 投稿
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/vim/atom.xml b/vhosts/blog/public/tags/vim/atom.xml
deleted file mode 100644
index bb74a2ce..00000000
--- a/vhosts/blog/public/tags/vim/atom.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-vim</id>
- <title>タグ「Vim」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/vim/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/vim/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2024-07-19T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:222488dd-cf07-4961-83aa-a014b05369ff</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-07-19/reparojson-fix-only-json-formatter/"></link>
- <title>reparojson: 文法エラーを直すだけの JSON フォーマッタを作った</title>
- <summary>文法エラーだけを直し、空白の削除や挿入といった整形処理を一切おこなわない JSON フォーマッタを作成した。Neovim と連携させる設定例も紹介する。</summary>
- <published>2024-07-19T00:00:00+09:00</published>
- <updated>2024-07-19T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:44171f75-c312-4c92-9927-3d260e162175</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2021-10-02/vim-difference-between-autocmd-bufwrite-and-bufwritepre/"></link>
- <title>【Vim】 autocmd events の BufWrite/BufWritePre の違い</title>
- <summary>Vim の autocmd events における BufWrite/BufWritePre がどう違うのかを調べた結果、違いはないことがわかった。</summary>
- <published>2021-10-02T00:00:00+09:00</published>
- <updated>2021-10-02T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:665de47e-0ed6-405e-ad30-81c3c4592d45</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2021-10-02/vim-swap-order-of-selected-lines/"></link>
- <title>Vimで選択した行の順番を入れ替える</title>
- <summary>Vim で選択した行の順番を入れ替える方法。</summary>
- <published>2021-10-02T00:00:00+09:00</published>
- <updated>2021-10-02T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/vim/index.html b/vhosts/blog/public/tags/vim/index.html
deleted file mode 100644
index 16adf278..00000000
--- a/vhosts/blog/public/tags/vim/index.html
+++ /dev/null
@@ -1,96 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2021 nsfisis">
- <meta name="description" content="タグ「Vim」のついた記事またはスライドの一覧">
- <meta name="keywords" content="Vim">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「Vim」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「Vim」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/vim/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「Vim」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「Vim」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2024-07-19/reparojson-fix-only-json-formatter/">
- <header class="entry-header">
- <h2>reparojson: 文法エラーを直すだけの JSON フォーマッタを作った</h2>
- </header>
- <section class="entry-content">
- <p>
- 文法エラーだけを直し、空白の削除や挿入といった整形処理を一切おこなわない JSON フォーマッタを作成した。Neovim と連携させる設定例も紹介する。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-07-19">2024-07-19</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2021-10-02/vim-difference-between-autocmd-bufwrite-and-bufwritepre/">
- <header class="entry-header">
- <h2>【Vim】 autocmd events の BufWrite/BufWritePre の違い</h2>
- </header>
- <section class="entry-content">
- <p>
- Vim の autocmd events における BufWrite/BufWritePre がどう違うのかを調べた結果、違いはないことがわかった。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2021-10-02">2021-10-02</time> 投稿
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2021-10-02/vim-swap-order-of-selected-lines/">
- <header class="entry-header">
- <h2>Vimで選択した行の順番を入れ替える</h2>
- </header>
- <section class="entry-content">
- <p>
- Vim で選択した行の順番を入れ替える方法。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2021-10-02">2021-10-02</time> 投稿
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/wasm/atom.xml b/vhosts/blog/public/tags/wasm/atom.xml
deleted file mode 100644
index c0051ba4..00000000
--- a/vhosts/blog/public/tags/wasm/atom.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-wasm</id>
- <title>タグ「WebAssembly」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/wasm/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/wasm/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2025-04-23T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:da7b1d5a-70df-4c4a-936c-1b49ca1a7c37</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-03-15/ya8-2024/"></link>
- <title>CLI の PHP プログラムを限界まで高速化してみる</title>
- <summary>登壇: Ya8 2024 (レギュラートーク (60分))</summary>
- <published>2024-03-15T00:00:00+09:00</published>
- <updated>2024-03-15T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:cee40048-f3c5-4043-9ef8-a4ee2ae7cf0e</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-03-08/phperkaigi-2024/"></link>
- <title>WebAssembly を理解する 〜VM の作成を通して〜</title>
- <summary>登壇: PHPerKaigi 2024 (レギュラートーク (40分))</summary>
- <published>2024-03-08T00:00:00+09:00</published>
- <updated>2024-03-08T00:00:00+09:00</updated>
- </entry>
- <entry>
- <id>urn:uuid:0ed1ccc8-d437-481c-8cca-2131ce800cc0</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2023-10-02/compile-php-runtime-to-wasm/"></link>
- <title>PHP の処理系を Emscripten で WebAssembly にコンパイルする</title>
- <summary>PHP の処理系 (php/php-src) を Emscripten で WebAssembly にコンパイルし、任意のコードを隔離された環境で評価できるようにした。</summary>
- <published>2023-10-02T00:00:00+09:00</published>
- <updated>2025-04-23T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/wasm/index.html b/vhosts/blog/public/tags/wasm/index.html
deleted file mode 100644
index 11b65951..00000000
--- a/vhosts/blog/public/tags/wasm/index.html
+++ /dev/null
@@ -1,96 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2023 nsfisis">
- <meta name="description" content="タグ「WebAssembly」のついた記事またはスライドの一覧">
- <meta name="keywords" content="WebAssembly">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「WebAssembly」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「WebAssembly」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/wasm/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「WebAssembly」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「WebAssembly」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/slides/2024-03-15/ya8-2024/">
- <header class="entry-header">
- <h2>登壇: Ya8 2024 (レギュラートーク (60分))</h2>
- </header>
- <section class="entry-content">
- <p>
- CLI の PHP プログラムを限界まで高速化してみる
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-03-15">2024-03-15</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/slides/2024-03-08/phperkaigi-2024/">
- <header class="entry-header">
- <h2>登壇: PHPerKaigi 2024 (レギュラートーク (40分))</h2>
- </header>
- <section class="entry-content">
- <p>
- WebAssembly を理解する 〜VM の作成を通して〜
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-03-08">2024-03-08</time> 登壇
- </footer>
- </a>
- </article>
- <article class="post-entry">
- <a href="/posts/2023-10-02/compile-php-runtime-to-wasm/">
- <header class="entry-header">
- <h2>PHP の処理系を Emscripten で WebAssembly にコンパイルする</h2>
- </header>
- <section class="entry-content">
- <p>
- PHP の処理系 (php/php-src) を Emscripten で WebAssembly にコンパイルし、任意のコードを隔離された環境で評価できるようにした。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2023-10-02">2023-10-02</time> 投稿、<time datetime="2025-04-23">2025-04-23</time> 更新
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/wireguard/atom.xml b/vhosts/blog/public/tags/wireguard/atom.xml
deleted file mode 100644
index b78c75a9..00000000
--- a/vhosts/blog/public/tags/wireguard/atom.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-wireguard</id>
- <title>タグ「WireGuard」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/wireguard/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/wireguard/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2024-02-17T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:210673d0-c19e-4195-a280-968a0729dd41</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-02-03/install-wireguard-on-personal-server/"></link>
- <title>【備忘録】 個人用サーバに WireGuard を導入する</title>
- <summary>個人用サービスのセルフホストに使っているサーバに WireGuard を導入する作業をしたメモ</summary>
- <published>2024-02-03T00:00:00+09:00</published>
- <updated>2024-02-17T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/wireguard/index.html b/vhosts/blog/public/tags/wireguard/index.html
deleted file mode 100644
index f93950c1..00000000
--- a/vhosts/blog/public/tags/wireguard/index.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="タグ「WireGuard」のついた記事またはスライドの一覧">
- <meta name="keywords" content="WireGuard">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「WireGuard」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「WireGuard」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/wireguard/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「WireGuard」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「WireGuard」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2024-02-03/install-wireguard-on-personal-server/">
- <header class="entry-header">
- <h2>【備忘録】 個人用サーバに WireGuard を導入する</h2>
- </header>
- <section class="entry-content">
- <p>
- 個人用サービスのセルフホストに使っているサーバに WireGuard を導入する作業をしたメモ
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-02-03">2024-02-03</time> 投稿、<time datetime="2024-02-17">2024-02-17</time> 更新
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/ya8/atom.xml b/vhosts/blog/public/tags/ya8/atom.xml
deleted file mode 100644
index ea5360b7..00000000
--- a/vhosts/blog/public/tags/ya8/atom.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-ya8</id>
- <title>タグ「Ya8」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/ya8/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/ya8/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2024-03-15T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:da7b1d5a-70df-4c4a-936c-1b49ca1a7c37</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/slides/2024-03-15/ya8-2024/"></link>
- <title>CLI の PHP プログラムを限界まで高速化してみる</title>
- <summary>登壇: Ya8 2024 (レギュラートーク (60分))</summary>
- <published>2024-03-15T00:00:00+09:00</published>
- <updated>2024-03-15T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/ya8/index.html b/vhosts/blog/public/tags/ya8/index.html
deleted file mode 100644
index bacd8ebd..00000000
--- a/vhosts/blog/public/tags/ya8/index.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="タグ「Ya8」のついた記事またはスライドの一覧">
- <meta name="keywords" content="Ya8">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「Ya8」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「Ya8」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/ya8/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「Ya8」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「Ya8」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/slides/2024-03-15/ya8-2024/">
- <header class="entry-header">
- <h2>登壇: Ya8 2024 (レギュラートーク (60分))</h2>
- </header>
- <section class="entry-content">
- <p>
- CLI の PHP プログラムを限界まで高速化してみる
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-03-15">2024-03-15</time> 登壇
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/yaml/atom.xml b/vhosts/blog/public/tags/yaml/atom.xml
deleted file mode 100644
index 0bc35fa7..00000000
--- a/vhosts/blog/public/tags/yaml/atom.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-yaml</id>
- <title>タグ「YAML」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/yaml/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/yaml/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2025-01-26T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:da2a0cec-74b3-4c5e-b2a2-47fe79ef49f9</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-01-26/yaml-breaking-changes-between-v1-1-and-v1-2/"></link>
- <title>【YAML】YAML 1.1 と YAML 1.2 の主な破壊的変更</title>
- <summary>データ記述言語 YAML におけるバージョン 1.1 と 1.2 の主な破壊的変更をまとめた。</summary>
- <published>2025-01-26T00:00:00+09:00</published>
- <updated>2025-01-26T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/yaml/index.html b/vhosts/blog/public/tags/yaml/index.html
deleted file mode 100644
index 85e3f867..00000000
--- a/vhosts/blog/public/tags/yaml/index.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2025 nsfisis">
- <meta name="description" content="タグ「YAML」のついた記事またはスライドの一覧">
- <meta name="keywords" content="YAML">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「YAML」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「YAML」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/yaml/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「YAML」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「YAML」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2025-01-26/yaml-breaking-changes-between-v1-1-and-v1-2/">
- <header class="entry-header">
- <h2>【YAML】YAML 1.1 と YAML 1.2 の主な破壊的変更</h2>
- </header>
- <section class="entry-content">
- <p>
- データ記述言語 YAML におけるバージョン 1.1 と 1.2 の主な破壊的変更をまとめた。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2025-01-26">2025-01-26</time> 投稿
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/yapc/atom.xml b/vhosts/blog/public/tags/yapc/atom.xml
deleted file mode 100644
index f9c92e69..00000000
--- a/vhosts/blog/public/tags/yapc/atom.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-yapc</id>
- <title>タグ「YAPC」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/yapc/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/yapc/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2024-02-10T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:230a0048-93c0-4aac-91ef-bb3108f3e587</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-02-10/yapcjapan-2024-report/"></link>
- <title>YAPC::Hiroshima 2024 参加レポ</title>
- <summary>2024-02-10 に開催された、YAPC::Hiroshima 2024 に参加した。</summary>
- <published>2024-02-10T00:00:00+09:00</published>
- <updated>2024-02-10T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/yapc/index.html b/vhosts/blog/public/tags/yapc/index.html
deleted file mode 100644
index 101e020e..00000000
--- a/vhosts/blog/public/tags/yapc/index.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="タグ「YAPC」のついた記事またはスライドの一覧">
- <meta name="keywords" content="YAPC">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「YAPC」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「YAPC」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/yapc/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「YAPC」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「YAPC」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2024-02-10/yapcjapan-2024-report/">
- <header class="entry-header">
- <h2>YAPC::Hiroshima 2024 参加レポ</h2>
- </header>
- <section class="entry-content">
- <p>
- 2024-02-10 に開催された、YAPC::Hiroshima 2024 に参加した。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-02-10">2024-02-10</time> 投稿
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>
diff --git a/vhosts/blog/public/tags/zsh/atom.xml b/vhosts/blog/public/tags/zsh/atom.xml
deleted file mode 100644
index 9100fff5..00000000
--- a/vhosts/blog/public/tags/zsh/atom.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>tag:blog.nsfisis.dev,2021:tag-zsh</id>
- <title>タグ「Zsh」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="alternate" href="https://blog.nsfisis.dev/tags/zsh/"></link>
- <link rel="self" href="https://blog.nsfisis.dev/tags/zsh/atom.xml"></link>
- <author>
- <name>nsfisis</name>
- </author>
- <updated>2024-04-29T00:00:00+09:00</updated>
- <entry>
- <id>urn:uuid:9b26c1ed-45c3-4cad-9476-cbf2cf2e4de7</id>
- <link rel="alternate" href="https://blog.nsfisis.dev/posts/2024-04-29/zsh-file-completion-for-composer-custom-commands/"></link>
- <title>【Zsh】 Composer のカスタムコマンドに対する Zsh 補完で引数にファイルを補完させる</title>
- <summary>Zsh の Composer に対する補完はカスタムコマンドやその引数を補完しない。カスタムコマンドの引数としてファイルを補完させる方法を調べた。</summary>
- <published>2024-04-29T00:00:00+09:00</published>
- <updated>2024-04-29T00:00:00+09:00</updated>
- </entry>
-</feed>
diff --git a/vhosts/blog/public/tags/zsh/index.html b/vhosts/blog/public/tags/zsh/index.html
deleted file mode 100644
index 2d519848..00000000
--- a/vhosts/blog/public/tags/zsh/index.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja-JP">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="author" content="nsfisis">
- <meta name="copyright" content="&copy; 2024 nsfisis">
- <meta name="description" content="タグ「Zsh」のついた記事またはスライドの一覧">
- <meta name="keywords" content="Zsh">
- <meta property="og:type" content="article">
- <meta property="og:title" content="タグ「Zsh」一覧|REPL: Rest-Eat-Program Loop">
- <meta property="og:description" content="タグ「Zsh」のついた記事またはスライドの一覧">
- <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
- <meta property="og:locale" content="ja_JP">
- <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/zsh/atom.xml">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
- <title>タグ「Zsh」一覧|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
- </head>
- <body class="list">
- <header class="header">
- <div class="site-logo">
- <a href="/">REPL: Rest-Eat-Program Loop</a>
- </div>
- <nav class="nav">
- <ul>
- <li>
- <a href="/about/">About</a>
- </li>
- <li>
- <a href="/posts/">Posts</a>
- </li>
- <li>
- <a href="/slides/">Slides</a>
- </li>
- <li>
- <a href="/tags/">Tags</a>
- </li>
- </ul>
- </nav>
- </header>
- <main class="main">
- <header class="page-header">
- <h1>タグ「Zsh」一覧</h1>
- </header>
- <article class="post-entry">
- <a href="/posts/2024-04-29/zsh-file-completion-for-composer-custom-commands/">
- <header class="entry-header">
- <h2>【Zsh】 Composer のカスタムコマンドに対する Zsh 補完で引数にファイルを補完させる</h2>
- </header>
- <section class="entry-content">
- <p>
- Zsh の Composer に対する補完はカスタムコマンドやその引数を補完しない。カスタムコマンドの引数としてファイルを補完させる方法を調べた。
- </p>
- </section>
- <footer class="entry-footer">
- <time datetime="2024-04-29">2024-04-29</time> 投稿
- </footer>
- </a>
- </article>
- </main>
- <footer class="footer">
- &copy; 2021 nsfisis
- </footer>
- </body>
-</html>