Alecriar Studioの中の人の技術メモ

横浜の個人事業主が日々の技術的な情報をつづります

家庭内LANをIPv6対応にするお話 01 - IPv6とは

インターネットの根幹技術 TCP/IP

TCP/IP はインターネットの代名詞とも言える技術で、黎明期からインターネットを支え続けてきました。TCPは「Transmission Control Protocol」、IPは「Internet Protocol」のことを指します。TCP については割愛しまして、今回は IP についてのお話です。

初期から存在した IP は IPv4 といい、 v4 はバージョン4であることを示します。IP は端的に言えばIPアドレスのことであり、インターネット上の住所を表現するためにこの技術が使用されました。

IPv4 では、IPアドレスは「XXX.XXX.XXX.XXX」といった表記になります。Xは0~9の数字で、最大でもわずか15文字の数字とピリオドのみで構成されています。インターネットに接続されている世の中のすべての機器はこのIPアドレスを持ち、それぞれが世界で一つしかなく(重複してはいけない)、そのためにIPアドレスを指し示して互いに通信することができるようになりました。

しかし、状況がかわりつつあります。

IPアドレス枯渇問題

www.nic.ad.jp

IPv4では、それぞれのノードごとの数字の範囲が0~255の範囲に限られており、最小の数値の「0.0.0.0」から最大の数値の「255.255.255.255」までが有効なIPアドレスとなります。これを2進数に直すと32桁となり、それにより総数としては2の32乗、つまり約43億個のIPアドレスが存在します。

しかし、この約43億個という数字は多いようで少ないです。世界の人口が70億人にも達しようという今日、一人ひとりに1つのIPアドレスを配ることができません。その上、多くの人がPCやスマートフォンなどの情報機器を複数所持しており、それにはそれぞれIPアドレスが割り振られているため、ひとりで複数のIPアドレスを使用している現状です。

日本におけるIPアドレスの管理機関であるJPNICでも公式声明が出されている通り、世界中でIPアドレスの枯渇問題が浮かび上がっており、日本においてもあと3年ほどで完全に枯渇するといわれています。

では、どうするのかという問いに対しての答えは、既存の IPv4 に代わる新しいIP技術を作り、それを今後の標準にしていくということでした。それが IPv6 です。

IPv6 にするには

f:id:alecriarstudio:20200122212103p:plain

まず、IPv4 から比べると、割り当てられるIPアドレスが大幅に増えました。

表記は以下のようなものになります。

IPv6の表記 「XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX」

0~Fまでの4桁の16進数をコロンで区切り、それを8つ並べたものとなります。これを2進数で表すと128桁となり、総数としては2の128乗(約340澗)という途方もない数値となります。IPアドレスの枯渇についてはこれでほぼ解消されます。

では、ただ単に IPアドレス の表記がかわるだけなら、いままで IPv4 で構築した家庭内LAN環境も IPアドレスの部分だけ書き換えていけば IPv6 対応になるのではないか、と考えるところですが、事はそう単純には済まされません。

このお話の続きはまた次回です。

Vue CLIを使用してVue.jsをインストール

インストール方法の選択肢

Vue.js をインストールするにはいくつかの選択肢があります。

  • CDNから直接参照する方法

  • npmでインストールする方法

  • 公式のツール Vue CLI を使用する方法

いずれの方法でも Vue.js を使用できますが、今回は Vue CLI を使用したインストール方法を紹介します。Vue.js をフルスペックで使用でき、大規模向け開発に向いています。

Node.js をインストール

Vue CLI を使用するには Node.js を先にインストールします。 公式サイトにアクセスし、最新版をダウンロードしインストールします。

nodejs.org

または、Chocolateyでパッケージ管理を行っている場合は、コマンドから導入することもできます。

> choco install nodejs -y

PowerShellまたはコマンドラインで、以下のバージョン情報が表示されれば正常にインストールされています。バージョン番号はインストールした時点で異なります。

> node -v
v13.6.0

>  npm -v
6.13.4

Vue CLI 4 をインストール

現時点での Vue CLI はバージョン4が公開されています。こちらのインストールもコマンドで行います。 PowerShell またはコマンドラインで以下のコマンドを実行します。

> npm install -g @vue/cli

正常にインストールされた場合、以下のようにバージョン番号が表示されます。

> vue --version
@vue/cli 4.1.2

以上でインストールは終了です。とても簡単。 ここからプロジェクトを作成したり、実際の開発を行っていきます。

(参考)Vue CLI 4 でインストールされるツール群

Vue CLI は Vue.js の開発で利用されるさまざまな多種多様のツールを一つにまとめた集合体です。以下のようにインストールされたパッケージ一覧を表示してみると、非常に多くのツールがインストールされることがわかります。

> npm list -g
C:\Users\[ユーザー名]\AppData\Roaming\npm
`-- @vue/cli@4.1.2
  +-- @vue/cli-shared-utils@4.1.2
  | +-- @hapi/joi@15.1.1
  | | +-- @hapi/address@2.1.4
  | | +-- @hapi/bourne@1.3.2
  | | +-- @hapi/hoek@8.5.0
  | | `-- @hapi/topo@3.1.6
  | |   `-- @hapi/hoek@8.5.0 deduped
  | +-- chalk@2.4.2
  | | +-- ansi-styles@3.2.1
  | | | `-- color-convert@1.9.3
  | | |   `-- color-name@1.1.3
  | | +-- escape-string-regexp@1.0.5
  | | `-- supports-color@5.5.0
  | |   `-- has-flag@3.0.0
  | +-- execa@1.0.0
  | | +-- cross-spawn@6.0.5
  | | | +-- nice-try@1.0.5
  | | | +-- path-key@2.0.1
  | | | +-- semver@5.7.1
  | | | +-- shebang-command@1.2.0
  | | | | `-- shebang-regex@1.0.0
  | | | `-- which@1.3.1 deduped
  | | +-- get-stream@4.1.0
  | | | `-- pump@3.0.0
  | | |   +-- end-of-stream@1.4.4
  | | |   | `-- once@1.4.0 deduped
  | | |   `-- once@1.4.0 deduped
  | | +-- is-stream@1.1.0
  | | +-- npm-run-path@2.0.2
  | | | `-- path-key@2.0.1 deduped
  | | +-- p-finally@1.0.0
  | | +-- signal-exit@3.0.2
  | | `-- strip-eof@1.0.0
  | +-- launch-editor@2.2.1
  | | +-- chalk@2.4.2 deduped
  | | `-- shell-quote@1.7.2
  | +-- lru-cache@5.1.1 deduped
  | +-- node-ipc@9.1.1
  | | +-- event-pubsub@4.3.0
  | | +-- js-message@1.0.5
  | | `-- js-queue@2.0.0
  | |   `-- easy-stack@1.0.0
  | +-- open@6.4.0
  | | `-- is-wsl@1.1.0
  | +-- ora@3.4.0
  | | +-- chalk@2.4.2 deduped
  | | +-- cli-cursor@2.1.0 deduped
  | | +-- cli-spinners@2.2.0
  | | +-- log-symbols@2.2.0
  | | | `-- chalk@2.4.2 deduped
  | | +-- strip-ansi@5.2.0
  | | | `-- ansi-regex@4.1.0 deduped
  | | `-- wcwidth@1.0.1
  | |   `-- defaults@1.0.3
  | |     `-- clone@1.0.4
  | +-- request@2.88.0
  | | +-- aws-sign2@0.7.0
  | | +-- aws4@1.9.1
  | | +-- caseless@0.12.0
  | | +-- combined-stream@1.0.8
  | | | `-- delayed-stream@1.0.0
  | | +-- extend@3.0.2
  | | +-- forever-agent@0.6.1
  | | +-- form-data@2.3.3
  | | | +-- asynckit@0.4.0
  | | | +-- combined-stream@1.0.8 deduped
  | | | `-- mime-types@2.1.26 deduped
  | | +-- har-validator@5.1.3
  | | | +-- ajv@6.10.2
  | | | | +-- fast-deep-equal@2.0.1
  | | | | +-- fast-json-stable-stringify@2.1.0 deduped
  | | | | +-- json-schema-traverse@0.4.1
  | | | | `-- uri-js@4.2.2
  | | | |   `-- punycode@2.1.1
  | | | `-- har-schema@2.0.0
  | | +-- http-signature@1.2.0
  | | | +-- assert-plus@1.0.0
  | | | +-- jsprim@1.4.1
  | | | | +-- assert-plus@1.0.0 deduped
  | | | | +-- extsprintf@1.3.0
  | | | | +-- json-schema@0.2.3
  | | | | `-- verror@1.10.0
  | | | |   +-- assert-plus@1.0.0 deduped
  | | | |   +-- core-util-is@1.0.2
  | | | |   `-- extsprintf@1.3.0 deduped
  | | | `-- sshpk@1.16.1
  | | |   +-- asn1@0.2.4
  | | |   | `-- safer-buffer@2.1.2 deduped
  | | |   +-- assert-plus@1.0.0 deduped
  | | |   +-- bcrypt-pbkdf@1.0.2
  | | |   | `-- tweetnacl@0.14.5 deduped
  | | |   +-- dashdash@1.14.1
  | | |   | `-- assert-plus@1.0.0 deduped
  | | |   +-- ecc-jsbn@0.1.2
  | | |   | +-- jsbn@0.1.1 deduped
  | | |   | `-- safer-buffer@2.1.2 deduped
  | | |   +-- getpass@0.1.7
  | | |   | `-- assert-plus@1.0.0 deduped
  | | |   +-- jsbn@0.1.1
  | | |   +-- safer-buffer@2.1.2 deduped
  | | |   `-- tweetnacl@0.14.5
  | | +-- is-typedarray@1.0.0
  | | +-- isstream@0.1.2
  | | +-- json-stringify-safe@5.0.1
  | | +-- mime-types@2.1.26
  | | | `-- mime-db@1.43.0
  | | +-- oauth-sign@0.9.0
  | | +-- performance-now@2.1.0
  | | +-- qs@6.5.2
  | | +-- safe-buffer@5.2.0
  | | +-- tough-cookie@2.4.3
  | | | +-- psl@1.7.0
  | | | `-- punycode@1.4.1
  | | +-- tunnel-agent@0.6.0
  | | | `-- safe-buffer@5.2.0 deduped
  | | `-- uuid@3.3.3
  | +-- request-promise-native@1.0.8
  | | +-- request-promise-core@1.1.3
  | | | `-- lodash@4.17.15 deduped
  | | +-- stealthy-require@1.1.1
  | | `-- tough-cookie@2.4.3 deduped
  | +-- semver@6.3.0
  | `-- strip-ansi@6.0.0
  |   `-- ansi-regex@5.0.0
  +-- @vue/cli-ui@4.1.2
  | +-- @akryum/winattr@3.0.0
  | | `-- fswin@2.17.1227
  | +-- @vue/cli-shared-utils@4.1.2 deduped
  | +-- clone@2.1.2
  | +-- deepmerge@3.3.0 deduped
  | +-- express-history-api-fallback@2.2.1
  | +-- fkill@6.2.0
  | | +-- aggregate-error@3.0.1
  | | | +-- clean-stack@2.2.0
  | | | `-- indent-string@4.0.0 deduped
  | | +-- arrify@2.0.1
  | | +-- execa@1.0.0 deduped
  | | +-- pid-from-port@1.1.3
  | | | `-- execa@0.9.0
  | | |   +-- cross-spawn@5.1.0
  | | |   | +-- lru-cache@4.1.5
  | | |   | | +-- pseudomap@1.0.2
  | | |   | | `-- yallist@2.1.2
  | | |   | +-- shebang-command@1.2.0 deduped
  | | |   | `-- which@1.3.1 deduped
  | | |   +-- get-stream@3.0.0
  | | |   +-- is-stream@1.1.0 deduped
  | | |   +-- npm-run-path@2.0.2 deduped
  | | |   +-- p-finally@1.0.0 deduped
  | | |   +-- signal-exit@3.0.2 deduped
  | | |   `-- strip-eof@1.0.0 deduped
  | | +-- process-exists@3.1.0
  | | | `-- ps-list@4.1.0
  | | |   +-- pify@3.0.0 deduped
  | | |   `-- tasklist@3.1.1
  | | |     +-- neat-csv@2.1.0
  | | |     | +-- csv-parser@1.12.1
  | | |     | | +-- buffer-alloc@1.2.0 deduped
  | | |     | | +-- buffer-from@1.1.1 deduped
  | | |     | | +-- generate-function@1.1.0
  | | |     | | +-- generate-object-property@1.2.0
  | | |     | | | `-- is-property@1.0.2
  | | |     | | +-- inherits@2.0.4 deduped
  | | |     | | +-- minimist@1.2.0 deduped
  | | |     | | `-- ndjson@1.5.0
  | | |     | |   +-- json-stringify-safe@5.0.1 deduped
  | | |     | |   +-- minimist@1.2.0 deduped
  | | |     | |   +-- split2@2.2.0
  | | |     | |   | `-- through2@2.0.5 deduped
  | | |     | |   `-- through2@2.0.5
  | | |     | |     +-- readable-stream@2.3.7 deduped
  | | |     | |     `-- xtend@4.0.2 deduped
  | | |     | +-- get-stream@2.3.1
  | | |     | | +-- object-assign@4.1.1 deduped
  | | |     | | `-- pinkie-promise@2.0.1 deduped
  | | |     | `-- into-stream@2.0.1
  | | |     |   `-- from2@2.3.0
  | | |     |     +-- inherits@2.0.4 deduped
  | | |     |     `-- readable-stream@2.3.7 deduped
  | | |     +-- pify@2.3.0
  | | |     `-- sec@1.0.0
  | | `-- taskkill@3.1.0
  | |   +-- arrify@2.0.1 deduped
  | |   `-- execa@3.4.0
  | |     +-- cross-spawn@7.0.1
  | |     | +-- path-key@3.1.1
  | |     | +-- shebang-command@2.0.0
  | |     | | `-- shebang-regex@3.0.0
  | |     | `-- which@2.0.2
  | |     |   `-- isexe@2.0.0 deduped
  | |     +-- get-stream@5.1.0
  | |     | `-- pump@3.0.0 deduped
  | |     +-- human-signals@1.1.1 deduped
  | |     +-- is-stream@2.0.0
  | |     +-- merge-stream@2.0.0 deduped
  | |     +-- npm-run-path@4.0.1
  | |     | `-- path-key@3.1.1 deduped
  | |     +-- onetime@5.1.0
  | |     | `-- mimic-fn@2.1.0
  | |     +-- p-finally@2.0.1
  | |     +-- signal-exit@3.0.2 deduped
  | |     `-- strip-final-newline@2.0.0 deduped
  | +-- fs-extra@7.0.1 deduped
  | +-- globby@9.2.0 deduped
  | +-- graphql@14.5.8
  | | `-- iterall@1.3.0
  | +-- graphql-subscriptions@1.1.0
  | | `-- iterall@1.3.0 deduped
  | +-- graphql-tag@2.10.1
  | +-- graphql-type-json@0.3.1
  | +-- javascript-stringify@1.6.0 deduped
  | +-- js-yaml@3.13.1 deduped
  | +-- lodash.merge@4.6.2
  | +-- lowdb@1.0.0
  | | +-- graceful-fs@4.2.3 deduped
  | | +-- is-promise@2.1.0
  | | +-- lodash@4.17.15 deduped
  | | +-- pify@3.0.0
  | | `-- steno@0.4.4
  | |   `-- graceful-fs@4.2.3 deduped
  | +-- lru-cache@5.1.1 deduped
  | +-- node-ipc@9.1.1 deduped
  | +-- node-notifier@5.4.3
  | | +-- growly@1.3.0
  | | +-- is-wsl@1.1.0 deduped
  | | +-- semver@5.7.1
  | | +-- shellwords@0.1.1
  | | `-- which@1.3.1
  | |   `-- isexe@2.0.0
  | +-- parse-git-config@2.0.3
  | | +-- expand-tilde@2.0.2
  | | | `-- homedir-polyfill@1.0.3
  | | |   `-- parse-passwd@1.0.0
  | | +-- git-config-path@1.0.1
  | | | +-- extend-shallow@2.0.1
  | | | | `-- is-extendable@0.1.1
  | | | +-- fs-exists-sync@0.1.0
  | | | `-- homedir-polyfill@1.0.3 deduped
  | | `-- ini@1.3.5
  | +-- portfinder@1.0.25
  | | +-- async@2.6.3
  | | | `-- lodash@4.17.15 deduped
  | | +-- debug@3.2.6
  | | | `-- ms@2.1.2
  | | `-- mkdirp@0.5.1 deduped
  | +-- prismjs@1.19.0
  | | `-- clipboard@2.0.4
  | |   +-- good-listener@1.2.2
  | |   | `-- delegate@3.2.0
  | |   +-- select@1.1.2
  | |   `-- tiny-emitter@2.1.0
  | +-- rss-parser@3.7.3
  | | +-- entities@1.1.2
  | | `-- xml2js@0.4.23
  | |   +-- sax@1.2.4
  | |   `-- xmlbuilder@11.0.1
  | +-- shortid@2.2.15 deduped
  | +-- typescript@3.7.4
  | +-- vue-cli-plugin-apollo@0.21.3
  | | +-- apollo@2.21.3
  | | | +-- @apollographql/apollo-tools@0.4.3
  | | | | `-- apollo-env@0.6.1 deduped
  | | | +-- @oclif/command@1.5.19
  | | | | +-- @oclif/config@1.13.3 deduped
  | | | | +-- @oclif/errors@1.2.2 deduped
  | | | | +-- @oclif/parser@3.8.4
  | | | | | +-- @oclif/linewrap@1.0.0
  | | | | | +-- chalk@2.4.2 deduped
  | | | | | `-- tslib@1.10.0 deduped
  | | | | +-- @oclif/plugin-help@2.2.3 deduped
  | | | | +-- debug@4.1.1 deduped
  | | | | `-- semver@5.7.1
  | | | +-- @oclif/config@1.13.3
  | | | | +-- @oclif/parser@3.8.4 deduped
  | | | | +-- debug@4.1.1 deduped
  | | | | `-- tslib@1.10.0 deduped
  | | | +-- @oclif/errors@1.2.2
  | | | | +-- clean-stack@1.3.0
  | | | | +-- fs-extra@7.0.1 deduped
  | | | | +-- indent-string@3.2.0
  | | | | +-- strip-ansi@5.2.0
  | | | | | `-- ansi-regex@4.1.0 deduped
  | | | | `-- wrap-ansi@4.0.0
  | | | |   +-- ansi-styles@3.2.1 deduped
  | | | |   +-- string-width@2.1.1 deduped
  | | | |   `-- strip-ansi@4.0.0
  | | | |     `-- ansi-regex@3.0.0
  | | | +-- @oclif/plugin-autocomplete@0.1.5
  | | | | +-- @oclif/command@1.5.19 deduped
  | | | | +-- @oclif/config@1.13.3 deduped
  | | | | +-- chalk@2.4.2 deduped
  | | | | +-- cli-ux@4.9.3
  | | | | | +-- @oclif/errors@1.2.2 deduped
  | | | | | +-- @oclif/linewrap@1.0.0 deduped
  | | | | | +-- @oclif/screen@1.0.4
  | | | | | +-- ansi-escapes@3.2.0 deduped
  | | | | | +-- ansi-styles@3.2.1 deduped
  | | | | | +-- cardinal@2.1.1
  | | | | | | +-- ansicolors@0.3.2
  | | | | | | `-- redeyed@2.1.1
  | | | | | |   `-- esprima@4.0.1 deduped
  | | | | | +-- chalk@2.4.2 deduped
  | | | | | +-- clean-stack@2.2.0 deduped
  | | | | | +-- extract-stack@1.0.0
  | | | | | +-- fs-extra@7.0.1 deduped
  | | | | | +-- hyperlinker@1.0.0
  | | | | | +-- indent-string@3.2.0
  | | | | | +-- is-wsl@1.1.0 deduped
  | | | | | +-- lodash@4.17.15 deduped
  | | | | | +-- password-prompt@1.1.2
  | | | | | | +-- ansi-escapes@3.2.0 deduped
  | | | | | | `-- cross-spawn@6.0.5 deduped
  | | | | | +-- semver@5.7.1
  | | | | | +-- strip-ansi@5.2.0
  | | | | | | `-- ansi-regex@4.1.0 deduped
  | | | | | +-- supports-color@5.5.0 deduped
  | | | | | +-- supports-hyperlinks@1.0.1
  | | | | | | +-- has-flag@2.0.0
  | | | | | | `-- supports-color@5.5.0 deduped
  | | | | | +-- treeify@1.1.0
  | | | | | `-- tslib@1.10.0 deduped
  | | | | +-- debug@3.2.6
  | | | | | `-- ms@2.1.2
  | | | | +-- fs-extra@6.0.1
  | | | | | +-- graceful-fs@4.2.3 deduped
  | | | | | +-- jsonfile@4.0.0 deduped
  | | | | | `-- universalify@0.1.2 deduped
  | | | | `-- moment@2.24.0 deduped
  | | | +-- @oclif/plugin-help@2.2.3
  | | | | +-- @oclif/command@1.5.19 deduped
  | | | | +-- chalk@2.4.2 deduped
  | | | | +-- indent-string@4.0.0 deduped
  | | | | +-- lodash.template@4.5.0
  | | | | | +-- lodash._reinterpolate@3.0.0
  | | | | | `-- lodash.templatesettings@4.2.0
  | | | | |   `-- lodash._reinterpolate@3.0.0 deduped
  | | | | +-- string-width@3.1.0
  | | | | | +-- emoji-regex@7.0.3 deduped
  | | | | | +-- is-fullwidth-code-point@2.0.0 deduped
  | | | | | `-- strip-ansi@5.2.0 deduped
  | | | | +-- strip-ansi@5.2.0
  | | | | | `-- ansi-regex@4.1.0 deduped
  | | | | +-- widest-line@2.0.1
  | | | | | `-- string-width@2.1.1 deduped
  | | | | `-- wrap-ansi@4.0.0 deduped
  | | | +-- @oclif/plugin-not-found@1.2.3
  | | | | +-- @oclif/color@0.0.0
  | | | | | +-- ansi-styles@3.2.1 deduped
  | | | | | +-- supports-color@5.5.0 deduped
  | | | | | `-- tslib@1.10.0 deduped
  | | | | +-- @oclif/command@1.5.19 deduped
  | | | | +-- cli-ux@4.9.3 deduped
  | | | | +-- fast-levenshtein@2.0.6
  | | | | `-- lodash@4.17.15 deduped
  | | | +-- @oclif/plugin-plugins@1.7.9
  | | | | +-- @oclif/color@0.0.0 deduped
  | | | | +-- @oclif/command@1.5.19 deduped
  | | | | +-- chalk@2.4.2 deduped
  | | | | +-- cli-ux@5.4.1
  | | | | | +-- @oclif/command@1.5.19 deduped
  | | | | | +-- @oclif/errors@1.2.2 deduped
  | | | | | +-- @oclif/linewrap@1.0.0 deduped
  | | | | | +-- @oclif/screen@1.0.4 deduped
  | | | | | +-- ansi-escapes@3.2.0 deduped
  | | | | | +-- ansi-styles@3.2.1 deduped
  | | | | | +-- cardinal@2.1.1 deduped
  | | | | | +-- chalk@2.4.2 deduped
  | | | | | +-- clean-stack@2.2.0 deduped
  | | | | | +-- cli-progress@3.5.0
  | | | | | | +-- colors@1.4.0 deduped
  | | | | | | `-- string-width@2.1.1 deduped
  | | | | | +-- extract-stack@1.0.0 deduped
  | | | | | +-- fs-extra@7.0.1 deduped
  | | | | | +-- hyperlinker@1.0.0 deduped
  | | | | | +-- indent-string@4.0.0 deduped
  | | | | | +-- is-wsl@1.1.0 deduped
  | | | | | +-- js-yaml@3.13.1 deduped
  | | | | | +-- lodash@4.17.15 deduped
  | | | | | +-- natural-orderby@2.0.3
  | | | | | +-- password-prompt@1.1.2 deduped
  | | | | | +-- semver@5.7.1 deduped
  | | | | | +-- string-width@3.1.0
  | | | | | | +-- emoji-regex@7.0.3 deduped
  | | | | | | +-- is-fullwidth-code-point@2.0.0 deduped
  | | | | | | `-- strip-ansi@5.2.0 deduped
  | | | | | +-- strip-ansi@5.2.0
  | | | | | | `-- ansi-regex@4.1.0 deduped
  | | | | | +-- supports-color@5.5.0 deduped
  | | | | | +-- supports-hyperlinks@1.0.1 deduped
  | | | | | +-- treeify@1.1.0 deduped
  | | | | | `-- tslib@1.10.0 deduped
  | | | | +-- debug@4.1.1 deduped
  | | | | +-- fs-extra@7.0.1 deduped
  | | | | +-- http-call@5.3.0
  | | | | | +-- content-type@1.0.4 deduped
  | | | | | +-- debug@4.1.1 deduped
  | | | | | +-- is-retry-allowed@1.2.0 deduped
  | | | | | +-- is-stream@2.0.0
  | | | | | +-- parse-json@4.0.0
  | | | | | | +-- error-ex@1.3.2
  | | | | | | | `-- is-arrayish@0.2.1
  | | | | | | `-- json-parse-better-errors@1.0.2
  | | | | | `-- tunnel-agent@0.6.0 deduped
  | | | | +-- load-json-file@5.3.0
  | | | | | +-- graceful-fs@4.2.3 deduped
  | | | | | +-- parse-json@4.0.0 deduped
  | | | | | +-- pify@4.0.1
  | | | | | +-- strip-bom@3.0.0
  | | | | | `-- type-fest@0.3.1
  | | | | +-- npm-run-path@3.1.0
  | | | | | `-- path-key@3.1.1
  | | | | +-- semver@5.7.1
  | | | | +-- tslib@1.10.0 deduped
  | | | | `-- yarn@1.21.1
  | | | +-- @oclif/plugin-warn-if-update-available@1.7.0
  | | | | +-- @oclif/command@1.5.19 deduped
  | | | | +-- @oclif/config@1.13.3 deduped
  | | | | +-- @oclif/errors@1.2.2 deduped
  | | | | +-- chalk@2.4.2 deduped
  | | | | +-- debug@4.1.1 deduped
  | | | | +-- fs-extra@7.0.1 deduped
  | | | | +-- http-call@5.3.0 deduped
  | | | | +-- lodash.template@4.5.0 deduped
  | | | | `-- semver@5.7.1
  | | | +-- apollo-codegen-core@0.35.10
  | | | | +-- @babel/generator@7.7.7
  | | | | | +-- @babel/types@7.7.4 deduped
  | | | | | +-- jsesc@2.5.2 deduped
  | | | | | +-- lodash@4.17.15 deduped
  | | | | | `-- source-map@0.5.7 deduped
  | | | | +-- @babel/parser@7.8.3 deduped
  | | | | +-- @babel/types@7.7.4
  | | | | | +-- esutils@2.0.3 deduped
  | | | | | +-- lodash@4.17.15 deduped
  | | | | | `-- to-fast-properties@2.0.0 deduped
  | | | | +-- apollo-env@0.6.1 deduped
  | | | | +-- apollo-language-server@1.18.0 deduped
  | | | | +-- ast-types@0.13.2 deduped
  | | | | +-- common-tags@1.8.0
  | | | | `-- recast@0.18.5 deduped
  | | | +-- apollo-codegen-flow@0.33.35
  | | | | +-- @babel/generator@7.7.7 deduped
  | | | | +-- @babel/types@7.7.4 deduped
  | | | | +-- apollo-codegen-core@0.35.10 deduped
  | | | | +-- change-case@3.1.0
  | | | | | +-- camel-case@3.0.0
  | | | | | | +-- no-case@2.3.2 deduped
  | | | | | | `-- upper-case@1.1.3 deduped
  | | | | | +-- constant-case@2.0.0
  | | | | | | +-- snake-case@2.1.0 deduped
  | | | | | | `-- upper-case@1.1.3 deduped
  | | | | | +-- dot-case@2.1.1
  | | | | | | `-- no-case@2.3.2 deduped
  | | | | | +-- header-case@1.0.1
  | | | | | | +-- no-case@2.3.2 deduped
  | | | | | | `-- upper-case@1.1.3 deduped
  | | | | | +-- is-lower-case@1.1.3
  | | | | | | `-- lower-case@1.1.4 deduped
  | | | | | +-- is-upper-case@1.1.2
  | | | | | | `-- upper-case@1.1.3 deduped
  | | | | | +-- lower-case@1.1.4
  | | | | | +-- lower-case-first@1.0.2
  | | | | | | `-- lower-case@1.1.4 deduped
  | | | | | +-- no-case@2.3.2
  | | | | | | `-- lower-case@1.1.4 deduped
  | | | | | +-- param-case@2.1.1
  | | | | | | `-- no-case@2.3.2 deduped
  | | | | | +-- pascal-case@2.0.1
  | | | | | | +-- camel-case@3.0.0 deduped
  | | | | | | `-- upper-case-first@1.1.2 deduped
  | | | | | +-- path-case@2.1.1
  | | | | | | `-- no-case@2.3.2 deduped
  | | | | | +-- sentence-case@2.1.1
  | | | | | | +-- no-case@2.3.2 deduped
  | | | | | | `-- upper-case-first@1.1.2 deduped
  | | | | | +-- snake-case@2.1.0
  | | | | | | `-- no-case@2.3.2 deduped
  | | | | | +-- swap-case@1.1.2
  | | | | | | +-- lower-case@1.1.4 deduped
  | | | | | | `-- upper-case@1.1.3 deduped
  | | | | | +-- title-case@2.1.1
  | | | | | | +-- no-case@2.3.2 deduped
  | | | | | | `-- upper-case@1.1.3 deduped
  | | | | | +-- upper-case@1.1.3
  | | | | | `-- upper-case-first@1.1.2
  | | | | |   `-- upper-case@1.1.3 deduped
  | | | | +-- common-tags@1.8.0 deduped
  | | | | `-- inflected@2.0.4
  | | | +-- apollo-codegen-scala@0.34.35
  | | | | +-- apollo-codegen-core@0.35.10 deduped
  | | | | +-- change-case@3.1.0 deduped
  | | | | +-- common-tags@1.8.0 deduped
  | | | | `-- inflected@2.0.4 deduped
  | | | +-- apollo-codegen-swift@0.35.15
  | | | | +-- apollo-codegen-core@0.35.10 deduped
  | | | | +-- change-case@3.1.0 deduped
  | | | | +-- common-tags@1.8.0 deduped
  | | | | `-- inflected@2.0.4 deduped
  | | | +-- apollo-codegen-typescript@0.35.10
  | | | | +-- @babel/generator@7.7.7 deduped
  | | | | +-- @babel/types@7.7.4 deduped
  | | | | +-- apollo-codegen-core@0.35.10 deduped
  | | | | +-- change-case@3.1.0 deduped
  | | | | +-- common-tags@1.8.0 deduped
  | | | | `-- inflected@2.0.4 deduped
  | | | +-- apollo-env@0.6.1
  | | | | +-- @types/node-fetch@2.5.4
  | | | | | `-- @types/node@13.1.6 deduped
  | | | | +-- core-js@3.6.4
  | | | | +-- node-fetch@2.6.0 deduped
  | | | | `-- sha.js@2.4.11
  | | | |   +-- inherits@2.0.4 deduped
  | | | |   `-- safe-buffer@5.2.0 deduped
  | | | +-- apollo-graphql@0.3.7
  | | | | +-- apollo-env@0.6.1 deduped
  | | | | `-- lodash.sortby@4.7.0
  | | | +-- apollo-language-server@1.18.0
  | | | | +-- @apollo/federation@0.11.2
  | | | | | +-- apollo-graphql@0.3.7 deduped
  | | | | | +-- apollo-server-env@2.4.3 deduped
  | | | | | +-- core-js@3.6.4 deduped
  | | | | | `-- lodash.xorby@4.7.0
  | | | | +-- @apollographql/apollo-tools@0.4.3 deduped
  | | | | +-- @apollographql/graphql-language-service-interface@2.0.2
  | | | | | +-- @apollographql/graphql-language-service-parser@2.0.2
  | | | | | | `-- @apollographql/graphql-language-service-types@2.0.2 deduped
  | | | | | +-- @apollographql/graphql-language-service-types@2.0.2
  | | | | | `-- @apollographql/graphql-language-service-utils@2.0.2
  | | | | |   `-- @apollographql/graphql-language-service-types@2.0.2 deduped
  | | | | +-- @endemolshinegroup/cosmiconfig-typescript-loader@1.0.1
  | | | | | +-- lodash.get@4.4.2
  | | | | | +-- make-error@1.3.5 deduped
  | | | | | +-- ts-node@8.6.2 deduped
  | | | | | `-- tslib@1.10.0 deduped
  | | | | +-- apollo-datasource@0.6.4
  | | | | | +-- apollo-server-caching@0.5.1 deduped
  | | | | | `-- apollo-server-env@2.4.3 deduped
  | | | | +-- apollo-env@0.6.1 deduped
  | | | | +-- apollo-graphql@0.3.7 deduped
  | | | | +-- apollo-link@1.2.13 deduped
  | | | | +-- apollo-link-context@1.0.19 deduped
  | | | | +-- apollo-link-error@1.1.12
  | | | | | +-- apollo-link@1.2.13 deduped
  | | | | | +-- apollo-link-http-common@0.2.15 deduped
  | | | | | `-- tslib@1.10.0 deduped
  | | | | +-- apollo-link-http@1.5.16 deduped
  | | | | +-- apollo-server-errors@2.3.4
  | | | | +-- await-to-js@2.1.1
  | | | | +-- core-js@3.6.4 deduped
  | | | | +-- cosmiconfig@5.2.1
  | | | | | +-- import-fresh@2.0.0
  | | | | | | +-- caller-path@2.0.0
  | | | | | | | `-- caller-callsite@2.0.0
  | | | | | | |   `-- callsites@2.0.0
  | | | | | | `-- resolve-from@3.0.0
  | | | | | +-- is-directory@0.3.1
  | | | | | +-- js-yaml@3.13.1 deduped
  | | | | | `-- parse-json@4.0.0 deduped
  | | | | +-- dotenv@8.2.0 deduped
  | | | | +-- glob@7.1.6 deduped
  | | | | +-- graphql@14.5.8 deduped
  | | | | +-- graphql-tag@2.10.1 deduped
  | | | | +-- lodash.debounce@4.0.8
  | | | | +-- lodash.merge@4.6.2 deduped
  | | | | +-- minimatch@3.0.4 deduped
  | | | | +-- moment@2.24.0 deduped
  | | | | +-- vscode-languageserver@5.2.1
  | | | | | +-- vscode-languageserver-protocol@3.14.1
  | | | | | | +-- vscode-jsonrpc@4.0.0
  | | | | | | `-- vscode-languageserver-types@3.14.0
  | | | | | `-- vscode-uri@1.0.6 deduped
  | | | | `-- vscode-uri@1.0.6 deduped
  | | | +-- chalk@2.4.2 deduped
  | | | +-- env-ci@3.2.2
  | | | | +-- execa@1.0.0 deduped
  | | | | `-- java-properties@1.0.2
  | | | +-- gaze@1.1.3
  | | | | `-- globule@1.3.0
  | | | |   +-- glob@7.1.6 deduped
  | | | |   +-- lodash@4.17.15 deduped
  | | | |   `-- minimatch@3.0.4 deduped
  | | | +-- git-parse@1.0.3
  | | | | +-- babel-polyfill@6.26.0
  | | | | | +-- babel-runtime@6.26.0
  | | | | | | +-- core-js@2.6.11
  | | | | | | `-- regenerator-runtime@0.11.1
  | | | | | +-- core-js@2.6.11
  | | | | | `-- regenerator-runtime@0.10.5
  | | | | +-- byline@5.0.0
  | | | | `-- util.promisify@1.0.0
  | | | |   +-- define-properties@1.1.3
  | | | |   | `-- object-keys@1.1.1 deduped
  | | | |   `-- object.getownpropertydescriptors@2.1.0
  | | | |     +-- define-properties@1.1.3 deduped
  | | | |     `-- es-abstract@1.17.0
  | | | |       +-- es-to-primitive@1.2.1
  | | | |       | +-- is-callable@1.1.5 deduped
  | | | |       | +-- is-date-object@1.0.2
  | | | |       | `-- is-symbol@1.0.3
  | | | |       |   `-- has-symbols@1.0.1 deduped
  | | | |       +-- function-bind@1.1.1 deduped
  | | | |       +-- has@1.0.3
  | | | |       | `-- function-bind@1.1.1 deduped
  | | | |       +-- has-symbols@1.0.1 deduped
  | | | |       +-- is-callable@1.1.5
  | | | |       +-- is-regex@1.0.5
  | | | |       | `-- has@1.0.3 deduped
  | | | |       +-- object-inspect@1.7.0
  | | | |       +-- object-keys@1.1.1 deduped
  | | | |       +-- object.assign@4.1.0 deduped
  | | | |       +-- string.prototype.trimleft@2.1.1
  | | | |       | +-- define-properties@1.1.3 deduped
  | | | |       | `-- function-bind@1.1.1 deduped
  | | | |       `-- string.prototype.trimright@2.1.1
  | | | |         +-- define-properties@1.1.3 deduped
  | | | |         `-- function-bind@1.1.1 deduped
  | | | +-- git-rev-sync@1.12.0
  | | | | +-- escape-string-regexp@1.0.5 deduped
  | | | | +-- graceful-fs@4.1.11
  | | | | `-- shelljs@0.7.7
  | | | |   +-- glob@7.1.6 deduped
  | | | |   +-- interpret@1.2.0
  | | | |   `-- rechoir@0.6.2
  | | | |     `-- resolve@1.14.2 deduped
  | | | +-- glob@7.1.5
  | | | | +-- fs.realpath@1.0.0 deduped
  | | | | +-- inflight@1.0.6 deduped
  | | | | +-- inherits@2.0.4 deduped
  | | | | +-- minimatch@3.0.4 deduped
  | | | | +-- once@1.4.0 deduped
  | | | | `-- path-is-absolute@1.0.1 deduped
  | | | +-- graphql@14.5.8 deduped
  | | | +-- graphql-tag@2.10.1 deduped
  | | | +-- listr@0.14.3
  | | | | +-- @samverschueren/stream-to-observable@0.3.0
  | | | | | `-- any-observable@0.3.0
  | | | | +-- is-observable@1.1.0
  | | | | | `-- symbol-observable@1.2.0 deduped
  | | | | +-- is-promise@2.1.0 deduped
  | | | | +-- is-stream@1.1.0 deduped
  | | | | +-- listr-silent-renderer@1.1.1
  | | | | +-- listr-update-renderer@0.5.0
  | | | | | +-- chalk@1.1.3
  | | | | | | +-- ansi-styles@2.2.1
  | | | | | | +-- escape-string-regexp@1.0.5 deduped
  | | | | | | +-- has-ansi@2.0.0
  | | | | | | | `-- ansi-regex@2.1.1
  | | | | | | +-- strip-ansi@3.0.1 deduped
  | | | | | | `-- supports-color@2.0.0
  | | | | | +-- cli-truncate@0.2.1
  | | | | | | +-- slice-ansi@0.0.4
  | | | | | | `-- string-width@1.0.2
  | | | | | |   +-- code-point-at@1.1.0
  | | | | | |   +-- is-fullwidth-code-point@1.0.0
  | | | | | |   | `-- number-is-nan@1.0.1
  | | | | | |   `-- strip-ansi@3.0.1
  | | | | | |     `-- ansi-regex@2.1.1
  | | | | | +-- elegant-spinner@1.0.1
  | | | | | +-- figures@1.7.0
  | | | | | | +-- escape-string-regexp@1.0.5 deduped
  | | | | | | `-- object-assign@4.1.1 deduped
  | | | | | +-- indent-string@3.2.0
  | | | | | +-- log-symbols@1.0.2
  | | | | | | `-- chalk@1.1.3 deduped
  | | | | | +-- log-update@2.3.0
  | | | | | | +-- ansi-escapes@3.2.0 deduped
  | | | | | | +-- cli-cursor@2.1.0 deduped
  | | | | | | `-- wrap-ansi@3.0.1
  | | | | | |   +-- string-width@2.1.1 deduped
  | | | | | |   `-- strip-ansi@4.0.0
  | | | | | |     `-- ansi-regex@3.0.0
  | | | | | `-- strip-ansi@3.0.1
  | | | | |   `-- ansi-regex@2.1.1
  | | | | +-- listr-verbose-renderer@0.5.0
  | | | | | +-- chalk@2.4.2 deduped
  | | | | | +-- cli-cursor@2.1.0 deduped
  | | | | | +-- date-fns@1.30.1
  | | | | | `-- figures@2.0.0
  | | | | |   `-- escape-string-regexp@1.0.5 deduped
  | | | | +-- p-map@2.1.0
  | | | | `-- rxjs@6.5.4 deduped
  | | | +-- lodash.identity@3.0.0
  | | | +-- lodash.pickby@4.6.0
  | | | +-- moment@2.24.0
  | | | +-- strip-ansi@5.2.0
  | | | | `-- ansi-regex@4.1.0 deduped
  | | | +-- table@5.4.6
  | | | | +-- ajv@6.10.2 deduped
  | | | | +-- lodash@4.17.15 deduped
  | | | | +-- slice-ansi@2.1.0
  | | | | | +-- ansi-styles@3.2.1 deduped
  | | | | | +-- astral-regex@1.0.0
  | | | | | `-- is-fullwidth-code-point@2.0.0 deduped
  | | | | `-- string-width@3.1.0
  | | | |   +-- emoji-regex@7.0.3 deduped
  | | | |   +-- is-fullwidth-code-point@2.0.0 deduped
  | | | |   `-- strip-ansi@5.2.0
  | | | |     `-- ansi-regex@4.1.0 deduped
  | | | +-- tty@1.0.1
  | | | `-- vscode-uri@1.0.6
  | | +-- apollo-cache-inmemory@1.6.5
  | | | +-- apollo-cache@1.3.4
  | | | | +-- apollo-utilities@1.3.3 deduped
  | | | | `-- tslib@1.10.0 deduped
  | | | +-- apollo-utilities@1.3.3 deduped
  | | | +-- optimism@0.10.3
  | | | | `-- @wry/context@0.4.4
  | | | |   +-- @types/node@13.1.6 deduped
  | | | |   `-- tslib@1.10.0 deduped
  | | | +-- ts-invariant@0.4.4
  | | | | `-- tslib@1.10.0 deduped
  | | | `-- tslib@1.10.0 deduped
  | | +-- apollo-client@2.6.8
  | | | +-- @types/zen-observable@0.8.0
  | | | +-- apollo-cache@1.3.4 deduped
  | | | +-- apollo-link@1.2.13 deduped
  | | | +-- apollo-utilities@1.3.3 deduped
  | | | +-- symbol-observable@1.2.0
  | | | +-- ts-invariant@0.4.4 deduped
  | | | +-- tslib@1.10.0 deduped
  | | | `-- zen-observable@0.8.15
  | | +-- apollo-link@1.2.13
  | | | +-- apollo-utilities@1.3.3 deduped
  | | | +-- ts-invariant@0.4.4 deduped
  | | | +-- tslib@1.10.0 deduped
  | | | `-- zen-observable-ts@0.8.20
  | | |   +-- tslib@1.10.0 deduped
  | | |   `-- zen-observable@0.8.15 deduped
  | | +-- apollo-link-context@1.0.19
  | | | +-- apollo-link@1.2.13 deduped
  | | | `-- tslib@1.10.0 deduped
  | | +-- apollo-link-http@1.5.16
  | | | +-- apollo-link@1.2.13 deduped
  | | | +-- apollo-link-http-common@0.2.15
  | | | | +-- apollo-link@1.2.13 deduped
  | | | | +-- ts-invariant@0.4.4 deduped
  | | | | `-- tslib@1.10.0 deduped
  | | | `-- tslib@1.10.0 deduped
  | | +-- apollo-link-persisted-queries@0.2.2
  | | | +-- apollo-link@1.2.13 deduped
  | | | `-- hash.js@1.1.7
  | | |   +-- inherits@2.0.4 deduped
  | | |   `-- minimalistic-assert@1.0.1
  | | +-- apollo-link-state@0.4.2
  | | | +-- apollo-utilities@1.3.3 deduped
  | | | `-- graphql-anywhere@4.2.6
  | | |   +-- apollo-utilities@1.3.3 deduped
  | | |   +-- ts-invariant@0.3.3
  | | |   | `-- tslib@1.10.0 deduped
  | | |   `-- tslib@1.10.0 deduped
  | | +-- apollo-link-ws@1.0.19
  | | | +-- apollo-link@1.2.13 deduped
  | | | `-- tslib@1.10.0 deduped
  | | +-- apollo-server-express@2.9.16
  | | | +-- @apollographql/graphql-playground-html@1.6.24
  | | | +-- @types/accepts@1.3.5
  | | | | `-- @types/node@13.1.6 deduped
  | | | +-- @types/body-parser@1.17.1
  | | | | +-- @types/connect@3.4.33
  | | | | | `-- @types/node@13.1.6 deduped
  | | | | `-- @types/node@13.1.6 deduped
  | | | +-- @types/cors@2.8.6
  | | | | `-- @types/express@4.17.2 deduped
  | | | +-- @types/express@4.17.2
  | | | | +-- @types/body-parser@1.17.1 deduped
  | | | | +-- @types/express-serve-static-core@4.17.1
  | | | | | +-- @types/node@13.1.6 deduped
  | | | | | `-- @types/range-parser@1.2.3
  | | | | `-- @types/serve-static@1.13.3
  | | | |   +-- @types/express-serve-static-core@4.17.1 deduped
  | | | |   `-- @types/mime@2.0.1
  | | | +-- accepts@1.3.7
  | | | | +-- mime-types@2.1.26 deduped
  | | | | `-- negotiator@0.6.2
  | | | +-- apollo-server-core@2.9.16
  | | | | +-- @apollographql/apollo-tools@0.4.3 deduped
  | | | | +-- @apollographql/graphql-playground-html@1.6.24 deduped
  | | | | +-- @types/graphql-upload@8.0.3
  | | | | | +-- @types/express@4.17.2 deduped
  | | | | | +-- @types/fs-capacitor@2.0.0
  | | | | | | `-- @types/node@13.1.6 deduped
  | | | | | +-- @types/koa@2.11.0
  | | | | | | +-- @types/accepts@1.3.5 deduped
  | | | | | | +-- @types/cookies@0.7.4
  | | | | | | | +-- @types/connect@3.4.33 deduped
  | | | | | | | +-- @types/express@4.17.2 deduped
  | | | | | | | +-- @types/keygrip@1.0.2 deduped
  | | | | | | | `-- @types/node@13.1.6 deduped
  | | | | | | +-- @types/http-assert@1.5.1
  | | | | | | +-- @types/keygrip@1.0.2
  | | | | | | +-- @types/koa-compose@3.2.5
  | | | | | | | `-- @types/koa@2.11.0 deduped
  | | | | | | `-- @types/node@13.1.6 deduped
  | | | | | `-- graphql@14.5.8 deduped
  | | | | +-- @types/ws@6.0.4
  | | | | | `-- @types/node@13.1.6 deduped
  | | | | +-- apollo-cache-control@0.8.11
  | | | | | +-- apollo-server-env@2.4.3 deduped
  | | | | | `-- graphql-extensions@0.10.10 deduped
  | | | | +-- apollo-datasource@0.6.4 deduped
  | | | | +-- apollo-engine-reporting@1.4.14
  | | | | | +-- apollo-engine-reporting-protobuf@0.4.4 deduped
  | | | | | +-- apollo-graphql@0.3.7 deduped
  | | | | | +-- apollo-server-caching@0.5.1 deduped
  | | | | | +-- apollo-server-env@2.4.3 deduped
  | | | | | +-- apollo-server-errors@2.3.4 deduped
  | | | | | +-- apollo-server-types@0.2.10 deduped
  | | | | | +-- async-retry@1.3.1
  | | | | | | `-- retry@0.12.0
  | | | | | `-- graphql-extensions@0.10.10 deduped
  | | | | +-- apollo-server-caching@0.5.1
  | | | | | `-- lru-cache@5.1.1 deduped
  | | | | +-- apollo-server-env@2.4.3
  | | | | | +-- node-fetch@2.6.0 deduped
  | | | | | `-- util.promisify@1.0.0 deduped
  | | | | +-- apollo-server-errors@2.3.4 deduped
  | | | | +-- apollo-server-plugin-base@0.6.10
  | | | | | `-- apollo-server-types@0.2.10 deduped
  | | | | +-- apollo-server-types@0.2.10 deduped
  | | | | +-- apollo-tracing@0.8.11
  | | | | | +-- apollo-server-env@2.4.3 deduped
  | | | | | `-- graphql-extensions@0.10.10 deduped
  | | | | +-- fast-json-stable-stringify@2.1.0 deduped
  | | | | +-- graphql-extensions@0.10.10
  | | | | | +-- @apollographql/apollo-tools@0.4.3 deduped
  | | | | | +-- apollo-server-env@2.4.3 deduped
  | | | | | `-- apollo-server-types@0.2.10 deduped
  | | | | +-- graphql-tag@2.10.1 deduped
  | | | | +-- graphql-tools@4.0.6 deduped
  | | | | +-- graphql-upload@8.1.0
  | | | | | +-- busboy@0.3.1
  | | | | | | `-- dicer@0.3.0
  | | | | | |   `-- streamsearch@0.1.2
  | | | | | +-- fs-capacitor@2.0.4
  | | | | | +-- http-errors@1.7.3 deduped
  | | | | | `-- object-path@0.11.4
  | | | | +-- sha.js@2.4.11 deduped
  | | | | +-- subscriptions-transport-ws@0.9.16 deduped
  | | | | `-- ws@6.2.1
  | | | |   `-- async-limiter@1.0.1 deduped
  | | | +-- apollo-server-types@0.2.10
  | | | | +-- apollo-engine-reporting-protobuf@0.4.4
  | | | | | `-- @apollo/protobufjs@1.0.3
  | | | | |   +-- @protobufjs/aspromise@1.1.2
  | | | | |   +-- @protobufjs/base64@1.1.2
  | | | | |   +-- @protobufjs/codegen@2.0.4
  | | | | |   +-- @protobufjs/eventemitter@1.1.0
  | | | | |   +-- @protobufjs/fetch@1.1.0
  | | | | |   | +-- @protobufjs/aspromise@1.1.2 deduped
  | | | | |   | `-- @protobufjs/inquire@1.1.0 deduped
  | | | | |   +-- @protobufjs/float@1.0.2
  | | | | |   +-- @protobufjs/inquire@1.1.0
  | | | | |   +-- @protobufjs/path@1.1.2
  | | | | |   +-- @protobufjs/pool@1.1.0
  | | | | |   +-- @protobufjs/utf8@1.1.0
  | | | | |   +-- @types/long@4.0.0
  | | | | |   +-- @types/node@10.17.13
  | | | | |   `-- long@4.0.0
  | | | | +-- apollo-server-caching@0.5.1 deduped
  | | | | `-- apollo-server-env@2.4.3 deduped
  | | | +-- body-parser@1.19.0
  | | | | +-- bytes@3.1.0
  | | | | +-- content-type@1.0.4 deduped
  | | | | +-- debug@2.6.9
  | | | | | `-- ms@2.0.0 deduped
  | | | | +-- depd@1.1.2 deduped
  | | | | +-- http-errors@1.7.2
  | | | | | +-- depd@1.1.2 deduped
  | | | | | +-- inherits@2.0.3
  | | | | | +-- setprototypeof@1.1.1 deduped
  | | | | | +-- statuses@1.5.0 deduped
  | | | | | `-- toidentifier@1.0.0
  | | | | +-- iconv-lite@0.4.24 deduped
  | | | | +-- on-finished@2.3.0 deduped
  | | | | +-- qs@6.7.0
  | | | | +-- raw-body@2.4.0
  | | | | | +-- bytes@3.1.0 deduped
  | | | | | +-- http-errors@1.7.2
  | | | | | | +-- depd@1.1.2 deduped
  | | | | | | +-- inherits@2.0.3
  | | | | | | +-- setprototypeof@1.1.1 deduped
  | | | | | | +-- statuses@1.5.0 deduped
  | | | | | | `-- toidentifier@1.0.0 deduped
  | | | | | +-- iconv-lite@0.4.24 deduped
  | | | | | `-- unpipe@1.0.0 deduped
  | | | | `-- type-is@1.6.18 deduped
  | | | +-- cors@2.8.5
  | | | | +-- object-assign@4.1.1
  | | | | `-- vary@1.1.2 deduped
  | | | +-- express@4.17.1 deduped
  | | | +-- graphql-subscriptions@1.1.0 deduped
  | | | +-- graphql-tools@4.0.6 deduped
  | | | +-- parseurl@1.3.3
  | | | +-- subscriptions-transport-ws@0.9.16 deduped
  | | | `-- type-is@1.6.18
  | | |   +-- media-typer@0.3.0
  | | |   `-- mime-types@2.1.26 deduped
  | | +-- apollo-upload-client@11.0.0
  | | | +-- @babel/runtime@7.8.3
  | | | | `-- regenerator-runtime@0.13.3
  | | | +-- apollo-link@1.2.13 deduped
  | | | +-- apollo-link-http-common@0.2.15 deduped
  | | | `-- extract-files@5.0.1
  | | +-- apollo-utilities@1.3.3
  | | | +-- @wry/equality@0.1.9
  | | | | `-- tslib@1.10.0 deduped
  | | | +-- fast-json-stable-stringify@2.1.0
  | | | +-- ts-invariant@0.4.4 deduped
  | | | `-- tslib@1.10.0 deduped
  | | +-- chalk@2.4.2 deduped
  | | +-- deepmerge@4.2.2
  | | +-- dotenv@8.2.0
  | | +-- esm@3.2.25
  | | +-- execa@3.4.0
  | | | +-- cross-spawn@7.0.1
  | | | | +-- path-key@3.1.1
  | | | | +-- shebang-command@2.0.0
  | | | | | `-- shebang-regex@3.0.0
  | | | | `-- which@2.0.2
  | | | |   `-- isexe@2.0.0 deduped
  | | | +-- get-stream@5.1.0
  | | | | `-- pump@3.0.0 deduped
  | | | +-- human-signals@1.1.1
  | | | +-- is-stream@2.0.0
  | | | +-- merge-stream@2.0.0
  | | | +-- npm-run-path@4.0.1
  | | | | `-- path-key@3.1.1 deduped
  | | | +-- onetime@5.1.0
  | | | | `-- mimic-fn@2.1.0
  | | | +-- p-finally@2.0.1
  | | | +-- signal-exit@3.0.2 deduped
  | | | `-- strip-final-newline@2.0.0
  | | +-- express@4.17.1
  | | | +-- accepts@1.3.7 deduped
  | | | +-- array-flatten@1.1.1
  | | | +-- body-parser@1.19.0 deduped
  | | | +-- content-disposition@0.5.3
  | | | | `-- safe-buffer@5.1.2
  | | | +-- content-type@1.0.4
  | | | +-- cookie@0.4.0
  | | | +-- cookie-signature@1.0.6
  | | | +-- debug@2.6.9
  | | | | `-- ms@2.0.0
  | | | +-- depd@1.1.2
  | | | +-- encodeurl@1.0.2
  | | | +-- escape-html@1.0.3
  | | | +-- etag@1.8.1
  | | | +-- finalhandler@1.1.2
  | | | | +-- debug@2.6.9
  | | | | | `-- ms@2.0.0 deduped
  | | | | +-- encodeurl@1.0.2 deduped
  | | | | +-- escape-html@1.0.3 deduped
  | | | | +-- on-finished@2.3.0 deduped
  | | | | +-- parseurl@1.3.3 deduped
  | | | | +-- statuses@1.5.0 deduped
  | | | | `-- unpipe@1.0.0
  | | | +-- fresh@0.5.2
  | | | +-- merge-descriptors@1.0.1
  | | | +-- methods@1.1.2
  | | | +-- on-finished@2.3.0
  | | | | `-- ee-first@1.1.1
  | | | +-- parseurl@1.3.3 deduped
  | | | +-- path-to-regexp@0.1.7
  | | | +-- proxy-addr@2.0.5
  | | | | +-- forwarded@0.1.2
  | | | | `-- ipaddr.js@1.9.0
  | | | +-- qs@6.7.0
  | | | +-- range-parser@1.2.1
  | | | +-- safe-buffer@5.1.2
  | | | +-- send@0.17.1
  | | | | +-- debug@2.6.9
  | | | | | `-- ms@2.0.0
  | | | | +-- depd@1.1.2 deduped
  | | | | +-- destroy@1.0.4
  | | | | +-- encodeurl@1.0.2 deduped
  | | | | +-- escape-html@1.0.3 deduped
  | | | | +-- etag@1.8.1 deduped
  | | | | +-- fresh@0.5.2 deduped
  | | | | +-- http-errors@1.7.3
  | | | | | +-- depd@1.1.2 deduped
  | | | | | +-- inherits@2.0.4 deduped
  | | | | | +-- setprototypeof@1.1.1 deduped
  | | | | | +-- statuses@1.5.0 deduped
  | | | | | `-- toidentifier@1.0.0 deduped
  | | | | +-- mime@1.6.0
  | | | | +-- ms@2.1.1
  | | | | +-- on-finished@2.3.0 deduped
  | | | | +-- range-parser@1.2.1 deduped
  | | | | `-- statuses@1.5.0 deduped
  | | | +-- serve-static@1.14.1
  | | | | +-- encodeurl@1.0.2 deduped
  | | | | +-- escape-html@1.0.3 deduped
  | | | | +-- parseurl@1.3.3 deduped
  | | | | `-- send@0.17.1 deduped
  | | | +-- setprototypeof@1.1.1
  | | | +-- statuses@1.5.0
  | | | +-- type-is@1.6.18 deduped
  | | | +-- utils-merge@1.0.1
  | | | `-- vary@1.1.2
  | | +-- fs-extra@8.1.0
  | | | +-- graceful-fs@4.2.3 deduped
  | | | +-- jsonfile@4.0.0 deduped
  | | | `-- universalify@0.1.2 deduped
  | | +-- graphql@14.5.8 deduped
  | | +-- graphql-subscriptions@1.1.0 deduped
  | | +-- graphql-tag@2.10.1 deduped
  | | +-- graphql-tools@4.0.6
  | | | +-- apollo-link@1.2.13 deduped
  | | | +-- apollo-utilities@1.3.3 deduped
  | | | +-- deprecated-decorator@0.1.6
  | | | +-- iterall@1.3.0 deduped
  | | | `-- uuid@3.3.3 deduped
  | | +-- node-fetch@2.6.0
  | | +-- nodemon@1.19.4
  | | | +-- chokidar@2.1.8
  | | | | +-- anymatch@2.0.0
  | | | | | +-- micromatch@3.1.10 deduped
  | | | | | `-- normalize-path@2.1.1
  | | | | |   `-- remove-trailing-separator@1.1.0
  | | | | +-- async-each@1.0.3
  | | | | +-- braces@2.3.2 deduped
  | | | | +-- UNMET OPTIONAL DEPENDENCY fsevents@^1.2.7
  | | | | +-- glob-parent@3.1.0 deduped
  | | | | +-- inherits@2.0.4 deduped
  | | | | +-- is-binary-path@1.0.1
  | | | | | `-- binary-extensions@1.13.1
  | | | | +-- is-glob@4.0.1 deduped
  | | | | +-- normalize-path@3.0.0
  | | | | +-- path-is-absolute@1.0.1 deduped
  | | | | +-- readdirp@2.2.1
  | | | | | +-- graceful-fs@4.2.3 deduped
  | | | | | +-- micromatch@3.1.10 deduped
  | | | | | `-- readable-stream@2.3.7
  | | | | |   +-- core-util-is@1.0.2 deduped
  | | | | |   +-- inherits@2.0.4 deduped
  | | | | |   +-- isarray@1.0.0
  | | | | |   +-- process-nextick-args@2.0.1
  | | | | |   +-- safe-buffer@5.1.2
  | | | | |   +-- string_decoder@1.1.1 deduped
  | | | | |   `-- util-deprecate@1.0.2 deduped
  | | | | `-- upath@1.2.0
  | | | +-- debug@3.2.6
  | | | | `-- ms@2.1.2
  | | | +-- ignore-by-default@1.0.1
  | | | +-- minimatch@3.0.4 deduped
  | | | +-- pstree.remy@1.1.7
  | | | +-- semver@5.7.1
  | | | +-- supports-color@5.5.0 deduped
  | | | +-- touch@3.1.0
  | | | | `-- nopt@1.0.10
  | | | |   `-- abbrev@1.1.1
  | | | +-- undefsafe@2.0.2
  | | | | `-- debug@2.6.9
  | | | |   `-- ms@2.0.0 deduped
  | | | `-- update-notifier@2.5.0
  | | |   +-- boxen@1.3.0
  | | |   | +-- ansi-align@2.0.0
  | | |   | | `-- string-width@2.1.1 deduped
  | | |   | +-- camelcase@4.1.0
  | | |   | +-- chalk@2.4.2 deduped
  | | |   | +-- cli-boxes@1.0.0
  | | |   | +-- string-width@2.1.1 deduped
  | | |   | +-- term-size@1.2.0
  | | |   | | `-- execa@0.7.0
  | | |   | |   +-- cross-spawn@5.1.0
  | | |   | |   | +-- lru-cache@4.1.5
  | | |   | |   | | +-- pseudomap@1.0.2 deduped
  | | |   | |   | | `-- yallist@2.1.2
  | | |   | |   | +-- shebang-command@1.2.0 deduped
  | | |   | |   | `-- which@1.3.1 deduped
  | | |   | |   +-- get-stream@3.0.0
  | | |   | |   +-- is-stream@1.1.0 deduped
  | | |   | |   +-- npm-run-path@2.0.2 deduped
  | | |   | |   +-- p-finally@1.0.0 deduped
  | | |   | |   +-- signal-exit@3.0.2 deduped
  | | |   | |   `-- strip-eof@1.0.0 deduped
  | | |   | `-- widest-line@2.0.1 deduped
  | | |   +-- chalk@2.4.2 deduped
  | | |   +-- configstore@3.1.2
  | | |   | +-- dot-prop@4.2.0
  | | |   | | `-- is-obj@1.0.1
  | | |   | +-- graceful-fs@4.2.3 deduped
  | | |   | +-- make-dir@1.3.0 deduped
  | | |   | +-- unique-string@1.0.0
  | | |   | | `-- crypto-random-string@1.0.0
  | | |   | +-- write-file-atomic@2.4.3 deduped
  | | |   | `-- xdg-basedir@3.0.0 deduped
  | | |   +-- import-lazy@2.1.0
  | | |   +-- is-ci@1.2.1
  | | |   | `-- ci-info@1.6.0
  | | |   +-- is-installed-globally@0.1.0
  | | |   | +-- global-dirs@0.1.1 deduped
  | | |   | `-- is-path-inside@1.0.1
  | | |   |   `-- path-is-inside@1.0.2
  | | |   +-- is-npm@1.0.0
  | | |   +-- latest-version@3.1.0
  | | |   | `-- package-json@4.0.1
  | | |   |   +-- got@6.7.1 deduped
  | | |   |   +-- registry-auth-token@3.4.0
  | | |   |   | +-- rc@1.2.8
  | | |   |   | | +-- deep-extend@0.6.0
  | | |   |   | | +-- ini@1.3.5 deduped
  | | |   |   | | +-- minimist@1.2.0 deduped
  | | |   |   | | `-- strip-json-comments@2.0.1
  | | |   |   | `-- safe-buffer@5.2.0 deduped
  | | |   |   +-- registry-url@3.1.0
  | | |   |   | `-- rc@1.2.8 deduped
  | | |   |   `-- semver@5.7.1
  | | |   +-- semver-diff@2.1.0
  | | |   | `-- semver@5.7.1
  | | |   `-- xdg-basedir@3.0.0
  | | +-- subscriptions-transport-ws@0.9.16
  | | | +-- backo2@1.0.2
  | | | +-- eventemitter3@3.1.2
  | | | +-- iterall@1.3.0 deduped
  | | | +-- symbol-observable@1.2.0 deduped
  | | | `-- ws@5.2.2
  | | |   `-- async-limiter@1.0.1
  | | `-- ts-node@8.6.2
  | |   +-- arg@4.1.2
  | |   +-- diff@4.0.2
  | |   +-- make-error@1.3.5
  | |   +-- source-map-support@0.5.16 deduped
  | |   `-- yn@3.1.1
  | `-- watch@1.0.2
  |   +-- exec-sh@0.2.2
  |   | `-- merge@1.2.1
  |   `-- minimist@1.2.0 deduped
  +-- @vue/cli-ui-addon-webpack@4.1.2
  +-- @vue/cli-ui-addon-widgets@4.1.2
  +-- boxen@4.2.0
  | +-- ansi-align@3.0.0
  | | `-- string-width@3.1.0
  | |   +-- emoji-regex@7.0.3
  | |   +-- is-fullwidth-code-point@2.0.0 deduped
  | |   `-- strip-ansi@5.2.0
  | |     `-- ansi-regex@4.1.0 deduped
  | +-- camelcase@5.3.1
  | +-- chalk@3.0.0
  | | +-- ansi-styles@4.2.1
  | | | +-- @types/color-name@1.1.1
  | | | `-- color-convert@2.0.1
  | | |   `-- color-name@1.1.4
  | | `-- supports-color@7.1.0
  | |   `-- has-flag@4.0.0
  | +-- cli-boxes@2.2.0
  | +-- string-width@4.2.0
  | | +-- emoji-regex@8.0.0
  | | +-- is-fullwidth-code-point@3.0.0
  | | `-- strip-ansi@6.0.0
  | |   `-- ansi-regex@5.0.0
  | +-- term-size@2.1.1
  | +-- type-fest@0.8.1
  | `-- widest-line@3.1.0
  |   `-- string-width@4.2.0 deduped
  +-- cmd-shim@3.0.3
  | +-- graceful-fs@4.2.3
  | `-- mkdirp@0.5.1
  |   `-- minimist@0.0.8
  +-- commander@2.20.3
  +-- debug@4.1.1
  | `-- ms@2.1.2
  +-- deepmerge@3.3.0
  +-- didyoumean@1.2.1
  +-- download-git-repo@1.1.0
  | +-- download@5.0.3
  | | +-- caw@2.0.1
  | | | +-- get-proxy@2.1.0
  | | | | `-- npm-conf@1.1.3
  | | | |   +-- config-chain@1.1.12
  | | | |   | +-- ini@1.3.5 deduped
  | | | |   | `-- proto-list@1.2.4
  | | | |   `-- pify@3.0.0 deduped
  | | | +-- isurl@1.0.0
  | | | | +-- has-to-string-tag-x@1.4.1
  | | | | | `-- has-symbol-support-x@1.4.2
  | | | | `-- is-object@1.0.1
  | | | +-- tunnel-agent@0.6.0 deduped
  | | | `-- url-to-options@1.0.1
  | | +-- decompress@4.2.0
  | | | +-- decompress-tar@4.1.1
  | | | | +-- file-type@5.2.0
  | | | | +-- is-stream@1.1.0 deduped
  | | | | `-- tar-stream@1.6.2
  | | | |   +-- bl@1.2.2
  | | | |   | +-- readable-stream@2.3.7 deduped
  | | | |   | `-- safe-buffer@5.2.0 deduped
  | | | |   +-- buffer-alloc@1.2.0
  | | | |   | +-- buffer-alloc-unsafe@1.1.0
  | | | |   | `-- buffer-fill@1.0.0
  | | | |   +-- end-of-stream@1.4.4 deduped
  | | | |   +-- fs-constants@1.0.0
  | | | |   +-- readable-stream@2.3.7 deduped
  | | | |   +-- to-buffer@1.1.1
  | | | |   `-- xtend@4.0.2
  | | | +-- decompress-tarbz2@4.1.1
  | | | | +-- decompress-tar@4.1.1 deduped
  | | | | +-- file-type@6.2.0
  | | | | +-- is-stream@1.1.0 deduped
  | | | | +-- seek-bzip@1.0.5
  | | | | | `-- commander@2.8.1
  | | | | |   `-- graceful-readlink@1.0.1
  | | | | `-- unbzip2-stream@1.3.3
  | | | |   +-- buffer@5.4.3
  | | | |   | +-- base64-js@1.3.1
  | | | |   | `-- ieee754@1.1.13
  | | | |   `-- through@2.3.8 deduped
  | | | +-- decompress-targz@4.1.1
  | | | | +-- decompress-tar@4.1.1 deduped
  | | | | +-- file-type@5.2.0 deduped
  | | | | `-- is-stream@1.1.0 deduped
  | | | +-- decompress-unzip@4.0.1
  | | | | +-- file-type@3.9.0
  | | | | +-- get-stream@2.3.1
  | | | | | +-- object-assign@4.1.1 deduped
  | | | | | `-- pinkie-promise@2.0.1
  | | | | |   `-- pinkie@2.0.4
  | | | | +-- pify@2.3.0
  | | | | `-- yauzl@2.10.0
  | | | |   +-- buffer-crc32@0.2.13
  | | | |   `-- fd-slicer@1.1.0
  | | | |     `-- pend@1.2.0
  | | | +-- graceful-fs@4.2.3 deduped
  | | | +-- make-dir@1.3.0
  | | | | `-- pify@3.0.0 deduped
  | | | +-- pify@2.3.0
  | | | `-- strip-dirs@2.1.0
  | | |   `-- is-natural-number@4.0.1
  | | +-- filenamify@2.1.0
  | | | +-- filename-reserved-regex@2.0.0
  | | | +-- strip-outer@1.0.1
  | | | | `-- escape-string-regexp@1.0.5 deduped
  | | | `-- trim-repeated@1.0.0
  | | |   `-- escape-string-regexp@1.0.5 deduped
  | | +-- get-stream@3.0.0
  | | +-- got@6.7.1
  | | | +-- create-error-class@3.0.2
  | | | | `-- capture-stack-trace@1.0.1
  | | | +-- duplexer3@0.1.4
  | | | +-- get-stream@3.0.0
  | | | +-- is-redirect@1.0.0
  | | | +-- is-retry-allowed@1.2.0
  | | | +-- is-stream@1.1.0 deduped
  | | | +-- lowercase-keys@1.0.1
  | | | +-- safe-buffer@5.2.0 deduped
  | | | +-- timed-out@4.0.1
  | | | +-- unzip-response@2.0.1
  | | | `-- url-parse-lax@1.0.0
  | | |   `-- prepend-http@1.0.4
  | | +-- mkdirp@0.5.1 deduped
  | | `-- pify@2.3.0
  | +-- git-clone@0.1.0
  | `-- rimraf@2.7.1
  |   `-- glob@7.1.6 deduped
  +-- ejs@2.7.4
  +-- envinfo@7.5.0
  +-- fs-extra@7.0.1
  | +-- graceful-fs@4.2.3 deduped
  | +-- jsonfile@4.0.0
  | | `-- graceful-fs@4.2.3 deduped
  | `-- universalify@0.1.2
  +-- globby@9.2.0
  | +-- @types/glob@7.1.1
  | | +-- @types/events@3.0.0
  | | +-- @types/minimatch@3.0.3
  | | `-- @types/node@13.1.6
  | +-- array-union@1.0.2
  | | `-- array-uniq@1.0.3
  | +-- dir-glob@2.2.2
  | | `-- path-type@3.0.0
  | |   `-- pify@3.0.0 deduped
  | +-- fast-glob@2.2.7
  | | +-- @mrmlnc/readdir-enhanced@2.2.1
  | | | +-- call-me-maybe@1.0.1
  | | | `-- glob-to-regexp@0.3.0
  | | +-- @nodelib/fs.stat@1.1.3
  | | +-- glob-parent@3.1.0
  | | | +-- is-glob@3.1.0
  | | | | `-- is-extglob@2.1.1 deduped
  | | | `-- path-dirname@1.0.2
  | | +-- is-glob@4.0.1
  | | | `-- is-extglob@2.1.1
  | | +-- merge2@1.3.0
  | | `-- micromatch@3.1.10 deduped
  | +-- glob@7.1.6
  | | +-- fs.realpath@1.0.0
  | | +-- inflight@1.0.6
  | | | +-- once@1.4.0 deduped
  | | | `-- wrappy@1.0.2
  | | +-- inherits@2.0.4
  | | +-- minimatch@3.0.4
  | | | `-- brace-expansion@1.1.11
  | | |   +-- balanced-match@1.0.0
  | | |   `-- concat-map@0.0.1
  | | +-- once@1.4.0
  | | | `-- wrappy@1.0.2 deduped
  | | `-- path-is-absolute@1.0.1
  | +-- ignore@4.0.6
  | +-- pify@4.0.1
  | `-- slash@2.0.0
  +-- import-global@0.1.0
  | `-- global-dirs@0.1.1
  |   `-- ini@1.3.5 deduped
  +-- inquirer@6.5.2
  | +-- ansi-escapes@3.2.0
  | +-- chalk@2.4.2 deduped
  | +-- cli-cursor@2.1.0
  | | `-- restore-cursor@2.0.0
  | |   +-- onetime@2.0.1
  | |   | `-- mimic-fn@1.2.0
  | |   `-- signal-exit@3.0.2 deduped
  | +-- cli-width@2.2.0
  | +-- external-editor@3.1.0
  | | +-- chardet@0.7.0
  | | +-- iconv-lite@0.4.24
  | | | `-- safer-buffer@2.1.2
  | | `-- tmp@0.0.33
  | |   `-- os-tmpdir@1.0.2
  | +-- figures@2.0.0
  | | `-- escape-string-regexp@1.0.5 deduped
  | +-- lodash@4.17.15
  | +-- mute-stream@0.0.7
  | +-- run-async@2.3.0
  | | `-- is-promise@2.1.0 deduped
  | +-- rxjs@6.5.4
  | | `-- tslib@1.10.0
  | +-- string-width@2.1.1
  | | +-- is-fullwidth-code-point@2.0.0
  | | `-- strip-ansi@4.0.0
  | |   `-- ansi-regex@3.0.0
  | +-- strip-ansi@5.2.0
  | | `-- ansi-regex@4.1.0
  | `-- through@2.3.8
  +-- isbinaryfile@4.0.4
  +-- javascript-stringify@1.6.0
  +-- js-yaml@3.13.1
  | +-- argparse@1.0.10
  | | `-- sprintf-js@1.0.3
  | `-- esprima@4.0.1
  +-- jscodeshift@0.6.4
  | +-- @babel/core@7.8.3
  | | +-- @babel/code-frame@7.8.3
  | | | `-- @babel/highlight@7.8.3
  | | |   +-- chalk@2.4.2 deduped
  | | |   +-- esutils@2.0.3 deduped
  | | |   `-- js-tokens@4.0.0
  | | +-- @babel/generator@7.8.3
  | | | +-- @babel/types@7.8.3 deduped
  | | | +-- jsesc@2.5.2
  | | | +-- lodash@4.17.15 deduped
  | | | `-- source-map@0.5.7 deduped
  | | +-- @babel/helpers@7.8.3
  | | | +-- @babel/template@7.8.3 deduped
  | | | +-- @babel/traverse@7.8.3 deduped
  | | | `-- @babel/types@7.8.3
  | | |   +-- esutils@2.0.3 deduped
  | | |   +-- lodash@4.17.15 deduped
  | | |   `-- to-fast-properties@2.0.0 deduped
  | | +-- @babel/parser@7.8.3 deduped
  | | +-- @babel/template@7.8.3
  | | | +-- @babel/code-frame@7.8.3 deduped
  | | | +-- @babel/parser@7.8.3 deduped
  | | | `-- @babel/types@7.8.3
  | | |   +-- esutils@2.0.3 deduped
  | | |   +-- lodash@4.17.15 deduped
  | | |   `-- to-fast-properties@2.0.0 deduped
  | | +-- @babel/traverse@7.8.3
  | | | +-- @babel/code-frame@7.8.3 deduped
  | | | +-- @babel/generator@7.8.3
  | | | | +-- @babel/types@7.8.3 deduped
  | | | | +-- jsesc@2.5.2 deduped
  | | | | +-- lodash@4.17.15 deduped
  | | | | `-- source-map@0.5.7 deduped
  | | | +-- @babel/helper-function-name@7.8.3
  | | | | +-- @babel/helper-get-function-arity@7.8.3 deduped
  | | | | +-- @babel/template@7.8.3 deduped
  | | | | `-- @babel/types@7.8.3
  | | | |   +-- esutils@2.0.3 deduped
  | | | |   +-- lodash@4.17.15 deduped
  | | | |   `-- to-fast-properties@2.0.0 deduped
  | | | +-- @babel/helper-split-export-declaration@7.8.3
  | | | | `-- @babel/types@7.8.3
  | | | |   +-- esutils@2.0.3 deduped
  | | | |   +-- lodash@4.17.15 deduped
  | | | |   `-- to-fast-properties@2.0.0 deduped
  | | | +-- @babel/parser@7.8.3 deduped
  | | | +-- @babel/types@7.8.3
  | | | | +-- esutils@2.0.3 deduped
  | | | | +-- lodash@4.17.15 deduped
  | | | | `-- to-fast-properties@2.0.0 deduped
  | | | +-- debug@4.1.1 deduped
  | | | +-- globals@11.12.0
  | | | `-- lodash@4.17.15 deduped
  | | +-- @babel/types@7.8.3
  | | | +-- esutils@2.0.3
  | | | +-- lodash@4.17.15 deduped
  | | | `-- to-fast-properties@2.0.0
  | | +-- convert-source-map@1.7.0
  | | | `-- safe-buffer@5.1.2
  | | +-- debug@4.1.1 deduped
  | | +-- gensync@1.0.0-beta.1
  | | +-- json5@2.1.1
  | | | `-- minimist@1.2.0 deduped
  | | +-- lodash@4.17.15 deduped
  | | +-- resolve@1.14.2 deduped
  | | +-- semver@5.7.1
  | | `-- source-map@0.5.7
  | +-- @babel/parser@7.8.3
  | +-- @babel/plugin-proposal-class-properties@7.8.3
  | | +-- @babel/helper-create-class-features-plugin@7.8.3
  | | | +-- @babel/helper-function-name@7.8.3 deduped
  | | | +-- @babel/helper-member-expression-to-functions@7.8.3
  | | | | `-- @babel/types@7.8.3
  | | | |   +-- esutils@2.0.3 deduped
  | | | |   +-- lodash@4.17.15 deduped
  | | | |   `-- to-fast-properties@2.0.0 deduped
  | | | +-- @babel/helper-optimise-call-expression@7.8.3
  | | | | `-- @babel/types@7.8.3
  | | | |   +-- esutils@2.0.3 deduped
  | | | |   +-- lodash@4.17.15 deduped
  | | | |   `-- to-fast-properties@2.0.0 deduped
  | | | +-- @babel/helper-plugin-utils@7.8.3 deduped
  | | | +-- @babel/helper-replace-supers@7.8.3
  | | | | +-- @babel/helper-member-expression-to-functions@7.8.3 deduped
  | | | | +-- @babel/helper-optimise-call-expression@7.8.3 deduped
  | | | | +-- @babel/traverse@7.8.3 deduped
  | | | | `-- @babel/types@7.8.3
  | | | |   +-- esutils@2.0.3 deduped
  | | | |   +-- lodash@4.17.15 deduped
  | | | |   `-- to-fast-properties@2.0.0 deduped
  | | | `-- @babel/helper-split-export-declaration@7.8.3 deduped
  | | `-- @babel/helper-plugin-utils@7.8.3
  | +-- @babel/plugin-proposal-object-rest-spread@7.8.3
  | | +-- @babel/helper-plugin-utils@7.8.3 deduped
  | | `-- @babel/plugin-syntax-object-rest-spread@7.8.3
  | |   `-- @babel/helper-plugin-utils@7.8.3 deduped
  | +-- @babel/preset-env@7.8.3
  | | +-- @babel/compat-data@7.8.1
  | | | +-- browserslist@4.8.3 deduped
  | | | +-- invariant@2.2.4 deduped
  | | | `-- semver@5.7.1
  | | +-- @babel/helper-compilation-targets@7.8.3
  | | | +-- @babel/compat-data@7.8.1 deduped
  | | | +-- browserslist@4.8.3 deduped
  | | | +-- invariant@2.2.4 deduped
  | | | +-- levenary@1.1.0 deduped
  | | | `-- semver@5.7.1
  | | +-- @babel/helper-module-imports@7.8.3
  | | | `-- @babel/types@7.8.3
  | | |   +-- esutils@2.0.3 deduped
  | | |   +-- lodash@4.17.15 deduped
  | | |   `-- to-fast-properties@2.0.0 deduped
  | | +-- @babel/helper-plugin-utils@7.8.3 deduped
  | | +-- @babel/plugin-proposal-async-generator-functions@7.8.3
  | | | +-- @babel/helper-plugin-utils@7.8.3 deduped
  | | | +-- @babel/helper-remap-async-to-generator@7.8.3
  | | | | +-- @babel/helper-annotate-as-pure@7.8.3 deduped
  | | | | +-- @babel/helper-wrap-function@7.8.3
  | | | | | +-- @babel/helper-function-name@7.8.3 deduped
  | | | | | +-- @babel/template@7.8.3 deduped
  | | | | | +-- @babel/traverse@7.8.3 deduped
  | | | | | `-- @babel/types@7.8.3
  | | | | |   +-- esutils@2.0.3 deduped
  | | | | |   +-- lodash@4.17.15 deduped
  | | | | |   `-- to-fast-properties@2.0.0 deduped
  | | | | +-- @babel/template@7.8.3 deduped
  | | | | +-- @babel/traverse@7.8.3 deduped
  | | | | `-- @babel/types@7.8.3
  | | | |   +-- esutils@2.0.3 deduped
  | | | |   +-- lodash@4.17.15 deduped
  | | | |   `-- to-fast-properties@2.0.0 deduped
  | | | `-- @babel/plugin-syntax-async-generators@7.8.4 deduped
  | | +-- @babel/plugin-proposal-dynamic-import@7.8.3
  | | | +-- @babel/helper-plugin-utils@7.8.3 deduped
  | | | `-- @babel/plugin-syntax-dynamic-import@7.8.3 deduped
  | | +-- @babel/plugin-proposal-json-strings@7.8.3
  | | | +-- @babel/helper-plugin-utils@7.8.3 deduped
  | | | `-- @babel/plugin-syntax-json-strings@7.8.3 deduped
  | | +-- @babel/plugin-proposal-nullish-coalescing-operator@7.8.3
  | | | +-- @babel/helper-plugin-utils@7.8.3 deduped
  | | | `-- @babel/plugin-syntax-nullish-coalescing-operator@7.8.3 deduped
  | | +-- @babel/plugin-proposal-object-rest-spread@7.8.3 deduped
  | | +-- @babel/plugin-proposal-optional-catch-binding@7.8.3
  | | | +-- @babel/helper-plugin-utils@7.8.3 deduped
  | | | `-- @babel/plugin-syntax-optional-catch-binding@7.8.3 deduped
  | | +-- @babel/plugin-proposal-optional-chaining@7.8.3
  | | | +-- @babel/helper-plugin-utils@7.8.3 deduped
  | | | `-- @babel/plugin-syntax-optional-chaining@7.8.3 deduped
  | | +-- @babel/plugin-proposal-unicode-property-regex@7.8.3
  | | | +-- @babel/helper-create-regexp-features-plugin@7.8.3
  | | | | +-- @babel/helper-regex@7.8.3 deduped
  | | | | `-- regexpu-core@4.6.0
  | | | |   +-- regenerate@1.4.0
  | | | |   +-- regenerate-unicode-properties@8.1.0
  | | | |   | `-- regenerate@1.4.0 deduped
  | | | |   +-- regjsgen@0.5.1
  | | | |   +-- regjsparser@0.6.2
  | | | |   | `-- jsesc@0.5.0
  | | | |   +-- unicode-match-property-ecmascript@1.0.4
  | | | |   | +-- unicode-canonical-property-names-ecmascript@1.0.4
  | | | |   | `-- unicode-property-aliases-ecmascript@1.0.5
  | | | |   `-- unicode-match-property-value-ecmascript@1.1.0
  | | | `-- @babel/helper-plugin-utils@7.8.3 deduped
  | | +-- @babel/plugin-syntax-async-generators@7.8.4
  | | | `-- @babel/helper-plugin-utils@7.8.3 deduped
  | | +-- @babel/plugin-syntax-dynamic-import@7.8.3
  | | | `-- @babel/helper-plugin-utils@7.8.3 deduped
  | | +-- @babel/plugin-syntax-json-strings@7.8.3
  | | | `-- @babel/helper-plugin-utils@7.8.3 deduped
  | | +-- @babel/plugin-syntax-nullish-coalescing-operator@7.8.3
  | | | `-- @babel/helper-plugin-utils@7.8.3 deduped
  | | +-- @babel/plugin-syntax-object-rest-spread@7.8.3 deduped
  | | +-- @babel/plugin-syntax-optional-catch-binding@7.8.3
  | | | `-- @babel/helper-plugin-utils@7.8.3 deduped
  | | +-- @babel/plugin-syntax-optional-chaining@7.8.3
  | | | `-- @babel/helper-plugin-utils@7.8.3 deduped
  | | +-- @babel/plugin-syntax-top-level-await@7.8.3
  | | | `-- @babel/helper-plugin-utils@7.8.3 deduped
  | | +-- @babel/plugin-transform-arrow-functions@7.8.3
  | | | `-- @babel/helper-plugin-utils@7.8.3 deduped
  | | +-- @babel/plugin-transform-async-to-generator@7.8.3
  | | | +-- @babel/helper-module-imports@7.8.3 deduped
  | | | +-- @babel/helper-plugin-utils@7.8.3 deduped
  | | | `-- @babel/helper-remap-async-to-generator@7.8.3 deduped
  | | +-- @babel/plugin-transform-block-scoped-functions@7.8.3
  | | | `-- @babel/helper-plugin-utils@7.8.3 deduped
  | | +-- @babel/plugin-transform-block-scoping@7.8.3
  | | | +-- @babel/helper-plugin-utils@7.8.3 deduped
  | | | `-- lodash@4.17.15 deduped
  | | +-- @babel/plugin-transform-classes@7.8.3
  | | | +-- @babel/helper-annotate-as-pure@7.8.3
  | | | | `-- @babel/types@7.8.3
  | | | |   +-- esutils@2.0.3 deduped
  | | | |   +-- lodash@4.17.15 deduped
  | | | |   `-- to-fast-properties@2.0.0 deduped
  | | | +-- @babel/helper-define-map@7.8.3
  | | | | +-- @babel/helper-function-name@7.8.3 deduped
  | | | | +-- @babel/types@7.8.3
  | | | | | +-- esutils@2.0.3 deduped
  | | | | | +-- lodash@4.17.15 deduped
  | | | | | `-- to-fast-properties@2.0.0 deduped
  | | | | `-- lodash@4.17.15 deduped
  | | | +-- @babel/helper-function-name@7.8.3 deduped
  | | | +-- @babel/helper-optimise-call-expression@7.8.3 deduped
  | | | +-- @babel/helper-plugin-utils@7.8.3 deduped
  | | | +-- @babel/helper-replace-supers@7.8.3 deduped
  | | | +-- @babel/helper-split-export-declaration@7.8.3 deduped
  | | | `-- globals@11.12.0 deduped
  | | +-- @babel/plugin-transform-computed-properties@7.8.3
  | | | `-- @babel/helper-plugin-utils@7.8.3 deduped
  | | +-- @babel/plugin-transform-destructuring@7.8.3
  | | | `-- @babel/helper-plugin-utils@7.8.3 deduped
  | | +-- @babel/plugin-transform-dotall-regex@7.8.3
  | | | +-- @babel/helper-create-regexp-features-plugin@7.8.3 deduped
  | | | `-- @babel/helper-plugin-utils@7.8.3 deduped
  | | +-- @babel/plugin-transform-duplicate-keys@7.8.3
  | | | `-- @babel/helper-plugin-utils@7.8.3 deduped
  | | +-- @babel/plugin-transform-exponentiation-operator@7.8.3
  | | | +-- @babel/helper-builder-binary-assignment-operator-visitor@7.8.3
  | | | | +-- @babel/helper-explode-assignable-expression@7.8.3
  | | | | | +-- @babel/traverse@7.8.3 deduped
  | | | | | `-- @babel/types@7.8.3
  | | | | |   +-- esutils@2.0.3 deduped
  | | | | |   +-- lodash@4.17.15 deduped
  | | | | |   `-- to-fast-properties@2.0.0 deduped
  | | | | `-- @babel/types@7.8.3
  | | | |   +-- esutils@2.0.3 deduped
  | | | |   +-- lodash@4.17.15 deduped
  | | | |   `-- to-fast-properties@2.0.0 deduped
  | | | `-- @babel/helper-plugin-utils@7.8.3 deduped
  | | +-- @babel/plugin-transform-for-of@7.8.3
  | | | `-- @babel/helper-plugin-utils@7.8.3 deduped
  | | +-- @babel/plugin-transform-function-name@7.8.3
  | | | +-- @babel/helper-function-name@7.8.3 deduped
  | | | `-- @babel/helper-plugin-utils@7.8.3 deduped
  | | +-- @babel/plugin-transform-literals@7.8.3
  | | | `-- @babel/helper-plugin-utils@7.8.3 deduped
  | | +-- @babel/plugin-transform-member-expression-literals@7.8.3
  | | | `-- @babel/helper-plugin-utils@7.8.3 deduped
  | | +-- @babel/plugin-transform-modules-amd@7.8.3
  | | | +-- @babel/helper-module-transforms@7.8.3
  | | | | +-- @babel/helper-module-imports@7.8.3 deduped
  | | | | +-- @babel/helper-simple-access@7.8.3 deduped
  | | | | +-- @babel/helper-split-export-declaration@7.8.3 deduped
  | | | | +-- @babel/template@7.8.3 deduped
  | | | | +-- @babel/types@7.8.3
  | | | | | +-- esutils@2.0.3 deduped
  | | | | | +-- lodash@4.17.15 deduped
  | | | | | `-- to-fast-properties@2.0.0 deduped
  | | | | `-- lodash@4.17.15 deduped
  | | | +-- @babel/helper-plugin-utils@7.8.3 deduped
  | | | `-- babel-plugin-dynamic-import-node@2.3.0
  | | |   `-- object.assign@4.1.0
  | | |     +-- define-properties@1.1.3 deduped
  | | |     +-- function-bind@1.1.1
  | | |     +-- has-symbols@1.0.1
  | | |     `-- object-keys@1.1.1
  | | +-- @babel/plugin-transform-modules-commonjs@7.8.3
  | | | +-- @babel/helper-module-transforms@7.8.3 deduped
  | | | +-- @babel/helper-plugin-utils@7.8.3 deduped
  | | | +-- @babel/helper-simple-access@7.8.3
  | | | | +-- @babel/template@7.8.3 deduped
  | | | | `-- @babel/types@7.8.3
  | | | |   +-- esutils@2.0.3 deduped
  | | | |   +-- lodash@4.17.15 deduped
  | | | |   `-- to-fast-properties@2.0.0 deduped
  | | | `-- babel-plugin-dynamic-import-node@2.3.0 deduped
  | | +-- @babel/plugin-transform-modules-systemjs@7.8.3
  | | | +-- @babel/helper-hoist-variables@7.8.3
  | | | | `-- @babel/types@7.8.3
  | | | |   +-- esutils@2.0.3 deduped
  | | | |   +-- lodash@4.17.15 deduped
  | | | |   `-- to-fast-properties@2.0.0 deduped
  | | | +-- @babel/helper-module-transforms@7.8.3 deduped
  | | | +-- @babel/helper-plugin-utils@7.8.3 deduped
  | | | `-- babel-plugin-dynamic-import-node@2.3.0 deduped
  | | +-- @babel/plugin-transform-modules-umd@7.8.3
  | | | +-- @babel/helper-module-transforms@7.8.3 deduped
  | | | `-- @babel/helper-plugin-utils@7.8.3 deduped
  | | +-- @babel/plugin-transform-named-capturing-groups-regex@7.8.3
  | | | `-- @babel/helper-create-regexp-features-plugin@7.8.3 deduped
  | | +-- @babel/plugin-transform-new-target@7.8.3
  | | | `-- @babel/helper-plugin-utils@7.8.3 deduped
  | | +-- @babel/plugin-transform-object-super@7.8.3
  | | | +-- @babel/helper-plugin-utils@7.8.3 deduped
  | | | `-- @babel/helper-replace-supers@7.8.3 deduped
  | | +-- @babel/plugin-transform-parameters@7.8.3
  | | | +-- @babel/helper-call-delegate@7.8.3
  | | | | +-- @babel/helper-hoist-variables@7.8.3 deduped
  | | | | +-- @babel/traverse@7.8.3 deduped
  | | | | `-- @babel/types@7.8.3
  | | | |   +-- esutils@2.0.3 deduped
  | | | |   +-- lodash@4.17.15 deduped
  | | | |   `-- to-fast-properties@2.0.0 deduped
  | | | +-- @babel/helper-get-function-arity@7.8.3
  | | | | `-- @babel/types@7.8.3
  | | | |   +-- esutils@2.0.3 deduped
  | | | |   +-- lodash@4.17.15 deduped
  | | | |   `-- to-fast-properties@2.0.0 deduped
  | | | `-- @babel/helper-plugin-utils@7.8.3 deduped
  | | +-- @babel/plugin-transform-property-literals@7.8.3
  | | | `-- @babel/helper-plugin-utils@7.8.3 deduped
  | | +-- @babel/plugin-transform-regenerator@7.8.3
  | | | `-- regenerator-transform@0.14.1
  | | |   `-- private@0.1.8 deduped
  | | +-- @babel/plugin-transform-reserved-words@7.8.3
  | | | `-- @babel/helper-plugin-utils@7.8.3 deduped
  | | +-- @babel/plugin-transform-shorthand-properties@7.8.3
  | | | `-- @babel/helper-plugin-utils@7.8.3 deduped
  | | +-- @babel/plugin-transform-spread@7.8.3
  | | | `-- @babel/helper-plugin-utils@7.8.3 deduped
  | | +-- @babel/plugin-transform-sticky-regex@7.8.3
  | | | +-- @babel/helper-plugin-utils@7.8.3 deduped
  | | | `-- @babel/helper-regex@7.8.3
  | | |   `-- lodash@4.17.15 deduped
  | | +-- @babel/plugin-transform-template-literals@7.8.3
  | | | +-- @babel/helper-annotate-as-pure@7.8.3 deduped
  | | | `-- @babel/helper-plugin-utils@7.8.3 deduped
  | | +-- @babel/plugin-transform-typeof-symbol@7.8.3
  | | | `-- @babel/helper-plugin-utils@7.8.3 deduped
  | | +-- @babel/plugin-transform-unicode-regex@7.8.3
  | | | +-- @babel/helper-create-regexp-features-plugin@7.8.3 deduped
  | | | `-- @babel/helper-plugin-utils@7.8.3 deduped
  | | +-- @babel/types@7.8.3
  | | | +-- esutils@2.0.3 deduped
  | | | +-- lodash@4.17.15 deduped
  | | | `-- to-fast-properties@2.0.0 deduped
  | | +-- browserslist@4.8.3
  | | | +-- caniuse-lite@1.0.30001020
  | | | +-- electron-to-chromium@1.3.333
  | | | `-- node-releases@1.1.45
  | | |   `-- semver@6.3.0 deduped
  | | +-- core-js-compat@3.6.4
  | | | +-- browserslist@4.8.3 deduped
  | | | `-- semver@7.0.0
  | | +-- invariant@2.2.4
  | | | `-- loose-envify@1.4.0
  | | |   `-- js-tokens@4.0.0 deduped
  | | +-- levenary@1.1.0
  | | | `-- leven@3.1.0
  | | `-- semver@5.7.1
  | +-- @babel/preset-flow@7.8.3
  | | +-- @babel/helper-plugin-utils@7.8.3 deduped
  | | `-- @babel/plugin-transform-flow-strip-types@7.8.3
  | |   +-- @babel/helper-plugin-utils@7.8.3 deduped
  | |   `-- @babel/plugin-syntax-flow@7.8.3
  | |     `-- @babel/helper-plugin-utils@7.8.3 deduped
  | +-- @babel/preset-typescript@7.8.3
  | | +-- @babel/helper-plugin-utils@7.8.3 deduped
  | | `-- @babel/plugin-transform-typescript@7.8.3
  | |   +-- @babel/helper-create-class-features-plugin@7.8.3 deduped
  | |   +-- @babel/helper-plugin-utils@7.8.3 deduped
  | |   `-- @babel/plugin-syntax-typescript@7.8.3
  | |     `-- @babel/helper-plugin-utils@7.8.3 deduped
  | +-- @babel/register@7.8.3
  | | +-- find-cache-dir@2.1.0
  | | | +-- commondir@1.0.1
  | | | +-- make-dir@2.1.0
  | | | | +-- pify@4.0.1
  | | | | `-- semver@5.7.1
  | | | `-- pkg-dir@3.0.0
  | | |   `-- find-up@3.0.0
  | | |     `-- locate-path@3.0.0
  | | |       +-- p-locate@3.0.0
  | | |       | `-- p-limit@2.2.2
  | | |       |   `-- p-try@2.2.0
  | | |       `-- path-exists@3.0.0
  | | +-- lodash@4.17.15 deduped
  | | +-- make-dir@2.1.0
  | | | +-- pify@4.0.1
  | | | `-- semver@5.7.1
  | | +-- pirates@4.0.1
  | | | `-- node-modules-regexp@1.0.0
  | | `-- source-map-support@0.5.16
  | |   +-- buffer-from@1.1.1
  | |   `-- source-map@0.6.1
  | +-- babel-core@7.0.0-bridge.0
  | +-- colors@1.4.0
  | +-- flow-parser@0.116.0
  | +-- graceful-fs@4.2.3 deduped
  | +-- micromatch@3.1.10
  | | +-- arr-diff@4.0.0
  | | +-- array-unique@0.3.2
  | | +-- braces@2.3.2
  | | | +-- arr-flatten@1.1.0
  | | | +-- array-unique@0.3.2 deduped
  | | | +-- extend-shallow@2.0.1
  | | | | `-- is-extendable@0.1.1 deduped
  | | | +-- fill-range@4.0.0
  | | | | +-- extend-shallow@2.0.1
  | | | | | `-- is-extendable@0.1.1 deduped
  | | | | +-- is-number@3.0.0
  | | | | | `-- kind-of@3.2.2
  | | | | |   `-- is-buffer@1.1.6
  | | | | +-- repeat-string@1.6.1
  | | | | `-- to-regex-range@2.1.1
  | | | |   +-- is-number@3.0.0 deduped
  | | | |   `-- repeat-string@1.6.1 deduped
  | | | +-- isobject@3.0.1
  | | | +-- repeat-element@1.1.3
  | | | +-- snapdragon@0.8.2 deduped
  | | | +-- snapdragon-node@2.1.1
  | | | | +-- define-property@1.0.0
  | | | | | `-- is-descriptor@1.0.2
  | | | | |   +-- is-accessor-descriptor@1.0.0
  | | | | |   | `-- kind-of@6.0.2 deduped
  | | | | |   +-- is-data-descriptor@1.0.0
  | | | | |   | `-- kind-of@6.0.2 deduped
  | | | | |   `-- kind-of@6.0.2 deduped
  | | | | +-- isobject@3.0.1 deduped
  | | | | `-- snapdragon-util@3.0.1
  | | | |   `-- kind-of@3.2.2
  | | | |     `-- is-buffer@1.1.6 deduped
  | | | +-- split-string@3.1.0
  | | | | `-- extend-shallow@3.0.2 deduped
  | | | `-- to-regex@3.0.2 deduped
  | | +-- define-property@2.0.2
  | | | +-- is-descriptor@1.0.2
  | | | | +-- is-accessor-descriptor@1.0.0
  | | | | | `-- kind-of@6.0.2 deduped
  | | | | +-- is-data-descriptor@1.0.0
  | | | | | `-- kind-of@6.0.2 deduped
  | | | | `-- kind-of@6.0.2 deduped
  | | | `-- isobject@3.0.1 deduped
  | | +-- extend-shallow@3.0.2
  | | | +-- assign-symbols@1.0.0
  | | | `-- is-extendable@1.0.1
  | | |   `-- is-plain-object@2.0.4
  | | |     `-- isobject@3.0.1 deduped
  | | +-- extglob@2.0.4
  | | | +-- array-unique@0.3.2 deduped
  | | | +-- define-property@1.0.0
  | | | | `-- is-descriptor@1.0.2
  | | | |   +-- is-accessor-descriptor@1.0.0
  | | | |   | `-- kind-of@6.0.2 deduped
  | | | |   +-- is-data-descriptor@1.0.0
  | | | |   | `-- kind-of@6.0.2 deduped
  | | | |   `-- kind-of@6.0.2 deduped
  | | | +-- expand-brackets@2.1.4
  | | | | +-- debug@2.6.9
  | | | | | `-- ms@2.0.0 deduped
  | | | | +-- define-property@0.2.5
  | | | | | `-- is-descriptor@0.1.6 deduped
  | | | | +-- extend-shallow@2.0.1
  | | | | | `-- is-extendable@0.1.1 deduped
  | | | | +-- posix-character-classes@0.1.1
  | | | | +-- regex-not@1.0.2 deduped
  | | | | +-- snapdragon@0.8.2 deduped
  | | | | `-- to-regex@3.0.2 deduped
  | | | +-- extend-shallow@2.0.1
  | | | | `-- is-extendable@0.1.1 deduped
  | | | +-- fragment-cache@0.2.1 deduped
  | | | +-- regex-not@1.0.2 deduped
  | | | +-- snapdragon@0.8.2 deduped
  | | | `-- to-regex@3.0.2 deduped
  | | +-- fragment-cache@0.2.1
  | | | `-- map-cache@0.2.2
  | | +-- kind-of@6.0.2
  | | +-- nanomatch@1.2.13
  | | | +-- arr-diff@4.0.0 deduped
  | | | +-- array-unique@0.3.2 deduped
  | | | +-- define-property@2.0.2 deduped
  | | | +-- extend-shallow@3.0.2 deduped
  | | | +-- fragment-cache@0.2.1 deduped
  | | | +-- is-windows@1.0.2
  | | | +-- kind-of@6.0.2 deduped
  | | | +-- object.pick@1.3.0 deduped
  | | | +-- regex-not@1.0.2 deduped
  | | | +-- snapdragon@0.8.2 deduped
  | | | `-- to-regex@3.0.2 deduped
  | | +-- object.pick@1.3.0
  | | | `-- isobject@3.0.1 deduped
  | | +-- regex-not@1.0.2
  | | | +-- extend-shallow@3.0.2 deduped
  | | | `-- safe-regex@1.1.0
  | | |   `-- ret@0.1.15
  | | +-- snapdragon@0.8.2
  | | | +-- base@0.11.2
  | | | | +-- cache-base@1.0.1
  | | | | | +-- collection-visit@1.0.0
  | | | | | | +-- map-visit@1.0.0
  | | | | | | | `-- object-visit@1.0.1 deduped
  | | | | | | `-- object-visit@1.0.1
  | | | | | |   `-- isobject@3.0.1 deduped
  | | | | | +-- component-emitter@1.3.0 deduped
  | | | | | +-- get-value@2.0.6
  | | | | | +-- has-value@1.0.0
  | | | | | | +-- get-value@2.0.6 deduped
  | | | | | | +-- has-values@1.0.0
  | | | | | | | +-- is-number@3.0.0 deduped
  | | | | | | | `-- kind-of@4.0.0
  | | | | | | |   `-- is-buffer@1.1.6 deduped
  | | | | | | `-- isobject@3.0.1 deduped
  | | | | | +-- isobject@3.0.1 deduped
  | | | | | +-- set-value@2.0.1
  | | | | | | +-- extend-shallow@2.0.1
  | | | | | | | `-- is-extendable@0.1.1 deduped
  | | | | | | +-- is-extendable@0.1.1 deduped
  | | | | | | +-- is-plain-object@2.0.4 deduped
  | | | | | | `-- split-string@3.1.0 deduped
  | | | | | +-- to-object-path@0.3.0
  | | | | | | `-- kind-of@3.2.2
  | | | | | |   `-- is-buffer@1.1.6 deduped
  | | | | | +-- union-value@1.0.1
  | | | | | | +-- arr-union@3.1.0 deduped
  | | | | | | +-- get-value@2.0.6 deduped
  | | | | | | +-- is-extendable@0.1.1 deduped
  | | | | | | `-- set-value@2.0.1 deduped
  | | | | | `-- unset-value@1.0.0
  | | | | |   +-- has-value@0.3.1
  | | | | |   | +-- get-value@2.0.6 deduped
  | | | | |   | +-- has-values@0.1.4
  | | | | |   | `-- isobject@2.1.0
  | | | | |   |   `-- isarray@1.0.0 deduped
  | | | | |   `-- isobject@3.0.1 deduped
  | | | | +-- class-utils@0.3.6
  | | | | | +-- arr-union@3.1.0
  | | | | | +-- define-property@0.2.5
  | | | | | | `-- is-descriptor@0.1.6 deduped
  | | | | | +-- isobject@3.0.1 deduped
  | | | | | `-- static-extend@0.1.2
  | | | | |   +-- define-property@0.2.5
  | | | | |   | `-- is-descriptor@0.1.6 deduped
  | | | | |   `-- object-copy@0.1.0
  | | | | |     +-- copy-descriptor@0.1.1
  | | | | |     +-- define-property@0.2.5
  | | | | |     | `-- is-descriptor@0.1.6 deduped
  | | | | |     `-- kind-of@3.2.2
  | | | | |       `-- is-buffer@1.1.6 deduped
  | | | | +-- component-emitter@1.3.0
  | | | | +-- define-property@1.0.0
  | | | | | `-- is-descriptor@1.0.2
  | | | | |   +-- is-accessor-descriptor@1.0.0
  | | | | |   | `-- kind-of@6.0.2 deduped
  | | | | |   +-- is-data-descriptor@1.0.0
  | | | | |   | `-- kind-of@6.0.2 deduped
  | | | | |   `-- kind-of@6.0.2 deduped
  | | | | +-- isobject@3.0.1 deduped
  | | | | +-- mixin-deep@1.3.2
  | | | | | +-- for-in@1.0.2
  | | | | | `-- is-extendable@1.0.1
  | | | | |   `-- is-plain-object@2.0.4 deduped
  | | | | `-- pascalcase@0.1.1
  | | | +-- debug@2.6.9
  | | | | `-- ms@2.0.0 deduped
  | | | +-- define-property@0.2.5
  | | | | `-- is-descriptor@0.1.6
  | | | |   +-- is-accessor-descriptor@0.1.6
  | | | |   | `-- kind-of@3.2.2
  | | | |   |   `-- is-buffer@1.1.6 deduped
  | | | |   +-- is-data-descriptor@0.1.4
  | | | |   | `-- kind-of@3.2.2
  | | | |   |   `-- is-buffer@1.1.6 deduped
  | | | |   `-- kind-of@5.1.0
  | | | +-- extend-shallow@2.0.1
  | | | | `-- is-extendable@0.1.1 deduped
  | | | +-- map-cache@0.2.2 deduped
  | | | +-- source-map@0.5.7 deduped
  | | | +-- source-map-resolve@0.5.3
  | | | | +-- atob@2.1.2
  | | | | +-- decode-uri-component@0.2.0
  | | | | +-- resolve-url@0.2.1
  | | | | +-- source-map-url@0.4.0
  | | | | `-- urix@0.1.0
  | | | `-- use@3.1.1
  | | `-- to-regex@3.0.2
  | |   +-- define-property@2.0.2 deduped
  | |   +-- extend-shallow@3.0.2 deduped
  | |   +-- regex-not@1.0.2 deduped
  | |   `-- safe-regex@1.1.0 deduped
  | +-- neo-async@2.6.1
  | +-- node-dir@0.1.17
  | | `-- minimatch@3.0.4 deduped
  | +-- recast@0.16.2
  | | +-- ast-types@0.11.7
  | | +-- esprima@4.0.1 deduped
  | | +-- private@0.1.8 deduped
  | | `-- source-map@0.6.1
  | +-- temp@0.8.4
  | | `-- rimraf@2.6.3
  | |   `-- glob@7.1.6 deduped
  | `-- write-file-atomic@2.4.3
  |   +-- graceful-fs@4.2.3 deduped
  |   +-- imurmurhash@0.1.4
  |   `-- signal-exit@3.0.2 deduped
  +-- lodash.clonedeep@4.5.0
  +-- lru-cache@5.1.1
  | `-- yallist@3.1.1
  +-- minimist@1.2.0
  +-- recast@0.18.5
  | +-- ast-types@0.13.2
  | +-- esprima@4.0.1 deduped
  | +-- private@0.1.8
  | `-- source-map@0.6.1
  +-- resolve@1.14.2
  | `-- path-parse@1.0.6
  +-- shortid@2.2.15
  | `-- nanoid@2.1.9
  +-- slash@3.0.0
  +-- validate-npm-package-name@3.0.0
  | `-- builtins@1.0.3
  +-- vue-jscodeshift-adapter@2.0.3
  | +-- cheerio@1.0.0-rc.3
  | | +-- css-select@1.2.0
  | | | +-- boolbase@1.0.0
  | | | +-- css-what@2.1.3
  | | | +-- domutils@1.5.1
  | | | | +-- dom-serializer@0.1.1 deduped
  | | | | `-- domelementtype@1.3.1 deduped
  | | | `-- nth-check@1.0.2
  | | |   `-- boolbase@1.0.0 deduped
  | | +-- dom-serializer@0.1.1
  | | | +-- domelementtype@1.3.1
  | | | `-- entities@1.1.2 deduped
  | | +-- entities@1.1.2 deduped
  | | +-- htmlparser2@3.10.1
  | | | +-- domelementtype@1.3.1 deduped
  | | | +-- domhandler@2.4.2
  | | | | `-- domelementtype@1.3.1 deduped
  | | | +-- domutils@1.5.1 deduped
  | | | +-- entities@1.1.2 deduped
  | | | +-- inherits@2.0.4 deduped
  | | | `-- readable-stream@3.4.0
  | | |   +-- inherits@2.0.4 deduped
  | | |   +-- string_decoder@1.1.1
  | | |   | `-- safe-buffer@5.1.2
  | | |   `-- util-deprecate@1.0.2
  | | +-- lodash@4.17.15 deduped
  | | `-- parse5@3.0.3
  | |   `-- @types/node@13.1.6 deduped
  | +-- detect-indent@6.0.0
  | +-- indent-string@4.0.0
  | +-- vue-sfc-descriptor-to-string@1.0.0
  | | `-- indent-string@3.2.0
  | `-- vue-template-compiler@2.6.11
  |   +-- de-indent@1.0.2
  |   `-- he@1.2.0
  `-- yaml-front-matter@3.4.1
    +-- commander@1.0.0
    `-- js-yaml@3.13.1 deduped

Arch Linuxのパッケージ作成に Zstandard を使用する

Zstarndard とは

Facebook 社が開発した比較的新しい可逆圧縮アルゴリズムです。Cで実装され、今後各OSで広く浸透してくるものと思われます。 性能については以下が詳しいですが、gzip より大きい圧縮率を誇りながら、それでいて圧縮にかかる時間、伸長にかかる時間ともに大幅に短いという優れものです。

qiita.com

最近 Arch Linux においても使用できるようになりましたので、そのインストールや設定の仕方をメモします。

Arch Linux でのインストール

Core パッケージに入ってきていますので、sのまま pacman でインストールできます。

$ sudo pacman -S zstd

主な機能は以下の通り。

圧縮

ファイルを圧縮する。拡張子は zst になる。

$ zstd inputfile

圧縮レベルを使用して圧縮。以下の例は圧縮レベルを11とした。

$ zstd -11 inputfile

出力ファイルの名前を指定して圧縮。

$ zstd inputfile -o outputfile.zst

伸長

ファイルを伸長する。

$ zstd -d inputfile.zst

以下でも同様です。

$ unzstd inputfile.zst

主なオプション

$ zstd --help
*** zstd command line interface 64-bits v1.4.4, by Yann Collet ***
Usage : 
      zstd [args] [FILE(s)] [-o file] 

FILE    : a filename 
          with no FILE, or when FILE is - , read standard input
Arguments : 
 -#     : # compression level (1-19, default: 3) 
 -d     : decompression 
 -D file: use `file` as Dictionary 
 -o file: result stored into `file` (only if 1 input file) 
 -f     : overwrite output without prompting and (de)compress links 
--rm    : remove source file(s) after successful de/compression 
 -k     : preserve source file(s) (default) 
 -h/-H  : display help/long help and exit 

Advanced arguments : 
 -V     : display Version number and exit 
 -v     : verbose mode; specify multiple times to increase verbosity
 -q     : suppress warnings; specify twice to suppress errors too
 -c     : force write to standard output, even if it is the console
 -l     : print information about zstd compressed files 
--exclude-compressed:  only compress files that are not previously compressed 
--ultra : enable levels beyond 19, up to 22 (requires more memory)
--long[=#]: enable long distance matching with given window log (default: 27)
--fast[=#]: switch to very fast compression levels (default: 1)
--adapt : dynamically adapt compression level to I/O conditions 
--stream-size=# : optimize compression parameters for streaming input of given number of bytes 
--size-hint=# optimize compression parameters for streaming input of approximately this size
--target-compressed-block-size=# : make compressed block near targeted size 
 -T#    : spawns # compression threads (default: 1, 0==# cores) 
 -B#    : select size of each job (default: 0==automatic) 
--rsyncable : compress using a rsync-friendly method (-B sets block size) 
--no-dictID : don't write dictID into header (dictionary compression)
--[no-]check : integrity check (default: enabled) 
--[no-]compress-literals : force (un)compressed literals 
 -r     : operate recursively on directories 
--output-dir-flat[=directory]: all resulting files stored into `directory`. 
--format=zstd : compress files to the .zst format (default) 
--format=gzip : compress files to the .gz format 
--format=xz : compress files to the .xz format 
--format=lzma : compress files to the .lzma format 
--format=lz4 : compress files to the .lz4 format 
--test  : test compressed file integrity 
--[no-]sparse : sparse mode (default: enabled on file, disabled on stdout)
 -M#    : Set a memory usage limit for decompression 
--no-progress : do not display the progress bar 
--      : All arguments after "--" are treated as files 

Dictionary builder : 
--train ## : create a dictionary from a training set of files 
--train-cover[=k=#,d=#,steps=#,split=#,shrink[=#]] : use the cover algorithm with optional args
--train-fastcover[=k=#,d=#,f=#,steps=#,split=#,accel=#,shrink[=#]] : use the fast cover algorithm with optional args
--train-legacy[=s=#] : use the legacy algorithm with selectivity (default: 9)
 -o file : `file` is dictionary name (default: dictionary) 
--maxdict=# : limit dictionary to specified size (default: 112640) 
--dictID=# : force dictionary ID to specified value (default: random)

Benchmark arguments : 
 -b#    : benchmark file(s), using # compression level (default: 3) 
 -e#    : test all compression levels from -bX to # (default: 1)
 -i#    : minimum evaluation time in seconds (default: 3s) 
 -B#    : cut file into independent blocks of size # (default: no block)
--priority=rt : set process priority to real-time

makepkg.conf

最新の pacman (執筆時点では 5.2.1-1 )を導入していれば、 makepkg.conf に自動的に Zstandard についての以下のような項目が追加されています。

/etc/makepkg.conf

COMPRESSZST=(zstd -c -z -q -)

もし見当たらない場合は追記してください。

カーネルなど、パッケージ作成時の圧縮伸長に Zstandard をデフォルトにしたい場合は、以下のように変更します。

/etc/makepkg.conf

PKGEXT='.pkg.tar.zst'

以上で、makepkg を実行した際に作成されるパッケージファイルは Zstandard で圧縮されます。

GeoIPでIPアドレスから国や都市を判別

f:id:alecriarstudio:20191123182433j:plain
GeoIP

筆者は Apache を使用して自宅でWebサーバーを立ち上げており、以前から GeoIP によりアクセス元の国を判別し、望ましくない国からのアクセスは遮断していました。つい最近アクセスログを覗くと GeoIP 関連のエラーが大量に残っており、どうやら今までのデータベースはレガシーとなり、GeoIP は GeoIP2 として新しく生まれ変わったようで、そのためにエラーとなっていたのでした。

そこで新たな GeoIP2 を設定し Apache (2.2以降)で使用するまでの手順を書き記します。

GeoIP2

MaxMind 社が提供する特定のIPアドレスに関する情報を提供するサービス。さまざまなデータベースという形でユーザーに提供されています。有料版と無料版があり、無料版はフリーで利用できます。最近 GeoIP は収束し、これからは GeoIP2 になる模様です。

GeoLite2 データベース

GeoLite2 Free Downloadable Databases « MaxMind Developer Site

MaxMind 社がフリーで提供する GeoIP2 データベース。旧来の GeoLite データベースはレガシーとなり、GeoLite2 に生まれ変わりました。内部形式も MaxMind DB という新しい形式に変わったらしく、それを取り扱うためのライブラリが必要です。

Arch Linux では、GeoLite2 データベースがパッケージという形で配布されています。これをインストールしておきます。

$ pikaur -S geoip2-database

インストールされた場所を確認。

$ pikaur -Ql geoip2-database

geoip2-database /usr/
geoip2-database /usr/share/
geoip2-database /usr/share/GeoIP/
geoip2-database /usr/share/GeoIP/GeoLite2-ASN.mmdb
geoip2-database /usr/share/GeoIP/GeoLite2-City.mmdb
geoip2-database /usr/share/GeoIP/GeoLite2-Country.mmdb
geoip2-database /usr/share/licenses/
geoip2-database /usr/share/licenses/geoip2-database/
geoip2-database /usr/share/licenses/geoip2-database/COPYRIGHT.txt
geoip2-database /usr/share/licenses/geoip2-database/LICENSE.txt

libmaxminddb

maxmind.github.io

MaxMind DB ファイルを読み込むための C ライブラリ。GeoIP2 を使用するためにインストールする必要があります。

以下は Arch Linux でのインストール例です。

$ pikaur -Ss libmaxminddb

community/libmaxminddb 1.3.2-1 
    MaxMindDB GeoIP2 database library
aur/libmaxminddb-git r959.00316fe-1 (2, 0.00)
    C library for the MaxMind DB file format

$ pikaur -S libmaxminddb

pikaur はAURヘルパーです。環境によって yay や yaourt などで代用してください。

mod_maxminddb

github.com

libmaxminddb を介して MaxMind DB を Apache で取り扱うためのモジュールです。Apache は 2.2 以降が必須です。

現時点では公式やAURリポジトリにパッケージが登録されていないようですので、自前でインストールする必要があります。tarball からコンパイルしインストールすることもできますが、ここでは Arch らしくパッケージ作成しインストールする方法を紹介します。

自前パッケージの作成方法はここでは詳しくふれません。以下の Wiki が詳しいです。

パッケージの作成 - ArchWiki

パッケージを作成する準備を整えた後、PKGBUILD ファイルを作成します。以下にサンプルをのせます。

# Maintainer: Hoge <hoge@sample.com>

pkgname=mod_maxminddb-git
pkgver=1.1.0
pkgrel=1
pkgdesc="MaxMindDB Apache Module using the libmaxminddb library"
arch=('any')
url="https://github.com/maxmind/mod_maxminddb"
license=('Apache')
depends=('pacman')
makedepends=('git' 'apache>=2.2' 'gcc-libs')
optdepends=('libmaxminddb: MaxMindDB GeoIP2 database library')

__gitroot="git://github.com/maxmind/mod_maxminddb.git"

prepare() {
  cd "$srcdir"
  if [ -d $pkgname ] ; then
    rm -rf $pkgname
  fi
  git clone $__gitroot $pkgname
}

pkgver() {
  cd "$srcdir/$pkgname"
  git describe --long | sed -E 's/([^-]*-g)/r\1/;s/-/./g'
}

build() {
  cd "$srcdir/$pkgname"
  ./bootstrap
  ./configure --prefix=/usr
  make
}

check() {
  cd "$srcdir/$pkgname"
  make check
}

package() {
  cd "$srcdir/$pkgname/src"
  install -d "$pkgdir/usr/lib/httpd/modules"
  install -Dm755 ".libs/mod_maxminddb.so" "$pkgdir/usr/lib/httpd/modules"
}

その後パッケージを作成しインストールします。

$ makepkg

$ pikaur -U [作成されたパッケージのファイル名]

インストールされた Apache モジュールを確認します。

$ pikaur -Ql mod_maxminddb-git

mod_maxminddb-git /usr/
mod_maxminddb-git /usr/lib/
mod_maxminddb-git /usr/lib/httpd/
mod_maxminddb-git /usr/lib/httpd/modules/
mod_maxminddb-git /usr/lib/httpd/modules/mod_maxminddb.so

Apache の設定

Apache の設定ファイル本体に以下の行を追加します。

/etc/httpd/conf/httpd.conf

LoadModule maxminddb_module /usr/lib/httpd/modules/mod_maxminddb.so

Include conf/extra/mod_maxminddb.conf

さらにMaxMind DBの設定ファイルを新規に編集します。以下はそのサンプルです。

/etc/httpd/conf/extra/mod_maxminddb.conf

<IfModule mod_maxminddb.c>
    MaxMindDBEnable On

    # ASN Database
    #MaxMindDBFile ASN_DB /usr/share/GeoIP/GeoLite2-ASN.mmdb
    #MaxMindDBEnv MM_ASN ASN_DB/autonomous_system_number
    #MaxMindDBEnv MM_ASORG ASN_DB/autonomous_system_organization
    #MaxMindDBNetworkEnv ASN_DB ASN_DB_NETWORK

    # City Database
    #MaxMindDBFile CITY_DB /usr/share/GeoIP/GeoLite2-City.mmdb
    #MaxMindDBEnv MM_CONTINENT_CODE         CITY_DB/continent/code
    #MaxMindDBEnv MM_CONTINENT_GEONAME_ID   CITY_DB/continent/geoname_id
    #MaxMindDBEnv MM_CONTINENT_NAME         CITY_DB/continent/names/en
    #MaxMindDBEnv MM_CONTINENT_NAME_JA      CITY_DB/continent/names/ja
    #MaxMindDBEnv MM_COUNTRY_CODE           CITY_DB/country/iso_code
    #MaxMindDBEnv MM_COUNTRY_GEONAME_ID     CITY_DB/country/geoname_id
    #MaxMindDBEnv MM_COUNTRY_NAME           CITY_DB/country/names/en
    #MaxMindDBEnv MM_COUNTRY_NAME_JA        CITY_DB/country/names/ja
    #MaxMindDBEnv MM_CITY_NAME              CITY_DB/city/names/en
    #MaxMindDBEnv MM_CITY_NAME_JA           CITY_DB/city/names/ja
    #MaxMindDBEnv MM_LONGITUDE              CITY_DB/location/longitude
    #MaxMindDBEnv MM_LATITUDE               CITY_DB/location/latitude
    #MaxMindDBEnv MM_TIME_ZONE              CITY_DB/location/time_zone
    #MaxMindDBEnv MM_POSTAL_CODE            CITY_DB/postal/code
    #MaxMindDBNetworkEnv CITY_DB CITY_DB_NETWORK

    # Country Database
    MaxMindDBFile COUNTRY_DB /usr/share/GeoIP/GeoLite2-Country.mmdb
    MaxMindDBEnv MM_CONTINENT_CODE          COUNTRY_DB/continent/code
    #MaxMindDBEnv MM_CONTINENT_GEONAME_ID   COUNTRY_DB/continent/geoname_id
    MaxMindDBEnv MM_CONTINENT_NAME          COUNTRY_DB/continent/names/en
    #MaxMindDBEnv MM_CONTINENT_NAME_JA      COUNTRY_DB/continent/names/ja
    MaxMindDBEnv MM_COUNTRY_CODE            COUNTRY_DB/country/iso_code
    #MaxMindDBEnv MM_COUNTRY_GEONAME_ID     COUNTRY_DB/country/geoname_id
    MaxMindDBEnv MM_COUNTRY_NAME            COUNTRY_DB/country/names/en
    #MaxMindDBEnv MM_COUNTRY_NAME_JA        COUNTRY_DB/country/names/ja

    # Log entry
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" Country_Code=\"%{MM_COUNTRY_CODE}e\" Country_Name=\"%{MM_COUNTRY_NAME}e\"" combined
    <IfModule logio_module>
      # You need to enable mod_logio.c to use %I and %O
      LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O Country_Code=\"%{MM_COUNTRY_CODE}e\" Country_Name=\"%{MM_COUNTRY_NAME}e\"" combinedio
    </IfModule>
    
    # Blocking by Country
    SetEnvIf MM_COUNTRY_CODE JP AllowCountry
    <Location />
        <RequireAny>
            Require all denied
            Require env AllowCountry
        </RequireAny>
    </Location>
</IfModule>

この設定ファイルではIPアドレスから国の情報を引き出し、それを元にログファイルに記録したりアクセス制限に使用したりしています。使用目的によって適宜改変してください。

設定ファイルの編集が終わった後、Apache の再起動をします。

# sudo systemctl restart httpd

正常であればアクセスログに国についての情報が記録されるようになるはずです。

geoipupdate

本手順では GeoIP2 データベースのファイルはパッケージをアップデートしない限りは固定されたままですが、cron などを使用し定期的にアップデートしたい方は geoipupdate ツールが用意されています。以下のようにパッケージをインストールすればすぐに使用できます。

$ pikaur -S geoipupdate

コマンドを実行すればデータベースファイルを即時更新します。

/usr/bin/geoipupdate

正常に動作することを確認後、cron などに登録し定期的に動かすことで、最新のデータベースに保つことができます。

pacmanでのエラー:処理の準備に失敗しました (依存関係を解決できませんでした)

ほぼ1ヶ月ぶりのパッケージのアップデートをしようとしたのですが、以下のようなエラーが発生。

$ pikaur -Syu

:: パッケージデータベースの同期中...
 core                                           135.6 KiB  2.37M/s 00:00 [########################################] 100%
 extra                                         1646.8 KiB  21.2M/s 00:00 [########################################] 100%
 community                                        4.7 MiB  42.0M/s 00:00 [########################################] 100%
 xenlism-arch は最新です

:: Starting full AUR upgrade...
Reading repository package databases...
Reading local package database...
:: pacman (5.2.1-1) をインストールすると 'pacman<=5.1.3' が破壊され yay-bin の依存関係が壊れます

メッセージから、どうも pacman がおかしいのではと思い、まずは pacman そのものの再インストールを試行。

$ sudo pacman -S pacman

依存関係を解決しています...
衝突するパッケージがないか確認しています...
エラー: 処理の準備に失敗しました (依存関係を解決できませんでした)
:: pacman (5.2.1-1) をインストールすると 'pacman<=5.1.3' が破壊され yay-bin の依存関係が壊れます

同じエラーで止まりました。 何かヒントがないかと探ったところ以下の情報がヒット。

fugenjikko.com

全くの同じ症状。他のArch使いの方も遭遇している様子です。 情報によると、どうやら yay のほうが問題ありそうでしたので、一旦 yay を削除することにしました。

$ sudo pacman -R yay-bin

依存関係を確認しています...

パッケージ (1) yay-bin-9.3.1-1

合計削除容量:  6.31 MiB

:: 以上のパッケージを削除しますか? [Y/n] y
:: パッケージの変更を処理しています...
(1/1) 削除 yay-bin                                                       [########################################] 100%
:: トランザクション後のフックを実行...
(1/1) Arming ConditionNeedsUpdate...

その後再びアップデートをやり直して、無事に最後まで進めることができました。

$ sudo pacman -Syyu
:: パッケージデータベースの同期中...
 core                                           135.6 KiB  2024K/s 00:00 [########################################] 100%
 extra                                         1646.8 KiB  20.1M/s 00:00 [########################################] 100%
 community                                        4.7 MiB  40.5M/s 00:00 [########################################] 100%
 xenlism-arch                                     3.3 KiB  0.00B/s 00:00 [########################################] 100%
:: システム全体の更新を開始...
:: ilmbase を extra/openexr に置き換えますか? [Y/n] y
:: totem-plparser を extra/totem-pl-parser に置き換えますか? [Y/n] y
依存関係を解決しています...
衝突するパッケージがないか確認しています...
警告: 循環依存が検出されました:
警告: libglvnd は依存パッケージ mesa の前にインストールされます

パッケージ (483) accerciser-3.34.2-1  acl-2.2.53-2  adwaita-icon-theme-3.34.3-1  alsa-lib-1.2.1.1-1
                 alsa-plugins-1.2.1-1  anjuta-3.34.0-2  appstream-glib-0.7.16-2  archlinux-keyring-20191018-2
                 argon2-20190702-2  aspell-0.60.8-1  at-spi2-atk-2.34.1-1  attr-2.4.48-2  audit-2.8.5-6
                 autoconf-2.69-6  automake-1.16.1-2  avahi-0.7+18+g1b5f401-3  bash-5.0.011-2  bind-tools-9.14.8-1
                 binutils-2.33.1-2  bison-3.4.2-2  bluez-5.52-1  bluez-libs-5.52-1  boost-libs-1.71.0-4  brltty-6.0-7
                 brotli-1.0.7-3  btrfs-progs-5.3.1-3  bzip2-1.0.8-3  ca-certificates-20181109-2
                 ca-certificates-mozilla-3.47.1-1  ca-certificates-utils-20181109-2  cairo-1.17.2+17+g52a7c79fd-2
                 cdrtools-3.02a09-2  chrome-gnome-shell-10.1-3  cifs-utils-6.9-1  clang-9.0.0-3  clutter-gst-3.0.27-2
                 colord-1.4.4+9+g1ce26da-1  compiler-rt-9.0.0-2  coreutils-8.31-3  cpio-2.13-1  cracklib-2.9.7-2
                 cryptsetup-2.2.2-1  curl-7.67.0-3  dav1d-0.5.1-1  db-5.3.28-5  dbus-1.12.16-3  dconf-editor-3.34.2-1
                 device-mapper-2.02.186-3  dhcpcd-8.1.2-1  diffutils-3.7-3  dmraid-1.0.0.rc16.3-12
                 dnssec-anchors-20190629-2  dosfstools-4.1-3  e2fsprogs-1.45.4-2  efibootmgr-16-2  efivar-37-2
                 ........

合計ダウンロード容量:   881.13 MiB
合計インストール容量:  4139.23 MiB
最終的なアップグレード容量:    80.05 MiB

:: インストールを行いますか? [Y/n] 

まさか yay が悪さをしているとは気づきませんでした。筆者の環境では yay はほぼ使うことはなく、 pikaur を専ら利用しているので、yay はこのまま使用停止することにしました。

yay を使用している方は、正常に pacman が動作するようにしてから再度 yay をインストールすれば復旧するようです。

PowerShellを使ってWindows 10のアプリを管理をしよう

PowerShellでのパッケージ管理 Package Management

前回の記事ではChocolateyを使用し、PowerShellコマンドラインからWindowsのアプリを管理する(パッケージ管理)方法を解説しました。では、WindowsそのものにはPowerShellを使ってパッケージ管理する方法はないのでしょうか。

実はWindows 10から、標準でPowerShellからパッケージを操作することができるようになりました。その名も Package Management です。それだけでなく、既存の Chocolatey や NuGet といったサードパーティーをパッケージプロバイダという形で取り込み、Package Management の下で一元的に取り扱いできるようになりました。今回は Package Management の設定と、パッケージの操作まで解説します。

Package Management を使用するための前準備

PowerShellのデフォルトでは、外部のスクリプトを実行するのは許可されていません。そこでまずスクリプトの実行ポリシーを変更します。 Windowsキー + X を押し、Windows PowerShell (管理者)(A) を選択し管理者モードPowerShellを起動し、そこで以下のコマンドを実行します。

PS C:\> Set-ExecutionPolicy RemoteSigned

実行ポリシーの変更
実行ポリシーは、信頼されていないスクリプトからの保護に役立ちます。実行ポリシーを変更すると、about_Execution_Policies
のヘルプ トピック (https://go.microsoft.com/fwlink/?LinkID=135170)
で説明されているセキュリティ上の危険にさらされる可能性があります。実行ポリシーを変更しますか?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "N"): Y

設問にはYと打ってEnterを押します。

パッケージプロバイダの確認・インストール

現在インストールされているのパッケージプロバイダの一覧を確認します。

PS C:\> Get-PackageProvider

Name                     Version          DynamicOptions
----                     -------          --------------
msi                      3.0.0.0          AdditionalArguments
msu                      3.0.0.0
PowerShellGet            1.0.0.1          PackageManagementProvider, Type, Scope, AllowClobber, SkipPublisherCheck, InstallUpdate, NoPathUpdate, Fi...
Programs                 3.0.0.0          IncludeWindowsInstaller, IncludeSystemComponent

現状ではパッケージの数ではChocolateyが最も多いので、Chcolateyをパッケージプロバイダとしてインストールします。

PS C:\> Get-PackageProvider Chocolatey

プロバイダー 'chocolatey v2.8.5.130' がインストールされていません。
chocolatey は、https://onegetcdn.azureedge.net/providers/ChocolateyPrototype-2.8.5.130.exe から手動でダウンロードしてインストールすることができます。
PackageManagement で chocolatey を自動的にダウンロードしてインストールしますか?
[Y] はい(Y)  [N] いいえ(N)  [S] 中断(S)  [?] ヘルプ (既定値は "Y"): Y

設問にはYと打ってEnterを押します。正常にChocolateyがインストールされると以下が表示されます。

Name                     Version          DynamicOptions
----                     -------          --------------
Chocolatey               2.8.5.130        SkipDependencies, ContinueOnFailure, ExcludeVersion, ForceX86, PackageSaveMode, FilterOnTag, Contains, Al...

もう一度パッケージプロバイダを一覧表示すれば、Chocolateyが新たに加わっていることを確認できます。

PS C:\> Get-PackageProvider

Name                     Version          DynamicOptions
----                     -------          --------------
Chocolatey               2.8.5.130        SkipDependencies, ContinueOnFailure, ExcludeVersion, ForceX86, PackageSaveMode, FilterOnTag, Contains, AllowPrereleaseVersions,...
msi                      3.0.0.0          AdditionalArguments
msu                      3.0.0.0
Programs                 3.0.0.0          IncludeWindowsInstaller, IncludeSystemComponent

今後はChocolateyに含まれるパッケージも Package Management のコマンドで操作できるようになりました。

パッケージの操作

パッケージの検索

インストールできるパッケージを検索し、候補を表示します。以下の例は Firefox を検索したときの例です。

PS C:\> Find-Package -Name Firefox

プロバイダー 'nuget v2.8.5.208' がインストールされていません。
nuget は、https://onegetcdn.azureedge.net/providers/Microsoft.PackageManagement.NuGetProvider-2.8.5.208.dll
から手動でダウンロードしてインストールすることができます。
PackageManagement で nuget を自動的にダウンロードしてインストールしますか?
[Y] はい(Y)  [N] いいえ(N)  [S] 中断(S)  [?] ヘルプ (既定値は "Y"): Y

Name                           Version          Source           Summary
----                           -------          ------           -------
Firefox                        70.0.1           chocolatey       Bringing together all kinds of awesomeness to make browsing better ...

途中で nuget を入れるかどうかを聞いてきていますが、 NuGetもまたパッケージプロバイダの一種です。Firefoxをインストールする場合はこれを先に入れる必要があります。

パッケージのインストール

パッケージの検索で該当するパッケージが見つかれば、以下のコマンドでパッケージのインストールを行います。

PS C:\> Install-Package Firefox

パッケージは、信頼済みとマークされていないパッケージ ソースから取得されています。
'chocolatey' からソフトウェアをアンインストールしますか?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "N"): Y

Name                           Version          Source           Summary
----                           -------          ------           -------
Firefox                        70.0.1           chocolatey       Bringing together all kinds of awesomeness to make browsing better for you

インストール済みパッケージの確認

以下のコマンドでインストールされているかどうかを確認します。

PS C:\> Get-Package Firefox

Name                           Version          Source                           ProviderName
----                           -------          ------                           ------------
Firefox                        70.0.1           C:\Chocolatey\lib\Firefox.70.... Chocolatey

また、単に引数なしで実行すると現在インストールされているパッケージの一覧がでます。

PS C:\> Get-Package

この場合、Chocolatelyのパッケージだけでなく、Windows標準インストーラでインストールされたパッケージも合わせて表示されます。もちChocolateyのパッケージのみを表示したい場合は以下のようにします。

PS C:\> Get-Package -ProviderName Chocolatey

Name                           Version          Source                           ProviderName
----                           -------          ------                           ------------
Firefox                        70.0.1           C:\Chocolatey\lib\Firefox.70.... Chocolatey

パッケージの削除

パッケージが不要になり削除したい場合は、以下のようにします。

PS C:\> Uninstall-Package Firefox

Package Management の問題点

便利な Package Management ですが、ひとつ気になる点があります。 Chocolateyにはパッケージのアップデート機能がありました。コマンドで掛けば choco update です。どうやら Package Management には同様の機能が存在しないらしく、パッケージのバージョンが新しくなった場合は一旦アンインストールし再インストールするしか手段がなさそうです。またどのパッケージのバージョンが新しくなったかの情報も確認しずらいという点もあります。

Windowsの標準機能でPowerShellからパッケージ管理ができるという点は非常に有用なので、アップデート機能などの機能追加を今後期待したいところです。

Windowsのアプリ管理をChocolatelyでやろう

Windowsのアプリ管理って・・

Windowsのアプリ管理って何となく使い勝手が悪くありませんか?パッケージのバージョンを新しくしようにも通知機能はありませんし、まとめてアップデートしようにも一つひとつ行う必要があります。また、あるアプリを入れようとしても、わざわざ配布元サイトにアクセスしてアプリをダウンロードしインストールプログラムを実行する必要があり、煩雑な手間を取られます。

一方、LinuxBSDといったOSには優れたパッケージ(アプリ)管理の仕組みが存在します。Ubuntu/Debianにはapt-get、RedHatにはrpmGentooにはPortage、Arch LinuxにはpacmanFreeBSDにはportsといったものです。それらのパッケージ管理システムは、ほぼすべてのことをコマンド一行で実行でき、煩わしいステップを踏むこともなく自動的に行ってくれます。それらのパッケージ管理がWindowsで実現できないかと探ったところ、ありました。

Windows用パッケージ管理アプリ chocolatey

chocolateyをインストールすると、それ以降さまざまなアプリをchocolateyで一括管理できるようになります。さらに、ほとんどの操作がコマンド一行で行えます。以下のようなコマンドです。

chocolatey install [アプリ名]

前述しましたが、chocolateyはアプリを一括管理できます。一括でインストールもアップデートも削除もできます。また、いちいちインストールファイルをクリックなどといった手間はありません。

ただし、デメリットもあります。現時点でWindows用のアプリを全て網羅しているわけではなく、メジャーなものだけがインストールできます。chocolateyでインストールできないアプリは従来通りWindows側で管理する必要があります。将来的にすべてのアプリがchocolatey対応になれば良いのですが・・。

chocolateyのインストール方法

PowerShellを管理者権限で実行する

Winows10での方法です。キーボードのWindowsキーXを同時に押し、Windows PowerShell (管理者)(A)を選択します。

f:id:alecriarstudio:20191118160830p:plain
Windows PowerShell (管理者)

もしPowerShellが見当たらない場合は、設定→個人用設定→タスクバーで、「[スタート]ボタンを右クリックするかWindowsキー + Xキーを押したときに表示されるメニューで、コマンドプロンプトWindows PowerShellに置き換える」をオンにしてください。

f:id:alecriarstudio:20191118161247p:plain
コマンドプロンプトWindows PowerShellに置き換える

実行ポリシーの確認

PowerShell側の制限で、デフォルトではスクリプトの実行が制限されています。そこで制限を緩めるために、以下のコマンドを予め実行しておきます。

PS C:\> Set-ExecutionPolicy RemoteSigned

実行ポリシーの変更
実行ポリシーは、信頼されていないスクリプトからの保護に役立ちます。実行ポリシーを変更すると、about_Execution_Policies
のヘルプ トピック (https://go.microsoft.com/fwlink/?LinkID=135170)
で説明されているセキュリティ上の危険にさらされる可能性があります。実行ポリシーを変更しますか?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "N"): Y

設問にはYと打ってEnterを押します。

chocolateyのインストールを実行

chocolateyのサイトにアクセスし、PowerShellに「Now run the following command:」と書かれた以下の箇所をコピーし貼り付けます。無事に貼り付けられたらそのままEnterキーを押して実行します。

chocolatey.org

f:id:alecriarstudio:20191118162401p:plain
chocolateyインストールコマンド

無事にインストール完了後、PowerShellからchocolateyのコマンドが使用できるようになります。

chocolateyのコマンド

管理者権限を持ったPowerShellでさまざまなコマンドが実行でき、以下のような形式になります。

chocolatey [コマンド] [オプション]

chocoleteyの短縮形chocoでも同じように実行できます。

choco [コマンド] [オプション]

コマンドの例

アプリインストールの例

choco install gimp

chocolateyで登録されているアプリをリスト表示

choco list

特定のアプリを文字列で検索

choco list [アプリ名の文字列]

既にchocolateyにてインストールされたアプリ一覧

choco list -localonly

アプリをすべてアップデート

choco update all

特定のアプリのみアップデート

choco update [アプリ名]

アプリの削除

choco uninstall [アプリ名]

これ以外にも様々なコマンドがあります。あとは実際にさわってみてください。

(参考)chocoletey GUI

chocolateyはコマンドで操作するのが基本ですが、実はGUI版もあります。とはいえ、GUI版はコマンドのラッパーになっていますので、内部的にはコマンド版と同じことを行っています。操作をコマンドではなくGUIで行いたい方にはこしらをどうぞ。

chocolatey GUIをインストールする場合は次のようにします。

choco install chocolateygui

Windowsのスタートメニューにアイコンが登録され、以降はGUIからchocolateyが操作できるようになります。

f:id:alecriarstudio:20191118164238p:plain
Chocolatey GUI

余談

どうやら、似たようなパッケージ管理システムがWindows10で公式にサポートされる流れのようです。そちらのほうが有益ならchocolateyからの乗り換えも考えてもいいかもしれません。